1//
2// Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3// Copyright (c) 2014, 2019, 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 invisible to the allocator (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 R10     ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()        );
98reg_def R10_H   ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
99reg_def R11     ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()        );
100reg_def R11_H   ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
101reg_def R12     ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()        );
102reg_def R12_H   ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next());
103reg_def R13     ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()        );
104reg_def R13_H   ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next());
105reg_def R14     ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()        );
106reg_def R14_H   ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next());
107reg_def R15     ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()        );
108reg_def R15_H   ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next());
109reg_def R16     ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()        );
110reg_def R16_H   ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next());
111reg_def R17     ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()        );
112reg_def R17_H   ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next());
113reg_def R18     ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()        );
114reg_def R18_H   ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next());
115reg_def R19     ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()        );
116reg_def R19_H   ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next());
117reg_def R20     ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()        ); // caller esp
118reg_def R20_H   ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next());
119reg_def R21     ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()        );
120reg_def R21_H   ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next());
121reg_def R22     ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()        );
122reg_def R22_H   ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next());
123reg_def R23     ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()        );
124reg_def R23_H   ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next());
125reg_def R24     ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()        );
126reg_def R24_H   ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next());
127reg_def R25     ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()        );
128reg_def R25_H   ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next());
129reg_def R26     ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()        );
130reg_def R26_H   ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next());
131reg_def R27     (  NS, SOE, Op_RegI, 27, r27->as_VMReg()        ); // heapbase
132reg_def R27_H   (  NS, SOE, Op_RegI, 27, r27->as_VMReg()->next());
133reg_def R28     (  NS, SOE, Op_RegI, 28, r28->as_VMReg()        ); // thread
134reg_def R28_H   (  NS, SOE, Op_RegI, 28, r28->as_VMReg()->next());
135reg_def R29     (  NS,  NS, Op_RegI, 29, r29->as_VMReg()        ); // fp
136reg_def R29_H   (  NS,  NS, Op_RegI, 29, r29->as_VMReg()->next());
137reg_def R30     (  NS,  NS, Op_RegI, 30, r30->as_VMReg()        ); // lr
138reg_def R30_H   (  NS,  NS, Op_RegI, 30, r30->as_VMReg()->next());
139reg_def R31     (  NS,  NS, Op_RegI, 31, r31_sp->as_VMReg()     ); // sp
140reg_def R31_H   (  NS,  NS, Op_RegI, 31, r31_sp->as_VMReg()->next());
141
142// ----------------------------
143// Float/Double Registers
144// ----------------------------
145
146// Double Registers
147
148// The rules of ADL require that double registers be defined in pairs.
149// Each pair must be two 32-bit values, but not necessarily a pair of
150// single float registers. In each pair, ADLC-assigned register numbers
151// must be adjacent, with the lower number even. Finally, when the
152// CPU stores such a register pair to memory, the word associated with
153// the lower ADLC-assigned number must be stored to the lower address.
154
155// AArch64 has 32 floating-point registers. Each can store a vector of
156// single or double precision floating-point values up to 8 * 32
157// floats, 4 * 64 bit floats or 2 * 128 bit floats.  We currently only
158// use the first float or double element of the vector.
159
160// for Java use float registers v0-v15 are always save on call whereas
161// the platform ABI treats v8-v15 as callee save). float registers
162// v16-v31 are SOC as per the platform spec
163
164  reg_def V0   ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()          );
165  reg_def V0_H ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()->next()  );
166  reg_def V0_J ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()->next(2) );
167  reg_def V0_K ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()->next(3) );
168
169  reg_def V1   ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()          );
170  reg_def V1_H ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()->next()  );
171  reg_def V1_J ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()->next(2) );
172  reg_def V1_K ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()->next(3) );
173
174  reg_def V2   ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()          );
175  reg_def V2_H ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()->next()  );
176  reg_def V2_J ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()->next(2) );
177  reg_def V2_K ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()->next(3) );
178
179  reg_def V3   ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()          );
180  reg_def V3_H ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()->next()  );
181  reg_def V3_J ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()->next(2) );
182  reg_def V3_K ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()->next(3) );
183
184  reg_def V4   ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()          );
185  reg_def V4_H ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()->next()  );
186  reg_def V4_J ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()->next(2) );
187  reg_def V4_K ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()->next(3) );
188
189  reg_def V5   ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()          );
190  reg_def V5_H ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()->next()  );
191  reg_def V5_J ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()->next(2) );
192  reg_def V5_K ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()->next(3) );
193
194  reg_def V6   ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()          );
195  reg_def V6_H ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()->next()  );
196  reg_def V6_J ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()->next(2) );
197  reg_def V6_K ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()->next(3) );
198
199  reg_def V7   ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()          );
200  reg_def V7_H ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()->next()  );
201  reg_def V7_J ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()->next(2) );
202  reg_def V7_K ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()->next(3) );
203
204  reg_def V8   ( SOC, SOE, Op_RegF,  8, v8->as_VMReg()          );
205  reg_def V8_H ( SOC, SOE, Op_RegF,  8, v8->as_VMReg()->next()  );
206  reg_def V8_J ( SOC, SOC, Op_RegF,  8, v8->as_VMReg()->next(2) );
207  reg_def V8_K ( SOC, SOC, Op_RegF,  8, v8->as_VMReg()->next(3) );
208
209  reg_def V9   ( SOC, SOE, Op_RegF,  9, v9->as_VMReg()          );
210  reg_def V9_H ( SOC, SOE, Op_RegF,  9, v9->as_VMReg()->next()  );
211  reg_def V9_J ( SOC, SOC, Op_RegF,  9, v9->as_VMReg()->next(2) );
212  reg_def V9_K ( SOC, SOC, Op_RegF,  9, v9->as_VMReg()->next(3) );
213
214  reg_def V10  ( SOC, SOE, Op_RegF, 10, v10->as_VMReg()         );
215  reg_def V10_H( SOC, SOE, Op_RegF, 10, v10->as_VMReg()->next() );
216  reg_def V10_J( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2));
217  reg_def V10_K( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3));
218
219  reg_def V11  ( SOC, SOE, Op_RegF, 11, v11->as_VMReg()         );
220  reg_def V11_H( SOC, SOE, Op_RegF, 11, v11->as_VMReg()->next() );
221  reg_def V11_J( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2));
222  reg_def V11_K( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3));
223
224  reg_def V12  ( SOC, SOE, Op_RegF, 12, v12->as_VMReg()         );
225  reg_def V12_H( SOC, SOE, Op_RegF, 12, v12->as_VMReg()->next() );
226  reg_def V12_J( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2));
227  reg_def V12_K( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3));
228
229  reg_def V13  ( SOC, SOE, Op_RegF, 13, v13->as_VMReg()         );
230  reg_def V13_H( SOC, SOE, Op_RegF, 13, v13->as_VMReg()->next() );
231  reg_def V13_J( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2));
232  reg_def V13_K( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3));
233
234  reg_def V14  ( SOC, SOE, Op_RegF, 14, v14->as_VMReg()         );
235  reg_def V14_H( SOC, SOE, Op_RegF, 14, v14->as_VMReg()->next() );
236  reg_def V14_J( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2));
237  reg_def V14_K( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3));
238
239  reg_def V15  ( SOC, SOE, Op_RegF, 15, v15->as_VMReg()         );
240  reg_def V15_H( SOC, SOE, Op_RegF, 15, v15->as_VMReg()->next() );
241  reg_def V15_J( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2));
242  reg_def V15_K( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3));
243
244  reg_def V16  ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()         );
245  reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() );
246  reg_def V16_J( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2));
247  reg_def V16_K( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3));
248
249  reg_def V17  ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()         );
250  reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() );
251  reg_def V17_J( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2));
252  reg_def V17_K( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3));
253
254  reg_def V18  ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()         );
255  reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() );
256  reg_def V18_J( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2));
257  reg_def V18_K( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3));
258
259  reg_def V19  ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()         );
260  reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() );
261  reg_def V19_J( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2));
262  reg_def V19_K( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3));
263
264  reg_def V20  ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()         );
265  reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() );
266  reg_def V20_J( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2));
267  reg_def V20_K( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3));
268
269  reg_def V21  ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()         );
270  reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() );
271  reg_def V21_J( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2));
272  reg_def V21_K( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3));
273
274  reg_def V22  ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()         );
275  reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() );
276  reg_def V22_J( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2));
277  reg_def V22_K( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3));
278
279  reg_def V23  ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()         );
280  reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() );
281  reg_def V23_J( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2));
282  reg_def V23_K( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3));
283
284  reg_def V24  ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()         );
285  reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() );
286  reg_def V24_J( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2));
287  reg_def V24_K( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3));
288
289  reg_def V25  ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()         );
290  reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() );
291  reg_def V25_J( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2));
292  reg_def V25_K( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3));
293
294  reg_def V26  ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()         );
295  reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() );
296  reg_def V26_J( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2));
297  reg_def V26_K( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3));
298
299  reg_def V27  ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()         );
300  reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() );
301  reg_def V27_J( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2));
302  reg_def V27_K( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3));
303
304  reg_def V28  ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()         );
305  reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() );
306  reg_def V28_J( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2));
307  reg_def V28_K( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3));
308
309  reg_def V29  ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()         );
310  reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() );
311  reg_def V29_J( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2));
312  reg_def V29_K( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3));
313
314  reg_def V30  ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()         );
315  reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() );
316  reg_def V30_J( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2));
317  reg_def V30_K( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3));
318
319  reg_def V31  ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()         );
320  reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() );
321  reg_def V31_J( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2));
322  reg_def V31_K( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3));
323
324// ----------------------------
325// Special Registers
326// ----------------------------
327
328// the AArch64 CSPR status flag register is not directly acessible as
329// instruction operand. the FPSR status flag register is a system
330// register which can be written/read using MSR/MRS but again does not
331// appear as an operand (a code identifying the FSPR occurs as an
332// immediate value in the instruction).
333
334reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad());
335
336
337// Specify priority of register selection within phases of register
338// allocation.  Highest priority is first.  A useful heuristic is to
339// give registers a low priority when they are required by machine
340// instructions, like EAX and EDX on I486, and choose no-save registers
341// before save-on-call, & save-on-call before save-on-entry.  Registers
342// which participate in fixed calling sequences should come last.
343// Registers which are used as pairs must fall on an even boundary.
344
345alloc_class chunk0(
346    // volatiles
347    R10, R10_H,
348    R11, R11_H,
349    R12, R12_H,
350    R13, R13_H,
351    R14, R14_H,
352    R15, R15_H,
353    R16, R16_H,
354    R17, R17_H,
355    R18, R18_H,
356
357    // arg registers
358    R0, R0_H,
359    R1, R1_H,
360    R2, R2_H,
361    R3, R3_H,
362    R4, R4_H,
363    R5, R5_H,
364    R6, R6_H,
365    R7, R7_H,
366
367    // non-volatiles
368    R19, R19_H,
369    R20, R20_H,
370    R21, R21_H,
371    R22, R22_H,
372    R23, R23_H,
373    R24, R24_H,
374    R25, R25_H,
375    R26, R26_H,
376
377    // non-allocatable registers
378
379    R27, R27_H, // heapbase
380    R28, R28_H, // thread
381    R29, R29_H, // fp
382    R30, R30_H, // lr
383    R31, R31_H, // sp
384);
385
386alloc_class chunk1(
387
388    // no save
389    V16, V16_H, V16_J, V16_K,
390    V17, V17_H, V17_J, V17_K,
391    V18, V18_H, V18_J, V18_K,
392    V19, V19_H, V19_J, V19_K,
393    V20, V20_H, V20_J, V20_K,
394    V21, V21_H, V21_J, V21_K,
395    V22, V22_H, V22_J, V22_K,
396    V23, V23_H, V23_J, V23_K,
397    V24, V24_H, V24_J, V24_K,
398    V25, V25_H, V25_J, V25_K,
399    V26, V26_H, V26_J, V26_K,
400    V27, V27_H, V27_J, V27_K,
401    V28, V28_H, V28_J, V28_K,
402    V29, V29_H, V29_J, V29_K,
403    V30, V30_H, V30_J, V30_K,
404    V31, V31_H, V31_J, V31_K,
405
406    // arg registers
407    V0, V0_H, V0_J, V0_K,
408    V1, V1_H, V1_J, V1_K,
409    V2, V2_H, V2_J, V2_K,
410    V3, V3_H, V3_J, V3_K,
411    V4, V4_H, V4_J, V4_K,
412    V5, V5_H, V5_J, V5_K,
413    V6, V6_H, V6_J, V6_K,
414    V7, V7_H, V7_J, V7_K,
415
416    // non-volatiles
417    V8, V8_H, V8_J, V8_K,
418    V9, V9_H, V9_J, V9_K,
419    V10, V10_H, V10_J, V10_K,
420    V11, V11_H, V11_J, V11_K,
421    V12, V12_H, V12_J, V12_K,
422    V13, V13_H, V13_J, V13_K,
423    V14, V14_H, V14_J, V14_K,
424    V15, V15_H, V15_J, V15_K,
425);
426
427alloc_class chunk2(RFLAGS);
428
429//----------Architecture Description Register Classes--------------------------
430// Several register classes are automatically defined based upon information in
431// this architecture description.
432// 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
433// 2) reg_class compiler_method_oop_reg    ( /* as def'd in frame section */ )
434// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
435// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
436//
437
438// Class for all 32 bit integer registers -- excludes SP which will
439// never be used as an integer register
440reg_class any_reg32(
441    R0,
442    R1,
443    R2,
444    R3,
445    R4,
446    R5,
447    R6,
448    R7,
449    R10,
450    R11,
451    R12,
452    R13,
453    R14,
454    R15,
455    R16,
456    R17,
457    R18,
458    R19,
459    R20,
460    R21,
461    R22,
462    R23,
463    R24,
464    R25,
465    R26,
466    R27,
467    R28,
468    R29,
469    R30
470);
471
472// Singleton class for R0 int register
473reg_class int_r0_reg(R0);
474
475// Singleton class for R2 int register
476reg_class int_r2_reg(R2);
477
478// Singleton class for R3 int register
479reg_class int_r3_reg(R3);
480
481// Singleton class for R4 int register
482reg_class int_r4_reg(R4);
483
484// Class for all long integer registers (including RSP)
485reg_class any_reg(
486    R0, R0_H,
487    R1, R1_H,
488    R2, R2_H,
489    R3, R3_H,
490    R4, R4_H,
491    R5, R5_H,
492    R6, R6_H,
493    R7, R7_H,
494    R10, R10_H,
495    R11, R11_H,
496    R12, R12_H,
497    R13, R13_H,
498    R14, R14_H,
499    R15, R15_H,
500    R16, R16_H,
501    R17, R17_H,
502    R18, R18_H,
503    R19, R19_H,
504    R20, R20_H,
505    R21, R21_H,
506    R22, R22_H,
507    R23, R23_H,
508    R24, R24_H,
509    R25, R25_H,
510    R26, R26_H,
511    R27, R27_H,
512    R28, R28_H,
513    R29, R29_H,
514    R30, R30_H,
515    R31, R31_H
516);
517
518// Class for all non-special integer registers
519reg_class no_special_reg32_no_fp(
520    R0,
521    R1,
522    R2,
523    R3,
524    R4,
525    R5,
526    R6,
527    R7,
528    R10,
529    R11,
530    R12,                        // rmethod
531    R13,
532    R14,
533    R15,
534    R16,
535    R17,
536    R18,
537    R19,
538    R20,
539    R21,
540    R22,
541    R23,
542    R24,
543    R25,
544    R26
545 /* R27, */                     // heapbase
546 /* R28, */                     // thread
547 /* R29, */                     // fp
548 /* R30, */                     // lr
549 /* R31 */                      // sp
550);
551
552reg_class no_special_reg32_with_fp(
553    R0,
554    R1,
555    R2,
556    R3,
557    R4,
558    R5,
559    R6,
560    R7,
561    R10,
562    R11,
563    R12,                        // rmethod
564    R13,
565    R14,
566    R15,
567    R16,
568    R17,
569    R18,
570    R19,
571    R20,
572    R21,
573    R22,
574    R23,
575    R24,
576    R25,
577    R26
578 /* R27, */                     // heapbase
579 /* R28, */                     // thread
580    R29,                        // fp
581 /* R30, */                     // lr
582 /* R31 */                      // sp
583);
584
585reg_class_dynamic no_special_reg32(no_special_reg32_no_fp, no_special_reg32_with_fp, %{ PreserveFramePointer %});
586
587// Class for all non-special long integer registers
588reg_class no_special_reg_no_fp(
589    R0, R0_H,
590    R1, R1_H,
591    R2, R2_H,
592    R3, R3_H,
593    R4, R4_H,
594    R5, R5_H,
595    R6, R6_H,
596    R7, R7_H,
597    R10, R10_H,
598    R11, R11_H,
599    R12, R12_H,                 // rmethod
600    R13, R13_H,
601    R14, R14_H,
602    R15, R15_H,
603    R16, R16_H,
604    R17, R17_H,
605    R18, R18_H,
606    R19, R19_H,
607    R20, R20_H,
608    R21, R21_H,
609    R22, R22_H,
610    R23, R23_H,
611    R24, R24_H,
612    R25, R25_H,
613    R26, R26_H,
614 /* R27, R27_H, */              // heapbase
615 /* R28, R28_H, */              // thread
616 /* R29, R29_H, */              // fp
617 /* R30, R30_H, */              // lr
618 /* R31, R31_H */               // sp
619);
620
621reg_class no_special_reg_with_fp(
622    R0, R0_H,
623    R1, R1_H,
624    R2, R2_H,
625    R3, R3_H,
626    R4, R4_H,
627    R5, R5_H,
628    R6, R6_H,
629    R7, R7_H,
630    R10, R10_H,
631    R11, R11_H,
632    R12, R12_H,                 // rmethod
633    R13, R13_H,
634    R14, R14_H,
635    R15, R15_H,
636    R16, R16_H,
637    R17, R17_H,
638    R18, R18_H,
639    R19, R19_H,
640    R20, R20_H,
641    R21, R21_H,
642    R22, R22_H,
643    R23, R23_H,
644    R24, R24_H,
645    R25, R25_H,
646    R26, R26_H,
647 /* R27, R27_H, */              // heapbase
648 /* R28, R28_H, */              // thread
649    R29, R29_H,                 // fp
650 /* R30, R30_H, */              // lr
651 /* R31, R31_H */               // sp
652);
653
654reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %});
655
656// Class for 64 bit register r0
657reg_class r0_reg(
658    R0, R0_H
659);
660
661// Class for 64 bit register r1
662reg_class r1_reg(
663    R1, R1_H
664);
665
666// Class for 64 bit register r2
667reg_class r2_reg(
668    R2, R2_H
669);
670
671// Class for 64 bit register r3
672reg_class r3_reg(
673    R3, R3_H
674);
675
676// Class for 64 bit register r4
677reg_class r4_reg(
678    R4, R4_H
679);
680
681// Class for 64 bit register r5
682reg_class r5_reg(
683    R5, R5_H
684);
685
686// Class for 64 bit register r10
687reg_class r10_reg(
688    R10, R10_H
689);
690
691// Class for 64 bit register r11
692reg_class r11_reg(
693    R11, R11_H
694);
695
696// Class for method register
697reg_class method_reg(
698    R12, R12_H
699);
700
701// Class for heapbase register
702reg_class heapbase_reg(
703    R27, R27_H
704);
705
706// Class for thread register
707reg_class thread_reg(
708    R28, R28_H
709);
710
711// Class for frame pointer register
712reg_class fp_reg(
713    R29, R29_H
714);
715
716// Class for link register
717reg_class lr_reg(
718    R30, R30_H
719);
720
721// Class for long sp register
722reg_class sp_reg(
723  R31, R31_H
724);
725
726// Class for all pointer registers
727reg_class ptr_reg(
728    R0, R0_H,
729    R1, R1_H,
730    R2, R2_H,
731    R3, R3_H,
732    R4, R4_H,
733    R5, R5_H,
734    R6, R6_H,
735    R7, R7_H,
736    R10, R10_H,
737    R11, R11_H,
738    R12, R12_H,
739    R13, R13_H,
740    R14, R14_H,
741    R15, R15_H,
742    R16, R16_H,
743    R17, R17_H,
744    R18, R18_H,
745    R19, R19_H,
746    R20, R20_H,
747    R21, R21_H,
748    R22, R22_H,
749    R23, R23_H,
750    R24, R24_H,
751    R25, R25_H,
752    R26, R26_H,
753    R27, R27_H,
754    R28, R28_H,
755    R29, R29_H,
756    R30, R30_H,
757    R31, R31_H
758);
759
760// Class for all non_special pointer registers
761reg_class no_special_ptr_reg(
762    R0, R0_H,
763    R1, R1_H,
764    R2, R2_H,
765    R3, R3_H,
766    R4, R4_H,
767    R5, R5_H,
768    R6, R6_H,
769    R7, R7_H,
770    R10, R10_H,
771    R11, R11_H,
772    R12, R12_H,
773    R13, R13_H,
774    R14, R14_H,
775    R15, R15_H,
776    R16, R16_H,
777    R17, R17_H,
778    R18, R18_H,
779    R19, R19_H,
780    R20, R20_H,
781    R21, R21_H,
782    R22, R22_H,
783    R23, R23_H,
784    R24, R24_H,
785    R25, R25_H,
786    R26, R26_H,
787 /* R27, R27_H, */              // heapbase
788 /* R28, R28_H, */              // thread
789 /* R29, R29_H, */              // fp
790 /* R30, R30_H, */              // lr
791 /* R31, R31_H */               // sp
792);
793
794// Class for all float registers
795reg_class float_reg(
796    V0,
797    V1,
798    V2,
799    V3,
800    V4,
801    V5,
802    V6,
803    V7,
804    V8,
805    V9,
806    V10,
807    V11,
808    V12,
809    V13,
810    V14,
811    V15,
812    V16,
813    V17,
814    V18,
815    V19,
816    V20,
817    V21,
818    V22,
819    V23,
820    V24,
821    V25,
822    V26,
823    V27,
824    V28,
825    V29,
826    V30,
827    V31
828);
829
830// Double precision float registers have virtual `high halves' that
831// are needed by the allocator.
832// Class for all double registers
833reg_class double_reg(
834    V0, V0_H,
835    V1, V1_H,
836    V2, V2_H,
837    V3, V3_H,
838    V4, V4_H,
839    V5, V5_H,
840    V6, V6_H,
841    V7, V7_H,
842    V8, V8_H,
843    V9, V9_H,
844    V10, V10_H,
845    V11, V11_H,
846    V12, V12_H,
847    V13, V13_H,
848    V14, V14_H,
849    V15, V15_H,
850    V16, V16_H,
851    V17, V17_H,
852    V18, V18_H,
853    V19, V19_H,
854    V20, V20_H,
855    V21, V21_H,
856    V22, V22_H,
857    V23, V23_H,
858    V24, V24_H,
859    V25, V25_H,
860    V26, V26_H,
861    V27, V27_H,
862    V28, V28_H,
863    V29, V29_H,
864    V30, V30_H,
865    V31, V31_H
866);
867
868// Class for all 64bit vector registers
869reg_class vectord_reg(
870    V0, V0_H,
871    V1, V1_H,
872    V2, V2_H,
873    V3, V3_H,
874    V4, V4_H,
875    V5, V5_H,
876    V6, V6_H,
877    V7, V7_H,
878    V8, V8_H,
879    V9, V9_H,
880    V10, V10_H,
881    V11, V11_H,
882    V12, V12_H,
883    V13, V13_H,
884    V14, V14_H,
885    V15, V15_H,
886    V16, V16_H,
887    V17, V17_H,
888    V18, V18_H,
889    V19, V19_H,
890    V20, V20_H,
891    V21, V21_H,
892    V22, V22_H,
893    V23, V23_H,
894    V24, V24_H,
895    V25, V25_H,
896    V26, V26_H,
897    V27, V27_H,
898    V28, V28_H,
899    V29, V29_H,
900    V30, V30_H,
901    V31, V31_H
902);
903
904// Class for all 128bit vector registers
905reg_class vectorx_reg(
906    V0, V0_H, V0_J, V0_K,
907    V1, V1_H, V1_J, V1_K,
908    V2, V2_H, V2_J, V2_K,
909    V3, V3_H, V3_J, V3_K,
910    V4, V4_H, V4_J, V4_K,
911    V5, V5_H, V5_J, V5_K,
912    V6, V6_H, V6_J, V6_K,
913    V7, V7_H, V7_J, V7_K,
914    V8, V8_H, V8_J, V8_K,
915    V9, V9_H, V9_J, V9_K,
916    V10, V10_H, V10_J, V10_K,
917    V11, V11_H, V11_J, V11_K,
918    V12, V12_H, V12_J, V12_K,
919    V13, V13_H, V13_J, V13_K,
920    V14, V14_H, V14_J, V14_K,
921    V15, V15_H, V15_J, V15_K,
922    V16, V16_H, V16_J, V16_K,
923    V17, V17_H, V17_J, V17_K,
924    V18, V18_H, V18_J, V18_K,
925    V19, V19_H, V19_J, V19_K,
926    V20, V20_H, V20_J, V20_K,
927    V21, V21_H, V21_J, V21_K,
928    V22, V22_H, V22_J, V22_K,
929    V23, V23_H, V23_J, V23_K,
930    V24, V24_H, V24_J, V24_K,
931    V25, V25_H, V25_J, V25_K,
932    V26, V26_H, V26_J, V26_K,
933    V27, V27_H, V27_J, V27_K,
934    V28, V28_H, V28_J, V28_K,
935    V29, V29_H, V29_J, V29_K,
936    V30, V30_H, V30_J, V30_K,
937    V31, V31_H, V31_J, V31_K
938);
939
940// Class for 128 bit register v0
941reg_class v0_reg(
942    V0, V0_H
943);
944
945// Class for 128 bit register v1
946reg_class v1_reg(
947    V1, V1_H
948);
949
950// Class for 128 bit register v2
951reg_class v2_reg(
952    V2, V2_H
953);
954
955// Class for 128 bit register v3
956reg_class v3_reg(
957    V3, V3_H
958);
959
960// Singleton class for condition codes
961reg_class int_flags(RFLAGS);
962
963%}
964
965//----------DEFINITION BLOCK---------------------------------------------------
966// Define name --> value mappings to inform the ADLC of an integer valued name
967// Current support includes integer values in the range [0, 0x7FFFFFFF]
968// Format:
969//        int_def  <name>         ( <int_value>, <expression>);
970// Generated Code in ad_<arch>.hpp
971//        #define  <name>   (<expression>)
972//        // value == <int_value>
973// Generated code in ad_<arch>.cpp adlc_verification()
974//        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
975//
976
977// we follow the ppc-aix port in using a simple cost model which ranks
978// register operations as cheap, memory ops as more expensive and
979// branches as most expensive. the first two have a low as well as a
980// normal cost. huge cost appears to be a way of saying don't do
981// something
982
983definitions %{
984  // The default cost (of a register move instruction).
985  int_def INSN_COST            (    100,     100);
986  int_def BRANCH_COST          (    200,     2 * INSN_COST);
987  int_def CALL_COST            (    200,     2 * INSN_COST);
988  int_def VOLATILE_REF_COST    (   1000,     10 * INSN_COST);
989%}
990
991
992//----------SOURCE BLOCK-------------------------------------------------------
993// This is a block of C++ code which provides values, functions, and
994// definitions necessary in the rest of the architecture description
995
996source_hpp %{
997
998#include "asm/macroAssembler.hpp"
999#include "gc/shared/barrierSetAssembler.hpp"
1000#include "gc/shared/cardTable.hpp"
1001#include "gc/shared/cardTableBarrierSet.hpp"
1002#include "gc/shared/collectedHeap.hpp"
1003#include "opto/addnode.hpp"
1004
1005class CallStubImpl {
1006
1007  //--------------------------------------------------------------
1008  //---<  Used for optimization in Compile::shorten_branches  >---
1009  //--------------------------------------------------------------
1010
1011 public:
1012  // Size of call trampoline stub.
1013  static uint size_call_trampoline() {
1014    return 0; // no call trampolines on this platform
1015  }
1016
1017  // number of relocations needed by a call trampoline stub
1018  static uint reloc_call_trampoline() {
1019    return 0; // no call trampolines on this platform
1020  }
1021};
1022
1023class HandlerImpl {
1024
1025 public:
1026
1027  static int emit_exception_handler(CodeBuffer &cbuf);
1028  static int emit_deopt_handler(CodeBuffer& cbuf);
1029
1030  static uint size_exception_handler() {
1031    return MacroAssembler::far_branch_size();
1032  }
1033
1034  static uint size_deopt_handler() {
1035    // count one adr and one far branch instruction
1036    return 4 * NativeInstruction::instruction_size;
1037  }
1038};
1039
1040 bool is_CAS(int opcode, bool maybe_volatile);
1041
1042  // predicates controlling emit of ldr<x>/ldar<x> and associated dmb
1043
1044  bool unnecessary_acquire(const Node *barrier);
1045  bool needs_acquiring_load(const Node *load);
1046
1047  // predicates controlling emit of str<x>/stlr<x> and associated dmbs
1048
1049  bool unnecessary_release(const Node *barrier);
1050  bool unnecessary_volatile(const Node *barrier);
1051  bool needs_releasing_store(const Node *store);
1052
1053  // predicate controlling translation of CompareAndSwapX
1054  bool needs_acquiring_load_exclusive(const Node *load);
1055
1056  // predicate controlling translation of StoreCM
1057  bool unnecessary_storestore(const Node *storecm);
1058
1059  // predicate controlling addressing modes
1060  bool size_fits_all_mem_uses(AddPNode* addp, int shift);
1061%}
1062
1063source %{
1064
1065  // Optimizaton of volatile gets and puts
1066  // -------------------------------------
1067  //
1068  // AArch64 has ldar<x> and stlr<x> instructions which we can safely
1069  // use to implement volatile reads and writes. For a volatile read
1070  // we simply need
1071  //
1072  //   ldar<x>
1073  //
1074  // and for a volatile write we need
1075  //
1076  //   stlr<x>
1077  //
1078  // Alternatively, we can implement them by pairing a normal
1079  // load/store with a memory barrier. For a volatile read we need
1080  //
1081  //   ldr<x>
1082  //   dmb ishld
1083  //
1084  // for a volatile write
1085  //
1086  //   dmb ish
1087  //   str<x>
1088  //   dmb ish
1089  //
1090  // We can also use ldaxr and stlxr to implement compare and swap CAS
1091  // sequences. These are normally translated to an instruction
1092  // sequence like the following
1093  //
1094  //   dmb      ish
1095  // retry:
1096  //   ldxr<x>   rval raddr
1097  //   cmp       rval rold
1098  //   b.ne done
1099  //   stlxr<x>  rval, rnew, rold
1100  //   cbnz      rval retry
1101  // done:
1102  //   cset      r0, eq
1103  //   dmb ishld
1104  //
1105  // Note that the exclusive store is already using an stlxr
1106  // instruction. That is required to ensure visibility to other
1107  // threads of the exclusive write (assuming it succeeds) before that
1108  // of any subsequent writes.
1109  //
1110  // The following instruction sequence is an improvement on the above
1111  //
1112  // retry:
1113  //   ldaxr<x>  rval raddr
1114  //   cmp       rval rold
1115  //   b.ne done
1116  //   stlxr<x>  rval, rnew, rold
1117  //   cbnz      rval retry
1118  // done:
1119  //   cset      r0, eq
1120  //
1121  // We don't need the leading dmb ish since the stlxr guarantees
1122  // visibility of prior writes in the case that the swap is
1123  // successful. Crucially we don't have to worry about the case where
1124  // the swap is not successful since no valid program should be
1125  // relying on visibility of prior changes by the attempting thread
1126  // in the case where the CAS fails.
1127  //
1128  // Similarly, we don't need the trailing dmb ishld if we substitute
1129  // an ldaxr instruction since that will provide all the guarantees we
1130  // require regarding observation of changes made by other threads
1131  // before any change to the CAS address observed by the load.
1132  //
1133  // In order to generate the desired instruction sequence we need to
1134  // be able to identify specific 'signature' ideal graph node
1135  // sequences which i) occur as a translation of a volatile reads or
1136  // writes or CAS operations and ii) do not occur through any other
1137  // translation or graph transformation. We can then provide
1138  // alternative aldc matching rules which translate these node
1139  // sequences to the desired machine code sequences. Selection of the
1140  // alternative rules can be implemented by predicates which identify
1141  // the relevant node sequences.
1142  //
1143  // The ideal graph generator translates a volatile read to the node
1144  // sequence
1145  //
1146  //   LoadX[mo_acquire]
1147  //   MemBarAcquire
1148  //
1149  // As a special case when using the compressed oops optimization we
1150  // may also see this variant
1151  //
1152  //   LoadN[mo_acquire]
1153  //   DecodeN
1154  //   MemBarAcquire
1155  //
1156  // A volatile write is translated to the node sequence
1157  //
1158  //   MemBarRelease
1159  //   StoreX[mo_release] {CardMark}-optional
1160  //   MemBarVolatile
1161  //
1162  // n.b. the above node patterns are generated with a strict
1163  // 'signature' configuration of input and output dependencies (see
1164  // the predicates below for exact details). The card mark may be as
1165  // simple as a few extra nodes or, in a few GC configurations, may
1166  // include more complex control flow between the leading and
1167  // trailing memory barriers. However, whatever the card mark
1168  // configuration these signatures are unique to translated volatile
1169  // reads/stores -- they will not appear as a result of any other
1170  // bytecode translation or inlining nor as a consequence of
1171  // optimizing transforms.
1172  //
1173  // We also want to catch inlined unsafe volatile gets and puts and
1174  // be able to implement them using either ldar<x>/stlr<x> or some
1175  // combination of ldr<x>/stlr<x> and dmb instructions.
1176  //
1177  // Inlined unsafe volatiles puts manifest as a minor variant of the
1178  // normal volatile put node sequence containing an extra cpuorder
1179  // membar
1180  //
1181  //   MemBarRelease
1182  //   MemBarCPUOrder
1183  //   StoreX[mo_release] {CardMark}-optional
1184  //   MemBarCPUOrder
1185  //   MemBarVolatile
1186  //
1187  // n.b. as an aside, a cpuorder membar is not itself subject to
1188  // matching and translation by adlc rules.  However, the rule
1189  // predicates need to detect its presence in order to correctly
1190  // select the desired adlc rules.
1191  //
1192  // Inlined unsafe volatile gets manifest as a slightly different
1193  // node sequence to a normal volatile get because of the
1194  // introduction of some CPUOrder memory barriers to bracket the
1195  // Load. However, but the same basic skeleton of a LoadX feeding a
1196  // MemBarAcquire, possibly thorugh an optional DecodeN, is still
1197  // present
1198  //
1199  //   MemBarCPUOrder
1200  //        ||       \\
1201  //   MemBarCPUOrder LoadX[mo_acquire]
1202  //        ||            |
1203  //        ||       {DecodeN} optional
1204  //        ||       /
1205  //     MemBarAcquire
1206  //
1207  // In this case the acquire membar does not directly depend on the
1208  // load. However, we can be sure that the load is generated from an
1209  // inlined unsafe volatile get if we see it dependent on this unique
1210  // sequence of membar nodes. Similarly, given an acquire membar we
1211  // can know that it was added because of an inlined unsafe volatile
1212  // get if it is fed and feeds a cpuorder membar and if its feed
1213  // membar also feeds an acquiring load.
1214  //
1215  // Finally an inlined (Unsafe) CAS operation is translated to the
1216  // following ideal graph
1217  //
1218  //   MemBarRelease
1219  //   MemBarCPUOrder
1220  //   CompareAndSwapX {CardMark}-optional
1221  //   MemBarCPUOrder
1222  //   MemBarAcquire
1223  //
1224  // So, where we can identify these volatile read and write
1225  // signatures we can choose to plant either of the above two code
1226  // sequences. For a volatile read we can simply plant a normal
1227  // ldr<x> and translate the MemBarAcquire to a dmb. However, we can
1228  // also choose to inhibit translation of the MemBarAcquire and
1229  // inhibit planting of the ldr<x>, instead planting an ldar<x>.
1230  //
1231  // When we recognise a volatile store signature we can choose to
1232  // plant at a dmb ish as a translation for the MemBarRelease, a
1233  // normal str<x> and then a dmb ish for the MemBarVolatile.
1234  // Alternatively, we can inhibit translation of the MemBarRelease
1235  // and MemBarVolatile and instead plant a simple stlr<x>
1236  // instruction.
1237  //
1238  // when we recognise a CAS signature we can choose to plant a dmb
1239  // ish as a translation for the MemBarRelease, the conventional
1240  // macro-instruction sequence for the CompareAndSwap node (which
1241  // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire.
1242  // Alternatively, we can elide generation of the dmb instructions
1243  // and plant the alternative CompareAndSwap macro-instruction
1244  // sequence (which uses ldaxr<x>).
1245  //
1246  // Of course, the above only applies when we see these signature
1247  // configurations. We still want to plant dmb instructions in any
1248  // other cases where we may see a MemBarAcquire, MemBarRelease or
1249  // MemBarVolatile. For example, at the end of a constructor which
1250  // writes final/volatile fields we will see a MemBarRelease
1251  // instruction and this needs a 'dmb ish' lest we risk the
1252  // constructed object being visible without making the
1253  // final/volatile field writes visible.
1254  //
1255  // n.b. the translation rules below which rely on detection of the
1256  // volatile signatures and insert ldar<x> or stlr<x> are failsafe.
1257  // If we see anything other than the signature configurations we
1258  // always just translate the loads and stores to ldr<x> and str<x>
1259  // and translate acquire, release and volatile membars to the
1260  // relevant dmb instructions.
1261  //
1262
1263  // is_CAS(int opcode, bool maybe_volatile)
1264  //
1265  // return true if opcode is one of the possible CompareAndSwapX
1266  // values otherwise false.
1267
1268  bool is_CAS(int opcode, bool maybe_volatile)
1269  {
1270    switch(opcode) {
1271      // We handle these
1272    case Op_CompareAndSwapI:
1273    case Op_CompareAndSwapL:
1274    case Op_CompareAndSwapP:
1275    case Op_CompareAndSwapN:
1276    case Op_CompareAndSwapB:
1277    case Op_CompareAndSwapS:
1278    case Op_GetAndSetI:
1279    case Op_GetAndSetL:
1280    case Op_GetAndSetP:
1281    case Op_GetAndSetN:
1282    case Op_GetAndAddI:
1283    case Op_GetAndAddL:
1284#if INCLUDE_SHENANDOAHGC
1285    case Op_ShenandoahCompareAndSwapP:
1286    case Op_ShenandoahCompareAndSwapN:
1287#endif
1288      return true;
1289    case Op_CompareAndExchangeI:
1290    case Op_CompareAndExchangeN:
1291    case Op_CompareAndExchangeB:
1292    case Op_CompareAndExchangeS:
1293    case Op_CompareAndExchangeL:
1294    case Op_CompareAndExchangeP:
1295    case Op_WeakCompareAndSwapB:
1296    case Op_WeakCompareAndSwapS:
1297    case Op_WeakCompareAndSwapI:
1298    case Op_WeakCompareAndSwapL:
1299    case Op_WeakCompareAndSwapP:
1300    case Op_WeakCompareAndSwapN:
1301      return maybe_volatile;
1302    default:
1303      return false;
1304    }
1305  }
1306
1307  // helper to determine the maximum number of Phi nodes we may need to
1308  // traverse when searching from a card mark membar for the merge mem
1309  // feeding a trailing membar or vice versa
1310
1311// predicates controlling emit of ldr<x>/ldar<x> and associated dmb
1312
1313bool unnecessary_acquire(const Node *barrier)
1314{
1315  assert(barrier->is_MemBar(), "expecting a membar");
1316
1317  if (UseBarriersForVolatile) {
1318    // we need to plant a dmb
1319    return false;
1320  }
1321
1322  MemBarNode* mb = barrier->as_MemBar();
1323
1324  if (mb->trailing_load()) {
1325    return true;
1326  }
1327
1328  if (mb->trailing_load_store()) {
1329    Node* load_store = mb->in(MemBarNode::Precedent);
1330    assert(load_store->is_LoadStore(), "unexpected graph shape");
1331    return is_CAS(load_store->Opcode(), true);
1332  }
1333
1334  return false;
1335}
1336
1337bool needs_acquiring_load(const Node *n)
1338{
1339  assert(n->is_Load(), "expecting a load");
1340  if (UseBarriersForVolatile) {
1341    // we use a normal load and a dmb
1342    return false;
1343  }
1344
1345  LoadNode *ld = n->as_Load();
1346
1347  return ld->is_acquire();
1348}
1349
1350bool unnecessary_release(const Node *n)
1351{
1352  assert((n->is_MemBar() &&
1353	  n->Opcode() == Op_MemBarRelease),
1354	 "expecting a release membar");
1355
1356  if (UseBarriersForVolatile) {
1357    // we need to plant a dmb
1358    return false;
1359  }
1360
1361  MemBarNode *barrier = n->as_MemBar();
1362  if (!barrier->leading()) {
1363    return false;
1364  } else {
1365    Node* trailing = barrier->trailing_membar();
1366    MemBarNode* trailing_mb = trailing->as_MemBar();
1367    assert(trailing_mb->trailing(), "Not a trailing membar?");
1368    assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars");
1369
1370    Node* mem = trailing_mb->in(MemBarNode::Precedent);
1371    if (mem->is_Store()) {
1372      assert(mem->as_Store()->is_release(), "");
1373      assert(trailing_mb->Opcode() == Op_MemBarVolatile, "");
1374      return true;
1375    } else {
1376      assert(mem->is_LoadStore(), "");
1377      assert(trailing_mb->Opcode() == Op_MemBarAcquire, "");
1378      return is_CAS(mem->Opcode(), true);
1379    }
1380  }
1381  return false;
1382}
1383
1384bool unnecessary_volatile(const Node *n)
1385{
1386  // assert n->is_MemBar();
1387  if (UseBarriersForVolatile) {
1388    // we need to plant a dmb
1389    return false;
1390  }
1391
1392  MemBarNode *mbvol = n->as_MemBar();
1393
1394  bool release = mbvol->trailing_store();
1395  assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), "");
1396#ifdef ASSERT
1397  if (release) {
1398    Node* leading = mbvol->leading_membar();
1399    assert(leading->Opcode() == Op_MemBarRelease, "");
1400    assert(leading->as_MemBar()->leading_store(), "");
1401    assert(leading->as_MemBar()->trailing_membar() == mbvol, "");
1402  }
1403#endif
1404
1405  return release;
1406}
1407
1408// predicates controlling emit of str<x>/stlr<x> and associated dmbs
1409
1410bool needs_releasing_store(const Node *n)
1411{
1412  // assert n->is_Store();
1413  if (UseBarriersForVolatile) {
1414    // we use a normal store and dmb combination
1415    return false;
1416  }
1417
1418  StoreNode *st = n->as_Store();
1419
1420  return st->trailing_membar() != NULL;
1421}
1422
1423// predicate controlling translation of CAS
1424//
1425// returns true if CAS needs to use an acquiring load otherwise false
1426
1427bool needs_acquiring_load_exclusive(const Node *n)
1428{
1429  assert(is_CAS(n->Opcode(), true), "expecting a compare and swap");
1430  if (UseBarriersForVolatile) {
1431    return false;
1432  }
1433
1434  LoadStoreNode* ldst = n->as_LoadStore();
1435  if (is_CAS(n->Opcode(), false)) {
1436    assert(ldst->trailing_membar() != NULL, "expected trailing membar");
1437  } else {
1438    return ldst->trailing_membar() != NULL;
1439  }
1440
1441  // so we can just return true here
1442  return true;
1443}
1444
1445// predicate controlling translation of StoreCM
1446//
1447// returns true if a StoreStore must precede the card write otherwise
1448// false
1449
1450bool unnecessary_storestore(const Node *storecm)
1451{
1452  assert(storecm->Opcode()  == Op_StoreCM, "expecting a StoreCM");
1453
1454  // we need to generate a dmb ishst between an object put and the
1455  // associated card mark when we are using CMS without conditional
1456  // card marking
1457
1458  if (UseConcMarkSweepGC && !UseCondCardMark) {
1459    return false;
1460  }
1461
1462  // a storestore is unnecesary in all other cases
1463
1464  return true;
1465}
1466
1467
1468#define __ _masm.
1469
1470// advance declarations for helper functions to convert register
1471// indices to register objects
1472
1473// the ad file has to provide implementations of certain methods
1474// expected by the generic code
1475//
1476// REQUIRED FUNCTIONALITY
1477
1478//=============================================================================
1479
1480// !!!!! Special hack to get all types of calls to specify the byte offset
1481//       from the start of the call to the point where the return address
1482//       will point.
1483
1484int MachCallStaticJavaNode::ret_addr_offset()
1485{
1486  // call should be a simple bl
1487  int off = 4;
1488  return off;
1489}
1490
1491int MachCallDynamicJavaNode::ret_addr_offset()
1492{
1493  return 16; // movz, movk, movk, bl
1494}
1495
1496int MachCallRuntimeNode::ret_addr_offset() {
1497  // for generated stubs the call will be
1498  //   bl(addr)
1499  // or with far branches
1500  //   bl(trampoline_stub)
1501  // for real runtime callouts it will be six instructions
1502  // see aarch64_enc_java_to_runtime
1503  //   adr(rscratch2, retaddr)
1504  //   lea(rscratch1, RuntimeAddress(addr)
1505  //   stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)))
1506  //   blr(rscratch1)
1507  CodeBlob *cb = CodeCache::find_blob(_entry_point);
1508  if (cb) {
1509    return 1 * NativeInstruction::instruction_size;
1510  } else {
1511    return 6 * NativeInstruction::instruction_size;
1512  }
1513}
1514
1515// Indicate if the safepoint node needs the polling page as an input
1516
1517// the shared code plants the oop data at the start of the generated
1518// code for the safepoint node and that needs ot be at the load
1519// instruction itself. so we cannot plant a mov of the safepoint poll
1520// address followed by a load. setting this to true means the mov is
1521// scheduled as a prior instruction. that's better for scheduling
1522// anyway.
1523
1524bool SafePointNode::needs_polling_address_input()
1525{
1526  return true;
1527}
1528
1529//=============================================================================
1530
1531#ifndef PRODUCT
1532void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1533  st->print("BREAKPOINT");
1534}
1535#endif
1536
1537void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1538  MacroAssembler _masm(&cbuf);
1539  __ brk(0);
1540}
1541
1542uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1543  return MachNode::size(ra_);
1544}
1545
1546//=============================================================================
1547
1548#ifndef PRODUCT
1549  void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const {
1550    st->print("nop \t# %d bytes pad for loops and calls", _count);
1551  }
1552#endif
1553
1554  void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const {
1555    MacroAssembler _masm(&cbuf);
1556    for (int i = 0; i < _count; i++) {
1557      __ nop();
1558    }
1559  }
1560
1561  uint MachNopNode::size(PhaseRegAlloc*) const {
1562    return _count * NativeInstruction::instruction_size;
1563  }
1564
1565//=============================================================================
1566const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
1567
1568int Compile::ConstantTable::calculate_table_base_offset() const {
1569  return 0;  // absolute addressing, no offset
1570}
1571
1572bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1573void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1574  ShouldNotReachHere();
1575}
1576
1577void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1578  // Empty encoding
1579}
1580
1581uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1582  return 0;
1583}
1584
1585#ifndef PRODUCT
1586void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1587  st->print("-- \t// MachConstantBaseNode (empty encoding)");
1588}
1589#endif
1590
1591#ifndef PRODUCT
1592void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1593  Compile* C = ra_->C;
1594
1595  int framesize = C->frame_slots() << LogBytesPerInt;
1596
1597  if (C->need_stack_bang(framesize))
1598    st->print("# stack bang size=%d\n\t", framesize);
1599
1600  if (framesize < ((1 << 9) + 2 * wordSize)) {
1601    st->print("sub  sp, sp, #%d\n\t", framesize);
1602    st->print("stp  rfp, lr, [sp, #%d]", framesize - 2 * wordSize);
1603    if (PreserveFramePointer) st->print("\n\tadd  rfp, sp, #%d", framesize - 2 * wordSize);
1604  } else {
1605    st->print("stp  lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize));
1606    if (PreserveFramePointer) st->print("mov  rfp, sp\n\t");
1607    st->print("mov  rscratch1, #%d\n\t", framesize - 2 * wordSize);
1608    st->print("sub  sp, sp, rscratch1");
1609  }
1610}
1611#endif
1612
1613void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1614  Compile* C = ra_->C;
1615  MacroAssembler _masm(&cbuf);
1616
1617  // n.b. frame size includes space for return pc and rfp
1618  const int framesize = C->frame_size_in_bytes();
1619  assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment");
1620
1621  // insert a nop at the start of the prolog so we can patch in a
1622  // branch if we need to invalidate the method later
1623  __ nop();
1624
1625  int bangsize = C->bang_size_in_bytes();
1626  if (C->need_stack_bang(bangsize) && UseStackBanging)
1627    __ generate_stack_overflow_check(bangsize);
1628
1629  __ build_frame(framesize);
1630
1631  if (VerifyStackAtCalls) {
1632    Unimplemented();
1633  }
1634
1635  C->set_frame_complete(cbuf.insts_size());
1636
1637  if (C->has_mach_constant_base_node()) {
1638    // NOTE: We set the table base offset here because users might be
1639    // emitted before MachConstantBaseNode.
1640    Compile::ConstantTable& constant_table = C->constant_table();
1641    constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1642  }
1643}
1644
1645uint MachPrologNode::size(PhaseRegAlloc* ra_) const
1646{
1647  return MachNode::size(ra_); // too many variables; just compute it
1648                              // the hard way
1649}
1650
1651int MachPrologNode::reloc() const
1652{
1653  return 0;
1654}
1655
1656//=============================================================================
1657
1658#ifndef PRODUCT
1659void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1660  Compile* C = ra_->C;
1661  int framesize = C->frame_slots() << LogBytesPerInt;
1662
1663  st->print("# pop frame %d\n\t",framesize);
1664
1665  if (framesize == 0) {
1666    st->print("ldp  lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1667  } else if (framesize < ((1 << 9) + 2 * wordSize)) {
1668    st->print("ldp  lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize);
1669    st->print("add  sp, sp, #%d\n\t", framesize);
1670  } else {
1671    st->print("mov  rscratch1, #%d\n\t", framesize - 2 * wordSize);
1672    st->print("add  sp, sp, rscratch1\n\t");
1673    st->print("ldp  lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1674  }
1675
1676  if (do_polling() && C->is_method_compilation()) {
1677    st->print("# touch polling page\n\t");
1678    st->print("mov  rscratch1, #0x%lx\n\t", p2i(os::get_polling_page()));
1679    st->print("ldr zr, [rscratch1]");
1680  }
1681}
1682#endif
1683
1684void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1685  Compile* C = ra_->C;
1686  MacroAssembler _masm(&cbuf);
1687  int framesize = C->frame_slots() << LogBytesPerInt;
1688
1689  __ remove_frame(framesize);
1690
1691  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1692    __ reserved_stack_check();
1693  }
1694
1695  if (do_polling() && C->is_method_compilation()) {
1696    __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type);
1697  }
1698}
1699
1700uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1701  // Variable size. Determine dynamically.
1702  return MachNode::size(ra_);
1703}
1704
1705int MachEpilogNode::reloc() const {
1706  // Return number of relocatable values contained in this instruction.
1707  return 1; // 1 for polling page.
1708}
1709
1710const Pipeline * MachEpilogNode::pipeline() const {
1711  return MachNode::pipeline_class();
1712}
1713
1714// This method seems to be obsolete. It is declared in machnode.hpp
1715// and defined in all *.ad files, but it is never called. Should we
1716// get rid of it?
1717int MachEpilogNode::safepoint_offset() const {
1718  assert(do_polling(), "no return for this epilog node");
1719  return 4;
1720}
1721
1722//=============================================================================
1723
1724// Figure out which register class each belongs in: rc_int, rc_float or
1725// rc_stack.
1726enum RC { rc_bad, rc_int, rc_float, rc_stack };
1727
1728static enum RC rc_class(OptoReg::Name reg) {
1729
1730  if (reg == OptoReg::Bad) {
1731    return rc_bad;
1732  }
1733
1734  // we have 30 int registers * 2 halves
1735  // (rscratch1 and rscratch2 are omitted)
1736  int slots_of_int_registers = RegisterImpl::max_slots_per_register * (RegisterImpl::number_of_registers - 2);
1737
1738  if (reg < slots_of_int_registers) {
1739    return rc_int;
1740  }
1741
1742  // we have 32 float register * 4 halves
1743  if (reg < slots_of_int_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) {
1744    return rc_float;
1745  }
1746
1747  // Between float regs & stack is the flags regs.
1748  assert(OptoReg::is_stack(reg), "blow up if spilling flags");
1749
1750  return rc_stack;
1751}
1752
1753uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1754  Compile* C = ra_->C;
1755
1756  // Get registers to move.
1757  OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1758  OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1759  OptoReg::Name dst_hi = ra_->get_reg_second(this);
1760  OptoReg::Name dst_lo = ra_->get_reg_first(this);
1761
1762  enum RC src_hi_rc = rc_class(src_hi);
1763  enum RC src_lo_rc = rc_class(src_lo);
1764  enum RC dst_hi_rc = rc_class(dst_hi);
1765  enum RC dst_lo_rc = rc_class(dst_lo);
1766
1767  assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1768
1769  if (src_hi != OptoReg::Bad) {
1770    assert((src_lo&1)==0 && src_lo+1==src_hi &&
1771           (dst_lo&1)==0 && dst_lo+1==dst_hi,
1772           "expected aligned-adjacent pairs");
1773  }
1774
1775  if (src_lo == dst_lo && src_hi == dst_hi) {
1776    return 0;            // Self copy, no move.
1777  }
1778
1779  bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi &&
1780              (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi;
1781  int src_offset = ra_->reg2offset(src_lo);
1782  int dst_offset = ra_->reg2offset(dst_lo);
1783
1784  if (bottom_type()->isa_vect() != NULL) {
1785    uint ireg = ideal_reg();
1786    assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector");
1787    if (cbuf) {
1788      MacroAssembler _masm(cbuf);
1789      assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity");
1790      if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1791        // stack->stack
1792        assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset");
1793        if (ireg == Op_VecD) {
1794          __ unspill(rscratch1, true, src_offset);
1795          __ spill(rscratch1, true, dst_offset);
1796        } else {
1797          __ spill_copy128(src_offset, dst_offset);
1798        }
1799      } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1800        __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1801               ireg == Op_VecD ? __ T8B : __ T16B,
1802               as_FloatRegister(Matcher::_regEncode[src_lo]));
1803      } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1804        __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
1805                       ireg == Op_VecD ? __ D : __ Q,
1806                       ra_->reg2offset(dst_lo));
1807      } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) {
1808        __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1809                       ireg == Op_VecD ? __ D : __ Q,
1810                       ra_->reg2offset(src_lo));
1811      } else {
1812        ShouldNotReachHere();
1813      }
1814    }
1815  } else if (cbuf) {
1816    MacroAssembler _masm(cbuf);
1817    switch (src_lo_rc) {
1818    case rc_int:
1819      if (dst_lo_rc == rc_int) {  // gpr --> gpr copy
1820        if (is64) {
1821            __ mov(as_Register(Matcher::_regEncode[dst_lo]),
1822                   as_Register(Matcher::_regEncode[src_lo]));
1823        } else {
1824            MacroAssembler _masm(cbuf);
1825            __ movw(as_Register(Matcher::_regEncode[dst_lo]),
1826                    as_Register(Matcher::_regEncode[src_lo]));
1827        }
1828      } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
1829        if (is64) {
1830            __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1831                     as_Register(Matcher::_regEncode[src_lo]));
1832        } else {
1833            __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1834                     as_Register(Matcher::_regEncode[src_lo]));
1835        }
1836      } else {                    // gpr --> stack spill
1837        assert(dst_lo_rc == rc_stack, "spill to bad register class");
1838        __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
1839      }
1840      break;
1841    case rc_float:
1842      if (dst_lo_rc == rc_int) {  // fpr --> gpr copy
1843        if (is64) {
1844            __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
1845                     as_FloatRegister(Matcher::_regEncode[src_lo]));
1846        } else {
1847            __ fmovs(as_Register(Matcher::_regEncode[dst_lo]),
1848                     as_FloatRegister(Matcher::_regEncode[src_lo]));
1849        }
1850      } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
1851          if (cbuf) {
1852            __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1853                     as_FloatRegister(Matcher::_regEncode[src_lo]));
1854        } else {
1855            __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1856                     as_FloatRegister(Matcher::_regEncode[src_lo]));
1857        }
1858      } else {                    // fpr --> stack spill
1859        assert(dst_lo_rc == rc_stack, "spill to bad register class");
1860        __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
1861                 is64 ? __ D : __ S, dst_offset);
1862      }
1863      break;
1864    case rc_stack:
1865      if (dst_lo_rc == rc_int) {  // stack --> gpr load
1866        __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
1867      } else if (dst_lo_rc == rc_float) { // stack --> fpr load
1868        __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1869                   is64 ? __ D : __ S, src_offset);
1870      } else {                    // stack --> stack copy
1871        assert(dst_lo_rc == rc_stack, "spill to bad register class");
1872        __ unspill(rscratch1, is64, src_offset);
1873        __ spill(rscratch1, is64, dst_offset);
1874      }
1875      break;
1876    default:
1877      assert(false, "bad rc_class for spill");
1878      ShouldNotReachHere();
1879    }
1880  }
1881
1882  if (st) {
1883    st->print("spill ");
1884    if (src_lo_rc == rc_stack) {
1885      st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo));
1886    } else {
1887      st->print("%s -> ", Matcher::regName[src_lo]);
1888    }
1889    if (dst_lo_rc == rc_stack) {
1890      st->print("[sp, #%d]", ra_->reg2offset(dst_lo));
1891    } else {
1892      st->print("%s", Matcher::regName[dst_lo]);
1893    }
1894    if (bottom_type()->isa_vect() != NULL) {
1895      st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128);
1896    } else {
1897      st->print("\t# spill size = %d", is64 ? 64:32);
1898    }
1899  }
1900
1901  return 0;
1902
1903}
1904
1905#ifndef PRODUCT
1906void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1907  if (!ra_)
1908    st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1909  else
1910    implementation(NULL, ra_, false, st);
1911}
1912#endif
1913
1914void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1915  implementation(&cbuf, ra_, false, NULL);
1916}
1917
1918uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1919  return MachNode::size(ra_);
1920}
1921
1922//=============================================================================
1923
1924#ifndef PRODUCT
1925void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1926  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1927  int reg = ra_->get_reg_first(this);
1928  st->print("add %s, rsp, #%d]\t# box lock",
1929            Matcher::regName[reg], offset);
1930}
1931#endif
1932
1933void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1934  MacroAssembler _masm(&cbuf);
1935
1936  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1937  int reg    = ra_->get_encode(this);
1938
1939  // This add will handle any 24-bit signed offset. 24 bits allows an
1940  // 8 megabyte stack frame.
1941  __ add(as_Register(reg), sp, offset);
1942}
1943
1944uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1945  // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1946  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1947
1948  if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
1949    return NativeInstruction::instruction_size;
1950  } else {
1951    return 2 * NativeInstruction::instruction_size;
1952  }
1953}
1954
1955//=============================================================================
1956
1957#ifndef PRODUCT
1958void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1959{
1960  st->print_cr("# MachUEPNode");
1961  if (UseCompressedClassPointers) {
1962    st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1963    if (Universe::narrow_klass_shift() != 0) {
1964      st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1965    }
1966  } else {
1967   st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1968  }
1969  st->print_cr("\tcmp r0, rscratch1\t # Inline cache check");
1970  st->print_cr("\tbne, SharedRuntime::_ic_miss_stub");
1971}
1972#endif
1973
1974void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1975{
1976  // This is the unverified entry point.
1977  MacroAssembler _masm(&cbuf);
1978
1979  __ cmp_klass(j_rarg0, rscratch2, rscratch1);
1980  Label skip;
1981  // TODO
1982  // can we avoid this skip and still use a reloc?
1983  __ br(Assembler::EQ, skip);
1984  __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1985  __ bind(skip);
1986}
1987
1988uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1989{
1990  return MachNode::size(ra_);
1991}
1992
1993// REQUIRED EMIT CODE
1994
1995//=============================================================================
1996
1997// Emit exception handler code.
1998int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf)
1999{
2000  // mov rscratch1 #exception_blob_entry_point
2001  // br rscratch1
2002  // Note that the code buffer's insts_mark is always relative to insts.
2003  // That's why we must use the macroassembler to generate a handler.
2004  MacroAssembler _masm(&cbuf);
2005  address base = __ start_a_stub(size_exception_handler());
2006  if (base == NULL) {
2007    ciEnv::current()->record_failure("CodeCache is full");
2008    return 0;  // CodeBuffer::expand failed
2009  }
2010  int offset = __ offset();
2011  __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
2012  assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
2013  __ end_a_stub();
2014  return offset;
2015}
2016
2017// Emit deopt handler code.
2018int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf)
2019{
2020  // Note that the code buffer's insts_mark is always relative to insts.
2021  // That's why we must use the macroassembler to generate a handler.
2022  MacroAssembler _masm(&cbuf);
2023  address base = __ start_a_stub(size_deopt_handler());
2024  if (base == NULL) {
2025    ciEnv::current()->record_failure("CodeCache is full");
2026    return 0;  // CodeBuffer::expand failed
2027  }
2028  int offset = __ offset();
2029
2030  __ adr(lr, __ pc());
2031  __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
2032
2033  assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
2034  __ end_a_stub();
2035  return offset;
2036}
2037
2038// REQUIRED MATCHER CODE
2039
2040//=============================================================================
2041
2042const bool Matcher::match_rule_supported(int opcode) {
2043
2044  switch (opcode) {
2045  default:
2046    break;
2047  }
2048
2049  if (!has_match_rule(opcode)) {
2050    return false;
2051  }
2052
2053  return true;  // Per default match rules are supported.
2054}
2055
2056const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
2057
2058  // TODO
2059  // identify extra cases that we might want to provide match rules for
2060  // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
2061  bool ret_value = match_rule_supported(opcode);
2062  // Add rules here.
2063
2064  return ret_value;  // Per default match rules are supported.
2065}
2066
2067const bool Matcher::has_predicated_vectors(void) {
2068  return false;
2069}
2070
2071const int Matcher::float_pressure(int default_pressure_threshold) {
2072  return default_pressure_threshold;
2073}
2074
2075int Matcher::regnum_to_fpu_offset(int regnum)
2076{
2077  Unimplemented();
2078  return 0;
2079}
2080
2081// Is this branch offset short enough that a short branch can be used?
2082//
2083// NOTE: If the platform does not provide any short branch variants, then
2084//       this method should return false for offset 0.
2085bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2086  // The passed offset is relative to address of the branch.
2087
2088  return (-32768 <= offset && offset < 32768);
2089}
2090
2091const bool Matcher::isSimpleConstant64(jlong value) {
2092  // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
2093  // Probably always true, even if a temp register is required.
2094  return true;
2095}
2096
2097// true just means we have fast l2f conversion
2098const bool Matcher::convL2FSupported(void) {
2099  return true;
2100}
2101
2102// Vector width in bytes.
2103const int Matcher::vector_width_in_bytes(BasicType bt) {
2104  int size = MIN2(16,(int)MaxVectorSize);
2105  // Minimum 2 values in vector
2106  if (size < 2*type2aelembytes(bt)) size = 0;
2107  // But never < 4
2108  if (size < 4) size = 0;
2109  return size;
2110}
2111
2112// Limits on vector size (number of elements) loaded into vector.
2113const int Matcher::max_vector_size(const BasicType bt) {
2114  return vector_width_in_bytes(bt)/type2aelembytes(bt);
2115}
2116const int Matcher::min_vector_size(const BasicType bt) {
2117//  For the moment limit the vector size to 8 bytes
2118    int size = 8 / type2aelembytes(bt);
2119    if (size < 2) size = 2;
2120    return size;
2121}
2122
2123// Vector ideal reg.
2124const uint Matcher::vector_ideal_reg(int len) {
2125  switch(len) {
2126    case  8: return Op_VecD;
2127    case 16: return Op_VecX;
2128  }
2129  ShouldNotReachHere();
2130  return 0;
2131}
2132
2133const uint Matcher::vector_shift_count_ideal_reg(int size) {
2134  switch(size) {
2135    case  8: return Op_VecD;
2136    case 16: return Op_VecX;
2137  }
2138  ShouldNotReachHere();
2139  return 0;
2140}
2141
2142// AES support not yet implemented
2143const bool Matcher::pass_original_key_for_aes() {
2144  return false;
2145}
2146
2147// aarch64 supports misaligned vectors store/load.
2148const bool Matcher::misaligned_vectors_ok() {
2149  return true;
2150}
2151
2152// false => size gets scaled to BytesPerLong, ok.
2153const bool Matcher::init_array_count_is_in_bytes = false;
2154
2155// Use conditional move (CMOVL)
2156const int Matcher::long_cmove_cost() {
2157  // long cmoves are no more expensive than int cmoves
2158  return 0;
2159}
2160
2161const int Matcher::float_cmove_cost() {
2162  // float cmoves are no more expensive than int cmoves
2163  return 0;
2164}
2165
2166// Does the CPU require late expand (see block.cpp for description of late expand)?
2167const bool Matcher::require_postalloc_expand = false;
2168
2169// Do we need to mask the count passed to shift instructions or does
2170// the cpu only look at the lower 5/6 bits anyway?
2171const bool Matcher::need_masked_shift_count = false;
2172
2173// This affects two different things:
2174//  - how Decode nodes are matched
2175//  - how ImplicitNullCheck opportunities are recognized
2176// If true, the matcher will try to remove all Decodes and match them
2177// (as operands) into nodes. NullChecks are not prepared to deal with
2178// Decodes by final_graph_reshaping().
2179// If false, final_graph_reshaping() forces the decode behind the Cmp
2180// for a NullCheck. The matcher matches the Decode node into a register.
2181// Implicit_null_check optimization moves the Decode along with the
2182// memory operation back up before the NullCheck.
2183bool Matcher::narrow_oop_use_complex_address() {
2184  return Universe::narrow_oop_shift() == 0;
2185}
2186
2187bool Matcher::narrow_klass_use_complex_address() {
2188// TODO
2189// decide whether we need to set this to true
2190  return false;
2191}
2192
2193bool Matcher::const_oop_prefer_decode() {
2194  // Prefer ConN+DecodeN over ConP in simple compressed oops mode.
2195  return Universe::narrow_oop_base() == NULL;
2196}
2197
2198bool Matcher::const_klass_prefer_decode() {
2199  // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
2200  return Universe::narrow_klass_base() == NULL;
2201}
2202
2203// Is it better to copy float constants, or load them directly from
2204// memory?  Intel can load a float constant from a direct address,
2205// requiring no extra registers.  Most RISCs will have to materialize
2206// an address into a register first, so they would do better to copy
2207// the constant from stack.
2208const bool Matcher::rematerialize_float_constants = false;
2209
2210// If CPU can load and store mis-aligned doubles directly then no
2211// fixup is needed.  Else we split the double into 2 integer pieces
2212// and move it piece-by-piece.  Only happens when passing doubles into
2213// C code as the Java calling convention forces doubles to be aligned.
2214const bool Matcher::misaligned_doubles_ok = true;
2215
2216// No-op on amd64
2217void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
2218  Unimplemented();
2219}
2220
2221// Advertise here if the CPU requires explicit rounding operations to
2222// implement the UseStrictFP mode.
2223const bool Matcher::strict_fp_requires_explicit_rounding = false;
2224
2225// Are floats converted to double when stored to stack during
2226// deoptimization?
2227bool Matcher::float_in_double() { return false; }
2228
2229// Do ints take an entire long register or just half?
2230// The relevant question is how the int is callee-saved:
2231// the whole long is written but de-opt'ing will have to extract
2232// the relevant 32 bits.
2233const bool Matcher::int_in_long = true;
2234
2235// Return whether or not this register is ever used as an argument.
2236// This function is used on startup to build the trampoline stubs in
2237// generateOptoStub.  Registers not mentioned will be killed by the VM
2238// call in the trampoline, and arguments in those registers not be
2239// available to the callee.
2240bool Matcher::can_be_java_arg(int reg)
2241{
2242  return
2243    reg ==  R0_num || reg == R0_H_num ||
2244    reg ==  R1_num || reg == R1_H_num ||
2245    reg ==  R2_num || reg == R2_H_num ||
2246    reg ==  R3_num || reg == R3_H_num ||
2247    reg ==  R4_num || reg == R4_H_num ||
2248    reg ==  R5_num || reg == R5_H_num ||
2249    reg ==  R6_num || reg == R6_H_num ||
2250    reg ==  R7_num || reg == R7_H_num ||
2251    reg ==  V0_num || reg == V0_H_num ||
2252    reg ==  V1_num || reg == V1_H_num ||
2253    reg ==  V2_num || reg == V2_H_num ||
2254    reg ==  V3_num || reg == V3_H_num ||
2255    reg ==  V4_num || reg == V4_H_num ||
2256    reg ==  V5_num || reg == V5_H_num ||
2257    reg ==  V6_num || reg == V6_H_num ||
2258    reg ==  V7_num || reg == V7_H_num;
2259}
2260
2261bool Matcher::is_spillable_arg(int reg)
2262{
2263  return can_be_java_arg(reg);
2264}
2265
2266bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
2267  return false;
2268}
2269
2270RegMask Matcher::divI_proj_mask() {
2271  ShouldNotReachHere();
2272  return RegMask();
2273}
2274
2275// Register for MODI projection of divmodI.
2276RegMask Matcher::modI_proj_mask() {
2277  ShouldNotReachHere();
2278  return RegMask();
2279}
2280
2281// Register for DIVL projection of divmodL.
2282RegMask Matcher::divL_proj_mask() {
2283  ShouldNotReachHere();
2284  return RegMask();
2285}
2286
2287// Register for MODL projection of divmodL.
2288RegMask Matcher::modL_proj_mask() {
2289  ShouldNotReachHere();
2290  return RegMask();
2291}
2292
2293const RegMask Matcher::method_handle_invoke_SP_save_mask() {
2294  return FP_REG_mask();
2295}
2296
2297bool size_fits_all_mem_uses(AddPNode* addp, int shift) {
2298  for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) {
2299    Node* u = addp->fast_out(i);
2300    if (u->is_Mem()) {
2301      int opsize = u->as_Mem()->memory_size();
2302      assert(opsize > 0, "unexpected memory operand size");
2303      if (u->as_Mem()->memory_size() != (1<<shift)) {
2304        return false;
2305      }
2306    }
2307  }
2308  return true;
2309}
2310
2311const bool Matcher::convi2l_type_required = false;
2312
2313// Should the Matcher clone shifts on addressing modes, expecting them
2314// to be subsumed into complex addressing expressions or compute them
2315// into registers?
2316bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
2317  if (clone_base_plus_offset_address(m, mstack, address_visited)) {
2318    return true;
2319  }
2320
2321  Node *off = m->in(AddPNode::Offset);
2322  if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() &&
2323      size_fits_all_mem_uses(m, off->in(2)->get_int()) &&
2324      // Are there other uses besides address expressions?
2325      !is_visited(off)) {
2326    address_visited.set(off->_idx); // Flag as address_visited
2327    mstack.push(off->in(2), Visit);
2328    Node *conv = off->in(1);
2329    if (conv->Opcode() == Op_ConvI2L &&
2330        // Are there other uses besides address expressions?
2331        !is_visited(conv)) {
2332      address_visited.set(conv->_idx); // Flag as address_visited
2333      mstack.push(conv->in(1), Pre_Visit);
2334    } else {
2335      mstack.push(conv, Pre_Visit);
2336    }
2337    address_visited.test_set(m->_idx); // Flag as address_visited
2338    mstack.push(m->in(AddPNode::Address), Pre_Visit);
2339    mstack.push(m->in(AddPNode::Base), Pre_Visit);
2340    return true;
2341  } else if (off->Opcode() == Op_ConvI2L &&
2342             // Are there other uses besides address expressions?
2343             !is_visited(off)) {
2344    address_visited.test_set(m->_idx); // Flag as address_visited
2345    address_visited.set(off->_idx); // Flag as address_visited
2346    mstack.push(off->in(1), Pre_Visit);
2347    mstack.push(m->in(AddPNode::Address), Pre_Visit);
2348    mstack.push(m->in(AddPNode::Base), Pre_Visit);
2349    return true;
2350  }
2351  return false;
2352}
2353
2354void Compile::reshape_address(AddPNode* addp) {
2355}
2356
2357
2358#define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN)      \
2359  MacroAssembler _masm(&cbuf);                                          \
2360  {                                                                     \
2361    guarantee(INDEX == -1, "mode not permitted for volatile");          \
2362    guarantee(DISP == 0, "mode not permitted for volatile");            \
2363    guarantee(SCALE == 0, "mode not permitted for volatile");           \
2364    __ INSN(REG, as_Register(BASE));                                    \
2365  }
2366
2367typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr);
2368typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr);
2369typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
2370                                  MacroAssembler::SIMD_RegVariant T, const Address &adr);
2371
2372  // Used for all non-volatile memory accesses.  The use of
2373  // $mem->opcode() to discover whether this pattern uses sign-extended
2374  // offsets is something of a kludge.
2375  static void loadStore(MacroAssembler masm, mem_insn insn,
2376                         Register reg, int opcode,
2377                         Register base, int index, int size, int disp)
2378  {
2379    Address::extend scale;
2380
2381    // Hooboy, this is fugly.  We need a way to communicate to the
2382    // encoder that the index needs to be sign extended, so we have to
2383    // enumerate all the cases.
2384    switch (opcode) {
2385    case INDINDEXSCALEDI2L:
2386    case INDINDEXSCALEDI2LN:
2387    case INDINDEXI2L:
2388    case INDINDEXI2LN:
2389      scale = Address::sxtw(size);
2390      break;
2391    default:
2392      scale = Address::lsl(size);
2393    }
2394
2395    if (index == -1) {
2396      (masm.*insn)(reg, Address(base, disp));
2397    } else {
2398      assert(disp == 0, "unsupported address mode: disp = %d", disp);
2399      (masm.*insn)(reg, Address(base, as_Register(index), scale));
2400    }
2401  }
2402
2403  static void loadStore(MacroAssembler masm, mem_float_insn insn,
2404                         FloatRegister reg, int opcode,
2405                         Register base, int index, int size, int disp)
2406  {
2407    Address::extend scale;
2408
2409    switch (opcode) {
2410    case INDINDEXSCALEDI2L:
2411    case INDINDEXSCALEDI2LN:
2412      scale = Address::sxtw(size);
2413      break;
2414    default:
2415      scale = Address::lsl(size);
2416    }
2417
2418     if (index == -1) {
2419      (masm.*insn)(reg, Address(base, disp));
2420    } else {
2421      assert(disp == 0, "unsupported address mode: disp = %d", disp);
2422      (masm.*insn)(reg, Address(base, as_Register(index), scale));
2423    }
2424  }
2425
2426  static void loadStore(MacroAssembler masm, mem_vector_insn insn,
2427                         FloatRegister reg, MacroAssembler::SIMD_RegVariant T,
2428                         int opcode, Register base, int index, int size, int disp)
2429  {
2430    if (index == -1) {
2431      (masm.*insn)(reg, T, Address(base, disp));
2432    } else {
2433      assert(disp == 0, "unsupported address mode");
2434      (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size)));
2435    }
2436  }
2437
2438%}
2439
2440
2441
2442//----------ENCODING BLOCK-----------------------------------------------------
2443// This block specifies the encoding classes used by the compiler to
2444// output byte streams.  Encoding classes are parameterized macros
2445// used by Machine Instruction Nodes in order to generate the bit
2446// encoding of the instruction.  Operands specify their base encoding
2447// interface with the interface keyword.  There are currently
2448// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
2449// COND_INTER.  REG_INTER causes an operand to generate a function
2450// which returns its register number when queried.  CONST_INTER causes
2451// an operand to generate a function which returns the value of the
2452// constant when queried.  MEMORY_INTER causes an operand to generate
2453// four functions which return the Base Register, the Index Register,
2454// the Scale Value, and the Offset Value of the operand when queried.
2455// COND_INTER causes an operand to generate six functions which return
2456// the encoding code (ie - encoding bits for the instruction)
2457// associated with each basic boolean condition for a conditional
2458// instruction.
2459//
2460// Instructions specify two basic values for encoding.  Again, a
2461// function is available to check if the constant displacement is an
2462// oop. They use the ins_encode keyword to specify their encoding
2463// classes (which must be a sequence of enc_class names, and their
2464// parameters, specified in the encoding block), and they use the
2465// opcode keyword to specify, in order, their primary, secondary, and
2466// tertiary opcode.  Only the opcode sections which a particular
2467// instruction needs for encoding need to be specified.
2468encode %{
2469  // Build emit functions for each basic byte or larger field in the
2470  // intel encoding scheme (opcode, rm, sib, immediate), and call them
2471  // from C++ code in the enc_class source block.  Emit functions will
2472  // live in the main source block for now.  In future, we can
2473  // generalize this by adding a syntax that specifies the sizes of
2474  // fields in an order, so that the adlc can build the emit functions
2475  // automagically
2476
2477  // catch all for unimplemented encodings
2478  enc_class enc_unimplemented %{
2479    MacroAssembler _masm(&cbuf);
2480    __ unimplemented("C2 catch all");
2481  %}
2482
2483  // BEGIN Non-volatile memory access
2484
2485  enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{
2486    Register dst_reg = as_Register($dst$$reg);
2487    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(),
2488               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2489  %}
2490
2491  enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{
2492    Register dst_reg = as_Register($dst$$reg);
2493    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(),
2494               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2495  %}
2496
2497  enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{
2498    Register dst_reg = as_Register($dst$$reg);
2499    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2500               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2501  %}
2502
2503  enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{
2504    Register dst_reg = as_Register($dst$$reg);
2505    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2506               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2507  %}
2508
2509  enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{
2510    Register dst_reg = as_Register($dst$$reg);
2511    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(),
2512               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2513  %}
2514
2515  enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{
2516    Register dst_reg = as_Register($dst$$reg);
2517    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(),
2518               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2519  %}
2520
2521  enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{
2522    Register dst_reg = as_Register($dst$$reg);
2523    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2524               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2525  %}
2526
2527  enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{
2528    Register dst_reg = as_Register($dst$$reg);
2529    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2530               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2531  %}
2532
2533  enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{
2534    Register dst_reg = as_Register($dst$$reg);
2535    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2536               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2537  %}
2538
2539  enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{
2540    Register dst_reg = as_Register($dst$$reg);
2541    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2542               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2543  %}
2544
2545  enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{
2546    Register dst_reg = as_Register($dst$$reg);
2547    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(),
2548               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2549  %}
2550
2551  enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{
2552    Register dst_reg = as_Register($dst$$reg);
2553    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(),
2554               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2555  %}
2556
2557  enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{
2558    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2559    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(),
2560               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2561  %}
2562
2563  enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{
2564    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2565    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(),
2566               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2567  %}
2568
2569  enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{
2570    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2571    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S,
2572       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2573  %}
2574
2575  enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{
2576    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2577    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D,
2578       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2579  %}
2580
2581  enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{
2582    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2583    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q,
2584       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2585  %}
2586
2587  enc_class aarch64_enc_strb(iRegI src, memory mem) %{
2588    Register src_reg = as_Register($src$$reg);
2589    loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(),
2590               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2591  %}
2592
2593  enc_class aarch64_enc_strb0(memory mem) %{
2594    MacroAssembler _masm(&cbuf);
2595    loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(),
2596               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2597  %}
2598
2599  enc_class aarch64_enc_strb0_ordered(memory mem) %{
2600    MacroAssembler _masm(&cbuf);
2601    __ membar(Assembler::StoreStore);
2602    loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(),
2603               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2604  %}
2605
2606  enc_class aarch64_enc_strh(iRegI src, memory mem) %{
2607    Register src_reg = as_Register($src$$reg);
2608    loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(),
2609               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2610  %}
2611
2612  enc_class aarch64_enc_strh0(memory mem) %{
2613    MacroAssembler _masm(&cbuf);
2614    loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(),
2615               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2616  %}
2617
2618  enc_class aarch64_enc_strw(iRegI src, memory mem) %{
2619    Register src_reg = as_Register($src$$reg);
2620    loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(),
2621               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2622  %}
2623
2624  enc_class aarch64_enc_strw0(memory mem) %{
2625    MacroAssembler _masm(&cbuf);
2626    loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(),
2627               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2628  %}
2629
2630  enc_class aarch64_enc_str(iRegL src, memory mem) %{
2631    Register src_reg = as_Register($src$$reg);
2632    // we sometimes get asked to store the stack pointer into the
2633    // current thread -- we cannot do that directly on AArch64
2634    if (src_reg == r31_sp) {
2635      MacroAssembler _masm(&cbuf);
2636      assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
2637      __ mov(rscratch2, sp);
2638      src_reg = rscratch2;
2639    }
2640    loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(),
2641               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2642  %}
2643
2644  enc_class aarch64_enc_str0(memory mem) %{
2645    MacroAssembler _masm(&cbuf);
2646    loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(),
2647               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2648  %}
2649
2650  enc_class aarch64_enc_strs(vRegF src, memory mem) %{
2651    FloatRegister src_reg = as_FloatRegister($src$$reg);
2652    loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(),
2653               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2654  %}
2655
2656  enc_class aarch64_enc_strd(vRegD src, memory mem) %{
2657    FloatRegister src_reg = as_FloatRegister($src$$reg);
2658    loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(),
2659               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2660  %}
2661
2662  enc_class aarch64_enc_strvS(vecD src, memory mem) %{
2663    FloatRegister src_reg = as_FloatRegister($src$$reg);
2664    loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S,
2665       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2666  %}
2667
2668  enc_class aarch64_enc_strvD(vecD src, memory mem) %{
2669    FloatRegister src_reg = as_FloatRegister($src$$reg);
2670    loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D,
2671       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2672  %}
2673
2674  enc_class aarch64_enc_strvQ(vecX src, memory mem) %{
2675    FloatRegister src_reg = as_FloatRegister($src$$reg);
2676    loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q,
2677       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2678  %}
2679
2680  // END Non-volatile memory access
2681
2682  // volatile loads and stores
2683
2684  enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{
2685    MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2686                 rscratch1, stlrb);
2687  %}
2688
2689  enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{
2690    MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2691                 rscratch1, stlrh);
2692  %}
2693
2694  enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{
2695    MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2696                 rscratch1, stlrw);
2697  %}
2698
2699
2700  enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{
2701    Register dst_reg = as_Register($dst$$reg);
2702    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2703             rscratch1, ldarb);
2704    __ sxtbw(dst_reg, dst_reg);
2705  %}
2706
2707  enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{
2708    Register dst_reg = as_Register($dst$$reg);
2709    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2710             rscratch1, ldarb);
2711    __ sxtb(dst_reg, dst_reg);
2712  %}
2713
2714  enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{
2715    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2716             rscratch1, ldarb);
2717  %}
2718
2719  enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{
2720    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2721             rscratch1, ldarb);
2722  %}
2723
2724  enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{
2725    Register dst_reg = as_Register($dst$$reg);
2726    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2727             rscratch1, ldarh);
2728    __ sxthw(dst_reg, dst_reg);
2729  %}
2730
2731  enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{
2732    Register dst_reg = as_Register($dst$$reg);
2733    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2734             rscratch1, ldarh);
2735    __ sxth(dst_reg, dst_reg);
2736  %}
2737
2738  enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{
2739    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2740             rscratch1, ldarh);
2741  %}
2742
2743  enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{
2744    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2745             rscratch1, ldarh);
2746  %}
2747
2748  enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{
2749    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2750             rscratch1, ldarw);
2751  %}
2752
2753  enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{
2754    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2755             rscratch1, ldarw);
2756  %}
2757
2758  enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{
2759    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2760             rscratch1, ldar);
2761  %}
2762
2763  enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{
2764    MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2765             rscratch1, ldarw);
2766    __ fmovs(as_FloatRegister($dst$$reg), rscratch1);
2767  %}
2768
2769  enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{
2770    MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2771             rscratch1, ldar);
2772    __ fmovd(as_FloatRegister($dst$$reg), rscratch1);
2773  %}
2774
2775  enc_class aarch64_enc_stlr(iRegL src, memory mem) %{
2776    Register src_reg = as_Register($src$$reg);
2777    // we sometimes get asked to store the stack pointer into the
2778    // current thread -- we cannot do that directly on AArch64
2779    if (src_reg == r31_sp) {
2780        MacroAssembler _masm(&cbuf);
2781      assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
2782      __ mov(rscratch2, sp);
2783      src_reg = rscratch2;
2784    }
2785    MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2786                 rscratch1, stlr);
2787  %}
2788
2789  enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{
2790    {
2791      MacroAssembler _masm(&cbuf);
2792      FloatRegister src_reg = as_FloatRegister($src$$reg);
2793      __ fmovs(rscratch2, src_reg);
2794    }
2795    MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2796                 rscratch1, stlrw);
2797  %}
2798
2799  enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{
2800    {
2801      MacroAssembler _masm(&cbuf);
2802      FloatRegister src_reg = as_FloatRegister($src$$reg);
2803      __ fmovd(rscratch2, src_reg);
2804    }
2805    MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2806                 rscratch1, stlr);
2807  %}
2808
2809  // synchronized read/update encodings
2810
2811  enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{
2812    MacroAssembler _masm(&cbuf);
2813    Register dst_reg = as_Register($dst$$reg);
2814    Register base = as_Register($mem$$base);
2815    int index = $mem$$index;
2816    int scale = $mem$$scale;
2817    int disp = $mem$$disp;
2818    if (index == -1) {
2819       if (disp != 0) {
2820        __ lea(rscratch1, Address(base, disp));
2821        __ ldaxr(dst_reg, rscratch1);
2822      } else {
2823        // TODO
2824        // should we ever get anything other than this case?
2825        __ ldaxr(dst_reg, base);
2826      }
2827    } else {
2828      Register index_reg = as_Register(index);
2829      if (disp == 0) {
2830        __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale)));
2831        __ ldaxr(dst_reg, rscratch1);
2832      } else {
2833        __ lea(rscratch1, Address(base, disp));
2834        __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale)));
2835        __ ldaxr(dst_reg, rscratch1);
2836      }
2837    }
2838  %}
2839
2840  enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{
2841    MacroAssembler _masm(&cbuf);
2842    Register src_reg = as_Register($src$$reg);
2843    Register base = as_Register($mem$$base);
2844    int index = $mem$$index;
2845    int scale = $mem$$scale;
2846    int disp = $mem$$disp;
2847    if (index == -1) {
2848       if (disp != 0) {
2849        __ lea(rscratch2, Address(base, disp));
2850        __ stlxr(rscratch1, src_reg, rscratch2);
2851      } else {
2852        // TODO
2853        // should we ever get anything other than this case?
2854        __ stlxr(rscratch1, src_reg, base);
2855      }
2856    } else {
2857      Register index_reg = as_Register(index);
2858      if (disp == 0) {
2859        __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale)));
2860        __ stlxr(rscratch1, src_reg, rscratch2);
2861      } else {
2862        __ lea(rscratch2, Address(base, disp));
2863        __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale)));
2864        __ stlxr(rscratch1, src_reg, rscratch2);
2865      }
2866    }
2867    __ cmpw(rscratch1, zr);
2868  %}
2869
2870  enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
2871    MacroAssembler _masm(&cbuf);
2872    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2873    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2874               Assembler::xword, /*acquire*/ false, /*release*/ true,
2875               /*weak*/ false, noreg);
2876  %}
2877
2878  enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2879    MacroAssembler _masm(&cbuf);
2880    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2881    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2882               Assembler::word, /*acquire*/ false, /*release*/ true,
2883               /*weak*/ false, noreg);
2884  %}
2885
2886  enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2887    MacroAssembler _masm(&cbuf);
2888    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2889    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2890               Assembler::halfword, /*acquire*/ false, /*release*/ true,
2891               /*weak*/ false, noreg);
2892  %}
2893
2894  enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2895    MacroAssembler _masm(&cbuf);
2896    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2897    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2898               Assembler::byte, /*acquire*/ false, /*release*/ true,
2899               /*weak*/ false, noreg);
2900  %}
2901
2902
2903  // The only difference between aarch64_enc_cmpxchg and
2904  // aarch64_enc_cmpxchg_acq is that we use load-acquire in the
2905  // CompareAndSwap sequence to serve as a barrier on acquiring a
2906  // lock.
2907  enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
2908    MacroAssembler _masm(&cbuf);
2909    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2910    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2911               Assembler::xword, /*acquire*/ true, /*release*/ true,
2912               /*weak*/ false, noreg);
2913  %}
2914
2915  enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2916    MacroAssembler _masm(&cbuf);
2917    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2918    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2919               Assembler::word, /*acquire*/ true, /*release*/ true,
2920               /*weak*/ false, noreg);
2921  %}
2922
2923  enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2924    MacroAssembler _masm(&cbuf);
2925    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2926    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2927               Assembler::halfword, /*acquire*/ true, /*release*/ true,
2928               /*weak*/ false, noreg);
2929  %}
2930
2931  enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2932    MacroAssembler _masm(&cbuf);
2933    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2934    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2935               Assembler::byte, /*acquire*/ true, /*release*/ true,
2936               /*weak*/ false, noreg);
2937  %}
2938
2939  // auxiliary used for CompareAndSwapX to set result register
2940  enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
2941    MacroAssembler _masm(&cbuf);
2942    Register res_reg = as_Register($res$$reg);
2943    __ cset(res_reg, Assembler::EQ);
2944  %}
2945
2946  // prefetch encodings
2947
2948  enc_class aarch64_enc_prefetchw(memory mem) %{
2949    MacroAssembler _masm(&cbuf);
2950    Register base = as_Register($mem$$base);
2951    int index = $mem$$index;
2952    int scale = $mem$$scale;
2953    int disp = $mem$$disp;
2954    if (index == -1) {
2955      __ prfm(Address(base, disp), PSTL1KEEP);
2956    } else {
2957      Register index_reg = as_Register(index);
2958      if (disp == 0) {
2959        __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP);
2960      } else {
2961        __ lea(rscratch1, Address(base, disp));
2962	__ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP);
2963      }
2964    }
2965  %}
2966
2967  /// mov envcodings
2968
2969  enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{
2970    MacroAssembler _masm(&cbuf);
2971    uint32_t con = (uint32_t)$src$$constant;
2972    Register dst_reg = as_Register($dst$$reg);
2973    if (con == 0) {
2974      __ movw(dst_reg, zr);
2975    } else {
2976      __ movw(dst_reg, con);
2977    }
2978  %}
2979
2980  enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{
2981    MacroAssembler _masm(&cbuf);
2982    Register dst_reg = as_Register($dst$$reg);
2983    uint64_t con = (uint64_t)$src$$constant;
2984    if (con == 0) {
2985      __ mov(dst_reg, zr);
2986    } else {
2987      __ mov(dst_reg, con);
2988    }
2989  %}
2990
2991  enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
2992    MacroAssembler _masm(&cbuf);
2993    Register dst_reg = as_Register($dst$$reg);
2994    address con = (address)$src$$constant;
2995    if (con == NULL || con == (address)1) {
2996      ShouldNotReachHere();
2997    } else {
2998      relocInfo::relocType rtype = $src->constant_reloc();
2999      if (rtype == relocInfo::oop_type) {
3000        __ movoop(dst_reg, (jobject)con, /*immediate*/true);
3001      } else if (rtype == relocInfo::metadata_type) {
3002        __ mov_metadata(dst_reg, (Metadata*)con);
3003      } else {
3004        assert(rtype == relocInfo::none, "unexpected reloc type");
3005        if (con < (address)(uintptr_t)os::vm_page_size()) {
3006          __ mov(dst_reg, con);
3007        } else {
3008          uintptr_t offset;
3009          __ adrp(dst_reg, con, offset);
3010          __ add(dst_reg, dst_reg, offset);
3011        }
3012      }
3013    }
3014  %}
3015
3016  enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{
3017    MacroAssembler _masm(&cbuf);
3018    Register dst_reg = as_Register($dst$$reg);
3019    __ mov(dst_reg, zr);
3020  %}
3021
3022  enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{
3023    MacroAssembler _masm(&cbuf);
3024    Register dst_reg = as_Register($dst$$reg);
3025    __ mov(dst_reg, (uint64_t)1);
3026  %}
3027
3028  enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{
3029    MacroAssembler _masm(&cbuf);
3030    address page = (address)$src$$constant;
3031    Register dst_reg = as_Register($dst$$reg);
3032    uint64_t off;
3033    __ adrp(dst_reg, Address(page, relocInfo::poll_type), off);
3034    assert(off == 0, "assumed offset == 0");
3035  %}
3036
3037  enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{
3038    MacroAssembler _masm(&cbuf);
3039    __ load_byte_map_base($dst$$Register);
3040  %}
3041
3042  enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{
3043    MacroAssembler _masm(&cbuf);
3044    Register dst_reg = as_Register($dst$$reg);
3045    address con = (address)$src$$constant;
3046    if (con == NULL) {
3047      ShouldNotReachHere();
3048    } else {
3049      relocInfo::relocType rtype = $src->constant_reloc();
3050      assert(rtype == relocInfo::oop_type, "unexpected reloc type");
3051      __ set_narrow_oop(dst_reg, (jobject)con);
3052    }
3053  %}
3054
3055  enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{
3056    MacroAssembler _masm(&cbuf);
3057    Register dst_reg = as_Register($dst$$reg);
3058    __ mov(dst_reg, zr);
3059  %}
3060
3061  enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{
3062    MacroAssembler _masm(&cbuf);
3063    Register dst_reg = as_Register($dst$$reg);
3064    address con = (address)$src$$constant;
3065    if (con == NULL) {
3066      ShouldNotReachHere();
3067    } else {
3068      relocInfo::relocType rtype = $src->constant_reloc();
3069      assert(rtype == relocInfo::metadata_type, "unexpected reloc type");
3070      __ set_narrow_klass(dst_reg, (Klass *)con);
3071    }
3072  %}
3073
3074  // arithmetic encodings
3075
3076  enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{
3077    MacroAssembler _masm(&cbuf);
3078    Register dst_reg = as_Register($dst$$reg);
3079    Register src_reg = as_Register($src1$$reg);
3080    int32_t con = (int32_t)$src2$$constant;
3081    // add has primary == 0, subtract has primary == 1
3082    if ($primary) { con = -con; }
3083    if (con < 0) {
3084      __ subw(dst_reg, src_reg, -con);
3085    } else {
3086      __ addw(dst_reg, src_reg, con);
3087    }
3088  %}
3089
3090  enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{
3091    MacroAssembler _masm(&cbuf);
3092    Register dst_reg = as_Register($dst$$reg);
3093    Register src_reg = as_Register($src1$$reg);
3094    int32_t con = (int32_t)$src2$$constant;
3095    // add has primary == 0, subtract has primary == 1
3096    if ($primary) { con = -con; }
3097    if (con < 0) {
3098      __ sub(dst_reg, src_reg, -con);
3099    } else {
3100      __ add(dst_reg, src_reg, con);
3101    }
3102  %}
3103
3104  enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{
3105    MacroAssembler _masm(&cbuf);
3106   Register dst_reg = as_Register($dst$$reg);
3107   Register src1_reg = as_Register($src1$$reg);
3108   Register src2_reg = as_Register($src2$$reg);
3109    __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1);
3110  %}
3111
3112  enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{
3113    MacroAssembler _masm(&cbuf);
3114   Register dst_reg = as_Register($dst$$reg);
3115   Register src1_reg = as_Register($src1$$reg);
3116   Register src2_reg = as_Register($src2$$reg);
3117    __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1);
3118  %}
3119
3120  enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{
3121    MacroAssembler _masm(&cbuf);
3122   Register dst_reg = as_Register($dst$$reg);
3123   Register src1_reg = as_Register($src1$$reg);
3124   Register src2_reg = as_Register($src2$$reg);
3125    __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1);
3126  %}
3127
3128  enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{
3129    MacroAssembler _masm(&cbuf);
3130   Register dst_reg = as_Register($dst$$reg);
3131   Register src1_reg = as_Register($src1$$reg);
3132   Register src2_reg = as_Register($src2$$reg);
3133    __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1);
3134  %}
3135
3136  // compare instruction encodings
3137
3138  enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{
3139    MacroAssembler _masm(&cbuf);
3140    Register reg1 = as_Register($src1$$reg);
3141    Register reg2 = as_Register($src2$$reg);
3142    __ cmpw(reg1, reg2);
3143  %}
3144
3145  enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{
3146    MacroAssembler _masm(&cbuf);
3147    Register reg = as_Register($src1$$reg);
3148    int32_t val = $src2$$constant;
3149    if (val >= 0) {
3150      __ subsw(zr, reg, val);
3151    } else {
3152      __ addsw(zr, reg, -val);
3153    }
3154  %}
3155
3156  enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{
3157    MacroAssembler _masm(&cbuf);
3158    Register reg1 = as_Register($src1$$reg);
3159    uint32_t val = (uint32_t)$src2$$constant;
3160    __ movw(rscratch1, val);
3161    __ cmpw(reg1, rscratch1);
3162  %}
3163
3164  enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{
3165    MacroAssembler _masm(&cbuf);
3166    Register reg1 = as_Register($src1$$reg);
3167    Register reg2 = as_Register($src2$$reg);
3168    __ cmp(reg1, reg2);
3169  %}
3170
3171  enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{
3172    MacroAssembler _masm(&cbuf);
3173    Register reg = as_Register($src1$$reg);
3174    int64_t val = $src2$$constant;
3175    if (val >= 0) {
3176      __ subs(zr, reg, val);
3177    } else if (val != -val) {
3178      __ adds(zr, reg, -val);
3179    } else {
3180    // aargh, Long.MIN_VALUE is a special case
3181      __ orr(rscratch1, zr, (uint64_t)val);
3182      __ subs(zr, reg, rscratch1);
3183    }
3184  %}
3185
3186  enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{
3187    MacroAssembler _masm(&cbuf);
3188    Register reg1 = as_Register($src1$$reg);
3189    uint64_t val = (uint64_t)$src2$$constant;
3190    __ mov(rscratch1, val);
3191    __ cmp(reg1, rscratch1);
3192  %}
3193
3194  enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{
3195    MacroAssembler _masm(&cbuf);
3196    Register reg1 = as_Register($src1$$reg);
3197    Register reg2 = as_Register($src2$$reg);
3198    __ cmp(reg1, reg2);
3199  %}
3200
3201  enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{
3202    MacroAssembler _masm(&cbuf);
3203    Register reg1 = as_Register($src1$$reg);
3204    Register reg2 = as_Register($src2$$reg);
3205    __ cmpw(reg1, reg2);
3206  %}
3207
3208  enc_class aarch64_enc_testp(iRegP src) %{
3209    MacroAssembler _masm(&cbuf);
3210    Register reg = as_Register($src$$reg);
3211    __ cmp(reg, zr);
3212  %}
3213
3214  enc_class aarch64_enc_testn(iRegN src) %{
3215    MacroAssembler _masm(&cbuf);
3216    Register reg = as_Register($src$$reg);
3217    __ cmpw(reg, zr);
3218  %}
3219
3220  enc_class aarch64_enc_b(label lbl) %{
3221    MacroAssembler _masm(&cbuf);
3222    Label *L = $lbl$$label;
3223    __ b(*L);
3224  %}
3225
3226  enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{
3227    MacroAssembler _masm(&cbuf);
3228    Label *L = $lbl$$label;
3229    __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3230  %}
3231
3232  enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{
3233    MacroAssembler _masm(&cbuf);
3234    Label *L = $lbl$$label;
3235    __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3236  %}
3237
3238  enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result)
3239  %{
3240     Register sub_reg = as_Register($sub$$reg);
3241     Register super_reg = as_Register($super$$reg);
3242     Register temp_reg = as_Register($temp$$reg);
3243     Register result_reg = as_Register($result$$reg);
3244
3245     Label miss;
3246     MacroAssembler _masm(&cbuf);
3247     __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg,
3248                                     NULL, &miss,
3249                                     /*set_cond_codes:*/ true);
3250     if ($primary) {
3251       __ mov(result_reg, zr);
3252     }
3253     __ bind(miss);
3254  %}
3255
3256  enc_class aarch64_enc_java_static_call(method meth) %{
3257    MacroAssembler _masm(&cbuf);
3258
3259    address addr = (address)$meth$$method;
3260    address call;
3261    if (!_method) {
3262      // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3263      call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf);
3264      if (call == NULL) {
3265        ciEnv::current()->record_failure("CodeCache is full");
3266        return;
3267      }
3268    } else {
3269      int method_index = resolved_method_index(cbuf);
3270      RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3271                                                  : static_call_Relocation::spec(method_index);
3272      call = __ trampoline_call(Address(addr, rspec), &cbuf);
3273      if (call == NULL) {
3274        ciEnv::current()->record_failure("CodeCache is full");
3275        return;
3276      }
3277      // Emit stub for static call
3278      address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
3279      if (stub == NULL) {
3280        ciEnv::current()->record_failure("CodeCache is full");
3281        return;
3282      }
3283    }
3284  %}
3285
3286  enc_class aarch64_enc_java_dynamic_call(method meth) %{
3287    MacroAssembler _masm(&cbuf);
3288    int method_index = resolved_method_index(cbuf);
3289    address call = __ ic_call((address)$meth$$method, method_index);
3290    if (call == NULL) {
3291      ciEnv::current()->record_failure("CodeCache is full");
3292      return;
3293    }
3294  %}
3295
3296  enc_class aarch64_enc_call_epilog() %{
3297    MacroAssembler _masm(&cbuf);
3298    if (VerifyStackAtCalls) {
3299      // Check that stack depth is unchanged: find majik cookie on stack
3300      __ call_Unimplemented();
3301    }
3302  %}
3303
3304  enc_class aarch64_enc_java_to_runtime(method meth) %{
3305    MacroAssembler _masm(&cbuf);
3306
3307    // some calls to generated routines (arraycopy code) are scheduled
3308    // by C2 as runtime calls. if so we can call them using a br (they
3309    // will be in a reachable segment) otherwise we have to use a blr
3310    // which loads the absolute address into a register.
3311    address entry = (address)$meth$$method;
3312    CodeBlob *cb = CodeCache::find_blob(entry);
3313    if (cb) {
3314      address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type));
3315      if (call == NULL) {
3316        ciEnv::current()->record_failure("CodeCache is full");
3317        return;
3318      }
3319    } else {
3320      Label retaddr;
3321      __ adr(rscratch2, retaddr);
3322      __ lea(rscratch1, RuntimeAddress(entry));
3323      // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc()
3324      __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)));
3325      __ blr(rscratch1);
3326      __ bind(retaddr);
3327      __ add(sp, sp, 2 * wordSize);
3328    }
3329  %}
3330
3331  enc_class aarch64_enc_rethrow() %{
3332    MacroAssembler _masm(&cbuf);
3333    __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub()));
3334  %}
3335
3336  enc_class aarch64_enc_ret() %{
3337    MacroAssembler _masm(&cbuf);
3338    __ ret(lr);
3339  %}
3340
3341  enc_class aarch64_enc_tail_call(iRegP jump_target) %{
3342    MacroAssembler _masm(&cbuf);
3343    Register target_reg = as_Register($jump_target$$reg);
3344    __ br(target_reg);
3345  %}
3346
3347  enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{
3348    MacroAssembler _masm(&cbuf);
3349    Register target_reg = as_Register($jump_target$$reg);
3350    // exception oop should be in r0
3351    // ret addr has been popped into lr
3352    // callee expects it in r3
3353    __ mov(r3, lr);
3354    __ br(target_reg);
3355  %}
3356
3357  enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{
3358    MacroAssembler _masm(&cbuf);
3359    Register oop = as_Register($object$$reg);
3360    Register box = as_Register($box$$reg);
3361    Register disp_hdr = as_Register($tmp$$reg);
3362    Register tmp = as_Register($tmp2$$reg);
3363    Label cont;
3364    Label object_has_monitor;
3365    Label cas_failed;
3366
3367    assert_different_registers(oop, box, tmp, disp_hdr);
3368
3369    // Load markOop from object into displaced_header.
3370    __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
3371
3372    // Always do locking in runtime.
3373    if (EmitSync & 0x01) {
3374      __ cmp(oop, zr);
3375      return;
3376    }
3377
3378    if (UseBiasedLocking && !UseOptoBiasInlining) {
3379      __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont);
3380    }
3381
3382    // Check for existing monitor
3383    if ((EmitSync & 0x02) == 0) {
3384      __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor);
3385    }
3386
3387    // Set tmp to be (markOop of object | UNLOCK_VALUE).
3388    __ orr(tmp, disp_hdr, markOopDesc::unlocked_value);
3389
3390    // Initialize the box. (Must happen before we update the object mark!)
3391    __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3392
3393    // Compare object markOop with an unlocked value (tmp) and if
3394    // equal exchange the stack address of our box with object markOop.
3395    // On failure disp_hdr contains the possibly locked markOop.
3396    __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true,
3397               /*release*/ true, /*weak*/ false, disp_hdr);
3398    __ br(Assembler::EQ, cont);
3399
3400    assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
3401
3402    // If the compare-and-exchange succeeded, then we found an unlocked
3403    // object, will have now locked it will continue at label cont
3404
3405    __ bind(cas_failed);
3406    // We did not see an unlocked object so try the fast recursive case.
3407
3408    // Check if the owner is self by comparing the value in the
3409    // markOop of object (disp_hdr) with the stack pointer.
3410    __ mov(rscratch1, sp);
3411    __ sub(disp_hdr, disp_hdr, rscratch1);
3412    __ mov(tmp, (address) (~(os::vm_page_size()-1) | (uintptr_t)markOopDesc::lock_mask_in_place));
3413    // If condition is true we are cont and hence we can store 0 as the
3414    // displaced header in the box, which indicates that it is a recursive lock.
3415    __ ands(tmp/*==0?*/, disp_hdr, tmp);   // Sets flags for result
3416    __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3417
3418    if ((EmitSync & 0x02) == 0) {
3419      __ b(cont);
3420
3421      // Handle existing monitor.
3422      __ bind(object_has_monitor);
3423      // The object's monitor m is unlocked iff m->owner == NULL,
3424      // otherwise m->owner may contain a thread or a stack address.
3425      //
3426      // Try to CAS m->owner from NULL to current thread.
3427      __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value));
3428    __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true,
3429               /*release*/ true, /*weak*/ false, noreg); // Sets flags for result
3430
3431      // Store a non-null value into the box to avoid looking like a re-entrant
3432      // lock. The fast-path monitor unlock code checks for
3433      // markOopDesc::monitor_value so use markOopDesc::unused_mark which has the
3434      // relevant bit set, and also matches ObjectSynchronizer::slow_enter.
3435      __ mov(tmp, (address)markOopDesc::unused_mark());
3436      __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3437    }
3438
3439    __ bind(cont);
3440    // flag == EQ indicates success
3441    // flag == NE indicates failure
3442  %}
3443
3444  enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{
3445    MacroAssembler _masm(&cbuf);
3446    Register oop = as_Register($object$$reg);
3447    Register box = as_Register($box$$reg);
3448    Register disp_hdr = as_Register($tmp$$reg);
3449    Register tmp = as_Register($tmp2$$reg);
3450    Label cont;
3451    Label object_has_monitor;
3452
3453    assert_different_registers(oop, box, tmp, disp_hdr);
3454
3455    // Always do locking in runtime.
3456    if (EmitSync & 0x01) {
3457      __ cmp(oop, zr); // Oop can't be 0 here => always false.
3458      return;
3459    }
3460
3461    if (UseBiasedLocking && !UseOptoBiasInlining) {
3462      __ biased_locking_exit(oop, tmp, cont);
3463    }
3464
3465    // Find the lock address and load the displaced header from the stack.
3466    __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3467
3468    // If the displaced header is 0, we have a recursive unlock.
3469    __ cmp(disp_hdr, zr);
3470    __ br(Assembler::EQ, cont);
3471
3472    // Handle existing monitor.
3473    if ((EmitSync & 0x02) == 0) {
3474      __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
3475      __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor);
3476    }
3477
3478    // Check if it is still a light weight lock, this is is true if we
3479    // see the stack address of the basicLock in the markOop of the
3480    // object.
3481
3482    __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false,
3483               /*release*/ true, /*weak*/ false, tmp);
3484    __ b(cont);
3485
3486    assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
3487
3488    // Handle existing monitor.
3489    if ((EmitSync & 0x02) == 0) {
3490      __ bind(object_has_monitor);
3491      __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor
3492      __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
3493      __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes()));
3494      __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner.
3495      __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions
3496      __ cmp(rscratch1, zr); // Sets flags for result
3497      __ br(Assembler::NE, cont);
3498
3499      __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes()));
3500      __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes()));
3501      __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0.
3502      __ cmp(rscratch1, zr); // Sets flags for result
3503      __ cbnz(rscratch1, cont);
3504      // need a release store here
3505      __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
3506      __ stlr(zr, tmp); // set unowned
3507    }
3508
3509    __ bind(cont);
3510    // flag == EQ indicates success
3511    // flag == NE indicates failure
3512  %}
3513
3514%}
3515
3516//----------FRAME--------------------------------------------------------------
3517// Definition of frame structure and management information.
3518//
3519//  S T A C K   L A Y O U T    Allocators stack-slot number
3520//                             |   (to get allocators register number
3521//  G  Owned by    |        |  v    add OptoReg::stack0())
3522//  r   CALLER     |        |
3523//  o     |        +--------+      pad to even-align allocators stack-slot
3524//  w     V        |  pad0  |        numbers; owned by CALLER
3525//  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
3526//  h     ^        |   in   |  5
3527//        |        |  args  |  4   Holes in incoming args owned by SELF
3528//  |     |        |        |  3
3529//  |     |        +--------+
3530//  V     |        | old out|      Empty on Intel, window on Sparc
3531//        |    old |preserve|      Must be even aligned.
3532//        |     SP-+--------+----> Matcher::_old_SP, even aligned
3533//        |        |   in   |  3   area for Intel ret address
3534//     Owned by    |preserve|      Empty on Sparc.
3535//       SELF      +--------+
3536//        |        |  pad2  |  2   pad to align old SP
3537//        |        +--------+  1
3538//        |        | locks  |  0
3539//        |        +--------+----> OptoReg::stack0(), even aligned
3540//        |        |  pad1  | 11   pad to align new SP
3541//        |        +--------+
3542//        |        |        | 10
3543//        |        | spills |  9   spills
3544//        V        |        |  8   (pad0 slot for callee)
3545//      -----------+--------+----> Matcher::_out_arg_limit, unaligned
3546//        ^        |  out   |  7
3547//        |        |  args  |  6   Holes in outgoing args owned by CALLEE
3548//     Owned by    +--------+
3549//      CALLEE     | new out|  6   Empty on Intel, window on Sparc
3550//        |    new |preserve|      Must be even-aligned.
3551//        |     SP-+--------+----> Matcher::_new_SP, even aligned
3552//        |        |        |
3553//
3554// Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
3555//         known from SELF's arguments and the Java calling convention.
3556//         Region 6-7 is determined per call site.
3557// Note 2: If the calling convention leaves holes in the incoming argument
3558//         area, those holes are owned by SELF.  Holes in the outgoing area
3559//         are owned by the CALLEE.  Holes should not be nessecary in the
3560//         incoming area, as the Java calling convention is completely under
3561//         the control of the AD file.  Doubles can be sorted and packed to
3562//         avoid holes.  Holes in the outgoing arguments may be nessecary for
3563//         varargs C calling conventions.
3564// Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
3565//         even aligned with pad0 as needed.
3566//         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
3567//           (the latter is true on Intel but is it false on AArch64?)
3568//         region 6-11 is even aligned; it may be padded out more so that
3569//         the region from SP to FP meets the minimum stack alignment.
3570// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3571//         alignment.  Region 11, pad1, may be dynamically extended so that
3572//         SP meets the minimum alignment.
3573
3574frame %{
3575  // What direction does stack grow in (assumed to be same for C & Java)
3576  stack_direction(TOWARDS_LOW);
3577
3578  // These three registers define part of the calling convention
3579  // between compiled code and the interpreter.
3580
3581  // Inline Cache Register or methodOop for I2C.
3582  inline_cache_reg(R12);
3583
3584  // Method Oop Register when calling interpreter.
3585  interpreter_method_oop_reg(R12);
3586
3587  // Number of stack slots consumed by locking an object
3588  sync_stack_slots(2);
3589
3590  // Compiled code's Frame Pointer
3591  frame_pointer(R31);
3592
3593  // Interpreter stores its frame pointer in a register which is
3594  // stored to the stack by I2CAdaptors.
3595  // I2CAdaptors convert from interpreted java to compiled java.
3596  interpreter_frame_pointer(R29);
3597
3598  // Stack alignment requirement
3599  stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
3600
3601  // Number of stack slots between incoming argument block and the start of
3602  // a new frame.  The PROLOG must add this many slots to the stack.  The
3603  // EPILOG must remove this many slots. aarch64 needs two slots for
3604  // return address and fp.
3605  // TODO think this is correct but check
3606  in_preserve_stack_slots(4);
3607
3608  // Number of outgoing stack slots killed above the out_preserve_stack_slots
3609  // for calls to C.  Supports the var-args backing area for register parms.
3610  varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
3611
3612  // The after-PROLOG location of the return address.  Location of
3613  // return address specifies a type (REG or STACK) and a number
3614  // representing the register number (i.e. - use a register name) or
3615  // stack slot.
3616  // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3617  // Otherwise, it is above the locks and verification slot and alignment word
3618  // TODO this may well be correct but need to check why that - 2 is there
3619  // ppc port uses 0 but we definitely need to allow for fixed_slots
3620  // which folds in the space used for monitors
3621  return_addr(STACK - 2 +
3622              align_up((Compile::current()->in_preserve_stack_slots() +
3623                        Compile::current()->fixed_slots()),
3624                       stack_alignment_in_slots()));
3625
3626  // Body of function which returns an integer array locating
3627  // arguments either in registers or in stack slots.  Passed an array
3628  // of ideal registers called "sig" and a "length" count.  Stack-slot
3629  // offsets are based on outgoing arguments, i.e. a CALLER setting up
3630  // arguments for a CALLEE.  Incoming stack arguments are
3631  // automatically biased by the preserve_stack_slots field above.
3632
3633  calling_convention
3634  %{
3635    // No difference between ingoing/outgoing just pass false
3636    SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3637  %}
3638
3639  c_calling_convention
3640  %{
3641    // This is obviously always outgoing
3642    (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length);
3643  %}
3644
3645  // Location of compiled Java return values.  Same as C for now.
3646  return_value
3647  %{
3648    // TODO do we allow ideal_reg == Op_RegN???
3649    assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
3650           "only return normal values");
3651
3652    static const int lo[Op_RegL + 1] = { // enum name
3653      0,                                 // Op_Node
3654      0,                                 // Op_Set
3655      R0_num,                            // Op_RegN
3656      R0_num,                            // Op_RegI
3657      R0_num,                            // Op_RegP
3658      V0_num,                            // Op_RegF
3659      V0_num,                            // Op_RegD
3660      R0_num                             // Op_RegL
3661    };
3662
3663    static const int hi[Op_RegL + 1] = { // enum name
3664      0,                                 // Op_Node
3665      0,                                 // Op_Set
3666      OptoReg::Bad,                       // Op_RegN
3667      OptoReg::Bad,                      // Op_RegI
3668      R0_H_num,                          // Op_RegP
3669      OptoReg::Bad,                      // Op_RegF
3670      V0_H_num,                          // Op_RegD
3671      R0_H_num                           // Op_RegL
3672    };
3673
3674    return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
3675  %}
3676%}
3677
3678//----------ATTRIBUTES---------------------------------------------------------
3679//----------Operand Attributes-------------------------------------------------
3680op_attrib op_cost(1);        // Required cost attribute
3681
3682//----------Instruction Attributes---------------------------------------------
3683ins_attrib ins_cost(INSN_COST); // Required cost attribute
3684ins_attrib ins_size(32);        // Required size attribute (in bits)
3685ins_attrib ins_short_branch(0); // Required flag: is this instruction
3686                                // a non-matching short branch variant
3687                                // of some long branch?
3688ins_attrib ins_alignment(4);    // Required alignment attribute (must
3689                                // be a power of 2) specifies the
3690                                // alignment that some part of the
3691                                // instruction (not necessarily the
3692                                // start) requires.  If > 1, a
3693                                // compute_padding() function must be
3694                                // provided for the instruction
3695
3696//----------OPERANDS-----------------------------------------------------------
3697// Operand definitions must precede instruction definitions for correct parsing
3698// in the ADLC because operands constitute user defined types which are used in
3699// instruction definitions.
3700
3701//----------Simple Operands----------------------------------------------------
3702
3703// Integer operands 32 bit
3704// 32 bit immediate
3705operand immI()
3706%{
3707  match(ConI);
3708
3709  op_cost(0);
3710  format %{ %}
3711  interface(CONST_INTER);
3712%}
3713
3714// 32 bit zero
3715operand immI0()
3716%{
3717  predicate(n->get_int() == 0);
3718  match(ConI);
3719
3720  op_cost(0);
3721  format %{ %}
3722  interface(CONST_INTER);
3723%}
3724
3725// 32 bit unit increment
3726operand immI_1()
3727%{
3728  predicate(n->get_int() == 1);
3729  match(ConI);
3730
3731  op_cost(0);
3732  format %{ %}
3733  interface(CONST_INTER);
3734%}
3735
3736// 32 bit unit decrement
3737operand immI_M1()
3738%{
3739  predicate(n->get_int() == -1);
3740  match(ConI);
3741
3742  op_cost(0);
3743  format %{ %}
3744  interface(CONST_INTER);
3745%}
3746
3747// Shift values for add/sub extension shift
3748operand immIExt()
3749%{
3750  predicate(0 <= n->get_int() && (n->get_int() <= 4));
3751  match(ConI);
3752
3753  op_cost(0);
3754  format %{ %}
3755  interface(CONST_INTER);
3756%}
3757
3758operand immI_le_4()
3759%{
3760  predicate(n->get_int() <= 4);
3761  match(ConI);
3762
3763  op_cost(0);
3764  format %{ %}
3765  interface(CONST_INTER);
3766%}
3767
3768operand immI_31()
3769%{
3770  predicate(n->get_int() == 31);
3771  match(ConI);
3772
3773  op_cost(0);
3774  format %{ %}
3775  interface(CONST_INTER);
3776%}
3777
3778operand immI_8()
3779%{
3780  predicate(n->get_int() == 8);
3781  match(ConI);
3782
3783  op_cost(0);
3784  format %{ %}
3785  interface(CONST_INTER);
3786%}
3787
3788operand immI_16()
3789%{
3790  predicate(n->get_int() == 16);
3791  match(ConI);
3792
3793  op_cost(0);
3794  format %{ %}
3795  interface(CONST_INTER);
3796%}
3797
3798operand immI_24()
3799%{
3800  predicate(n->get_int() == 24);
3801  match(ConI);
3802
3803  op_cost(0);
3804  format %{ %}
3805  interface(CONST_INTER);
3806%}
3807
3808operand immI_32()
3809%{
3810  predicate(n->get_int() == 32);
3811  match(ConI);
3812
3813  op_cost(0);
3814  format %{ %}
3815  interface(CONST_INTER);
3816%}
3817
3818operand immI_48()
3819%{
3820  predicate(n->get_int() == 48);
3821  match(ConI);
3822
3823  op_cost(0);
3824  format %{ %}
3825  interface(CONST_INTER);
3826%}
3827
3828operand immI_56()
3829%{
3830  predicate(n->get_int() == 56);
3831  match(ConI);
3832
3833  op_cost(0);
3834  format %{ %}
3835  interface(CONST_INTER);
3836%}
3837
3838operand immI_63()
3839%{
3840  predicate(n->get_int() == 63);
3841  match(ConI);
3842
3843  op_cost(0);
3844  format %{ %}
3845  interface(CONST_INTER);
3846%}
3847
3848operand immI_64()
3849%{
3850  predicate(n->get_int() == 64);
3851  match(ConI);
3852
3853  op_cost(0);
3854  format %{ %}
3855  interface(CONST_INTER);
3856%}
3857
3858operand immI_255()
3859%{
3860  predicate(n->get_int() == 255);
3861  match(ConI);
3862
3863  op_cost(0);
3864  format %{ %}
3865  interface(CONST_INTER);
3866%}
3867
3868operand immI_65535()
3869%{
3870  predicate(n->get_int() == 65535);
3871  match(ConI);
3872
3873  op_cost(0);
3874  format %{ %}
3875  interface(CONST_INTER);
3876%}
3877
3878operand immL_255()
3879%{
3880  predicate(n->get_long() == 255L);
3881  match(ConL);
3882
3883  op_cost(0);
3884  format %{ %}
3885  interface(CONST_INTER);
3886%}
3887
3888operand immL_65535()
3889%{
3890  predicate(n->get_long() == 65535L);
3891  match(ConL);
3892
3893  op_cost(0);
3894  format %{ %}
3895  interface(CONST_INTER);
3896%}
3897
3898operand immL_4294967295()
3899%{
3900  predicate(n->get_long() == 4294967295L);
3901  match(ConL);
3902
3903  op_cost(0);
3904  format %{ %}
3905  interface(CONST_INTER);
3906%}
3907
3908operand immL_bitmask()
3909%{
3910  predicate((n->get_long() != 0)
3911            && ((n->get_long() & 0xc000000000000000l) == 0)
3912            && is_power_of_2(n->get_long() + 1));
3913  match(ConL);
3914
3915  op_cost(0);
3916  format %{ %}
3917  interface(CONST_INTER);
3918%}
3919
3920operand immI_bitmask()
3921%{
3922  predicate((n->get_int() != 0)
3923            && ((n->get_int() & 0xc0000000) == 0)
3924            && is_power_of_2(n->get_int() + 1));
3925  match(ConI);
3926
3927  op_cost(0);
3928  format %{ %}
3929  interface(CONST_INTER);
3930%}
3931
3932operand immL_positive_bitmaskI()
3933%{
3934  predicate((n->get_long() != 0)
3935            && ((julong)n->get_long() < 0x80000000ULL)
3936            && is_power_of_2(n->get_long() + 1));
3937  match(ConL);
3938
3939  op_cost(0);
3940  format %{ %}
3941  interface(CONST_INTER);
3942%}
3943
3944// Scale values for scaled offset addressing modes (up to long but not quad)
3945operand immIScale()
3946%{
3947  predicate(0 <= n->get_int() && (n->get_int() <= 3));
3948  match(ConI);
3949
3950  op_cost(0);
3951  format %{ %}
3952  interface(CONST_INTER);
3953%}
3954
3955// 26 bit signed offset -- for pc-relative branches
3956operand immI26()
3957%{
3958  predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25)));
3959  match(ConI);
3960
3961  op_cost(0);
3962  format %{ %}
3963  interface(CONST_INTER);
3964%}
3965
3966// 19 bit signed offset -- for pc-relative loads
3967operand immI19()
3968%{
3969  predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18)));
3970  match(ConI);
3971
3972  op_cost(0);
3973  format %{ %}
3974  interface(CONST_INTER);
3975%}
3976
3977// 12 bit unsigned offset -- for base plus immediate loads
3978operand immIU12()
3979%{
3980  predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12)));
3981  match(ConI);
3982
3983  op_cost(0);
3984  format %{ %}
3985  interface(CONST_INTER);
3986%}
3987
3988operand immLU12()
3989%{
3990  predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12)));
3991  match(ConL);
3992
3993  op_cost(0);
3994  format %{ %}
3995  interface(CONST_INTER);
3996%}
3997
3998// Offset for scaled or unscaled immediate loads and stores
3999operand immIOffset()
4000%{
4001  predicate(Address::offset_ok_for_immed(n->get_int()));
4002  match(ConI);
4003
4004  op_cost(0);
4005  format %{ %}
4006  interface(CONST_INTER);
4007%}
4008
4009operand immIOffset4()
4010%{
4011  predicate(Address::offset_ok_for_immed(n->get_int(), 2));
4012  match(ConI);
4013
4014  op_cost(0);
4015  format %{ %}
4016  interface(CONST_INTER);
4017%}
4018
4019operand immIOffset8()
4020%{
4021  predicate(Address::offset_ok_for_immed(n->get_int(), 3));
4022  match(ConI);
4023
4024  op_cost(0);
4025  format %{ %}
4026  interface(CONST_INTER);
4027%}
4028
4029operand immIOffset16()
4030%{
4031  predicate(Address::offset_ok_for_immed(n->get_int(), 4));
4032  match(ConI);
4033
4034  op_cost(0);
4035  format %{ %}
4036  interface(CONST_INTER);
4037%}
4038
4039operand immLoffset()
4040%{
4041  predicate(Address::offset_ok_for_immed(n->get_long()));
4042  match(ConL);
4043
4044  op_cost(0);
4045  format %{ %}
4046  interface(CONST_INTER);
4047%}
4048
4049operand immLoffset4()
4050%{
4051  predicate(Address::offset_ok_for_immed(n->get_long(), 2));
4052  match(ConL);
4053
4054  op_cost(0);
4055  format %{ %}
4056  interface(CONST_INTER);
4057%}
4058
4059operand immLoffset8()
4060%{
4061  predicate(Address::offset_ok_for_immed(n->get_long(), 3));
4062  match(ConL);
4063
4064  op_cost(0);
4065  format %{ %}
4066  interface(CONST_INTER);
4067%}
4068
4069operand immLoffset16()
4070%{
4071  predicate(Address::offset_ok_for_immed(n->get_long(), 4));
4072  match(ConL);
4073
4074  op_cost(0);
4075  format %{ %}
4076  interface(CONST_INTER);
4077%}
4078
4079// 32 bit integer valid for add sub immediate
4080operand immIAddSub()
4081%{
4082  predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int()));
4083  match(ConI);
4084  op_cost(0);
4085  format %{ %}
4086  interface(CONST_INTER);
4087%}
4088
4089// 32 bit unsigned integer valid for logical immediate
4090// TODO -- check this is right when e.g the mask is 0x80000000
4091operand immILog()
4092%{
4093  predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int()));
4094  match(ConI);
4095
4096  op_cost(0);
4097  format %{ %}
4098  interface(CONST_INTER);
4099%}
4100
4101// Integer operands 64 bit
4102// 64 bit immediate
4103operand immL()
4104%{
4105  match(ConL);
4106
4107  op_cost(0);
4108  format %{ %}
4109  interface(CONST_INTER);
4110%}
4111
4112// 64 bit zero
4113operand immL0()
4114%{
4115  predicate(n->get_long() == 0);
4116  match(ConL);
4117
4118  op_cost(0);
4119  format %{ %}
4120  interface(CONST_INTER);
4121%}
4122
4123// 64 bit unit increment
4124operand immL_1()
4125%{
4126  predicate(n->get_long() == 1);
4127  match(ConL);
4128
4129  op_cost(0);
4130  format %{ %}
4131  interface(CONST_INTER);
4132%}
4133
4134// 64 bit unit decrement
4135operand immL_M1()
4136%{
4137  predicate(n->get_long() == -1);
4138  match(ConL);
4139
4140  op_cost(0);
4141  format %{ %}
4142  interface(CONST_INTER);
4143%}
4144
4145// 32 bit offset of pc in thread anchor
4146
4147operand immL_pc_off()
4148%{
4149  predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) +
4150                             in_bytes(JavaFrameAnchor::last_Java_pc_offset()));
4151  match(ConL);
4152
4153  op_cost(0);
4154  format %{ %}
4155  interface(CONST_INTER);
4156%}
4157
4158// 64 bit integer valid for add sub immediate
4159operand immLAddSub()
4160%{
4161  predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long()));
4162  match(ConL);
4163  op_cost(0);
4164  format %{ %}
4165  interface(CONST_INTER);
4166%}
4167
4168// 64 bit integer valid for logical immediate
4169operand immLLog()
4170%{
4171  predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long()));
4172  match(ConL);
4173  op_cost(0);
4174  format %{ %}
4175  interface(CONST_INTER);
4176%}
4177
4178// Long Immediate: low 32-bit mask
4179operand immL_32bits()
4180%{
4181  predicate(n->get_long() == 0xFFFFFFFFL);
4182  match(ConL);
4183  op_cost(0);
4184  format %{ %}
4185  interface(CONST_INTER);
4186%}
4187
4188// Pointer operands
4189// Pointer Immediate
4190operand immP()
4191%{
4192  match(ConP);
4193
4194  op_cost(0);
4195  format %{ %}
4196  interface(CONST_INTER);
4197%}
4198
4199// NULL Pointer Immediate
4200operand immP0()
4201%{
4202  predicate(n->get_ptr() == 0);
4203  match(ConP);
4204
4205  op_cost(0);
4206  format %{ %}
4207  interface(CONST_INTER);
4208%}
4209
4210// Pointer Immediate One
4211// this is used in object initialization (initial object header)
4212operand immP_1()
4213%{
4214  predicate(n->get_ptr() == 1);
4215  match(ConP);
4216
4217  op_cost(0);
4218  format %{ %}
4219  interface(CONST_INTER);
4220%}
4221
4222// Polling Page Pointer Immediate
4223operand immPollPage()
4224%{
4225  predicate((address)n->get_ptr() == os::get_polling_page());
4226  match(ConP);
4227
4228  op_cost(0);
4229  format %{ %}
4230  interface(CONST_INTER);
4231%}
4232
4233// Card Table Byte Map Base
4234operand immByteMapBase()
4235%{
4236  // Get base of card map
4237  predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) &&
4238            (jbyte*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base());
4239  match(ConP);
4240
4241  op_cost(0);
4242  format %{ %}
4243  interface(CONST_INTER);
4244%}
4245
4246// Pointer Immediate Minus One
4247// this is used when we want to write the current PC to the thread anchor
4248operand immP_M1()
4249%{
4250  predicate(n->get_ptr() == -1);
4251  match(ConP);
4252
4253  op_cost(0);
4254  format %{ %}
4255  interface(CONST_INTER);
4256%}
4257
4258// Pointer Immediate Minus Two
4259// this is used when we want to write the current PC to the thread anchor
4260operand immP_M2()
4261%{
4262  predicate(n->get_ptr() == -2);
4263  match(ConP);
4264
4265  op_cost(0);
4266  format %{ %}
4267  interface(CONST_INTER);
4268%}
4269
4270// Float and Double operands
4271// Double Immediate
4272operand immD()
4273%{
4274  match(ConD);
4275  op_cost(0);
4276  format %{ %}
4277  interface(CONST_INTER);
4278%}
4279
4280// Double Immediate: +0.0d
4281operand immD0()
4282%{
4283  predicate(jlong_cast(n->getd()) == 0);
4284  match(ConD);
4285
4286  op_cost(0);
4287  format %{ %}
4288  interface(CONST_INTER);
4289%}
4290
4291// constant 'double +0.0'.
4292operand immDPacked()
4293%{
4294  predicate(Assembler::operand_valid_for_float_immediate(n->getd()));
4295  match(ConD);
4296  op_cost(0);
4297  format %{ %}
4298  interface(CONST_INTER);
4299%}
4300
4301// Float Immediate
4302operand immF()
4303%{
4304  match(ConF);
4305  op_cost(0);
4306  format %{ %}
4307  interface(CONST_INTER);
4308%}
4309
4310// Float Immediate: +0.0f.
4311operand immF0()
4312%{
4313  predicate(jint_cast(n->getf()) == 0);
4314  match(ConF);
4315
4316  op_cost(0);
4317  format %{ %}
4318  interface(CONST_INTER);
4319%}
4320
4321//
4322operand immFPacked()
4323%{
4324  predicate(Assembler::operand_valid_for_float_immediate((double)n->getf()));
4325  match(ConF);
4326  op_cost(0);
4327  format %{ %}
4328  interface(CONST_INTER);
4329%}
4330
4331// Narrow pointer operands
4332// Narrow Pointer Immediate
4333operand immN()
4334%{
4335  match(ConN);
4336
4337  op_cost(0);
4338  format %{ %}
4339  interface(CONST_INTER);
4340%}
4341
4342// Narrow NULL Pointer Immediate
4343operand immN0()
4344%{
4345  predicate(n->get_narrowcon() == 0);
4346  match(ConN);
4347
4348  op_cost(0);
4349  format %{ %}
4350  interface(CONST_INTER);
4351%}
4352
4353operand immNKlass()
4354%{
4355  match(ConNKlass);
4356
4357  op_cost(0);
4358  format %{ %}
4359  interface(CONST_INTER);
4360%}
4361
4362// Integer 32 bit Register Operands
4363// Integer 32 bitRegister (excludes SP)
4364operand iRegI()
4365%{
4366  constraint(ALLOC_IN_RC(any_reg32));
4367  match(RegI);
4368  match(iRegINoSp);
4369  op_cost(0);
4370  format %{ %}
4371  interface(REG_INTER);
4372%}
4373
4374// Integer 32 bit Register not Special
4375operand iRegINoSp()
4376%{
4377  constraint(ALLOC_IN_RC(no_special_reg32));
4378  match(RegI);
4379  op_cost(0);
4380  format %{ %}
4381  interface(REG_INTER);
4382%}
4383
4384// Integer 64 bit Register Operands
4385// Integer 64 bit Register (includes SP)
4386operand iRegL()
4387%{
4388  constraint(ALLOC_IN_RC(any_reg));
4389  match(RegL);
4390  match(iRegLNoSp);
4391  op_cost(0);
4392  format %{ %}
4393  interface(REG_INTER);
4394%}
4395
4396// Integer 64 bit Register not Special
4397operand iRegLNoSp()
4398%{
4399  constraint(ALLOC_IN_RC(no_special_reg));
4400  match(RegL);
4401  match(iRegL_R0);
4402  format %{ %}
4403  interface(REG_INTER);
4404%}
4405
4406// Pointer Register Operands
4407// Pointer Register
4408operand iRegP()
4409%{
4410  constraint(ALLOC_IN_RC(ptr_reg));
4411  match(RegP);
4412  match(iRegPNoSp);
4413  match(iRegP_R0);
4414  //match(iRegP_R2);
4415  //match(iRegP_R4);
4416  //match(iRegP_R5);
4417  match(thread_RegP);
4418  op_cost(0);
4419  format %{ %}
4420  interface(REG_INTER);
4421%}
4422
4423// Pointer 64 bit Register not Special
4424operand iRegPNoSp()
4425%{
4426  constraint(ALLOC_IN_RC(no_special_ptr_reg));
4427  match(RegP);
4428  // match(iRegP);
4429  // match(iRegP_R0);
4430  // match(iRegP_R2);
4431  // match(iRegP_R4);
4432  // match(iRegP_R5);
4433  // match(thread_RegP);
4434  op_cost(0);
4435  format %{ %}
4436  interface(REG_INTER);
4437%}
4438
4439// Pointer 64 bit Register R0 only
4440operand iRegP_R0()
4441%{
4442  constraint(ALLOC_IN_RC(r0_reg));
4443  match(RegP);
4444  // match(iRegP);
4445  match(iRegPNoSp);
4446  op_cost(0);
4447  format %{ %}
4448  interface(REG_INTER);
4449%}
4450
4451// Pointer 64 bit Register R1 only
4452operand iRegP_R1()
4453%{
4454  constraint(ALLOC_IN_RC(r1_reg));
4455  match(RegP);
4456  // match(iRegP);
4457  match(iRegPNoSp);
4458  op_cost(0);
4459  format %{ %}
4460  interface(REG_INTER);
4461%}
4462
4463// Pointer 64 bit Register R2 only
4464operand iRegP_R2()
4465%{
4466  constraint(ALLOC_IN_RC(r2_reg));
4467  match(RegP);
4468  // match(iRegP);
4469  match(iRegPNoSp);
4470  op_cost(0);
4471  format %{ %}
4472  interface(REG_INTER);
4473%}
4474
4475// Pointer 64 bit Register R3 only
4476operand iRegP_R3()
4477%{
4478  constraint(ALLOC_IN_RC(r3_reg));
4479  match(RegP);
4480  // match(iRegP);
4481  match(iRegPNoSp);
4482  op_cost(0);
4483  format %{ %}
4484  interface(REG_INTER);
4485%}
4486
4487// Pointer 64 bit Register R4 only
4488operand iRegP_R4()
4489%{
4490  constraint(ALLOC_IN_RC(r4_reg));
4491  match(RegP);
4492  // match(iRegP);
4493  match(iRegPNoSp);
4494  op_cost(0);
4495  format %{ %}
4496  interface(REG_INTER);
4497%}
4498
4499// Pointer 64 bit Register R5 only
4500operand iRegP_R5()
4501%{
4502  constraint(ALLOC_IN_RC(r5_reg));
4503  match(RegP);
4504  // match(iRegP);
4505  match(iRegPNoSp);
4506  op_cost(0);
4507  format %{ %}
4508  interface(REG_INTER);
4509%}
4510
4511// Pointer 64 bit Register R10 only
4512operand iRegP_R10()
4513%{
4514  constraint(ALLOC_IN_RC(r10_reg));
4515  match(RegP);
4516  // match(iRegP);
4517  match(iRegPNoSp);
4518  op_cost(0);
4519  format %{ %}
4520  interface(REG_INTER);
4521%}
4522
4523// Long 64 bit Register R0 only
4524operand iRegL_R0()
4525%{
4526  constraint(ALLOC_IN_RC(r0_reg));
4527  match(RegL);
4528  match(iRegLNoSp);
4529  op_cost(0);
4530  format %{ %}
4531  interface(REG_INTER);
4532%}
4533
4534// Long 64 bit Register R2 only
4535operand iRegL_R2()
4536%{
4537  constraint(ALLOC_IN_RC(r2_reg));
4538  match(RegL);
4539  match(iRegLNoSp);
4540  op_cost(0);
4541  format %{ %}
4542  interface(REG_INTER);
4543%}
4544
4545// Long 64 bit Register R3 only
4546operand iRegL_R3()
4547%{
4548  constraint(ALLOC_IN_RC(r3_reg));
4549  match(RegL);
4550  match(iRegLNoSp);
4551  op_cost(0);
4552  format %{ %}
4553  interface(REG_INTER);
4554%}
4555
4556// Long 64 bit Register R11 only
4557operand iRegL_R11()
4558%{
4559  constraint(ALLOC_IN_RC(r11_reg));
4560  match(RegL);
4561  match(iRegLNoSp);
4562  op_cost(0);
4563  format %{ %}
4564  interface(REG_INTER);
4565%}
4566
4567// Pointer 64 bit Register FP only
4568operand iRegP_FP()
4569%{
4570  constraint(ALLOC_IN_RC(fp_reg));
4571  match(RegP);
4572  // match(iRegP);
4573  op_cost(0);
4574  format %{ %}
4575  interface(REG_INTER);
4576%}
4577
4578// Register R0 only
4579operand iRegI_R0()
4580%{
4581  constraint(ALLOC_IN_RC(int_r0_reg));
4582  match(RegI);
4583  match(iRegINoSp);
4584  op_cost(0);
4585  format %{ %}
4586  interface(REG_INTER);
4587%}
4588
4589// Register R2 only
4590operand iRegI_R2()
4591%{
4592  constraint(ALLOC_IN_RC(int_r2_reg));
4593  match(RegI);
4594  match(iRegINoSp);
4595  op_cost(0);
4596  format %{ %}
4597  interface(REG_INTER);
4598%}
4599
4600// Register R3 only
4601operand iRegI_R3()
4602%{
4603  constraint(ALLOC_IN_RC(int_r3_reg));
4604  match(RegI);
4605  match(iRegINoSp);
4606  op_cost(0);
4607  format %{ %}
4608  interface(REG_INTER);
4609%}
4610
4611
4612// Register R4 only
4613operand iRegI_R4()
4614%{
4615  constraint(ALLOC_IN_RC(int_r4_reg));
4616  match(RegI);
4617  match(iRegINoSp);
4618  op_cost(0);
4619  format %{ %}
4620  interface(REG_INTER);
4621%}
4622
4623
4624// Pointer Register Operands
4625// Narrow Pointer Register
4626operand iRegN()
4627%{
4628  constraint(ALLOC_IN_RC(any_reg32));
4629  match(RegN);
4630  match(iRegNNoSp);
4631  op_cost(0);
4632  format %{ %}
4633  interface(REG_INTER);
4634%}
4635
4636operand iRegN_R0()
4637%{
4638  constraint(ALLOC_IN_RC(r0_reg));
4639  match(iRegN);
4640  op_cost(0);
4641  format %{ %}
4642  interface(REG_INTER);
4643%}
4644
4645operand iRegN_R2()
4646%{
4647  constraint(ALLOC_IN_RC(r2_reg));
4648  match(iRegN);
4649  op_cost(0);
4650  format %{ %}
4651  interface(REG_INTER);
4652%}
4653
4654operand iRegN_R3()
4655%{
4656  constraint(ALLOC_IN_RC(r3_reg));
4657  match(iRegN);
4658  op_cost(0);
4659  format %{ %}
4660  interface(REG_INTER);
4661%}
4662
4663// Integer 64 bit Register not Special
4664operand iRegNNoSp()
4665%{
4666  constraint(ALLOC_IN_RC(no_special_reg32));
4667  match(RegN);
4668  op_cost(0);
4669  format %{ %}
4670  interface(REG_INTER);
4671%}
4672
4673// heap base register -- used for encoding immN0
4674
4675operand iRegIHeapbase()
4676%{
4677  constraint(ALLOC_IN_RC(heapbase_reg));
4678  match(RegI);
4679  op_cost(0);
4680  format %{ %}
4681  interface(REG_INTER);
4682%}
4683
4684// Float Register
4685// Float register operands
4686operand vRegF()
4687%{
4688  constraint(ALLOC_IN_RC(float_reg));
4689  match(RegF);
4690
4691  op_cost(0);
4692  format %{ %}
4693  interface(REG_INTER);
4694%}
4695
4696// Double Register
4697// Double register operands
4698operand vRegD()
4699%{
4700  constraint(ALLOC_IN_RC(double_reg));
4701  match(RegD);
4702
4703  op_cost(0);
4704  format %{ %}
4705  interface(REG_INTER);
4706%}
4707
4708operand vecD()
4709%{
4710  constraint(ALLOC_IN_RC(vectord_reg));
4711  match(VecD);
4712
4713  op_cost(0);
4714  format %{ %}
4715  interface(REG_INTER);
4716%}
4717
4718operand vecX()
4719%{
4720  constraint(ALLOC_IN_RC(vectorx_reg));
4721  match(VecX);
4722
4723  op_cost(0);
4724  format %{ %}
4725  interface(REG_INTER);
4726%}
4727
4728operand vRegD_V0()
4729%{
4730  constraint(ALLOC_IN_RC(v0_reg));
4731  match(RegD);
4732  op_cost(0);
4733  format %{ %}
4734  interface(REG_INTER);
4735%}
4736
4737operand vRegD_V1()
4738%{
4739  constraint(ALLOC_IN_RC(v1_reg));
4740  match(RegD);
4741  op_cost(0);
4742  format %{ %}
4743  interface(REG_INTER);
4744%}
4745
4746operand vRegD_V2()
4747%{
4748  constraint(ALLOC_IN_RC(v2_reg));
4749  match(RegD);
4750  op_cost(0);
4751  format %{ %}
4752  interface(REG_INTER);
4753%}
4754
4755operand vRegD_V3()
4756%{
4757  constraint(ALLOC_IN_RC(v3_reg));
4758  match(RegD);
4759  op_cost(0);
4760  format %{ %}
4761  interface(REG_INTER);
4762%}
4763
4764// Flags register, used as output of signed compare instructions
4765
4766// note that on AArch64 we also use this register as the output for
4767// for floating point compare instructions (CmpF CmpD). this ensures
4768// that ordered inequality tests use GT, GE, LT or LE none of which
4769// pass through cases where the result is unordered i.e. one or both
4770// inputs to the compare is a NaN. this means that the ideal code can
4771// replace e.g. a GT with an LE and not end up capturing the NaN case
4772// (where the comparison should always fail). EQ and NE tests are
4773// always generated in ideal code so that unordered folds into the NE
4774// case, matching the behaviour of AArch64 NE.
4775//
4776// This differs from x86 where the outputs of FP compares use a
4777// special FP flags registers and where compares based on this
4778// register are distinguished into ordered inequalities (cmpOpUCF) and
4779// EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests
4780// to explicitly handle the unordered case in branches. x86 also has
4781// to include extra CMoveX rules to accept a cmpOpUCF input.
4782
4783operand rFlagsReg()
4784%{
4785  constraint(ALLOC_IN_RC(int_flags));
4786  match(RegFlags);
4787
4788  op_cost(0);
4789  format %{ "RFLAGS" %}
4790  interface(REG_INTER);
4791%}
4792
4793// Flags register, used as output of unsigned compare instructions
4794operand rFlagsRegU()
4795%{
4796  constraint(ALLOC_IN_RC(int_flags));
4797  match(RegFlags);
4798
4799  op_cost(0);
4800  format %{ "RFLAGSU" %}
4801  interface(REG_INTER);
4802%}
4803
4804// Special Registers
4805
4806// Method Register
4807operand inline_cache_RegP(iRegP reg)
4808%{
4809  constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg
4810  match(reg);
4811  match(iRegPNoSp);
4812  op_cost(0);
4813  format %{ %}
4814  interface(REG_INTER);
4815%}
4816
4817operand interpreter_method_oop_RegP(iRegP reg)
4818%{
4819  constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg
4820  match(reg);
4821  match(iRegPNoSp);
4822  op_cost(0);
4823  format %{ %}
4824  interface(REG_INTER);
4825%}
4826
4827// Thread Register
4828operand thread_RegP(iRegP reg)
4829%{
4830  constraint(ALLOC_IN_RC(thread_reg)); // link_reg
4831  match(reg);
4832  op_cost(0);
4833  format %{ %}
4834  interface(REG_INTER);
4835%}
4836
4837operand lr_RegP(iRegP reg)
4838%{
4839  constraint(ALLOC_IN_RC(lr_reg)); // link_reg
4840  match(reg);
4841  op_cost(0);
4842  format %{ %}
4843  interface(REG_INTER);
4844%}
4845
4846//----------Memory Operands----------------------------------------------------
4847
4848operand indirect(iRegP reg)
4849%{
4850  constraint(ALLOC_IN_RC(ptr_reg));
4851  match(reg);
4852  op_cost(0);
4853  format %{ "[$reg]" %}
4854  interface(MEMORY_INTER) %{
4855    base($reg);
4856    index(0xffffffff);
4857    scale(0x0);
4858    disp(0x0);
4859  %}
4860%}
4861
4862operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale)
4863%{
4864  constraint(ALLOC_IN_RC(ptr_reg));
4865  predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
4866  match(AddP reg (LShiftL (ConvI2L ireg) scale));
4867  op_cost(0);
4868  format %{ "$reg, $ireg sxtw($scale), 0, I2L" %}
4869  interface(MEMORY_INTER) %{
4870    base($reg);
4871    index($ireg);
4872    scale($scale);
4873    disp(0x0);
4874  %}
4875%}
4876
4877operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale)
4878%{
4879  constraint(ALLOC_IN_RC(ptr_reg));
4880  predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
4881  match(AddP reg (LShiftL lreg scale));
4882  op_cost(0);
4883  format %{ "$reg, $lreg lsl($scale)" %}
4884  interface(MEMORY_INTER) %{
4885    base($reg);
4886    index($lreg);
4887    scale($scale);
4888    disp(0x0);
4889  %}
4890%}
4891
4892operand indIndexI2L(iRegP reg, iRegI ireg)
4893%{
4894  constraint(ALLOC_IN_RC(ptr_reg));
4895  match(AddP reg (ConvI2L ireg));
4896  op_cost(0);
4897  format %{ "$reg, $ireg, 0, I2L" %}
4898  interface(MEMORY_INTER) %{
4899    base($reg);
4900    index($ireg);
4901    scale(0x0);
4902    disp(0x0);
4903  %}
4904%}
4905
4906operand indIndex(iRegP reg, iRegL lreg)
4907%{
4908  constraint(ALLOC_IN_RC(ptr_reg));
4909  match(AddP reg lreg);
4910  op_cost(0);
4911  format %{ "$reg, $lreg" %}
4912  interface(MEMORY_INTER) %{
4913    base($reg);
4914    index($lreg);
4915    scale(0x0);
4916    disp(0x0);
4917  %}
4918%}
4919
4920operand indOffI(iRegP reg, immIOffset off)
4921%{
4922  constraint(ALLOC_IN_RC(ptr_reg));
4923  match(AddP reg off);
4924  op_cost(0);
4925  format %{ "[$reg, $off]" %}
4926  interface(MEMORY_INTER) %{
4927    base($reg);
4928    index(0xffffffff);
4929    scale(0x0);
4930    disp($off);
4931  %}
4932%}
4933
4934operand indOffI4(iRegP reg, immIOffset4 off)
4935%{
4936  constraint(ALLOC_IN_RC(ptr_reg));
4937  match(AddP reg off);
4938  op_cost(0);
4939  format %{ "[$reg, $off]" %}
4940  interface(MEMORY_INTER) %{
4941    base($reg);
4942    index(0xffffffff);
4943    scale(0x0);
4944    disp($off);
4945  %}
4946%}
4947
4948operand indOffI8(iRegP reg, immIOffset8 off)
4949%{
4950  constraint(ALLOC_IN_RC(ptr_reg));
4951  match(AddP reg off);
4952  op_cost(0);
4953  format %{ "[$reg, $off]" %}
4954  interface(MEMORY_INTER) %{
4955    base($reg);
4956    index(0xffffffff);
4957    scale(0x0);
4958    disp($off);
4959  %}
4960%}
4961
4962operand indOffI16(iRegP reg, immIOffset16 off)
4963%{
4964  constraint(ALLOC_IN_RC(ptr_reg));
4965  match(AddP reg off);
4966  op_cost(0);
4967  format %{ "[$reg, $off]" %}
4968  interface(MEMORY_INTER) %{
4969    base($reg);
4970    index(0xffffffff);
4971    scale(0x0);
4972    disp($off);
4973  %}
4974%}
4975
4976operand indOffL(iRegP reg, immLoffset off)
4977%{
4978  constraint(ALLOC_IN_RC(ptr_reg));
4979  match(AddP reg off);
4980  op_cost(0);
4981  format %{ "[$reg, $off]" %}
4982  interface(MEMORY_INTER) %{
4983    base($reg);
4984    index(0xffffffff);
4985    scale(0x0);
4986    disp($off);
4987  %}
4988%}
4989
4990operand indOffL4(iRegP reg, immLoffset4 off)
4991%{
4992  constraint(ALLOC_IN_RC(ptr_reg));
4993  match(AddP reg off);
4994  op_cost(0);
4995  format %{ "[$reg, $off]" %}
4996  interface(MEMORY_INTER) %{
4997    base($reg);
4998    index(0xffffffff);
4999    scale(0x0);
5000    disp($off);
5001  %}
5002%}
5003
5004operand indOffL8(iRegP reg, immLoffset8 off)
5005%{
5006  constraint(ALLOC_IN_RC(ptr_reg));
5007  match(AddP reg off);
5008  op_cost(0);
5009  format %{ "[$reg, $off]" %}
5010  interface(MEMORY_INTER) %{
5011    base($reg);
5012    index(0xffffffff);
5013    scale(0x0);
5014    disp($off);
5015  %}
5016%}
5017
5018operand indOffL16(iRegP reg, immLoffset16 off)
5019%{
5020  constraint(ALLOC_IN_RC(ptr_reg));
5021  match(AddP reg off);
5022  op_cost(0);
5023  format %{ "[$reg, $off]" %}
5024  interface(MEMORY_INTER) %{
5025    base($reg);
5026    index(0xffffffff);
5027    scale(0x0);
5028    disp($off);
5029  %}
5030%}
5031
5032operand indirectN(iRegN reg)
5033%{
5034  predicate(Universe::narrow_oop_shift() == 0);
5035  constraint(ALLOC_IN_RC(ptr_reg));
5036  match(DecodeN reg);
5037  op_cost(0);
5038  format %{ "[$reg]\t# narrow" %}
5039  interface(MEMORY_INTER) %{
5040    base($reg);
5041    index(0xffffffff);
5042    scale(0x0);
5043    disp(0x0);
5044  %}
5045%}
5046
5047operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale)
5048%{
5049  predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5050  constraint(ALLOC_IN_RC(ptr_reg));
5051  match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale));
5052  op_cost(0);
5053  format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %}
5054  interface(MEMORY_INTER) %{
5055    base($reg);
5056    index($ireg);
5057    scale($scale);
5058    disp(0x0);
5059  %}
5060%}
5061
5062operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale)
5063%{
5064  predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5065  constraint(ALLOC_IN_RC(ptr_reg));
5066  match(AddP (DecodeN reg) (LShiftL lreg scale));
5067  op_cost(0);
5068  format %{ "$reg, $lreg lsl($scale)\t# narrow" %}
5069  interface(MEMORY_INTER) %{
5070    base($reg);
5071    index($lreg);
5072    scale($scale);
5073    disp(0x0);
5074  %}
5075%}
5076
5077operand indIndexI2LN(iRegN reg, iRegI ireg)
5078%{
5079  predicate(Universe::narrow_oop_shift() == 0);
5080  constraint(ALLOC_IN_RC(ptr_reg));
5081  match(AddP (DecodeN reg) (ConvI2L ireg));
5082  op_cost(0);
5083  format %{ "$reg, $ireg, 0, I2L\t# narrow" %}
5084  interface(MEMORY_INTER) %{
5085    base($reg);
5086    index($ireg);
5087    scale(0x0);
5088    disp(0x0);
5089  %}
5090%}
5091
5092operand indIndexN(iRegN reg, iRegL lreg)
5093%{
5094  predicate(Universe::narrow_oop_shift() == 0);
5095  constraint(ALLOC_IN_RC(ptr_reg));
5096  match(AddP (DecodeN reg) lreg);
5097  op_cost(0);
5098  format %{ "$reg, $lreg\t# narrow" %}
5099  interface(MEMORY_INTER) %{
5100    base($reg);
5101    index($lreg);
5102    scale(0x0);
5103    disp(0x0);
5104  %}
5105%}
5106
5107operand indOffIN(iRegN reg, immIOffset off)
5108%{
5109  predicate(Universe::narrow_oop_shift() == 0);
5110  constraint(ALLOC_IN_RC(ptr_reg));
5111  match(AddP (DecodeN reg) off);
5112  op_cost(0);
5113  format %{ "[$reg, $off]\t# narrow" %}
5114  interface(MEMORY_INTER) %{
5115    base($reg);
5116    index(0xffffffff);
5117    scale(0x0);
5118    disp($off);
5119  %}
5120%}
5121
5122operand indOffLN(iRegN reg, immLoffset off)
5123%{
5124  predicate(Universe::narrow_oop_shift() == 0);
5125  constraint(ALLOC_IN_RC(ptr_reg));
5126  match(AddP (DecodeN reg) off);
5127  op_cost(0);
5128  format %{ "[$reg, $off]\t# narrow" %}
5129  interface(MEMORY_INTER) %{
5130    base($reg);
5131    index(0xffffffff);
5132    scale(0x0);
5133    disp($off);
5134  %}
5135%}
5136
5137
5138
5139// AArch64 opto stubs need to write to the pc slot in the thread anchor
5140operand thread_anchor_pc(thread_RegP reg, immL_pc_off off)
5141%{
5142  constraint(ALLOC_IN_RC(ptr_reg));
5143  match(AddP reg off);
5144  op_cost(0);
5145  format %{ "[$reg, $off]" %}
5146  interface(MEMORY_INTER) %{
5147    base($reg);
5148    index(0xffffffff);
5149    scale(0x0);
5150    disp($off);
5151  %}
5152%}
5153
5154//----------Special Memory Operands--------------------------------------------
5155// Stack Slot Operand - This operand is used for loading and storing temporary
5156//                      values on the stack where a match requires a value to
5157//                      flow through memory.
5158operand stackSlotP(sRegP reg)
5159%{
5160  constraint(ALLOC_IN_RC(stack_slots));
5161  op_cost(100);
5162  // No match rule because this operand is only generated in matching
5163  // match(RegP);
5164  format %{ "[$reg]" %}
5165  interface(MEMORY_INTER) %{
5166    base(0x1e);  // RSP
5167    index(0x0);  // No Index
5168    scale(0x0);  // No Scale
5169    disp($reg);  // Stack Offset
5170  %}
5171%}
5172
5173operand stackSlotI(sRegI reg)
5174%{
5175  constraint(ALLOC_IN_RC(stack_slots));
5176  // No match rule because this operand is only generated in matching
5177  // match(RegI);
5178  format %{ "[$reg]" %}
5179  interface(MEMORY_INTER) %{
5180    base(0x1e);  // RSP
5181    index(0x0);  // No Index
5182    scale(0x0);  // No Scale
5183    disp($reg);  // Stack Offset
5184  %}
5185%}
5186
5187operand stackSlotF(sRegF reg)
5188%{
5189  constraint(ALLOC_IN_RC(stack_slots));
5190  // No match rule because this operand is only generated in matching
5191  // match(RegF);
5192  format %{ "[$reg]" %}
5193  interface(MEMORY_INTER) %{
5194    base(0x1e);  // RSP
5195    index(0x0);  // No Index
5196    scale(0x0);  // No Scale
5197    disp($reg);  // Stack Offset
5198  %}
5199%}
5200
5201operand stackSlotD(sRegD reg)
5202%{
5203  constraint(ALLOC_IN_RC(stack_slots));
5204  // No match rule because this operand is only generated in matching
5205  // match(RegD);
5206  format %{ "[$reg]" %}
5207  interface(MEMORY_INTER) %{
5208    base(0x1e);  // RSP
5209    index(0x0);  // No Index
5210    scale(0x0);  // No Scale
5211    disp($reg);  // Stack Offset
5212  %}
5213%}
5214
5215operand stackSlotL(sRegL reg)
5216%{
5217  constraint(ALLOC_IN_RC(stack_slots));
5218  // No match rule because this operand is only generated in matching
5219  // match(RegL);
5220  format %{ "[$reg]" %}
5221  interface(MEMORY_INTER) %{
5222    base(0x1e);  // RSP
5223    index(0x0);  // No Index
5224    scale(0x0);  // No Scale
5225    disp($reg);  // Stack Offset
5226  %}
5227%}
5228
5229// Operands for expressing Control Flow
5230// NOTE: Label is a predefined operand which should not be redefined in
5231//       the AD file. It is generically handled within the ADLC.
5232
5233//----------Conditional Branch Operands----------------------------------------
5234// Comparison Op  - This is the operation of the comparison, and is limited to
5235//                  the following set of codes:
5236//                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5237//
5238// Other attributes of the comparison, such as unsignedness, are specified
5239// by the comparison instruction that sets a condition code flags register.
5240// That result is represented by a flags operand whose subtype is appropriate
5241// to the unsignedness (etc.) of the comparison.
5242//
5243// Later, the instruction which matches both the Comparison Op (a Bool) and
5244// the flags (produced by the Cmp) specifies the coding of the comparison op
5245// by matching a specific subtype of Bool operand below, such as cmpOpU.
5246
5247// used for signed integral comparisons and fp comparisons
5248
5249operand cmpOp()
5250%{
5251  match(Bool);
5252
5253  format %{ "" %}
5254  interface(COND_INTER) %{
5255    equal(0x0, "eq");
5256    not_equal(0x1, "ne");
5257    less(0xb, "lt");
5258    greater_equal(0xa, "ge");
5259    less_equal(0xd, "le");
5260    greater(0xc, "gt");
5261    overflow(0x6, "vs");
5262    no_overflow(0x7, "vc");
5263  %}
5264%}
5265
5266// used for unsigned integral comparisons
5267
5268operand cmpOpU()
5269%{
5270  match(Bool);
5271
5272  format %{ "" %}
5273  interface(COND_INTER) %{
5274    equal(0x0, "eq");
5275    not_equal(0x1, "ne");
5276    less(0x3, "lo");
5277    greater_equal(0x2, "hs");
5278    less_equal(0x9, "ls");
5279    greater(0x8, "hi");
5280    overflow(0x6, "vs");
5281    no_overflow(0x7, "vc");
5282  %}
5283%}
5284
5285// used for certain integral comparisons which can be
5286// converted to cbxx or tbxx instructions
5287
5288operand cmpOpEqNe()
5289%{
5290  match(Bool);
5291  match(CmpOp);
5292  op_cost(0);
5293  predicate(n->as_Bool()->_test._test == BoolTest::ne
5294            || n->as_Bool()->_test._test == BoolTest::eq);
5295
5296  format %{ "" %}
5297  interface(COND_INTER) %{
5298    equal(0x0, "eq");
5299    not_equal(0x1, "ne");
5300    less(0xb, "lt");
5301    greater_equal(0xa, "ge");
5302    less_equal(0xd, "le");
5303    greater(0xc, "gt");
5304    overflow(0x6, "vs");
5305    no_overflow(0x7, "vc");
5306  %}
5307%}
5308
5309// used for certain integral comparisons which can be
5310// converted to cbxx or tbxx instructions
5311
5312operand cmpOpLtGe()
5313%{
5314  match(Bool);
5315  match(CmpOp);
5316  op_cost(0);
5317
5318  predicate(n->as_Bool()->_test._test == BoolTest::lt
5319            || n->as_Bool()->_test._test == BoolTest::ge);
5320
5321  format %{ "" %}
5322  interface(COND_INTER) %{
5323    equal(0x0, "eq");
5324    not_equal(0x1, "ne");
5325    less(0xb, "lt");
5326    greater_equal(0xa, "ge");
5327    less_equal(0xd, "le");
5328    greater(0xc, "gt");
5329    overflow(0x6, "vs");
5330    no_overflow(0x7, "vc");
5331  %}
5332%}
5333
5334// used for certain unsigned integral comparisons which can be
5335// converted to cbxx or tbxx instructions
5336
5337operand cmpOpUEqNeLtGe()
5338%{
5339  match(Bool);
5340  match(CmpOp);
5341  op_cost(0);
5342
5343  predicate(n->as_Bool()->_test._test == BoolTest::eq
5344            || n->as_Bool()->_test._test == BoolTest::ne
5345            || n->as_Bool()->_test._test == BoolTest::lt
5346            || n->as_Bool()->_test._test == BoolTest::ge);
5347
5348  format %{ "" %}
5349  interface(COND_INTER) %{
5350    equal(0x0, "eq");
5351    not_equal(0x1, "ne");
5352    less(0xb, "lt");
5353    greater_equal(0xa, "ge");
5354    less_equal(0xd, "le");
5355    greater(0xc, "gt");
5356    overflow(0x6, "vs");
5357    no_overflow(0x7, "vc");
5358  %}
5359%}
5360
5361// Special operand allowing long args to int ops to be truncated for free
5362
5363operand iRegL2I(iRegL reg) %{
5364
5365  op_cost(0);
5366
5367  match(ConvL2I reg);
5368
5369  format %{ "l2i($reg)" %}
5370
5371  interface(REG_INTER)
5372%}
5373
5374opclass vmem4(indirect, indIndex, indOffI4, indOffL4);
5375opclass vmem8(indirect, indIndex, indOffI8, indOffL8);
5376opclass vmem16(indirect, indIndex, indOffI16, indOffL16);
5377
5378//----------OPERAND CLASSES----------------------------------------------------
5379// Operand Classes are groups of operands that are used as to simplify
5380// instruction definitions by not requiring the AD writer to specify
5381// separate instructions for every form of operand when the
5382// instruction accepts multiple operand types with the same basic
5383// encoding and format. The classic case of this is memory operands.
5384
5385// memory is used to define read/write location for load/store
5386// instruction defs. we can turn a memory op into an Address
5387
5388opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI, indOffL,
5389               indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN);
5390
5391// iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5392// operations. it allows the src to be either an iRegI or a (ConvL2I
5393// iRegL). in the latter case the l2i normally planted for a ConvL2I
5394// can be elided because the 32-bit instruction will just employ the
5395// lower 32 bits anyway.
5396//
5397// n.b. this does not elide all L2I conversions. if the truncated
5398// value is consumed by more than one operation then the ConvL2I
5399// cannot be bundled into the consuming nodes so an l2i gets planted
5400// (actually a movw $dst $src) and the downstream instructions consume
5401// the result of the l2i as an iRegI input. That's a shame since the
5402// movw is actually redundant but its not too costly.
5403
5404opclass iRegIorL2I(iRegI, iRegL2I);
5405
5406//----------PIPELINE-----------------------------------------------------------
5407// Rules which define the behavior of the target architectures pipeline.
5408
5409// For specific pipelines, eg A53, define the stages of that pipeline
5410//pipe_desc(ISS, EX1, EX2, WR);
5411#define ISS S0
5412#define EX1 S1
5413#define EX2 S2
5414#define WR  S3
5415
5416// Integer ALU reg operation
5417pipeline %{
5418
5419attributes %{
5420  // ARM instructions are of fixed length
5421  fixed_size_instructions;        // Fixed size instructions TODO does
5422  max_instructions_per_bundle = 2;   // A53 = 2, A57 = 4
5423  // ARM instructions come in 32-bit word units
5424  instruction_unit_size = 4;         // An instruction is 4 bytes long
5425  instruction_fetch_unit_size = 64;  // The processor fetches one line
5426  instruction_fetch_units = 1;       // of 64 bytes
5427
5428  // List of nop instructions
5429  nops( MachNop );
5430%}
5431
5432// We don't use an actual pipeline model so don't care about resources
5433// or description. we do use pipeline classes to introduce fixed
5434// latencies
5435
5436//----------RESOURCES----------------------------------------------------------
5437// Resources are the functional units available to the machine
5438
5439resources( INS0, INS1, INS01 = INS0 | INS1,
5440           ALU0, ALU1, ALU = ALU0 | ALU1,
5441           MAC,
5442           DIV,
5443           BRANCH,
5444           LDST,
5445           NEON_FP);
5446
5447//----------PIPELINE DESCRIPTION-----------------------------------------------
5448// Pipeline Description specifies the stages in the machine's pipeline
5449
5450// Define the pipeline as a generic 6 stage pipeline
5451pipe_desc(S0, S1, S2, S3, S4, S5);
5452
5453//----------PIPELINE CLASSES---------------------------------------------------
5454// Pipeline Classes describe the stages in which input and output are
5455// referenced by the hardware pipeline.
5456
5457pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2)
5458%{
5459  single_instruction;
5460  src1   : S1(read);
5461  src2   : S2(read);
5462  dst    : S5(write);
5463  INS01  : ISS;
5464  NEON_FP : S5;
5465%}
5466
5467pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2)
5468%{
5469  single_instruction;
5470  src1   : S1(read);
5471  src2   : S2(read);
5472  dst    : S5(write);
5473  INS01  : ISS;
5474  NEON_FP : S5;
5475%}
5476
5477pipe_class fp_uop_s(vRegF dst, vRegF src)
5478%{
5479  single_instruction;
5480  src    : S1(read);
5481  dst    : S5(write);
5482  INS01  : ISS;
5483  NEON_FP : S5;
5484%}
5485
5486pipe_class fp_uop_d(vRegD dst, vRegD src)
5487%{
5488  single_instruction;
5489  src    : S1(read);
5490  dst    : S5(write);
5491  INS01  : ISS;
5492  NEON_FP : S5;
5493%}
5494
5495pipe_class fp_d2f(vRegF dst, vRegD src)
5496%{
5497  single_instruction;
5498  src    : S1(read);
5499  dst    : S5(write);
5500  INS01  : ISS;
5501  NEON_FP : S5;
5502%}
5503
5504pipe_class fp_f2d(vRegD dst, vRegF src)
5505%{
5506  single_instruction;
5507  src    : S1(read);
5508  dst    : S5(write);
5509  INS01  : ISS;
5510  NEON_FP : S5;
5511%}
5512
5513pipe_class fp_f2i(iRegINoSp dst, vRegF src)
5514%{
5515  single_instruction;
5516  src    : S1(read);
5517  dst    : S5(write);
5518  INS01  : ISS;
5519  NEON_FP : S5;
5520%}
5521
5522pipe_class fp_f2l(iRegLNoSp dst, vRegF src)
5523%{
5524  single_instruction;
5525  src    : S1(read);
5526  dst    : S5(write);
5527  INS01  : ISS;
5528  NEON_FP : S5;
5529%}
5530
5531pipe_class fp_i2f(vRegF dst, iRegIorL2I src)
5532%{
5533  single_instruction;
5534  src    : S1(read);
5535  dst    : S5(write);
5536  INS01  : ISS;
5537  NEON_FP : S5;
5538%}
5539
5540pipe_class fp_l2f(vRegF dst, iRegL src)
5541%{
5542  single_instruction;
5543  src    : S1(read);
5544  dst    : S5(write);
5545  INS01  : ISS;
5546  NEON_FP : S5;
5547%}
5548
5549pipe_class fp_d2i(iRegINoSp dst, vRegD src)
5550%{
5551  single_instruction;
5552  src    : S1(read);
5553  dst    : S5(write);
5554  INS01  : ISS;
5555  NEON_FP : S5;
5556%}
5557
5558pipe_class fp_d2l(iRegLNoSp dst, vRegD src)
5559%{
5560  single_instruction;
5561  src    : S1(read);
5562  dst    : S5(write);
5563  INS01  : ISS;
5564  NEON_FP : S5;
5565%}
5566
5567pipe_class fp_i2d(vRegD dst, iRegIorL2I src)
5568%{
5569  single_instruction;
5570  src    : S1(read);
5571  dst    : S5(write);
5572  INS01  : ISS;
5573  NEON_FP : S5;
5574%}
5575
5576pipe_class fp_l2d(vRegD dst, iRegIorL2I src)
5577%{
5578  single_instruction;
5579  src    : S1(read);
5580  dst    : S5(write);
5581  INS01  : ISS;
5582  NEON_FP : S5;
5583%}
5584
5585pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2)
5586%{
5587  single_instruction;
5588  src1   : S1(read);
5589  src2   : S2(read);
5590  dst    : S5(write);
5591  INS0   : ISS;
5592  NEON_FP : S5;
5593%}
5594
5595pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2)
5596%{
5597  single_instruction;
5598  src1   : S1(read);
5599  src2   : S2(read);
5600  dst    : S5(write);
5601  INS0   : ISS;
5602  NEON_FP : S5;
5603%}
5604
5605pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr)
5606%{
5607  single_instruction;
5608  cr     : S1(read);
5609  src1   : S1(read);
5610  src2   : S1(read);
5611  dst    : S3(write);
5612  INS01  : ISS;
5613  NEON_FP : S3;
5614%}
5615
5616pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr)
5617%{
5618  single_instruction;
5619  cr     : S1(read);
5620  src1   : S1(read);
5621  src2   : S1(read);
5622  dst    : S3(write);
5623  INS01  : ISS;
5624  NEON_FP : S3;
5625%}
5626
5627pipe_class fp_imm_s(vRegF dst)
5628%{
5629  single_instruction;
5630  dst    : S3(write);
5631  INS01  : ISS;
5632  NEON_FP : S3;
5633%}
5634
5635pipe_class fp_imm_d(vRegD dst)
5636%{
5637  single_instruction;
5638  dst    : S3(write);
5639  INS01  : ISS;
5640  NEON_FP : S3;
5641%}
5642
5643pipe_class fp_load_constant_s(vRegF dst)
5644%{
5645  single_instruction;
5646  dst    : S4(write);
5647  INS01  : ISS;
5648  NEON_FP : S4;
5649%}
5650
5651pipe_class fp_load_constant_d(vRegD dst)
5652%{
5653  single_instruction;
5654  dst    : S4(write);
5655  INS01  : ISS;
5656  NEON_FP : S4;
5657%}
5658
5659pipe_class vmul64(vecD dst, vecD src1, vecD src2)
5660%{
5661  single_instruction;
5662  dst    : S5(write);
5663  src1   : S1(read);
5664  src2   : S1(read);
5665  INS01  : ISS;
5666  NEON_FP : S5;
5667%}
5668
5669pipe_class vmul128(vecX dst, vecX src1, vecX src2)
5670%{
5671  single_instruction;
5672  dst    : S5(write);
5673  src1   : S1(read);
5674  src2   : S1(read);
5675  INS0   : ISS;
5676  NEON_FP : S5;
5677%}
5678
5679pipe_class vmla64(vecD dst, vecD src1, vecD src2)
5680%{
5681  single_instruction;
5682  dst    : S5(write);
5683  src1   : S1(read);
5684  src2   : S1(read);
5685  dst    : S1(read);
5686  INS01  : ISS;
5687  NEON_FP : S5;
5688%}
5689
5690pipe_class vmla128(vecX dst, vecX src1, vecX src2)
5691%{
5692  single_instruction;
5693  dst    : S5(write);
5694  src1   : S1(read);
5695  src2   : S1(read);
5696  dst    : S1(read);
5697  INS0   : ISS;
5698  NEON_FP : S5;
5699%}
5700
5701pipe_class vdop64(vecD dst, vecD src1, vecD src2)
5702%{
5703  single_instruction;
5704  dst    : S4(write);
5705  src1   : S2(read);
5706  src2   : S2(read);
5707  INS01  : ISS;
5708  NEON_FP : S4;
5709%}
5710
5711pipe_class vdop128(vecX dst, vecX src1, vecX src2)
5712%{
5713  single_instruction;
5714  dst    : S4(write);
5715  src1   : S2(read);
5716  src2   : S2(read);
5717  INS0   : ISS;
5718  NEON_FP : S4;
5719%}
5720
5721pipe_class vlogical64(vecD dst, vecD src1, vecD src2)
5722%{
5723  single_instruction;
5724  dst    : S3(write);
5725  src1   : S2(read);
5726  src2   : S2(read);
5727  INS01  : ISS;
5728  NEON_FP : S3;
5729%}
5730
5731pipe_class vlogical128(vecX dst, vecX src1, vecX src2)
5732%{
5733  single_instruction;
5734  dst    : S3(write);
5735  src1   : S2(read);
5736  src2   : S2(read);
5737  INS0   : ISS;
5738  NEON_FP : S3;
5739%}
5740
5741pipe_class vshift64(vecD dst, vecD src, vecX shift)
5742%{
5743  single_instruction;
5744  dst    : S3(write);
5745  src    : S1(read);
5746  shift  : S1(read);
5747  INS01  : ISS;
5748  NEON_FP : S3;
5749%}
5750
5751pipe_class vshift128(vecX dst, vecX src, vecX shift)
5752%{
5753  single_instruction;
5754  dst    : S3(write);
5755  src    : S1(read);
5756  shift  : S1(read);
5757  INS0   : ISS;
5758  NEON_FP : S3;
5759%}
5760
5761pipe_class vshift64_imm(vecD dst, vecD src, immI shift)
5762%{
5763  single_instruction;
5764  dst    : S3(write);
5765  src    : S1(read);
5766  INS01  : ISS;
5767  NEON_FP : S3;
5768%}
5769
5770pipe_class vshift128_imm(vecX dst, vecX src, immI shift)
5771%{
5772  single_instruction;
5773  dst    : S3(write);
5774  src    : S1(read);
5775  INS0   : ISS;
5776  NEON_FP : S3;
5777%}
5778
5779pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2)
5780%{
5781  single_instruction;
5782  dst    : S5(write);
5783  src1   : S1(read);
5784  src2   : S1(read);
5785  INS01  : ISS;
5786  NEON_FP : S5;
5787%}
5788
5789pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2)
5790%{
5791  single_instruction;
5792  dst    : S5(write);
5793  src1   : S1(read);
5794  src2   : S1(read);
5795  INS0   : ISS;
5796  NEON_FP : S5;
5797%}
5798
5799pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2)
5800%{
5801  single_instruction;
5802  dst    : S5(write);
5803  src1   : S1(read);
5804  src2   : S1(read);
5805  INS0   : ISS;
5806  NEON_FP : S5;
5807%}
5808
5809pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2)
5810%{
5811  single_instruction;
5812  dst    : S5(write);
5813  src1   : S1(read);
5814  src2   : S1(read);
5815  INS0   : ISS;
5816  NEON_FP : S5;
5817%}
5818
5819pipe_class vsqrt_fp128(vecX dst, vecX src)
5820%{
5821  single_instruction;
5822  dst    : S5(write);
5823  src    : S1(read);
5824  INS0   : ISS;
5825  NEON_FP : S5;
5826%}
5827
5828pipe_class vunop_fp64(vecD dst, vecD src)
5829%{
5830  single_instruction;
5831  dst    : S5(write);
5832  src    : S1(read);
5833  INS01  : ISS;
5834  NEON_FP : S5;
5835%}
5836
5837pipe_class vunop_fp128(vecX dst, vecX src)
5838%{
5839  single_instruction;
5840  dst    : S5(write);
5841  src    : S1(read);
5842  INS0   : ISS;
5843  NEON_FP : S5;
5844%}
5845
5846pipe_class vdup_reg_reg64(vecD dst, iRegI src)
5847%{
5848  single_instruction;
5849  dst    : S3(write);
5850  src    : S1(read);
5851  INS01  : ISS;
5852  NEON_FP : S3;
5853%}
5854
5855pipe_class vdup_reg_reg128(vecX dst, iRegI src)
5856%{
5857  single_instruction;
5858  dst    : S3(write);
5859  src    : S1(read);
5860  INS01  : ISS;
5861  NEON_FP : S3;
5862%}
5863
5864pipe_class vdup_reg_freg64(vecD dst, vRegF src)
5865%{
5866  single_instruction;
5867  dst    : S3(write);
5868  src    : S1(read);
5869  INS01  : ISS;
5870  NEON_FP : S3;
5871%}
5872
5873pipe_class vdup_reg_freg128(vecX dst, vRegF src)
5874%{
5875  single_instruction;
5876  dst    : S3(write);
5877  src    : S1(read);
5878  INS01  : ISS;
5879  NEON_FP : S3;
5880%}
5881
5882pipe_class vdup_reg_dreg128(vecX dst, vRegD src)
5883%{
5884  single_instruction;
5885  dst    : S3(write);
5886  src    : S1(read);
5887  INS01  : ISS;
5888  NEON_FP : S3;
5889%}
5890
5891pipe_class vmovi_reg_imm64(vecD dst)
5892%{
5893  single_instruction;
5894  dst    : S3(write);
5895  INS01  : ISS;
5896  NEON_FP : S3;
5897%}
5898
5899pipe_class vmovi_reg_imm128(vecX dst)
5900%{
5901  single_instruction;
5902  dst    : S3(write);
5903  INS0   : ISS;
5904  NEON_FP : S3;
5905%}
5906
5907pipe_class vload_reg_mem64(vecD dst, vmem8 mem)
5908%{
5909  single_instruction;
5910  dst    : S5(write);
5911  mem    : ISS(read);
5912  INS01  : ISS;
5913  NEON_FP : S3;
5914%}
5915
5916pipe_class vload_reg_mem128(vecX dst, vmem16 mem)
5917%{
5918  single_instruction;
5919  dst    : S5(write);
5920  mem    : ISS(read);
5921  INS01  : ISS;
5922  NEON_FP : S3;
5923%}
5924
5925pipe_class vstore_reg_mem64(vecD src, vmem8 mem)
5926%{
5927  single_instruction;
5928  mem    : ISS(read);
5929  src    : S2(read);
5930  INS01  : ISS;
5931  NEON_FP : S3;
5932%}
5933
5934pipe_class vstore_reg_mem128(vecD src, vmem16 mem)
5935%{
5936  single_instruction;
5937  mem    : ISS(read);
5938  src    : S2(read);
5939  INS01  : ISS;
5940  NEON_FP : S3;
5941%}
5942
5943//------- Integer ALU operations --------------------------
5944
5945// Integer ALU reg-reg operation
5946// Operands needed in EX1, result generated in EX2
5947// Eg.  ADD     x0, x1, x2
5948pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2)
5949%{
5950  single_instruction;
5951  dst    : EX2(write);
5952  src1   : EX1(read);
5953  src2   : EX1(read);
5954  INS01  : ISS; // Dual issue as instruction 0 or 1
5955  ALU    : EX2;
5956%}
5957
5958// Integer ALU reg-reg operation with constant shift
5959// Shifted register must be available in LATE_ISS instead of EX1
5960// Eg.  ADD     x0, x1, x2, LSL #2
5961pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift)
5962%{
5963  single_instruction;
5964  dst    : EX2(write);
5965  src1   : EX1(read);
5966  src2   : ISS(read);
5967  INS01  : ISS;
5968  ALU    : EX2;
5969%}
5970
5971// Integer ALU reg operation with constant shift
5972// Eg.  LSL     x0, x1, #shift
5973pipe_class ialu_reg_shift(iRegI dst, iRegI src1)
5974%{
5975  single_instruction;
5976  dst    : EX2(write);
5977  src1   : ISS(read);
5978  INS01  : ISS;
5979  ALU    : EX2;
5980%}
5981
5982// Integer ALU reg-reg operation with variable shift
5983// Both operands must be available in LATE_ISS instead of EX1
5984// Result is available in EX1 instead of EX2
5985// Eg.  LSLV    x0, x1, x2
5986pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2)
5987%{
5988  single_instruction;
5989  dst    : EX1(write);
5990  src1   : ISS(read);
5991  src2   : ISS(read);
5992  INS01  : ISS;
5993  ALU    : EX1;
5994%}
5995
5996// Integer ALU reg-reg operation with extract
5997// As for _vshift above, but result generated in EX2
5998// Eg.  EXTR    x0, x1, x2, #N
5999pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2)
6000%{
6001  single_instruction;
6002  dst    : EX2(write);
6003  src1   : ISS(read);
6004  src2   : ISS(read);
6005  INS1   : ISS; // Can only dual issue as Instruction 1
6006  ALU    : EX1;
6007%}
6008
6009// Integer ALU reg operation
6010// Eg.  NEG     x0, x1
6011pipe_class ialu_reg(iRegI dst, iRegI src)
6012%{
6013  single_instruction;
6014  dst    : EX2(write);
6015  src    : EX1(read);
6016  INS01  : ISS;
6017  ALU    : EX2;
6018%}
6019
6020// Integer ALU reg mmediate operation
6021// Eg.  ADD     x0, x1, #N
6022pipe_class ialu_reg_imm(iRegI dst, iRegI src1)
6023%{
6024  single_instruction;
6025  dst    : EX2(write);
6026  src1   : EX1(read);
6027  INS01  : ISS;
6028  ALU    : EX2;
6029%}
6030
6031// Integer ALU immediate operation (no source operands)
6032// Eg.  MOV     x0, #N
6033pipe_class ialu_imm(iRegI dst)
6034%{
6035  single_instruction;
6036  dst    : EX1(write);
6037  INS01  : ISS;
6038  ALU    : EX1;
6039%}
6040
6041//------- Compare operation -------------------------------
6042
6043// Compare reg-reg
6044// Eg.  CMP     x0, x1
6045pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
6046%{
6047  single_instruction;
6048//  fixed_latency(16);
6049  cr     : EX2(write);
6050  op1    : EX1(read);
6051  op2    : EX1(read);
6052  INS01  : ISS;
6053  ALU    : EX2;
6054%}
6055
6056// Compare reg-reg
6057// Eg.  CMP     x0, #N
6058pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1)
6059%{
6060  single_instruction;
6061//  fixed_latency(16);
6062  cr     : EX2(write);
6063  op1    : EX1(read);
6064  INS01  : ISS;
6065  ALU    : EX2;
6066%}
6067
6068//------- Conditional instructions ------------------------
6069
6070// Conditional no operands
6071// Eg.  CSINC   x0, zr, zr, <cond>
6072pipe_class icond_none(iRegI dst, rFlagsReg cr)
6073%{
6074  single_instruction;
6075  cr     : EX1(read);
6076  dst    : EX2(write);
6077  INS01  : ISS;
6078  ALU    : EX2;
6079%}
6080
6081// Conditional 2 operand
6082// EG.  CSEL    X0, X1, X2, <cond>
6083pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr)
6084%{
6085  single_instruction;
6086  cr     : EX1(read);
6087  src1   : EX1(read);
6088  src2   : EX1(read);
6089  dst    : EX2(write);
6090  INS01  : ISS;
6091  ALU    : EX2;
6092%}
6093
6094// Conditional 2 operand
6095// EG.  CSEL    X0, X1, X2, <cond>
6096pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr)
6097%{
6098  single_instruction;
6099  cr     : EX1(read);
6100  src    : EX1(read);
6101  dst    : EX2(write);
6102  INS01  : ISS;
6103  ALU    : EX2;
6104%}
6105
6106//------- Multiply pipeline operations --------------------
6107
6108// Multiply reg-reg
6109// Eg.  MUL     w0, w1, w2
6110pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6111%{
6112  single_instruction;
6113  dst    : WR(write);
6114  src1   : ISS(read);
6115  src2   : ISS(read);
6116  INS01  : ISS;
6117  MAC    : WR;
6118%}
6119
6120// Multiply accumulate
6121// Eg.  MADD    w0, w1, w2, w3
6122pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6123%{
6124  single_instruction;
6125  dst    : WR(write);
6126  src1   : ISS(read);
6127  src2   : ISS(read);
6128  src3   : ISS(read);
6129  INS01  : ISS;
6130  MAC    : WR;
6131%}
6132
6133// Eg.  MUL     w0, w1, w2
6134pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6135%{
6136  single_instruction;
6137  fixed_latency(3); // Maximum latency for 64 bit mul
6138  dst    : WR(write);
6139  src1   : ISS(read);
6140  src2   : ISS(read);
6141  INS01  : ISS;
6142  MAC    : WR;
6143%}
6144
6145// Multiply accumulate
6146// Eg.  MADD    w0, w1, w2, w3
6147pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6148%{
6149  single_instruction;
6150  fixed_latency(3); // Maximum latency for 64 bit mul
6151  dst    : WR(write);
6152  src1   : ISS(read);
6153  src2   : ISS(read);
6154  src3   : ISS(read);
6155  INS01  : ISS;
6156  MAC    : WR;
6157%}
6158
6159//------- Divide pipeline operations --------------------
6160
6161// Eg.  SDIV    w0, w1, w2
6162pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6163%{
6164  single_instruction;
6165  fixed_latency(8); // Maximum latency for 32 bit divide
6166  dst    : WR(write);
6167  src1   : ISS(read);
6168  src2   : ISS(read);
6169  INS0   : ISS; // Can only dual issue as instruction 0
6170  DIV    : WR;
6171%}
6172
6173// Eg.  SDIV    x0, x1, x2
6174pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6175%{
6176  single_instruction;
6177  fixed_latency(16); // Maximum latency for 64 bit divide
6178  dst    : WR(write);
6179  src1   : ISS(read);
6180  src2   : ISS(read);
6181  INS0   : ISS; // Can only dual issue as instruction 0
6182  DIV    : WR;
6183%}
6184
6185//------- Load pipeline operations ------------------------
6186
6187// Load - prefetch
6188// Eg.  PFRM    <mem>
6189pipe_class iload_prefetch(memory mem)
6190%{
6191  single_instruction;
6192  mem    : ISS(read);
6193  INS01  : ISS;
6194  LDST   : WR;
6195%}
6196
6197// Load - reg, mem
6198// Eg.  LDR     x0, <mem>
6199pipe_class iload_reg_mem(iRegI dst, memory mem)
6200%{
6201  single_instruction;
6202  dst    : WR(write);
6203  mem    : ISS(read);
6204  INS01  : ISS;
6205  LDST   : WR;
6206%}
6207
6208// Load - reg, reg
6209// Eg.  LDR     x0, [sp, x1]
6210pipe_class iload_reg_reg(iRegI dst, iRegI src)
6211%{
6212  single_instruction;
6213  dst    : WR(write);
6214  src    : ISS(read);
6215  INS01  : ISS;
6216  LDST   : WR;
6217%}
6218
6219//------- Store pipeline operations -----------------------
6220
6221// Store - zr, mem
6222// Eg.  STR     zr, <mem>
6223pipe_class istore_mem(memory mem)
6224%{
6225  single_instruction;
6226  mem    : ISS(read);
6227  INS01  : ISS;
6228  LDST   : WR;
6229%}
6230
6231// Store - reg, mem
6232// Eg.  STR     x0, <mem>
6233pipe_class istore_reg_mem(iRegI src, memory mem)
6234%{
6235  single_instruction;
6236  mem    : ISS(read);
6237  src    : EX2(read);
6238  INS01  : ISS;
6239  LDST   : WR;
6240%}
6241
6242// Store - reg, reg
6243// Eg. STR      x0, [sp, x1]
6244pipe_class istore_reg_reg(iRegI dst, iRegI src)
6245%{
6246  single_instruction;
6247  dst    : ISS(read);
6248  src    : EX2(read);
6249  INS01  : ISS;
6250  LDST   : WR;
6251%}
6252
6253//------- Store pipeline operations -----------------------
6254
6255// Branch
6256pipe_class pipe_branch()
6257%{
6258  single_instruction;
6259  INS01  : ISS;
6260  BRANCH : EX1;
6261%}
6262
6263// Conditional branch
6264pipe_class pipe_branch_cond(rFlagsReg cr)
6265%{
6266  single_instruction;
6267  cr     : EX1(read);
6268  INS01  : ISS;
6269  BRANCH : EX1;
6270%}
6271
6272// Compare & Branch
6273// EG.  CBZ/CBNZ
6274pipe_class pipe_cmp_branch(iRegI op1)
6275%{
6276  single_instruction;
6277  op1    : EX1(read);
6278  INS01  : ISS;
6279  BRANCH : EX1;
6280%}
6281
6282//------- Synchronisation operations ----------------------
6283
6284// Any operation requiring serialization.
6285// EG.  DMB/Atomic Ops/Load Acquire/Str Release
6286pipe_class pipe_serial()
6287%{
6288  single_instruction;
6289  force_serialization;
6290  fixed_latency(16);
6291  INS01  : ISS(2); // Cannot dual issue with any other instruction
6292  LDST   : WR;
6293%}
6294
6295// Generic big/slow expanded idiom - also serialized
6296pipe_class pipe_slow()
6297%{
6298  instruction_count(10);
6299  multiple_bundles;
6300  force_serialization;
6301  fixed_latency(16);
6302  INS01  : ISS(2); // Cannot dual issue with any other instruction
6303  LDST   : WR;
6304%}
6305
6306// Empty pipeline class
6307pipe_class pipe_class_empty()
6308%{
6309  single_instruction;
6310  fixed_latency(0);
6311%}
6312
6313// Default pipeline class.
6314pipe_class pipe_class_default()
6315%{
6316  single_instruction;
6317  fixed_latency(2);
6318%}
6319
6320// Pipeline class for compares.
6321pipe_class pipe_class_compare()
6322%{
6323  single_instruction;
6324  fixed_latency(16);
6325%}
6326
6327// Pipeline class for memory operations.
6328pipe_class pipe_class_memory()
6329%{
6330  single_instruction;
6331  fixed_latency(16);
6332%}
6333
6334// Pipeline class for call.
6335pipe_class pipe_class_call()
6336%{
6337  single_instruction;
6338  fixed_latency(100);
6339%}
6340
6341// Define the class for the Nop node.
6342define %{
6343   MachNop = pipe_class_empty;
6344%}
6345
6346%}
6347//----------INSTRUCTIONS-------------------------------------------------------
6348//
6349// match      -- States which machine-independent subtree may be replaced
6350//               by this instruction.
6351// ins_cost   -- The estimated cost of this instruction is used by instruction
6352//               selection to identify a minimum cost tree of machine
6353//               instructions that matches a tree of machine-independent
6354//               instructions.
6355// format     -- A string providing the disassembly for this instruction.
6356//               The value of an instruction's operand may be inserted
6357//               by referring to it with a '$' prefix.
6358// opcode     -- Three instruction opcodes may be provided.  These are referred
6359//               to within an encode class as $primary, $secondary, and $tertiary
6360//               rrspectively.  The primary opcode is commonly used to
6361//               indicate the type of machine instruction, while secondary
6362//               and tertiary are often used for prefix options or addressing
6363//               modes.
6364// ins_encode -- A list of encode classes with parameters. The encode class
6365//               name must have been defined in an 'enc_class' specification
6366//               in the encode section of the architecture description.
6367
6368// ============================================================================
6369// Memory (Load/Store) Instructions
6370
6371// Load Instructions
6372
6373// Load Byte (8 bit signed)
6374instruct loadB(iRegINoSp dst, memory mem)
6375%{
6376  match(Set dst (LoadB mem));
6377  predicate(!needs_acquiring_load(n));
6378
6379  ins_cost(4 * INSN_COST);
6380  format %{ "ldrsbw  $dst, $mem\t# byte" %}
6381
6382  ins_encode(aarch64_enc_ldrsbw(dst, mem));
6383
6384  ins_pipe(iload_reg_mem);
6385%}
6386
6387// Load Byte (8 bit signed) into long
6388instruct loadB2L(iRegLNoSp dst, memory mem)
6389%{
6390  match(Set dst (ConvI2L (LoadB mem)));
6391  predicate(!needs_acquiring_load(n->in(1)));
6392
6393  ins_cost(4 * INSN_COST);
6394  format %{ "ldrsb  $dst, $mem\t# byte" %}
6395
6396  ins_encode(aarch64_enc_ldrsb(dst, mem));
6397
6398  ins_pipe(iload_reg_mem);
6399%}
6400
6401// Load Byte (8 bit unsigned)
6402instruct loadUB(iRegINoSp dst, memory mem)
6403%{
6404  match(Set dst (LoadUB mem));
6405  predicate(!needs_acquiring_load(n));
6406
6407  ins_cost(4 * INSN_COST);
6408  format %{ "ldrbw  $dst, $mem\t# byte" %}
6409
6410  ins_encode(aarch64_enc_ldrb(dst, mem));
6411
6412  ins_pipe(iload_reg_mem);
6413%}
6414
6415// Load Byte (8 bit unsigned) into long
6416instruct loadUB2L(iRegLNoSp dst, memory mem)
6417%{
6418  match(Set dst (ConvI2L (LoadUB mem)));
6419  predicate(!needs_acquiring_load(n->in(1)));
6420
6421  ins_cost(4 * INSN_COST);
6422  format %{ "ldrb  $dst, $mem\t# byte" %}
6423
6424  ins_encode(aarch64_enc_ldrb(dst, mem));
6425
6426  ins_pipe(iload_reg_mem);
6427%}
6428
6429// Load Short (16 bit signed)
6430instruct loadS(iRegINoSp dst, memory mem)
6431%{
6432  match(Set dst (LoadS mem));
6433  predicate(!needs_acquiring_load(n));
6434
6435  ins_cost(4 * INSN_COST);
6436  format %{ "ldrshw  $dst, $mem\t# short" %}
6437
6438  ins_encode(aarch64_enc_ldrshw(dst, mem));
6439
6440  ins_pipe(iload_reg_mem);
6441%}
6442
6443// Load Short (16 bit signed) into long
6444instruct loadS2L(iRegLNoSp dst, memory mem)
6445%{
6446  match(Set dst (ConvI2L (LoadS mem)));
6447  predicate(!needs_acquiring_load(n->in(1)));
6448
6449  ins_cost(4 * INSN_COST);
6450  format %{ "ldrsh  $dst, $mem\t# short" %}
6451
6452  ins_encode(aarch64_enc_ldrsh(dst, mem));
6453
6454  ins_pipe(iload_reg_mem);
6455%}
6456
6457// Load Char (16 bit unsigned)
6458instruct loadUS(iRegINoSp dst, memory mem)
6459%{
6460  match(Set dst (LoadUS mem));
6461  predicate(!needs_acquiring_load(n));
6462
6463  ins_cost(4 * INSN_COST);
6464  format %{ "ldrh  $dst, $mem\t# short" %}
6465
6466  ins_encode(aarch64_enc_ldrh(dst, mem));
6467
6468  ins_pipe(iload_reg_mem);
6469%}
6470
6471// Load Short/Char (16 bit unsigned) into long
6472instruct loadUS2L(iRegLNoSp dst, memory mem)
6473%{
6474  match(Set dst (ConvI2L (LoadUS mem)));
6475  predicate(!needs_acquiring_load(n->in(1)));
6476
6477  ins_cost(4 * INSN_COST);
6478  format %{ "ldrh  $dst, $mem\t# short" %}
6479
6480  ins_encode(aarch64_enc_ldrh(dst, mem));
6481
6482  ins_pipe(iload_reg_mem);
6483%}
6484
6485// Load Integer (32 bit signed)
6486instruct loadI(iRegINoSp dst, memory mem)
6487%{
6488  match(Set dst (LoadI mem));
6489  predicate(!needs_acquiring_load(n));
6490
6491  ins_cost(4 * INSN_COST);
6492  format %{ "ldrw  $dst, $mem\t# int" %}
6493
6494  ins_encode(aarch64_enc_ldrw(dst, mem));
6495
6496  ins_pipe(iload_reg_mem);
6497%}
6498
6499// Load Integer (32 bit signed) into long
6500instruct loadI2L(iRegLNoSp dst, memory mem)
6501%{
6502  match(Set dst (ConvI2L (LoadI mem)));
6503  predicate(!needs_acquiring_load(n->in(1)));
6504
6505  ins_cost(4 * INSN_COST);
6506  format %{ "ldrsw  $dst, $mem\t# int" %}
6507
6508  ins_encode(aarch64_enc_ldrsw(dst, mem));
6509
6510  ins_pipe(iload_reg_mem);
6511%}
6512
6513// Load Integer (32 bit unsigned) into long
6514instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask)
6515%{
6516  match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
6517  predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load()));
6518
6519  ins_cost(4 * INSN_COST);
6520  format %{ "ldrw  $dst, $mem\t# int" %}
6521
6522  ins_encode(aarch64_enc_ldrw(dst, mem));
6523
6524  ins_pipe(iload_reg_mem);
6525%}
6526
6527// Load Long (64 bit signed)
6528instruct loadL(iRegLNoSp dst, memory mem)
6529%{
6530  match(Set dst (LoadL mem));
6531  predicate(!needs_acquiring_load(n));
6532
6533  ins_cost(4 * INSN_COST);
6534  format %{ "ldr  $dst, $mem\t# int" %}
6535
6536  ins_encode(aarch64_enc_ldr(dst, mem));
6537
6538  ins_pipe(iload_reg_mem);
6539%}
6540
6541// Load Range
6542instruct loadRange(iRegINoSp dst, memory mem)
6543%{
6544  match(Set dst (LoadRange mem));
6545
6546  ins_cost(4 * INSN_COST);
6547  format %{ "ldrw  $dst, $mem\t# range" %}
6548
6549  ins_encode(aarch64_enc_ldrw(dst, mem));
6550
6551  ins_pipe(iload_reg_mem);
6552%}
6553
6554// Load Pointer
6555instruct loadP(iRegPNoSp dst, memory mem)
6556%{
6557  match(Set dst (LoadP mem));
6558  predicate(!needs_acquiring_load(n));
6559
6560  ins_cost(4 * INSN_COST);
6561  format %{ "ldr  $dst, $mem\t# ptr" %}
6562
6563  ins_encode(aarch64_enc_ldr(dst, mem));
6564
6565  ins_pipe(iload_reg_mem);
6566%}
6567
6568// Load Compressed Pointer
6569instruct loadN(iRegNNoSp dst, memory mem)
6570%{
6571  match(Set dst (LoadN mem));
6572  predicate(!needs_acquiring_load(n));
6573
6574  ins_cost(4 * INSN_COST);
6575  format %{ "ldrw  $dst, $mem\t# compressed ptr" %}
6576
6577  ins_encode(aarch64_enc_ldrw(dst, mem));
6578
6579  ins_pipe(iload_reg_mem);
6580%}
6581
6582// Load Klass Pointer
6583instruct loadKlass(iRegPNoSp dst, memory mem)
6584%{
6585  match(Set dst (LoadKlass mem));
6586  predicate(!needs_acquiring_load(n));
6587
6588  ins_cost(4 * INSN_COST);
6589  format %{ "ldr  $dst, $mem\t# class" %}
6590
6591  ins_encode(aarch64_enc_ldr(dst, mem));
6592
6593  ins_pipe(iload_reg_mem);
6594%}
6595
6596// Load Narrow Klass Pointer
6597instruct loadNKlass(iRegNNoSp dst, memory mem)
6598%{
6599  match(Set dst (LoadNKlass mem));
6600  predicate(!needs_acquiring_load(n));
6601
6602  ins_cost(4 * INSN_COST);
6603  format %{ "ldrw  $dst, $mem\t# compressed class ptr" %}
6604
6605  ins_encode(aarch64_enc_ldrw(dst, mem));
6606
6607  ins_pipe(iload_reg_mem);
6608%}
6609
6610// Load Float
6611instruct loadF(vRegF dst, memory mem)
6612%{
6613  match(Set dst (LoadF mem));
6614  predicate(!needs_acquiring_load(n));
6615
6616  ins_cost(4 * INSN_COST);
6617  format %{ "ldrs  $dst, $mem\t# float" %}
6618
6619  ins_encode( aarch64_enc_ldrs(dst, mem) );
6620
6621  ins_pipe(pipe_class_memory);
6622%}
6623
6624// Load Double
6625instruct loadD(vRegD dst, memory mem)
6626%{
6627  match(Set dst (LoadD mem));
6628  predicate(!needs_acquiring_load(n));
6629
6630  ins_cost(4 * INSN_COST);
6631  format %{ "ldrd  $dst, $mem\t# double" %}
6632
6633  ins_encode( aarch64_enc_ldrd(dst, mem) );
6634
6635  ins_pipe(pipe_class_memory);
6636%}
6637
6638
6639// Load Int Constant
6640instruct loadConI(iRegINoSp dst, immI src)
6641%{
6642  match(Set dst src);
6643
6644  ins_cost(INSN_COST);
6645  format %{ "mov $dst, $src\t# int" %}
6646
6647  ins_encode( aarch64_enc_movw_imm(dst, src) );
6648
6649  ins_pipe(ialu_imm);
6650%}
6651
6652// Load Long Constant
6653instruct loadConL(iRegLNoSp dst, immL src)
6654%{
6655  match(Set dst src);
6656
6657  ins_cost(INSN_COST);
6658  format %{ "mov $dst, $src\t# long" %}
6659
6660  ins_encode( aarch64_enc_mov_imm(dst, src) );
6661
6662  ins_pipe(ialu_imm);
6663%}
6664
6665// Load Pointer Constant
6666
6667instruct loadConP(iRegPNoSp dst, immP con)
6668%{
6669  match(Set dst con);
6670
6671  ins_cost(INSN_COST * 4);
6672  format %{
6673    "mov  $dst, $con\t# ptr\n\t"
6674  %}
6675
6676  ins_encode(aarch64_enc_mov_p(dst, con));
6677
6678  ins_pipe(ialu_imm);
6679%}
6680
6681// Load Null Pointer Constant
6682
6683instruct loadConP0(iRegPNoSp dst, immP0 con)
6684%{
6685  match(Set dst con);
6686
6687  ins_cost(INSN_COST);
6688  format %{ "mov  $dst, $con\t# NULL ptr" %}
6689
6690  ins_encode(aarch64_enc_mov_p0(dst, con));
6691
6692  ins_pipe(ialu_imm);
6693%}
6694
6695// Load Pointer Constant One
6696
6697instruct loadConP1(iRegPNoSp dst, immP_1 con)
6698%{
6699  match(Set dst con);
6700
6701  ins_cost(INSN_COST);
6702  format %{ "mov  $dst, $con\t# NULL ptr" %}
6703
6704  ins_encode(aarch64_enc_mov_p1(dst, con));
6705
6706  ins_pipe(ialu_imm);
6707%}
6708
6709// Load Poll Page Constant
6710
6711instruct loadConPollPage(iRegPNoSp dst, immPollPage con)
6712%{
6713  match(Set dst con);
6714
6715  ins_cost(INSN_COST);
6716  format %{ "adr  $dst, $con\t# Poll Page Ptr" %}
6717
6718  ins_encode(aarch64_enc_mov_poll_page(dst, con));
6719
6720  ins_pipe(ialu_imm);
6721%}
6722
6723// Load Byte Map Base Constant
6724
6725instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con)
6726%{
6727  match(Set dst con);
6728
6729  ins_cost(INSN_COST);
6730  format %{ "adr  $dst, $con\t# Byte Map Base" %}
6731
6732  ins_encode(aarch64_enc_mov_byte_map_base(dst, con));
6733
6734  ins_pipe(ialu_imm);
6735%}
6736
6737// Load Narrow Pointer Constant
6738
6739instruct loadConN(iRegNNoSp dst, immN con)
6740%{
6741  match(Set dst con);
6742
6743  ins_cost(INSN_COST * 4);
6744  format %{ "mov  $dst, $con\t# compressed ptr" %}
6745
6746  ins_encode(aarch64_enc_mov_n(dst, con));
6747
6748  ins_pipe(ialu_imm);
6749%}
6750
6751// Load Narrow Null Pointer Constant
6752
6753instruct loadConN0(iRegNNoSp dst, immN0 con)
6754%{
6755  match(Set dst con);
6756
6757  ins_cost(INSN_COST);
6758  format %{ "mov  $dst, $con\t# compressed NULL ptr" %}
6759
6760  ins_encode(aarch64_enc_mov_n0(dst, con));
6761
6762  ins_pipe(ialu_imm);
6763%}
6764
6765// Load Narrow Klass Constant
6766
6767instruct loadConNKlass(iRegNNoSp dst, immNKlass con)
6768%{
6769  match(Set dst con);
6770
6771  ins_cost(INSN_COST);
6772  format %{ "mov  $dst, $con\t# compressed klass ptr" %}
6773
6774  ins_encode(aarch64_enc_mov_nk(dst, con));
6775
6776  ins_pipe(ialu_imm);
6777%}
6778
6779// Load Packed Float Constant
6780
6781instruct loadConF_packed(vRegF dst, immFPacked con) %{
6782  match(Set dst con);
6783  ins_cost(INSN_COST * 4);
6784  format %{ "fmovs  $dst, $con"%}
6785  ins_encode %{
6786    __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant);
6787  %}
6788
6789  ins_pipe(fp_imm_s);
6790%}
6791
6792// Load Float Constant
6793
6794instruct loadConF(vRegF dst, immF con) %{
6795  match(Set dst con);
6796
6797  ins_cost(INSN_COST * 4);
6798
6799  format %{
6800    "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
6801  %}
6802
6803  ins_encode %{
6804    __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con));
6805  %}
6806
6807  ins_pipe(fp_load_constant_s);
6808%}
6809
6810// Load Packed Double Constant
6811
6812instruct loadConD_packed(vRegD dst, immDPacked con) %{
6813  match(Set dst con);
6814  ins_cost(INSN_COST);
6815  format %{ "fmovd  $dst, $con"%}
6816  ins_encode %{
6817    __ fmovd(as_FloatRegister($dst$$reg), $con$$constant);
6818  %}
6819
6820  ins_pipe(fp_imm_d);
6821%}
6822
6823// Load Double Constant
6824
6825instruct loadConD(vRegD dst, immD con) %{
6826  match(Set dst con);
6827
6828  ins_cost(INSN_COST * 5);
6829  format %{
6830    "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
6831  %}
6832
6833  ins_encode %{
6834    __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con));
6835  %}
6836
6837  ins_pipe(fp_load_constant_d);
6838%}
6839
6840// Store Instructions
6841
6842// Store CMS card-mark Immediate
6843instruct storeimmCM0(immI0 zero, memory mem)
6844%{
6845  match(Set mem (StoreCM mem zero));
6846  predicate(unnecessary_storestore(n));
6847
6848  ins_cost(INSN_COST);
6849  format %{ "storestore (elided)\n\t"
6850            "strb zr, $mem\t# byte" %}
6851
6852  ins_encode(aarch64_enc_strb0(mem));
6853
6854  ins_pipe(istore_mem);
6855%}
6856
6857// Store CMS card-mark Immediate with intervening StoreStore
6858// needed when using CMS with no conditional card marking
6859instruct storeimmCM0_ordered(immI0 zero, memory mem)
6860%{
6861  match(Set mem (StoreCM mem zero));
6862
6863  ins_cost(INSN_COST * 2);
6864  format %{ "storestore\n\t"
6865            "dmb ishst"
6866            "\n\tstrb zr, $mem\t# byte" %}
6867
6868  ins_encode(aarch64_enc_strb0_ordered(mem));
6869
6870  ins_pipe(istore_mem);
6871%}
6872
6873// Store Byte
6874instruct storeB(iRegIorL2I src, memory mem)
6875%{
6876  match(Set mem (StoreB mem src));
6877  predicate(!needs_releasing_store(n));
6878
6879  ins_cost(INSN_COST);
6880  format %{ "strb  $src, $mem\t# byte" %}
6881
6882  ins_encode(aarch64_enc_strb(src, mem));
6883
6884  ins_pipe(istore_reg_mem);
6885%}
6886
6887
6888instruct storeimmB0(immI0 zero, memory mem)
6889%{
6890  match(Set mem (StoreB mem zero));
6891  predicate(!needs_releasing_store(n));
6892
6893  ins_cost(INSN_COST);
6894  format %{ "strb rscractch2, $mem\t# byte" %}
6895
6896  ins_encode(aarch64_enc_strb0(mem));
6897
6898  ins_pipe(istore_mem);
6899%}
6900
6901// Store Char/Short
6902instruct storeC(iRegIorL2I src, memory mem)
6903%{
6904  match(Set mem (StoreC mem src));
6905  predicate(!needs_releasing_store(n));
6906
6907  ins_cost(INSN_COST);
6908  format %{ "strh  $src, $mem\t# short" %}
6909
6910  ins_encode(aarch64_enc_strh(src, mem));
6911
6912  ins_pipe(istore_reg_mem);
6913%}
6914
6915instruct storeimmC0(immI0 zero, memory mem)
6916%{
6917  match(Set mem (StoreC mem zero));
6918  predicate(!needs_releasing_store(n));
6919
6920  ins_cost(INSN_COST);
6921  format %{ "strh  zr, $mem\t# short" %}
6922
6923  ins_encode(aarch64_enc_strh0(mem));
6924
6925  ins_pipe(istore_mem);
6926%}
6927
6928// Store Integer
6929
6930instruct storeI(iRegIorL2I src, memory mem)
6931%{
6932  match(Set mem(StoreI mem src));
6933  predicate(!needs_releasing_store(n));
6934
6935  ins_cost(INSN_COST);
6936  format %{ "strw  $src, $mem\t# int" %}
6937
6938  ins_encode(aarch64_enc_strw(src, mem));
6939
6940  ins_pipe(istore_reg_mem);
6941%}
6942
6943instruct storeimmI0(immI0 zero, memory mem)
6944%{
6945  match(Set mem(StoreI mem zero));
6946  predicate(!needs_releasing_store(n));
6947
6948  ins_cost(INSN_COST);
6949  format %{ "strw  zr, $mem\t# int" %}
6950
6951  ins_encode(aarch64_enc_strw0(mem));
6952
6953  ins_pipe(istore_mem);
6954%}
6955
6956// Store Long (64 bit signed)
6957instruct storeL(iRegL src, memory mem)
6958%{
6959  match(Set mem (StoreL mem src));
6960  predicate(!needs_releasing_store(n));
6961
6962  ins_cost(INSN_COST);
6963  format %{ "str  $src, $mem\t# int" %}
6964
6965  ins_encode(aarch64_enc_str(src, mem));
6966
6967  ins_pipe(istore_reg_mem);
6968%}
6969
6970// Store Long (64 bit signed)
6971instruct storeimmL0(immL0 zero, memory mem)
6972%{
6973  match(Set mem (StoreL mem zero));
6974  predicate(!needs_releasing_store(n));
6975
6976  ins_cost(INSN_COST);
6977  format %{ "str  zr, $mem\t# int" %}
6978
6979  ins_encode(aarch64_enc_str0(mem));
6980
6981  ins_pipe(istore_mem);
6982%}
6983
6984// Store Pointer
6985instruct storeP(iRegP src, memory mem)
6986%{
6987  match(Set mem (StoreP mem src));
6988  predicate(!needs_releasing_store(n));
6989
6990  ins_cost(INSN_COST);
6991  format %{ "str  $src, $mem\t# ptr" %}
6992
6993  ins_encode(aarch64_enc_str(src, mem));
6994
6995  ins_pipe(istore_reg_mem);
6996%}
6997
6998// Store Pointer
6999instruct storeimmP0(immP0 zero, memory mem)
7000%{
7001  match(Set mem (StoreP mem zero));
7002  predicate(!needs_releasing_store(n));
7003
7004  ins_cost(INSN_COST);
7005  format %{ "str zr, $mem\t# ptr" %}
7006
7007  ins_encode(aarch64_enc_str0(mem));
7008
7009  ins_pipe(istore_mem);
7010%}
7011
7012// Store Compressed Pointer
7013instruct storeN(iRegN src, memory mem)
7014%{
7015  match(Set mem (StoreN mem src));
7016  predicate(!needs_releasing_store(n));
7017
7018  ins_cost(INSN_COST);
7019  format %{ "strw  $src, $mem\t# compressed ptr" %}
7020
7021  ins_encode(aarch64_enc_strw(src, mem));
7022
7023  ins_pipe(istore_reg_mem);
7024%}
7025
7026instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem)
7027%{
7028  match(Set mem (StoreN mem zero));
7029  predicate(Universe::narrow_oop_base() == NULL &&
7030            Universe::narrow_klass_base() == NULL &&
7031            (!needs_releasing_store(n)));
7032
7033  ins_cost(INSN_COST);
7034  format %{ "strw  rheapbase, $mem\t# compressed ptr (rheapbase==0)" %}
7035
7036  ins_encode(aarch64_enc_strw(heapbase, mem));
7037
7038  ins_pipe(istore_reg_mem);
7039%}
7040
7041// Store Float
7042instruct storeF(vRegF src, memory mem)
7043%{
7044  match(Set mem (StoreF mem src));
7045  predicate(!needs_releasing_store(n));
7046
7047  ins_cost(INSN_COST);
7048  format %{ "strs  $src, $mem\t# float" %}
7049
7050  ins_encode( aarch64_enc_strs(src, mem) );
7051
7052  ins_pipe(pipe_class_memory);
7053%}
7054
7055// TODO
7056// implement storeImmF0 and storeFImmPacked
7057
7058// Store Double
7059instruct storeD(vRegD src, memory mem)
7060%{
7061  match(Set mem (StoreD mem src));
7062  predicate(!needs_releasing_store(n));
7063
7064  ins_cost(INSN_COST);
7065  format %{ "strd  $src, $mem\t# double" %}
7066
7067  ins_encode( aarch64_enc_strd(src, mem) );
7068
7069  ins_pipe(pipe_class_memory);
7070%}
7071
7072// Store Compressed Klass Pointer
7073instruct storeNKlass(iRegN src, memory mem)
7074%{
7075  predicate(!needs_releasing_store(n));
7076  match(Set mem (StoreNKlass mem src));
7077
7078  ins_cost(INSN_COST);
7079  format %{ "strw  $src, $mem\t# compressed klass ptr" %}
7080
7081  ins_encode(aarch64_enc_strw(src, mem));
7082
7083  ins_pipe(istore_reg_mem);
7084%}
7085
7086// TODO
7087// implement storeImmD0 and storeDImmPacked
7088
7089// prefetch instructions
7090// Must be safe to execute with invalid address (cannot fault).
7091
7092instruct prefetchalloc( memory mem ) %{
7093  match(PrefetchAllocation mem);
7094
7095  ins_cost(INSN_COST);
7096  format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %}
7097
7098  ins_encode( aarch64_enc_prefetchw(mem) );
7099
7100  ins_pipe(iload_prefetch);
7101%}
7102
7103//  ---------------- volatile loads and stores ----------------
7104
7105// Load Byte (8 bit signed)
7106instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7107%{
7108  match(Set dst (LoadB mem));
7109
7110  ins_cost(VOLATILE_REF_COST);
7111  format %{ "ldarsb  $dst, $mem\t# byte" %}
7112
7113  ins_encode(aarch64_enc_ldarsb(dst, mem));
7114
7115  ins_pipe(pipe_serial);
7116%}
7117
7118// Load Byte (8 bit signed) into long
7119instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7120%{
7121  match(Set dst (ConvI2L (LoadB mem)));
7122
7123  ins_cost(VOLATILE_REF_COST);
7124  format %{ "ldarsb  $dst, $mem\t# byte" %}
7125
7126  ins_encode(aarch64_enc_ldarsb(dst, mem));
7127
7128  ins_pipe(pipe_serial);
7129%}
7130
7131// Load Byte (8 bit unsigned)
7132instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7133%{
7134  match(Set dst (LoadUB mem));
7135
7136  ins_cost(VOLATILE_REF_COST);
7137  format %{ "ldarb  $dst, $mem\t# byte" %}
7138
7139  ins_encode(aarch64_enc_ldarb(dst, mem));
7140
7141  ins_pipe(pipe_serial);
7142%}
7143
7144// Load Byte (8 bit unsigned) into long
7145instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7146%{
7147  match(Set dst (ConvI2L (LoadUB mem)));
7148
7149  ins_cost(VOLATILE_REF_COST);
7150  format %{ "ldarb  $dst, $mem\t# byte" %}
7151
7152  ins_encode(aarch64_enc_ldarb(dst, mem));
7153
7154  ins_pipe(pipe_serial);
7155%}
7156
7157// Load Short (16 bit signed)
7158instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7159%{
7160  match(Set dst (LoadS mem));
7161
7162  ins_cost(VOLATILE_REF_COST);
7163  format %{ "ldarshw  $dst, $mem\t# short" %}
7164
7165  ins_encode(aarch64_enc_ldarshw(dst, mem));
7166
7167  ins_pipe(pipe_serial);
7168%}
7169
7170instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7171%{
7172  match(Set dst (LoadUS mem));
7173
7174  ins_cost(VOLATILE_REF_COST);
7175  format %{ "ldarhw  $dst, $mem\t# short" %}
7176
7177  ins_encode(aarch64_enc_ldarhw(dst, mem));
7178
7179  ins_pipe(pipe_serial);
7180%}
7181
7182// Load Short/Char (16 bit unsigned) into long
7183instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7184%{
7185  match(Set dst (ConvI2L (LoadUS mem)));
7186
7187  ins_cost(VOLATILE_REF_COST);
7188  format %{ "ldarh  $dst, $mem\t# short" %}
7189
7190  ins_encode(aarch64_enc_ldarh(dst, mem));
7191
7192  ins_pipe(pipe_serial);
7193%}
7194
7195// Load Short/Char (16 bit signed) into long
7196instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7197%{
7198  match(Set dst (ConvI2L (LoadS mem)));
7199
7200  ins_cost(VOLATILE_REF_COST);
7201  format %{ "ldarh  $dst, $mem\t# short" %}
7202
7203  ins_encode(aarch64_enc_ldarsh(dst, mem));
7204
7205  ins_pipe(pipe_serial);
7206%}
7207
7208// Load Integer (32 bit signed)
7209instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7210%{
7211  match(Set dst (LoadI mem));
7212
7213  ins_cost(VOLATILE_REF_COST);
7214  format %{ "ldarw  $dst, $mem\t# int" %}
7215
7216  ins_encode(aarch64_enc_ldarw(dst, mem));
7217
7218  ins_pipe(pipe_serial);
7219%}
7220
7221// Load Integer (32 bit unsigned) into long
7222instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask)
7223%{
7224  match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
7225
7226  ins_cost(VOLATILE_REF_COST);
7227  format %{ "ldarw  $dst, $mem\t# int" %}
7228
7229  ins_encode(aarch64_enc_ldarw(dst, mem));
7230
7231  ins_pipe(pipe_serial);
7232%}
7233
7234// Load Long (64 bit signed)
7235instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7236%{
7237  match(Set dst (LoadL mem));
7238
7239  ins_cost(VOLATILE_REF_COST);
7240  format %{ "ldar  $dst, $mem\t# int" %}
7241
7242  ins_encode(aarch64_enc_ldar(dst, mem));
7243
7244  ins_pipe(pipe_serial);
7245%}
7246
7247// Load Pointer
7248instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem)
7249%{
7250  match(Set dst (LoadP mem));
7251
7252  ins_cost(VOLATILE_REF_COST);
7253  format %{ "ldar  $dst, $mem\t# ptr" %}
7254
7255  ins_encode(aarch64_enc_ldar(dst, mem));
7256
7257  ins_pipe(pipe_serial);
7258%}
7259
7260// Load Compressed Pointer
7261instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem)
7262%{
7263  match(Set dst (LoadN mem));
7264
7265  ins_cost(VOLATILE_REF_COST);
7266  format %{ "ldarw  $dst, $mem\t# compressed ptr" %}
7267
7268  ins_encode(aarch64_enc_ldarw(dst, mem));
7269
7270  ins_pipe(pipe_serial);
7271%}
7272
7273// Load Float
7274instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem)
7275%{
7276  match(Set dst (LoadF mem));
7277
7278  ins_cost(VOLATILE_REF_COST);
7279  format %{ "ldars  $dst, $mem\t# float" %}
7280
7281  ins_encode( aarch64_enc_fldars(dst, mem) );
7282
7283  ins_pipe(pipe_serial);
7284%}
7285
7286// Load Double
7287instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem)
7288%{
7289  match(Set dst (LoadD mem));
7290
7291  ins_cost(VOLATILE_REF_COST);
7292  format %{ "ldard  $dst, $mem\t# double" %}
7293
7294  ins_encode( aarch64_enc_fldard(dst, mem) );
7295
7296  ins_pipe(pipe_serial);
7297%}
7298
7299// Store Byte
7300instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7301%{
7302  match(Set mem (StoreB mem src));
7303
7304  ins_cost(VOLATILE_REF_COST);
7305  format %{ "stlrb  $src, $mem\t# byte" %}
7306
7307  ins_encode(aarch64_enc_stlrb(src, mem));
7308
7309  ins_pipe(pipe_class_memory);
7310%}
7311
7312// Store Char/Short
7313instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7314%{
7315  match(Set mem (StoreC mem src));
7316
7317  ins_cost(VOLATILE_REF_COST);
7318  format %{ "stlrh  $src, $mem\t# short" %}
7319
7320  ins_encode(aarch64_enc_stlrh(src, mem));
7321
7322  ins_pipe(pipe_class_memory);
7323%}
7324
7325// Store Integer
7326
7327instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7328%{
7329  match(Set mem(StoreI mem src));
7330
7331  ins_cost(VOLATILE_REF_COST);
7332  format %{ "stlrw  $src, $mem\t# int" %}
7333
7334  ins_encode(aarch64_enc_stlrw(src, mem));
7335
7336  ins_pipe(pipe_class_memory);
7337%}
7338
7339// Store Long (64 bit signed)
7340instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem)
7341%{
7342  match(Set mem (StoreL mem src));
7343
7344  ins_cost(VOLATILE_REF_COST);
7345  format %{ "stlr  $src, $mem\t# int" %}
7346
7347  ins_encode(aarch64_enc_stlr(src, mem));
7348
7349  ins_pipe(pipe_class_memory);
7350%}
7351
7352// Store Pointer
7353instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem)
7354%{
7355  match(Set mem (StoreP mem src));
7356
7357  ins_cost(VOLATILE_REF_COST);
7358  format %{ "stlr  $src, $mem\t# ptr" %}
7359
7360  ins_encode(aarch64_enc_stlr(src, mem));
7361
7362  ins_pipe(pipe_class_memory);
7363%}
7364
7365// Store Compressed Pointer
7366instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem)
7367%{
7368  match(Set mem (StoreN mem src));
7369
7370  ins_cost(VOLATILE_REF_COST);
7371  format %{ "stlrw  $src, $mem\t# compressed ptr" %}
7372
7373  ins_encode(aarch64_enc_stlrw(src, mem));
7374
7375  ins_pipe(pipe_class_memory);
7376%}
7377
7378// Store Float
7379instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem)
7380%{
7381  match(Set mem (StoreF mem src));
7382
7383  ins_cost(VOLATILE_REF_COST);
7384  format %{ "stlrs  $src, $mem\t# float" %}
7385
7386  ins_encode( aarch64_enc_fstlrs(src, mem) );
7387
7388  ins_pipe(pipe_class_memory);
7389%}
7390
7391// TODO
7392// implement storeImmF0 and storeFImmPacked
7393
7394// Store Double
7395instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem)
7396%{
7397  match(Set mem (StoreD mem src));
7398
7399  ins_cost(VOLATILE_REF_COST);
7400  format %{ "stlrd  $src, $mem\t# double" %}
7401
7402  ins_encode( aarch64_enc_fstlrd(src, mem) );
7403
7404  ins_pipe(pipe_class_memory);
7405%}
7406
7407//  ---------------- end of volatile loads and stores ----------------
7408
7409// ============================================================================
7410// BSWAP Instructions
7411
7412instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{
7413  match(Set dst (ReverseBytesI src));
7414
7415  ins_cost(INSN_COST);
7416  format %{ "revw  $dst, $src" %}
7417
7418  ins_encode %{
7419    __ revw(as_Register($dst$$reg), as_Register($src$$reg));
7420  %}
7421
7422  ins_pipe(ialu_reg);
7423%}
7424
7425instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{
7426  match(Set dst (ReverseBytesL src));
7427
7428  ins_cost(INSN_COST);
7429  format %{ "rev  $dst, $src" %}
7430
7431  ins_encode %{
7432    __ rev(as_Register($dst$$reg), as_Register($src$$reg));
7433  %}
7434
7435  ins_pipe(ialu_reg);
7436%}
7437
7438instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{
7439  match(Set dst (ReverseBytesUS src));
7440
7441  ins_cost(INSN_COST);
7442  format %{ "rev16w  $dst, $src" %}
7443
7444  ins_encode %{
7445    __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
7446  %}
7447
7448  ins_pipe(ialu_reg);
7449%}
7450
7451instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{
7452  match(Set dst (ReverseBytesS src));
7453
7454  ins_cost(INSN_COST);
7455  format %{ "rev16w  $dst, $src\n\t"
7456            "sbfmw $dst, $dst, #0, #15" %}
7457
7458  ins_encode %{
7459    __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
7460    __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U);
7461  %}
7462
7463  ins_pipe(ialu_reg);
7464%}
7465
7466// ============================================================================
7467// Zero Count Instructions
7468
7469instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{
7470  match(Set dst (CountLeadingZerosI src));
7471
7472  ins_cost(INSN_COST);
7473  format %{ "clzw  $dst, $src" %}
7474  ins_encode %{
7475    __ clzw(as_Register($dst$$reg), as_Register($src$$reg));
7476  %}
7477
7478  ins_pipe(ialu_reg);
7479%}
7480
7481instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{
7482  match(Set dst (CountLeadingZerosL src));
7483
7484  ins_cost(INSN_COST);
7485  format %{ "clz   $dst, $src" %}
7486  ins_encode %{
7487    __ clz(as_Register($dst$$reg), as_Register($src$$reg));
7488  %}
7489
7490  ins_pipe(ialu_reg);
7491%}
7492
7493instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{
7494  match(Set dst (CountTrailingZerosI src));
7495
7496  ins_cost(INSN_COST * 2);
7497  format %{ "rbitw  $dst, $src\n\t"
7498            "clzw   $dst, $dst" %}
7499  ins_encode %{
7500    __ rbitw(as_Register($dst$$reg), as_Register($src$$reg));
7501    __ clzw(as_Register($dst$$reg), as_Register($dst$$reg));
7502  %}
7503
7504  ins_pipe(ialu_reg);
7505%}
7506
7507instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{
7508  match(Set dst (CountTrailingZerosL src));
7509
7510  ins_cost(INSN_COST * 2);
7511  format %{ "rbit   $dst, $src\n\t"
7512            "clz    $dst, $dst" %}
7513  ins_encode %{
7514    __ rbit(as_Register($dst$$reg), as_Register($src$$reg));
7515    __ clz(as_Register($dst$$reg), as_Register($dst$$reg));
7516  %}
7517
7518  ins_pipe(ialu_reg);
7519%}
7520
7521//---------- Population Count Instructions -------------------------------------
7522//
7523
7524instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{
7525  predicate(UsePopCountInstruction);
7526  match(Set dst (PopCountI src));
7527  effect(TEMP tmp);
7528  ins_cost(INSN_COST * 13);
7529
7530  format %{ "movw   $src, $src\n\t"
7531            "mov    $tmp, $src\t# vector (1D)\n\t"
7532            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7533            "addv   $tmp, $tmp\t# vector (8B)\n\t"
7534            "mov    $dst, $tmp\t# vector (1D)" %}
7535  ins_encode %{
7536    __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0
7537    __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register);
7538    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7539    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7540    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7541  %}
7542
7543  ins_pipe(pipe_class_default);
7544%}
7545
7546instruct popCountI_mem(iRegINoSp dst, memory mem, vRegF tmp) %{
7547  predicate(UsePopCountInstruction);
7548  match(Set dst (PopCountI (LoadI mem)));
7549  effect(TEMP tmp);
7550  ins_cost(INSN_COST * 13);
7551
7552  format %{ "ldrs   $tmp, $mem\n\t"
7553            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7554            "addv   $tmp, $tmp\t# vector (8B)\n\t"
7555            "mov    $dst, $tmp\t# vector (1D)" %}
7556  ins_encode %{
7557    FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
7558    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(),
7559               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
7560    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7561    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7562    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7563  %}
7564
7565  ins_pipe(pipe_class_default);
7566%}
7567
7568// Note: Long.bitCount(long) returns an int.
7569instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{
7570  predicate(UsePopCountInstruction);
7571  match(Set dst (PopCountL src));
7572  effect(TEMP tmp);
7573  ins_cost(INSN_COST * 13);
7574
7575  format %{ "mov    $tmp, $src\t# vector (1D)\n\t"
7576            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7577            "addv   $tmp, $tmp\t# vector (8B)\n\t"
7578            "mov    $dst, $tmp\t# vector (1D)" %}
7579  ins_encode %{
7580    __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register);
7581    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7582    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7583    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7584  %}
7585
7586  ins_pipe(pipe_class_default);
7587%}
7588
7589instruct popCountL_mem(iRegINoSp dst, memory mem, vRegD tmp) %{
7590  predicate(UsePopCountInstruction);
7591  match(Set dst (PopCountL (LoadL mem)));
7592  effect(TEMP tmp);
7593  ins_cost(INSN_COST * 13);
7594
7595  format %{ "ldrd   $tmp, $mem\n\t"
7596            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7597            "addv   $tmp, $tmp\t# vector (8B)\n\t"
7598            "mov    $dst, $tmp\t# vector (1D)" %}
7599  ins_encode %{
7600    FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
7601    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(),
7602               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
7603    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7604    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7605    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7606  %}
7607
7608  ins_pipe(pipe_class_default);
7609%}
7610
7611// ============================================================================
7612// MemBar Instruction
7613
7614instruct load_fence() %{
7615  match(LoadFence);
7616  ins_cost(VOLATILE_REF_COST);
7617
7618  format %{ "load_fence" %}
7619
7620  ins_encode %{
7621    __ membar(Assembler::LoadLoad|Assembler::LoadStore);
7622  %}
7623  ins_pipe(pipe_serial);
7624%}
7625
7626instruct unnecessary_membar_acquire() %{
7627  predicate(unnecessary_acquire(n));
7628  match(MemBarAcquire);
7629  ins_cost(0);
7630
7631  format %{ "membar_acquire (elided)" %}
7632
7633  ins_encode %{
7634    __ block_comment("membar_acquire (elided)");
7635  %}
7636
7637  ins_pipe(pipe_class_empty);
7638%}
7639
7640instruct membar_acquire() %{
7641  match(MemBarAcquire);
7642  ins_cost(VOLATILE_REF_COST);
7643
7644  format %{ "membar_acquire\n\t"
7645            "dmb ish" %}
7646
7647  ins_encode %{
7648    __ block_comment("membar_acquire");
7649    __ membar(Assembler::LoadLoad|Assembler::LoadStore);
7650  %}
7651
7652  ins_pipe(pipe_serial);
7653%}
7654
7655
7656instruct membar_acquire_lock() %{
7657  match(MemBarAcquireLock);
7658  ins_cost(VOLATILE_REF_COST);
7659
7660  format %{ "membar_acquire_lock (elided)" %}
7661
7662  ins_encode %{
7663    __ block_comment("membar_acquire_lock (elided)");
7664  %}
7665
7666  ins_pipe(pipe_serial);
7667%}
7668
7669instruct store_fence() %{
7670  match(StoreFence);
7671  ins_cost(VOLATILE_REF_COST);
7672
7673  format %{ "store_fence" %}
7674
7675  ins_encode %{
7676    __ membar(Assembler::LoadStore|Assembler::StoreStore);
7677  %}
7678  ins_pipe(pipe_serial);
7679%}
7680
7681instruct unnecessary_membar_release() %{
7682  predicate(unnecessary_release(n));
7683  match(MemBarRelease);
7684  ins_cost(0);
7685
7686  format %{ "membar_release (elided)" %}
7687
7688  ins_encode %{
7689    __ block_comment("membar_release (elided)");
7690  %}
7691  ins_pipe(pipe_serial);
7692%}
7693
7694instruct membar_release() %{
7695  match(MemBarRelease);
7696  ins_cost(VOLATILE_REF_COST);
7697
7698  format %{ "membar_release\n\t"
7699            "dmb ish" %}
7700
7701  ins_encode %{
7702    __ block_comment("membar_release");
7703    __ membar(Assembler::LoadStore|Assembler::StoreStore);
7704  %}
7705  ins_pipe(pipe_serial);
7706%}
7707
7708instruct membar_storestore() %{
7709  match(MemBarStoreStore);
7710  ins_cost(VOLATILE_REF_COST);
7711
7712  format %{ "MEMBAR-store-store" %}
7713
7714  ins_encode %{
7715    __ membar(Assembler::StoreStore);
7716  %}
7717  ins_pipe(pipe_serial);
7718%}
7719
7720instruct membar_release_lock() %{
7721  match(MemBarReleaseLock);
7722  ins_cost(VOLATILE_REF_COST);
7723
7724  format %{ "membar_release_lock (elided)" %}
7725
7726  ins_encode %{
7727    __ block_comment("membar_release_lock (elided)");
7728  %}
7729
7730  ins_pipe(pipe_serial);
7731%}
7732
7733instruct unnecessary_membar_volatile() %{
7734  predicate(unnecessary_volatile(n));
7735  match(MemBarVolatile);
7736  ins_cost(0);
7737
7738  format %{ "membar_volatile (elided)" %}
7739
7740  ins_encode %{
7741    __ block_comment("membar_volatile (elided)");
7742  %}
7743
7744  ins_pipe(pipe_serial);
7745%}
7746
7747instruct membar_volatile() %{
7748  match(MemBarVolatile);
7749  ins_cost(VOLATILE_REF_COST*100);
7750
7751  format %{ "membar_volatile\n\t"
7752             "dmb ish"%}
7753
7754  ins_encode %{
7755    __ block_comment("membar_volatile");
7756    __ membar(Assembler::StoreLoad);
7757  %}
7758
7759  ins_pipe(pipe_serial);
7760%}
7761
7762// ============================================================================
7763// Cast/Convert Instructions
7764
7765instruct castX2P(iRegPNoSp dst, iRegL src) %{
7766  match(Set dst (CastX2P src));
7767
7768  ins_cost(INSN_COST);
7769  format %{ "mov $dst, $src\t# long -> ptr" %}
7770
7771  ins_encode %{
7772    if ($dst$$reg != $src$$reg) {
7773      __ mov(as_Register($dst$$reg), as_Register($src$$reg));
7774    }
7775  %}
7776
7777  ins_pipe(ialu_reg);
7778%}
7779
7780instruct castP2X(iRegLNoSp dst, iRegP src) %{
7781  match(Set dst (CastP2X src));
7782
7783  ins_cost(INSN_COST);
7784  format %{ "mov $dst, $src\t# ptr -> long" %}
7785
7786  ins_encode %{
7787    if ($dst$$reg != $src$$reg) {
7788      __ mov(as_Register($dst$$reg), as_Register($src$$reg));
7789    }
7790  %}
7791
7792  ins_pipe(ialu_reg);
7793%}
7794
7795// Convert oop into int for vectors alignment masking
7796instruct convP2I(iRegINoSp dst, iRegP src) %{
7797  match(Set dst (ConvL2I (CastP2X src)));
7798
7799  ins_cost(INSN_COST);
7800  format %{ "movw $dst, $src\t# ptr -> int" %}
7801  ins_encode %{
7802    __ movw($dst$$Register, $src$$Register);
7803  %}
7804
7805  ins_pipe(ialu_reg);
7806%}
7807
7808// Convert compressed oop into int for vectors alignment masking
7809// in case of 32bit oops (heap < 4Gb).
7810instruct convN2I(iRegINoSp dst, iRegN src)
7811%{
7812  predicate(Universe::narrow_oop_shift() == 0);
7813  match(Set dst (ConvL2I (CastP2X (DecodeN src))));
7814
7815  ins_cost(INSN_COST);
7816  format %{ "mov dst, $src\t# compressed ptr -> int" %}
7817  ins_encode %{
7818    __ movw($dst$$Register, $src$$Register);
7819  %}
7820
7821  ins_pipe(ialu_reg);
7822%}
7823
7824
7825// Convert oop pointer into compressed form
7826instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
7827  predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
7828  match(Set dst (EncodeP src));
7829  effect(KILL cr);
7830  ins_cost(INSN_COST * 3);
7831  format %{ "encode_heap_oop $dst, $src" %}
7832  ins_encode %{
7833    Register s = $src$$Register;
7834    Register d = $dst$$Register;
7835    __ encode_heap_oop(d, s);
7836  %}
7837  ins_pipe(ialu_reg);
7838%}
7839
7840instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
7841  predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
7842  match(Set dst (EncodeP src));
7843  ins_cost(INSN_COST * 3);
7844  format %{ "encode_heap_oop_not_null $dst, $src" %}
7845  ins_encode %{
7846    __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
7847  %}
7848  ins_pipe(ialu_reg);
7849%}
7850
7851instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
7852  predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
7853            n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
7854  match(Set dst (DecodeN src));
7855  ins_cost(INSN_COST * 3);
7856  format %{ "decode_heap_oop $dst, $src" %}
7857  ins_encode %{
7858    Register s = $src$$Register;
7859    Register d = $dst$$Register;
7860    __ decode_heap_oop(d, s);
7861  %}
7862  ins_pipe(ialu_reg);
7863%}
7864
7865instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
7866  predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
7867            n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
7868  match(Set dst (DecodeN src));
7869  ins_cost(INSN_COST * 3);
7870  format %{ "decode_heap_oop_not_null $dst, $src" %}
7871  ins_encode %{
7872    Register s = $src$$Register;
7873    Register d = $dst$$Register;
7874    __ decode_heap_oop_not_null(d, s);
7875  %}
7876  ins_pipe(ialu_reg);
7877%}
7878
7879// n.b. AArch64 implementations of encode_klass_not_null and
7880// decode_klass_not_null do not modify the flags register so, unlike
7881// Intel, we don't kill CR as a side effect here
7882
7883instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{
7884  match(Set dst (EncodePKlass src));
7885
7886  ins_cost(INSN_COST * 3);
7887  format %{ "encode_klass_not_null $dst,$src" %}
7888
7889  ins_encode %{
7890    Register src_reg = as_Register($src$$reg);
7891    Register dst_reg = as_Register($dst$$reg);
7892    __ encode_klass_not_null(dst_reg, src_reg);
7893  %}
7894
7895   ins_pipe(ialu_reg);
7896%}
7897
7898instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{
7899  match(Set dst (DecodeNKlass src));
7900
7901  ins_cost(INSN_COST * 3);
7902  format %{ "decode_klass_not_null $dst,$src" %}
7903
7904  ins_encode %{
7905    Register src_reg = as_Register($src$$reg);
7906    Register dst_reg = as_Register($dst$$reg);
7907    if (dst_reg != src_reg) {
7908      __ decode_klass_not_null(dst_reg, src_reg);
7909    } else {
7910      __ decode_klass_not_null(dst_reg);
7911    }
7912  %}
7913
7914   ins_pipe(ialu_reg);
7915%}
7916
7917instruct checkCastPP(iRegPNoSp dst)
7918%{
7919  match(Set dst (CheckCastPP dst));
7920
7921  size(0);
7922  format %{ "# checkcastPP of $dst" %}
7923  ins_encode(/* empty encoding */);
7924  ins_pipe(pipe_class_empty);
7925%}
7926
7927instruct castPP(iRegPNoSp dst)
7928%{
7929  match(Set dst (CastPP dst));
7930
7931  size(0);
7932  format %{ "# castPP of $dst" %}
7933  ins_encode(/* empty encoding */);
7934  ins_pipe(pipe_class_empty);
7935%}
7936
7937instruct castII(iRegI dst)
7938%{
7939  match(Set dst (CastII dst));
7940
7941  size(0);
7942  format %{ "# castII of $dst" %}
7943  ins_encode(/* empty encoding */);
7944  ins_cost(0);
7945  ins_pipe(pipe_class_empty);
7946%}
7947
7948// ============================================================================
7949// Atomic operation instructions
7950//
7951// Intel and SPARC both implement Ideal Node LoadPLocked and
7952// Store{PIL}Conditional instructions using a normal load for the
7953// LoadPLocked and a CAS for the Store{PIL}Conditional.
7954//
7955// The ideal code appears only to use LoadPLocked/StorePLocked as a
7956// pair to lock object allocations from Eden space when not using
7957// TLABs.
7958//
7959// There does not appear to be a Load{IL}Locked Ideal Node and the
7960// Ideal code appears to use Store{IL}Conditional as an alias for CAS
7961// and to use StoreIConditional only for 32-bit and StoreLConditional
7962// only for 64-bit.
7963//
7964// We implement LoadPLocked and StorePLocked instructions using,
7965// respectively the AArch64 hw load-exclusive and store-conditional
7966// instructions. Whereas we must implement each of
7967// Store{IL}Conditional using a CAS which employs a pair of
7968// instructions comprising a load-exclusive followed by a
7969// store-conditional.
7970
7971
7972// Locked-load (linked load) of the current heap-top
7973// used when updating the eden heap top
7974// implemented using ldaxr on AArch64
7975
7976instruct loadPLocked(iRegPNoSp dst, indirect mem)
7977%{
7978  match(Set dst (LoadPLocked mem));
7979
7980  ins_cost(VOLATILE_REF_COST);
7981
7982  format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %}
7983
7984  ins_encode(aarch64_enc_ldaxr(dst, mem));
7985
7986  ins_pipe(pipe_serial);
7987%}
7988
7989// Conditional-store of the updated heap-top.
7990// Used during allocation of the shared heap.
7991// Sets flag (EQ) on success.
7992// implemented using stlxr on AArch64.
7993
7994instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr)
7995%{
7996  match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
7997
7998  ins_cost(VOLATILE_REF_COST);
7999
8000 // TODO
8001 // do we need to do a store-conditional release or can we just use a
8002 // plain store-conditional?
8003
8004  format %{
8005    "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release"
8006    "cmpw rscratch1, zr\t# EQ on successful write"
8007  %}
8008
8009  ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr));
8010
8011  ins_pipe(pipe_serial);
8012%}
8013
8014
8015// storeLConditional is used by PhaseMacroExpand::expand_lock_node
8016// when attempting to rebias a lock towards the current thread.  We
8017// must use the acquire form of cmpxchg in order to guarantee acquire
8018// semantics in this case.
8019instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr)
8020%{
8021  match(Set cr (StoreLConditional mem (Binary oldval newval)));
8022
8023  ins_cost(VOLATILE_REF_COST);
8024
8025  format %{
8026    "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
8027    "cmpw rscratch1, zr\t# EQ on successful write"
8028  %}
8029
8030  ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval));
8031
8032  ins_pipe(pipe_slow);
8033%}
8034
8035// storeIConditional also has acquire semantics, for no better reason
8036// than matching storeLConditional.  At the time of writing this
8037// comment storeIConditional was not used anywhere by AArch64.
8038instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr)
8039%{
8040  match(Set cr (StoreIConditional mem (Binary oldval newval)));
8041
8042  ins_cost(VOLATILE_REF_COST);
8043
8044  format %{
8045    "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
8046    "cmpw rscratch1, zr\t# EQ on successful write"
8047  %}
8048
8049  ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval));
8050
8051  ins_pipe(pipe_slow);
8052%}
8053
8054// standard CompareAndSwapX when we are using barriers
8055// these have higher priority than the rules selected by a predicate
8056
8057// XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher
8058// can't match them
8059
8060instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8061
8062  match(Set res (CompareAndSwapB mem (Binary oldval newval)));
8063  ins_cost(2 * VOLATILE_REF_COST);
8064
8065  effect(KILL cr);
8066
8067  format %{
8068    "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8069    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8070  %}
8071
8072  ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval),
8073            aarch64_enc_cset_eq(res));
8074
8075  ins_pipe(pipe_slow);
8076%}
8077
8078instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8079
8080  match(Set res (CompareAndSwapS mem (Binary oldval newval)));
8081  ins_cost(2 * VOLATILE_REF_COST);
8082
8083  effect(KILL cr);
8084
8085  format %{
8086    "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8087    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8088  %}
8089
8090  ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval),
8091            aarch64_enc_cset_eq(res));
8092
8093  ins_pipe(pipe_slow);
8094%}
8095
8096instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8097
8098  match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8099  ins_cost(2 * VOLATILE_REF_COST);
8100
8101  effect(KILL cr);
8102
8103 format %{
8104    "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8105    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8106 %}
8107
8108 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8109            aarch64_enc_cset_eq(res));
8110
8111  ins_pipe(pipe_slow);
8112%}
8113
8114instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8115
8116  match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8117  ins_cost(2 * VOLATILE_REF_COST);
8118
8119  effect(KILL cr);
8120
8121 format %{
8122    "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8123    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8124 %}
8125
8126 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8127            aarch64_enc_cset_eq(res));
8128
8129  ins_pipe(pipe_slow);
8130%}
8131
8132instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8133
8134  match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8135  ins_cost(2 * VOLATILE_REF_COST);
8136
8137  effect(KILL cr);
8138
8139 format %{
8140    "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8141    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8142 %}
8143
8144 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8145            aarch64_enc_cset_eq(res));
8146
8147  ins_pipe(pipe_slow);
8148%}
8149
8150instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8151
8152  match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8153  ins_cost(2 * VOLATILE_REF_COST);
8154
8155  effect(KILL cr);
8156
8157 format %{
8158    "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8159    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8160 %}
8161
8162 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8163            aarch64_enc_cset_eq(res));
8164
8165  ins_pipe(pipe_slow);
8166%}
8167
8168// alternative CompareAndSwapX when we are eliding barriers
8169
8170instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8171
8172  predicate(needs_acquiring_load_exclusive(n));
8173  match(Set res (CompareAndSwapB mem (Binary oldval newval)));
8174  ins_cost(VOLATILE_REF_COST);
8175
8176  effect(KILL cr);
8177
8178  format %{
8179    "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8180    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8181  %}
8182
8183  ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval),
8184            aarch64_enc_cset_eq(res));
8185
8186  ins_pipe(pipe_slow);
8187%}
8188
8189instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8190
8191  predicate(needs_acquiring_load_exclusive(n));
8192  match(Set res (CompareAndSwapS mem (Binary oldval newval)));
8193  ins_cost(VOLATILE_REF_COST);
8194
8195  effect(KILL cr);
8196
8197  format %{
8198    "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8199    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8200  %}
8201
8202  ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval),
8203            aarch64_enc_cset_eq(res));
8204
8205  ins_pipe(pipe_slow);
8206%}
8207
8208instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8209
8210  predicate(needs_acquiring_load_exclusive(n));
8211  match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8212  ins_cost(VOLATILE_REF_COST);
8213
8214  effect(KILL cr);
8215
8216 format %{
8217    "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8218    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8219 %}
8220
8221 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8222            aarch64_enc_cset_eq(res));
8223
8224  ins_pipe(pipe_slow);
8225%}
8226
8227instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8228
8229  predicate(needs_acquiring_load_exclusive(n));
8230  match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8231  ins_cost(VOLATILE_REF_COST);
8232
8233  effect(KILL cr);
8234
8235 format %{
8236    "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8237    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8238 %}
8239
8240 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8241            aarch64_enc_cset_eq(res));
8242
8243  ins_pipe(pipe_slow);
8244%}
8245
8246instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8247
8248  predicate(needs_acquiring_load_exclusive(n));
8249  match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8250  ins_cost(VOLATILE_REF_COST);
8251
8252  effect(KILL cr);
8253
8254 format %{
8255    "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8256    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8257 %}
8258
8259 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8260            aarch64_enc_cset_eq(res));
8261
8262  ins_pipe(pipe_slow);
8263%}
8264
8265instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8266
8267  predicate(needs_acquiring_load_exclusive(n));
8268  match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8269  ins_cost(VOLATILE_REF_COST);
8270
8271  effect(KILL cr);
8272
8273 format %{
8274    "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8275    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8276 %}
8277
8278 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8279            aarch64_enc_cset_eq(res));
8280
8281  ins_pipe(pipe_slow);
8282%}
8283
8284
8285// ---------------------------------------------------------------------
8286
8287
8288// BEGIN This section of the file is automatically generated. Do not edit --------------
8289
8290// Sundry CAS operations.  Note that release is always true,
8291// regardless of the memory ordering of the CAS.  This is because we
8292// need the volatile case to be sequentially consistent but there is
8293// no trailing StoreLoad barrier emitted by C2.  Unfortunately we
8294// can't check the type of memory ordering here, so we always emit a
8295// STLXR.
8296
8297// This section is generated from aarch64_ad_cas.m4
8298
8299
8300
8301instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8302  match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
8303  ins_cost(2 * VOLATILE_REF_COST);
8304  effect(TEMP_DEF res, KILL cr);
8305  format %{
8306    "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8307  %}
8308  ins_encode %{
8309    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8310               Assembler::byte, /*acquire*/ false, /*release*/ true,
8311               /*weak*/ false, $res$$Register);
8312    __ sxtbw($res$$Register, $res$$Register);
8313  %}
8314  ins_pipe(pipe_slow);
8315%}
8316
8317instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8318  match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
8319  ins_cost(2 * VOLATILE_REF_COST);
8320  effect(TEMP_DEF res, KILL cr);
8321  format %{
8322    "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8323  %}
8324  ins_encode %{
8325    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8326               Assembler::halfword, /*acquire*/ false, /*release*/ true,
8327               /*weak*/ false, $res$$Register);
8328    __ sxthw($res$$Register, $res$$Register);
8329  %}
8330  ins_pipe(pipe_slow);
8331%}
8332
8333instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8334  match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
8335  ins_cost(2 * VOLATILE_REF_COST);
8336  effect(TEMP_DEF res, KILL cr);
8337  format %{
8338    "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8339  %}
8340  ins_encode %{
8341    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8342               Assembler::word, /*acquire*/ false, /*release*/ true,
8343               /*weak*/ false, $res$$Register);
8344  %}
8345  ins_pipe(pipe_slow);
8346%}
8347
8348instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8349  match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
8350  ins_cost(2 * VOLATILE_REF_COST);
8351  effect(TEMP_DEF res, KILL cr);
8352  format %{
8353    "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8354  %}
8355  ins_encode %{
8356    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8357               Assembler::xword, /*acquire*/ false, /*release*/ true,
8358               /*weak*/ false, $res$$Register);
8359  %}
8360  ins_pipe(pipe_slow);
8361%}
8362
8363instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8364  match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
8365  ins_cost(2 * VOLATILE_REF_COST);
8366  effect(TEMP_DEF res, KILL cr);
8367  format %{
8368    "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8369  %}
8370  ins_encode %{
8371    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8372               Assembler::word, /*acquire*/ false, /*release*/ true,
8373               /*weak*/ false, $res$$Register);
8374  %}
8375  ins_pipe(pipe_slow);
8376%}
8377
8378instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8379  match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
8380  ins_cost(2 * VOLATILE_REF_COST);
8381  effect(TEMP_DEF res, KILL cr);
8382  format %{
8383    "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8384  %}
8385  ins_encode %{
8386    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8387               Assembler::xword, /*acquire*/ false, /*release*/ true,
8388               /*weak*/ false, $res$$Register);
8389  %}
8390  ins_pipe(pipe_slow);
8391%}
8392
8393instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8394  predicate(needs_acquiring_load_exclusive(n));
8395  match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
8396  ins_cost(VOLATILE_REF_COST);
8397  effect(TEMP_DEF res, KILL cr);
8398  format %{
8399    "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8400  %}
8401  ins_encode %{
8402    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8403               Assembler::byte, /*acquire*/ true, /*release*/ true,
8404               /*weak*/ false, $res$$Register);
8405    __ sxtbw($res$$Register, $res$$Register);
8406  %}
8407  ins_pipe(pipe_slow);
8408%}
8409
8410instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8411  predicate(needs_acquiring_load_exclusive(n));
8412  match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
8413  ins_cost(VOLATILE_REF_COST);
8414  effect(TEMP_DEF res, KILL cr);
8415  format %{
8416    "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8417  %}
8418  ins_encode %{
8419    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8420               Assembler::halfword, /*acquire*/ true, /*release*/ true,
8421               /*weak*/ false, $res$$Register);
8422    __ sxthw($res$$Register, $res$$Register);
8423  %}
8424  ins_pipe(pipe_slow);
8425%}
8426
8427
8428instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8429  predicate(needs_acquiring_load_exclusive(n));
8430  match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
8431  ins_cost(VOLATILE_REF_COST);
8432  effect(TEMP_DEF res, KILL cr);
8433  format %{
8434    "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8435  %}
8436  ins_encode %{
8437    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8438               Assembler::word, /*acquire*/ true, /*release*/ true,
8439               /*weak*/ false, $res$$Register);
8440  %}
8441  ins_pipe(pipe_slow);
8442%}
8443
8444instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8445  predicate(needs_acquiring_load_exclusive(n));
8446  match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
8447  ins_cost(VOLATILE_REF_COST);
8448  effect(TEMP_DEF res, KILL cr);
8449  format %{
8450    "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8451  %}
8452  ins_encode %{
8453    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8454               Assembler::xword, /*acquire*/ true, /*release*/ true,
8455               /*weak*/ false, $res$$Register);
8456  %}
8457  ins_pipe(pipe_slow);
8458%}
8459
8460
8461instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8462  predicate(needs_acquiring_load_exclusive(n));
8463  match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
8464  ins_cost(VOLATILE_REF_COST);
8465  effect(TEMP_DEF res, KILL cr);
8466  format %{
8467    "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8468  %}
8469  ins_encode %{
8470    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8471               Assembler::word, /*acquire*/ true, /*release*/ true,
8472               /*weak*/ false, $res$$Register);
8473  %}
8474  ins_pipe(pipe_slow);
8475%}
8476
8477instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8478  predicate(needs_acquiring_load_exclusive(n));
8479  match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
8480  ins_cost(VOLATILE_REF_COST);
8481  effect(TEMP_DEF res, KILL cr);
8482  format %{
8483    "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8484  %}
8485  ins_encode %{
8486    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8487               Assembler::xword, /*acquire*/ true, /*release*/ true,
8488               /*weak*/ false, $res$$Register);
8489  %}
8490  ins_pipe(pipe_slow);
8491%}
8492
8493instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8494  match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
8495  ins_cost(2 * VOLATILE_REF_COST);
8496  effect(KILL cr);
8497  format %{
8498    "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8499    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8500  %}
8501  ins_encode %{
8502    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8503               Assembler::byte, /*acquire*/ false, /*release*/ true,
8504               /*weak*/ true, noreg);
8505    __ csetw($res$$Register, Assembler::EQ);
8506  %}
8507  ins_pipe(pipe_slow);
8508%}
8509
8510instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8511  match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
8512  ins_cost(2 * VOLATILE_REF_COST);
8513  effect(KILL cr);
8514  format %{
8515    "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8516    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8517  %}
8518  ins_encode %{
8519    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8520               Assembler::halfword, /*acquire*/ false, /*release*/ true,
8521               /*weak*/ true, noreg);
8522    __ csetw($res$$Register, Assembler::EQ);
8523  %}
8524  ins_pipe(pipe_slow);
8525%}
8526
8527instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8528  match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
8529  ins_cost(2 * VOLATILE_REF_COST);
8530  effect(KILL cr);
8531  format %{
8532    "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8533    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8534  %}
8535  ins_encode %{
8536    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8537               Assembler::word, /*acquire*/ false, /*release*/ true,
8538               /*weak*/ true, noreg);
8539    __ csetw($res$$Register, Assembler::EQ);
8540  %}
8541  ins_pipe(pipe_slow);
8542%}
8543
8544instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8545  match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
8546  ins_cost(2 * VOLATILE_REF_COST);
8547  effect(KILL cr);
8548  format %{
8549    "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8550    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8551  %}
8552  ins_encode %{
8553    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8554               Assembler::xword, /*acquire*/ false, /*release*/ true,
8555               /*weak*/ true, noreg);
8556    __ csetw($res$$Register, Assembler::EQ);
8557  %}
8558  ins_pipe(pipe_slow);
8559%}
8560
8561instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8562  match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
8563  ins_cost(2 * VOLATILE_REF_COST);
8564  effect(KILL cr);
8565  format %{
8566    "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8567    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8568  %}
8569  ins_encode %{
8570    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8571               Assembler::word, /*acquire*/ false, /*release*/ true,
8572               /*weak*/ true, noreg);
8573    __ csetw($res$$Register, Assembler::EQ);
8574  %}
8575  ins_pipe(pipe_slow);
8576%}
8577
8578instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8579  match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
8580  ins_cost(2 * VOLATILE_REF_COST);
8581  effect(KILL cr);
8582  format %{
8583    "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8584    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8585  %}
8586  ins_encode %{
8587    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8588               Assembler::xword, /*acquire*/ false, /*release*/ true,
8589               /*weak*/ true, noreg);
8590    __ csetw($res$$Register, Assembler::EQ);
8591  %}
8592  ins_pipe(pipe_slow);
8593%}
8594
8595instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8596  predicate(needs_acquiring_load_exclusive(n));
8597  match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
8598  ins_cost(VOLATILE_REF_COST);
8599  effect(KILL cr);
8600  format %{
8601    "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8602    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8603  %}
8604  ins_encode %{
8605    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8606               Assembler::byte, /*acquire*/ true, /*release*/ true,
8607               /*weak*/ true, noreg);
8608    __ csetw($res$$Register, Assembler::EQ);
8609  %}
8610  ins_pipe(pipe_slow);
8611%}
8612
8613instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8614  predicate(needs_acquiring_load_exclusive(n));
8615  match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
8616  ins_cost(VOLATILE_REF_COST);
8617  effect(KILL cr);
8618  format %{
8619    "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8620    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8621  %}
8622  ins_encode %{
8623    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8624               Assembler::halfword, /*acquire*/ true, /*release*/ true,
8625               /*weak*/ true, noreg);
8626    __ csetw($res$$Register, Assembler::EQ);
8627  %}
8628  ins_pipe(pipe_slow);
8629%}
8630
8631instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8632  predicate(needs_acquiring_load_exclusive(n));
8633  match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
8634  ins_cost(VOLATILE_REF_COST);
8635  effect(KILL cr);
8636  format %{
8637    "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8638    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8639  %}
8640  ins_encode %{
8641    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8642               Assembler::word, /*acquire*/ true, /*release*/ true,
8643               /*weak*/ true, noreg);
8644    __ csetw($res$$Register, Assembler::EQ);
8645  %}
8646  ins_pipe(pipe_slow);
8647%}
8648
8649instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8650  predicate(needs_acquiring_load_exclusive(n));
8651  match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
8652  ins_cost(VOLATILE_REF_COST);
8653  effect(KILL cr);
8654  format %{
8655    "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8656    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8657  %}
8658  ins_encode %{
8659    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8660               Assembler::xword, /*acquire*/ true, /*release*/ true,
8661               /*weak*/ true, noreg);
8662    __ csetw($res$$Register, Assembler::EQ);
8663  %}
8664  ins_pipe(pipe_slow);
8665%}
8666
8667instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8668  predicate(needs_acquiring_load_exclusive(n));
8669  match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
8670  ins_cost(VOLATILE_REF_COST);
8671  effect(KILL cr);
8672  format %{
8673    "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8674    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8675  %}
8676  ins_encode %{
8677    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8678               Assembler::word, /*acquire*/ true, /*release*/ true,
8679               /*weak*/ true, noreg);
8680    __ csetw($res$$Register, Assembler::EQ);
8681  %}
8682  ins_pipe(pipe_slow);
8683%}
8684
8685instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8686  predicate(needs_acquiring_load_exclusive(n));
8687  match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
8688  ins_cost(VOLATILE_REF_COST);
8689  effect(KILL cr);
8690  format %{
8691    "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8692    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8693  %}
8694  ins_encode %{
8695    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8696               Assembler::xword, /*acquire*/ true, /*release*/ true,
8697               /*weak*/ true, noreg);
8698    __ csetw($res$$Register, Assembler::EQ);
8699  %}
8700  ins_pipe(pipe_slow);
8701%}
8702
8703// END This section of the file is automatically generated. Do not edit --------------
8704// ---------------------------------------------------------------------
8705
8706instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
8707  match(Set prev (GetAndSetI mem newv));
8708  ins_cost(2 * VOLATILE_REF_COST);
8709  format %{ "atomic_xchgw  $prev, $newv, [$mem]" %}
8710  ins_encode %{
8711    __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8712  %}
8713  ins_pipe(pipe_serial);
8714%}
8715
8716instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{
8717  match(Set prev (GetAndSetL mem newv));
8718  ins_cost(2 * VOLATILE_REF_COST);
8719  format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
8720  ins_encode %{
8721    __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
8722  %}
8723  ins_pipe(pipe_serial);
8724%}
8725
8726instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{
8727  match(Set prev (GetAndSetN mem newv));
8728  ins_cost(2 * VOLATILE_REF_COST);
8729  format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
8730  ins_encode %{
8731    __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8732  %}
8733  ins_pipe(pipe_serial);
8734%}
8735
8736instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
8737  match(Set prev (GetAndSetP mem newv));
8738  ins_cost(2 * VOLATILE_REF_COST);
8739  format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
8740  ins_encode %{
8741    __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
8742  %}
8743  ins_pipe(pipe_serial);
8744%}
8745
8746instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{
8747  predicate(needs_acquiring_load_exclusive(n));
8748  match(Set prev (GetAndSetI mem newv));
8749  ins_cost(VOLATILE_REF_COST);
8750  format %{ "atomic_xchgw_acq  $prev, $newv, [$mem]" %}
8751  ins_encode %{
8752    __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8753  %}
8754  ins_pipe(pipe_serial);
8755%}
8756
8757instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{
8758  predicate(needs_acquiring_load_exclusive(n));
8759  match(Set prev (GetAndSetL mem newv));
8760  ins_cost(VOLATILE_REF_COST);
8761  format %{ "atomic_xchg_acq  $prev, $newv, [$mem]" %}
8762  ins_encode %{
8763    __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
8764  %}
8765  ins_pipe(pipe_serial);
8766%}
8767
8768instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{
8769  predicate(needs_acquiring_load_exclusive(n));
8770  match(Set prev (GetAndSetN mem newv));
8771  ins_cost(VOLATILE_REF_COST);
8772  format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %}
8773  ins_encode %{
8774    __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8775  %}
8776  ins_pipe(pipe_serial);
8777%}
8778
8779instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{
8780  predicate(needs_acquiring_load_exclusive(n));
8781  match(Set prev (GetAndSetP mem newv));
8782  ins_cost(VOLATILE_REF_COST);
8783  format %{ "atomic_xchg_acq  $prev, $newv, [$mem]" %}
8784  ins_encode %{
8785    __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
8786  %}
8787  ins_pipe(pipe_serial);
8788%}
8789
8790
8791instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{
8792  match(Set newval (GetAndAddL mem incr));
8793  ins_cost(2 * VOLATILE_REF_COST + 1);
8794  format %{ "get_and_addL $newval, [$mem], $incr" %}
8795  ins_encode %{
8796    __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base));
8797  %}
8798  ins_pipe(pipe_serial);
8799%}
8800
8801instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{
8802  predicate(n->as_LoadStore()->result_not_used());
8803  match(Set dummy (GetAndAddL mem incr));
8804  ins_cost(2 * VOLATILE_REF_COST);
8805  format %{ "get_and_addL [$mem], $incr" %}
8806  ins_encode %{
8807    __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base));
8808  %}
8809  ins_pipe(pipe_serial);
8810%}
8811
8812instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
8813  match(Set newval (GetAndAddL mem incr));
8814  ins_cost(2 * VOLATILE_REF_COST + 1);
8815  format %{ "get_and_addL $newval, [$mem], $incr" %}
8816  ins_encode %{
8817    __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base));
8818  %}
8819  ins_pipe(pipe_serial);
8820%}
8821
8822instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{
8823  predicate(n->as_LoadStore()->result_not_used());
8824  match(Set dummy (GetAndAddL mem incr));
8825  ins_cost(2 * VOLATILE_REF_COST);
8826  format %{ "get_and_addL [$mem], $incr" %}
8827  ins_encode %{
8828    __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base));
8829  %}
8830  ins_pipe(pipe_serial);
8831%}
8832
8833instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
8834  match(Set newval (GetAndAddI mem incr));
8835  ins_cost(2 * VOLATILE_REF_COST + 1);
8836  format %{ "get_and_addI $newval, [$mem], $incr" %}
8837  ins_encode %{
8838    __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base));
8839  %}
8840  ins_pipe(pipe_serial);
8841%}
8842
8843instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{
8844  predicate(n->as_LoadStore()->result_not_used());
8845  match(Set dummy (GetAndAddI mem incr));
8846  ins_cost(2 * VOLATILE_REF_COST);
8847  format %{ "get_and_addI [$mem], $incr" %}
8848  ins_encode %{
8849    __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base));
8850  %}
8851  ins_pipe(pipe_serial);
8852%}
8853
8854instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{
8855  match(Set newval (GetAndAddI mem incr));
8856  ins_cost(2 * VOLATILE_REF_COST + 1);
8857  format %{ "get_and_addI $newval, [$mem], $incr" %}
8858  ins_encode %{
8859    __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base));
8860  %}
8861  ins_pipe(pipe_serial);
8862%}
8863
8864instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{
8865  predicate(n->as_LoadStore()->result_not_used());
8866  match(Set dummy (GetAndAddI mem incr));
8867  ins_cost(2 * VOLATILE_REF_COST);
8868  format %{ "get_and_addI [$mem], $incr" %}
8869  ins_encode %{
8870    __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base));
8871  %}
8872  ins_pipe(pipe_serial);
8873%}
8874
8875instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{
8876  predicate(needs_acquiring_load_exclusive(n));
8877  match(Set newval (GetAndAddL mem incr));
8878  ins_cost(VOLATILE_REF_COST + 1);
8879  format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
8880  ins_encode %{
8881    __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base));
8882  %}
8883  ins_pipe(pipe_serial);
8884%}
8885
8886instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{
8887  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
8888  match(Set dummy (GetAndAddL mem incr));
8889  ins_cost(VOLATILE_REF_COST);
8890  format %{ "get_and_addL_acq [$mem], $incr" %}
8891  ins_encode %{
8892    __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base));
8893  %}
8894  ins_pipe(pipe_serial);
8895%}
8896
8897instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
8898  predicate(needs_acquiring_load_exclusive(n));
8899  match(Set newval (GetAndAddL mem incr));
8900  ins_cost(VOLATILE_REF_COST + 1);
8901  format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
8902  ins_encode %{
8903    __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base));
8904  %}
8905  ins_pipe(pipe_serial);
8906%}
8907
8908instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{
8909  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
8910  match(Set dummy (GetAndAddL mem incr));
8911  ins_cost(VOLATILE_REF_COST);
8912  format %{ "get_and_addL_acq [$mem], $incr" %}
8913  ins_encode %{
8914    __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base));
8915  %}
8916  ins_pipe(pipe_serial);
8917%}
8918
8919instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
8920  predicate(needs_acquiring_load_exclusive(n));
8921  match(Set newval (GetAndAddI mem incr));
8922  ins_cost(VOLATILE_REF_COST + 1);
8923  format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
8924  ins_encode %{
8925    __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base));
8926  %}
8927  ins_pipe(pipe_serial);
8928%}
8929
8930instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{
8931  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
8932  match(Set dummy (GetAndAddI mem incr));
8933  ins_cost(VOLATILE_REF_COST);
8934  format %{ "get_and_addI_acq [$mem], $incr" %}
8935  ins_encode %{
8936    __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base));
8937  %}
8938  ins_pipe(pipe_serial);
8939%}
8940
8941instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{
8942  predicate(needs_acquiring_load_exclusive(n));
8943  match(Set newval (GetAndAddI mem incr));
8944  ins_cost(VOLATILE_REF_COST + 1);
8945  format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
8946  ins_encode %{
8947    __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base));
8948  %}
8949  ins_pipe(pipe_serial);
8950%}
8951
8952instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{
8953  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
8954  match(Set dummy (GetAndAddI mem incr));
8955  ins_cost(VOLATILE_REF_COST);
8956  format %{ "get_and_addI_acq [$mem], $incr" %}
8957  ins_encode %{
8958    __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base));
8959  %}
8960  ins_pipe(pipe_serial);
8961%}
8962
8963// Manifest a CmpL result in an integer register.
8964// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
8965instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
8966%{
8967  match(Set dst (CmpL3 src1 src2));
8968  effect(KILL flags);
8969
8970  ins_cost(INSN_COST * 6);
8971  format %{
8972      "cmp $src1, $src2"
8973      "csetw $dst, ne"
8974      "cnegw $dst, lt"
8975  %}
8976  // format %{ "CmpL3 $dst, $src1, $src2" %}
8977  ins_encode %{
8978    __ cmp($src1$$Register, $src2$$Register);
8979    __ csetw($dst$$Register, Assembler::NE);
8980    __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
8981  %}
8982
8983  ins_pipe(pipe_class_default);
8984%}
8985
8986instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags)
8987%{
8988  match(Set dst (CmpL3 src1 src2));
8989  effect(KILL flags);
8990
8991  ins_cost(INSN_COST * 6);
8992  format %{
8993      "cmp $src1, $src2"
8994      "csetw $dst, ne"
8995      "cnegw $dst, lt"
8996  %}
8997  ins_encode %{
8998    int32_t con = (int32_t)$src2$$constant;
8999     if (con < 0) {
9000      __ adds(zr, $src1$$Register, -con);
9001    } else {
9002      __ subs(zr, $src1$$Register, con);
9003    }
9004    __ csetw($dst$$Register, Assembler::NE);
9005    __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
9006  %}
9007
9008  ins_pipe(pipe_class_default);
9009%}
9010
9011// ============================================================================
9012// Conditional Move Instructions
9013
9014// n.b. we have identical rules for both a signed compare op (cmpOp)
9015// and an unsigned compare op (cmpOpU). it would be nice if we could
9016// define an op class which merged both inputs and use it to type the
9017// argument to a single rule. unfortunatelyt his fails because the
9018// opclass does not live up to the COND_INTER interface of its
9019// component operands. When the generic code tries to negate the
9020// operand it ends up running the generci Machoper::negate method
9021// which throws a ShouldNotHappen. So, we have to provide two flavours
9022// of each rule, one for a cmpOp and a second for a cmpOpU (sigh).
9023
9024instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9025  match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
9026
9027  ins_cost(INSN_COST * 2);
9028  format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int"  %}
9029
9030  ins_encode %{
9031    __ cselw(as_Register($dst$$reg),
9032             as_Register($src2$$reg),
9033             as_Register($src1$$reg),
9034             (Assembler::Condition)$cmp$$cmpcode);
9035  %}
9036
9037  ins_pipe(icond_reg_reg);
9038%}
9039
9040instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9041  match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
9042
9043  ins_cost(INSN_COST * 2);
9044  format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int"  %}
9045
9046  ins_encode %{
9047    __ cselw(as_Register($dst$$reg),
9048             as_Register($src2$$reg),
9049             as_Register($src1$$reg),
9050             (Assembler::Condition)$cmp$$cmpcode);
9051  %}
9052
9053  ins_pipe(icond_reg_reg);
9054%}
9055
9056// special cases where one arg is zero
9057
9058// n.b. this is selected in preference to the rule above because it
9059// avoids loading constant 0 into a source register
9060
9061// TODO
9062// we ought only to be able to cull one of these variants as the ideal
9063// transforms ought always to order the zero consistently (to left/right?)
9064
9065instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
9066  match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
9067
9068  ins_cost(INSN_COST * 2);
9069  format %{ "cselw $dst, $src, zr $cmp\t# signed, int"  %}
9070
9071  ins_encode %{
9072    __ cselw(as_Register($dst$$reg),
9073             as_Register($src$$reg),
9074             zr,
9075             (Assembler::Condition)$cmp$$cmpcode);
9076  %}
9077
9078  ins_pipe(icond_reg);
9079%}
9080
9081instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
9082  match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
9083
9084  ins_cost(INSN_COST * 2);
9085  format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int"  %}
9086
9087  ins_encode %{
9088    __ cselw(as_Register($dst$$reg),
9089             as_Register($src$$reg),
9090             zr,
9091             (Assembler::Condition)$cmp$$cmpcode);
9092  %}
9093
9094  ins_pipe(icond_reg);
9095%}
9096
9097instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
9098  match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
9099
9100  ins_cost(INSN_COST * 2);
9101  format %{ "cselw $dst, zr, $src $cmp\t# signed, int"  %}
9102
9103  ins_encode %{
9104    __ cselw(as_Register($dst$$reg),
9105             zr,
9106             as_Register($src$$reg),
9107             (Assembler::Condition)$cmp$$cmpcode);
9108  %}
9109
9110  ins_pipe(icond_reg);
9111%}
9112
9113instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
9114  match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
9115
9116  ins_cost(INSN_COST * 2);
9117  format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int"  %}
9118
9119  ins_encode %{
9120    __ cselw(as_Register($dst$$reg),
9121             zr,
9122             as_Register($src$$reg),
9123             (Assembler::Condition)$cmp$$cmpcode);
9124  %}
9125
9126  ins_pipe(icond_reg);
9127%}
9128
9129// special case for creating a boolean 0 or 1
9130
9131// n.b. this is selected in preference to the rule above because it
9132// avoids loading constants 0 and 1 into a source register
9133
9134instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
9135  match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
9136
9137  ins_cost(INSN_COST * 2);
9138  format %{ "csincw $dst, zr, zr $cmp\t# signed, int"  %}
9139
9140  ins_encode %{
9141    // equivalently
9142    // cset(as_Register($dst$$reg),
9143    //      negate_condition((Assembler::Condition)$cmp$$cmpcode));
9144    __ csincw(as_Register($dst$$reg),
9145             zr,
9146             zr,
9147             (Assembler::Condition)$cmp$$cmpcode);
9148  %}
9149
9150  ins_pipe(icond_none);
9151%}
9152
9153instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
9154  match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
9155
9156  ins_cost(INSN_COST * 2);
9157  format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int"  %}
9158
9159  ins_encode %{
9160    // equivalently
9161    // cset(as_Register($dst$$reg),
9162    //      negate_condition((Assembler::Condition)$cmp$$cmpcode));
9163    __ csincw(as_Register($dst$$reg),
9164             zr,
9165             zr,
9166             (Assembler::Condition)$cmp$$cmpcode);
9167  %}
9168
9169  ins_pipe(icond_none);
9170%}
9171
9172instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
9173  match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
9174
9175  ins_cost(INSN_COST * 2);
9176  format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long"  %}
9177
9178  ins_encode %{
9179    __ csel(as_Register($dst$$reg),
9180            as_Register($src2$$reg),
9181            as_Register($src1$$reg),
9182            (Assembler::Condition)$cmp$$cmpcode);
9183  %}
9184
9185  ins_pipe(icond_reg_reg);
9186%}
9187
9188instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
9189  match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
9190
9191  ins_cost(INSN_COST * 2);
9192  format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long"  %}
9193
9194  ins_encode %{
9195    __ csel(as_Register($dst$$reg),
9196            as_Register($src2$$reg),
9197            as_Register($src1$$reg),
9198            (Assembler::Condition)$cmp$$cmpcode);
9199  %}
9200
9201  ins_pipe(icond_reg_reg);
9202%}
9203
9204// special cases where one arg is zero
9205
9206instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
9207  match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
9208
9209  ins_cost(INSN_COST * 2);
9210  format %{ "csel $dst, zr, $src $cmp\t# signed, long"  %}
9211
9212  ins_encode %{
9213    __ csel(as_Register($dst$$reg),
9214            zr,
9215            as_Register($src$$reg),
9216            (Assembler::Condition)$cmp$$cmpcode);
9217  %}
9218
9219  ins_pipe(icond_reg);
9220%}
9221
9222instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
9223  match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
9224
9225  ins_cost(INSN_COST * 2);
9226  format %{ "csel $dst, zr, $src $cmp\t# unsigned, long"  %}
9227
9228  ins_encode %{
9229    __ csel(as_Register($dst$$reg),
9230            zr,
9231            as_Register($src$$reg),
9232            (Assembler::Condition)$cmp$$cmpcode);
9233  %}
9234
9235  ins_pipe(icond_reg);
9236%}
9237
9238instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
9239  match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
9240
9241  ins_cost(INSN_COST * 2);
9242  format %{ "csel $dst, $src, zr $cmp\t# signed, long"  %}
9243
9244  ins_encode %{
9245    __ csel(as_Register($dst$$reg),
9246            as_Register($src$$reg),
9247            zr,
9248            (Assembler::Condition)$cmp$$cmpcode);
9249  %}
9250
9251  ins_pipe(icond_reg);
9252%}
9253
9254instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
9255  match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
9256
9257  ins_cost(INSN_COST * 2);
9258  format %{ "csel $dst, $src, zr $cmp\t# unsigned, long"  %}
9259
9260  ins_encode %{
9261    __ csel(as_Register($dst$$reg),
9262            as_Register($src$$reg),
9263            zr,
9264            (Assembler::Condition)$cmp$$cmpcode);
9265  %}
9266
9267  ins_pipe(icond_reg);
9268%}
9269
9270instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
9271  match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
9272
9273  ins_cost(INSN_COST * 2);
9274  format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr"  %}
9275
9276  ins_encode %{
9277    __ csel(as_Register($dst$$reg),
9278            as_Register($src2$$reg),
9279            as_Register($src1$$reg),
9280            (Assembler::Condition)$cmp$$cmpcode);
9281  %}
9282
9283  ins_pipe(icond_reg_reg);
9284%}
9285
9286instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
9287  match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
9288
9289  ins_cost(INSN_COST * 2);
9290  format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr"  %}
9291
9292  ins_encode %{
9293    __ csel(as_Register($dst$$reg),
9294            as_Register($src2$$reg),
9295            as_Register($src1$$reg),
9296            (Assembler::Condition)$cmp$$cmpcode);
9297  %}
9298
9299  ins_pipe(icond_reg_reg);
9300%}
9301
9302// special cases where one arg is zero
9303
9304instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
9305  match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
9306
9307  ins_cost(INSN_COST * 2);
9308  format %{ "csel $dst, zr, $src $cmp\t# signed, ptr"  %}
9309
9310  ins_encode %{
9311    __ csel(as_Register($dst$$reg),
9312            zr,
9313            as_Register($src$$reg),
9314            (Assembler::Condition)$cmp$$cmpcode);
9315  %}
9316
9317  ins_pipe(icond_reg);
9318%}
9319
9320instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
9321  match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
9322
9323  ins_cost(INSN_COST * 2);
9324  format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr"  %}
9325
9326  ins_encode %{
9327    __ csel(as_Register($dst$$reg),
9328            zr,
9329            as_Register($src$$reg),
9330            (Assembler::Condition)$cmp$$cmpcode);
9331  %}
9332
9333  ins_pipe(icond_reg);
9334%}
9335
9336instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
9337  match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
9338
9339  ins_cost(INSN_COST * 2);
9340  format %{ "csel $dst, $src, zr $cmp\t# signed, ptr"  %}
9341
9342  ins_encode %{
9343    __ csel(as_Register($dst$$reg),
9344            as_Register($src$$reg),
9345            zr,
9346            (Assembler::Condition)$cmp$$cmpcode);
9347  %}
9348
9349  ins_pipe(icond_reg);
9350%}
9351
9352instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
9353  match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
9354
9355  ins_cost(INSN_COST * 2);
9356  format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr"  %}
9357
9358  ins_encode %{
9359    __ csel(as_Register($dst$$reg),
9360            as_Register($src$$reg),
9361            zr,
9362            (Assembler::Condition)$cmp$$cmpcode);
9363  %}
9364
9365  ins_pipe(icond_reg);
9366%}
9367
9368instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
9369  match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
9370
9371  ins_cost(INSN_COST * 2);
9372  format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr"  %}
9373
9374  ins_encode %{
9375    __ cselw(as_Register($dst$$reg),
9376             as_Register($src2$$reg),
9377             as_Register($src1$$reg),
9378             (Assembler::Condition)$cmp$$cmpcode);
9379  %}
9380
9381  ins_pipe(icond_reg_reg);
9382%}
9383
9384instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
9385  match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
9386
9387  ins_cost(INSN_COST * 2);
9388  format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr"  %}
9389
9390  ins_encode %{
9391    __ cselw(as_Register($dst$$reg),
9392             as_Register($src2$$reg),
9393             as_Register($src1$$reg),
9394             (Assembler::Condition)$cmp$$cmpcode);
9395  %}
9396
9397  ins_pipe(icond_reg_reg);
9398%}
9399
9400// special cases where one arg is zero
9401
9402instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
9403  match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
9404
9405  ins_cost(INSN_COST * 2);
9406  format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr"  %}
9407
9408  ins_encode %{
9409    __ cselw(as_Register($dst$$reg),
9410             zr,
9411             as_Register($src$$reg),
9412             (Assembler::Condition)$cmp$$cmpcode);
9413  %}
9414
9415  ins_pipe(icond_reg);
9416%}
9417
9418instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
9419  match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
9420
9421  ins_cost(INSN_COST * 2);
9422  format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr"  %}
9423
9424  ins_encode %{
9425    __ cselw(as_Register($dst$$reg),
9426             zr,
9427             as_Register($src$$reg),
9428             (Assembler::Condition)$cmp$$cmpcode);
9429  %}
9430
9431  ins_pipe(icond_reg);
9432%}
9433
9434instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
9435  match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
9436
9437  ins_cost(INSN_COST * 2);
9438  format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr"  %}
9439
9440  ins_encode %{
9441    __ cselw(as_Register($dst$$reg),
9442             as_Register($src$$reg),
9443             zr,
9444             (Assembler::Condition)$cmp$$cmpcode);
9445  %}
9446
9447  ins_pipe(icond_reg);
9448%}
9449
9450instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
9451  match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
9452
9453  ins_cost(INSN_COST * 2);
9454  format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr"  %}
9455
9456  ins_encode %{
9457    __ cselw(as_Register($dst$$reg),
9458             as_Register($src$$reg),
9459             zr,
9460             (Assembler::Condition)$cmp$$cmpcode);
9461  %}
9462
9463  ins_pipe(icond_reg);
9464%}
9465
9466instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1,  vRegF src2)
9467%{
9468  match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
9469
9470  ins_cost(INSN_COST * 3);
9471
9472  format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
9473  ins_encode %{
9474    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9475    __ fcsels(as_FloatRegister($dst$$reg),
9476              as_FloatRegister($src2$$reg),
9477              as_FloatRegister($src1$$reg),
9478              cond);
9479  %}
9480
9481  ins_pipe(fp_cond_reg_reg_s);
9482%}
9483
9484instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1,  vRegF src2)
9485%{
9486  match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
9487
9488  ins_cost(INSN_COST * 3);
9489
9490  format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
9491  ins_encode %{
9492    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9493    __ fcsels(as_FloatRegister($dst$$reg),
9494              as_FloatRegister($src2$$reg),
9495              as_FloatRegister($src1$$reg),
9496              cond);
9497  %}
9498
9499  ins_pipe(fp_cond_reg_reg_s);
9500%}
9501
9502instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1,  vRegD src2)
9503%{
9504  match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
9505
9506  ins_cost(INSN_COST * 3);
9507
9508  format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
9509  ins_encode %{
9510    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9511    __ fcseld(as_FloatRegister($dst$$reg),
9512              as_FloatRegister($src2$$reg),
9513              as_FloatRegister($src1$$reg),
9514              cond);
9515  %}
9516
9517  ins_pipe(fp_cond_reg_reg_d);
9518%}
9519
9520instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1,  vRegD src2)
9521%{
9522  match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
9523
9524  ins_cost(INSN_COST * 3);
9525
9526  format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
9527  ins_encode %{
9528    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9529    __ fcseld(as_FloatRegister($dst$$reg),
9530              as_FloatRegister($src2$$reg),
9531              as_FloatRegister($src1$$reg),
9532              cond);
9533  %}
9534
9535  ins_pipe(fp_cond_reg_reg_d);
9536%}
9537
9538// ============================================================================
9539// Arithmetic Instructions
9540//
9541
9542// Integer Addition
9543
9544// TODO
9545// these currently employ operations which do not set CR and hence are
9546// not flagged as killing CR but we would like to isolate the cases
9547// where we want to set flags from those where we don't. need to work
9548// out how to do that.
9549
9550instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9551  match(Set dst (AddI src1 src2));
9552
9553  ins_cost(INSN_COST);
9554  format %{ "addw  $dst, $src1, $src2" %}
9555
9556  ins_encode %{
9557    __ addw(as_Register($dst$$reg),
9558            as_Register($src1$$reg),
9559            as_Register($src2$$reg));
9560  %}
9561
9562  ins_pipe(ialu_reg_reg);
9563%}
9564
9565instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
9566  match(Set dst (AddI src1 src2));
9567
9568  ins_cost(INSN_COST);
9569  format %{ "addw $dst, $src1, $src2" %}
9570
9571  // use opcode to indicate that this is an add not a sub
9572  opcode(0x0);
9573
9574  ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
9575
9576  ins_pipe(ialu_reg_imm);
9577%}
9578
9579instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{
9580  match(Set dst (AddI (ConvL2I src1) src2));
9581
9582  ins_cost(INSN_COST);
9583  format %{ "addw $dst, $src1, $src2" %}
9584
9585  // use opcode to indicate that this is an add not a sub
9586  opcode(0x0);
9587
9588  ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
9589
9590  ins_pipe(ialu_reg_imm);
9591%}
9592
9593// Pointer Addition
9594instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{
9595  match(Set dst (AddP src1 src2));
9596
9597  ins_cost(INSN_COST);
9598  format %{ "add $dst, $src1, $src2\t# ptr" %}
9599
9600  ins_encode %{
9601    __ add(as_Register($dst$$reg),
9602           as_Register($src1$$reg),
9603           as_Register($src2$$reg));
9604  %}
9605
9606  ins_pipe(ialu_reg_reg);
9607%}
9608
9609instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{
9610  match(Set dst (AddP src1 (ConvI2L src2)));
9611
9612  ins_cost(1.9 * INSN_COST);
9613  format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %}
9614
9615  ins_encode %{
9616    __ add(as_Register($dst$$reg),
9617           as_Register($src1$$reg),
9618           as_Register($src2$$reg), ext::sxtw);
9619  %}
9620
9621  ins_pipe(ialu_reg_reg);
9622%}
9623
9624instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{
9625  match(Set dst (AddP src1 (LShiftL src2 scale)));
9626
9627  ins_cost(1.9 * INSN_COST);
9628  format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %}
9629
9630  ins_encode %{
9631    __ lea(as_Register($dst$$reg),
9632           Address(as_Register($src1$$reg), as_Register($src2$$reg),
9633                   Address::lsl($scale$$constant)));
9634  %}
9635
9636  ins_pipe(ialu_reg_reg_shift);
9637%}
9638
9639instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{
9640  match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale)));
9641
9642  ins_cost(1.9 * INSN_COST);
9643  format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %}
9644
9645  ins_encode %{
9646    __ lea(as_Register($dst$$reg),
9647           Address(as_Register($src1$$reg), as_Register($src2$$reg),
9648                   Address::sxtw($scale$$constant)));
9649  %}
9650
9651  ins_pipe(ialu_reg_reg_shift);
9652%}
9653
9654instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{
9655  match(Set dst (LShiftL (ConvI2L src) scale));
9656
9657  ins_cost(INSN_COST);
9658  format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %}
9659
9660  ins_encode %{
9661    __ sbfiz(as_Register($dst$$reg),
9662          as_Register($src$$reg),
9663          $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63)));
9664  %}
9665
9666  ins_pipe(ialu_reg_shift);
9667%}
9668
9669// Pointer Immediate Addition
9670// n.b. this needs to be more expensive than using an indirect memory
9671// operand
9672instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{
9673  match(Set dst (AddP src1 src2));
9674
9675  ins_cost(INSN_COST);
9676  format %{ "add $dst, $src1, $src2\t# ptr" %}
9677
9678  // use opcode to indicate that this is an add not a sub
9679  opcode(0x0);
9680
9681  ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
9682
9683  ins_pipe(ialu_reg_imm);
9684%}
9685
9686// Long Addition
9687instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9688
9689  match(Set dst (AddL src1 src2));
9690
9691  ins_cost(INSN_COST);
9692  format %{ "add  $dst, $src1, $src2" %}
9693
9694  ins_encode %{
9695    __ add(as_Register($dst$$reg),
9696           as_Register($src1$$reg),
9697           as_Register($src2$$reg));
9698  %}
9699
9700  ins_pipe(ialu_reg_reg);
9701%}
9702
9703// No constant pool entries requiredLong Immediate Addition.
9704instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
9705  match(Set dst (AddL src1 src2));
9706
9707  ins_cost(INSN_COST);
9708  format %{ "add $dst, $src1, $src2" %}
9709
9710  // use opcode to indicate that this is an add not a sub
9711  opcode(0x0);
9712
9713  ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
9714
9715  ins_pipe(ialu_reg_imm);
9716%}
9717
9718// Integer Subtraction
9719instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9720  match(Set dst (SubI src1 src2));
9721
9722  ins_cost(INSN_COST);
9723  format %{ "subw  $dst, $src1, $src2" %}
9724
9725  ins_encode %{
9726    __ subw(as_Register($dst$$reg),
9727            as_Register($src1$$reg),
9728            as_Register($src2$$reg));
9729  %}
9730
9731  ins_pipe(ialu_reg_reg);
9732%}
9733
9734// Immediate Subtraction
9735instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
9736  match(Set dst (SubI src1 src2));
9737
9738  ins_cost(INSN_COST);
9739  format %{ "subw $dst, $src1, $src2" %}
9740
9741  // use opcode to indicate that this is a sub not an add
9742  opcode(0x1);
9743
9744  ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
9745
9746  ins_pipe(ialu_reg_imm);
9747%}
9748
9749// Long Subtraction
9750instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9751
9752  match(Set dst (SubL src1 src2));
9753
9754  ins_cost(INSN_COST);
9755  format %{ "sub  $dst, $src1, $src2" %}
9756
9757  ins_encode %{
9758    __ sub(as_Register($dst$$reg),
9759           as_Register($src1$$reg),
9760           as_Register($src2$$reg));
9761  %}
9762
9763  ins_pipe(ialu_reg_reg);
9764%}
9765
9766// No constant pool entries requiredLong Immediate Subtraction.
9767instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
9768  match(Set dst (SubL src1 src2));
9769
9770  ins_cost(INSN_COST);
9771  format %{ "sub$dst, $src1, $src2" %}
9772
9773  // use opcode to indicate that this is a sub not an add
9774  opcode(0x1);
9775
9776  ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
9777
9778  ins_pipe(ialu_reg_imm);
9779%}
9780
9781// Integer Negation (special case for sub)
9782
9783instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{
9784  match(Set dst (SubI zero src));
9785
9786  ins_cost(INSN_COST);
9787  format %{ "negw $dst, $src\t# int" %}
9788
9789  ins_encode %{
9790    __ negw(as_Register($dst$$reg),
9791            as_Register($src$$reg));
9792  %}
9793
9794  ins_pipe(ialu_reg);
9795%}
9796
9797// Long Negation
9798
9799instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{
9800  match(Set dst (SubL zero src));
9801
9802  ins_cost(INSN_COST);
9803  format %{ "neg $dst, $src\t# long" %}
9804
9805  ins_encode %{
9806    __ neg(as_Register($dst$$reg),
9807           as_Register($src$$reg));
9808  %}
9809
9810  ins_pipe(ialu_reg);
9811%}
9812
9813// Integer Multiply
9814
9815instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9816  match(Set dst (MulI src1 src2));
9817
9818  ins_cost(INSN_COST * 3);
9819  format %{ "mulw  $dst, $src1, $src2" %}
9820
9821  ins_encode %{
9822    __ mulw(as_Register($dst$$reg),
9823            as_Register($src1$$reg),
9824            as_Register($src2$$reg));
9825  %}
9826
9827  ins_pipe(imul_reg_reg);
9828%}
9829
9830instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9831  match(Set dst (MulL (ConvI2L src1) (ConvI2L src2)));
9832
9833  ins_cost(INSN_COST * 3);
9834  format %{ "smull  $dst, $src1, $src2" %}
9835
9836  ins_encode %{
9837    __ smull(as_Register($dst$$reg),
9838             as_Register($src1$$reg),
9839             as_Register($src2$$reg));
9840  %}
9841
9842  ins_pipe(imul_reg_reg);
9843%}
9844
9845// Long Multiply
9846
9847instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9848  match(Set dst (MulL src1 src2));
9849
9850  ins_cost(INSN_COST * 5);
9851  format %{ "mul  $dst, $src1, $src2" %}
9852
9853  ins_encode %{
9854    __ mul(as_Register($dst$$reg),
9855           as_Register($src1$$reg),
9856           as_Register($src2$$reg));
9857  %}
9858
9859  ins_pipe(lmul_reg_reg);
9860%}
9861
9862instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr)
9863%{
9864  match(Set dst (MulHiL src1 src2));
9865
9866  ins_cost(INSN_COST * 7);
9867  format %{ "smulh   $dst, $src1, $src2, \t# mulhi" %}
9868
9869  ins_encode %{
9870    __ smulh(as_Register($dst$$reg),
9871             as_Register($src1$$reg),
9872             as_Register($src2$$reg));
9873  %}
9874
9875  ins_pipe(lmul_reg_reg);
9876%}
9877
9878// Combined Integer Multiply & Add/Sub
9879
9880instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
9881  match(Set dst (AddI src3 (MulI src1 src2)));
9882
9883  ins_cost(INSN_COST * 3);
9884  format %{ "madd  $dst, $src1, $src2, $src3" %}
9885
9886  ins_encode %{
9887    __ maddw(as_Register($dst$$reg),
9888             as_Register($src1$$reg),
9889             as_Register($src2$$reg),
9890             as_Register($src3$$reg));
9891  %}
9892
9893  ins_pipe(imac_reg_reg);
9894%}
9895
9896instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
9897  match(Set dst (SubI src3 (MulI src1 src2)));
9898
9899  ins_cost(INSN_COST * 3);
9900  format %{ "msub  $dst, $src1, $src2, $src3" %}
9901
9902  ins_encode %{
9903    __ msubw(as_Register($dst$$reg),
9904             as_Register($src1$$reg),
9905             as_Register($src2$$reg),
9906             as_Register($src3$$reg));
9907  %}
9908
9909  ins_pipe(imac_reg_reg);
9910%}
9911
9912// Combined Long Multiply & Add/Sub
9913
9914instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
9915  match(Set dst (AddL src3 (MulL src1 src2)));
9916
9917  ins_cost(INSN_COST * 5);
9918  format %{ "madd  $dst, $src1, $src2, $src3" %}
9919
9920  ins_encode %{
9921    __ madd(as_Register($dst$$reg),
9922            as_Register($src1$$reg),
9923            as_Register($src2$$reg),
9924            as_Register($src3$$reg));
9925  %}
9926
9927  ins_pipe(lmac_reg_reg);
9928%}
9929
9930instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
9931  match(Set dst (SubL src3 (MulL src1 src2)));
9932
9933  ins_cost(INSN_COST * 5);
9934  format %{ "msub  $dst, $src1, $src2, $src3" %}
9935
9936  ins_encode %{
9937    __ msub(as_Register($dst$$reg),
9938            as_Register($src1$$reg),
9939            as_Register($src2$$reg),
9940            as_Register($src3$$reg));
9941  %}
9942
9943  ins_pipe(lmac_reg_reg);
9944%}
9945
9946// Combine Integer Signed Multiply & Add/Sub/Neg Long
9947
9948instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{
9949  match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2))));
9950
9951  ins_cost(INSN_COST * 3);
9952  format %{ "smaddl  $dst, $src1, $src2, $src3" %}
9953
9954  ins_encode %{
9955    __ smaddl(as_Register($dst$$reg),
9956              as_Register($src1$$reg),
9957              as_Register($src2$$reg),
9958              as_Register($src3$$reg));
9959  %}
9960
9961  ins_pipe(imac_reg_reg);
9962%}
9963
9964instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{
9965  match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2))));
9966
9967  ins_cost(INSN_COST * 3);
9968  format %{ "smsubl  $dst, $src1, $src2, $src3" %}
9969
9970  ins_encode %{
9971    __ smsubl(as_Register($dst$$reg),
9972              as_Register($src1$$reg),
9973              as_Register($src2$$reg),
9974              as_Register($src3$$reg));
9975  %}
9976
9977  ins_pipe(imac_reg_reg);
9978%}
9979
9980instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{
9981  match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2)));
9982  match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2))));
9983
9984  ins_cost(INSN_COST * 3);
9985  format %{ "smnegl  $dst, $src1, $src2" %}
9986
9987  ins_encode %{
9988    __ smnegl(as_Register($dst$$reg),
9989              as_Register($src1$$reg),
9990              as_Register($src2$$reg));
9991  %}
9992
9993  ins_pipe(imac_reg_reg);
9994%}
9995
9996// Integer Divide
9997
9998instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9999  match(Set dst (DivI src1 src2));
10000
10001  ins_cost(INSN_COST * 19);
10002  format %{ "sdivw  $dst, $src1, $src2" %}
10003
10004  ins_encode(aarch64_enc_divw(dst, src1, src2));
10005  ins_pipe(idiv_reg_reg);
10006%}
10007
10008// Long Divide
10009
10010instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10011  match(Set dst (DivL src1 src2));
10012
10013  ins_cost(INSN_COST * 35);
10014  format %{ "sdiv   $dst, $src1, $src2" %}
10015
10016  ins_encode(aarch64_enc_div(dst, src1, src2));
10017  ins_pipe(ldiv_reg_reg);
10018%}
10019
10020// Integer Remainder
10021
10022instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10023  match(Set dst (ModI src1 src2));
10024
10025  ins_cost(INSN_COST * 22);
10026  format %{ "sdivw  rscratch1, $src1, $src2\n\t"
10027            "msubw($dst, rscratch1, $src2, $src1" %}
10028
10029  ins_encode(aarch64_enc_modw(dst, src1, src2));
10030  ins_pipe(idiv_reg_reg);
10031%}
10032
10033// Long Remainder
10034
10035instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10036  match(Set dst (ModL src1 src2));
10037
10038  ins_cost(INSN_COST * 38);
10039  format %{ "sdiv   rscratch1, $src1, $src2\n"
10040            "msub($dst, rscratch1, $src2, $src1" %}
10041
10042  ins_encode(aarch64_enc_mod(dst, src1, src2));
10043  ins_pipe(ldiv_reg_reg);
10044%}
10045
10046// Integer Shifts
10047
10048// Shift Left Register
10049instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10050  match(Set dst (LShiftI src1 src2));
10051
10052  ins_cost(INSN_COST * 2);
10053  format %{ "lslvw  $dst, $src1, $src2" %}
10054
10055  ins_encode %{
10056    __ lslvw(as_Register($dst$$reg),
10057             as_Register($src1$$reg),
10058             as_Register($src2$$reg));
10059  %}
10060
10061  ins_pipe(ialu_reg_reg_vshift);
10062%}
10063
10064// Shift Left Immediate
10065instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10066  match(Set dst (LShiftI src1 src2));
10067
10068  ins_cost(INSN_COST);
10069  format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %}
10070
10071  ins_encode %{
10072    __ lslw(as_Register($dst$$reg),
10073            as_Register($src1$$reg),
10074            $src2$$constant & 0x1f);
10075  %}
10076
10077  ins_pipe(ialu_reg_shift);
10078%}
10079
10080// Shift Right Logical Register
10081instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10082  match(Set dst (URShiftI src1 src2));
10083
10084  ins_cost(INSN_COST * 2);
10085  format %{ "lsrvw  $dst, $src1, $src2" %}
10086
10087  ins_encode %{
10088    __ lsrvw(as_Register($dst$$reg),
10089             as_Register($src1$$reg),
10090             as_Register($src2$$reg));
10091  %}
10092
10093  ins_pipe(ialu_reg_reg_vshift);
10094%}
10095
10096// Shift Right Logical Immediate
10097instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10098  match(Set dst (URShiftI src1 src2));
10099
10100  ins_cost(INSN_COST);
10101  format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %}
10102
10103  ins_encode %{
10104    __ lsrw(as_Register($dst$$reg),
10105            as_Register($src1$$reg),
10106            $src2$$constant & 0x1f);
10107  %}
10108
10109  ins_pipe(ialu_reg_shift);
10110%}
10111
10112// Shift Right Arithmetic Register
10113instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10114  match(Set dst (RShiftI src1 src2));
10115
10116  ins_cost(INSN_COST * 2);
10117  format %{ "asrvw  $dst, $src1, $src2" %}
10118
10119  ins_encode %{
10120    __ asrvw(as_Register($dst$$reg),
10121             as_Register($src1$$reg),
10122             as_Register($src2$$reg));
10123  %}
10124
10125  ins_pipe(ialu_reg_reg_vshift);
10126%}
10127
10128// Shift Right Arithmetic Immediate
10129instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10130  match(Set dst (RShiftI src1 src2));
10131
10132  ins_cost(INSN_COST);
10133  format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %}
10134
10135  ins_encode %{
10136    __ asrw(as_Register($dst$$reg),
10137            as_Register($src1$$reg),
10138            $src2$$constant & 0x1f);
10139  %}
10140
10141  ins_pipe(ialu_reg_shift);
10142%}
10143
10144// Combined Int Mask and Right Shift (using UBFM)
10145// TODO
10146
10147// Long Shifts
10148
10149// Shift Left Register
10150instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10151  match(Set dst (LShiftL src1 src2));
10152
10153  ins_cost(INSN_COST * 2);
10154  format %{ "lslv  $dst, $src1, $src2" %}
10155
10156  ins_encode %{
10157    __ lslv(as_Register($dst$$reg),
10158            as_Register($src1$$reg),
10159            as_Register($src2$$reg));
10160  %}
10161
10162  ins_pipe(ialu_reg_reg_vshift);
10163%}
10164
10165// Shift Left Immediate
10166instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10167  match(Set dst (LShiftL src1 src2));
10168
10169  ins_cost(INSN_COST);
10170  format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %}
10171
10172  ins_encode %{
10173    __ lsl(as_Register($dst$$reg),
10174            as_Register($src1$$reg),
10175            $src2$$constant & 0x3f);
10176  %}
10177
10178  ins_pipe(ialu_reg_shift);
10179%}
10180
10181// Shift Right Logical Register
10182instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10183  match(Set dst (URShiftL src1 src2));
10184
10185  ins_cost(INSN_COST * 2);
10186  format %{ "lsrv  $dst, $src1, $src2" %}
10187
10188  ins_encode %{
10189    __ lsrv(as_Register($dst$$reg),
10190            as_Register($src1$$reg),
10191            as_Register($src2$$reg));
10192  %}
10193
10194  ins_pipe(ialu_reg_reg_vshift);
10195%}
10196
10197// Shift Right Logical Immediate
10198instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10199  match(Set dst (URShiftL src1 src2));
10200
10201  ins_cost(INSN_COST);
10202  format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %}
10203
10204  ins_encode %{
10205    __ lsr(as_Register($dst$$reg),
10206           as_Register($src1$$reg),
10207           $src2$$constant & 0x3f);
10208  %}
10209
10210  ins_pipe(ialu_reg_shift);
10211%}
10212
10213// A special-case pattern for card table stores.
10214instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{
10215  match(Set dst (URShiftL (CastP2X src1) src2));
10216
10217  ins_cost(INSN_COST);
10218  format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %}
10219
10220  ins_encode %{
10221    __ lsr(as_Register($dst$$reg),
10222           as_Register($src1$$reg),
10223           $src2$$constant & 0x3f);
10224  %}
10225
10226  ins_pipe(ialu_reg_shift);
10227%}
10228
10229// Shift Right Arithmetic Register
10230instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10231  match(Set dst (RShiftL src1 src2));
10232
10233  ins_cost(INSN_COST * 2);
10234  format %{ "asrv  $dst, $src1, $src2" %}
10235
10236  ins_encode %{
10237    __ asrv(as_Register($dst$$reg),
10238            as_Register($src1$$reg),
10239            as_Register($src2$$reg));
10240  %}
10241
10242  ins_pipe(ialu_reg_reg_vshift);
10243%}
10244
10245// Shift Right Arithmetic Immediate
10246instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10247  match(Set dst (RShiftL src1 src2));
10248
10249  ins_cost(INSN_COST);
10250  format %{ "asr $dst, $src1, ($src2 & 0x3f)" %}
10251
10252  ins_encode %{
10253    __ asr(as_Register($dst$$reg),
10254           as_Register($src1$$reg),
10255           $src2$$constant & 0x3f);
10256  %}
10257
10258  ins_pipe(ialu_reg_shift);
10259%}
10260
10261// BEGIN This section of the file is automatically generated. Do not edit --------------
10262
10263
10264
10265// This pattern is automatically generated from aarch64_ad.m4
10266// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10267instruct regL_not_reg(iRegLNoSp dst,
10268                         iRegL src1, immL_M1 m1,
10269                         rFlagsReg cr) %{
10270  match(Set dst (XorL src1 m1));
10271  ins_cost(INSN_COST);
10272  format %{ "eon  $dst, $src1, zr" %}
10273
10274  ins_encode %{
10275    __ eon(as_Register($dst$$reg),
10276              as_Register($src1$$reg),
10277              zr,
10278              Assembler::LSL, 0);
10279  %}
10280
10281  ins_pipe(ialu_reg);
10282%}
10283
10284// This pattern is automatically generated from aarch64_ad.m4
10285// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10286instruct regI_not_reg(iRegINoSp dst,
10287                         iRegIorL2I src1, immI_M1 m1,
10288                         rFlagsReg cr) %{
10289  match(Set dst (XorI src1 m1));
10290  ins_cost(INSN_COST);
10291  format %{ "eonw  $dst, $src1, zr" %}
10292
10293  ins_encode %{
10294    __ eonw(as_Register($dst$$reg),
10295              as_Register($src1$$reg),
10296              zr,
10297              Assembler::LSL, 0);
10298  %}
10299
10300  ins_pipe(ialu_reg);
10301%}
10302
10303// This pattern is automatically generated from aarch64_ad.m4
10304// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10305instruct AndI_reg_not_reg(iRegINoSp dst,
10306                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
10307                         rFlagsReg cr) %{
10308  match(Set dst (AndI src1 (XorI src2 m1)));
10309  ins_cost(INSN_COST);
10310  format %{ "bicw  $dst, $src1, $src2" %}
10311
10312  ins_encode %{
10313    __ bicw(as_Register($dst$$reg),
10314              as_Register($src1$$reg),
10315              as_Register($src2$$reg),
10316              Assembler::LSL, 0);
10317  %}
10318
10319  ins_pipe(ialu_reg_reg);
10320%}
10321
10322// This pattern is automatically generated from aarch64_ad.m4
10323// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10324instruct AndL_reg_not_reg(iRegLNoSp dst,
10325                         iRegL src1, iRegL src2, immL_M1 m1,
10326                         rFlagsReg cr) %{
10327  match(Set dst (AndL src1 (XorL src2 m1)));
10328  ins_cost(INSN_COST);
10329  format %{ "bic  $dst, $src1, $src2" %}
10330
10331  ins_encode %{
10332    __ bic(as_Register($dst$$reg),
10333              as_Register($src1$$reg),
10334              as_Register($src2$$reg),
10335              Assembler::LSL, 0);
10336  %}
10337
10338  ins_pipe(ialu_reg_reg);
10339%}
10340
10341// This pattern is automatically generated from aarch64_ad.m4
10342// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10343instruct OrI_reg_not_reg(iRegINoSp dst,
10344                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
10345                         rFlagsReg cr) %{
10346  match(Set dst (OrI src1 (XorI src2 m1)));
10347  ins_cost(INSN_COST);
10348  format %{ "ornw  $dst, $src1, $src2" %}
10349
10350  ins_encode %{
10351    __ ornw(as_Register($dst$$reg),
10352              as_Register($src1$$reg),
10353              as_Register($src2$$reg),
10354              Assembler::LSL, 0);
10355  %}
10356
10357  ins_pipe(ialu_reg_reg);
10358%}
10359
10360// This pattern is automatically generated from aarch64_ad.m4
10361// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10362instruct OrL_reg_not_reg(iRegLNoSp dst,
10363                         iRegL src1, iRegL src2, immL_M1 m1,
10364                         rFlagsReg cr) %{
10365  match(Set dst (OrL src1 (XorL src2 m1)));
10366  ins_cost(INSN_COST);
10367  format %{ "orn  $dst, $src1, $src2" %}
10368
10369  ins_encode %{
10370    __ orn(as_Register($dst$$reg),
10371              as_Register($src1$$reg),
10372              as_Register($src2$$reg),
10373              Assembler::LSL, 0);
10374  %}
10375
10376  ins_pipe(ialu_reg_reg);
10377%}
10378
10379// This pattern is automatically generated from aarch64_ad.m4
10380// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10381instruct XorI_reg_not_reg(iRegINoSp dst,
10382                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
10383                         rFlagsReg cr) %{
10384  match(Set dst (XorI m1 (XorI src2 src1)));
10385  ins_cost(INSN_COST);
10386  format %{ "eonw  $dst, $src1, $src2" %}
10387
10388  ins_encode %{
10389    __ eonw(as_Register($dst$$reg),
10390              as_Register($src1$$reg),
10391              as_Register($src2$$reg),
10392              Assembler::LSL, 0);
10393  %}
10394
10395  ins_pipe(ialu_reg_reg);
10396%}
10397
10398// This pattern is automatically generated from aarch64_ad.m4
10399// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10400instruct XorL_reg_not_reg(iRegLNoSp dst,
10401                         iRegL src1, iRegL src2, immL_M1 m1,
10402                         rFlagsReg cr) %{
10403  match(Set dst (XorL m1 (XorL src2 src1)));
10404  ins_cost(INSN_COST);
10405  format %{ "eon  $dst, $src1, $src2" %}
10406
10407  ins_encode %{
10408    __ eon(as_Register($dst$$reg),
10409              as_Register($src1$$reg),
10410              as_Register($src2$$reg),
10411              Assembler::LSL, 0);
10412  %}
10413
10414  ins_pipe(ialu_reg_reg);
10415%}
10416
10417// This pattern is automatically generated from aarch64_ad.m4
10418// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10419instruct AndI_reg_URShift_not_reg(iRegINoSp dst,
10420                         iRegIorL2I src1, iRegIorL2I src2,
10421                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10422  match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4)));
10423  ins_cost(1.9 * INSN_COST);
10424  format %{ "bicw  $dst, $src1, $src2, LSR $src3" %}
10425
10426  ins_encode %{
10427    __ bicw(as_Register($dst$$reg),
10428              as_Register($src1$$reg),
10429              as_Register($src2$$reg),
10430              Assembler::LSR,
10431              $src3$$constant & 0x1f);
10432  %}
10433
10434  ins_pipe(ialu_reg_reg_shift);
10435%}
10436
10437// This pattern is automatically generated from aarch64_ad.m4
10438// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10439instruct AndL_reg_URShift_not_reg(iRegLNoSp dst,
10440                         iRegL src1, iRegL src2,
10441                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10442  match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4)));
10443  ins_cost(1.9 * INSN_COST);
10444  format %{ "bic  $dst, $src1, $src2, LSR $src3" %}
10445
10446  ins_encode %{
10447    __ bic(as_Register($dst$$reg),
10448              as_Register($src1$$reg),
10449              as_Register($src2$$reg),
10450              Assembler::LSR,
10451              $src3$$constant & 0x3f);
10452  %}
10453
10454  ins_pipe(ialu_reg_reg_shift);
10455%}
10456
10457// This pattern is automatically generated from aarch64_ad.m4
10458// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10459instruct AndI_reg_RShift_not_reg(iRegINoSp dst,
10460                         iRegIorL2I src1, iRegIorL2I src2,
10461                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10462  match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4)));
10463  ins_cost(1.9 * INSN_COST);
10464  format %{ "bicw  $dst, $src1, $src2, ASR $src3" %}
10465
10466  ins_encode %{
10467    __ bicw(as_Register($dst$$reg),
10468              as_Register($src1$$reg),
10469              as_Register($src2$$reg),
10470              Assembler::ASR,
10471              $src3$$constant & 0x1f);
10472  %}
10473
10474  ins_pipe(ialu_reg_reg_shift);
10475%}
10476
10477// This pattern is automatically generated from aarch64_ad.m4
10478// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10479instruct AndL_reg_RShift_not_reg(iRegLNoSp dst,
10480                         iRegL src1, iRegL src2,
10481                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10482  match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4)));
10483  ins_cost(1.9 * INSN_COST);
10484  format %{ "bic  $dst, $src1, $src2, ASR $src3" %}
10485
10486  ins_encode %{
10487    __ bic(as_Register($dst$$reg),
10488              as_Register($src1$$reg),
10489              as_Register($src2$$reg),
10490              Assembler::ASR,
10491              $src3$$constant & 0x3f);
10492  %}
10493
10494  ins_pipe(ialu_reg_reg_shift);
10495%}
10496
10497// This pattern is automatically generated from aarch64_ad.m4
10498// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10499instruct AndI_reg_LShift_not_reg(iRegINoSp dst,
10500                         iRegIorL2I src1, iRegIorL2I src2,
10501                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10502  match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4)));
10503  ins_cost(1.9 * INSN_COST);
10504  format %{ "bicw  $dst, $src1, $src2, LSL $src3" %}
10505
10506  ins_encode %{
10507    __ bicw(as_Register($dst$$reg),
10508              as_Register($src1$$reg),
10509              as_Register($src2$$reg),
10510              Assembler::LSL,
10511              $src3$$constant & 0x1f);
10512  %}
10513
10514  ins_pipe(ialu_reg_reg_shift);
10515%}
10516
10517// This pattern is automatically generated from aarch64_ad.m4
10518// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10519instruct AndL_reg_LShift_not_reg(iRegLNoSp dst,
10520                         iRegL src1, iRegL src2,
10521                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10522  match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4)));
10523  ins_cost(1.9 * INSN_COST);
10524  format %{ "bic  $dst, $src1, $src2, LSL $src3" %}
10525
10526  ins_encode %{
10527    __ bic(as_Register($dst$$reg),
10528              as_Register($src1$$reg),
10529              as_Register($src2$$reg),
10530              Assembler::LSL,
10531              $src3$$constant & 0x3f);
10532  %}
10533
10534  ins_pipe(ialu_reg_reg_shift);
10535%}
10536
10537// This pattern is automatically generated from aarch64_ad.m4
10538// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10539instruct XorI_reg_URShift_not_reg(iRegINoSp dst,
10540                         iRegIorL2I src1, iRegIorL2I src2,
10541                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10542  match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1)));
10543  ins_cost(1.9 * INSN_COST);
10544  format %{ "eonw  $dst, $src1, $src2, LSR $src3" %}
10545
10546  ins_encode %{
10547    __ eonw(as_Register($dst$$reg),
10548              as_Register($src1$$reg),
10549              as_Register($src2$$reg),
10550              Assembler::LSR,
10551              $src3$$constant & 0x1f);
10552  %}
10553
10554  ins_pipe(ialu_reg_reg_shift);
10555%}
10556
10557// This pattern is automatically generated from aarch64_ad.m4
10558// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10559instruct XorL_reg_URShift_not_reg(iRegLNoSp dst,
10560                         iRegL src1, iRegL src2,
10561                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10562  match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1)));
10563  ins_cost(1.9 * INSN_COST);
10564  format %{ "eon  $dst, $src1, $src2, LSR $src3" %}
10565
10566  ins_encode %{
10567    __ eon(as_Register($dst$$reg),
10568              as_Register($src1$$reg),
10569              as_Register($src2$$reg),
10570              Assembler::LSR,
10571              $src3$$constant & 0x3f);
10572  %}
10573
10574  ins_pipe(ialu_reg_reg_shift);
10575%}
10576
10577// This pattern is automatically generated from aarch64_ad.m4
10578// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10579instruct XorI_reg_RShift_not_reg(iRegINoSp dst,
10580                         iRegIorL2I src1, iRegIorL2I src2,
10581                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10582  match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1)));
10583  ins_cost(1.9 * INSN_COST);
10584  format %{ "eonw  $dst, $src1, $src2, ASR $src3" %}
10585
10586  ins_encode %{
10587    __ eonw(as_Register($dst$$reg),
10588              as_Register($src1$$reg),
10589              as_Register($src2$$reg),
10590              Assembler::ASR,
10591              $src3$$constant & 0x1f);
10592  %}
10593
10594  ins_pipe(ialu_reg_reg_shift);
10595%}
10596
10597// This pattern is automatically generated from aarch64_ad.m4
10598// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10599instruct XorL_reg_RShift_not_reg(iRegLNoSp dst,
10600                         iRegL src1, iRegL src2,
10601                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10602  match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1)));
10603  ins_cost(1.9 * INSN_COST);
10604  format %{ "eon  $dst, $src1, $src2, ASR $src3" %}
10605
10606  ins_encode %{
10607    __ eon(as_Register($dst$$reg),
10608              as_Register($src1$$reg),
10609              as_Register($src2$$reg),
10610              Assembler::ASR,
10611              $src3$$constant & 0x3f);
10612  %}
10613
10614  ins_pipe(ialu_reg_reg_shift);
10615%}
10616
10617// This pattern is automatically generated from aarch64_ad.m4
10618// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10619instruct XorI_reg_LShift_not_reg(iRegINoSp dst,
10620                         iRegIorL2I src1, iRegIorL2I src2,
10621                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10622  match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1)));
10623  ins_cost(1.9 * INSN_COST);
10624  format %{ "eonw  $dst, $src1, $src2, LSL $src3" %}
10625
10626  ins_encode %{
10627    __ eonw(as_Register($dst$$reg),
10628              as_Register($src1$$reg),
10629              as_Register($src2$$reg),
10630              Assembler::LSL,
10631              $src3$$constant & 0x1f);
10632  %}
10633
10634  ins_pipe(ialu_reg_reg_shift);
10635%}
10636
10637// This pattern is automatically generated from aarch64_ad.m4
10638// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10639instruct XorL_reg_LShift_not_reg(iRegLNoSp dst,
10640                         iRegL src1, iRegL src2,
10641                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10642  match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1)));
10643  ins_cost(1.9 * INSN_COST);
10644  format %{ "eon  $dst, $src1, $src2, LSL $src3" %}
10645
10646  ins_encode %{
10647    __ eon(as_Register($dst$$reg),
10648              as_Register($src1$$reg),
10649              as_Register($src2$$reg),
10650              Assembler::LSL,
10651              $src3$$constant & 0x3f);
10652  %}
10653
10654  ins_pipe(ialu_reg_reg_shift);
10655%}
10656
10657// This pattern is automatically generated from aarch64_ad.m4
10658// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10659instruct OrI_reg_URShift_not_reg(iRegINoSp dst,
10660                         iRegIorL2I src1, iRegIorL2I src2,
10661                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10662  match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4)));
10663  ins_cost(1.9 * INSN_COST);
10664  format %{ "ornw  $dst, $src1, $src2, LSR $src3" %}
10665
10666  ins_encode %{
10667    __ ornw(as_Register($dst$$reg),
10668              as_Register($src1$$reg),
10669              as_Register($src2$$reg),
10670              Assembler::LSR,
10671              $src3$$constant & 0x1f);
10672  %}
10673
10674  ins_pipe(ialu_reg_reg_shift);
10675%}
10676
10677// This pattern is automatically generated from aarch64_ad.m4
10678// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10679instruct OrL_reg_URShift_not_reg(iRegLNoSp dst,
10680                         iRegL src1, iRegL src2,
10681                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10682  match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4)));
10683  ins_cost(1.9 * INSN_COST);
10684  format %{ "orn  $dst, $src1, $src2, LSR $src3" %}
10685
10686  ins_encode %{
10687    __ orn(as_Register($dst$$reg),
10688              as_Register($src1$$reg),
10689              as_Register($src2$$reg),
10690              Assembler::LSR,
10691              $src3$$constant & 0x3f);
10692  %}
10693
10694  ins_pipe(ialu_reg_reg_shift);
10695%}
10696
10697// This pattern is automatically generated from aarch64_ad.m4
10698// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10699instruct OrI_reg_RShift_not_reg(iRegINoSp dst,
10700                         iRegIorL2I src1, iRegIorL2I src2,
10701                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10702  match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4)));
10703  ins_cost(1.9 * INSN_COST);
10704  format %{ "ornw  $dst, $src1, $src2, ASR $src3" %}
10705
10706  ins_encode %{
10707    __ ornw(as_Register($dst$$reg),
10708              as_Register($src1$$reg),
10709              as_Register($src2$$reg),
10710              Assembler::ASR,
10711              $src3$$constant & 0x1f);
10712  %}
10713
10714  ins_pipe(ialu_reg_reg_shift);
10715%}
10716
10717// This pattern is automatically generated from aarch64_ad.m4
10718// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10719instruct OrL_reg_RShift_not_reg(iRegLNoSp dst,
10720                         iRegL src1, iRegL src2,
10721                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10722  match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4)));
10723  ins_cost(1.9 * INSN_COST);
10724  format %{ "orn  $dst, $src1, $src2, ASR $src3" %}
10725
10726  ins_encode %{
10727    __ orn(as_Register($dst$$reg),
10728              as_Register($src1$$reg),
10729              as_Register($src2$$reg),
10730              Assembler::ASR,
10731              $src3$$constant & 0x3f);
10732  %}
10733
10734  ins_pipe(ialu_reg_reg_shift);
10735%}
10736
10737// This pattern is automatically generated from aarch64_ad.m4
10738// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10739instruct OrI_reg_LShift_not_reg(iRegINoSp dst,
10740                         iRegIorL2I src1, iRegIorL2I src2,
10741                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10742  match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4)));
10743  ins_cost(1.9 * INSN_COST);
10744  format %{ "ornw  $dst, $src1, $src2, LSL $src3" %}
10745
10746  ins_encode %{
10747    __ ornw(as_Register($dst$$reg),
10748              as_Register($src1$$reg),
10749              as_Register($src2$$reg),
10750              Assembler::LSL,
10751              $src3$$constant & 0x1f);
10752  %}
10753
10754  ins_pipe(ialu_reg_reg_shift);
10755%}
10756
10757// This pattern is automatically generated from aarch64_ad.m4
10758// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10759instruct OrL_reg_LShift_not_reg(iRegLNoSp dst,
10760                         iRegL src1, iRegL src2,
10761                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10762  match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4)));
10763  ins_cost(1.9 * INSN_COST);
10764  format %{ "orn  $dst, $src1, $src2, LSL $src3" %}
10765
10766  ins_encode %{
10767    __ orn(as_Register($dst$$reg),
10768              as_Register($src1$$reg),
10769              as_Register($src2$$reg),
10770              Assembler::LSL,
10771              $src3$$constant & 0x3f);
10772  %}
10773
10774  ins_pipe(ialu_reg_reg_shift);
10775%}
10776
10777// This pattern is automatically generated from aarch64_ad.m4
10778// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10779instruct AndI_reg_URShift_reg(iRegINoSp dst,
10780                         iRegIorL2I src1, iRegIorL2I src2,
10781                         immI src3, rFlagsReg cr) %{
10782  match(Set dst (AndI src1 (URShiftI src2 src3)));
10783
10784  ins_cost(1.9 * INSN_COST);
10785  format %{ "andw  $dst, $src1, $src2, LSR $src3" %}
10786
10787  ins_encode %{
10788    __ andw(as_Register($dst$$reg),
10789              as_Register($src1$$reg),
10790              as_Register($src2$$reg),
10791              Assembler::LSR,
10792              $src3$$constant & 0x1f);
10793  %}
10794
10795  ins_pipe(ialu_reg_reg_shift);
10796%}
10797
10798// This pattern is automatically generated from aarch64_ad.m4
10799// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10800instruct AndL_reg_URShift_reg(iRegLNoSp dst,
10801                         iRegL src1, iRegL src2,
10802                         immI src3, rFlagsReg cr) %{
10803  match(Set dst (AndL src1 (URShiftL src2 src3)));
10804
10805  ins_cost(1.9 * INSN_COST);
10806  format %{ "andr  $dst, $src1, $src2, LSR $src3" %}
10807
10808  ins_encode %{
10809    __ andr(as_Register($dst$$reg),
10810              as_Register($src1$$reg),
10811              as_Register($src2$$reg),
10812              Assembler::LSR,
10813              $src3$$constant & 0x3f);
10814  %}
10815
10816  ins_pipe(ialu_reg_reg_shift);
10817%}
10818
10819// This pattern is automatically generated from aarch64_ad.m4
10820// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10821instruct AndI_reg_RShift_reg(iRegINoSp dst,
10822                         iRegIorL2I src1, iRegIorL2I src2,
10823                         immI src3, rFlagsReg cr) %{
10824  match(Set dst (AndI src1 (RShiftI src2 src3)));
10825
10826  ins_cost(1.9 * INSN_COST);
10827  format %{ "andw  $dst, $src1, $src2, ASR $src3" %}
10828
10829  ins_encode %{
10830    __ andw(as_Register($dst$$reg),
10831              as_Register($src1$$reg),
10832              as_Register($src2$$reg),
10833              Assembler::ASR,
10834              $src3$$constant & 0x1f);
10835  %}
10836
10837  ins_pipe(ialu_reg_reg_shift);
10838%}
10839
10840// This pattern is automatically generated from aarch64_ad.m4
10841// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10842instruct AndL_reg_RShift_reg(iRegLNoSp dst,
10843                         iRegL src1, iRegL src2,
10844                         immI src3, rFlagsReg cr) %{
10845  match(Set dst (AndL src1 (RShiftL src2 src3)));
10846
10847  ins_cost(1.9 * INSN_COST);
10848  format %{ "andr  $dst, $src1, $src2, ASR $src3" %}
10849
10850  ins_encode %{
10851    __ andr(as_Register($dst$$reg),
10852              as_Register($src1$$reg),
10853              as_Register($src2$$reg),
10854              Assembler::ASR,
10855              $src3$$constant & 0x3f);
10856  %}
10857
10858  ins_pipe(ialu_reg_reg_shift);
10859%}
10860
10861// This pattern is automatically generated from aarch64_ad.m4
10862// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10863instruct AndI_reg_LShift_reg(iRegINoSp dst,
10864                         iRegIorL2I src1, iRegIorL2I src2,
10865                         immI src3, rFlagsReg cr) %{
10866  match(Set dst (AndI src1 (LShiftI src2 src3)));
10867
10868  ins_cost(1.9 * INSN_COST);
10869  format %{ "andw  $dst, $src1, $src2, LSL $src3" %}
10870
10871  ins_encode %{
10872    __ andw(as_Register($dst$$reg),
10873              as_Register($src1$$reg),
10874              as_Register($src2$$reg),
10875              Assembler::LSL,
10876              $src3$$constant & 0x1f);
10877  %}
10878
10879  ins_pipe(ialu_reg_reg_shift);
10880%}
10881
10882// This pattern is automatically generated from aarch64_ad.m4
10883// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10884instruct AndL_reg_LShift_reg(iRegLNoSp dst,
10885                         iRegL src1, iRegL src2,
10886                         immI src3, rFlagsReg cr) %{
10887  match(Set dst (AndL src1 (LShiftL src2 src3)));
10888
10889  ins_cost(1.9 * INSN_COST);
10890  format %{ "andr  $dst, $src1, $src2, LSL $src3" %}
10891
10892  ins_encode %{
10893    __ andr(as_Register($dst$$reg),
10894              as_Register($src1$$reg),
10895              as_Register($src2$$reg),
10896              Assembler::LSL,
10897              $src3$$constant & 0x3f);
10898  %}
10899
10900  ins_pipe(ialu_reg_reg_shift);
10901%}
10902
10903// This pattern is automatically generated from aarch64_ad.m4
10904// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10905instruct XorI_reg_URShift_reg(iRegINoSp dst,
10906                         iRegIorL2I src1, iRegIorL2I src2,
10907                         immI src3, rFlagsReg cr) %{
10908  match(Set dst (XorI src1 (URShiftI src2 src3)));
10909
10910  ins_cost(1.9 * INSN_COST);
10911  format %{ "eorw  $dst, $src1, $src2, LSR $src3" %}
10912
10913  ins_encode %{
10914    __ eorw(as_Register($dst$$reg),
10915              as_Register($src1$$reg),
10916              as_Register($src2$$reg),
10917              Assembler::LSR,
10918              $src3$$constant & 0x1f);
10919  %}
10920
10921  ins_pipe(ialu_reg_reg_shift);
10922%}
10923
10924// This pattern is automatically generated from aarch64_ad.m4
10925// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10926instruct XorL_reg_URShift_reg(iRegLNoSp dst,
10927                         iRegL src1, iRegL src2,
10928                         immI src3, rFlagsReg cr) %{
10929  match(Set dst (XorL src1 (URShiftL src2 src3)));
10930
10931  ins_cost(1.9 * INSN_COST);
10932  format %{ "eor  $dst, $src1, $src2, LSR $src3" %}
10933
10934  ins_encode %{
10935    __ eor(as_Register($dst$$reg),
10936              as_Register($src1$$reg),
10937              as_Register($src2$$reg),
10938              Assembler::LSR,
10939              $src3$$constant & 0x3f);
10940  %}
10941
10942  ins_pipe(ialu_reg_reg_shift);
10943%}
10944
10945// This pattern is automatically generated from aarch64_ad.m4
10946// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10947instruct XorI_reg_RShift_reg(iRegINoSp dst,
10948                         iRegIorL2I src1, iRegIorL2I src2,
10949                         immI src3, rFlagsReg cr) %{
10950  match(Set dst (XorI src1 (RShiftI src2 src3)));
10951
10952  ins_cost(1.9 * INSN_COST);
10953  format %{ "eorw  $dst, $src1, $src2, ASR $src3" %}
10954
10955  ins_encode %{
10956    __ eorw(as_Register($dst$$reg),
10957              as_Register($src1$$reg),
10958              as_Register($src2$$reg),
10959              Assembler::ASR,
10960              $src3$$constant & 0x1f);
10961  %}
10962
10963  ins_pipe(ialu_reg_reg_shift);
10964%}
10965
10966// This pattern is automatically generated from aarch64_ad.m4
10967// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10968instruct XorL_reg_RShift_reg(iRegLNoSp dst,
10969                         iRegL src1, iRegL src2,
10970                         immI src3, rFlagsReg cr) %{
10971  match(Set dst (XorL src1 (RShiftL src2 src3)));
10972
10973  ins_cost(1.9 * INSN_COST);
10974  format %{ "eor  $dst, $src1, $src2, ASR $src3" %}
10975
10976  ins_encode %{
10977    __ eor(as_Register($dst$$reg),
10978              as_Register($src1$$reg),
10979              as_Register($src2$$reg),
10980              Assembler::ASR,
10981              $src3$$constant & 0x3f);
10982  %}
10983
10984  ins_pipe(ialu_reg_reg_shift);
10985%}
10986
10987// This pattern is automatically generated from aarch64_ad.m4
10988// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10989instruct XorI_reg_LShift_reg(iRegINoSp dst,
10990                         iRegIorL2I src1, iRegIorL2I src2,
10991                         immI src3, rFlagsReg cr) %{
10992  match(Set dst (XorI src1 (LShiftI src2 src3)));
10993
10994  ins_cost(1.9 * INSN_COST);
10995  format %{ "eorw  $dst, $src1, $src2, LSL $src3" %}
10996
10997  ins_encode %{
10998    __ eorw(as_Register($dst$$reg),
10999              as_Register($src1$$reg),
11000              as_Register($src2$$reg),
11001              Assembler::LSL,
11002              $src3$$constant & 0x1f);
11003  %}
11004
11005  ins_pipe(ialu_reg_reg_shift);
11006%}
11007
11008// This pattern is automatically generated from aarch64_ad.m4
11009// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11010instruct XorL_reg_LShift_reg(iRegLNoSp dst,
11011                         iRegL src1, iRegL src2,
11012                         immI src3, rFlagsReg cr) %{
11013  match(Set dst (XorL src1 (LShiftL src2 src3)));
11014
11015  ins_cost(1.9 * INSN_COST);
11016  format %{ "eor  $dst, $src1, $src2, LSL $src3" %}
11017
11018  ins_encode %{
11019    __ eor(as_Register($dst$$reg),
11020              as_Register($src1$$reg),
11021              as_Register($src2$$reg),
11022              Assembler::LSL,
11023              $src3$$constant & 0x3f);
11024  %}
11025
11026  ins_pipe(ialu_reg_reg_shift);
11027%}
11028
11029// This pattern is automatically generated from aarch64_ad.m4
11030// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11031instruct OrI_reg_URShift_reg(iRegINoSp dst,
11032                         iRegIorL2I src1, iRegIorL2I src2,
11033                         immI src3, rFlagsReg cr) %{
11034  match(Set dst (OrI src1 (URShiftI src2 src3)));
11035
11036  ins_cost(1.9 * INSN_COST);
11037  format %{ "orrw  $dst, $src1, $src2, LSR $src3" %}
11038
11039  ins_encode %{
11040    __ orrw(as_Register($dst$$reg),
11041              as_Register($src1$$reg),
11042              as_Register($src2$$reg),
11043              Assembler::LSR,
11044              $src3$$constant & 0x1f);
11045  %}
11046
11047  ins_pipe(ialu_reg_reg_shift);
11048%}
11049
11050// This pattern is automatically generated from aarch64_ad.m4
11051// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11052instruct OrL_reg_URShift_reg(iRegLNoSp dst,
11053                         iRegL src1, iRegL src2,
11054                         immI src3, rFlagsReg cr) %{
11055  match(Set dst (OrL src1 (URShiftL src2 src3)));
11056
11057  ins_cost(1.9 * INSN_COST);
11058  format %{ "orr  $dst, $src1, $src2, LSR $src3" %}
11059
11060  ins_encode %{
11061    __ orr(as_Register($dst$$reg),
11062              as_Register($src1$$reg),
11063              as_Register($src2$$reg),
11064              Assembler::LSR,
11065              $src3$$constant & 0x3f);
11066  %}
11067
11068  ins_pipe(ialu_reg_reg_shift);
11069%}
11070
11071// This pattern is automatically generated from aarch64_ad.m4
11072// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11073instruct OrI_reg_RShift_reg(iRegINoSp dst,
11074                         iRegIorL2I src1, iRegIorL2I src2,
11075                         immI src3, rFlagsReg cr) %{
11076  match(Set dst (OrI src1 (RShiftI src2 src3)));
11077
11078  ins_cost(1.9 * INSN_COST);
11079  format %{ "orrw  $dst, $src1, $src2, ASR $src3" %}
11080
11081  ins_encode %{
11082    __ orrw(as_Register($dst$$reg),
11083              as_Register($src1$$reg),
11084              as_Register($src2$$reg),
11085              Assembler::ASR,
11086              $src3$$constant & 0x1f);
11087  %}
11088
11089  ins_pipe(ialu_reg_reg_shift);
11090%}
11091
11092// This pattern is automatically generated from aarch64_ad.m4
11093// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11094instruct OrL_reg_RShift_reg(iRegLNoSp dst,
11095                         iRegL src1, iRegL src2,
11096                         immI src3, rFlagsReg cr) %{
11097  match(Set dst (OrL src1 (RShiftL src2 src3)));
11098
11099  ins_cost(1.9 * INSN_COST);
11100  format %{ "orr  $dst, $src1, $src2, ASR $src3" %}
11101
11102  ins_encode %{
11103    __ orr(as_Register($dst$$reg),
11104              as_Register($src1$$reg),
11105              as_Register($src2$$reg),
11106              Assembler::ASR,
11107              $src3$$constant & 0x3f);
11108  %}
11109
11110  ins_pipe(ialu_reg_reg_shift);
11111%}
11112
11113// This pattern is automatically generated from aarch64_ad.m4
11114// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11115instruct OrI_reg_LShift_reg(iRegINoSp dst,
11116                         iRegIorL2I src1, iRegIorL2I src2,
11117                         immI src3, rFlagsReg cr) %{
11118  match(Set dst (OrI src1 (LShiftI src2 src3)));
11119
11120  ins_cost(1.9 * INSN_COST);
11121  format %{ "orrw  $dst, $src1, $src2, LSL $src3" %}
11122
11123  ins_encode %{
11124    __ orrw(as_Register($dst$$reg),
11125              as_Register($src1$$reg),
11126              as_Register($src2$$reg),
11127              Assembler::LSL,
11128              $src3$$constant & 0x1f);
11129  %}
11130
11131  ins_pipe(ialu_reg_reg_shift);
11132%}
11133
11134// This pattern is automatically generated from aarch64_ad.m4
11135// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11136instruct OrL_reg_LShift_reg(iRegLNoSp dst,
11137                         iRegL src1, iRegL src2,
11138                         immI src3, rFlagsReg cr) %{
11139  match(Set dst (OrL src1 (LShiftL src2 src3)));
11140
11141  ins_cost(1.9 * INSN_COST);
11142  format %{ "orr  $dst, $src1, $src2, LSL $src3" %}
11143
11144  ins_encode %{
11145    __ orr(as_Register($dst$$reg),
11146              as_Register($src1$$reg),
11147              as_Register($src2$$reg),
11148              Assembler::LSL,
11149              $src3$$constant & 0x3f);
11150  %}
11151
11152  ins_pipe(ialu_reg_reg_shift);
11153%}
11154
11155// This pattern is automatically generated from aarch64_ad.m4
11156// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11157instruct AddI_reg_URShift_reg(iRegINoSp dst,
11158                         iRegIorL2I src1, iRegIorL2I src2,
11159                         immI src3, rFlagsReg cr) %{
11160  match(Set dst (AddI src1 (URShiftI src2 src3)));
11161
11162  ins_cost(1.9 * INSN_COST);
11163  format %{ "addw  $dst, $src1, $src2, LSR $src3" %}
11164
11165  ins_encode %{
11166    __ addw(as_Register($dst$$reg),
11167              as_Register($src1$$reg),
11168              as_Register($src2$$reg),
11169              Assembler::LSR,
11170              $src3$$constant & 0x1f);
11171  %}
11172
11173  ins_pipe(ialu_reg_reg_shift);
11174%}
11175
11176// This pattern is automatically generated from aarch64_ad.m4
11177// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11178instruct AddL_reg_URShift_reg(iRegLNoSp dst,
11179                         iRegL src1, iRegL src2,
11180                         immI src3, rFlagsReg cr) %{
11181  match(Set dst (AddL src1 (URShiftL src2 src3)));
11182
11183  ins_cost(1.9 * INSN_COST);
11184  format %{ "add  $dst, $src1, $src2, LSR $src3" %}
11185
11186  ins_encode %{
11187    __ add(as_Register($dst$$reg),
11188              as_Register($src1$$reg),
11189              as_Register($src2$$reg),
11190              Assembler::LSR,
11191              $src3$$constant & 0x3f);
11192  %}
11193
11194  ins_pipe(ialu_reg_reg_shift);
11195%}
11196
11197// This pattern is automatically generated from aarch64_ad.m4
11198// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11199instruct AddI_reg_RShift_reg(iRegINoSp dst,
11200                         iRegIorL2I src1, iRegIorL2I src2,
11201                         immI src3, rFlagsReg cr) %{
11202  match(Set dst (AddI src1 (RShiftI src2 src3)));
11203
11204  ins_cost(1.9 * INSN_COST);
11205  format %{ "addw  $dst, $src1, $src2, ASR $src3" %}
11206
11207  ins_encode %{
11208    __ addw(as_Register($dst$$reg),
11209              as_Register($src1$$reg),
11210              as_Register($src2$$reg),
11211              Assembler::ASR,
11212              $src3$$constant & 0x1f);
11213  %}
11214
11215  ins_pipe(ialu_reg_reg_shift);
11216%}
11217
11218// This pattern is automatically generated from aarch64_ad.m4
11219// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11220instruct AddL_reg_RShift_reg(iRegLNoSp dst,
11221                         iRegL src1, iRegL src2,
11222                         immI src3, rFlagsReg cr) %{
11223  match(Set dst (AddL src1 (RShiftL src2 src3)));
11224
11225  ins_cost(1.9 * INSN_COST);
11226  format %{ "add  $dst, $src1, $src2, ASR $src3" %}
11227
11228  ins_encode %{
11229    __ add(as_Register($dst$$reg),
11230              as_Register($src1$$reg),
11231              as_Register($src2$$reg),
11232              Assembler::ASR,
11233              $src3$$constant & 0x3f);
11234  %}
11235
11236  ins_pipe(ialu_reg_reg_shift);
11237%}
11238
11239// This pattern is automatically generated from aarch64_ad.m4
11240// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11241instruct AddI_reg_LShift_reg(iRegINoSp dst,
11242                         iRegIorL2I src1, iRegIorL2I src2,
11243                         immI src3, rFlagsReg cr) %{
11244  match(Set dst (AddI src1 (LShiftI src2 src3)));
11245
11246  ins_cost(1.9 * INSN_COST);
11247  format %{ "addw  $dst, $src1, $src2, LSL $src3" %}
11248
11249  ins_encode %{
11250    __ addw(as_Register($dst$$reg),
11251              as_Register($src1$$reg),
11252              as_Register($src2$$reg),
11253              Assembler::LSL,
11254              $src3$$constant & 0x1f);
11255  %}
11256
11257  ins_pipe(ialu_reg_reg_shift);
11258%}
11259
11260// This pattern is automatically generated from aarch64_ad.m4
11261// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11262instruct AddL_reg_LShift_reg(iRegLNoSp dst,
11263                         iRegL src1, iRegL src2,
11264                         immI src3, rFlagsReg cr) %{
11265  match(Set dst (AddL src1 (LShiftL src2 src3)));
11266
11267  ins_cost(1.9 * INSN_COST);
11268  format %{ "add  $dst, $src1, $src2, LSL $src3" %}
11269
11270  ins_encode %{
11271    __ add(as_Register($dst$$reg),
11272              as_Register($src1$$reg),
11273              as_Register($src2$$reg),
11274              Assembler::LSL,
11275              $src3$$constant & 0x3f);
11276  %}
11277
11278  ins_pipe(ialu_reg_reg_shift);
11279%}
11280
11281// This pattern is automatically generated from aarch64_ad.m4
11282// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11283instruct SubI_reg_URShift_reg(iRegINoSp dst,
11284                         iRegIorL2I src1, iRegIorL2I src2,
11285                         immI src3, rFlagsReg cr) %{
11286  match(Set dst (SubI src1 (URShiftI src2 src3)));
11287
11288  ins_cost(1.9 * INSN_COST);
11289  format %{ "subw  $dst, $src1, $src2, LSR $src3" %}
11290
11291  ins_encode %{
11292    __ subw(as_Register($dst$$reg),
11293              as_Register($src1$$reg),
11294              as_Register($src2$$reg),
11295              Assembler::LSR,
11296              $src3$$constant & 0x1f);
11297  %}
11298
11299  ins_pipe(ialu_reg_reg_shift);
11300%}
11301
11302// This pattern is automatically generated from aarch64_ad.m4
11303// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11304instruct SubL_reg_URShift_reg(iRegLNoSp dst,
11305                         iRegL src1, iRegL src2,
11306                         immI src3, rFlagsReg cr) %{
11307  match(Set dst (SubL src1 (URShiftL src2 src3)));
11308
11309  ins_cost(1.9 * INSN_COST);
11310  format %{ "sub  $dst, $src1, $src2, LSR $src3" %}
11311
11312  ins_encode %{
11313    __ sub(as_Register($dst$$reg),
11314              as_Register($src1$$reg),
11315              as_Register($src2$$reg),
11316              Assembler::LSR,
11317              $src3$$constant & 0x3f);
11318  %}
11319
11320  ins_pipe(ialu_reg_reg_shift);
11321%}
11322
11323// This pattern is automatically generated from aarch64_ad.m4
11324// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11325instruct SubI_reg_RShift_reg(iRegINoSp dst,
11326                         iRegIorL2I src1, iRegIorL2I src2,
11327                         immI src3, rFlagsReg cr) %{
11328  match(Set dst (SubI src1 (RShiftI src2 src3)));
11329
11330  ins_cost(1.9 * INSN_COST);
11331  format %{ "subw  $dst, $src1, $src2, ASR $src3" %}
11332
11333  ins_encode %{
11334    __ subw(as_Register($dst$$reg),
11335              as_Register($src1$$reg),
11336              as_Register($src2$$reg),
11337              Assembler::ASR,
11338              $src3$$constant & 0x1f);
11339  %}
11340
11341  ins_pipe(ialu_reg_reg_shift);
11342%}
11343
11344// This pattern is automatically generated from aarch64_ad.m4
11345// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11346instruct SubL_reg_RShift_reg(iRegLNoSp dst,
11347                         iRegL src1, iRegL src2,
11348                         immI src3, rFlagsReg cr) %{
11349  match(Set dst (SubL src1 (RShiftL src2 src3)));
11350
11351  ins_cost(1.9 * INSN_COST);
11352  format %{ "sub  $dst, $src1, $src2, ASR $src3" %}
11353
11354  ins_encode %{
11355    __ sub(as_Register($dst$$reg),
11356              as_Register($src1$$reg),
11357              as_Register($src2$$reg),
11358              Assembler::ASR,
11359              $src3$$constant & 0x3f);
11360  %}
11361
11362  ins_pipe(ialu_reg_reg_shift);
11363%}
11364
11365// This pattern is automatically generated from aarch64_ad.m4
11366// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11367instruct SubI_reg_LShift_reg(iRegINoSp dst,
11368                         iRegIorL2I src1, iRegIorL2I src2,
11369                         immI src3, rFlagsReg cr) %{
11370  match(Set dst (SubI src1 (LShiftI src2 src3)));
11371
11372  ins_cost(1.9 * INSN_COST);
11373  format %{ "subw  $dst, $src1, $src2, LSL $src3" %}
11374
11375  ins_encode %{
11376    __ subw(as_Register($dst$$reg),
11377              as_Register($src1$$reg),
11378              as_Register($src2$$reg),
11379              Assembler::LSL,
11380              $src3$$constant & 0x1f);
11381  %}
11382
11383  ins_pipe(ialu_reg_reg_shift);
11384%}
11385
11386// This pattern is automatically generated from aarch64_ad.m4
11387// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11388instruct SubL_reg_LShift_reg(iRegLNoSp dst,
11389                         iRegL src1, iRegL src2,
11390                         immI src3, rFlagsReg cr) %{
11391  match(Set dst (SubL src1 (LShiftL src2 src3)));
11392
11393  ins_cost(1.9 * INSN_COST);
11394  format %{ "sub  $dst, $src1, $src2, LSL $src3" %}
11395
11396  ins_encode %{
11397    __ sub(as_Register($dst$$reg),
11398              as_Register($src1$$reg),
11399              as_Register($src2$$reg),
11400              Assembler::LSL,
11401              $src3$$constant & 0x3f);
11402  %}
11403
11404  ins_pipe(ialu_reg_reg_shift);
11405%}
11406
11407
11408// This pattern is automatically generated from aarch64_ad.m4
11409// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11410
11411// Shift Left followed by Shift Right.
11412// This idiom is used by the compiler for the i2b bytecode etc.
11413instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
11414%{
11415  match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count));
11416  ins_cost(INSN_COST * 2);
11417  format %{ "sbfm  $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
11418  ins_encode %{
11419    int lshift = $lshift_count$$constant & 63;
11420    int rshift = $rshift_count$$constant & 63;
11421    int s = 63 - lshift;
11422    int r = (rshift - lshift) & 63;
11423    __ sbfm(as_Register($dst$$reg),
11424            as_Register($src$$reg),
11425            r, s);
11426  %}
11427
11428  ins_pipe(ialu_reg_shift);
11429%}
11430
11431// This pattern is automatically generated from aarch64_ad.m4
11432// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11433
11434// Shift Left followed by Shift Right.
11435// This idiom is used by the compiler for the i2b bytecode etc.
11436instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
11437%{
11438  match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count));
11439  ins_cost(INSN_COST * 2);
11440  format %{ "sbfmw  $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
11441  ins_encode %{
11442    int lshift = $lshift_count$$constant & 31;
11443    int rshift = $rshift_count$$constant & 31;
11444    int s = 31 - lshift;
11445    int r = (rshift - lshift) & 31;
11446    __ sbfmw(as_Register($dst$$reg),
11447            as_Register($src$$reg),
11448            r, s);
11449  %}
11450
11451  ins_pipe(ialu_reg_shift);
11452%}
11453
11454// This pattern is automatically generated from aarch64_ad.m4
11455// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11456
11457// Shift Left followed by Shift Right.
11458// This idiom is used by the compiler for the i2b bytecode etc.
11459instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
11460%{
11461  match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count));
11462  ins_cost(INSN_COST * 2);
11463  format %{ "ubfm  $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
11464  ins_encode %{
11465    int lshift = $lshift_count$$constant & 63;
11466    int rshift = $rshift_count$$constant & 63;
11467    int s = 63 - lshift;
11468    int r = (rshift - lshift) & 63;
11469    __ ubfm(as_Register($dst$$reg),
11470            as_Register($src$$reg),
11471            r, s);
11472  %}
11473
11474  ins_pipe(ialu_reg_shift);
11475%}
11476
11477// This pattern is automatically generated from aarch64_ad.m4
11478// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11479
11480// Shift Left followed by Shift Right.
11481// This idiom is used by the compiler for the i2b bytecode etc.
11482instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
11483%{
11484  match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count));
11485  ins_cost(INSN_COST * 2);
11486  format %{ "ubfmw  $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
11487  ins_encode %{
11488    int lshift = $lshift_count$$constant & 31;
11489    int rshift = $rshift_count$$constant & 31;
11490    int s = 31 - lshift;
11491    int r = (rshift - lshift) & 31;
11492    __ ubfmw(as_Register($dst$$reg),
11493            as_Register($src$$reg),
11494            r, s);
11495  %}
11496
11497  ins_pipe(ialu_reg_shift);
11498%}
11499
11500// Bitfield extract with shift & mask
11501
11502// This pattern is automatically generated from aarch64_ad.m4
11503// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11504instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
11505%{
11506  match(Set dst (AndI (URShiftI src rshift) mask));
11507  // Make sure we are not going to exceed what ubfxw can do.
11508  predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
11509
11510  ins_cost(INSN_COST);
11511  format %{ "ubfxw $dst, $src, $rshift, $mask" %}
11512  ins_encode %{
11513    int rshift = $rshift$$constant & 31;
11514    intptr_t mask = $mask$$constant;
11515    int width = exact_log2(mask+1);
11516    __ ubfxw(as_Register($dst$$reg),
11517            as_Register($src$$reg), rshift, width);
11518  %}
11519  ins_pipe(ialu_reg_shift);
11520%}
11521
11522// This pattern is automatically generated from aarch64_ad.m4
11523// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11524instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask)
11525%{
11526  match(Set dst (AndL (URShiftL src rshift) mask));
11527  // Make sure we are not going to exceed what ubfx can do.
11528  predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1));
11529
11530  ins_cost(INSN_COST);
11531  format %{ "ubfx $dst, $src, $rshift, $mask" %}
11532  ins_encode %{
11533    int rshift = $rshift$$constant & 63;
11534    intptr_t mask = $mask$$constant;
11535    int width = exact_log2_long(mask+1);
11536    __ ubfx(as_Register($dst$$reg),
11537            as_Register($src$$reg), rshift, width);
11538  %}
11539  ins_pipe(ialu_reg_shift);
11540%}
11541
11542
11543// This pattern is automatically generated from aarch64_ad.m4
11544// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11545
11546// We can use ubfx when extending an And with a mask when we know mask
11547// is positive.  We know that because immI_bitmask guarantees it.
11548instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
11549%{
11550  match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
11551  // Make sure we are not going to exceed what ubfxw can do.
11552  predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
11553
11554  ins_cost(INSN_COST * 2);
11555  format %{ "ubfx $dst, $src, $rshift, $mask" %}
11556  ins_encode %{
11557    int rshift = $rshift$$constant & 31;
11558    intptr_t mask = $mask$$constant;
11559    int width = exact_log2(mask+1);
11560    __ ubfx(as_Register($dst$$reg),
11561            as_Register($src$$reg), rshift, width);
11562  %}
11563  ins_pipe(ialu_reg_shift);
11564%}
11565
11566
11567// This pattern is automatically generated from aarch64_ad.m4
11568// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11569
11570// We can use ubfiz when masking by a positive number and then left shifting the result.
11571// We know that the mask is positive because immI_bitmask guarantees it.
11572instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
11573%{
11574  match(Set dst (LShiftI (AndI src mask) lshift));
11575  predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1));
11576
11577  ins_cost(INSN_COST);
11578  format %{ "ubfizw $dst, $src, $lshift, $mask" %}
11579  ins_encode %{
11580    int lshift = $lshift$$constant & 31;
11581    intptr_t mask = $mask$$constant;
11582    int width = exact_log2(mask+1);
11583    __ ubfizw(as_Register($dst$$reg),
11584          as_Register($src$$reg), lshift, width);
11585  %}
11586  ins_pipe(ialu_reg_shift);
11587%}
11588
11589// This pattern is automatically generated from aarch64_ad.m4
11590// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11591
11592// We can use ubfiz when masking by a positive number and then left shifting the result.
11593// We know that the mask is positive because immL_bitmask guarantees it.
11594instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask)
11595%{
11596  match(Set dst (LShiftL (AndL src mask) lshift));
11597  predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
11598
11599  ins_cost(INSN_COST);
11600  format %{ "ubfiz $dst, $src, $lshift, $mask" %}
11601  ins_encode %{
11602    int lshift = $lshift$$constant & 63;
11603    intptr_t mask = $mask$$constant;
11604    int width = exact_log2_long(mask+1);
11605    __ ubfiz(as_Register($dst$$reg),
11606          as_Register($src$$reg), lshift, width);
11607  %}
11608  ins_pipe(ialu_reg_shift);
11609%}
11610
11611// This pattern is automatically generated from aarch64_ad.m4
11612// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11613
11614// We can use ubfiz when masking by a positive number and then left shifting the result.
11615// We know that the mask is positive because immI_bitmask guarantees it.
11616instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
11617%{
11618  match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift)));
11619  predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31);
11620
11621  ins_cost(INSN_COST);
11622  format %{ "ubfizw $dst, $src, $lshift, $mask" %}
11623  ins_encode %{
11624    int lshift = $lshift$$constant & 31;
11625    intptr_t mask = $mask$$constant;
11626    int width = exact_log2(mask+1);
11627    __ ubfizw(as_Register($dst$$reg),
11628          as_Register($src$$reg), lshift, width);
11629  %}
11630  ins_pipe(ialu_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
11636// We can use ubfiz when masking by a positive number and then left shifting the result.
11637// We know that the mask is positive because immL_bitmask guarantees it.
11638instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask)
11639%{
11640  match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift)));
11641  predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31);
11642
11643  ins_cost(INSN_COST);
11644  format %{ "ubfiz $dst, $src, $lshift, $mask" %}
11645  ins_encode %{
11646    int lshift = $lshift$$constant & 63;
11647    intptr_t mask = $mask$$constant;
11648    int width = exact_log2_long(mask+1);
11649    __ ubfiz(as_Register($dst$$reg),
11650          as_Register($src$$reg), lshift, width);
11651  %}
11652  ins_pipe(ialu_reg_shift);
11653%}
11654
11655
11656// This pattern is automatically generated from aarch64_ad.m4
11657// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11658
11659// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
11660instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
11661%{
11662  match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift));
11663  predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
11664
11665  ins_cost(INSN_COST);
11666  format %{ "ubfiz $dst, $src, $lshift, $mask" %}
11667  ins_encode %{
11668    int lshift = $lshift$$constant & 63;
11669    intptr_t mask = $mask$$constant;
11670    int width = exact_log2(mask+1);
11671    __ ubfiz(as_Register($dst$$reg),
11672             as_Register($src$$reg), lshift, width);
11673  %}
11674  ins_pipe(ialu_reg_shift);
11675%}
11676
11677// This pattern is automatically generated from aarch64_ad.m4
11678// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11679
11680// If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz
11681instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask)
11682%{
11683  match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift));
11684  predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31);
11685
11686  ins_cost(INSN_COST);
11687  format %{ "ubfiz $dst, $src, $lshift, $mask" %}
11688  ins_encode %{
11689    int lshift = $lshift$$constant & 31;
11690    intptr_t mask = $mask$$constant;
11691    int width = exact_log2(mask+1);
11692    __ ubfiz(as_Register($dst$$reg),
11693             as_Register($src$$reg), lshift, width);
11694  %}
11695  ins_pipe(ialu_reg_shift);
11696%}
11697
11698// Can skip int2long conversions after AND with small bitmask
11699instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk)
11700%{
11701  match(Set dst (ConvI2L (AndI src msk)));
11702  ins_cost(INSN_COST);
11703  format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %}
11704  ins_encode %{
11705    __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1));
11706  %}
11707  ins_pipe(ialu_reg_shift);
11708%}
11709
11710
11711// Rotations
11712// This pattern is automatically generated from aarch64_ad.m4
11713// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11714instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
11715%{
11716  match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift)));
11717  predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63));
11718
11719  ins_cost(INSN_COST);
11720  format %{ "extr $dst, $src1, $src2, #$rshift" %}
11721
11722  ins_encode %{
11723    __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
11724            $rshift$$constant & 63);
11725  %}
11726  ins_pipe(ialu_reg_reg_extr);
11727%}
11728
11729
11730// This pattern is automatically generated from aarch64_ad.m4
11731// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11732instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
11733%{
11734  match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift)));
11735  predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31));
11736
11737  ins_cost(INSN_COST);
11738  format %{ "extr $dst, $src1, $src2, #$rshift" %}
11739
11740  ins_encode %{
11741    __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
11742            $rshift$$constant & 31);
11743  %}
11744  ins_pipe(ialu_reg_reg_extr);
11745%}
11746
11747
11748// This pattern is automatically generated from aarch64_ad.m4
11749// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11750instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
11751%{
11752  match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift)));
11753  predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63));
11754
11755  ins_cost(INSN_COST);
11756  format %{ "extr $dst, $src1, $src2, #$rshift" %}
11757
11758  ins_encode %{
11759    __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
11760            $rshift$$constant & 63);
11761  %}
11762  ins_pipe(ialu_reg_reg_extr);
11763%}
11764
11765
11766// This pattern is automatically generated from aarch64_ad.m4
11767// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11768instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
11769%{
11770  match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift)));
11771  predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31));
11772
11773  ins_cost(INSN_COST);
11774  format %{ "extr $dst, $src1, $src2, #$rshift" %}
11775
11776  ins_encode %{
11777    __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
11778            $rshift$$constant & 31);
11779  %}
11780  ins_pipe(ialu_reg_reg_extr);
11781%}
11782
11783
11784// This pattern is automatically generated from aarch64_ad.m4
11785// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11786
11787// rol expander
11788instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr)
11789%{
11790  effect(DEF dst, USE src, USE shift);
11791
11792  format %{ "rol    $dst, $src, $shift" %}
11793  ins_cost(INSN_COST * 3);
11794  ins_encode %{
11795    __ subw(rscratch1, zr, as_Register($shift$$reg));
11796    __ rorv(as_Register($dst$$reg), as_Register($src$$reg),
11797            rscratch1);
11798    %}
11799  ins_pipe(ialu_reg_reg_vshift);
11800%}
11801
11802// This pattern is automatically generated from aarch64_ad.m4
11803// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11804
11805// rol expander
11806instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr)
11807%{
11808  effect(DEF dst, USE src, USE shift);
11809
11810  format %{ "rol    $dst, $src, $shift" %}
11811  ins_cost(INSN_COST * 3);
11812  ins_encode %{
11813    __ subw(rscratch1, zr, as_Register($shift$$reg));
11814    __ rorvw(as_Register($dst$$reg), as_Register($src$$reg),
11815            rscratch1);
11816    %}
11817  ins_pipe(ialu_reg_reg_vshift);
11818%}
11819
11820// This pattern is automatically generated from aarch64_ad.m4
11821// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11822instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr)
11823%{
11824  match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift))));
11825
11826  expand %{
11827    rolL_rReg(dst, src, shift, cr);
11828  %}
11829%}
11830
11831// This pattern is automatically generated from aarch64_ad.m4
11832// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11833instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr)
11834%{
11835  match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift))));
11836
11837  expand %{
11838    rolL_rReg(dst, src, shift, cr);
11839  %}
11840%}
11841
11842// This pattern is automatically generated from aarch64_ad.m4
11843// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11844instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr)
11845%{
11846  match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift))));
11847
11848  expand %{
11849    rolI_rReg(dst, src, shift, cr);
11850  %}
11851%}
11852
11853// This pattern is automatically generated from aarch64_ad.m4
11854// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11855instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr)
11856%{
11857  match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift))));
11858
11859  expand %{
11860    rolI_rReg(dst, src, shift, cr);
11861  %}
11862%}
11863
11864// This pattern is automatically generated from aarch64_ad.m4
11865// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11866
11867// ror expander
11868instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr)
11869%{
11870  effect(DEF dst, USE src, USE shift);
11871
11872  format %{ "ror    $dst, $src, $shift" %}
11873  ins_cost(INSN_COST);
11874  ins_encode %{
11875    __ rorv(as_Register($dst$$reg), as_Register($src$$reg),
11876            as_Register($shift$$reg));
11877    %}
11878  ins_pipe(ialu_reg_reg_vshift);
11879%}
11880
11881// This pattern is automatically generated from aarch64_ad.m4
11882// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11883
11884// ror expander
11885instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr)
11886%{
11887  effect(DEF dst, USE src, USE shift);
11888
11889  format %{ "ror    $dst, $src, $shift" %}
11890  ins_cost(INSN_COST);
11891  ins_encode %{
11892    __ rorvw(as_Register($dst$$reg), as_Register($src$$reg),
11893            as_Register($shift$$reg));
11894    %}
11895  ins_pipe(ialu_reg_reg_vshift);
11896%}
11897
11898// This pattern is automatically generated from aarch64_ad.m4
11899// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11900instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr)
11901%{
11902  match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift))));
11903
11904  expand %{
11905    rorL_rReg(dst, src, shift, cr);
11906  %}
11907%}
11908
11909// This pattern is automatically generated from aarch64_ad.m4
11910// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11911instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr)
11912%{
11913  match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift))));
11914
11915  expand %{
11916    rorL_rReg(dst, src, shift, cr);
11917  %}
11918%}
11919
11920// This pattern is automatically generated from aarch64_ad.m4
11921// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11922instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr)
11923%{
11924  match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift))));
11925
11926  expand %{
11927    rorI_rReg(dst, src, shift, cr);
11928  %}
11929%}
11930
11931// This pattern is automatically generated from aarch64_ad.m4
11932// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11933instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr)
11934%{
11935  match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift))));
11936
11937  expand %{
11938    rorI_rReg(dst, src, shift, cr);
11939  %}
11940%}
11941
11942
11943// Add/subtract (extended)
11944
11945// This pattern is automatically generated from aarch64_ad.m4
11946// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11947instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
11948%{
11949  match(Set dst (AddL src1 (ConvI2L src2)));
11950  ins_cost(INSN_COST);
11951  format %{ "add  $dst, $src1, $src2, sxtw" %}
11952
11953   ins_encode %{
11954     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11955            as_Register($src2$$reg), ext::sxtw);
11956   %}
11957  ins_pipe(ialu_reg_reg);
11958%}
11959
11960// This pattern is automatically generated from aarch64_ad.m4
11961// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11962instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
11963%{
11964  match(Set dst (SubL src1 (ConvI2L src2)));
11965  ins_cost(INSN_COST);
11966  format %{ "sub  $dst, $src1, $src2, sxtw" %}
11967
11968   ins_encode %{
11969     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
11970            as_Register($src2$$reg), ext::sxtw);
11971   %}
11972  ins_pipe(ialu_reg_reg);
11973%}
11974
11975// This pattern is automatically generated from aarch64_ad.m4
11976// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11977instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr)
11978%{
11979  match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
11980  ins_cost(INSN_COST);
11981  format %{ "add  $dst, $src1, $src2, sxth" %}
11982
11983   ins_encode %{
11984     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11985            as_Register($src2$$reg), ext::sxth);
11986   %}
11987  ins_pipe(ialu_reg_reg);
11988%}
11989
11990// This pattern is automatically generated from aarch64_ad.m4
11991// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11992instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
11993%{
11994  match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
11995  ins_cost(INSN_COST);
11996  format %{ "add  $dst, $src1, $src2, sxtb" %}
11997
11998   ins_encode %{
11999     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12000            as_Register($src2$$reg), ext::sxtb);
12001   %}
12002  ins_pipe(ialu_reg_reg);
12003%}
12004
12005// This pattern is automatically generated from aarch64_ad.m4
12006// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12007instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
12008%{
12009  match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift)));
12010  ins_cost(INSN_COST);
12011  format %{ "add  $dst, $src1, $src2, uxtb" %}
12012
12013   ins_encode %{
12014     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12015            as_Register($src2$$reg), ext::uxtb);
12016   %}
12017  ins_pipe(ialu_reg_reg);
12018%}
12019
12020// This pattern is automatically generated from aarch64_ad.m4
12021// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12022instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr)
12023%{
12024  match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
12025  ins_cost(INSN_COST);
12026  format %{ "add  $dst, $src1, $src2, sxth" %}
12027
12028   ins_encode %{
12029     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12030            as_Register($src2$$reg), ext::sxth);
12031   %}
12032  ins_pipe(ialu_reg_reg);
12033%}
12034
12035// This pattern is automatically generated from aarch64_ad.m4
12036// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12037instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr)
12038%{
12039  match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
12040  ins_cost(INSN_COST);
12041  format %{ "add  $dst, $src1, $src2, sxtw" %}
12042
12043   ins_encode %{
12044     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12045            as_Register($src2$$reg), ext::sxtw);
12046   %}
12047  ins_pipe(ialu_reg_reg);
12048%}
12049
12050// This pattern is automatically generated from aarch64_ad.m4
12051// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12052instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
12053%{
12054  match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
12055  ins_cost(INSN_COST);
12056  format %{ "add  $dst, $src1, $src2, sxtb" %}
12057
12058   ins_encode %{
12059     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12060            as_Register($src2$$reg), ext::sxtb);
12061   %}
12062  ins_pipe(ialu_reg_reg);
12063%}
12064
12065// This pattern is automatically generated from aarch64_ad.m4
12066// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12067instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
12068%{
12069  match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift)));
12070  ins_cost(INSN_COST);
12071  format %{ "add  $dst, $src1, $src2, uxtb" %}
12072
12073   ins_encode %{
12074     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12075            as_Register($src2$$reg), ext::uxtb);
12076   %}
12077  ins_pipe(ialu_reg_reg);
12078%}
12079
12080// This pattern is automatically generated from aarch64_ad.m4
12081// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12082instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
12083%{
12084  match(Set dst (AddI src1 (AndI src2 mask)));
12085  ins_cost(INSN_COST);
12086  format %{ "addw  $dst, $src1, $src2, uxtb" %}
12087
12088   ins_encode %{
12089     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12090            as_Register($src2$$reg), ext::uxtb);
12091   %}
12092  ins_pipe(ialu_reg_reg);
12093%}
12094
12095// This pattern is automatically generated from aarch64_ad.m4
12096// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12097instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
12098%{
12099  match(Set dst (AddI src1 (AndI src2 mask)));
12100  ins_cost(INSN_COST);
12101  format %{ "addw  $dst, $src1, $src2, uxth" %}
12102
12103   ins_encode %{
12104     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12105            as_Register($src2$$reg), ext::uxth);
12106   %}
12107  ins_pipe(ialu_reg_reg);
12108%}
12109
12110// This pattern is automatically generated from aarch64_ad.m4
12111// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12112instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
12113%{
12114  match(Set dst (AddL src1 (AndL src2 mask)));
12115  ins_cost(INSN_COST);
12116  format %{ "add  $dst, $src1, $src2, uxtb" %}
12117
12118   ins_encode %{
12119     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12120            as_Register($src2$$reg), ext::uxtb);
12121   %}
12122  ins_pipe(ialu_reg_reg);
12123%}
12124
12125// This pattern is automatically generated from aarch64_ad.m4
12126// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12127instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
12128%{
12129  match(Set dst (AddL src1 (AndL src2 mask)));
12130  ins_cost(INSN_COST);
12131  format %{ "add  $dst, $src1, $src2, uxth" %}
12132
12133   ins_encode %{
12134     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12135            as_Register($src2$$reg), ext::uxth);
12136   %}
12137  ins_pipe(ialu_reg_reg);
12138%}
12139
12140// This pattern is automatically generated from aarch64_ad.m4
12141// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12142instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
12143%{
12144  match(Set dst (AddL src1 (AndL src2 mask)));
12145  ins_cost(INSN_COST);
12146  format %{ "add  $dst, $src1, $src2, uxtw" %}
12147
12148   ins_encode %{
12149     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12150            as_Register($src2$$reg), ext::uxtw);
12151   %}
12152  ins_pipe(ialu_reg_reg);
12153%}
12154
12155// This pattern is automatically generated from aarch64_ad.m4
12156// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12157instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
12158%{
12159  match(Set dst (SubI src1 (AndI src2 mask)));
12160  ins_cost(INSN_COST);
12161  format %{ "subw  $dst, $src1, $src2, uxtb" %}
12162
12163   ins_encode %{
12164     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12165            as_Register($src2$$reg), ext::uxtb);
12166   %}
12167  ins_pipe(ialu_reg_reg);
12168%}
12169
12170// This pattern is automatically generated from aarch64_ad.m4
12171// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12172instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
12173%{
12174  match(Set dst (SubI src1 (AndI src2 mask)));
12175  ins_cost(INSN_COST);
12176  format %{ "subw  $dst, $src1, $src2, uxth" %}
12177
12178   ins_encode %{
12179     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12180            as_Register($src2$$reg), ext::uxth);
12181   %}
12182  ins_pipe(ialu_reg_reg);
12183%}
12184
12185// This pattern is automatically generated from aarch64_ad.m4
12186// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12187instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
12188%{
12189  match(Set dst (SubL src1 (AndL src2 mask)));
12190  ins_cost(INSN_COST);
12191  format %{ "sub  $dst, $src1, $src2, uxtb" %}
12192
12193   ins_encode %{
12194     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12195            as_Register($src2$$reg), ext::uxtb);
12196   %}
12197  ins_pipe(ialu_reg_reg);
12198%}
12199
12200// This pattern is automatically generated from aarch64_ad.m4
12201// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12202instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
12203%{
12204  match(Set dst (SubL src1 (AndL src2 mask)));
12205  ins_cost(INSN_COST);
12206  format %{ "sub  $dst, $src1, $src2, uxth" %}
12207
12208   ins_encode %{
12209     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12210            as_Register($src2$$reg), ext::uxth);
12211   %}
12212  ins_pipe(ialu_reg_reg);
12213%}
12214
12215// This pattern is automatically generated from aarch64_ad.m4
12216// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12217instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
12218%{
12219  match(Set dst (SubL src1 (AndL src2 mask)));
12220  ins_cost(INSN_COST);
12221  format %{ "sub  $dst, $src1, $src2, uxtw" %}
12222
12223   ins_encode %{
12224     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12225            as_Register($src2$$reg), ext::uxtw);
12226   %}
12227  ins_pipe(ialu_reg_reg);
12228%}
12229
12230
12231// This pattern is automatically generated from aarch64_ad.m4
12232// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12233instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
12234%{
12235  match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12236  ins_cost(1.9 * INSN_COST);
12237  format %{ "add  $dst, $src1, $src2, sxtb #lshift2" %}
12238
12239   ins_encode %{
12240     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12241            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
12242   %}
12243  ins_pipe(ialu_reg_reg_shift);
12244%}
12245
12246// This pattern is automatically generated from aarch64_ad.m4
12247// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12248instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
12249%{
12250  match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12251  ins_cost(1.9 * INSN_COST);
12252  format %{ "add  $dst, $src1, $src2, sxth #lshift2" %}
12253
12254   ins_encode %{
12255     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12256            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
12257   %}
12258  ins_pipe(ialu_reg_reg_shift);
12259%}
12260
12261// This pattern is automatically generated from aarch64_ad.m4
12262// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12263instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
12264%{
12265  match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12266  ins_cost(1.9 * INSN_COST);
12267  format %{ "add  $dst, $src1, $src2, sxtw #lshift2" %}
12268
12269   ins_encode %{
12270     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12271            as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
12272   %}
12273  ins_pipe(ialu_reg_reg_shift);
12274%}
12275
12276// This pattern is automatically generated from aarch64_ad.m4
12277// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12278instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
12279%{
12280  match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12281  ins_cost(1.9 * INSN_COST);
12282  format %{ "sub  $dst, $src1, $src2, sxtb #lshift2" %}
12283
12284   ins_encode %{
12285     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12286            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
12287   %}
12288  ins_pipe(ialu_reg_reg_shift);
12289%}
12290
12291// This pattern is automatically generated from aarch64_ad.m4
12292// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12293instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
12294%{
12295  match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12296  ins_cost(1.9 * INSN_COST);
12297  format %{ "sub  $dst, $src1, $src2, sxth #lshift2" %}
12298
12299   ins_encode %{
12300     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12301            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
12302   %}
12303  ins_pipe(ialu_reg_reg_shift);
12304%}
12305
12306// This pattern is automatically generated from aarch64_ad.m4
12307// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12308instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
12309%{
12310  match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12311  ins_cost(1.9 * INSN_COST);
12312  format %{ "sub  $dst, $src1, $src2, sxtw #lshift2" %}
12313
12314   ins_encode %{
12315     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12316            as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
12317   %}
12318  ins_pipe(ialu_reg_reg_shift);
12319%}
12320
12321// This pattern is automatically generated from aarch64_ad.m4
12322// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12323instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
12324%{
12325  match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
12326  ins_cost(1.9 * INSN_COST);
12327  format %{ "addw  $dst, $src1, $src2, sxtb #lshift2" %}
12328
12329   ins_encode %{
12330     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12331            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
12332   %}
12333  ins_pipe(ialu_reg_reg_shift);
12334%}
12335
12336// This pattern is automatically generated from aarch64_ad.m4
12337// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12338instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
12339%{
12340  match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
12341  ins_cost(1.9 * INSN_COST);
12342  format %{ "addw  $dst, $src1, $src2, sxth #lshift2" %}
12343
12344   ins_encode %{
12345     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12346            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
12347   %}
12348  ins_pipe(ialu_reg_reg_shift);
12349%}
12350
12351// This pattern is automatically generated from aarch64_ad.m4
12352// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12353instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
12354%{
12355  match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
12356  ins_cost(1.9 * INSN_COST);
12357  format %{ "subw  $dst, $src1, $src2, sxtb #lshift2" %}
12358
12359   ins_encode %{
12360     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12361            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
12362   %}
12363  ins_pipe(ialu_reg_reg_shift);
12364%}
12365
12366// This pattern is automatically generated from aarch64_ad.m4
12367// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12368instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
12369%{
12370  match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
12371  ins_cost(1.9 * INSN_COST);
12372  format %{ "subw  $dst, $src1, $src2, sxth #lshift2" %}
12373
12374   ins_encode %{
12375     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12376            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
12377   %}
12378  ins_pipe(ialu_reg_reg_shift);
12379%}
12380
12381// This pattern is automatically generated from aarch64_ad.m4
12382// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12383instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
12384%{
12385  match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift)));
12386  ins_cost(1.9 * INSN_COST);
12387  format %{ "add  $dst, $src1, $src2, sxtw #lshift" %}
12388
12389   ins_encode %{
12390     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12391            as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
12392   %}
12393  ins_pipe(ialu_reg_reg_shift);
12394%}
12395
12396// This pattern is automatically generated from aarch64_ad.m4
12397// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12398instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
12399%{
12400  match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift)));
12401  ins_cost(1.9 * INSN_COST);
12402  format %{ "sub  $dst, $src1, $src2, sxtw #lshift" %}
12403
12404   ins_encode %{
12405     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12406            as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
12407   %}
12408  ins_pipe(ialu_reg_reg_shift);
12409%}
12410
12411// This pattern is automatically generated from aarch64_ad.m4
12412// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12413instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
12414%{
12415  match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
12416  ins_cost(1.9 * INSN_COST);
12417  format %{ "add  $dst, $src1, $src2, uxtb #lshift" %}
12418
12419   ins_encode %{
12420     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12421            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
12422   %}
12423  ins_pipe(ialu_reg_reg_shift);
12424%}
12425
12426// This pattern is automatically generated from aarch64_ad.m4
12427// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12428instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
12429%{
12430  match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
12431  ins_cost(1.9 * INSN_COST);
12432  format %{ "add  $dst, $src1, $src2, uxth #lshift" %}
12433
12434   ins_encode %{
12435     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12436            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
12437   %}
12438  ins_pipe(ialu_reg_reg_shift);
12439%}
12440
12441// This pattern is automatically generated from aarch64_ad.m4
12442// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12443instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
12444%{
12445  match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
12446  ins_cost(1.9 * INSN_COST);
12447  format %{ "add  $dst, $src1, $src2, uxtw #lshift" %}
12448
12449   ins_encode %{
12450     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12451            as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
12452   %}
12453  ins_pipe(ialu_reg_reg_shift);
12454%}
12455
12456// This pattern is automatically generated from aarch64_ad.m4
12457// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12458instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
12459%{
12460  match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
12461  ins_cost(1.9 * INSN_COST);
12462  format %{ "sub  $dst, $src1, $src2, uxtb #lshift" %}
12463
12464   ins_encode %{
12465     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12466            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
12467   %}
12468  ins_pipe(ialu_reg_reg_shift);
12469%}
12470
12471// This pattern is automatically generated from aarch64_ad.m4
12472// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12473instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
12474%{
12475  match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
12476  ins_cost(1.9 * INSN_COST);
12477  format %{ "sub  $dst, $src1, $src2, uxth #lshift" %}
12478
12479   ins_encode %{
12480     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12481            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
12482   %}
12483  ins_pipe(ialu_reg_reg_shift);
12484%}
12485
12486// This pattern is automatically generated from aarch64_ad.m4
12487// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12488instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
12489%{
12490  match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
12491  ins_cost(1.9 * INSN_COST);
12492  format %{ "sub  $dst, $src1, $src2, uxtw #lshift" %}
12493
12494   ins_encode %{
12495     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12496            as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
12497   %}
12498  ins_pipe(ialu_reg_reg_shift);
12499%}
12500
12501// This pattern is automatically generated from aarch64_ad.m4
12502// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12503instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
12504%{
12505  match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
12506  ins_cost(1.9 * INSN_COST);
12507  format %{ "addw  $dst, $src1, $src2, uxtb #lshift" %}
12508
12509   ins_encode %{
12510     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12511            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
12512   %}
12513  ins_pipe(ialu_reg_reg_shift);
12514%}
12515
12516// This pattern is automatically generated from aarch64_ad.m4
12517// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12518instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
12519%{
12520  match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
12521  ins_cost(1.9 * INSN_COST);
12522  format %{ "addw  $dst, $src1, $src2, uxth #lshift" %}
12523
12524   ins_encode %{
12525     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12526            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
12527   %}
12528  ins_pipe(ialu_reg_reg_shift);
12529%}
12530
12531// This pattern is automatically generated from aarch64_ad.m4
12532// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12533instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
12534%{
12535  match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
12536  ins_cost(1.9 * INSN_COST);
12537  format %{ "subw  $dst, $src1, $src2, uxtb #lshift" %}
12538
12539   ins_encode %{
12540     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12541            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
12542   %}
12543  ins_pipe(ialu_reg_reg_shift);
12544%}
12545
12546// This pattern is automatically generated from aarch64_ad.m4
12547// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12548instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
12549%{
12550  match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
12551  ins_cost(1.9 * INSN_COST);
12552  format %{ "subw  $dst, $src1, $src2, uxth #lshift" %}
12553
12554   ins_encode %{
12555     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12556            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
12557   %}
12558  ins_pipe(ialu_reg_reg_shift);
12559%}
12560
12561
12562
12563// END This section of the file is automatically generated. Do not edit --------------
12564
12565
12566// ============================================================================
12567// Floating Point Arithmetic Instructions
12568
12569instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
12570  match(Set dst (AddF src1 src2));
12571
12572  ins_cost(INSN_COST * 5);
12573  format %{ "fadds   $dst, $src1, $src2" %}
12574
12575  ins_encode %{
12576    __ fadds(as_FloatRegister($dst$$reg),
12577             as_FloatRegister($src1$$reg),
12578             as_FloatRegister($src2$$reg));
12579  %}
12580
12581  ins_pipe(fp_dop_reg_reg_s);
12582%}
12583
12584instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
12585  match(Set dst (AddD src1 src2));
12586
12587  ins_cost(INSN_COST * 5);
12588  format %{ "faddd   $dst, $src1, $src2" %}
12589
12590  ins_encode %{
12591    __ faddd(as_FloatRegister($dst$$reg),
12592             as_FloatRegister($src1$$reg),
12593             as_FloatRegister($src2$$reg));
12594  %}
12595
12596  ins_pipe(fp_dop_reg_reg_d);
12597%}
12598
12599instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
12600  match(Set dst (SubF src1 src2));
12601
12602  ins_cost(INSN_COST * 5);
12603  format %{ "fsubs   $dst, $src1, $src2" %}
12604
12605  ins_encode %{
12606    __ fsubs(as_FloatRegister($dst$$reg),
12607             as_FloatRegister($src1$$reg),
12608             as_FloatRegister($src2$$reg));
12609  %}
12610
12611  ins_pipe(fp_dop_reg_reg_s);
12612%}
12613
12614instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
12615  match(Set dst (SubD src1 src2));
12616
12617  ins_cost(INSN_COST * 5);
12618  format %{ "fsubd   $dst, $src1, $src2" %}
12619
12620  ins_encode %{
12621    __ fsubd(as_FloatRegister($dst$$reg),
12622             as_FloatRegister($src1$$reg),
12623             as_FloatRegister($src2$$reg));
12624  %}
12625
12626  ins_pipe(fp_dop_reg_reg_d);
12627%}
12628
12629instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
12630  match(Set dst (MulF src1 src2));
12631
12632  ins_cost(INSN_COST * 6);
12633  format %{ "fmuls   $dst, $src1, $src2" %}
12634
12635  ins_encode %{
12636    __ fmuls(as_FloatRegister($dst$$reg),
12637             as_FloatRegister($src1$$reg),
12638             as_FloatRegister($src2$$reg));
12639  %}
12640
12641  ins_pipe(fp_dop_reg_reg_s);
12642%}
12643
12644instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
12645  match(Set dst (MulD src1 src2));
12646
12647  ins_cost(INSN_COST * 6);
12648  format %{ "fmuld   $dst, $src1, $src2" %}
12649
12650  ins_encode %{
12651    __ fmuld(as_FloatRegister($dst$$reg),
12652             as_FloatRegister($src1$$reg),
12653             as_FloatRegister($src2$$reg));
12654  %}
12655
12656  ins_pipe(fp_dop_reg_reg_d);
12657%}
12658
12659// src1 * src2 + src3
12660instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
12661  predicate(UseFMA);
12662  match(Set dst (FmaF src3 (Binary src1 src2)));
12663
12664  format %{ "fmadds   $dst, $src1, $src2, $src3" %}
12665
12666  ins_encode %{
12667    __ fmadds(as_FloatRegister($dst$$reg),
12668             as_FloatRegister($src1$$reg),
12669             as_FloatRegister($src2$$reg),
12670             as_FloatRegister($src3$$reg));
12671  %}
12672
12673  ins_pipe(pipe_class_default);
12674%}
12675
12676// src1 * src2 + src3
12677instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
12678  predicate(UseFMA);
12679  match(Set dst (FmaD src3 (Binary src1 src2)));
12680
12681  format %{ "fmaddd   $dst, $src1, $src2, $src3" %}
12682
12683  ins_encode %{
12684    __ fmaddd(as_FloatRegister($dst$$reg),
12685             as_FloatRegister($src1$$reg),
12686             as_FloatRegister($src2$$reg),
12687             as_FloatRegister($src3$$reg));
12688  %}
12689
12690  ins_pipe(pipe_class_default);
12691%}
12692
12693// -src1 * src2 + src3
12694instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
12695  predicate(UseFMA);
12696  match(Set dst (FmaF src3 (Binary (NegF src1) src2)));
12697  match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
12698
12699  format %{ "fmsubs   $dst, $src1, $src2, $src3" %}
12700
12701  ins_encode %{
12702    __ fmsubs(as_FloatRegister($dst$$reg),
12703              as_FloatRegister($src1$$reg),
12704              as_FloatRegister($src2$$reg),
12705              as_FloatRegister($src3$$reg));
12706  %}
12707
12708  ins_pipe(pipe_class_default);
12709%}
12710
12711// -src1 * src2 + src3
12712instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
12713  predicate(UseFMA);
12714  match(Set dst (FmaD src3 (Binary (NegD src1) src2)));
12715  match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
12716
12717  format %{ "fmsubd   $dst, $src1, $src2, $src3" %}
12718
12719  ins_encode %{
12720    __ fmsubd(as_FloatRegister($dst$$reg),
12721              as_FloatRegister($src1$$reg),
12722              as_FloatRegister($src2$$reg),
12723              as_FloatRegister($src3$$reg));
12724  %}
12725
12726  ins_pipe(pipe_class_default);
12727%}
12728
12729// -src1 * src2 - src3
12730instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
12731  predicate(UseFMA);
12732  match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2)));
12733  match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
12734
12735  format %{ "fnmadds  $dst, $src1, $src2, $src3" %}
12736
12737  ins_encode %{
12738    __ fnmadds(as_FloatRegister($dst$$reg),
12739               as_FloatRegister($src1$$reg),
12740               as_FloatRegister($src2$$reg),
12741               as_FloatRegister($src3$$reg));
12742  %}
12743
12744  ins_pipe(pipe_class_default);
12745%}
12746
12747// -src1 * src2 - src3
12748instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
12749  predicate(UseFMA);
12750  match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2)));
12751  match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
12752
12753  format %{ "fnmaddd   $dst, $src1, $src2, $src3" %}
12754
12755  ins_encode %{
12756    __ fnmaddd(as_FloatRegister($dst$$reg),
12757               as_FloatRegister($src1$$reg),
12758               as_FloatRegister($src2$$reg),
12759               as_FloatRegister($src3$$reg));
12760  %}
12761
12762  ins_pipe(pipe_class_default);
12763%}
12764
12765// src1 * src2 - src3
12766instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{
12767  predicate(UseFMA);
12768  match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
12769
12770  format %{ "fnmsubs  $dst, $src1, $src2, $src3" %}
12771
12772  ins_encode %{
12773    __ fnmsubs(as_FloatRegister($dst$$reg),
12774               as_FloatRegister($src1$$reg),
12775               as_FloatRegister($src2$$reg),
12776               as_FloatRegister($src3$$reg));
12777  %}
12778
12779  ins_pipe(pipe_class_default);
12780%}
12781
12782// src1 * src2 - src3
12783instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{
12784  predicate(UseFMA);
12785  match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
12786
12787  format %{ "fnmsubd   $dst, $src1, $src2, $src3" %}
12788
12789  ins_encode %{
12790  // n.b. insn name should be fnmsubd
12791    __ fnmsub(as_FloatRegister($dst$$reg),
12792              as_FloatRegister($src1$$reg),
12793              as_FloatRegister($src2$$reg),
12794              as_FloatRegister($src3$$reg));
12795  %}
12796
12797  ins_pipe(pipe_class_default);
12798%}
12799
12800
12801// Math.max(FF)F
12802instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
12803  match(Set dst (MaxF src1 src2));
12804
12805  format %{ "fmaxs   $dst, $src1, $src2" %}
12806  ins_encode %{
12807    __ fmaxs(as_FloatRegister($dst$$reg),
12808             as_FloatRegister($src1$$reg),
12809             as_FloatRegister($src2$$reg));
12810  %}
12811
12812  ins_pipe(fp_dop_reg_reg_s);
12813%}
12814
12815// Math.min(FF)F
12816instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
12817  match(Set dst (MinF src1 src2));
12818
12819  format %{ "fmins   $dst, $src1, $src2" %}
12820  ins_encode %{
12821    __ fmins(as_FloatRegister($dst$$reg),
12822             as_FloatRegister($src1$$reg),
12823             as_FloatRegister($src2$$reg));
12824  %}
12825
12826  ins_pipe(fp_dop_reg_reg_s);
12827%}
12828
12829// Math.max(DD)D
12830instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
12831  match(Set dst (MaxD src1 src2));
12832
12833  format %{ "fmaxd   $dst, $src1, $src2" %}
12834  ins_encode %{
12835    __ fmaxd(as_FloatRegister($dst$$reg),
12836             as_FloatRegister($src1$$reg),
12837             as_FloatRegister($src2$$reg));
12838  %}
12839
12840  ins_pipe(fp_dop_reg_reg_d);
12841%}
12842
12843// Math.min(DD)D
12844instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
12845  match(Set dst (MinD src1 src2));
12846
12847  format %{ "fmind   $dst, $src1, $src2" %}
12848  ins_encode %{
12849    __ fmind(as_FloatRegister($dst$$reg),
12850             as_FloatRegister($src1$$reg),
12851             as_FloatRegister($src2$$reg));
12852  %}
12853
12854  ins_pipe(fp_dop_reg_reg_d);
12855%}
12856
12857
12858instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
12859  match(Set dst (DivF src1  src2));
12860
12861  ins_cost(INSN_COST * 18);
12862  format %{ "fdivs   $dst, $src1, $src2" %}
12863
12864  ins_encode %{
12865    __ fdivs(as_FloatRegister($dst$$reg),
12866             as_FloatRegister($src1$$reg),
12867             as_FloatRegister($src2$$reg));
12868  %}
12869
12870  ins_pipe(fp_div_s);
12871%}
12872
12873instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
12874  match(Set dst (DivD src1  src2));
12875
12876  ins_cost(INSN_COST * 32);
12877  format %{ "fdivd   $dst, $src1, $src2" %}
12878
12879  ins_encode %{
12880    __ fdivd(as_FloatRegister($dst$$reg),
12881             as_FloatRegister($src1$$reg),
12882             as_FloatRegister($src2$$reg));
12883  %}
12884
12885  ins_pipe(fp_div_d);
12886%}
12887
12888instruct negF_reg_reg(vRegF dst, vRegF src) %{
12889  match(Set dst (NegF src));
12890
12891  ins_cost(INSN_COST * 3);
12892  format %{ "fneg   $dst, $src" %}
12893
12894  ins_encode %{
12895    __ fnegs(as_FloatRegister($dst$$reg),
12896             as_FloatRegister($src$$reg));
12897  %}
12898
12899  ins_pipe(fp_uop_s);
12900%}
12901
12902instruct negD_reg_reg(vRegD dst, vRegD src) %{
12903  match(Set dst (NegD src));
12904
12905  ins_cost(INSN_COST * 3);
12906  format %{ "fnegd   $dst, $src" %}
12907
12908  ins_encode %{
12909    __ fnegd(as_FloatRegister($dst$$reg),
12910             as_FloatRegister($src$$reg));
12911  %}
12912
12913  ins_pipe(fp_uop_d);
12914%}
12915
12916instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr)
12917%{
12918  match(Set dst (AbsI src));
12919
12920  effect(KILL cr);
12921  ins_cost(INSN_COST * 2);
12922  format %{ "cmpw  $src, zr\n\t"
12923            "cnegw $dst, $src, Assembler::LT\t# int abs"
12924  %}
12925
12926  ins_encode %{
12927    __ cmpw(as_Register($src$$reg), zr);
12928    __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT);
12929  %}
12930  ins_pipe(pipe_class_default);
12931%}
12932
12933instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr)
12934%{
12935  match(Set dst (AbsL src));
12936
12937  effect(KILL cr);
12938  ins_cost(INSN_COST * 2);
12939  format %{ "cmp  $src, zr\n\t"
12940            "cneg $dst, $src, Assembler::LT\t# long abs"
12941  %}
12942
12943  ins_encode %{
12944    __ cmp(as_Register($src$$reg), zr);
12945    __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT);
12946  %}
12947  ins_pipe(pipe_class_default);
12948%}
12949
12950instruct absF_reg(vRegF dst, vRegF src) %{
12951  match(Set dst (AbsF src));
12952
12953  ins_cost(INSN_COST * 3);
12954  format %{ "fabss   $dst, $src" %}
12955  ins_encode %{
12956    __ fabss(as_FloatRegister($dst$$reg),
12957             as_FloatRegister($src$$reg));
12958  %}
12959
12960  ins_pipe(fp_uop_s);
12961%}
12962
12963instruct absD_reg(vRegD dst, vRegD src) %{
12964  match(Set dst (AbsD src));
12965
12966  ins_cost(INSN_COST * 3);
12967  format %{ "fabsd   $dst, $src" %}
12968  ins_encode %{
12969    __ fabsd(as_FloatRegister($dst$$reg),
12970             as_FloatRegister($src$$reg));
12971  %}
12972
12973  ins_pipe(fp_uop_d);
12974%}
12975
12976instruct sqrtD_reg(vRegD dst, vRegD src) %{
12977  match(Set dst (SqrtD src));
12978
12979  ins_cost(INSN_COST * 50);
12980  format %{ "fsqrtd  $dst, $src" %}
12981  ins_encode %{
12982    __ fsqrtd(as_FloatRegister($dst$$reg),
12983             as_FloatRegister($src$$reg));
12984  %}
12985
12986  ins_pipe(fp_div_s);
12987%}
12988
12989instruct sqrtF_reg(vRegF dst, vRegF src) %{
12990  match(Set dst (SqrtF src));
12991
12992  ins_cost(INSN_COST * 50);
12993  format %{ "fsqrts  $dst, $src" %}
12994  ins_encode %{
12995    __ fsqrts(as_FloatRegister($dst$$reg),
12996             as_FloatRegister($src$$reg));
12997  %}
12998
12999  ins_pipe(fp_div_d);
13000%}
13001
13002instruct copySignD_reg(vRegD dst, vRegD src1, vRegD src2, vRegD zero) %{
13003  match(Set dst (CopySignD src1 (Binary src2 zero)));
13004  effect(TEMP_DEF dst, USE src1, USE src2, USE zero);
13005  format %{ "CopySignD  $dst $src1 $src2" %}
13006  ins_encode %{
13007    FloatRegister dst = as_FloatRegister($dst$$reg),
13008                  src1 = as_FloatRegister($src1$$reg),
13009                  src2 = as_FloatRegister($src2$$reg),
13010                  zero = as_FloatRegister($zero$$reg);
13011    __ fnegd(dst, zero);
13012    __ bsl(dst, __ T8B, src2, src1);
13013  %}
13014  ins_pipe(fp_uop_d);
13015%}
13016
13017instruct copySignF_reg(vRegF dst, vRegF src1, vRegF src2) %{
13018  match(Set dst (CopySignF src1 src2));
13019  effect(TEMP_DEF dst, USE src1, USE src2);
13020  format %{ "CopySignF  $dst $src1 $src2" %}
13021  ins_encode %{
13022    FloatRegister dst = as_FloatRegister($dst$$reg),
13023                  src1 = as_FloatRegister($src1$$reg),
13024                  src2 = as_FloatRegister($src2$$reg);
13025    __ movi(dst, __ T2S, 0x80, 24);
13026    __ bsl(dst, __ T8B, src2, src1);
13027  %}
13028  ins_pipe(fp_uop_d);
13029%}
13030
13031instruct signumD_reg(vRegD dst, vRegD src, vRegD zero, vRegD one) %{
13032  match(Set dst (SignumD src (Binary zero one)));
13033  effect(TEMP_DEF dst, USE src, USE zero, USE one);
13034  format %{ "signumD  $dst, $src" %}
13035  ins_encode %{
13036    FloatRegister src = as_FloatRegister($src$$reg),
13037                  dst = as_FloatRegister($dst$$reg),
13038                  zero = as_FloatRegister($zero$$reg),
13039                  one = as_FloatRegister($one$$reg);
13040    __ facgtd(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise
13041    __ ushrd(dst, dst, 1);     // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise
13042    // Bit selection instruction gets bit from "one" for each enabled bit in
13043    // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or
13044    // NaN the whole "src" will be copied because "dst" is zero. For all other
13045    // "src" values dst is 0x7FF..F, which means only the sign bit is copied
13046    // from "src", and all other bits are copied from 1.0.
13047    __ bsl(dst, __ T8B, one, src);
13048  %}
13049  ins_pipe(fp_uop_d);
13050%}
13051
13052instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{
13053  match(Set dst (SignumF src (Binary zero one)));
13054  effect(TEMP_DEF dst, USE src, USE zero, USE one);
13055  format %{ "signumF  $dst, $src" %}
13056  ins_encode %{
13057    FloatRegister src = as_FloatRegister($src$$reg),
13058                  dst = as_FloatRegister($dst$$reg),
13059                  zero = as_FloatRegister($zero$$reg),
13060                  one = as_FloatRegister($one$$reg);
13061    __ facgts(dst, src, zero);    // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise
13062    __ ushr(dst, __ T2S, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise
13063    // Bit selection instruction gets bit from "one" for each enabled bit in
13064    // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or
13065    // NaN the whole "src" will be copied because "dst" is zero. For all other
13066    // "src" values dst is 0x7FF..F, which means only the sign bit is copied
13067    // from "src", and all other bits are copied from 1.0.
13068    __ bsl(dst, __ T8B, one, src);
13069  %}
13070  ins_pipe(fp_uop_d);
13071%}
13072
13073// ============================================================================
13074// Logical Instructions
13075
13076// Integer Logical Instructions
13077
13078// And Instructions
13079
13080
13081instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{
13082  match(Set dst (AndI src1 src2));
13083
13084  format %{ "andw  $dst, $src1, $src2\t# int" %}
13085
13086  ins_cost(INSN_COST);
13087  ins_encode %{
13088    __ andw(as_Register($dst$$reg),
13089            as_Register($src1$$reg),
13090            as_Register($src2$$reg));
13091  %}
13092
13093  ins_pipe(ialu_reg_reg);
13094%}
13095
13096instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{
13097  match(Set dst (AndI src1 src2));
13098
13099  format %{ "andsw  $dst, $src1, $src2\t# int" %}
13100
13101  ins_cost(INSN_COST);
13102  ins_encode %{
13103    __ andw(as_Register($dst$$reg),
13104            as_Register($src1$$reg),
13105            (uint64_t)($src2$$constant));
13106  %}
13107
13108  ins_pipe(ialu_reg_imm);
13109%}
13110
13111// Or Instructions
13112
13113instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
13114  match(Set dst (OrI src1 src2));
13115
13116  format %{ "orrw  $dst, $src1, $src2\t# int" %}
13117
13118  ins_cost(INSN_COST);
13119  ins_encode %{
13120    __ orrw(as_Register($dst$$reg),
13121            as_Register($src1$$reg),
13122            as_Register($src2$$reg));
13123  %}
13124
13125  ins_pipe(ialu_reg_reg);
13126%}
13127
13128instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
13129  match(Set dst (OrI src1 src2));
13130
13131  format %{ "orrw  $dst, $src1, $src2\t# int" %}
13132
13133  ins_cost(INSN_COST);
13134  ins_encode %{
13135    __ orrw(as_Register($dst$$reg),
13136            as_Register($src1$$reg),
13137            (uint64_t)($src2$$constant));
13138  %}
13139
13140  ins_pipe(ialu_reg_imm);
13141%}
13142
13143// Xor Instructions
13144
13145instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
13146  match(Set dst (XorI src1 src2));
13147
13148  format %{ "eorw  $dst, $src1, $src2\t# int" %}
13149
13150  ins_cost(INSN_COST);
13151  ins_encode %{
13152    __ eorw(as_Register($dst$$reg),
13153            as_Register($src1$$reg),
13154            as_Register($src2$$reg));
13155  %}
13156
13157  ins_pipe(ialu_reg_reg);
13158%}
13159
13160instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
13161  match(Set dst (XorI src1 src2));
13162
13163  format %{ "eorw  $dst, $src1, $src2\t# int" %}
13164
13165  ins_cost(INSN_COST);
13166  ins_encode %{
13167    __ eorw(as_Register($dst$$reg),
13168            as_Register($src1$$reg),
13169            (uint64_t)($src2$$constant));
13170  %}
13171
13172  ins_pipe(ialu_reg_imm);
13173%}
13174
13175// Long Logical Instructions
13176// TODO
13177
13178instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{
13179  match(Set dst (AndL src1 src2));
13180
13181  format %{ "and  $dst, $src1, $src2\t# int" %}
13182
13183  ins_cost(INSN_COST);
13184  ins_encode %{
13185    __ andr(as_Register($dst$$reg),
13186            as_Register($src1$$reg),
13187            as_Register($src2$$reg));
13188  %}
13189
13190  ins_pipe(ialu_reg_reg);
13191%}
13192
13193instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{
13194  match(Set dst (AndL src1 src2));
13195
13196  format %{ "and  $dst, $src1, $src2\t# int" %}
13197
13198  ins_cost(INSN_COST);
13199  ins_encode %{
13200    __ andr(as_Register($dst$$reg),
13201            as_Register($src1$$reg),
13202            (uint64_t)($src2$$constant));
13203  %}
13204
13205  ins_pipe(ialu_reg_imm);
13206%}
13207
13208// Or Instructions
13209
13210instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
13211  match(Set dst (OrL src1 src2));
13212
13213  format %{ "orr  $dst, $src1, $src2\t# int" %}
13214
13215  ins_cost(INSN_COST);
13216  ins_encode %{
13217    __ orr(as_Register($dst$$reg),
13218           as_Register($src1$$reg),
13219           as_Register($src2$$reg));
13220  %}
13221
13222  ins_pipe(ialu_reg_reg);
13223%}
13224
13225instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
13226  match(Set dst (OrL src1 src2));
13227
13228  format %{ "orr  $dst, $src1, $src2\t# int" %}
13229
13230  ins_cost(INSN_COST);
13231  ins_encode %{
13232    __ orr(as_Register($dst$$reg),
13233           as_Register($src1$$reg),
13234           (uint64_t)($src2$$constant));
13235  %}
13236
13237  ins_pipe(ialu_reg_imm);
13238%}
13239
13240// Xor Instructions
13241
13242instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
13243  match(Set dst (XorL src1 src2));
13244
13245  format %{ "eor  $dst, $src1, $src2\t# int" %}
13246
13247  ins_cost(INSN_COST);
13248  ins_encode %{
13249    __ eor(as_Register($dst$$reg),
13250           as_Register($src1$$reg),
13251           as_Register($src2$$reg));
13252  %}
13253
13254  ins_pipe(ialu_reg_reg);
13255%}
13256
13257instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
13258  match(Set dst (XorL src1 src2));
13259
13260  ins_cost(INSN_COST);
13261  format %{ "eor  $dst, $src1, $src2\t# int" %}
13262
13263  ins_encode %{
13264    __ eor(as_Register($dst$$reg),
13265           as_Register($src1$$reg),
13266           (uint64_t)($src2$$constant));
13267  %}
13268
13269  ins_pipe(ialu_reg_imm);
13270%}
13271
13272instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src)
13273%{
13274  match(Set dst (ConvI2L src));
13275
13276  ins_cost(INSN_COST);
13277  format %{ "sxtw  $dst, $src\t# i2l" %}
13278  ins_encode %{
13279    __ sbfm($dst$$Register, $src$$Register, 0, 31);
13280  %}
13281  ins_pipe(ialu_reg_shift);
13282%}
13283
13284// this pattern occurs in bigmath arithmetic
13285instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask)
13286%{
13287  match(Set dst (AndL (ConvI2L src) mask));
13288
13289  ins_cost(INSN_COST);
13290  format %{ "ubfm  $dst, $src, 0, 31\t# ui2l" %}
13291  ins_encode %{
13292    __ ubfm($dst$$Register, $src$$Register, 0, 31);
13293  %}
13294
13295  ins_pipe(ialu_reg_shift);
13296%}
13297
13298instruct convL2I_reg(iRegINoSp dst, iRegL src) %{
13299  match(Set dst (ConvL2I src));
13300
13301  ins_cost(INSN_COST);
13302  format %{ "movw  $dst, $src \t// l2i" %}
13303
13304  ins_encode %{
13305    __ movw(as_Register($dst$$reg), as_Register($src$$reg));
13306  %}
13307
13308  ins_pipe(ialu_reg);
13309%}
13310
13311instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr)
13312%{
13313  match(Set dst (Conv2B src));
13314  effect(KILL cr);
13315
13316  format %{
13317    "cmpw $src, zr\n\t"
13318    "cset $dst, ne"
13319  %}
13320
13321  ins_encode %{
13322    __ cmpw(as_Register($src$$reg), zr);
13323    __ cset(as_Register($dst$$reg), Assembler::NE);
13324  %}
13325
13326  ins_pipe(ialu_reg);
13327%}
13328
13329instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr)
13330%{
13331  match(Set dst (Conv2B src));
13332  effect(KILL cr);
13333
13334  format %{
13335    "cmp  $src, zr\n\t"
13336    "cset $dst, ne"
13337  %}
13338
13339  ins_encode %{
13340    __ cmp(as_Register($src$$reg), zr);
13341    __ cset(as_Register($dst$$reg), Assembler::NE);
13342  %}
13343
13344  ins_pipe(ialu_reg);
13345%}
13346
13347instruct convD2F_reg(vRegF dst, vRegD src) %{
13348  match(Set dst (ConvD2F src));
13349
13350  ins_cost(INSN_COST * 5);
13351  format %{ "fcvtd  $dst, $src \t// d2f" %}
13352
13353  ins_encode %{
13354    __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
13355  %}
13356
13357  ins_pipe(fp_d2f);
13358%}
13359
13360instruct convF2D_reg(vRegD dst, vRegF src) %{
13361  match(Set dst (ConvF2D src));
13362
13363  ins_cost(INSN_COST * 5);
13364  format %{ "fcvts  $dst, $src \t// f2d" %}
13365
13366  ins_encode %{
13367    __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
13368  %}
13369
13370  ins_pipe(fp_f2d);
13371%}
13372
13373instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{
13374  match(Set dst (ConvF2I src));
13375
13376  ins_cost(INSN_COST * 5);
13377  format %{ "fcvtzsw  $dst, $src \t// f2i" %}
13378
13379  ins_encode %{
13380    __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
13381  %}
13382
13383  ins_pipe(fp_f2i);
13384%}
13385
13386instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{
13387  match(Set dst (ConvF2L src));
13388
13389  ins_cost(INSN_COST * 5);
13390  format %{ "fcvtzs  $dst, $src \t// f2l" %}
13391
13392  ins_encode %{
13393    __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg));
13394  %}
13395
13396  ins_pipe(fp_f2l);
13397%}
13398
13399instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{
13400  match(Set dst (ConvI2F src));
13401
13402  ins_cost(INSN_COST * 5);
13403  format %{ "scvtfws  $dst, $src \t// i2f" %}
13404
13405  ins_encode %{
13406    __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg));
13407  %}
13408
13409  ins_pipe(fp_i2f);
13410%}
13411
13412instruct convL2F_reg_reg(vRegF dst, iRegL src) %{
13413  match(Set dst (ConvL2F src));
13414
13415  ins_cost(INSN_COST * 5);
13416  format %{ "scvtfs  $dst, $src \t// l2f" %}
13417
13418  ins_encode %{
13419    __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg));
13420  %}
13421
13422  ins_pipe(fp_l2f);
13423%}
13424
13425instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{
13426  match(Set dst (ConvD2I src));
13427
13428  ins_cost(INSN_COST * 5);
13429  format %{ "fcvtzdw  $dst, $src \t// d2i" %}
13430
13431  ins_encode %{
13432    __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
13433  %}
13434
13435  ins_pipe(fp_d2i);
13436%}
13437
13438instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
13439  match(Set dst (ConvD2L src));
13440
13441  ins_cost(INSN_COST * 5);
13442  format %{ "fcvtzd  $dst, $src \t// d2l" %}
13443
13444  ins_encode %{
13445    __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg));
13446  %}
13447
13448  ins_pipe(fp_d2l);
13449%}
13450
13451instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{
13452  match(Set dst (ConvI2D src));
13453
13454  ins_cost(INSN_COST * 5);
13455  format %{ "scvtfwd  $dst, $src \t// i2d" %}
13456
13457  ins_encode %{
13458    __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
13459  %}
13460
13461  ins_pipe(fp_i2d);
13462%}
13463
13464instruct convL2D_reg_reg(vRegD dst, iRegL src) %{
13465  match(Set dst (ConvL2D src));
13466
13467  ins_cost(INSN_COST * 5);
13468  format %{ "scvtfd  $dst, $src \t// l2d" %}
13469
13470  ins_encode %{
13471    __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
13472  %}
13473
13474  ins_pipe(fp_l2d);
13475%}
13476
13477// stack <-> reg and reg <-> reg shuffles with no conversion
13478
13479instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{
13480
13481  match(Set dst (MoveF2I src));
13482
13483  effect(DEF dst, USE src);
13484
13485  ins_cost(4 * INSN_COST);
13486
13487  format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %}
13488
13489  ins_encode %{
13490    __ ldrw($dst$$Register, Address(sp, $src$$disp));
13491  %}
13492
13493  ins_pipe(iload_reg_reg);
13494
13495%}
13496
13497instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{
13498
13499  match(Set dst (MoveI2F src));
13500
13501  effect(DEF dst, USE src);
13502
13503  ins_cost(4 * INSN_COST);
13504
13505  format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %}
13506
13507  ins_encode %{
13508    __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
13509  %}
13510
13511  ins_pipe(pipe_class_memory);
13512
13513%}
13514
13515instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{
13516
13517  match(Set dst (MoveD2L src));
13518
13519  effect(DEF dst, USE src);
13520
13521  ins_cost(4 * INSN_COST);
13522
13523  format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %}
13524
13525  ins_encode %{
13526    __ ldr($dst$$Register, Address(sp, $src$$disp));
13527  %}
13528
13529  ins_pipe(iload_reg_reg);
13530
13531%}
13532
13533instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{
13534
13535  match(Set dst (MoveL2D src));
13536
13537  effect(DEF dst, USE src);
13538
13539  ins_cost(4 * INSN_COST);
13540
13541  format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %}
13542
13543  ins_encode %{
13544    __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
13545  %}
13546
13547  ins_pipe(pipe_class_memory);
13548
13549%}
13550
13551instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{
13552
13553  match(Set dst (MoveF2I src));
13554
13555  effect(DEF dst, USE src);
13556
13557  ins_cost(INSN_COST);
13558
13559  format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %}
13560
13561  ins_encode %{
13562    __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
13563  %}
13564
13565  ins_pipe(pipe_class_memory);
13566
13567%}
13568
13569instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
13570
13571  match(Set dst (MoveI2F src));
13572
13573  effect(DEF dst, USE src);
13574
13575  ins_cost(INSN_COST);
13576
13577  format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %}
13578
13579  ins_encode %{
13580    __ strw($src$$Register, Address(sp, $dst$$disp));
13581  %}
13582
13583  ins_pipe(istore_reg_reg);
13584
13585%}
13586
13587instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{
13588
13589  match(Set dst (MoveD2L src));
13590
13591  effect(DEF dst, USE src);
13592
13593  ins_cost(INSN_COST);
13594
13595  format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %}
13596
13597  ins_encode %{
13598    __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
13599  %}
13600
13601  ins_pipe(pipe_class_memory);
13602
13603%}
13604
13605instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
13606
13607  match(Set dst (MoveL2D src));
13608
13609  effect(DEF dst, USE src);
13610
13611  ins_cost(INSN_COST);
13612
13613  format %{ "str $src, $dst\t# MoveL2D_reg_stack" %}
13614
13615  ins_encode %{
13616    __ str($src$$Register, Address(sp, $dst$$disp));
13617  %}
13618
13619  ins_pipe(istore_reg_reg);
13620
13621%}
13622
13623instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{
13624
13625  match(Set dst (MoveF2I src));
13626
13627  effect(DEF dst, USE src);
13628
13629  ins_cost(INSN_COST);
13630
13631  format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %}
13632
13633  ins_encode %{
13634    __ fmovs($dst$$Register, as_FloatRegister($src$$reg));
13635  %}
13636
13637  ins_pipe(fp_f2i);
13638
13639%}
13640
13641instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{
13642
13643  match(Set dst (MoveI2F src));
13644
13645  effect(DEF dst, USE src);
13646
13647  ins_cost(INSN_COST);
13648
13649  format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %}
13650
13651  ins_encode %{
13652    __ fmovs(as_FloatRegister($dst$$reg), $src$$Register);
13653  %}
13654
13655  ins_pipe(fp_i2f);
13656
13657%}
13658
13659instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
13660
13661  match(Set dst (MoveD2L src));
13662
13663  effect(DEF dst, USE src);
13664
13665  ins_cost(INSN_COST);
13666
13667  format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %}
13668
13669  ins_encode %{
13670    __ fmovd($dst$$Register, as_FloatRegister($src$$reg));
13671  %}
13672
13673  ins_pipe(fp_d2l);
13674
13675%}
13676
13677instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{
13678
13679  match(Set dst (MoveL2D src));
13680
13681  effect(DEF dst, USE src);
13682
13683  ins_cost(INSN_COST);
13684
13685  format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %}
13686
13687  ins_encode %{
13688    __ fmovd(as_FloatRegister($dst$$reg), $src$$Register);
13689  %}
13690
13691  ins_pipe(fp_l2d);
13692
13693%}
13694
13695// ============================================================================
13696// clearing of an array
13697
13698instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
13699%{
13700  match(Set dummy (ClearArray cnt base));
13701  effect(USE_KILL cnt, USE_KILL base, KILL cr);
13702
13703  ins_cost(4 * INSN_COST);
13704  format %{ "ClearArray $cnt, $base" %}
13705
13706  ins_encode %{
13707    address tpc = __ zero_words($base$$Register, $cnt$$Register);
13708    if (tpc == NULL) {
13709      ciEnv::current()->record_failure("CodeCache is full");
13710      return;
13711    }
13712  %}
13713
13714  ins_pipe(pipe_class_memory);
13715%}
13716
13717instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
13718%{
13719  predicate((uint64_t)n->in(2)->get_long()
13720            < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord));
13721  match(Set dummy (ClearArray cnt base));
13722  effect(USE_KILL base);
13723
13724  ins_cost(4 * INSN_COST);
13725  format %{ "ClearArray $cnt, $base" %}
13726
13727  ins_encode %{
13728    __ zero_words($base$$Register, (uint64_t)$cnt$$constant);
13729  %}
13730
13731  ins_pipe(pipe_class_memory);
13732%}
13733
13734// ============================================================================
13735// Overflow Math Instructions
13736
13737instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
13738%{
13739  match(Set cr (OverflowAddI op1 op2));
13740
13741  format %{ "cmnw  $op1, $op2\t# overflow check int" %}
13742  ins_cost(INSN_COST);
13743  ins_encode %{
13744    __ cmnw($op1$$Register, $op2$$Register);
13745  %}
13746
13747  ins_pipe(icmp_reg_reg);
13748%}
13749
13750instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
13751%{
13752  match(Set cr (OverflowAddI op1 op2));
13753
13754  format %{ "cmnw  $op1, $op2\t# overflow check int" %}
13755  ins_cost(INSN_COST);
13756  ins_encode %{
13757    __ cmnw($op1$$Register, $op2$$constant);
13758  %}
13759
13760  ins_pipe(icmp_reg_imm);
13761%}
13762
13763instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
13764%{
13765  match(Set cr (OverflowAddL op1 op2));
13766
13767  format %{ "cmn   $op1, $op2\t# overflow check long" %}
13768  ins_cost(INSN_COST);
13769  ins_encode %{
13770    __ cmn($op1$$Register, $op2$$Register);
13771  %}
13772
13773  ins_pipe(icmp_reg_reg);
13774%}
13775
13776instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
13777%{
13778  match(Set cr (OverflowAddL op1 op2));
13779
13780  format %{ "cmn   $op1, $op2\t# overflow check long" %}
13781  ins_cost(INSN_COST);
13782  ins_encode %{
13783    __ cmn($op1$$Register, $op2$$constant);
13784  %}
13785
13786  ins_pipe(icmp_reg_imm);
13787%}
13788
13789instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
13790%{
13791  match(Set cr (OverflowSubI op1 op2));
13792
13793  format %{ "cmpw  $op1, $op2\t# overflow check int" %}
13794  ins_cost(INSN_COST);
13795  ins_encode %{
13796    __ cmpw($op1$$Register, $op2$$Register);
13797  %}
13798
13799  ins_pipe(icmp_reg_reg);
13800%}
13801
13802instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
13803%{
13804  match(Set cr (OverflowSubI op1 op2));
13805
13806  format %{ "cmpw  $op1, $op2\t# overflow check int" %}
13807  ins_cost(INSN_COST);
13808  ins_encode %{
13809    __ cmpw($op1$$Register, $op2$$constant);
13810  %}
13811
13812  ins_pipe(icmp_reg_imm);
13813%}
13814
13815instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
13816%{
13817  match(Set cr (OverflowSubL op1 op2));
13818
13819  format %{ "cmp   $op1, $op2\t# overflow check long" %}
13820  ins_cost(INSN_COST);
13821  ins_encode %{
13822    __ cmp($op1$$Register, $op2$$Register);
13823  %}
13824
13825  ins_pipe(icmp_reg_reg);
13826%}
13827
13828instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
13829%{
13830  match(Set cr (OverflowSubL op1 op2));
13831
13832  format %{ "cmp   $op1, $op2\t# overflow check long" %}
13833  ins_cost(INSN_COST);
13834  ins_encode %{
13835    __ cmp($op1$$Register, $op2$$constant);
13836  %}
13837
13838  ins_pipe(icmp_reg_imm);
13839%}
13840
13841instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1)
13842%{
13843  match(Set cr (OverflowSubI zero op1));
13844
13845  format %{ "cmpw  zr, $op1\t# overflow check int" %}
13846  ins_cost(INSN_COST);
13847  ins_encode %{
13848    __ cmpw(zr, $op1$$Register);
13849  %}
13850
13851  ins_pipe(icmp_reg_imm);
13852%}
13853
13854instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1)
13855%{
13856  match(Set cr (OverflowSubL zero op1));
13857
13858  format %{ "cmp   zr, $op1\t# overflow check long" %}
13859  ins_cost(INSN_COST);
13860  ins_encode %{
13861    __ cmp(zr, $op1$$Register);
13862  %}
13863
13864  ins_pipe(icmp_reg_imm);
13865%}
13866
13867instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
13868%{
13869  match(Set cr (OverflowMulI op1 op2));
13870
13871  format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
13872            "cmp   rscratch1, rscratch1, sxtw\n\t"
13873            "movw  rscratch1, #0x80000000\n\t"
13874            "cselw rscratch1, rscratch1, zr, NE\n\t"
13875            "cmpw  rscratch1, #1" %}
13876  ins_cost(5 * INSN_COST);
13877  ins_encode %{
13878    __ smull(rscratch1, $op1$$Register, $op2$$Register);
13879    __ subs(zr, rscratch1, rscratch1, ext::sxtw);      // NE => overflow
13880    __ movw(rscratch1, 0x80000000);                    // Develop 0 (EQ),
13881    __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
13882    __ cmpw(rscratch1, 1);                             // 0x80000000 - 1 => VS
13883  %}
13884
13885  ins_pipe(pipe_slow);
13886%}
13887
13888instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr)
13889%{
13890  match(If cmp (OverflowMulI op1 op2));
13891  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
13892            || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
13893  effect(USE labl, KILL cr);
13894
13895  format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
13896            "cmp   rscratch1, rscratch1, sxtw\n\t"
13897            "b$cmp   $labl" %}
13898  ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST
13899  ins_encode %{
13900    Label* L = $labl$$label;
13901    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13902    __ smull(rscratch1, $op1$$Register, $op2$$Register);
13903    __ subs(zr, rscratch1, rscratch1, ext::sxtw);      // NE => overflow
13904    __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
13905  %}
13906
13907  ins_pipe(pipe_serial);
13908%}
13909
13910instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
13911%{
13912  match(Set cr (OverflowMulL op1 op2));
13913
13914  format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
13915            "smulh rscratch2, $op1, $op2\n\t"
13916            "cmp   rscratch2, rscratch1, ASR #63\n\t"
13917            "movw  rscratch1, #0x80000000\n\t"
13918            "cselw rscratch1, rscratch1, zr, NE\n\t"
13919            "cmpw  rscratch1, #1" %}
13920  ins_cost(6 * INSN_COST);
13921  ins_encode %{
13922    __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
13923    __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
13924    __ cmp(rscratch2, rscratch1, Assembler::ASR, 63);    // Top is pure sign ext
13925    __ movw(rscratch1, 0x80000000);                    // Develop 0 (EQ),
13926    __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
13927    __ cmpw(rscratch1, 1);                             // 0x80000000 - 1 => VS
13928  %}
13929
13930  ins_pipe(pipe_slow);
13931%}
13932
13933instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr)
13934%{
13935  match(If cmp (OverflowMulL op1 op2));
13936  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
13937            || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
13938  effect(USE labl, KILL cr);
13939
13940  format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
13941            "smulh rscratch2, $op1, $op2\n\t"
13942            "cmp   rscratch2, rscratch1, ASR #63\n\t"
13943            "b$cmp $labl" %}
13944  ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST
13945  ins_encode %{
13946    Label* L = $labl$$label;
13947    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13948    __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
13949    __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
13950    __ cmp(rscratch2, rscratch1, Assembler::ASR, 63);    // Top is pure sign ext
13951    __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
13952  %}
13953
13954  ins_pipe(pipe_serial);
13955%}
13956
13957// ============================================================================
13958// Compare Instructions
13959
13960instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
13961%{
13962  match(Set cr (CmpI op1 op2));
13963
13964  effect(DEF cr, USE op1, USE op2);
13965
13966  ins_cost(INSN_COST);
13967  format %{ "cmpw  $op1, $op2" %}
13968
13969  ins_encode(aarch64_enc_cmpw(op1, op2));
13970
13971  ins_pipe(icmp_reg_reg);
13972%}
13973
13974instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero)
13975%{
13976  match(Set cr (CmpI op1 zero));
13977
13978  effect(DEF cr, USE op1);
13979
13980  ins_cost(INSN_COST);
13981  format %{ "cmpw $op1, 0" %}
13982
13983  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
13984
13985  ins_pipe(icmp_reg_imm);
13986%}
13987
13988instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2)
13989%{
13990  match(Set cr (CmpI op1 op2));
13991
13992  effect(DEF cr, USE op1);
13993
13994  ins_cost(INSN_COST);
13995  format %{ "cmpw  $op1, $op2" %}
13996
13997  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
13998
13999  ins_pipe(icmp_reg_imm);
14000%}
14001
14002instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2)
14003%{
14004  match(Set cr (CmpI op1 op2));
14005
14006  effect(DEF cr, USE op1);
14007
14008  ins_cost(INSN_COST * 2);
14009  format %{ "cmpw  $op1, $op2" %}
14010
14011  ins_encode(aarch64_enc_cmpw_imm(op1, op2));
14012
14013  ins_pipe(icmp_reg_imm);
14014%}
14015
14016// Unsigned compare Instructions; really, same as signed compare
14017// except it should only be used to feed an If or a CMovI which takes a
14018// cmpOpU.
14019
14020instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2)
14021%{
14022  match(Set cr (CmpU op1 op2));
14023
14024  effect(DEF cr, USE op1, USE op2);
14025
14026  ins_cost(INSN_COST);
14027  format %{ "cmpw  $op1, $op2\t# unsigned" %}
14028
14029  ins_encode(aarch64_enc_cmpw(op1, op2));
14030
14031  ins_pipe(icmp_reg_reg);
14032%}
14033
14034instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero)
14035%{
14036  match(Set cr (CmpU op1 zero));
14037
14038  effect(DEF cr, USE op1);
14039
14040  ins_cost(INSN_COST);
14041  format %{ "cmpw $op1, #0\t# unsigned" %}
14042
14043  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
14044
14045  ins_pipe(icmp_reg_imm);
14046%}
14047
14048instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2)
14049%{
14050  match(Set cr (CmpU op1 op2));
14051
14052  effect(DEF cr, USE op1);
14053
14054  ins_cost(INSN_COST);
14055  format %{ "cmpw  $op1, $op2\t# unsigned" %}
14056
14057  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
14058
14059  ins_pipe(icmp_reg_imm);
14060%}
14061
14062instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2)
14063%{
14064  match(Set cr (CmpU op1 op2));
14065
14066  effect(DEF cr, USE op1);
14067
14068  ins_cost(INSN_COST * 2);
14069  format %{ "cmpw  $op1, $op2\t# unsigned" %}
14070
14071  ins_encode(aarch64_enc_cmpw_imm(op1, op2));
14072
14073  ins_pipe(icmp_reg_imm);
14074%}
14075
14076instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
14077%{
14078  match(Set cr (CmpL op1 op2));
14079
14080  effect(DEF cr, USE op1, USE op2);
14081
14082  ins_cost(INSN_COST);
14083  format %{ "cmp  $op1, $op2" %}
14084
14085  ins_encode(aarch64_enc_cmp(op1, op2));
14086
14087  ins_pipe(icmp_reg_reg);
14088%}
14089
14090instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero)
14091%{
14092  match(Set cr (CmpL op1 zero));
14093
14094  effect(DEF cr, USE op1);
14095
14096  ins_cost(INSN_COST);
14097  format %{ "tst  $op1" %}
14098
14099  ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
14100
14101  ins_pipe(icmp_reg_imm);
14102%}
14103
14104instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2)
14105%{
14106  match(Set cr (CmpL op1 op2));
14107
14108  effect(DEF cr, USE op1);
14109
14110  ins_cost(INSN_COST);
14111  format %{ "cmp  $op1, $op2" %}
14112
14113  ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
14114
14115  ins_pipe(icmp_reg_imm);
14116%}
14117
14118instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2)
14119%{
14120  match(Set cr (CmpL op1 op2));
14121
14122  effect(DEF cr, USE op1);
14123
14124  ins_cost(INSN_COST * 2);
14125  format %{ "cmp  $op1, $op2" %}
14126
14127  ins_encode(aarch64_enc_cmp_imm(op1, op2));
14128
14129  ins_pipe(icmp_reg_imm);
14130%}
14131
14132instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2)
14133%{
14134  match(Set cr (CmpUL op1 op2));
14135
14136  effect(DEF cr, USE op1, USE op2);
14137
14138  ins_cost(INSN_COST);
14139  format %{ "cmp  $op1, $op2" %}
14140
14141  ins_encode(aarch64_enc_cmp(op1, op2));
14142
14143  ins_pipe(icmp_reg_reg);
14144%}
14145
14146instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero)
14147%{
14148  match(Set cr (CmpUL op1 zero));
14149
14150  effect(DEF cr, USE op1);
14151
14152  ins_cost(INSN_COST);
14153  format %{ "tst  $op1" %}
14154
14155  ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
14156
14157  ins_pipe(icmp_reg_imm);
14158%}
14159
14160instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2)
14161%{
14162  match(Set cr (CmpUL op1 op2));
14163
14164  effect(DEF cr, USE op1);
14165
14166  ins_cost(INSN_COST);
14167  format %{ "cmp  $op1, $op2" %}
14168
14169  ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
14170
14171  ins_pipe(icmp_reg_imm);
14172%}
14173
14174instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2)
14175%{
14176  match(Set cr (CmpUL op1 op2));
14177
14178  effect(DEF cr, USE op1);
14179
14180  ins_cost(INSN_COST * 2);
14181  format %{ "cmp  $op1, $op2" %}
14182
14183  ins_encode(aarch64_enc_cmp_imm(op1, op2));
14184
14185  ins_pipe(icmp_reg_imm);
14186%}
14187
14188instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2)
14189%{
14190  match(Set cr (CmpP op1 op2));
14191
14192  effect(DEF cr, USE op1, USE op2);
14193
14194  ins_cost(INSN_COST);
14195  format %{ "cmp  $op1, $op2\t // ptr" %}
14196
14197  ins_encode(aarch64_enc_cmpp(op1, op2));
14198
14199  ins_pipe(icmp_reg_reg);
14200%}
14201
14202instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2)
14203%{
14204  match(Set cr (CmpN op1 op2));
14205
14206  effect(DEF cr, USE op1, USE op2);
14207
14208  ins_cost(INSN_COST);
14209  format %{ "cmp  $op1, $op2\t // compressed ptr" %}
14210
14211  ins_encode(aarch64_enc_cmpn(op1, op2));
14212
14213  ins_pipe(icmp_reg_reg);
14214%}
14215
14216instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero)
14217%{
14218  match(Set cr (CmpP op1 zero));
14219
14220  effect(DEF cr, USE op1, USE zero);
14221
14222  ins_cost(INSN_COST);
14223  format %{ "cmp  $op1, 0\t // ptr" %}
14224
14225  ins_encode(aarch64_enc_testp(op1));
14226
14227  ins_pipe(icmp_reg_imm);
14228%}
14229
14230instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero)
14231%{
14232  match(Set cr (CmpN op1 zero));
14233
14234  effect(DEF cr, USE op1, USE zero);
14235
14236  ins_cost(INSN_COST);
14237  format %{ "cmp  $op1, 0\t // compressed ptr" %}
14238
14239  ins_encode(aarch64_enc_testn(op1));
14240
14241  ins_pipe(icmp_reg_imm);
14242%}
14243
14244// FP comparisons
14245//
14246// n.b. CmpF/CmpD set a normal flags reg which then gets compared
14247// using normal cmpOp. See declaration of rFlagsReg for details.
14248
14249instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2)
14250%{
14251  match(Set cr (CmpF src1 src2));
14252
14253  ins_cost(3 * INSN_COST);
14254  format %{ "fcmps $src1, $src2" %}
14255
14256  ins_encode %{
14257    __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
14258  %}
14259
14260  ins_pipe(pipe_class_compare);
14261%}
14262
14263instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2)
14264%{
14265  match(Set cr (CmpF src1 src2));
14266
14267  ins_cost(3 * INSN_COST);
14268  format %{ "fcmps $src1, 0.0" %}
14269
14270  ins_encode %{
14271    __ fcmps(as_FloatRegister($src1$$reg), 0.0);
14272  %}
14273
14274  ins_pipe(pipe_class_compare);
14275%}
14276// FROM HERE
14277
14278instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2)
14279%{
14280  match(Set cr (CmpD src1 src2));
14281
14282  ins_cost(3 * INSN_COST);
14283  format %{ "fcmpd $src1, $src2" %}
14284
14285  ins_encode %{
14286    __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
14287  %}
14288
14289  ins_pipe(pipe_class_compare);
14290%}
14291
14292instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2)
14293%{
14294  match(Set cr (CmpD src1 src2));
14295
14296  ins_cost(3 * INSN_COST);
14297  format %{ "fcmpd $src1, 0.0" %}
14298
14299  ins_encode %{
14300    __ fcmpd(as_FloatRegister($src1$$reg), 0.0);
14301  %}
14302
14303  ins_pipe(pipe_class_compare);
14304%}
14305
14306instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr)
14307%{
14308  match(Set dst (CmpF3 src1 src2));
14309  effect(KILL cr);
14310
14311  ins_cost(5 * INSN_COST);
14312  format %{ "fcmps $src1, $src2\n\t"
14313            "csinvw($dst, zr, zr, eq\n\t"
14314            "csnegw($dst, $dst, $dst, lt)"
14315  %}
14316
14317  ins_encode %{
14318    Label done;
14319    FloatRegister s1 = as_FloatRegister($src1$$reg);
14320    FloatRegister s2 = as_FloatRegister($src2$$reg);
14321    Register d = as_Register($dst$$reg);
14322    __ fcmps(s1, s2);
14323    // installs 0 if EQ else -1
14324    __ csinvw(d, zr, zr, Assembler::EQ);
14325    // keeps -1 if less or unordered else installs 1
14326    __ csnegw(d, d, d, Assembler::LT);
14327    __ bind(done);
14328  %}
14329
14330  ins_pipe(pipe_class_default);
14331
14332%}
14333
14334instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr)
14335%{
14336  match(Set dst (CmpD3 src1 src2));
14337  effect(KILL cr);
14338
14339  ins_cost(5 * INSN_COST);
14340  format %{ "fcmpd $src1, $src2\n\t"
14341            "csinvw($dst, zr, zr, eq\n\t"
14342            "csnegw($dst, $dst, $dst, lt)"
14343  %}
14344
14345  ins_encode %{
14346    Label done;
14347    FloatRegister s1 = as_FloatRegister($src1$$reg);
14348    FloatRegister s2 = as_FloatRegister($src2$$reg);
14349    Register d = as_Register($dst$$reg);
14350    __ fcmpd(s1, s2);
14351    // installs 0 if EQ else -1
14352    __ csinvw(d, zr, zr, Assembler::EQ);
14353    // keeps -1 if less or unordered else installs 1
14354    __ csnegw(d, d, d, Assembler::LT);
14355    __ bind(done);
14356  %}
14357  ins_pipe(pipe_class_default);
14358
14359%}
14360
14361instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr)
14362%{
14363  match(Set dst (CmpF3 src1 zero));
14364  effect(KILL cr);
14365
14366  ins_cost(5 * INSN_COST);
14367  format %{ "fcmps $src1, 0.0\n\t"
14368            "csinvw($dst, zr, zr, eq\n\t"
14369            "csnegw($dst, $dst, $dst, lt)"
14370  %}
14371
14372  ins_encode %{
14373    Label done;
14374    FloatRegister s1 = as_FloatRegister($src1$$reg);
14375    Register d = as_Register($dst$$reg);
14376    __ fcmps(s1, 0.0);
14377    // installs 0 if EQ else -1
14378    __ csinvw(d, zr, zr, Assembler::EQ);
14379    // keeps -1 if less or unordered else installs 1
14380    __ csnegw(d, d, d, Assembler::LT);
14381    __ bind(done);
14382  %}
14383
14384  ins_pipe(pipe_class_default);
14385
14386%}
14387
14388instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr)
14389%{
14390  match(Set dst (CmpD3 src1 zero));
14391  effect(KILL cr);
14392
14393  ins_cost(5 * INSN_COST);
14394  format %{ "fcmpd $src1, 0.0\n\t"
14395            "csinvw($dst, zr, zr, eq\n\t"
14396            "csnegw($dst, $dst, $dst, lt)"
14397  %}
14398
14399  ins_encode %{
14400    Label done;
14401    FloatRegister s1 = as_FloatRegister($src1$$reg);
14402    Register d = as_Register($dst$$reg);
14403    __ fcmpd(s1, 0.0);
14404    // installs 0 if EQ else -1
14405    __ csinvw(d, zr, zr, Assembler::EQ);
14406    // keeps -1 if less or unordered else installs 1
14407    __ csnegw(d, d, d, Assembler::LT);
14408    __ bind(done);
14409  %}
14410  ins_pipe(pipe_class_default);
14411
14412%}
14413
14414instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr)
14415%{
14416  match(Set dst (CmpLTMask p q));
14417  effect(KILL cr);
14418
14419  ins_cost(3 * INSN_COST);
14420
14421  format %{ "cmpw $p, $q\t# cmpLTMask\n\t"
14422            "csetw $dst, lt\n\t"
14423            "subw $dst, zr, $dst"
14424  %}
14425
14426  ins_encode %{
14427    __ cmpw(as_Register($p$$reg), as_Register($q$$reg));
14428    __ csetw(as_Register($dst$$reg), Assembler::LT);
14429    __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg));
14430  %}
14431
14432  ins_pipe(ialu_reg_reg);
14433%}
14434
14435instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr)
14436%{
14437  match(Set dst (CmpLTMask src zero));
14438  effect(KILL cr);
14439
14440  ins_cost(INSN_COST);
14441
14442  format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %}
14443
14444  ins_encode %{
14445    __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31);
14446  %}
14447
14448  ins_pipe(ialu_reg_shift);
14449%}
14450
14451// ============================================================================
14452// Max and Min
14453
14454instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
14455%{
14456  effect( DEF dst, USE src1, USE src2, USE cr );
14457
14458  ins_cost(INSN_COST * 2);
14459  format %{ "cselw $dst, $src1, $src2 lt\t"  %}
14460
14461  ins_encode %{
14462    __ cselw(as_Register($dst$$reg),
14463             as_Register($src1$$reg),
14464             as_Register($src2$$reg),
14465             Assembler::LT);
14466  %}
14467
14468  ins_pipe(icond_reg_reg);
14469%}
14470
14471instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2)
14472%{
14473  match(Set dst (MinI src1 src2));
14474  ins_cost(INSN_COST * 3);
14475
14476  expand %{
14477    rFlagsReg cr;
14478    compI_reg_reg(cr, src1, src2);
14479    cmovI_reg_reg_lt(dst, src1, src2, cr);
14480  %}
14481
14482%}
14483// FROM HERE
14484
14485instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
14486%{
14487  effect( DEF dst, USE src1, USE src2, USE cr );
14488
14489  ins_cost(INSN_COST * 2);
14490  format %{ "cselw $dst, $src1, $src2 gt\t"  %}
14491
14492  ins_encode %{
14493    __ cselw(as_Register($dst$$reg),
14494             as_Register($src1$$reg),
14495             as_Register($src2$$reg),
14496             Assembler::GT);
14497  %}
14498
14499  ins_pipe(icond_reg_reg);
14500%}
14501
14502instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2)
14503%{
14504  match(Set dst (MaxI src1 src2));
14505  ins_cost(INSN_COST * 3);
14506  expand %{
14507    rFlagsReg cr;
14508    compI_reg_reg(cr, src1, src2);
14509    cmovI_reg_reg_gt(dst, src1, src2, cr);
14510  %}
14511%}
14512
14513// ============================================================================
14514// Branch Instructions
14515
14516// Direct Branch.
14517instruct branch(label lbl)
14518%{
14519  match(Goto);
14520
14521  effect(USE lbl);
14522
14523  ins_cost(BRANCH_COST);
14524  format %{ "b  $lbl" %}
14525
14526  ins_encode(aarch64_enc_b(lbl));
14527
14528  ins_pipe(pipe_branch);
14529%}
14530
14531// Conditional Near Branch
14532instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl)
14533%{
14534  // Same match rule as `branchConFar'.
14535  match(If cmp cr);
14536
14537  effect(USE lbl);
14538
14539  ins_cost(BRANCH_COST);
14540  // If set to 1 this indicates that the current instruction is a
14541  // short variant of a long branch. This avoids using this
14542  // instruction in first-pass matching. It will then only be used in
14543  // the `Shorten_branches' pass.
14544  // ins_short_branch(1);
14545  format %{ "b$cmp  $lbl" %}
14546
14547  ins_encode(aarch64_enc_br_con(cmp, lbl));
14548
14549  ins_pipe(pipe_branch_cond);
14550%}
14551
14552// Conditional Near Branch Unsigned
14553instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl)
14554%{
14555  // Same match rule as `branchConFar'.
14556  match(If cmp cr);
14557
14558  effect(USE lbl);
14559
14560  ins_cost(BRANCH_COST);
14561  // If set to 1 this indicates that the current instruction is a
14562  // short variant of a long branch. This avoids using this
14563  // instruction in first-pass matching. It will then only be used in
14564  // the `Shorten_branches' pass.
14565  // ins_short_branch(1);
14566  format %{ "b$cmp  $lbl\t# unsigned" %}
14567
14568  ins_encode(aarch64_enc_br_conU(cmp, lbl));
14569
14570  ins_pipe(pipe_branch_cond);
14571%}
14572
14573// Make use of CBZ and CBNZ.  These instructions, as well as being
14574// shorter than (cmp; branch), have the additional benefit of not
14575// killing the flags.
14576
14577instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{
14578  match(If cmp (CmpI op1 op2));
14579  effect(USE labl);
14580
14581  ins_cost(BRANCH_COST);
14582  format %{ "cbw$cmp   $op1, $labl" %}
14583  ins_encode %{
14584    Label* L = $labl$$label;
14585    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14586    if (cond == Assembler::EQ)
14587      __ cbzw($op1$$Register, *L);
14588    else
14589      __ cbnzw($op1$$Register, *L);
14590  %}
14591  ins_pipe(pipe_cmp_branch);
14592%}
14593
14594instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{
14595  match(If cmp (CmpL op1 op2));
14596  effect(USE labl);
14597
14598  ins_cost(BRANCH_COST);
14599  format %{ "cb$cmp   $op1, $labl" %}
14600  ins_encode %{
14601    Label* L = $labl$$label;
14602    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14603    if (cond == Assembler::EQ)
14604      __ cbz($op1$$Register, *L);
14605    else
14606      __ cbnz($op1$$Register, *L);
14607  %}
14608  ins_pipe(pipe_cmp_branch);
14609%}
14610
14611instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{
14612  match(If cmp (CmpP op1 op2));
14613  effect(USE labl);
14614
14615  ins_cost(BRANCH_COST);
14616  format %{ "cb$cmp   $op1, $labl" %}
14617  ins_encode %{
14618    Label* L = $labl$$label;
14619    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14620    if (cond == Assembler::EQ)
14621      __ cbz($op1$$Register, *L);
14622    else
14623      __ cbnz($op1$$Register, *L);
14624  %}
14625  ins_pipe(pipe_cmp_branch);
14626%}
14627
14628instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{
14629  match(If cmp (CmpN op1 op2));
14630  effect(USE labl);
14631
14632  ins_cost(BRANCH_COST);
14633  format %{ "cbw$cmp   $op1, $labl" %}
14634  ins_encode %{
14635    Label* L = $labl$$label;
14636    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14637    if (cond == Assembler::EQ)
14638      __ cbzw($op1$$Register, *L);
14639    else
14640      __ cbnzw($op1$$Register, *L);
14641  %}
14642  ins_pipe(pipe_cmp_branch);
14643%}
14644
14645instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{
14646  match(If cmp (CmpP (DecodeN oop) zero));
14647  effect(USE labl);
14648
14649  ins_cost(BRANCH_COST);
14650  format %{ "cb$cmp   $oop, $labl" %}
14651  ins_encode %{
14652    Label* L = $labl$$label;
14653    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14654    if (cond == Assembler::EQ)
14655      __ cbzw($oop$$Register, *L);
14656    else
14657      __ cbnzw($oop$$Register, *L);
14658  %}
14659  ins_pipe(pipe_cmp_branch);
14660%}
14661
14662instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{
14663  match(If cmp (CmpU op1 op2));
14664  effect(USE labl);
14665
14666  ins_cost(BRANCH_COST);
14667  format %{ "cbw$cmp   $op1, $labl" %}
14668  ins_encode %{
14669    Label* L = $labl$$label;
14670    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14671    if (cond == Assembler::EQ || cond == Assembler::LS)
14672      __ cbzw($op1$$Register, *L);
14673    else
14674      __ cbnzw($op1$$Register, *L);
14675  %}
14676  ins_pipe(pipe_cmp_branch);
14677%}
14678
14679instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{
14680  match(If cmp (CmpUL op1 op2));
14681  effect(USE labl);
14682
14683  ins_cost(BRANCH_COST);
14684  format %{ "cb$cmp   $op1, $labl" %}
14685  ins_encode %{
14686    Label* L = $labl$$label;
14687    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14688    if (cond == Assembler::EQ || cond == Assembler::LS)
14689      __ cbz($op1$$Register, *L);
14690    else
14691      __ cbnz($op1$$Register, *L);
14692  %}
14693  ins_pipe(pipe_cmp_branch);
14694%}
14695
14696// Test bit and Branch
14697
14698// Patterns for short (< 32KiB) variants
14699instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{
14700  match(If cmp (CmpL op1 op2));
14701  effect(USE labl);
14702
14703  ins_cost(BRANCH_COST);
14704  format %{ "cb$cmp   $op1, $labl # long" %}
14705  ins_encode %{
14706    Label* L = $labl$$label;
14707    Assembler::Condition cond =
14708      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
14709    __ tbr(cond, $op1$$Register, 63, *L);
14710  %}
14711  ins_pipe(pipe_cmp_branch);
14712  ins_short_branch(1);
14713%}
14714
14715instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{
14716  match(If cmp (CmpI op1 op2));
14717  effect(USE labl);
14718
14719  ins_cost(BRANCH_COST);
14720  format %{ "cb$cmp   $op1, $labl # int" %}
14721  ins_encode %{
14722    Label* L = $labl$$label;
14723    Assembler::Condition cond =
14724      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
14725    __ tbr(cond, $op1$$Register, 31, *L);
14726  %}
14727  ins_pipe(pipe_cmp_branch);
14728  ins_short_branch(1);
14729%}
14730
14731instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
14732  match(If cmp (CmpL (AndL op1 op2) op3));
14733  predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long()));
14734  effect(USE labl);
14735
14736  ins_cost(BRANCH_COST);
14737  format %{ "tb$cmp   $op1, $op2, $labl" %}
14738  ins_encode %{
14739    Label* L = $labl$$label;
14740    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14741    int bit = exact_log2($op2$$constant);
14742    __ tbr(cond, $op1$$Register, bit, *L);
14743  %}
14744  ins_pipe(pipe_cmp_branch);
14745  ins_short_branch(1);
14746%}
14747
14748instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
14749  match(If cmp (CmpI (AndI op1 op2) op3));
14750  predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int()));
14751  effect(USE labl);
14752
14753  ins_cost(BRANCH_COST);
14754  format %{ "tb$cmp   $op1, $op2, $labl" %}
14755  ins_encode %{
14756    Label* L = $labl$$label;
14757    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14758    int bit = exact_log2($op2$$constant);
14759    __ tbr(cond, $op1$$Register, bit, *L);
14760  %}
14761  ins_pipe(pipe_cmp_branch);
14762  ins_short_branch(1);
14763%}
14764
14765// And far variants
14766instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{
14767  match(If cmp (CmpL op1 op2));
14768  effect(USE labl);
14769
14770  ins_cost(BRANCH_COST);
14771  format %{ "cb$cmp   $op1, $labl # long" %}
14772  ins_encode %{
14773    Label* L = $labl$$label;
14774    Assembler::Condition cond =
14775      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
14776    __ tbr(cond, $op1$$Register, 63, *L, /*far*/true);
14777  %}
14778  ins_pipe(pipe_cmp_branch);
14779%}
14780
14781instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{
14782  match(If cmp (CmpI op1 op2));
14783  effect(USE labl);
14784
14785  ins_cost(BRANCH_COST);
14786  format %{ "cb$cmp   $op1, $labl # int" %}
14787  ins_encode %{
14788    Label* L = $labl$$label;
14789    Assembler::Condition cond =
14790      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
14791    __ tbr(cond, $op1$$Register, 31, *L, /*far*/true);
14792  %}
14793  ins_pipe(pipe_cmp_branch);
14794%}
14795
14796instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
14797  match(If cmp (CmpL (AndL op1 op2) op3));
14798  predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long()));
14799  effect(USE labl);
14800
14801  ins_cost(BRANCH_COST);
14802  format %{ "tb$cmp   $op1, $op2, $labl" %}
14803  ins_encode %{
14804    Label* L = $labl$$label;
14805    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14806    int bit = exact_log2($op2$$constant);
14807    __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
14808  %}
14809  ins_pipe(pipe_cmp_branch);
14810%}
14811
14812instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
14813  match(If cmp (CmpI (AndI op1 op2) op3));
14814  predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int()));
14815  effect(USE labl);
14816
14817  ins_cost(BRANCH_COST);
14818  format %{ "tb$cmp   $op1, $op2, $labl" %}
14819  ins_encode %{
14820    Label* L = $labl$$label;
14821    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14822    int bit = exact_log2($op2$$constant);
14823    __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
14824  %}
14825  ins_pipe(pipe_cmp_branch);
14826%}
14827
14828// Test bits
14829
14830instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{
14831  match(Set cr (CmpL (AndL op1 op2) op3));
14832  predicate(Assembler::operand_valid_for_logical_immediate
14833            (/*is_32*/false, n->in(1)->in(2)->get_long()));
14834
14835  ins_cost(INSN_COST);
14836  format %{ "tst $op1, $op2 # long" %}
14837  ins_encode %{
14838    __ tst($op1$$Register, $op2$$constant);
14839  %}
14840  ins_pipe(ialu_reg_reg);
14841%}
14842
14843instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{
14844  match(Set cr (CmpI (AndI op1 op2) op3));
14845  predicate(Assembler::operand_valid_for_logical_immediate
14846            (/*is_32*/true, n->in(1)->in(2)->get_int()));
14847
14848  ins_cost(INSN_COST);
14849  format %{ "tst $op1, $op2 # int" %}
14850  ins_encode %{
14851    __ tstw($op1$$Register, $op2$$constant);
14852  %}
14853  ins_pipe(ialu_reg_reg);
14854%}
14855
14856instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{
14857  match(Set cr (CmpL (AndL op1 op2) op3));
14858
14859  ins_cost(INSN_COST);
14860  format %{ "tst $op1, $op2 # long" %}
14861  ins_encode %{
14862    __ tst($op1$$Register, $op2$$Register);
14863  %}
14864  ins_pipe(ialu_reg_reg);
14865%}
14866
14867instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{
14868  match(Set cr (CmpI (AndI op1 op2) op3));
14869
14870  ins_cost(INSN_COST);
14871  format %{ "tstw $op1, $op2 # int" %}
14872  ins_encode %{
14873    __ tstw($op1$$Register, $op2$$Register);
14874  %}
14875  ins_pipe(ialu_reg_reg);
14876%}
14877
14878
14879// Conditional Far Branch
14880// Conditional Far Branch Unsigned
14881// TODO: fixme
14882
14883// counted loop end branch near
14884instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl)
14885%{
14886  match(CountedLoopEnd cmp cr);
14887
14888  effect(USE lbl);
14889
14890  ins_cost(BRANCH_COST);
14891  // short variant.
14892  // ins_short_branch(1);
14893  format %{ "b$cmp $lbl \t// counted loop end" %}
14894
14895  ins_encode(aarch64_enc_br_con(cmp, lbl));
14896
14897  ins_pipe(pipe_branch);
14898%}
14899
14900// counted loop end branch near Unsigned
14901instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl)
14902%{
14903  match(CountedLoopEnd cmp cr);
14904
14905  effect(USE lbl);
14906
14907  ins_cost(BRANCH_COST);
14908  // short variant.
14909  // ins_short_branch(1);
14910  format %{ "b$cmp $lbl \t// counted loop end unsigned" %}
14911
14912  ins_encode(aarch64_enc_br_conU(cmp, lbl));
14913
14914  ins_pipe(pipe_branch);
14915%}
14916
14917// counted loop end branch far
14918// counted loop end branch far unsigned
14919// TODO: fixme
14920
14921// ============================================================================
14922// inlined locking and unlocking
14923
14924instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2)
14925%{
14926  match(Set cr (FastLock object box));
14927  effect(TEMP tmp, TEMP tmp2);
14928
14929  // TODO
14930  // identify correct cost
14931  ins_cost(5 * INSN_COST);
14932  format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %}
14933
14934  ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2));
14935
14936  ins_pipe(pipe_serial);
14937%}
14938
14939instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2)
14940%{
14941  match(Set cr (FastUnlock object box));
14942  effect(TEMP tmp, TEMP tmp2);
14943
14944  ins_cost(5 * INSN_COST);
14945  format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %}
14946
14947  ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2));
14948
14949  ins_pipe(pipe_serial);
14950%}
14951
14952
14953// ============================================================================
14954// Safepoint Instructions
14955
14956// TODO
14957// provide a near and far version of this code
14958
14959instruct safePoint(rFlagsReg cr, iRegP poll)
14960%{
14961  match(SafePoint poll);
14962  effect(KILL cr);
14963
14964  format %{
14965    "ldrw zr, [$poll]\t# Safepoint: poll for GC"
14966  %}
14967  ins_encode %{
14968    __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type);
14969  %}
14970  ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem);
14971%}
14972
14973
14974// ============================================================================
14975// Procedure Call/Return Instructions
14976
14977// Call Java Static Instruction
14978
14979instruct CallStaticJavaDirect(method meth)
14980%{
14981  match(CallStaticJava);
14982
14983  effect(USE meth);
14984
14985  ins_cost(CALL_COST);
14986
14987  format %{ "call,static $meth \t// ==> " %}
14988
14989  ins_encode( aarch64_enc_java_static_call(meth),
14990              aarch64_enc_call_epilog );
14991
14992  ins_pipe(pipe_class_call);
14993%}
14994
14995// TO HERE
14996
14997// Call Java Dynamic Instruction
14998instruct CallDynamicJavaDirect(method meth)
14999%{
15000  match(CallDynamicJava);
15001
15002  effect(USE meth);
15003
15004  ins_cost(CALL_COST);
15005
15006  format %{ "CALL,dynamic $meth \t// ==> " %}
15007
15008  ins_encode( aarch64_enc_java_dynamic_call(meth),
15009               aarch64_enc_call_epilog );
15010
15011  ins_pipe(pipe_class_call);
15012%}
15013
15014// Call Runtime Instruction
15015
15016instruct CallRuntimeDirect(method meth)
15017%{
15018  match(CallRuntime);
15019
15020  effect(USE meth);
15021
15022  ins_cost(CALL_COST);
15023
15024  format %{ "CALL, runtime $meth" %}
15025
15026  ins_encode( aarch64_enc_java_to_runtime(meth) );
15027
15028  ins_pipe(pipe_class_call);
15029%}
15030
15031// Call Runtime Instruction
15032
15033instruct CallLeafDirect(method meth)
15034%{
15035  match(CallLeaf);
15036
15037  effect(USE meth);
15038
15039  ins_cost(CALL_COST);
15040
15041  format %{ "CALL, runtime leaf $meth" %}
15042
15043  ins_encode( aarch64_enc_java_to_runtime(meth) );
15044
15045  ins_pipe(pipe_class_call);
15046%}
15047
15048// Call Runtime Instruction
15049
15050instruct CallLeafNoFPDirect(method meth)
15051%{
15052  match(CallLeafNoFP);
15053
15054  effect(USE meth);
15055
15056  ins_cost(CALL_COST);
15057
15058  format %{ "CALL, runtime leaf nofp $meth" %}
15059
15060  ins_encode( aarch64_enc_java_to_runtime(meth) );
15061
15062  ins_pipe(pipe_class_call);
15063%}
15064
15065// Tail Call; Jump from runtime stub to Java code.
15066// Also known as an 'interprocedural jump'.
15067// Target of jump will eventually return to caller.
15068// TailJump below removes the return address.
15069instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop)
15070%{
15071  match(TailCall jump_target method_oop);
15072
15073  ins_cost(CALL_COST);
15074
15075  format %{ "br $jump_target\t# $method_oop holds method oop" %}
15076
15077  ins_encode(aarch64_enc_tail_call(jump_target));
15078
15079  ins_pipe(pipe_class_call);
15080%}
15081
15082instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop)
15083%{
15084  match(TailJump jump_target ex_oop);
15085
15086  ins_cost(CALL_COST);
15087
15088  format %{ "br $jump_target\t# $ex_oop holds exception oop" %}
15089
15090  ins_encode(aarch64_enc_tail_jmp(jump_target));
15091
15092  ins_pipe(pipe_class_call);
15093%}
15094
15095// Create exception oop: created by stack-crawling runtime code.
15096// Created exception is now available to this handler, and is setup
15097// just prior to jumping to this handler. No code emitted.
15098// TODO check
15099// should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1
15100instruct CreateException(iRegP_R0 ex_oop)
15101%{
15102  match(Set ex_oop (CreateEx));
15103
15104  format %{ " -- \t// exception oop; no code emitted" %}
15105
15106  size(0);
15107
15108  ins_encode( /*empty*/ );
15109
15110  ins_pipe(pipe_class_empty);
15111%}
15112
15113// Rethrow exception: The exception oop will come in the first
15114// argument position. Then JUMP (not call) to the rethrow stub code.
15115instruct RethrowException() %{
15116  match(Rethrow);
15117  ins_cost(CALL_COST);
15118
15119  format %{ "b rethrow_stub" %}
15120
15121  ins_encode( aarch64_enc_rethrow() );
15122
15123  ins_pipe(pipe_class_call);
15124%}
15125
15126
15127// Return Instruction
15128// epilog node loads ret address into lr as part of frame pop
15129instruct Ret()
15130%{
15131  match(Return);
15132
15133  format %{ "ret\t// return register" %}
15134
15135  ins_encode( aarch64_enc_ret() );
15136
15137  ins_pipe(pipe_branch);
15138%}
15139
15140// Die now.
15141instruct ShouldNotReachHere() %{
15142  match(Halt);
15143
15144  ins_cost(CALL_COST);
15145  format %{ "ShouldNotReachHere" %}
15146
15147  ins_encode %{
15148    if (is_reachable()) {
15149      __ dpcs1(0xdead + 1);
15150    }
15151  %}
15152
15153  ins_pipe(pipe_class_default);
15154%}
15155
15156// ============================================================================
15157// Partial Subtype Check
15158//
15159// superklass array for an instance of the superklass.  Set a hidden
15160// internal cache on a hit (cache is checked with exposed code in
15161// gen_subtype_check()).  Return NZ for a miss or zero for a hit.  The
15162// encoding ALSO sets flags.
15163
15164instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr)
15165%{
15166  match(Set result (PartialSubtypeCheck sub super));
15167  effect(KILL cr, KILL temp);
15168
15169  ins_cost(1100);  // slightly larger than the next version
15170  format %{ "partialSubtypeCheck $result, $sub, $super" %}
15171
15172  ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
15173
15174  opcode(0x1); // Force zero of result reg on hit
15175
15176  ins_pipe(pipe_class_memory);
15177%}
15178
15179instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr)
15180%{
15181  match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
15182  effect(KILL temp, KILL result);
15183
15184  ins_cost(1100);  // slightly larger than the next version
15185  format %{ "partialSubtypeCheck $result, $sub, $super == 0" %}
15186
15187  ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
15188
15189  opcode(0x0); // Don't zero result reg on hit
15190
15191  ins_pipe(pipe_class_memory);
15192%}
15193
15194instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
15195                        iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
15196%{
15197  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
15198  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
15199  effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
15200
15201  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
15202  ins_encode %{
15203    // Count is in 8-bit bytes; non-Compact chars are 16 bits.
15204    __ string_compare($str1$$Register, $str2$$Register,
15205                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
15206                      $tmp1$$Register, $tmp2$$Register,
15207                      fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU);
15208  %}
15209  ins_pipe(pipe_class_memory);
15210%}
15211
15212instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
15213                        iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
15214%{
15215  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
15216  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
15217  effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
15218
15219  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
15220  ins_encode %{
15221    __ string_compare($str1$$Register, $str2$$Register,
15222                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
15223                      $tmp1$$Register, $tmp2$$Register,
15224                      fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL);
15225  %}
15226  ins_pipe(pipe_class_memory);
15227%}
15228
15229instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
15230                        iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
15231                        vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
15232%{
15233  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
15234  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
15235  effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
15236         USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
15237
15238  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %}
15239  ins_encode %{
15240    __ string_compare($str1$$Register, $str2$$Register,
15241                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
15242                      $tmp1$$Register, $tmp2$$Register,
15243                      $vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
15244                      $vtmp3$$FloatRegister, StrIntrinsicNode::UL);
15245  %}
15246  ins_pipe(pipe_class_memory);
15247%}
15248
15249instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
15250                        iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
15251                        vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
15252%{
15253  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
15254  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
15255  effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
15256         USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
15257
15258  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %}
15259  ins_encode %{
15260    __ string_compare($str1$$Register, $str2$$Register,
15261                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
15262                      $tmp1$$Register, $tmp2$$Register,
15263                      $vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
15264                      $vtmp3$$FloatRegister,StrIntrinsicNode::LU);
15265  %}
15266  ins_pipe(pipe_class_memory);
15267%}
15268
15269instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
15270       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
15271       iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
15272%{
15273  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
15274  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
15275  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
15276         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
15277  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %}
15278
15279  ins_encode %{
15280    __ string_indexof($str1$$Register, $str2$$Register,
15281                      $cnt1$$Register, $cnt2$$Register,
15282                      $tmp1$$Register, $tmp2$$Register,
15283                      $tmp3$$Register, $tmp4$$Register,
15284                      $tmp5$$Register, $tmp6$$Register,
15285                      -1, $result$$Register, StrIntrinsicNode::UU);
15286  %}
15287  ins_pipe(pipe_class_memory);
15288%}
15289
15290instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
15291       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
15292       iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
15293%{
15294  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
15295  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
15296  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
15297         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
15298  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %}
15299
15300  ins_encode %{
15301    __ string_indexof($str1$$Register, $str2$$Register,
15302                      $cnt1$$Register, $cnt2$$Register,
15303                      $tmp1$$Register, $tmp2$$Register,
15304                      $tmp3$$Register, $tmp4$$Register,
15305                      $tmp5$$Register, $tmp6$$Register,
15306                      -1, $result$$Register, StrIntrinsicNode::LL);
15307  %}
15308  ins_pipe(pipe_class_memory);
15309%}
15310
15311instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
15312       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
15313       iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
15314%{
15315  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
15316  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
15317  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
15318         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
15319  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %}
15320
15321  ins_encode %{
15322    __ string_indexof($str1$$Register, $str2$$Register,
15323                      $cnt1$$Register, $cnt2$$Register,
15324                      $tmp1$$Register, $tmp2$$Register,
15325                      $tmp3$$Register, $tmp4$$Register,
15326                      $tmp5$$Register, $tmp6$$Register,
15327                      -1, $result$$Register, StrIntrinsicNode::UL);
15328  %}
15329  ins_pipe(pipe_class_memory);
15330%}
15331
15332instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
15333                 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
15334                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
15335%{
15336  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
15337  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
15338  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
15339         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
15340  format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %}
15341
15342  ins_encode %{
15343    int icnt2 = (int)$int_cnt2$$constant;
15344    __ string_indexof($str1$$Register, $str2$$Register,
15345                      $cnt1$$Register, zr,
15346                      $tmp1$$Register, $tmp2$$Register,
15347                      $tmp3$$Register, $tmp4$$Register, zr, zr,
15348                      icnt2, $result$$Register, StrIntrinsicNode::UU);
15349  %}
15350  ins_pipe(pipe_class_memory);
15351%}
15352
15353instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
15354                 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
15355                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
15356%{
15357  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
15358  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
15359  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
15360         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
15361  format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %}
15362
15363  ins_encode %{
15364    int icnt2 = (int)$int_cnt2$$constant;
15365    __ string_indexof($str1$$Register, $str2$$Register,
15366                      $cnt1$$Register, zr,
15367                      $tmp1$$Register, $tmp2$$Register,
15368                      $tmp3$$Register, $tmp4$$Register, zr, zr,
15369                      icnt2, $result$$Register, StrIntrinsicNode::LL);
15370  %}
15371  ins_pipe(pipe_class_memory);
15372%}
15373
15374instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
15375                 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
15376                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
15377%{
15378  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
15379  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
15380  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
15381         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
15382  format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %}
15383
15384  ins_encode %{
15385    int icnt2 = (int)$int_cnt2$$constant;
15386    __ string_indexof($str1$$Register, $str2$$Register,
15387                      $cnt1$$Register, zr,
15388                      $tmp1$$Register, $tmp2$$Register,
15389                      $tmp3$$Register, $tmp4$$Register, zr, zr,
15390                      icnt2, $result$$Register, StrIntrinsicNode::UL);
15391  %}
15392  ins_pipe(pipe_class_memory);
15393%}
15394
15395instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
15396                              iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
15397                              iRegINoSp tmp3, rFlagsReg cr)
15398%{
15399  match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
15400  effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
15401         TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
15402
15403  format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %}
15404
15405  ins_encode %{
15406    __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
15407                           $result$$Register, $tmp1$$Register, $tmp2$$Register,
15408                           $tmp3$$Register);
15409  %}
15410  ins_pipe(pipe_class_memory);
15411%}
15412
15413instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
15414                        iRegI_R0 result, rFlagsReg cr)
15415%{
15416  predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
15417  match(Set result (StrEquals (Binary str1 str2) cnt));
15418  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
15419
15420  format %{ "String Equals $str1,$str2,$cnt -> $result" %}
15421  ins_encode %{
15422    // Count is in 8-bit bytes; non-Compact chars are 16 bits.
15423    __ string_equals($str1$$Register, $str2$$Register,
15424                     $result$$Register, $cnt$$Register, 1);
15425  %}
15426  ins_pipe(pipe_class_memory);
15427%}
15428
15429instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
15430                        iRegI_R0 result, rFlagsReg cr)
15431%{
15432  predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
15433  match(Set result (StrEquals (Binary str1 str2) cnt));
15434  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
15435
15436  format %{ "String Equals $str1,$str2,$cnt -> $result" %}
15437  ins_encode %{
15438    // Count is in 8-bit bytes; non-Compact chars are 16 bits.
15439    __ string_equals($str1$$Register, $str2$$Register,
15440                     $result$$Register, $cnt$$Register, 2);
15441  %}
15442  ins_pipe(pipe_class_memory);
15443%}
15444
15445instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
15446                       iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3,
15447                       iRegP_R10 tmp, rFlagsReg cr)
15448%{
15449  predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
15450  match(Set result (AryEq ary1 ary2));
15451  effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
15452
15453  format %{ "Array Equals $ary1,ary2 -> $result    // KILL $tmp" %}
15454  ins_encode %{
15455    address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register,
15456                                   $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
15457                                   $result$$Register, $tmp$$Register, 1);
15458    if (tpc == NULL) {
15459      ciEnv::current()->record_failure("CodeCache is full");
15460      return;
15461    }
15462  %}
15463  ins_pipe(pipe_class_memory);
15464%}
15465
15466instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
15467                       iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3,
15468                       iRegP_R10 tmp, rFlagsReg cr)
15469%{
15470  predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
15471  match(Set result (AryEq ary1 ary2));
15472  effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
15473
15474  format %{ "Array Equals $ary1,ary2 -> $result    // KILL $tmp" %}
15475  ins_encode %{
15476    address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register,
15477                                   $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
15478                                   $result$$Register, $tmp$$Register, 2);
15479    if (tpc == NULL) {
15480      ciEnv::current()->record_failure("CodeCache is full");
15481      return;
15482    }
15483  %}
15484  ins_pipe(pipe_class_memory);
15485%}
15486
15487instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr)
15488%{
15489  match(Set result (HasNegatives ary1 len));
15490  effect(USE_KILL ary1, USE_KILL len, KILL cr);
15491  format %{ "has negatives byte[] $ary1,$len -> $result" %}
15492  ins_encode %{
15493    address tpc = __ has_negatives($ary1$$Register, $len$$Register, $result$$Register);
15494    if (tpc == NULL) {
15495      ciEnv::current()->record_failure("CodeCache is full");
15496      return;
15497    }
15498  %}
15499  ins_pipe( pipe_slow );
15500%}
15501
15502// fast char[] to byte[] compression
15503instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
15504                         vRegD_V0 tmp1, vRegD_V1 tmp2,
15505                         vRegD_V2 tmp3, vRegD_V3 tmp4,
15506                         iRegI_R0 result, rFlagsReg cr)
15507%{
15508  match(Set result (StrCompressedCopy src (Binary dst len)));
15509  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
15510
15511  format %{ "String Compress $src,$dst -> $result    // KILL R1, R2, R3, R4" %}
15512  ins_encode %{
15513    __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
15514                           $tmp1$$FloatRegister, $tmp2$$FloatRegister,
15515                           $tmp3$$FloatRegister, $tmp4$$FloatRegister,
15516                           $result$$Register);
15517  %}
15518  ins_pipe( pipe_slow );
15519%}
15520
15521// fast byte[] to char[] inflation
15522instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len,
15523                        vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr)
15524%{
15525  match(Set dummy (StrInflatedCopy src (Binary dst len)));
15526  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
15527
15528  format %{ "String Inflate $src,$dst    // KILL $tmp1, $tmp2" %}
15529  ins_encode %{
15530    address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
15531                                        $tmp1$$FloatRegister, $tmp2$$FloatRegister,
15532                                        $tmp3$$FloatRegister, $tmp4$$Register);
15533    if (tpc == NULL) {
15534      ciEnv::current()->record_failure("CodeCache is full");
15535      return;
15536    }
15537  %}
15538  ins_pipe(pipe_class_memory);
15539%}
15540
15541// encode char[] to byte[] in ISO_8859_1
15542instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
15543                          vRegD_V0 Vtmp1, vRegD_V1 Vtmp2,
15544                          vRegD_V2 Vtmp3, vRegD_V3 Vtmp4,
15545                          iRegI_R0 result, rFlagsReg cr)
15546%{
15547  match(Set result (EncodeISOArray src (Binary dst len)));
15548  effect(USE_KILL src, USE_KILL dst, USE_KILL len,
15549         KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr);
15550
15551  format %{ "Encode array $src,$dst,$len -> $result" %}
15552  ins_encode %{
15553    __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
15554         $result$$Register, $Vtmp1$$FloatRegister,  $Vtmp2$$FloatRegister,
15555         $Vtmp3$$FloatRegister,  $Vtmp4$$FloatRegister);
15556  %}
15557  ins_pipe( pipe_class_memory );
15558%}
15559
15560// ============================================================================
15561// This name is KNOWN by the ADLC and cannot be changed.
15562// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
15563// for this guy.
15564instruct tlsLoadP(thread_RegP dst)
15565%{
15566  match(Set dst (ThreadLocal));
15567
15568  ins_cost(0);
15569
15570  format %{ " -- \t// $dst=Thread::current(), empty" %}
15571
15572  size(0);
15573
15574  ins_encode( /*empty*/ );
15575
15576  ins_pipe(pipe_class_empty);
15577%}
15578
15579// ====================VECTOR INSTRUCTIONS=====================================
15580
15581// Load vector (32 bits)
15582instruct loadV4(vecD dst, vmem4 mem)
15583%{
15584  predicate(n->as_LoadVector()->memory_size() == 4);
15585  match(Set dst (LoadVector mem));
15586  ins_cost(4 * INSN_COST);
15587  format %{ "ldrs   $dst,$mem\t# vector (32 bits)" %}
15588  ins_encode( aarch64_enc_ldrvS(dst, mem) );
15589  ins_pipe(vload_reg_mem64);
15590%}
15591
15592// Load vector (64 bits)
15593instruct loadV8(vecD dst, vmem8 mem)
15594%{
15595  predicate(n->as_LoadVector()->memory_size() == 8);
15596  match(Set dst (LoadVector mem));
15597  ins_cost(4 * INSN_COST);
15598  format %{ "ldrd   $dst,$mem\t# vector (64 bits)" %}
15599  ins_encode( aarch64_enc_ldrvD(dst, mem) );
15600  ins_pipe(vload_reg_mem64);
15601%}
15602
15603// Load Vector (128 bits)
15604instruct loadV16(vecX dst, vmem16 mem)
15605%{
15606  predicate(n->as_LoadVector()->memory_size() == 16);
15607  match(Set dst (LoadVector mem));
15608  ins_cost(4 * INSN_COST);
15609  format %{ "ldrq   $dst,$mem\t# vector (128 bits)" %}
15610  ins_encode( aarch64_enc_ldrvQ(dst, mem) );
15611  ins_pipe(vload_reg_mem128);
15612%}
15613
15614// Store Vector (32 bits)
15615instruct storeV4(vecD src, vmem4 mem)
15616%{
15617  predicate(n->as_StoreVector()->memory_size() == 4);
15618  match(Set mem (StoreVector mem src));
15619  ins_cost(4 * INSN_COST);
15620  format %{ "strs   $mem,$src\t# vector (32 bits)" %}
15621  ins_encode( aarch64_enc_strvS(src, mem) );
15622  ins_pipe(vstore_reg_mem64);
15623%}
15624
15625// Store Vector (64 bits)
15626instruct storeV8(vecD src, vmem8 mem)
15627%{
15628  predicate(n->as_StoreVector()->memory_size() == 8);
15629  match(Set mem (StoreVector mem src));
15630  ins_cost(4 * INSN_COST);
15631  format %{ "strd   $mem,$src\t# vector (64 bits)" %}
15632  ins_encode( aarch64_enc_strvD(src, mem) );
15633  ins_pipe(vstore_reg_mem64);
15634%}
15635
15636// Store Vector (128 bits)
15637instruct storeV16(vecX src, vmem16 mem)
15638%{
15639  predicate(n->as_StoreVector()->memory_size() == 16);
15640  match(Set mem (StoreVector mem src));
15641  ins_cost(4 * INSN_COST);
15642  format %{ "strq   $mem,$src\t# vector (128 bits)" %}
15643  ins_encode( aarch64_enc_strvQ(src, mem) );
15644  ins_pipe(vstore_reg_mem128);
15645%}
15646
15647instruct replicate8B(vecD dst, iRegIorL2I src)
15648%{
15649  predicate(n->as_Vector()->length() == 4 ||
15650            n->as_Vector()->length() == 8);
15651  match(Set dst (ReplicateB src));
15652  ins_cost(INSN_COST);
15653  format %{ "dup  $dst, $src\t# vector (8B)" %}
15654  ins_encode %{
15655    __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg));
15656  %}
15657  ins_pipe(vdup_reg_reg64);
15658%}
15659
15660instruct replicate16B(vecX dst, iRegIorL2I src)
15661%{
15662  predicate(n->as_Vector()->length() == 16);
15663  match(Set dst (ReplicateB src));
15664  ins_cost(INSN_COST);
15665  format %{ "dup  $dst, $src\t# vector (16B)" %}
15666  ins_encode %{
15667    __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg));
15668  %}
15669  ins_pipe(vdup_reg_reg128);
15670%}
15671
15672instruct replicate8B_imm(vecD dst, immI con)
15673%{
15674  predicate(n->as_Vector()->length() == 4 ||
15675            n->as_Vector()->length() == 8);
15676  match(Set dst (ReplicateB con));
15677  ins_cost(INSN_COST);
15678  format %{ "movi  $dst, $con\t# vector(8B)" %}
15679  ins_encode %{
15680    __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff);
15681  %}
15682  ins_pipe(vmovi_reg_imm64);
15683%}
15684
15685instruct replicate16B_imm(vecX dst, immI con)
15686%{
15687  predicate(n->as_Vector()->length() == 16);
15688  match(Set dst (ReplicateB con));
15689  ins_cost(INSN_COST);
15690  format %{ "movi  $dst, $con\t# vector(16B)" %}
15691  ins_encode %{
15692    __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff);
15693  %}
15694  ins_pipe(vmovi_reg_imm128);
15695%}
15696
15697instruct replicate4S(vecD dst, iRegIorL2I src)
15698%{
15699  predicate(n->as_Vector()->length() == 2 ||
15700            n->as_Vector()->length() == 4);
15701  match(Set dst (ReplicateS src));
15702  ins_cost(INSN_COST);
15703  format %{ "dup  $dst, $src\t# vector (4S)" %}
15704  ins_encode %{
15705    __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg));
15706  %}
15707  ins_pipe(vdup_reg_reg64);
15708%}
15709
15710instruct replicate8S(vecX dst, iRegIorL2I src)
15711%{
15712  predicate(n->as_Vector()->length() == 8);
15713  match(Set dst (ReplicateS src));
15714  ins_cost(INSN_COST);
15715  format %{ "dup  $dst, $src\t# vector (8S)" %}
15716  ins_encode %{
15717    __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg));
15718  %}
15719  ins_pipe(vdup_reg_reg128);
15720%}
15721
15722instruct replicate4S_imm(vecD dst, immI con)
15723%{
15724  predicate(n->as_Vector()->length() == 2 ||
15725            n->as_Vector()->length() == 4);
15726  match(Set dst (ReplicateS con));
15727  ins_cost(INSN_COST);
15728  format %{ "movi  $dst, $con\t# vector(4H)" %}
15729  ins_encode %{
15730    __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff);
15731  %}
15732  ins_pipe(vmovi_reg_imm64);
15733%}
15734
15735instruct replicate8S_imm(vecX dst, immI con)
15736%{
15737  predicate(n->as_Vector()->length() == 8);
15738  match(Set dst (ReplicateS con));
15739  ins_cost(INSN_COST);
15740  format %{ "movi  $dst, $con\t# vector(8H)" %}
15741  ins_encode %{
15742    __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff);
15743  %}
15744  ins_pipe(vmovi_reg_imm128);
15745%}
15746
15747instruct replicate2I(vecD dst, iRegIorL2I src)
15748%{
15749  predicate(n->as_Vector()->length() == 2);
15750  match(Set dst (ReplicateI src));
15751  ins_cost(INSN_COST);
15752  format %{ "dup  $dst, $src\t# vector (2I)" %}
15753  ins_encode %{
15754    __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg));
15755  %}
15756  ins_pipe(vdup_reg_reg64);
15757%}
15758
15759instruct replicate4I(vecX dst, iRegIorL2I src)
15760%{
15761  predicate(n->as_Vector()->length() == 4);
15762  match(Set dst (ReplicateI src));
15763  ins_cost(INSN_COST);
15764  format %{ "dup  $dst, $src\t# vector (4I)" %}
15765  ins_encode %{
15766    __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg));
15767  %}
15768  ins_pipe(vdup_reg_reg128);
15769%}
15770
15771instruct replicate2I_imm(vecD dst, immI con)
15772%{
15773  predicate(n->as_Vector()->length() == 2);
15774  match(Set dst (ReplicateI con));
15775  ins_cost(INSN_COST);
15776  format %{ "movi  $dst, $con\t# vector(2I)" %}
15777  ins_encode %{
15778    __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant);
15779  %}
15780  ins_pipe(vmovi_reg_imm64);
15781%}
15782
15783instruct replicate4I_imm(vecX dst, immI con)
15784%{
15785  predicate(n->as_Vector()->length() == 4);
15786  match(Set dst (ReplicateI con));
15787  ins_cost(INSN_COST);
15788  format %{ "movi  $dst, $con\t# vector(4I)" %}
15789  ins_encode %{
15790    __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant);
15791  %}
15792  ins_pipe(vmovi_reg_imm128);
15793%}
15794
15795instruct replicate2L(vecX dst, iRegL src)
15796%{
15797  predicate(n->as_Vector()->length() == 2);
15798  match(Set dst (ReplicateL src));
15799  ins_cost(INSN_COST);
15800  format %{ "dup  $dst, $src\t# vector (2L)" %}
15801  ins_encode %{
15802    __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg));
15803  %}
15804  ins_pipe(vdup_reg_reg128);
15805%}
15806
15807instruct replicate2L_zero(vecX dst, immI0 zero)
15808%{
15809  predicate(n->as_Vector()->length() == 2);
15810  match(Set dst (ReplicateI zero));
15811  ins_cost(INSN_COST);
15812  format %{ "movi  $dst, $zero\t# vector(4I)" %}
15813  ins_encode %{
15814    __ eor(as_FloatRegister($dst$$reg), __ T16B,
15815           as_FloatRegister($dst$$reg),
15816           as_FloatRegister($dst$$reg));
15817  %}
15818  ins_pipe(vmovi_reg_imm128);
15819%}
15820
15821instruct replicate2F(vecD dst, vRegF src)
15822%{
15823  predicate(n->as_Vector()->length() == 2);
15824  match(Set dst (ReplicateF src));
15825  ins_cost(INSN_COST);
15826  format %{ "dup  $dst, $src\t# vector (2F)" %}
15827  ins_encode %{
15828    __ dup(as_FloatRegister($dst$$reg), __ T2S,
15829           as_FloatRegister($src$$reg));
15830  %}
15831  ins_pipe(vdup_reg_freg64);
15832%}
15833
15834instruct replicate4F(vecX dst, vRegF src)
15835%{
15836  predicate(n->as_Vector()->length() == 4);
15837  match(Set dst (ReplicateF src));
15838  ins_cost(INSN_COST);
15839  format %{ "dup  $dst, $src\t# vector (4F)" %}
15840  ins_encode %{
15841    __ dup(as_FloatRegister($dst$$reg), __ T4S,
15842           as_FloatRegister($src$$reg));
15843  %}
15844  ins_pipe(vdup_reg_freg128);
15845%}
15846
15847instruct replicate2D(vecX dst, vRegD src)
15848%{
15849  predicate(n->as_Vector()->length() == 2);
15850  match(Set dst (ReplicateD src));
15851  ins_cost(INSN_COST);
15852  format %{ "dup  $dst, $src\t# vector (2D)" %}
15853  ins_encode %{
15854    __ dup(as_FloatRegister($dst$$reg), __ T2D,
15855           as_FloatRegister($src$$reg));
15856  %}
15857  ins_pipe(vdup_reg_dreg128);
15858%}
15859
15860// ====================REDUCTION ARITHMETIC====================================
15861
15862instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2)
15863%{
15864  match(Set dst (AddReductionVI src1 src2));
15865  ins_cost(INSN_COST);
15866  effect(TEMP tmp, TEMP tmp2);
15867  format %{ "umov  $tmp, $src2, S, 0\n\t"
15868            "umov  $tmp2, $src2, S, 1\n\t"
15869            "addw  $tmp, $src1, $tmp\n\t"
15870            "addw  $dst, $tmp, $tmp2\t# add reduction2I"
15871  %}
15872  ins_encode %{
15873    __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0);
15874    __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1);
15875    __ addw($tmp$$Register, $src1$$Register, $tmp$$Register);
15876    __ addw($dst$$Register, $tmp$$Register, $tmp2$$Register);
15877  %}
15878  ins_pipe(pipe_class_default);
15879%}
15880
15881instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2)
15882%{
15883  match(Set dst (AddReductionVI src1 src2));
15884  ins_cost(INSN_COST);
15885  effect(TEMP tmp, TEMP tmp2);
15886  format %{ "addv  $tmp, T4S, $src2\n\t"
15887            "umov  $tmp2, $tmp, S, 0\n\t"
15888            "addw  $dst, $tmp2, $src1\t# add reduction4I"
15889  %}
15890  ins_encode %{
15891    __ addv(as_FloatRegister($tmp$$reg), __ T4S,
15892            as_FloatRegister($src2$$reg));
15893    __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0);
15894    __ addw($dst$$Register, $tmp2$$Register, $src1$$Register);
15895  %}
15896  ins_pipe(pipe_class_default);
15897%}
15898
15899instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp)
15900%{
15901  match(Set dst (MulReductionVI src1 src2));
15902  ins_cost(INSN_COST);
15903  effect(TEMP tmp, TEMP dst);
15904  format %{ "umov  $tmp, $src2, S, 0\n\t"
15905            "mul   $dst, $tmp, $src1\n\t"
15906            "umov  $tmp, $src2, S, 1\n\t"
15907            "mul   $dst, $tmp, $dst\t# mul reduction2I"
15908  %}
15909  ins_encode %{
15910    __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0);
15911    __ mul($dst$$Register, $tmp$$Register, $src1$$Register);
15912    __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1);
15913    __ mul($dst$$Register, $tmp$$Register, $dst$$Register);
15914  %}
15915  ins_pipe(pipe_class_default);
15916%}
15917
15918instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2)
15919%{
15920  match(Set dst (MulReductionVI src1 src2));
15921  ins_cost(INSN_COST);
15922  effect(TEMP tmp, TEMP tmp2, TEMP dst);
15923  format %{ "ins   $tmp, $src2, 0, 1\n\t"
15924            "mul   $tmp, $tmp, $src2\n\t"
15925            "umov  $tmp2, $tmp, S, 0\n\t"
15926            "mul   $dst, $tmp2, $src1\n\t"
15927            "umov  $tmp2, $tmp, S, 1\n\t"
15928            "mul   $dst, $tmp2, $dst\t# mul reduction4I"
15929  %}
15930  ins_encode %{
15931    __ ins(as_FloatRegister($tmp$$reg), __ D,
15932           as_FloatRegister($src2$$reg), 0, 1);
15933    __ mulv(as_FloatRegister($tmp$$reg), __ T2S,
15934           as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg));
15935    __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0);
15936    __ mul($dst$$Register, $tmp2$$Register, $src1$$Register);
15937    __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1);
15938    __ mul($dst$$Register, $tmp2$$Register, $dst$$Register);
15939  %}
15940  ins_pipe(pipe_class_default);
15941%}
15942
15943instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp)
15944%{
15945  match(Set dst (AddReductionVF src1 src2));
15946  ins_cost(INSN_COST);
15947  effect(TEMP tmp, TEMP dst);
15948  format %{ "fadds $dst, $src1, $src2\n\t"
15949            "ins   $tmp, S, $src2, 0, 1\n\t"
15950            "fadds $dst, $dst, $tmp\t# add reduction2F"
15951  %}
15952  ins_encode %{
15953    __ fadds(as_FloatRegister($dst$$reg),
15954             as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15955    __ ins(as_FloatRegister($tmp$$reg), __ S,
15956           as_FloatRegister($src2$$reg), 0, 1);
15957    __ fadds(as_FloatRegister($dst$$reg),
15958             as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15959  %}
15960  ins_pipe(pipe_class_default);
15961%}
15962
15963instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp)
15964%{
15965  match(Set dst (AddReductionVF src1 src2));
15966  ins_cost(INSN_COST);
15967  effect(TEMP tmp, TEMP dst);
15968  format %{ "fadds $dst, $src1, $src2\n\t"
15969            "ins   $tmp, S, $src2, 0, 1\n\t"
15970            "fadds $dst, $dst, $tmp\n\t"
15971            "ins   $tmp, S, $src2, 0, 2\n\t"
15972            "fadds $dst, $dst, $tmp\n\t"
15973            "ins   $tmp, S, $src2, 0, 3\n\t"
15974            "fadds $dst, $dst, $tmp\t# add reduction4F"
15975  %}
15976  ins_encode %{
15977    __ fadds(as_FloatRegister($dst$$reg),
15978             as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15979    __ ins(as_FloatRegister($tmp$$reg), __ S,
15980           as_FloatRegister($src2$$reg), 0, 1);
15981    __ fadds(as_FloatRegister($dst$$reg),
15982             as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15983    __ ins(as_FloatRegister($tmp$$reg), __ S,
15984           as_FloatRegister($src2$$reg), 0, 2);
15985    __ fadds(as_FloatRegister($dst$$reg),
15986             as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15987    __ ins(as_FloatRegister($tmp$$reg), __ S,
15988           as_FloatRegister($src2$$reg), 0, 3);
15989    __ fadds(as_FloatRegister($dst$$reg),
15990             as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15991  %}
15992  ins_pipe(pipe_class_default);
15993%}
15994
15995instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp)
15996%{
15997  match(Set dst (MulReductionVF src1 src2));
15998  ins_cost(INSN_COST);
15999  effect(TEMP tmp, TEMP dst);
16000  format %{ "fmuls $dst, $src1, $src2\n\t"
16001            "ins   $tmp, S, $src2, 0, 1\n\t"
16002            "fmuls $dst, $dst, $tmp\t# mul reduction2F"
16003  %}
16004  ins_encode %{
16005    __ fmuls(as_FloatRegister($dst$$reg),
16006             as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
16007    __ ins(as_FloatRegister($tmp$$reg), __ S,
16008           as_FloatRegister($src2$$reg), 0, 1);
16009    __ fmuls(as_FloatRegister($dst$$reg),
16010             as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
16011  %}
16012  ins_pipe(pipe_class_default);
16013%}
16014
16015instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp)
16016%{
16017  match(Set dst (MulReductionVF src1 src2));
16018  ins_cost(INSN_COST);
16019  effect(TEMP tmp, TEMP dst);
16020  format %{ "fmuls $dst, $src1, $src2\n\t"
16021            "ins   $tmp, S, $src2, 0, 1\n\t"
16022            "fmuls $dst, $dst, $tmp\n\t"
16023            "ins   $tmp, S, $src2, 0, 2\n\t"
16024            "fmuls $dst, $dst, $tmp\n\t"
16025            "ins   $tmp, S, $src2, 0, 3\n\t"
16026            "fmuls $dst, $dst, $tmp\t# mul reduction4F"
16027  %}
16028  ins_encode %{
16029    __ fmuls(as_FloatRegister($dst$$reg),
16030             as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
16031    __ ins(as_FloatRegister($tmp$$reg), __ S,
16032           as_FloatRegister($src2$$reg), 0, 1);
16033    __ fmuls(as_FloatRegister($dst$$reg),
16034             as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
16035    __ ins(as_FloatRegister($tmp$$reg), __ S,
16036           as_FloatRegister($src2$$reg), 0, 2);
16037    __ fmuls(as_FloatRegister($dst$$reg),
16038             as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
16039    __ ins(as_FloatRegister($tmp$$reg), __ S,
16040           as_FloatRegister($src2$$reg), 0, 3);
16041    __ fmuls(as_FloatRegister($dst$$reg),
16042             as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
16043  %}
16044  ins_pipe(pipe_class_default);
16045%}
16046
16047instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp)
16048%{
16049  match(Set dst (AddReductionVD src1 src2));
16050  ins_cost(INSN_COST);
16051  effect(TEMP tmp, TEMP dst);
16052  format %{ "faddd $dst, $src1, $src2\n\t"
16053            "ins   $tmp, D, $src2, 0, 1\n\t"
16054            "faddd $dst, $dst, $tmp\t# add reduction2D"
16055  %}
16056  ins_encode %{
16057    __ faddd(as_FloatRegister($dst$$reg),
16058             as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
16059    __ ins(as_FloatRegister($tmp$$reg), __ D,
16060           as_FloatRegister($src2$$reg), 0, 1);
16061    __ faddd(as_FloatRegister($dst$$reg),
16062             as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
16063  %}
16064  ins_pipe(pipe_class_default);
16065%}
16066
16067instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp)
16068%{
16069  match(Set dst (MulReductionVD src1 src2));
16070  ins_cost(INSN_COST);
16071  effect(TEMP tmp, TEMP dst);
16072  format %{ "fmuld $dst, $src1, $src2\n\t"
16073            "ins   $tmp, D, $src2, 0, 1\n\t"
16074            "fmuld $dst, $dst, $tmp\t# mul reduction2D"
16075  %}
16076  ins_encode %{
16077    __ fmuld(as_FloatRegister($dst$$reg),
16078             as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
16079    __ ins(as_FloatRegister($tmp$$reg), __ D,
16080           as_FloatRegister($src2$$reg), 0, 1);
16081    __ fmuld(as_FloatRegister($dst$$reg),
16082             as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
16083  %}
16084  ins_pipe(pipe_class_default);
16085%}
16086
16087instruct reduce_max2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{
16088  predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
16089  match(Set dst (MaxReductionV src1 src2));
16090  ins_cost(INSN_COST);
16091  effect(TEMP_DEF dst, TEMP tmp);
16092  format %{ "fmaxs $dst, $src1, $src2\n\t"
16093            "ins   $tmp, S, $src2, 0, 1\n\t"
16094            "fmaxs $dst, $dst, $tmp\t# max reduction2F" %}
16095  ins_encode %{
16096    __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
16097    __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1);
16098    __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
16099  %}
16100  ins_pipe(pipe_class_default);
16101%}
16102
16103instruct reduce_max4F(vRegF dst, vRegF src1, vecX src2) %{
16104  predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
16105  match(Set dst (MaxReductionV src1 src2));
16106  ins_cost(INSN_COST);
16107  effect(TEMP_DEF dst);
16108  format %{ "fmaxv $dst, T4S, $src2\n\t"
16109            "fmaxs $dst, $dst, $src1\t# max reduction4F" %}
16110  ins_encode %{
16111    __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg));
16112    __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg));
16113  %}
16114  ins_pipe(pipe_class_default);
16115%}
16116
16117instruct reduce_max2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{
16118  predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
16119  match(Set dst (MaxReductionV src1 src2));
16120  ins_cost(INSN_COST);
16121  effect(TEMP_DEF dst, TEMP tmp);
16122  format %{ "fmaxd $dst, $src1, $src2\n\t"
16123            "ins   $tmp, D, $src2, 0, 1\n\t"
16124            "fmaxd $dst, $dst, $tmp\t# max reduction2D" %}
16125  ins_encode %{
16126    __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
16127    __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1);
16128    __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
16129  %}
16130  ins_pipe(pipe_class_default);
16131%}
16132
16133instruct reduce_min2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{
16134  predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
16135  match(Set dst (MinReductionV src1 src2));
16136  ins_cost(INSN_COST);
16137  effect(TEMP_DEF dst, TEMP tmp);
16138  format %{ "fmins $dst, $src1, $src2\n\t"
16139            "ins   $tmp, S, $src2, 0, 1\n\t"
16140            "fmins $dst, $dst, $tmp\t# min reduction2F" %}
16141  ins_encode %{
16142    __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
16143    __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1);
16144    __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
16145  %}
16146  ins_pipe(pipe_class_default);
16147%}
16148
16149instruct reduce_min4F(vRegF dst, vRegF src1, vecX src2) %{
16150  predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
16151  match(Set dst (MinReductionV src1 src2));
16152  ins_cost(INSN_COST);
16153  effect(TEMP_DEF dst);
16154  format %{ "fminv $dst, T4S, $src2\n\t"
16155            "fmins $dst, $dst, $src1\t# min reduction4F" %}
16156  ins_encode %{
16157    __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg));
16158    __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg));
16159  %}
16160  ins_pipe(pipe_class_default);
16161%}
16162
16163instruct reduce_min2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{
16164  predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
16165  match(Set dst (MinReductionV src1 src2));
16166  ins_cost(INSN_COST);
16167  effect(TEMP_DEF dst, TEMP tmp);
16168  format %{ "fmind $dst, $src1, $src2\n\t"
16169            "ins   $tmp, D, $src2, 0, 1\n\t"
16170            "fmind $dst, $dst, $tmp\t# min reduction2D" %}
16171  ins_encode %{
16172    __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
16173    __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1);
16174    __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
16175  %}
16176  ins_pipe(pipe_class_default);
16177%}
16178
16179// ====================VECTOR ARITHMETIC=======================================
16180
16181// --------------------------------- ADD --------------------------------------
16182
16183instruct vadd8B(vecD dst, vecD src1, vecD src2)
16184%{
16185  predicate(n->as_Vector()->length() == 4 ||
16186            n->as_Vector()->length() == 8);
16187  match(Set dst (AddVB src1 src2));
16188  ins_cost(INSN_COST);
16189  format %{ "addv  $dst,$src1,$src2\t# vector (8B)" %}
16190  ins_encode %{
16191    __ addv(as_FloatRegister($dst$$reg), __ T8B,
16192            as_FloatRegister($src1$$reg),
16193            as_FloatRegister($src2$$reg));
16194  %}
16195  ins_pipe(vdop64);
16196%}
16197
16198instruct vadd16B(vecX dst, vecX src1, vecX src2)
16199%{
16200  predicate(n->as_Vector()->length() == 16);
16201  match(Set dst (AddVB src1 src2));
16202  ins_cost(INSN_COST);
16203  format %{ "addv  $dst,$src1,$src2\t# vector (16B)" %}
16204  ins_encode %{
16205    __ addv(as_FloatRegister($dst$$reg), __ T16B,
16206            as_FloatRegister($src1$$reg),
16207            as_FloatRegister($src2$$reg));
16208  %}
16209  ins_pipe(vdop128);
16210%}
16211
16212instruct vadd4S(vecD dst, vecD src1, vecD src2)
16213%{
16214  predicate(n->as_Vector()->length() == 2 ||
16215            n->as_Vector()->length() == 4);
16216  match(Set dst (AddVS src1 src2));
16217  ins_cost(INSN_COST);
16218  format %{ "addv  $dst,$src1,$src2\t# vector (4H)" %}
16219  ins_encode %{
16220    __ addv(as_FloatRegister($dst$$reg), __ T4H,
16221            as_FloatRegister($src1$$reg),
16222            as_FloatRegister($src2$$reg));
16223  %}
16224  ins_pipe(vdop64);
16225%}
16226
16227instruct vadd8S(vecX dst, vecX src1, vecX src2)
16228%{
16229  predicate(n->as_Vector()->length() == 8);
16230  match(Set dst (AddVS src1 src2));
16231  ins_cost(INSN_COST);
16232  format %{ "addv  $dst,$src1,$src2\t# vector (8H)" %}
16233  ins_encode %{
16234    __ addv(as_FloatRegister($dst$$reg), __ T8H,
16235            as_FloatRegister($src1$$reg),
16236            as_FloatRegister($src2$$reg));
16237  %}
16238  ins_pipe(vdop128);
16239%}
16240
16241instruct vadd2I(vecD dst, vecD src1, vecD src2)
16242%{
16243  predicate(n->as_Vector()->length() == 2);
16244  match(Set dst (AddVI src1 src2));
16245  ins_cost(INSN_COST);
16246  format %{ "addv  $dst,$src1,$src2\t# vector (2S)" %}
16247  ins_encode %{
16248    __ addv(as_FloatRegister($dst$$reg), __ T2S,
16249            as_FloatRegister($src1$$reg),
16250            as_FloatRegister($src2$$reg));
16251  %}
16252  ins_pipe(vdop64);
16253%}
16254
16255instruct vadd4I(vecX dst, vecX src1, vecX src2)
16256%{
16257  predicate(n->as_Vector()->length() == 4);
16258  match(Set dst (AddVI src1 src2));
16259  ins_cost(INSN_COST);
16260  format %{ "addv  $dst,$src1,$src2\t# vector (4S)" %}
16261  ins_encode %{
16262    __ addv(as_FloatRegister($dst$$reg), __ T4S,
16263            as_FloatRegister($src1$$reg),
16264            as_FloatRegister($src2$$reg));
16265  %}
16266  ins_pipe(vdop128);
16267%}
16268
16269instruct vadd2L(vecX dst, vecX src1, vecX src2)
16270%{
16271  predicate(n->as_Vector()->length() == 2);
16272  match(Set dst (AddVL src1 src2));
16273  ins_cost(INSN_COST);
16274  format %{ "addv  $dst,$src1,$src2\t# vector (2L)" %}
16275  ins_encode %{
16276    __ addv(as_FloatRegister($dst$$reg), __ T2D,
16277            as_FloatRegister($src1$$reg),
16278            as_FloatRegister($src2$$reg));
16279  %}
16280  ins_pipe(vdop128);
16281%}
16282
16283instruct vadd2F(vecD dst, vecD src1, vecD src2)
16284%{
16285  predicate(n->as_Vector()->length() == 2);
16286  match(Set dst (AddVF src1 src2));
16287  ins_cost(INSN_COST);
16288  format %{ "fadd  $dst,$src1,$src2\t# vector (2S)" %}
16289  ins_encode %{
16290    __ fadd(as_FloatRegister($dst$$reg), __ T2S,
16291            as_FloatRegister($src1$$reg),
16292            as_FloatRegister($src2$$reg));
16293  %}
16294  ins_pipe(vdop_fp64);
16295%}
16296
16297instruct vadd4F(vecX dst, vecX src1, vecX src2)
16298%{
16299  predicate(n->as_Vector()->length() == 4);
16300  match(Set dst (AddVF src1 src2));
16301  ins_cost(INSN_COST);
16302  format %{ "fadd  $dst,$src1,$src2\t# vector (4S)" %}
16303  ins_encode %{
16304    __ fadd(as_FloatRegister($dst$$reg), __ T4S,
16305            as_FloatRegister($src1$$reg),
16306            as_FloatRegister($src2$$reg));
16307  %}
16308  ins_pipe(vdop_fp128);
16309%}
16310
16311instruct vadd2D(vecX dst, vecX src1, vecX src2)
16312%{
16313  match(Set dst (AddVD src1 src2));
16314  ins_cost(INSN_COST);
16315  format %{ "fadd  $dst,$src1,$src2\t# vector (2D)" %}
16316  ins_encode %{
16317    __ fadd(as_FloatRegister($dst$$reg), __ T2D,
16318            as_FloatRegister($src1$$reg),
16319            as_FloatRegister($src2$$reg));
16320  %}
16321  ins_pipe(vdop_fp128);
16322%}
16323
16324// --------------------------------- SUB --------------------------------------
16325
16326instruct vsub8B(vecD dst, vecD src1, vecD src2)
16327%{
16328  predicate(n->as_Vector()->length() == 4 ||
16329            n->as_Vector()->length() == 8);
16330  match(Set dst (SubVB src1 src2));
16331  ins_cost(INSN_COST);
16332  format %{ "subv  $dst,$src1,$src2\t# vector (8B)" %}
16333  ins_encode %{
16334    __ subv(as_FloatRegister($dst$$reg), __ T8B,
16335            as_FloatRegister($src1$$reg),
16336            as_FloatRegister($src2$$reg));
16337  %}
16338  ins_pipe(vdop64);
16339%}
16340
16341instruct vsub16B(vecX dst, vecX src1, vecX src2)
16342%{
16343  predicate(n->as_Vector()->length() == 16);
16344  match(Set dst (SubVB src1 src2));
16345  ins_cost(INSN_COST);
16346  format %{ "subv  $dst,$src1,$src2\t# vector (16B)" %}
16347  ins_encode %{
16348    __ subv(as_FloatRegister($dst$$reg), __ T16B,
16349            as_FloatRegister($src1$$reg),
16350            as_FloatRegister($src2$$reg));
16351  %}
16352  ins_pipe(vdop128);
16353%}
16354
16355instruct vsub4S(vecD dst, vecD src1, vecD src2)
16356%{
16357  predicate(n->as_Vector()->length() == 2 ||
16358            n->as_Vector()->length() == 4);
16359  match(Set dst (SubVS src1 src2));
16360  ins_cost(INSN_COST);
16361  format %{ "subv  $dst,$src1,$src2\t# vector (4H)" %}
16362  ins_encode %{
16363    __ subv(as_FloatRegister($dst$$reg), __ T4H,
16364            as_FloatRegister($src1$$reg),
16365            as_FloatRegister($src2$$reg));
16366  %}
16367  ins_pipe(vdop64);
16368%}
16369
16370instruct vsub8S(vecX dst, vecX src1, vecX src2)
16371%{
16372  predicate(n->as_Vector()->length() == 8);
16373  match(Set dst (SubVS src1 src2));
16374  ins_cost(INSN_COST);
16375  format %{ "subv  $dst,$src1,$src2\t# vector (8H)" %}
16376  ins_encode %{
16377    __ subv(as_FloatRegister($dst$$reg), __ T8H,
16378            as_FloatRegister($src1$$reg),
16379            as_FloatRegister($src2$$reg));
16380  %}
16381  ins_pipe(vdop128);
16382%}
16383
16384instruct vsub2I(vecD dst, vecD src1, vecD src2)
16385%{
16386  predicate(n->as_Vector()->length() == 2);
16387  match(Set dst (SubVI src1 src2));
16388  ins_cost(INSN_COST);
16389  format %{ "subv  $dst,$src1,$src2\t# vector (2S)" %}
16390  ins_encode %{
16391    __ subv(as_FloatRegister($dst$$reg), __ T2S,
16392            as_FloatRegister($src1$$reg),
16393            as_FloatRegister($src2$$reg));
16394  %}
16395  ins_pipe(vdop64);
16396%}
16397
16398instruct vsub4I(vecX dst, vecX src1, vecX src2)
16399%{
16400  predicate(n->as_Vector()->length() == 4);
16401  match(Set dst (SubVI src1 src2));
16402  ins_cost(INSN_COST);
16403  format %{ "subv  $dst,$src1,$src2\t# vector (4S)" %}
16404  ins_encode %{
16405    __ subv(as_FloatRegister($dst$$reg), __ T4S,
16406            as_FloatRegister($src1$$reg),
16407            as_FloatRegister($src2$$reg));
16408  %}
16409  ins_pipe(vdop128);
16410%}
16411
16412instruct vsub2L(vecX dst, vecX src1, vecX src2)
16413%{
16414  predicate(n->as_Vector()->length() == 2);
16415  match(Set dst (SubVL src1 src2));
16416  ins_cost(INSN_COST);
16417  format %{ "subv  $dst,$src1,$src2\t# vector (2L)" %}
16418  ins_encode %{
16419    __ subv(as_FloatRegister($dst$$reg), __ T2D,
16420            as_FloatRegister($src1$$reg),
16421            as_FloatRegister($src2$$reg));
16422  %}
16423  ins_pipe(vdop128);
16424%}
16425
16426instruct vsub2F(vecD dst, vecD src1, vecD src2)
16427%{
16428  predicate(n->as_Vector()->length() == 2);
16429  match(Set dst (SubVF src1 src2));
16430  ins_cost(INSN_COST);
16431  format %{ "fsub  $dst,$src1,$src2\t# vector (2S)" %}
16432  ins_encode %{
16433    __ fsub(as_FloatRegister($dst$$reg), __ T2S,
16434            as_FloatRegister($src1$$reg),
16435            as_FloatRegister($src2$$reg));
16436  %}
16437  ins_pipe(vdop_fp64);
16438%}
16439
16440instruct vsub4F(vecX dst, vecX src1, vecX src2)
16441%{
16442  predicate(n->as_Vector()->length() == 4);
16443  match(Set dst (SubVF src1 src2));
16444  ins_cost(INSN_COST);
16445  format %{ "fsub  $dst,$src1,$src2\t# vector (4S)" %}
16446  ins_encode %{
16447    __ fsub(as_FloatRegister($dst$$reg), __ T4S,
16448            as_FloatRegister($src1$$reg),
16449            as_FloatRegister($src2$$reg));
16450  %}
16451  ins_pipe(vdop_fp128);
16452%}
16453
16454instruct vsub2D(vecX dst, vecX src1, vecX src2)
16455%{
16456  predicate(n->as_Vector()->length() == 2);
16457  match(Set dst (SubVD src1 src2));
16458  ins_cost(INSN_COST);
16459  format %{ "fsub  $dst,$src1,$src2\t# vector (2D)" %}
16460  ins_encode %{
16461    __ fsub(as_FloatRegister($dst$$reg), __ T2D,
16462            as_FloatRegister($src1$$reg),
16463            as_FloatRegister($src2$$reg));
16464  %}
16465  ins_pipe(vdop_fp128);
16466%}
16467
16468// --------------------------------- MUL --------------------------------------
16469
16470instruct vmul8B(vecD dst, vecD src1, vecD src2)
16471%{
16472  predicate(n->as_Vector()->length() == 4 ||
16473            n->as_Vector()->length() == 8);
16474  match(Set dst (MulVB src1 src2));
16475  ins_cost(INSN_COST);
16476  format %{ "mulv  $dst,$src1,$src2\t# vector (8B)" %}
16477  ins_encode %{
16478    __ mulv(as_FloatRegister($dst$$reg), __ T8B,
16479            as_FloatRegister($src1$$reg),
16480            as_FloatRegister($src2$$reg));
16481  %}
16482  ins_pipe(vmul64);
16483%}
16484
16485instruct vmul16B(vecX dst, vecX src1, vecX src2)
16486%{
16487  predicate(n->as_Vector()->length() == 16);
16488  match(Set dst (MulVB src1 src2));
16489  ins_cost(INSN_COST);
16490  format %{ "mulv  $dst,$src1,$src2\t# vector (16B)" %}
16491  ins_encode %{
16492    __ mulv(as_FloatRegister($dst$$reg), __ T16B,
16493            as_FloatRegister($src1$$reg),
16494            as_FloatRegister($src2$$reg));
16495  %}
16496  ins_pipe(vmul128);
16497%}
16498
16499instruct vmul4S(vecD dst, vecD src1, vecD src2)
16500%{
16501  predicate(n->as_Vector()->length() == 2 ||
16502            n->as_Vector()->length() == 4);
16503  match(Set dst (MulVS src1 src2));
16504  ins_cost(INSN_COST);
16505  format %{ "mulv  $dst,$src1,$src2\t# vector (4H)" %}
16506  ins_encode %{
16507    __ mulv(as_FloatRegister($dst$$reg), __ T4H,
16508            as_FloatRegister($src1$$reg),
16509            as_FloatRegister($src2$$reg));
16510  %}
16511  ins_pipe(vmul64);
16512%}
16513
16514instruct vmul8S(vecX dst, vecX src1, vecX src2)
16515%{
16516  predicate(n->as_Vector()->length() == 8);
16517  match(Set dst (MulVS src1 src2));
16518  ins_cost(INSN_COST);
16519  format %{ "mulv  $dst,$src1,$src2\t# vector (8H)" %}
16520  ins_encode %{
16521    __ mulv(as_FloatRegister($dst$$reg), __ T8H,
16522            as_FloatRegister($src1$$reg),
16523            as_FloatRegister($src2$$reg));
16524  %}
16525  ins_pipe(vmul128);
16526%}
16527
16528instruct vmul2I(vecD dst, vecD src1, vecD src2)
16529%{
16530  predicate(n->as_Vector()->length() == 2);
16531  match(Set dst (MulVI src1 src2));
16532  ins_cost(INSN_COST);
16533  format %{ "mulv  $dst,$src1,$src2\t# vector (2S)" %}
16534  ins_encode %{
16535    __ mulv(as_FloatRegister($dst$$reg), __ T2S,
16536            as_FloatRegister($src1$$reg),
16537            as_FloatRegister($src2$$reg));
16538  %}
16539  ins_pipe(vmul64);
16540%}
16541
16542instruct vmul4I(vecX dst, vecX src1, vecX src2)
16543%{
16544  predicate(n->as_Vector()->length() == 4);
16545  match(Set dst (MulVI src1 src2));
16546  ins_cost(INSN_COST);
16547  format %{ "mulv  $dst,$src1,$src2\t# vector (4S)" %}
16548  ins_encode %{
16549    __ mulv(as_FloatRegister($dst$$reg), __ T4S,
16550            as_FloatRegister($src1$$reg),
16551            as_FloatRegister($src2$$reg));
16552  %}
16553  ins_pipe(vmul128);
16554%}
16555
16556instruct vmul2F(vecD dst, vecD src1, vecD src2)
16557%{
16558  predicate(n->as_Vector()->length() == 2);
16559  match(Set dst (MulVF src1 src2));
16560  ins_cost(INSN_COST);
16561  format %{ "fmul  $dst,$src1,$src2\t# vector (2S)" %}
16562  ins_encode %{
16563    __ fmul(as_FloatRegister($dst$$reg), __ T2S,
16564            as_FloatRegister($src1$$reg),
16565            as_FloatRegister($src2$$reg));
16566  %}
16567  ins_pipe(vmuldiv_fp64);
16568%}
16569
16570instruct vmul4F(vecX dst, vecX src1, vecX src2)
16571%{
16572  predicate(n->as_Vector()->length() == 4);
16573  match(Set dst (MulVF src1 src2));
16574  ins_cost(INSN_COST);
16575  format %{ "fmul  $dst,$src1,$src2\t# vector (4S)" %}
16576  ins_encode %{
16577    __ fmul(as_FloatRegister($dst$$reg), __ T4S,
16578            as_FloatRegister($src1$$reg),
16579            as_FloatRegister($src2$$reg));
16580  %}
16581  ins_pipe(vmuldiv_fp128);
16582%}
16583
16584instruct vmul2D(vecX dst, vecX src1, vecX src2)
16585%{
16586  predicate(n->as_Vector()->length() == 2);
16587  match(Set dst (MulVD src1 src2));
16588  ins_cost(INSN_COST);
16589  format %{ "fmul  $dst,$src1,$src2\t# vector (2D)" %}
16590  ins_encode %{
16591    __ fmul(as_FloatRegister($dst$$reg), __ T2D,
16592            as_FloatRegister($src1$$reg),
16593            as_FloatRegister($src2$$reg));
16594  %}
16595  ins_pipe(vmuldiv_fp128);
16596%}
16597
16598// --------------------------------- MLA --------------------------------------
16599
16600instruct vmla4S(vecD dst, vecD src1, vecD src2)
16601%{
16602  predicate(n->as_Vector()->length() == 2 ||
16603            n->as_Vector()->length() == 4);
16604  match(Set dst (AddVS dst (MulVS src1 src2)));
16605  ins_cost(INSN_COST);
16606  format %{ "mlav  $dst,$src1,$src2\t# vector (4H)" %}
16607  ins_encode %{
16608    __ mlav(as_FloatRegister($dst$$reg), __ T4H,
16609            as_FloatRegister($src1$$reg),
16610            as_FloatRegister($src2$$reg));
16611  %}
16612  ins_pipe(vmla64);
16613%}
16614
16615instruct vmla8S(vecX dst, vecX src1, vecX src2)
16616%{
16617  predicate(n->as_Vector()->length() == 8);
16618  match(Set dst (AddVS dst (MulVS src1 src2)));
16619  ins_cost(INSN_COST);
16620  format %{ "mlav  $dst,$src1,$src2\t# vector (8H)" %}
16621  ins_encode %{
16622    __ mlav(as_FloatRegister($dst$$reg), __ T8H,
16623            as_FloatRegister($src1$$reg),
16624            as_FloatRegister($src2$$reg));
16625  %}
16626  ins_pipe(vmla128);
16627%}
16628
16629instruct vmla2I(vecD dst, vecD src1, vecD src2)
16630%{
16631  predicate(n->as_Vector()->length() == 2);
16632  match(Set dst (AddVI dst (MulVI src1 src2)));
16633  ins_cost(INSN_COST);
16634  format %{ "mlav  $dst,$src1,$src2\t# vector (2S)" %}
16635  ins_encode %{
16636    __ mlav(as_FloatRegister($dst$$reg), __ T2S,
16637            as_FloatRegister($src1$$reg),
16638            as_FloatRegister($src2$$reg));
16639  %}
16640  ins_pipe(vmla64);
16641%}
16642
16643instruct vmla4I(vecX dst, vecX src1, vecX src2)
16644%{
16645  predicate(n->as_Vector()->length() == 4);
16646  match(Set dst (AddVI dst (MulVI src1 src2)));
16647  ins_cost(INSN_COST);
16648  format %{ "mlav  $dst,$src1,$src2\t# vector (4S)" %}
16649  ins_encode %{
16650    __ mlav(as_FloatRegister($dst$$reg), __ T4S,
16651            as_FloatRegister($src1$$reg),
16652            as_FloatRegister($src2$$reg));
16653  %}
16654  ins_pipe(vmla128);
16655%}
16656
16657// dst + src1 * src2
16658instruct vmla2F(vecD dst, vecD src1, vecD src2) %{
16659  predicate(UseFMA && n->as_Vector()->length() == 2);
16660  match(Set dst (FmaVF  dst (Binary src1 src2)));
16661  format %{ "fmla  $dst,$src1,$src2\t# vector (2S)" %}
16662  ins_cost(INSN_COST);
16663  ins_encode %{
16664    __ fmla(as_FloatRegister($dst$$reg), __ T2S,
16665            as_FloatRegister($src1$$reg),
16666            as_FloatRegister($src2$$reg));
16667  %}
16668  ins_pipe(vmuldiv_fp64);
16669%}
16670
16671// dst + src1 * src2
16672instruct vmla4F(vecX dst, vecX src1, vecX src2) %{
16673  predicate(UseFMA && n->as_Vector()->length() == 4);
16674  match(Set dst (FmaVF  dst (Binary src1 src2)));
16675  format %{ "fmla  $dst,$src1,$src2\t# vector (4S)" %}
16676  ins_cost(INSN_COST);
16677  ins_encode %{
16678    __ fmla(as_FloatRegister($dst$$reg), __ T4S,
16679            as_FloatRegister($src1$$reg),
16680            as_FloatRegister($src2$$reg));
16681  %}
16682  ins_pipe(vmuldiv_fp128);
16683%}
16684
16685// dst + src1 * src2
16686instruct vmla2D(vecX dst, vecX src1, vecX src2) %{
16687  predicate(UseFMA && n->as_Vector()->length() == 2);
16688  match(Set dst (FmaVD  dst (Binary src1 src2)));
16689  format %{ "fmla  $dst,$src1,$src2\t# vector (2D)" %}
16690  ins_cost(INSN_COST);
16691  ins_encode %{
16692    __ fmla(as_FloatRegister($dst$$reg), __ T2D,
16693            as_FloatRegister($src1$$reg),
16694            as_FloatRegister($src2$$reg));
16695  %}
16696  ins_pipe(vmuldiv_fp128);
16697%}
16698
16699// --------------------------------- MLS --------------------------------------
16700
16701instruct vmls4S(vecD dst, vecD src1, vecD src2)
16702%{
16703  predicate(n->as_Vector()->length() == 2 ||
16704            n->as_Vector()->length() == 4);
16705  match(Set dst (SubVS dst (MulVS src1 src2)));
16706  ins_cost(INSN_COST);
16707  format %{ "mlsv  $dst,$src1,$src2\t# vector (4H)" %}
16708  ins_encode %{
16709    __ mlsv(as_FloatRegister($dst$$reg), __ T4H,
16710            as_FloatRegister($src1$$reg),
16711            as_FloatRegister($src2$$reg));
16712  %}
16713  ins_pipe(vmla64);
16714%}
16715
16716instruct vmls8S(vecX dst, vecX src1, vecX src2)
16717%{
16718  predicate(n->as_Vector()->length() == 8);
16719  match(Set dst (SubVS dst (MulVS src1 src2)));
16720  ins_cost(INSN_COST);
16721  format %{ "mlsv  $dst,$src1,$src2\t# vector (8H)" %}
16722  ins_encode %{
16723    __ mlsv(as_FloatRegister($dst$$reg), __ T8H,
16724            as_FloatRegister($src1$$reg),
16725            as_FloatRegister($src2$$reg));
16726  %}
16727  ins_pipe(vmla128);
16728%}
16729
16730instruct vmls2I(vecD dst, vecD src1, vecD src2)
16731%{
16732  predicate(n->as_Vector()->length() == 2);
16733  match(Set dst (SubVI dst (MulVI src1 src2)));
16734  ins_cost(INSN_COST);
16735  format %{ "mlsv  $dst,$src1,$src2\t# vector (2S)" %}
16736  ins_encode %{
16737    __ mlsv(as_FloatRegister($dst$$reg), __ T2S,
16738            as_FloatRegister($src1$$reg),
16739            as_FloatRegister($src2$$reg));
16740  %}
16741  ins_pipe(vmla64);
16742%}
16743
16744instruct vmls4I(vecX dst, vecX src1, vecX src2)
16745%{
16746  predicate(n->as_Vector()->length() == 4);
16747  match(Set dst (SubVI dst (MulVI src1 src2)));
16748  ins_cost(INSN_COST);
16749  format %{ "mlsv  $dst,$src1,$src2\t# vector (4S)" %}
16750  ins_encode %{
16751    __ mlsv(as_FloatRegister($dst$$reg), __ T4S,
16752            as_FloatRegister($src1$$reg),
16753            as_FloatRegister($src2$$reg));
16754  %}
16755  ins_pipe(vmla128);
16756%}
16757
16758// dst - src1 * src2
16759instruct vmls2F(vecD dst, vecD src1, vecD src2) %{
16760  predicate(UseFMA && n->as_Vector()->length() == 2);
16761  match(Set dst (FmaVF  dst (Binary (NegVF src1) src2)));
16762  match(Set dst (FmaVF  dst (Binary src1 (NegVF src2))));
16763  format %{ "fmls  $dst,$src1,$src2\t# vector (2S)" %}
16764  ins_cost(INSN_COST);
16765  ins_encode %{
16766    __ fmls(as_FloatRegister($dst$$reg), __ T2S,
16767            as_FloatRegister($src1$$reg),
16768            as_FloatRegister($src2$$reg));
16769  %}
16770  ins_pipe(vmuldiv_fp64);
16771%}
16772
16773// dst - src1 * src2
16774instruct vmls4F(vecX dst, vecX src1, vecX src2) %{
16775  predicate(UseFMA && n->as_Vector()->length() == 4);
16776  match(Set dst (FmaVF  dst (Binary (NegVF src1) src2)));
16777  match(Set dst (FmaVF  dst (Binary src1 (NegVF src2))));
16778  format %{ "fmls  $dst,$src1,$src2\t# vector (4S)" %}
16779  ins_cost(INSN_COST);
16780  ins_encode %{
16781    __ fmls(as_FloatRegister($dst$$reg), __ T4S,
16782            as_FloatRegister($src1$$reg),
16783            as_FloatRegister($src2$$reg));
16784  %}
16785  ins_pipe(vmuldiv_fp128);
16786%}
16787
16788// dst - src1 * src2
16789instruct vmls2D(vecX dst, vecX src1, vecX src2) %{
16790  predicate(UseFMA && n->as_Vector()->length() == 2);
16791  match(Set dst (FmaVD  dst (Binary (NegVD src1) src2)));
16792  match(Set dst (FmaVD  dst (Binary src1 (NegVD src2))));
16793  format %{ "fmls  $dst,$src1,$src2\t# vector (2D)" %}
16794  ins_cost(INSN_COST);
16795  ins_encode %{
16796    __ fmls(as_FloatRegister($dst$$reg), __ T2D,
16797            as_FloatRegister($src1$$reg),
16798            as_FloatRegister($src2$$reg));
16799  %}
16800  ins_pipe(vmuldiv_fp128);
16801%}
16802
16803// --------------------------------- DIV --------------------------------------
16804
16805instruct vdiv2F(vecD dst, vecD src1, vecD src2)
16806%{
16807  predicate(n->as_Vector()->length() == 2);
16808  match(Set dst (DivVF src1 src2));
16809  ins_cost(INSN_COST);
16810  format %{ "fdiv  $dst,$src1,$src2\t# vector (2S)" %}
16811  ins_encode %{
16812    __ fdiv(as_FloatRegister($dst$$reg), __ T2S,
16813            as_FloatRegister($src1$$reg),
16814            as_FloatRegister($src2$$reg));
16815  %}
16816  ins_pipe(vmuldiv_fp64);
16817%}
16818
16819instruct vdiv4F(vecX dst, vecX src1, vecX src2)
16820%{
16821  predicate(n->as_Vector()->length() == 4);
16822  match(Set dst (DivVF src1 src2));
16823  ins_cost(INSN_COST);
16824  format %{ "fdiv  $dst,$src1,$src2\t# vector (4S)" %}
16825  ins_encode %{
16826    __ fdiv(as_FloatRegister($dst$$reg), __ T4S,
16827            as_FloatRegister($src1$$reg),
16828            as_FloatRegister($src2$$reg));
16829  %}
16830  ins_pipe(vmuldiv_fp128);
16831%}
16832
16833instruct vdiv2D(vecX dst, vecX src1, vecX src2)
16834%{
16835  predicate(n->as_Vector()->length() == 2);
16836  match(Set dst (DivVD src1 src2));
16837  ins_cost(INSN_COST);
16838  format %{ "fdiv  $dst,$src1,$src2\t# vector (2D)" %}
16839  ins_encode %{
16840    __ fdiv(as_FloatRegister($dst$$reg), __ T2D,
16841            as_FloatRegister($src1$$reg),
16842            as_FloatRegister($src2$$reg));
16843  %}
16844  ins_pipe(vmuldiv_fp128);
16845%}
16846
16847// --------------------------------- SQRT -------------------------------------
16848
16849instruct vsqrt2F(vecD dst, vecD src)
16850%{
16851  predicate(n->as_Vector()->length() == 2);
16852  match(Set dst (SqrtVF src));
16853  format %{ "fsqrt  $dst, $src\t# vector (2F)" %}
16854  ins_encode %{
16855    __ fsqrt(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg));
16856  %}
16857  ins_pipe(vunop_fp64);
16858%}
16859
16860instruct vsqrt4F(vecX dst, vecX src)
16861%{
16862  predicate(n->as_Vector()->length() == 4);
16863  match(Set dst (SqrtVF src));
16864  format %{ "fsqrt  $dst, $src\t# vector (4F)" %}
16865  ins_encode %{
16866    __ fsqrt(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg));
16867  %}
16868  ins_pipe(vsqrt_fp128);
16869%}
16870
16871instruct vsqrt2D(vecX dst, vecX src)
16872%{
16873  predicate(n->as_Vector()->length() == 2);
16874  match(Set dst (SqrtVD src));
16875  format %{ "fsqrt  $dst, $src\t# vector (2D)" %}
16876  ins_encode %{
16877    __ fsqrt(as_FloatRegister($dst$$reg), __ T2D,
16878             as_FloatRegister($src$$reg));
16879  %}
16880  ins_pipe(vsqrt_fp128);
16881%}
16882
16883// --------------------------------- ABS --------------------------------------
16884
16885instruct vabs8B(vecD dst, vecD src)
16886%{
16887  predicate(n->as_Vector()->length() == 4 ||
16888            n->as_Vector()->length() == 8);
16889  match(Set dst (AbsVB src));
16890  ins_cost(INSN_COST);
16891  format %{ "abs  $dst, $src\t# vector (8B)" %}
16892  ins_encode %{
16893    __ absr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg));
16894  %}
16895  ins_pipe(vlogical64);
16896%}
16897
16898instruct vabs16B(vecX dst, vecX src)
16899%{
16900  predicate(n->as_Vector()->length() == 16);
16901  match(Set dst (AbsVB src));
16902  ins_cost(INSN_COST);
16903  format %{ "abs  $dst, $src\t# vector (16B)" %}
16904  ins_encode %{
16905    __ absr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg));
16906  %}
16907  ins_pipe(vlogical128);
16908%}
16909
16910instruct vabs4S(vecD dst, vecD src)
16911%{
16912  predicate(n->as_Vector()->length() == 4);
16913  match(Set dst (AbsVS src));
16914  ins_cost(INSN_COST);
16915  format %{ "abs  $dst, $src\t# vector (4H)" %}
16916  ins_encode %{
16917    __ absr(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg));
16918  %}
16919  ins_pipe(vlogical64);
16920%}
16921
16922instruct vabs8S(vecX dst, vecX src)
16923%{
16924  predicate(n->as_Vector()->length() == 8);
16925  match(Set dst (AbsVS src));
16926  ins_cost(INSN_COST);
16927  format %{ "abs  $dst, $src\t# vector (8H)" %}
16928  ins_encode %{
16929    __ absr(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg));
16930  %}
16931  ins_pipe(vlogical128);
16932%}
16933
16934instruct vabs2I(vecD dst, vecD src)
16935%{
16936  predicate(n->as_Vector()->length() == 2);
16937  match(Set dst (AbsVI src));
16938  ins_cost(INSN_COST);
16939  format %{ "abs  $dst, $src\t# vector (2S)" %}
16940  ins_encode %{
16941    __ absr(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg));
16942  %}
16943  ins_pipe(vlogical64);
16944%}
16945
16946instruct vabs4I(vecX dst, vecX src)
16947%{
16948  predicate(n->as_Vector()->length() == 4);
16949  match(Set dst (AbsVI src));
16950  ins_cost(INSN_COST);
16951  format %{ "abs  $dst, $src\t# vector (4S)" %}
16952  ins_encode %{
16953    __ absr(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg));
16954  %}
16955  ins_pipe(vlogical128);
16956%}
16957
16958instruct vabs2L(vecX dst, vecX src)
16959%{
16960  predicate(n->as_Vector()->length() == 2);
16961  match(Set dst (AbsVL src));
16962  ins_cost(INSN_COST);
16963  format %{ "abs  $dst, $src\t# vector (2D)" %}
16964  ins_encode %{
16965    __ absr(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg));
16966  %}
16967  ins_pipe(vlogical128);
16968%}
16969
16970instruct vabs2F(vecD dst, vecD src)
16971%{
16972  predicate(n->as_Vector()->length() == 2);
16973  match(Set dst (AbsVF src));
16974  ins_cost(INSN_COST * 3);
16975  format %{ "fabs  $dst,$src\t# vector (2S)" %}
16976  ins_encode %{
16977    __ fabs(as_FloatRegister($dst$$reg), __ T2S,
16978            as_FloatRegister($src$$reg));
16979  %}
16980  ins_pipe(vunop_fp64);
16981%}
16982
16983instruct vabs4F(vecX dst, vecX src)
16984%{
16985  predicate(n->as_Vector()->length() == 4);
16986  match(Set dst (AbsVF src));
16987  ins_cost(INSN_COST * 3);
16988  format %{ "fabs  $dst,$src\t# vector (4S)" %}
16989  ins_encode %{
16990    __ fabs(as_FloatRegister($dst$$reg), __ T4S,
16991            as_FloatRegister($src$$reg));
16992  %}
16993  ins_pipe(vunop_fp128);
16994%}
16995
16996instruct vabs2D(vecX dst, vecX src)
16997%{
16998  predicate(n->as_Vector()->length() == 2);
16999  match(Set dst (AbsVD src));
17000  ins_cost(INSN_COST * 3);
17001  format %{ "fabs  $dst,$src\t# vector (2D)" %}
17002  ins_encode %{
17003    __ fabs(as_FloatRegister($dst$$reg), __ T2D,
17004            as_FloatRegister($src$$reg));
17005  %}
17006  ins_pipe(vunop_fp128);
17007%}
17008
17009// --------------------------------- NEG --------------------------------------
17010
17011instruct vneg2F(vecD dst, vecD src)
17012%{
17013  predicate(n->as_Vector()->length() == 2);
17014  match(Set dst (NegVF src));
17015  ins_cost(INSN_COST * 3);
17016  format %{ "fneg  $dst,$src\t# vector (2S)" %}
17017  ins_encode %{
17018    __ fneg(as_FloatRegister($dst$$reg), __ T2S,
17019            as_FloatRegister($src$$reg));
17020  %}
17021  ins_pipe(vunop_fp64);
17022%}
17023
17024instruct vneg4F(vecX dst, vecX src)
17025%{
17026  predicate(n->as_Vector()->length() == 4);
17027  match(Set dst (NegVF src));
17028  ins_cost(INSN_COST * 3);
17029  format %{ "fneg  $dst,$src\t# vector (4S)" %}
17030  ins_encode %{
17031    __ fneg(as_FloatRegister($dst$$reg), __ T4S,
17032            as_FloatRegister($src$$reg));
17033  %}
17034  ins_pipe(vunop_fp128);
17035%}
17036
17037instruct vneg2D(vecX dst, vecX src)
17038%{
17039  predicate(n->as_Vector()->length() == 2);
17040  match(Set dst (NegVD src));
17041  ins_cost(INSN_COST * 3);
17042  format %{ "fneg  $dst,$src\t# vector (2D)" %}
17043  ins_encode %{
17044    __ fneg(as_FloatRegister($dst$$reg), __ T2D,
17045            as_FloatRegister($src$$reg));
17046  %}
17047  ins_pipe(vunop_fp128);
17048%}
17049
17050// --------------------------------- AND --------------------------------------
17051
17052instruct vand8B(vecD dst, vecD src1, vecD src2)
17053%{
17054  predicate(n->as_Vector()->length_in_bytes() == 4 ||
17055            n->as_Vector()->length_in_bytes() == 8);
17056  match(Set dst (AndV src1 src2));
17057  ins_cost(INSN_COST);
17058  format %{ "and  $dst,$src1,$src2\t# vector (8B)" %}
17059  ins_encode %{
17060    __ andr(as_FloatRegister($dst$$reg), __ T8B,
17061            as_FloatRegister($src1$$reg),
17062            as_FloatRegister($src2$$reg));
17063  %}
17064  ins_pipe(vlogical64);
17065%}
17066
17067instruct vand16B(vecX dst, vecX src1, vecX src2)
17068%{
17069  predicate(n->as_Vector()->length_in_bytes() == 16);
17070  match(Set dst (AndV src1 src2));
17071  ins_cost(INSN_COST);
17072  format %{ "and  $dst,$src1,$src2\t# vector (16B)" %}
17073  ins_encode %{
17074    __ andr(as_FloatRegister($dst$$reg), __ T16B,
17075            as_FloatRegister($src1$$reg),
17076            as_FloatRegister($src2$$reg));
17077  %}
17078  ins_pipe(vlogical128);
17079%}
17080
17081// --------------------------------- OR ---------------------------------------
17082
17083instruct vor8B(vecD dst, vecD src1, vecD src2)
17084%{
17085  predicate(n->as_Vector()->length_in_bytes() == 4 ||
17086            n->as_Vector()->length_in_bytes() == 8);
17087  match(Set dst (OrV src1 src2));
17088  ins_cost(INSN_COST);
17089  format %{ "and  $dst,$src1,$src2\t# vector (8B)" %}
17090  ins_encode %{
17091    __ orr(as_FloatRegister($dst$$reg), __ T8B,
17092            as_FloatRegister($src1$$reg),
17093            as_FloatRegister($src2$$reg));
17094  %}
17095  ins_pipe(vlogical64);
17096%}
17097
17098instruct vor16B(vecX dst, vecX src1, vecX src2)
17099%{
17100  predicate(n->as_Vector()->length_in_bytes() == 16);
17101  match(Set dst (OrV src1 src2));
17102  ins_cost(INSN_COST);
17103  format %{ "orr  $dst,$src1,$src2\t# vector (16B)" %}
17104  ins_encode %{
17105    __ orr(as_FloatRegister($dst$$reg), __ T16B,
17106            as_FloatRegister($src1$$reg),
17107            as_FloatRegister($src2$$reg));
17108  %}
17109  ins_pipe(vlogical128);
17110%}
17111
17112// --------------------------------- XOR --------------------------------------
17113
17114instruct vxor8B(vecD dst, vecD src1, vecD src2)
17115%{
17116  predicate(n->as_Vector()->length_in_bytes() == 4 ||
17117            n->as_Vector()->length_in_bytes() == 8);
17118  match(Set dst (XorV src1 src2));
17119  ins_cost(INSN_COST);
17120  format %{ "xor  $dst,$src1,$src2\t# vector (8B)" %}
17121  ins_encode %{
17122    __ eor(as_FloatRegister($dst$$reg), __ T8B,
17123            as_FloatRegister($src1$$reg),
17124            as_FloatRegister($src2$$reg));
17125  %}
17126  ins_pipe(vlogical64);
17127%}
17128
17129instruct vxor16B(vecX dst, vecX src1, vecX src2)
17130%{
17131  predicate(n->as_Vector()->length_in_bytes() == 16);
17132  match(Set dst (XorV src1 src2));
17133  ins_cost(INSN_COST);
17134  format %{ "xor  $dst,$src1,$src2\t# vector (16B)" %}
17135  ins_encode %{
17136    __ eor(as_FloatRegister($dst$$reg), __ T16B,
17137            as_FloatRegister($src1$$reg),
17138            as_FloatRegister($src2$$reg));
17139  %}
17140  ins_pipe(vlogical128);
17141%}
17142
17143// ------------------------------ Shift ---------------------------------------
17144instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{
17145  predicate(n->as_Vector()->length_in_bytes() == 8);
17146  match(Set dst (LShiftCntV cnt));
17147  match(Set dst (RShiftCntV cnt));
17148  format %{ "dup  $dst, $cnt\t# shift count vector (8B)" %}
17149  ins_encode %{
17150    __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg));
17151  %}
17152  ins_pipe(vdup_reg_reg64);
17153%}
17154
17155instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{
17156  predicate(n->as_Vector()->length_in_bytes() == 16);
17157  match(Set dst (LShiftCntV cnt));
17158  match(Set dst (RShiftCntV cnt));
17159  format %{ "dup  $dst, $cnt\t# shift count vector (16B)" %}
17160  ins_encode %{
17161    __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg));
17162  %}
17163  ins_pipe(vdup_reg_reg128);
17164%}
17165
17166instruct vsll8B(vecD dst, vecD src, vecD shift) %{
17167  predicate(n->as_Vector()->length() == 4 ||
17168            n->as_Vector()->length() == 8);
17169  match(Set dst (LShiftVB src shift));
17170  ins_cost(INSN_COST);
17171  format %{ "sshl  $dst,$src,$shift\t# vector (8B)" %}
17172  ins_encode %{
17173    __ sshl(as_FloatRegister($dst$$reg), __ T8B,
17174            as_FloatRegister($src$$reg),
17175            as_FloatRegister($shift$$reg));
17176  %}
17177  ins_pipe(vshift64);
17178%}
17179
17180instruct vsll16B(vecX dst, vecX src, vecX shift) %{
17181  predicate(n->as_Vector()->length() == 16);
17182  match(Set dst (LShiftVB src shift));
17183  ins_cost(INSN_COST);
17184  format %{ "sshl  $dst,$src,$shift\t# vector (16B)" %}
17185  ins_encode %{
17186    __ sshl(as_FloatRegister($dst$$reg), __ T16B,
17187            as_FloatRegister($src$$reg),
17188            as_FloatRegister($shift$$reg));
17189  %}
17190  ins_pipe(vshift128);
17191%}
17192
17193// Right shifts with vector shift count on aarch64 SIMD are implemented
17194// as left shift by negative shift count.
17195// There are two cases for vector shift count.
17196//
17197// Case 1: The vector shift count is from replication.
17198//        |            |
17199//    LoadVector  RShiftCntV
17200//        |       /
17201//     RShiftVI
17202// Note: In inner loop, multiple neg instructions are used, which can be
17203// moved to outer loop and merge into one neg instruction.
17204//
17205// Case 2: The vector shift count is from loading.
17206// This case isn't supported by middle-end now. But it's supported by
17207// panama/vectorIntrinsics(JEP 338: Vector API).
17208//        |            |
17209//    LoadVector  LoadVector
17210//        |       /
17211//     RShiftVI
17212//
17213
17214instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{
17215  predicate(n->as_Vector()->length() == 4 ||
17216            n->as_Vector()->length() == 8);
17217  match(Set dst (RShiftVB src shift));
17218  ins_cost(INSN_COST);
17219  effect(TEMP tmp);
17220  format %{ "negr  $tmp,$shift\t"
17221            "sshl  $dst,$src,$tmp\t# vector (8B)" %}
17222  ins_encode %{
17223    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
17224            as_FloatRegister($shift$$reg));
17225    __ sshl(as_FloatRegister($dst$$reg), __ T8B,
17226            as_FloatRegister($src$$reg),
17227            as_FloatRegister($tmp$$reg));
17228  %}
17229  ins_pipe(vshift64);
17230%}
17231
17232instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{
17233  predicate(n->as_Vector()->length() == 16);
17234  match(Set dst (RShiftVB src shift));
17235  ins_cost(INSN_COST);
17236  effect(TEMP tmp);
17237  format %{ "negr  $tmp,$shift\t"
17238            "sshl  $dst,$src,$tmp\t# vector (16B)" %}
17239  ins_encode %{
17240    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
17241            as_FloatRegister($shift$$reg));
17242    __ sshl(as_FloatRegister($dst$$reg), __ T16B,
17243            as_FloatRegister($src$$reg),
17244            as_FloatRegister($tmp$$reg));
17245  %}
17246  ins_pipe(vshift128);
17247%}
17248
17249instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{
17250  predicate(n->as_Vector()->length() == 4 ||
17251            n->as_Vector()->length() == 8);
17252  match(Set dst (URShiftVB src shift));
17253  ins_cost(INSN_COST);
17254  effect(TEMP tmp);
17255  format %{ "negr  $tmp,$shift\t"
17256            "ushl  $dst,$src,$tmp\t# vector (8B)" %}
17257  ins_encode %{
17258    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
17259            as_FloatRegister($shift$$reg));
17260    __ ushl(as_FloatRegister($dst$$reg), __ T8B,
17261            as_FloatRegister($src$$reg),
17262            as_FloatRegister($tmp$$reg));
17263  %}
17264  ins_pipe(vshift64);
17265%}
17266
17267instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{
17268  predicate(n->as_Vector()->length() == 16);
17269  match(Set dst (URShiftVB src shift));
17270  ins_cost(INSN_COST);
17271  effect(TEMP tmp);
17272  format %{ "negr  $tmp,$shift\t"
17273            "ushl  $dst,$src,$tmp\t# vector (16B)" %}
17274  ins_encode %{
17275    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
17276            as_FloatRegister($shift$$reg));
17277    __ ushl(as_FloatRegister($dst$$reg), __ T16B,
17278            as_FloatRegister($src$$reg),
17279            as_FloatRegister($tmp$$reg));
17280  %}
17281  ins_pipe(vshift128);
17282%}
17283
17284instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{
17285  predicate(n->as_Vector()->length() == 4 ||
17286            n->as_Vector()->length() == 8);
17287  match(Set dst (LShiftVB src shift));
17288  ins_cost(INSN_COST);
17289  format %{ "shl    $dst, $src, $shift\t# vector (8B)" %}
17290  ins_encode %{
17291    int sh = (int)$shift$$constant;
17292    if (sh >= 8) {
17293      __ eor(as_FloatRegister($dst$$reg), __ T8B,
17294             as_FloatRegister($src$$reg),
17295             as_FloatRegister($src$$reg));
17296    } else {
17297      __ shl(as_FloatRegister($dst$$reg), __ T8B,
17298             as_FloatRegister($src$$reg), sh);
17299    }
17300  %}
17301  ins_pipe(vshift64_imm);
17302%}
17303
17304instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{
17305  predicate(n->as_Vector()->length() == 16);
17306  match(Set dst (LShiftVB src shift));
17307  ins_cost(INSN_COST);
17308  format %{ "shl    $dst, $src, $shift\t# vector (16B)" %}
17309  ins_encode %{
17310    int sh = (int)$shift$$constant;
17311    if (sh >= 8) {
17312      __ eor(as_FloatRegister($dst$$reg), __ T16B,
17313             as_FloatRegister($src$$reg),
17314             as_FloatRegister($src$$reg));
17315    } else {
17316      __ shl(as_FloatRegister($dst$$reg), __ T16B,
17317             as_FloatRegister($src$$reg), sh);
17318    }
17319  %}
17320  ins_pipe(vshift128_imm);
17321%}
17322
17323instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{
17324  predicate(n->as_Vector()->length() == 4 ||
17325            n->as_Vector()->length() == 8);
17326  match(Set dst (RShiftVB src shift));
17327  ins_cost(INSN_COST);
17328  format %{ "sshr    $dst, $src, $shift\t# vector (8B)" %}
17329  ins_encode %{
17330    int sh = (int)$shift$$constant;
17331    if (sh >= 8) sh = 7;
17332    __ sshr(as_FloatRegister($dst$$reg), __ T8B,
17333           as_FloatRegister($src$$reg), sh);
17334  %}
17335  ins_pipe(vshift64_imm);
17336%}
17337
17338instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{
17339  predicate(n->as_Vector()->length() == 16);
17340  match(Set dst (RShiftVB src shift));
17341  ins_cost(INSN_COST);
17342  format %{ "sshr    $dst, $src, $shift\t# vector (16B)" %}
17343  ins_encode %{
17344    int sh = (int)$shift$$constant;
17345    if (sh >= 8) sh = 7;
17346    __ sshr(as_FloatRegister($dst$$reg), __ T16B,
17347           as_FloatRegister($src$$reg), sh);
17348  %}
17349  ins_pipe(vshift128_imm);
17350%}
17351
17352instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{
17353  predicate(n->as_Vector()->length() == 4 ||
17354            n->as_Vector()->length() == 8);
17355  match(Set dst (URShiftVB src shift));
17356  ins_cost(INSN_COST);
17357  format %{ "ushr    $dst, $src, $shift\t# vector (8B)" %}
17358  ins_encode %{
17359    int sh = (int)$shift$$constant;
17360    if (sh >= 8) {
17361      __ eor(as_FloatRegister($dst$$reg), __ T8B,
17362             as_FloatRegister($src$$reg),
17363             as_FloatRegister($src$$reg));
17364    } else {
17365      __ ushr(as_FloatRegister($dst$$reg), __ T8B,
17366             as_FloatRegister($src$$reg), sh);
17367    }
17368  %}
17369  ins_pipe(vshift64_imm);
17370%}
17371
17372instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{
17373  predicate(n->as_Vector()->length() == 16);
17374  match(Set dst (URShiftVB src shift));
17375  ins_cost(INSN_COST);
17376  format %{ "ushr    $dst, $src, $shift\t# vector (16B)" %}
17377  ins_encode %{
17378    int sh = (int)$shift$$constant;
17379    if (sh >= 8) {
17380      __ eor(as_FloatRegister($dst$$reg), __ T16B,
17381             as_FloatRegister($src$$reg),
17382             as_FloatRegister($src$$reg));
17383    } else {
17384      __ ushr(as_FloatRegister($dst$$reg), __ T16B,
17385             as_FloatRegister($src$$reg), sh);
17386    }
17387  %}
17388  ins_pipe(vshift128_imm);
17389%}
17390
17391instruct vsll4S(vecD dst, vecD src, vecD shift) %{
17392  predicate(n->as_Vector()->length() == 2 ||
17393            n->as_Vector()->length() == 4);
17394  match(Set dst (LShiftVS src shift));
17395  ins_cost(INSN_COST);
17396  format %{ "sshl  $dst,$src,$shift\t# vector (4H)" %}
17397  ins_encode %{
17398    __ sshl(as_FloatRegister($dst$$reg), __ T4H,
17399            as_FloatRegister($src$$reg),
17400            as_FloatRegister($shift$$reg));
17401  %}
17402  ins_pipe(vshift64);
17403%}
17404
17405instruct vsll8S(vecX dst, vecX src, vecX shift) %{
17406  predicate(n->as_Vector()->length() == 8);
17407  match(Set dst (LShiftVS src shift));
17408  ins_cost(INSN_COST);
17409  format %{ "sshl  $dst,$src,$shift\t# vector (8H)" %}
17410  ins_encode %{
17411    __ sshl(as_FloatRegister($dst$$reg), __ T8H,
17412            as_FloatRegister($src$$reg),
17413            as_FloatRegister($shift$$reg));
17414  %}
17415  ins_pipe(vshift128);
17416%}
17417
17418instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{
17419  predicate(n->as_Vector()->length() == 2 ||
17420            n->as_Vector()->length() == 4);
17421  match(Set dst (RShiftVS src shift));
17422  ins_cost(INSN_COST);
17423  effect(TEMP tmp);
17424  format %{ "negr  $tmp,$shift\t"
17425            "sshl  $dst,$src,$tmp\t# vector (4H)" %}
17426  ins_encode %{
17427    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
17428            as_FloatRegister($shift$$reg));
17429    __ sshl(as_FloatRegister($dst$$reg), __ T4H,
17430            as_FloatRegister($src$$reg),
17431            as_FloatRegister($tmp$$reg));
17432  %}
17433  ins_pipe(vshift64);
17434%}
17435
17436instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{
17437  predicate(n->as_Vector()->length() == 8);
17438  match(Set dst (RShiftVS src shift));
17439  ins_cost(INSN_COST);
17440  effect(TEMP tmp);
17441  format %{ "negr  $tmp,$shift\t"
17442            "sshl  $dst,$src,$tmp\t# vector (8H)" %}
17443  ins_encode %{
17444    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
17445            as_FloatRegister($shift$$reg));
17446    __ sshl(as_FloatRegister($dst$$reg), __ T8H,
17447            as_FloatRegister($src$$reg),
17448            as_FloatRegister($tmp$$reg));
17449  %}
17450  ins_pipe(vshift128);
17451%}
17452
17453instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{
17454  predicate(n->as_Vector()->length() == 2 ||
17455            n->as_Vector()->length() == 4);
17456  match(Set dst (URShiftVS src shift));
17457  ins_cost(INSN_COST);
17458  effect(TEMP tmp);
17459  format %{ "negr  $tmp,$shift\t"
17460            "ushl  $dst,$src,$tmp\t# vector (4H)" %}
17461  ins_encode %{
17462    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
17463            as_FloatRegister($shift$$reg));
17464    __ ushl(as_FloatRegister($dst$$reg), __ T4H,
17465            as_FloatRegister($src$$reg),
17466            as_FloatRegister($tmp$$reg));
17467  %}
17468  ins_pipe(vshift64);
17469%}
17470
17471instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{
17472  predicate(n->as_Vector()->length() == 8);
17473  match(Set dst (URShiftVS src shift));
17474  ins_cost(INSN_COST);
17475  effect(TEMP tmp);
17476  format %{ "negr  $tmp,$shift\t"
17477            "ushl  $dst,$src,$tmp\t# vector (8H)" %}
17478  ins_encode %{
17479    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
17480            as_FloatRegister($shift$$reg));
17481    __ ushl(as_FloatRegister($dst$$reg), __ T8H,
17482            as_FloatRegister($src$$reg),
17483            as_FloatRegister($tmp$$reg));
17484  %}
17485  ins_pipe(vshift128);
17486%}
17487
17488instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{
17489  predicate(n->as_Vector()->length() == 2 ||
17490            n->as_Vector()->length() == 4);
17491  match(Set dst (LShiftVS src shift));
17492  ins_cost(INSN_COST);
17493  format %{ "shl    $dst, $src, $shift\t# vector (4H)" %}
17494  ins_encode %{
17495    int sh = (int)$shift$$constant;
17496    if (sh >= 16) {
17497      __ eor(as_FloatRegister($dst$$reg), __ T8B,
17498             as_FloatRegister($src$$reg),
17499             as_FloatRegister($src$$reg));
17500    } else {
17501      __ shl(as_FloatRegister($dst$$reg), __ T4H,
17502             as_FloatRegister($src$$reg), sh);
17503    }
17504  %}
17505  ins_pipe(vshift64_imm);
17506%}
17507
17508instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{
17509  predicate(n->as_Vector()->length() == 8);
17510  match(Set dst (LShiftVS src shift));
17511  ins_cost(INSN_COST);
17512  format %{ "shl    $dst, $src, $shift\t# vector (8H)" %}
17513  ins_encode %{
17514    int sh = (int)$shift$$constant;
17515    if (sh >= 16) {
17516      __ eor(as_FloatRegister($dst$$reg), __ T16B,
17517             as_FloatRegister($src$$reg),
17518             as_FloatRegister($src$$reg));
17519    } else {
17520      __ shl(as_FloatRegister($dst$$reg), __ T8H,
17521             as_FloatRegister($src$$reg), sh);
17522    }
17523  %}
17524  ins_pipe(vshift128_imm);
17525%}
17526
17527instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{
17528  predicate(n->as_Vector()->length() == 2 ||
17529            n->as_Vector()->length() == 4);
17530  match(Set dst (RShiftVS src shift));
17531  ins_cost(INSN_COST);
17532  format %{ "sshr    $dst, $src, $shift\t# vector (4H)" %}
17533  ins_encode %{
17534    int sh = (int)$shift$$constant;
17535    if (sh >= 16) sh = 15;
17536    __ sshr(as_FloatRegister($dst$$reg), __ T4H,
17537           as_FloatRegister($src$$reg), sh);
17538  %}
17539  ins_pipe(vshift64_imm);
17540%}
17541
17542instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{
17543  predicate(n->as_Vector()->length() == 8);
17544  match(Set dst (RShiftVS src shift));
17545  ins_cost(INSN_COST);
17546  format %{ "sshr    $dst, $src, $shift\t# vector (8H)" %}
17547  ins_encode %{
17548    int sh = (int)$shift$$constant;
17549    if (sh >= 16) sh = 15;
17550    __ sshr(as_FloatRegister($dst$$reg), __ T8H,
17551           as_FloatRegister($src$$reg), sh);
17552  %}
17553  ins_pipe(vshift128_imm);
17554%}
17555
17556instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{
17557  predicate(n->as_Vector()->length() == 2 ||
17558            n->as_Vector()->length() == 4);
17559  match(Set dst (URShiftVS src shift));
17560  ins_cost(INSN_COST);
17561  format %{ "ushr    $dst, $src, $shift\t# vector (4H)" %}
17562  ins_encode %{
17563    int sh = (int)$shift$$constant;
17564    if (sh >= 16) {
17565      __ eor(as_FloatRegister($dst$$reg), __ T8B,
17566             as_FloatRegister($src$$reg),
17567             as_FloatRegister($src$$reg));
17568    } else {
17569      __ ushr(as_FloatRegister($dst$$reg), __ T4H,
17570             as_FloatRegister($src$$reg), sh);
17571    }
17572  %}
17573  ins_pipe(vshift64_imm);
17574%}
17575
17576instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{
17577  predicate(n->as_Vector()->length() == 8);
17578  match(Set dst (URShiftVS src shift));
17579  ins_cost(INSN_COST);
17580  format %{ "ushr    $dst, $src, $shift\t# vector (8H)" %}
17581  ins_encode %{
17582    int sh = (int)$shift$$constant;
17583    if (sh >= 16) {
17584      __ eor(as_FloatRegister($dst$$reg), __ T16B,
17585             as_FloatRegister($src$$reg),
17586             as_FloatRegister($src$$reg));
17587    } else {
17588      __ ushr(as_FloatRegister($dst$$reg), __ T8H,
17589             as_FloatRegister($src$$reg), sh);
17590    }
17591  %}
17592  ins_pipe(vshift128_imm);
17593%}
17594
17595instruct vsll2I(vecD dst, vecD src, vecD shift) %{
17596  predicate(n->as_Vector()->length() == 2);
17597  match(Set dst (LShiftVI src shift));
17598  ins_cost(INSN_COST);
17599  format %{ "sshl  $dst,$src,$shift\t# vector (2S)" %}
17600  ins_encode %{
17601    __ sshl(as_FloatRegister($dst$$reg), __ T2S,
17602            as_FloatRegister($src$$reg),
17603            as_FloatRegister($shift$$reg));
17604  %}
17605  ins_pipe(vshift64);
17606%}
17607
17608instruct vsll4I(vecX dst, vecX src, vecX shift) %{
17609  predicate(n->as_Vector()->length() == 4);
17610  match(Set dst (LShiftVI src shift));
17611  ins_cost(INSN_COST);
17612  format %{ "sshl  $dst,$src,$shift\t# vector (4S)" %}
17613  ins_encode %{
17614    __ sshl(as_FloatRegister($dst$$reg), __ T4S,
17615            as_FloatRegister($src$$reg),
17616            as_FloatRegister($shift$$reg));
17617  %}
17618  ins_pipe(vshift128);
17619%}
17620
17621instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{
17622  predicate(n->as_Vector()->length() == 2);
17623  match(Set dst (RShiftVI src shift));
17624  ins_cost(INSN_COST);
17625  effect(TEMP tmp);
17626  format %{ "negr  $tmp,$shift\t"
17627            "sshl  $dst,$src,$tmp\t# vector (2S)" %}
17628  ins_encode %{
17629    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
17630            as_FloatRegister($shift$$reg));
17631    __ sshl(as_FloatRegister($dst$$reg), __ T2S,
17632            as_FloatRegister($src$$reg),
17633            as_FloatRegister($tmp$$reg));
17634  %}
17635  ins_pipe(vshift64);
17636%}
17637
17638instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{
17639  predicate(n->as_Vector()->length() == 4);
17640  match(Set dst (RShiftVI src shift));
17641  ins_cost(INSN_COST);
17642  effect(TEMP tmp);
17643  format %{ "negr  $tmp,$shift\t"
17644            "sshl  $dst,$src,$tmp\t# vector (4S)" %}
17645  ins_encode %{
17646    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
17647            as_FloatRegister($shift$$reg));
17648    __ sshl(as_FloatRegister($dst$$reg), __ T4S,
17649            as_FloatRegister($src$$reg),
17650            as_FloatRegister($tmp$$reg));
17651  %}
17652  ins_pipe(vshift128);
17653%}
17654
17655instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{
17656  predicate(n->as_Vector()->length() == 2);
17657  match(Set dst (URShiftVI src shift));
17658  ins_cost(INSN_COST);
17659  effect(TEMP tmp);
17660  format %{ "negr  $tmp,$shift\t"
17661            "ushl  $dst,$src,$tmp\t# vector (2S)" %}
17662  ins_encode %{
17663    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
17664            as_FloatRegister($shift$$reg));
17665    __ ushl(as_FloatRegister($dst$$reg), __ T2S,
17666            as_FloatRegister($src$$reg),
17667            as_FloatRegister($tmp$$reg));
17668  %}
17669  ins_pipe(vshift64);
17670%}
17671
17672instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{
17673  predicate(n->as_Vector()->length() == 4);
17674  match(Set dst (URShiftVI src shift));
17675  ins_cost(INSN_COST);
17676  effect(TEMP tmp);
17677  format %{ "negr  $tmp,$shift\t"
17678            "ushl  $dst,$src,$tmp\t# vector (4S)" %}
17679  ins_encode %{
17680    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
17681            as_FloatRegister($shift$$reg));
17682    __ ushl(as_FloatRegister($dst$$reg), __ T4S,
17683            as_FloatRegister($src$$reg),
17684            as_FloatRegister($tmp$$reg));
17685  %}
17686  ins_pipe(vshift128);
17687%}
17688
17689instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{
17690  predicate(n->as_Vector()->length() == 2);
17691  match(Set dst (LShiftVI src shift));
17692  ins_cost(INSN_COST);
17693  format %{ "shl    $dst, $src, $shift\t# vector (2S)" %}
17694  ins_encode %{
17695    __ shl(as_FloatRegister($dst$$reg), __ T2S,
17696           as_FloatRegister($src$$reg),
17697           (int)$shift$$constant);
17698  %}
17699  ins_pipe(vshift64_imm);
17700%}
17701
17702instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{
17703  predicate(n->as_Vector()->length() == 4);
17704  match(Set dst (LShiftVI src shift));
17705  ins_cost(INSN_COST);
17706  format %{ "shl    $dst, $src, $shift\t# vector (4S)" %}
17707  ins_encode %{
17708    __ shl(as_FloatRegister($dst$$reg), __ T4S,
17709           as_FloatRegister($src$$reg),
17710           (int)$shift$$constant);
17711  %}
17712  ins_pipe(vshift128_imm);
17713%}
17714
17715instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{
17716  predicate(n->as_Vector()->length() == 2);
17717  match(Set dst (RShiftVI src shift));
17718  ins_cost(INSN_COST);
17719  format %{ "sshr    $dst, $src, $shift\t# vector (2S)" %}
17720  ins_encode %{
17721    __ sshr(as_FloatRegister($dst$$reg), __ T2S,
17722            as_FloatRegister($src$$reg),
17723            (int)$shift$$constant);
17724  %}
17725  ins_pipe(vshift64_imm);
17726%}
17727
17728instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{
17729  predicate(n->as_Vector()->length() == 4);
17730  match(Set dst (RShiftVI src shift));
17731  ins_cost(INSN_COST);
17732  format %{ "sshr    $dst, $src, $shift\t# vector (4S)" %}
17733  ins_encode %{
17734    __ sshr(as_FloatRegister($dst$$reg), __ T4S,
17735            as_FloatRegister($src$$reg),
17736            (int)$shift$$constant);
17737  %}
17738  ins_pipe(vshift128_imm);
17739%}
17740
17741instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{
17742  predicate(n->as_Vector()->length() == 2);
17743  match(Set dst (URShiftVI src shift));
17744  ins_cost(INSN_COST);
17745  format %{ "ushr    $dst, $src, $shift\t# vector (2S)" %}
17746  ins_encode %{
17747    __ ushr(as_FloatRegister($dst$$reg), __ T2S,
17748            as_FloatRegister($src$$reg),
17749            (int)$shift$$constant);
17750  %}
17751  ins_pipe(vshift64_imm);
17752%}
17753
17754instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{
17755  predicate(n->as_Vector()->length() == 4);
17756  match(Set dst (URShiftVI src shift));
17757  ins_cost(INSN_COST);
17758  format %{ "ushr    $dst, $src, $shift\t# vector (4S)" %}
17759  ins_encode %{
17760    __ ushr(as_FloatRegister($dst$$reg), __ T4S,
17761            as_FloatRegister($src$$reg),
17762            (int)$shift$$constant);
17763  %}
17764  ins_pipe(vshift128_imm);
17765%}
17766
17767instruct vsll2L(vecX dst, vecX src, vecX shift) %{
17768  predicate(n->as_Vector()->length() == 2);
17769  match(Set dst (LShiftVL src shift));
17770  ins_cost(INSN_COST);
17771  format %{ "sshl  $dst,$src,$shift\t# vector (2D)" %}
17772  ins_encode %{
17773    __ sshl(as_FloatRegister($dst$$reg), __ T2D,
17774            as_FloatRegister($src$$reg),
17775            as_FloatRegister($shift$$reg));
17776  %}
17777  ins_pipe(vshift128);
17778%}
17779
17780instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{
17781  predicate(n->as_Vector()->length() == 2);
17782  match(Set dst (RShiftVL src shift));
17783  ins_cost(INSN_COST);
17784  effect(TEMP tmp);
17785  format %{ "negr  $tmp,$shift\t"
17786            "sshl  $dst,$src,$tmp\t# vector (2D)" %}
17787  ins_encode %{
17788    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
17789            as_FloatRegister($shift$$reg));
17790    __ sshl(as_FloatRegister($dst$$reg), __ T2D,
17791            as_FloatRegister($src$$reg),
17792            as_FloatRegister($tmp$$reg));
17793  %}
17794  ins_pipe(vshift128);
17795%}
17796
17797instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{
17798  predicate(n->as_Vector()->length() == 2);
17799  match(Set dst (URShiftVL src shift));
17800  ins_cost(INSN_COST);
17801  effect(TEMP tmp);
17802  format %{ "negr  $tmp,$shift\t"
17803            "ushl  $dst,$src,$tmp\t# vector (2D)" %}
17804  ins_encode %{
17805    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
17806            as_FloatRegister($shift$$reg));
17807    __ ushl(as_FloatRegister($dst$$reg), __ T2D,
17808            as_FloatRegister($src$$reg),
17809            as_FloatRegister($tmp$$reg));
17810  %}
17811  ins_pipe(vshift128);
17812%}
17813
17814instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{
17815  predicate(n->as_Vector()->length() == 2);
17816  match(Set dst (LShiftVL src shift));
17817  ins_cost(INSN_COST);
17818  format %{ "shl    $dst, $src, $shift\t# vector (2D)" %}
17819  ins_encode %{
17820    __ shl(as_FloatRegister($dst$$reg), __ T2D,
17821           as_FloatRegister($src$$reg),
17822           (int)$shift$$constant);
17823  %}
17824  ins_pipe(vshift128_imm);
17825%}
17826
17827instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{
17828  predicate(n->as_Vector()->length() == 2);
17829  match(Set dst (RShiftVL src shift));
17830  ins_cost(INSN_COST);
17831  format %{ "sshr    $dst, $src, $shift\t# vector (2D)" %}
17832  ins_encode %{
17833    __ sshr(as_FloatRegister($dst$$reg), __ T2D,
17834            as_FloatRegister($src$$reg),
17835            (int)$shift$$constant);
17836  %}
17837  ins_pipe(vshift128_imm);
17838%}
17839
17840instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{
17841  predicate(n->as_Vector()->length() == 2);
17842  match(Set dst (URShiftVL src shift));
17843  ins_cost(INSN_COST);
17844  format %{ "ushr    $dst, $src, $shift\t# vector (2D)" %}
17845  ins_encode %{
17846    __ ushr(as_FloatRegister($dst$$reg), __ T2D,
17847            as_FloatRegister($src$$reg),
17848            (int)$shift$$constant);
17849  %}
17850  ins_pipe(vshift128_imm);
17851%}
17852
17853instruct vmax2F(vecD dst, vecD src1, vecD src2)
17854%{
17855  predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
17856  match(Set dst (MaxV src1 src2));
17857  ins_cost(INSN_COST);
17858  format %{ "fmax  $dst,$src1,$src2\t# vector (2F)" %}
17859  ins_encode %{
17860    __ fmax(as_FloatRegister($dst$$reg), __ T2S,
17861            as_FloatRegister($src1$$reg),
17862            as_FloatRegister($src2$$reg));
17863  %}
17864  ins_pipe(vdop_fp64);
17865%}
17866
17867instruct vmax4F(vecX dst, vecX src1, vecX src2)
17868%{
17869  predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
17870  match(Set dst (MaxV src1 src2));
17871  ins_cost(INSN_COST);
17872  format %{ "fmax  $dst,$src1,$src2\t# vector (4S)" %}
17873  ins_encode %{
17874    __ fmax(as_FloatRegister($dst$$reg), __ T4S,
17875            as_FloatRegister($src1$$reg),
17876            as_FloatRegister($src2$$reg));
17877  %}
17878  ins_pipe(vdop_fp128);
17879%}
17880
17881instruct vmax2D(vecX dst, vecX src1, vecX src2)
17882%{
17883  predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
17884  match(Set dst (MaxV src1 src2));
17885  ins_cost(INSN_COST);
17886  format %{ "fmax  $dst,$src1,$src2\t# vector (2D)" %}
17887  ins_encode %{
17888    __ fmax(as_FloatRegister($dst$$reg), __ T2D,
17889            as_FloatRegister($src1$$reg),
17890            as_FloatRegister($src2$$reg));
17891  %}
17892  ins_pipe(vdop_fp128);
17893%}
17894
17895instruct vmin2F(vecD dst, vecD src1, vecD src2)
17896%{
17897  predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
17898  match(Set dst (MinV src1 src2));
17899  ins_cost(INSN_COST);
17900  format %{ "fmin  $dst,$src1,$src2\t# vector (2F)" %}
17901  ins_encode %{
17902    __ fmin(as_FloatRegister($dst$$reg), __ T2S,
17903            as_FloatRegister($src1$$reg),
17904            as_FloatRegister($src2$$reg));
17905  %}
17906  ins_pipe(vdop_fp64);
17907%}
17908
17909instruct vmin4F(vecX dst, vecX src1, vecX src2)
17910%{
17911  predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
17912  match(Set dst (MinV src1 src2));
17913  ins_cost(INSN_COST);
17914  format %{ "fmin  $dst,$src1,$src2\t# vector (4S)" %}
17915  ins_encode %{
17916    __ fmin(as_FloatRegister($dst$$reg), __ T4S,
17917            as_FloatRegister($src1$$reg),
17918            as_FloatRegister($src2$$reg));
17919  %}
17920  ins_pipe(vdop_fp128);
17921%}
17922
17923instruct vmin2D(vecX dst, vecX src1, vecX src2)
17924%{
17925  predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
17926  match(Set dst (MinV src1 src2));
17927  ins_cost(INSN_COST);
17928  format %{ "fmin  $dst,$src1,$src2\t# vector (2D)" %}
17929  ins_encode %{
17930    __ fmin(as_FloatRegister($dst$$reg), __ T2D,
17931            as_FloatRegister($src1$$reg),
17932            as_FloatRegister($src2$$reg));
17933  %}
17934  ins_pipe(vdop_fp128);
17935%}
17936
17937instruct vpopcount4I(vecX dst, vecX src) %{
17938  predicate(UsePopCountInstruction && n->as_Vector()->length() == 4);
17939  match(Set dst (PopCountVI src));
17940  format %{
17941    "cnt     $dst, $src\t# vector (16B)\n\t"
17942    "uaddlp  $dst, $dst\t# vector (16B)\n\t"
17943    "uaddlp  $dst, $dst\t# vector (8H)"
17944  %}
17945  ins_encode %{
17946     __ cnt(as_FloatRegister($dst$$reg), __ T16B,
17947            as_FloatRegister($src$$reg));
17948     __ uaddlp(as_FloatRegister($dst$$reg), __ T16B,
17949               as_FloatRegister($dst$$reg));
17950     __ uaddlp(as_FloatRegister($dst$$reg), __ T8H,
17951               as_FloatRegister($dst$$reg));
17952  %}
17953  ins_pipe(pipe_class_default);
17954%}
17955
17956instruct vpopcount2I(vecD dst, vecD src) %{
17957  predicate(UsePopCountInstruction && n->as_Vector()->length() == 2);
17958  match(Set dst (PopCountVI src));
17959  format %{
17960    "cnt     $dst, $src\t# vector (8B)\n\t"
17961    "uaddlp  $dst, $dst\t# vector (8B)\n\t"
17962    "uaddlp  $dst, $dst\t# vector (4H)"
17963  %}
17964  ins_encode %{
17965     __ cnt(as_FloatRegister($dst$$reg), __ T8B,
17966            as_FloatRegister($src$$reg));
17967     __ uaddlp(as_FloatRegister($dst$$reg), __ T8B,
17968               as_FloatRegister($dst$$reg));
17969     __ uaddlp(as_FloatRegister($dst$$reg), __ T4H,
17970               as_FloatRegister($dst$$reg));
17971  %}
17972  ins_pipe(pipe_class_default);
17973%}
17974
17975//----------PEEPHOLE RULES-----------------------------------------------------
17976// These must follow all instruction definitions as they use the names
17977// defined in the instructions definitions.
17978//
17979// peepmatch ( root_instr_name [preceding_instruction]* );
17980//
17981// peepconstraint %{
17982// (instruction_number.operand_name relational_op instruction_number.operand_name
17983//  [, ...] );
17984// // instruction numbers are zero-based using left to right order in peepmatch
17985//
17986// peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
17987// // provide an instruction_number.operand_name for each operand that appears
17988// // in the replacement instruction's match rule
17989//
17990// ---------VM FLAGS---------------------------------------------------------
17991//
17992// All peephole optimizations can be turned off using -XX:-OptoPeephole
17993//
17994// Each peephole rule is given an identifying number starting with zero and
17995// increasing by one in the order seen by the parser.  An individual peephole
17996// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
17997// on the command-line.
17998//
17999// ---------CURRENT LIMITATIONS----------------------------------------------
18000//
18001// Only match adjacent instructions in same basic block
18002// Only equality constraints
18003// Only constraints between operands, not (0.dest_reg == RAX_enc)
18004// Only one replacement instruction
18005//
18006// ---------EXAMPLE----------------------------------------------------------
18007//
18008// // pertinent parts of existing instructions in architecture description
18009// instruct movI(iRegINoSp dst, iRegI src)
18010// %{
18011//   match(Set dst (CopyI src));
18012// %}
18013//
18014// instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr)
18015// %{
18016//   match(Set dst (AddI dst src));
18017//   effect(KILL cr);
18018// %}
18019//
18020// // Change (inc mov) to lea
18021// peephole %{
18022//   // increment preceeded by register-register move
18023//   peepmatch ( incI_iReg movI );
18024//   // require that the destination register of the increment
18025//   // match the destination register of the move
18026//   peepconstraint ( 0.dst == 1.dst );
18027//   // construct a replacement instruction that sets
18028//   // the destination to ( move's source register + one )
18029//   peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) );
18030// %}
18031//
18032
18033// Implementation no longer uses movX instructions since
18034// machine-independent system no longer uses CopyX nodes.
18035//
18036// peephole
18037// %{
18038//   peepmatch (incI_iReg movI);
18039//   peepconstraint (0.dst == 1.dst);
18040//   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
18041// %}
18042
18043// peephole
18044// %{
18045//   peepmatch (decI_iReg movI);
18046//   peepconstraint (0.dst == 1.dst);
18047//   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
18048// %}
18049
18050// peephole
18051// %{
18052//   peepmatch (addI_iReg_imm movI);
18053//   peepconstraint (0.dst == 1.dst);
18054//   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
18055// %}
18056
18057// peephole
18058// %{
18059//   peepmatch (incL_iReg movL);
18060//   peepconstraint (0.dst == 1.dst);
18061//   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
18062// %}
18063
18064// peephole
18065// %{
18066//   peepmatch (decL_iReg movL);
18067//   peepconstraint (0.dst == 1.dst);
18068//   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
18069// %}
18070
18071// peephole
18072// %{
18073//   peepmatch (addL_iReg_imm movL);
18074//   peepconstraint (0.dst == 1.dst);
18075//   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
18076// %}
18077
18078// peephole
18079// %{
18080//   peepmatch (addP_iReg_imm movP);
18081//   peepconstraint (0.dst == 1.dst);
18082//   peepreplace (leaP_iReg_imm(0.dst 1.src 0.src));
18083// %}
18084
18085// // Change load of spilled value to only a spill
18086// instruct storeI(memory mem, iRegI src)
18087// %{
18088//   match(Set mem (StoreI mem src));
18089// %}
18090//
18091// instruct loadI(iRegINoSp dst, memory mem)
18092// %{
18093//   match(Set dst (LoadI mem));
18094// %}
18095//
18096
18097//----------SMARTSPILL RULES---------------------------------------------------
18098// These must follow all instruction definitions as they use the names
18099// defined in the instructions definitions.
18100
18101// Local Variables:
18102// mode: c++
18103// End:
18104