1//
2// Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3// Copyright (c) 2014, 2019, Red Hat Inc.
4// All rights reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6//
7// This code is free software; you can redistribute it and/or modify it
8// under the terms of the GNU General Public License version 2 only, as
9// published by the Free Software Foundation.
10//
11// This code is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14// version 2 for more details (a copy is included in the LICENSE file that
15// accompanied this code).
16//
17// You should have received a copy of the GNU General Public License version
18// 2 along with this work; if not, write to the Free Software Foundation,
19// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22// or visit www.oracle.com if you need additional information or have any
23// questions.
24//
25//
26
27// AArch64 Architecture Description File
28
29//----------REGISTER DEFINITION BLOCK------------------------------------------
30// This information is used by the matcher and the register allocator to
31// describe individual registers and classes of registers within the target
32// archtecture.
33
34register %{
35//----------Architecture Description Register Definitions----------------------
36// General Registers
37// "reg_def"  name ( register save type, C convention save type,
38//                   ideal register type, encoding );
39// Register Save Types:
40//
41// NS  = No-Save:       The register allocator assumes that these registers
42//                      can be used without saving upon entry to the method, &
43//                      that they do not need to be saved at call sites.
44//
45// SOC = Save-On-Call:  The register allocator assumes that these registers
46//                      can be used without saving upon entry to the method,
47//                      but that they must be saved at call sites.
48//
49// SOE = Save-On-Entry: The register allocator assumes that these registers
50//                      must be saved before using them upon entry to the
51//                      method, but they do not need to be saved at call
52//                      sites.
53//
54// AS  = Always-Save:   The register allocator assumes that these registers
55//                      must be saved before using them upon entry to the
56//                      method, & that they must be saved at call sites.
57//
58// Ideal Register Type is used to determine how to save & restore a
59// register.  Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
60// spilled with LoadP/StoreP.  If the register supports both, use Op_RegI.
61//
62// The encoding number is the actual bit-pattern placed into the opcodes.
63
64// We must define the 64 bit int registers in two 32 bit halves, the
65// real lower register and a virtual upper half register. upper halves
66// are used by the register allocator but are not actually supplied as
67// operands to memory ops.
68//
69// follow the C1 compiler in making registers
70//
71//   r0-r7,r10-r26 volatile (caller save)
72//   r27-r32 system (no save, no allocate)
73//   r8-r9 invisible to the allocator (so we can use them as scratch regs)
74//
75// as regards Java usage. we don't use any callee save registers
76// because this makes it difficult to de-optimise a frame (see comment
77// in x86 implementation of Deoptimization::unwind_callee_save_values)
78//
79
80// General Registers
81
82reg_def R0      ( SOC, SOC, Op_RegI,  0, r0->as_VMReg()         );
83reg_def R0_H    ( SOC, SOC, Op_RegI,  0, r0->as_VMReg()->next() );
84reg_def R1      ( SOC, SOC, Op_RegI,  1, r1->as_VMReg()         );
85reg_def R1_H    ( SOC, SOC, Op_RegI,  1, r1->as_VMReg()->next() );
86reg_def R2      ( SOC, SOC, Op_RegI,  2, r2->as_VMReg()         );
87reg_def R2_H    ( SOC, SOC, Op_RegI,  2, r2->as_VMReg()->next() );
88reg_def R3      ( SOC, SOC, Op_RegI,  3, r3->as_VMReg()         );
89reg_def R3_H    ( SOC, SOC, Op_RegI,  3, r3->as_VMReg()->next() );
90reg_def R4      ( SOC, SOC, Op_RegI,  4, r4->as_VMReg()         );
91reg_def R4_H    ( SOC, SOC, Op_RegI,  4, r4->as_VMReg()->next() );
92reg_def R5      ( SOC, SOC, Op_RegI,  5, r5->as_VMReg()         );
93reg_def R5_H    ( SOC, SOC, Op_RegI,  5, r5->as_VMReg()->next() );
94reg_def R6      ( SOC, SOC, Op_RegI,  6, r6->as_VMReg()         );
95reg_def R6_H    ( SOC, SOC, Op_RegI,  6, r6->as_VMReg()->next() );
96reg_def R7      ( SOC, SOC, Op_RegI,  7, r7->as_VMReg()         );
97reg_def R7_H    ( SOC, SOC, Op_RegI,  7, r7->as_VMReg()->next() );
98reg_def R10     ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()        );
99reg_def R10_H   ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
100reg_def R11     ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()        );
101reg_def R11_H   ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
102reg_def R12     ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()        );
103reg_def R12_H   ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next());
104reg_def R13     ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()        );
105reg_def R13_H   ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next());
106reg_def R14     ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()        );
107reg_def R14_H   ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next());
108reg_def R15     ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()        );
109reg_def R15_H   ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next());
110reg_def R16     ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()        );
111reg_def R16_H   ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next());
112reg_def R17     ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()        );
113reg_def R17_H   ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next());
114reg_def R18     ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()        );
115reg_def R18_H   ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next());
116reg_def R19     ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()        );
117reg_def R19_H   ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next());
118reg_def R20     ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()        ); // caller esp
119reg_def R20_H   ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next());
120reg_def R21     ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()        );
121reg_def R21_H   ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next());
122reg_def R22     ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()        );
123reg_def R22_H   ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next());
124reg_def R23     ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()        );
125reg_def R23_H   ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next());
126reg_def R24     ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()        );
127reg_def R24_H   ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next());
128reg_def R25     ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()        );
129reg_def R25_H   ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next());
130reg_def R26     ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()        );
131reg_def R26_H   ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next());
132reg_def R27     (  NS, SOE, Op_RegI, 27, r27->as_VMReg()        ); // heapbase
133reg_def R27_H   (  NS, SOE, Op_RegI, 27, r27->as_VMReg()->next());
134reg_def R28     (  NS, SOE, Op_RegI, 28, r28->as_VMReg()        ); // thread
135reg_def R28_H   (  NS, SOE, Op_RegI, 28, r28->as_VMReg()->next());
136reg_def R29     (  NS,  NS, Op_RegI, 29, r29->as_VMReg()        ); // fp
137reg_def R29_H   (  NS,  NS, Op_RegI, 29, r29->as_VMReg()->next());
138reg_def R30     (  NS,  NS, Op_RegI, 30, r30->as_VMReg()        ); // lr
139reg_def R30_H   (  NS,  NS, Op_RegI, 30, r30->as_VMReg()->next());
140reg_def R31     (  NS,  NS, Op_RegI, 31, r31_sp->as_VMReg()     ); // sp
141reg_def R31_H   (  NS,  NS, Op_RegI, 31, r31_sp->as_VMReg()->next());
142
143// ----------------------------
144// Float/Double Registers
145// ----------------------------
146
147// Double Registers
148
149// The rules of ADL require that double registers be defined in pairs.
150// Each pair must be two 32-bit values, but not necessarily a pair of
151// single float registers. In each pair, ADLC-assigned register numbers
152// must be adjacent, with the lower number even. Finally, when the
153// CPU stores such a register pair to memory, the word associated with
154// the lower ADLC-assigned number must be stored to the lower address.
155
156// AArch64 has 32 floating-point registers. Each can store a vector of
157// single or double precision floating-point values up to 8 * 32
158// floats, 4 * 64 bit floats or 2 * 128 bit floats.  We currently only
159// use the first float or double element of the vector.
160
161// for Java use float registers v0-v15 are always save on call whereas
162// the platform ABI treats v8-v15 as callee save). float registers
163// v16-v31 are SOC as per the platform spec
164
165  reg_def V0   ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()          );
166  reg_def V0_H ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()->next()  );
167  reg_def V0_J ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()->next(2) );
168  reg_def V0_K ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()->next(3) );
169
170  reg_def V1   ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()          );
171  reg_def V1_H ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()->next()  );
172  reg_def V1_J ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()->next(2) );
173  reg_def V1_K ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()->next(3) );
174
175  reg_def V2   ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()          );
176  reg_def V2_H ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()->next()  );
177  reg_def V2_J ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()->next(2) );
178  reg_def V2_K ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()->next(3) );
179
180  reg_def V3   ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()          );
181  reg_def V3_H ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()->next()  );
182  reg_def V3_J ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()->next(2) );
183  reg_def V3_K ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()->next(3) );
184
185  reg_def V4   ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()          );
186  reg_def V4_H ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()->next()  );
187  reg_def V4_J ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()->next(2) );
188  reg_def V4_K ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()->next(3) );
189
190  reg_def V5   ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()          );
191  reg_def V5_H ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()->next()  );
192  reg_def V5_J ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()->next(2) );
193  reg_def V5_K ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()->next(3) );
194
195  reg_def V6   ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()          );
196  reg_def V6_H ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()->next()  );
197  reg_def V6_J ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()->next(2) );
198  reg_def V6_K ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()->next(3) );
199
200  reg_def V7   ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()          );
201  reg_def V7_H ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()->next()  );
202  reg_def V7_J ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()->next(2) );
203  reg_def V7_K ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()->next(3) );
204
205  reg_def V8   ( SOC, SOC, Op_RegF,  8, v8->as_VMReg()          );
206  reg_def V8_H ( SOC, SOC, Op_RegF,  8, v8->as_VMReg()->next()  );
207  reg_def V8_J ( SOC, SOC, Op_RegF,  8, v8->as_VMReg()->next(2) );
208  reg_def V8_K ( SOC, SOC, Op_RegF,  8, v8->as_VMReg()->next(3) );
209
210  reg_def V9   ( SOC, SOC, Op_RegF,  9, v9->as_VMReg()          );
211  reg_def V9_H ( SOC, SOC, Op_RegF,  9, v9->as_VMReg()->next()  );
212  reg_def V9_J ( SOC, SOC, Op_RegF,  9, v9->as_VMReg()->next(2) );
213  reg_def V9_K ( SOC, SOC, Op_RegF,  9, v9->as_VMReg()->next(3) );
214
215  reg_def V10  ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()         );
216  reg_def V10_H( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next() );
217  reg_def V10_J( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2));
218  reg_def V10_K( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3));
219
220  reg_def V11  ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()         );
221  reg_def V11_H( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next() );
222  reg_def V11_J( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2));
223  reg_def V11_K( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3));
224
225  reg_def V12  ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()         );
226  reg_def V12_H( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next() );
227  reg_def V12_J( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2));
228  reg_def V12_K( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3));
229
230  reg_def V13  ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()         );
231  reg_def V13_H( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next() );
232  reg_def V13_J( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2));
233  reg_def V13_K( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3));
234
235  reg_def V14  ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()         );
236  reg_def V14_H( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next() );
237  reg_def V14_J( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2));
238  reg_def V14_K( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3));
239
240  reg_def V15  ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()         );
241  reg_def V15_H( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next() );
242  reg_def V15_J( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2));
243  reg_def V15_K( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3));
244
245  reg_def V16  ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()         );
246  reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() );
247  reg_def V16_J( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2));
248  reg_def V16_K( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3));
249
250  reg_def V17  ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()         );
251  reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() );
252  reg_def V17_J( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2));
253  reg_def V17_K( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3));
254
255  reg_def V18  ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()         );
256  reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() );
257  reg_def V18_J( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2));
258  reg_def V18_K( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3));
259
260  reg_def V19  ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()         );
261  reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() );
262  reg_def V19_J( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2));
263  reg_def V19_K( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3));
264
265  reg_def V20  ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()         );
266  reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() );
267  reg_def V20_J( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2));
268  reg_def V20_K( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3));
269
270  reg_def V21  ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()         );
271  reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() );
272  reg_def V21_J( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2));
273  reg_def V21_K( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3));
274
275  reg_def V22  ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()         );
276  reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() );
277  reg_def V22_J( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2));
278  reg_def V22_K( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3));
279
280  reg_def V23  ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()         );
281  reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() );
282  reg_def V23_J( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2));
283  reg_def V23_K( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3));
284
285  reg_def V24  ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()         );
286  reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() );
287  reg_def V24_J( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2));
288  reg_def V24_K( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3));
289
290  reg_def V25  ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()         );
291  reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() );
292  reg_def V25_J( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2));
293  reg_def V25_K( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3));
294
295  reg_def V26  ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()         );
296  reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() );
297  reg_def V26_J( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2));
298  reg_def V26_K( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3));
299
300  reg_def V27  ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()         );
301  reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() );
302  reg_def V27_J( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2));
303  reg_def V27_K( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3));
304
305  reg_def V28  ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()         );
306  reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() );
307  reg_def V28_J( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2));
308  reg_def V28_K( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3));
309
310  reg_def V29  ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()         );
311  reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() );
312  reg_def V29_J( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2));
313  reg_def V29_K( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3));
314
315  reg_def V30  ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()         );
316  reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() );
317  reg_def V30_J( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2));
318  reg_def V30_K( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3));
319
320  reg_def V31  ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()         );
321  reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() );
322  reg_def V31_J( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2));
323  reg_def V31_K( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3));
324
325// ----------------------------
326// Special Registers
327// ----------------------------
328
329// the AArch64 CSPR status flag register is not directly acessible as
330// instruction operand. the FPSR status flag register is a system
331// register which can be written/read using MSR/MRS but again does not
332// appear as an operand (a code identifying the FSPR occurs as an
333// immediate value in the instruction).
334
335reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad());
336
337
338// Specify priority of register selection within phases of register
339// allocation.  Highest priority is first.  A useful heuristic is to
340// give registers a low priority when they are required by machine
341// instructions, like EAX and EDX on I486, and choose no-save registers
342// before save-on-call, & save-on-call before save-on-entry.  Registers
343// which participate in fixed calling sequences should come last.
344// Registers which are used as pairs must fall on an even boundary.
345
346alloc_class chunk0(
347    // volatiles
348    R10, R10_H,
349    R11, R11_H,
350    R12, R12_H,
351    R13, R13_H,
352    R14, R14_H,
353    R15, R15_H,
354    R16, R16_H,
355    R17, R17_H,
356    R18, R18_H,
357
358    // arg registers
359    R0, R0_H,
360    R1, R1_H,
361    R2, R2_H,
362    R3, R3_H,
363    R4, R4_H,
364    R5, R5_H,
365    R6, R6_H,
366    R7, R7_H,
367
368    // non-volatiles
369    R19, R19_H,
370    R20, R20_H,
371    R21, R21_H,
372    R22, R22_H,
373    R23, R23_H,
374    R24, R24_H,
375    R25, R25_H,
376    R26, R26_H,
377
378    // non-allocatable registers
379
380    R27, R27_H, // heapbase
381    R28, R28_H, // thread
382    R29, R29_H, // fp
383    R30, R30_H, // lr
384    R31, R31_H, // sp
385);
386
387alloc_class chunk1(
388
389    // no save
390    V16, V16_H, V16_J, V16_K,
391    V17, V17_H, V17_J, V17_K,
392    V18, V18_H, V18_J, V18_K,
393    V19, V19_H, V19_J, V19_K,
394    V20, V20_H, V20_J, V20_K,
395    V21, V21_H, V21_J, V21_K,
396    V22, V22_H, V22_J, V22_K,
397    V23, V23_H, V23_J, V23_K,
398    V24, V24_H, V24_J, V24_K,
399    V25, V25_H, V25_J, V25_K,
400    V26, V26_H, V26_J, V26_K,
401    V27, V27_H, V27_J, V27_K,
402    V28, V28_H, V28_J, V28_K,
403    V29, V29_H, V29_J, V29_K,
404    V30, V30_H, V30_J, V30_K,
405    V31, V31_H, V31_J, V31_K,
406
407    // arg registers
408    V0, V0_H, V0_J, V0_K,
409    V1, V1_H, V1_J, V1_K,
410    V2, V2_H, V2_J, V2_K,
411    V3, V3_H, V3_J, V3_K,
412    V4, V4_H, V4_J, V4_K,
413    V5, V5_H, V5_J, V5_K,
414    V6, V6_H, V6_J, V6_K,
415    V7, V7_H, V7_J, V7_K,
416
417    // non-volatiles
418    V8, V8_H, V8_J, V8_K,
419    V9, V9_H, V9_J, V9_K,
420    V10, V10_H, V10_J, V10_K,
421    V11, V11_H, V11_J, V11_K,
422    V12, V12_H, V12_J, V12_K,
423    V13, V13_H, V13_J, V13_K,
424    V14, V14_H, V14_J, V14_K,
425    V15, V15_H, V15_J, V15_K,
426);
427
428alloc_class chunk2(RFLAGS);
429
430//----------Architecture Description Register Classes--------------------------
431// Several register classes are automatically defined based upon information in
432// this architecture description.
433// 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
434// 2) reg_class compiler_method_oop_reg    ( /* as def'd in frame section */ )
435// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
436// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
437//
438
439// Class for all 32 bit integer registers -- excludes SP which will
440// never be used as an integer register
441reg_class any_reg32(
442    R0,
443    R1,
444    R2,
445    R3,
446    R4,
447    R5,
448    R6,
449    R7,
450    R10,
451    R11,
452    R12,
453    R13,
454    R14,
455    R15,
456    R16,
457    R17,
458    R18,
459    R19,
460    R20,
461    R21,
462    R22,
463    R23,
464    R24,
465    R25,
466    R26,
467    R27,
468    R28,
469    R29,
470    R30
471);
472
473// Singleton class for R0 int register
474reg_class int_r0_reg(R0);
475
476// Singleton class for R2 int register
477reg_class int_r2_reg(R2);
478
479// Singleton class for R3 int register
480reg_class int_r3_reg(R3);
481
482// Singleton class for R4 int register
483reg_class int_r4_reg(R4);
484
485// Class for all long integer registers (including RSP)
486reg_class any_reg(
487    R0, R0_H,
488    R1, R1_H,
489    R2, R2_H,
490    R3, R3_H,
491    R4, R4_H,
492    R5, R5_H,
493    R6, R6_H,
494    R7, R7_H,
495    R10, R10_H,
496    R11, R11_H,
497    R12, R12_H,
498    R13, R13_H,
499    R14, R14_H,
500    R15, R15_H,
501    R16, R16_H,
502    R17, R17_H,
503    R18, R18_H,
504    R19, R19_H,
505    R20, R20_H,
506    R21, R21_H,
507    R22, R22_H,
508    R23, R23_H,
509    R24, R24_H,
510    R25, R25_H,
511    R26, R26_H,
512    R27, R27_H,
513    R28, R28_H,
514    R29, R29_H,
515    R30, R30_H,
516    R31, R31_H
517);
518
519// Class for all non-special integer registers
520reg_class no_special_reg32(
521    R0,
522    R1,
523    R2,
524    R3,
525    R4,
526    R5,
527    R6,
528    R7,
529    R10,
530    R11,
531    R12,			// rmethod
532    R13,
533    R14,
534    R15,
535    R16,
536    R17,
537    R18,
538    R19,
539    R20,
540    R21,
541    R22,
542    R23,
543    R24,
544    R25,
545    R26
546 /* R27, */			// heapbase
547 /* R28, */			// thread
548 /* R29, */                     // fp
549 /* R30, */			// lr
550 /* R31 */			// sp
551);
552
553// Class for all non-special long integer registers
554reg_class no_special_reg(
555    R0, R0_H,
556    R1, R1_H,
557    R2, R2_H,
558    R3, R3_H,
559    R4, R4_H,
560    R5, R5_H,
561    R6, R6_H,
562    R7, R7_H,
563    R10, R10_H,
564    R11, R11_H,
565    R12, R12_H,			// rmethod
566    R13, R13_H,
567    R14, R14_H,
568    R15, R15_H,
569    R16, R16_H,
570    R17, R17_H,
571    R18, R18_H,
572    R19, R19_H,
573    R20, R20_H,
574    R21, R21_H,
575    R22, R22_H,
576    R23, R23_H,
577    R24, R24_H,
578    R25, R25_H,
579    R26, R26_H,
580 /* R27, R27_H,	*/		// heapbase
581 /* R28, R28_H, */		// thread
582 /* R29, R29_H, */              // fp
583 /* R30, R30_H, */		// lr
584 /* R31, R31_H */		// sp
585);
586
587// Class for 64 bit register r0
588reg_class r0_reg(
589    R0, R0_H
590);
591
592// Class for 64 bit register r1
593reg_class r1_reg(
594    R1, R1_H
595);
596
597// Class for 64 bit register r2
598reg_class r2_reg(
599    R2, R2_H
600);
601
602// Class for 64 bit register r3
603reg_class r3_reg(
604    R3, R3_H
605);
606
607// Class for 64 bit register r4
608reg_class r4_reg(
609    R4, R4_H
610);
611
612// Class for 64 bit register r5
613reg_class r5_reg(
614    R5, R5_H
615);
616
617// Class for 64 bit register r10
618reg_class r10_reg(
619    R10, R10_H
620);
621
622// Class for 64 bit register r11
623reg_class r11_reg(
624    R11, R11_H
625);
626
627// Class for method register
628reg_class method_reg(
629    R12, R12_H
630);
631
632// Class for heapbase register
633reg_class heapbase_reg(
634    R27, R27_H
635);
636
637// Class for thread register
638reg_class thread_reg(
639    R28, R28_H
640);
641
642// Class for frame pointer register
643reg_class fp_reg(
644    R29, R29_H
645);
646
647// Class for link register
648reg_class lr_reg(
649    R30, R30_H
650);
651
652// Class for long sp register
653reg_class sp_reg(
654  R31, R31_H
655);
656
657// Class for all pointer registers
658reg_class ptr_reg(
659    R0, R0_H,
660    R1, R1_H,
661    R2, R2_H,
662    R3, R3_H,
663    R4, R4_H,
664    R5, R5_H,
665    R6, R6_H,
666    R7, R7_H,
667    R10, R10_H,
668    R11, R11_H,
669    R12, R12_H,
670    R13, R13_H,
671    R14, R14_H,
672    R15, R15_H,
673    R16, R16_H,
674    R17, R17_H,
675    R18, R18_H,
676    R19, R19_H,
677    R20, R20_H,
678    R21, R21_H,
679    R22, R22_H,
680    R23, R23_H,
681    R24, R24_H,
682    R25, R25_H,
683    R26, R26_H,
684    R27, R27_H,
685    R28, R28_H,
686    R29, R29_H,
687    R30, R30_H,
688    R31, R31_H
689);
690
691// Class for all non_special pointer registers
692reg_class no_special_ptr_reg(
693    R0, R0_H,
694    R1, R1_H,
695    R2, R2_H,
696    R3, R3_H,
697    R4, R4_H,
698    R5, R5_H,
699    R6, R6_H,
700    R7, R7_H,
701    R10, R10_H,
702    R11, R11_H,
703    R12, R12_H,
704    R13, R13_H,
705    R14, R14_H,
706    R15, R15_H,
707    R16, R16_H,
708    R17, R17_H,
709    R18, R18_H,
710    R19, R19_H,
711    R20, R20_H,
712    R21, R21_H,
713    R22, R22_H,
714    R23, R23_H,
715    R24, R24_H,
716    R25, R25_H,
717    R26, R26_H,
718 /* R27, R27_H, */		// heapbase
719 /* R28, R28_H, */		// thread
720 /* R29, R29_H, */		// fp
721 /* R30, R30_H, */		// lr
722 /* R31, R31_H */		// sp
723);
724
725// Class for all float registers
726reg_class float_reg(
727    V0,
728    V1,
729    V2,
730    V3,
731    V4,
732    V5,
733    V6,
734    V7,
735    V8,
736    V9,
737    V10,
738    V11,
739    V12,
740    V13,
741    V14,
742    V15,
743    V16,
744    V17,
745    V18,
746    V19,
747    V20,
748    V21,
749    V22,
750    V23,
751    V24,
752    V25,
753    V26,
754    V27,
755    V28,
756    V29,
757    V30,
758    V31
759);
760
761// Double precision float registers have virtual `high halves' that
762// are needed by the allocator.
763// Class for all double registers
764reg_class double_reg(
765    V0, V0_H,
766    V1, V1_H,
767    V2, V2_H,
768    V3, V3_H,
769    V4, V4_H,
770    V5, V5_H,
771    V6, V6_H,
772    V7, V7_H,
773    V8, V8_H,
774    V9, V9_H,
775    V10, V10_H,
776    V11, V11_H,
777    V12, V12_H,
778    V13, V13_H,
779    V14, V14_H,
780    V15, V15_H,
781    V16, V16_H,
782    V17, V17_H,
783    V18, V18_H,
784    V19, V19_H,
785    V20, V20_H,
786    V21, V21_H,
787    V22, V22_H,
788    V23, V23_H,
789    V24, V24_H,
790    V25, V25_H,
791    V26, V26_H,
792    V27, V27_H,
793    V28, V28_H,
794    V29, V29_H,
795    V30, V30_H,
796    V31, V31_H
797);
798
799// Class for all 64bit vector registers
800reg_class vectord_reg(
801    V0, V0_H,
802    V1, V1_H,
803    V2, V2_H,
804    V3, V3_H,
805    V4, V4_H,
806    V5, V5_H,
807    V6, V6_H,
808    V7, V7_H,
809    V8, V8_H,
810    V9, V9_H,
811    V10, V10_H,
812    V11, V11_H,
813    V12, V12_H,
814    V13, V13_H,
815    V14, V14_H,
816    V15, V15_H,
817    V16, V16_H,
818    V17, V17_H,
819    V18, V18_H,
820    V19, V19_H,
821    V20, V20_H,
822    V21, V21_H,
823    V22, V22_H,
824    V23, V23_H,
825    V24, V24_H,
826    V25, V25_H,
827    V26, V26_H,
828    V27, V27_H,
829    V28, V28_H,
830    V29, V29_H,
831    V30, V30_H,
832    V31, V31_H
833);
834
835// Class for all 128bit vector registers
836reg_class vectorx_reg(
837    V0, V0_H, V0_J, V0_K,
838    V1, V1_H, V1_J, V1_K,
839    V2, V2_H, V2_J, V2_K,
840    V3, V3_H, V3_J, V3_K,
841    V4, V4_H, V4_J, V4_K,
842    V5, V5_H, V5_J, V5_K,
843    V6, V6_H, V6_J, V6_K,
844    V7, V7_H, V7_J, V7_K,
845    V8, V8_H, V8_J, V8_K,
846    V9, V9_H, V9_J, V9_K,
847    V10, V10_H, V10_J, V10_K,
848    V11, V11_H, V11_J, V11_K,
849    V12, V12_H, V12_J, V12_K,
850    V13, V13_H, V13_J, V13_K,
851    V14, V14_H, V14_J, V14_K,
852    V15, V15_H, V15_J, V15_K,
853    V16, V16_H, V16_J, V16_K,
854    V17, V17_H, V17_J, V17_K,
855    V18, V18_H, V18_J, V18_K,
856    V19, V19_H, V19_J, V19_K,
857    V20, V20_H, V20_J, V20_K,
858    V21, V21_H, V21_J, V21_K,
859    V22, V22_H, V22_J, V22_K,
860    V23, V23_H, V23_J, V23_K,
861    V24, V24_H, V24_J, V24_K,
862    V25, V25_H, V25_J, V25_K,
863    V26, V26_H, V26_J, V26_K,
864    V27, V27_H, V27_J, V27_K,
865    V28, V28_H, V28_J, V28_K,
866    V29, V29_H, V29_J, V29_K,
867    V30, V30_H, V30_J, V30_K,
868    V31, V31_H, V31_J, V31_K
869);
870
871// Class for 128 bit register v0
872reg_class v0_reg(
873    V0, V0_H
874);
875
876// Class for 128 bit register v1
877reg_class v1_reg(
878    V1, V1_H
879);
880
881// Class for 128 bit register v2
882reg_class v2_reg(
883    V2, V2_H
884);
885
886// Class for 128 bit register v3
887reg_class v3_reg(
888    V3, V3_H
889);
890
891// Singleton class for condition codes
892reg_class int_flags(RFLAGS);
893
894%}
895
896//----------DEFINITION BLOCK---------------------------------------------------
897// Define name --> value mappings to inform the ADLC of an integer valued name
898// Current support includes integer values in the range [0, 0x7FFFFFFF]
899// Format:
900//        int_def  <name>         ( <int_value>, <expression>);
901// Generated Code in ad_<arch>.hpp
902//        #define  <name>   (<expression>)
903//        // value == <int_value>
904// Generated code in ad_<arch>.cpp adlc_verification()
905//        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
906//
907
908// we follow the ppc-aix port in using a simple cost model which ranks
909// register operations as cheap, memory ops as more expensive and
910// branches as most expensive. the first two have a low as well as a
911// normal cost. huge cost appears to be a way of saying don't do
912// something
913
914definitions %{
915  // The default cost (of a register move instruction).
916  int_def INSN_COST            (    100,     100);
917  int_def BRANCH_COST          (    200,     2 * INSN_COST);
918  int_def CALL_COST            (    200,     2 * INSN_COST);
919  int_def VOLATILE_REF_COST    (   1000,     10 * INSN_COST);
920%}
921
922
923//----------SOURCE BLOCK-------------------------------------------------------
924// This is a block of C++ code which provides values, functions, and
925// definitions necessary in the rest of the architecture description
926
927source_hpp %{
928
929#include "opto/addnode.hpp"
930
931class CallStubImpl {
932
933  //--------------------------------------------------------------
934  //---<  Used for optimization in Compile::shorten_branches  >---
935  //--------------------------------------------------------------
936
937 public:
938  // Size of call trampoline stub.
939  static uint size_call_trampoline() {
940    return 0; // no call trampolines on this platform
941  }
942
943  // number of relocations needed by a call trampoline stub
944  static uint reloc_call_trampoline() {
945    return 0; // no call trampolines on this platform
946  }
947};
948
949class HandlerImpl {
950
951 public:
952
953  static int emit_exception_handler(CodeBuffer &cbuf);
954  static int emit_deopt_handler(CodeBuffer& cbuf);
955
956  static uint size_exception_handler() {
957    return MacroAssembler::far_branch_size();
958  }
959
960  static uint size_deopt_handler() {
961    // count one adr and one far branch instruction
962    // return 4 * NativeInstruction::instruction_size;
963    return NativeInstruction::instruction_size + MacroAssembler::far_branch_size();
964  }
965};
966
967  bool is_CAS(int opcode);
968
969  // predicates controlling emit of ldr<x>/ldar<x> and associated dmb
970
971  bool unnecessary_acquire(const Node *barrier);
972  bool needs_acquiring_load(const Node *load);
973
974  // predicates controlling emit of str<x>/stlr<x> and associated dmbs
975
976  bool unnecessary_release(const Node *barrier);
977  bool unnecessary_volatile(const Node *barrier);
978  bool needs_releasing_store(const Node *store);
979
980  // predicate controlling translation of CompareAndSwapX
981  bool needs_acquiring_load_exclusive(const Node *load);
982
983  // predicate controlling translation of StoreCM
984  bool unnecessary_storestore(const Node *storecm);
985
986  // predicate controlling addressing modes
987  bool size_fits_all_mem_uses(AddPNode* addp, int shift);
988%}
989
990source %{
991
992  // Optimizaton of volatile gets and puts
993  // -------------------------------------
994  //
995  // AArch64 has ldar<x> and stlr<x> instructions which we can safely
996  // use to implement volatile reads and writes. For a volatile read
997  // we simply need
998  //
999  //   ldar<x>
1000  //
1001  // and for a volatile write we need
1002  //
1003  //   stlr<x>
1004  //
1005  // Alternatively, we can implement them by pairing a normal
1006  // load/store with a memory barrier. For a volatile read we need
1007  //
1008  //   ldr<x>
1009  //   dmb ishld
1010  //
1011  // for a volatile write
1012  //
1013  //   dmb ish
1014  //   str<x>
1015  //   dmb ish
1016  //
1017  // We can also use ldaxr and stlxr to implement compare and swap CAS
1018  // sequences. These are normally translated to an instruction
1019  // sequence like the following
1020  //
1021  //   dmb      ish
1022  // retry:
1023  //   ldxr<x>   rval raddr
1024  //   cmp       rval rold
1025  //   b.ne done
1026  //   stlxr<x>  rval, rnew, rold
1027  //   cbnz      rval retry
1028  // done:
1029  //   cset      r0, eq
1030  //   dmb ishld
1031  //
1032  // Note that the exclusive store is already using an stlxr
1033  // instruction. That is required to ensure visibility to other
1034  // threads of the exclusive write (assuming it succeeds) before that
1035  // of any subsequent writes.
1036  //
1037  // The following instruction sequence is an improvement on the above
1038  //
1039  // retry:
1040  //   ldaxr<x>  rval raddr
1041  //   cmp       rval rold
1042  //   b.ne done
1043  //   stlxr<x>  rval, rnew, rold
1044  //   cbnz      rval retry
1045  // done:
1046  //   cset      r0, eq
1047  //
1048  // We don't need the leading dmb ish since the stlxr guarantees
1049  // visibility of prior writes in the case that the swap is
1050  // successful. Crucially we don't have to worry about the case where
1051  // the swap is not successful since no valid program should be
1052  // relying on visibility of prior changes by the attempting thread
1053  // in the case where the CAS fails.
1054  //
1055  // Similarly, we don't need the trailing dmb ishld if we substitute
1056  // an ldaxr instruction since that will provide all the guarantees we
1057  // require regarding observation of changes made by other threads
1058  // before any change to the CAS address observed by the load.
1059  //
1060  // In order to generate the desired instruction sequence we need to
1061  // be able to identify specific 'signature' ideal graph node
1062  // sequences which i) occur as a translation of a volatile reads or
1063  // writes or CAS operations and ii) do not occur through any other
1064  // translation or graph transformation. We can then provide
1065  // alternative aldc matching rules which translate these node
1066  // sequences to the desired machine code sequences. Selection of the
1067  // alternative rules can be implemented by predicates which identify
1068  // the relevant node sequences.
1069  //
1070  // The ideal graph generator translates a volatile read to the node
1071  // sequence
1072  //
1073  //   LoadX[mo_acquire]
1074  //   MemBarAcquire
1075  //
1076  // As a special case when using the compressed oops optimization we
1077  // may also see this variant
1078  //
1079  //   LoadN[mo_acquire]
1080  //   DecodeN
1081  //   MemBarAcquire
1082  //
1083  // A volatile write is translated to the node sequence
1084  //
1085  //   MemBarRelease
1086  //   StoreX[mo_release] {CardMark}-optional
1087  //   MemBarVolatile
1088  //
1089  // n.b. the above node patterns are generated with a strict
1090  // 'signature' configuration of input and output dependencies (see
1091  // the predicates below for exact details). The card mark may be as
1092  // simple as a few extra nodes or, in a few GC configurations, may
1093  // include more complex control flow between the leading and
1094  // trailing memory barriers. However, whatever the card mark
1095  // configuration these signatures are unique to translated volatile
1096  // reads/stores -- they will not appear as a result of any other
1097  // bytecode translation or inlining nor as a consequence of
1098  // optimizing transforms.
1099  //
1100  // We also want to catch inlined unsafe volatile gets and puts and
1101  // be able to implement them using either ldar<x>/stlr<x> or some
1102  // combination of ldr<x>/stlr<x> and dmb instructions.
1103  //
1104  // Inlined unsafe volatiles puts manifest as a minor variant of the
1105  // normal volatile put node sequence containing an extra cpuorder
1106  // membar
1107  //
1108  //   MemBarRelease
1109  //   MemBarCPUOrder
1110  //   StoreX[mo_release] {CardMark}-optional
1111  //   MemBarVolatile
1112  //
1113  // n.b. as an aside, the cpuorder membar is not itself subject to
1114  // matching and translation by adlc rules.  However, the rule
1115  // predicates need to detect its presence in order to correctly
1116  // select the desired adlc rules.
1117  //
1118  // Inlined unsafe volatile gets manifest as a somewhat different
1119  // node sequence to a normal volatile get
1120  //
1121  //   MemBarCPUOrder
1122  //        ||       \\
1123  //   MemBarAcquire LoadX[mo_acquire]
1124  //        ||
1125  //   MemBarCPUOrder
1126  //
1127  // In this case the acquire membar does not directly depend on the
1128  // load. However, we can be sure that the load is generated from an
1129  // inlined unsafe volatile get if we see it dependent on this unique
1130  // sequence of membar nodes. Similarly, given an acquire membar we
1131  // can know that it was added because of an inlined unsafe volatile
1132  // get if it is fed and feeds a cpuorder membar and if its feed
1133  // membar also feeds an acquiring load.
1134  //
1135  // Finally an inlined (Unsafe) CAS operation is translated to the
1136  // following ideal graph
1137  //
1138  //   MemBarRelease
1139  //   MemBarCPUOrder
1140  //   CompareAndSwapX {CardMark}-optional
1141  //   MemBarCPUOrder
1142  //   MemBarAcquire
1143  //
1144  // So, where we can identify these volatile read and write
1145  // signatures we can choose to plant either of the above two code
1146  // sequences. For a volatile read we can simply plant a normal
1147  // ldr<x> and translate the MemBarAcquire to a dmb. However, we can
1148  // also choose to inhibit translation of the MemBarAcquire and
1149  // inhibit planting of the ldr<x>, instead planting an ldar<x>.
1150  //
1151  // When we recognise a volatile store signature we can choose to
1152  // plant at a dmb ish as a translation for the MemBarRelease, a
1153  // normal str<x> and then a dmb ish for the MemBarVolatile.
1154  // Alternatively, we can inhibit translation of the MemBarRelease
1155  // and MemBarVolatile and instead plant a simple stlr<x>
1156  // instruction.
1157  //
1158  // when we recognise a CAS signature we can choose to plant a dmb
1159  // ish as a translation for the MemBarRelease, the conventional
1160  // macro-instruction sequence for the CompareAndSwap node (which
1161  // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire.
1162  // Alternatively, we can elide generation of the dmb instructions
1163  // and plant the alternative CompareAndSwap macro-instruction
1164  // sequence (which uses ldaxr<x>).
1165  //
1166  // Of course, the above only applies when we see these signature
1167  // configurations. We still want to plant dmb instructions in any
1168  // other cases where we may see a MemBarAcquire, MemBarRelease or
1169  // MemBarVolatile. For example, at the end of a constructor which
1170  // writes final/volatile fields we will see a MemBarRelease
1171  // instruction and this needs a 'dmb ish' lest we risk the
1172  // constructed object being visible without making the
1173  // final/volatile field writes visible.
1174  //
1175  // n.b. the translation rules below which rely on detection of the
1176  // volatile signatures and insert ldar<x> or stlr<x> are failsafe.
1177  // If we see anything other than the signature configurations we
1178  // always just translate the loads and stores to ldr<x> and str<x>
1179  // and translate acquire, release and volatile membars to the
1180  // relevant dmb instructions.
1181  //
1182
1183  // is_CAS(int opcode)
1184  //
1185  // return true if opcode is one of the possible CompareAndSwapX
1186  // values otherwise false.
1187
1188  bool is_CAS(int opcode)
1189  {
1190    switch(opcode) {
1191    // We handle these
1192    case Op_CompareAndSwapI:
1193    case Op_CompareAndSwapL:
1194    case Op_CompareAndSwapP:
1195    case Op_CompareAndSwapN:
1196    case Op_GetAndSetI:
1197    case Op_GetAndSetL:
1198    case Op_GetAndSetP:
1199    case Op_GetAndSetN:
1200    case Op_GetAndAddI:
1201    case Op_GetAndAddL:
1202      return true;
1203    default:
1204      return false;
1205    }
1206  }
1207
1208// predicates controlling emit of ldr<x>/ldar<x> and associated dmb
1209
1210bool unnecessary_acquire(const Node *barrier)
1211{
1212  assert(barrier->is_MemBar(), "expecting a membar");
1213
1214  if (UseBarriersForVolatile) {
1215    // we need to plant a dmb
1216    return false;
1217  }
1218
1219  MemBarNode* mb = barrier->as_MemBar();
1220
1221  if (mb->trailing_load()) {
1222    return true;
1223  }
1224
1225  if (mb->trailing_load_store()) {
1226    Node* load_store = mb->in(MemBarNode::Precedent);
1227    assert(load_store->is_LoadStore(), "unexpected graph shape");
1228    return is_CAS(load_store->Opcode());
1229  }
1230
1231  return false;
1232}
1233
1234bool needs_acquiring_load(const Node *n)
1235{
1236  assert(n->is_Load(), "expecting a load");
1237  if (UseBarriersForVolatile) {
1238    // we use a normal load and a dmb
1239    return false;
1240  }
1241
1242  LoadNode *ld = n->as_Load();
1243
1244  return ld->is_acquire();
1245}
1246
1247bool unnecessary_release(const Node *n)
1248{
1249  assert((n->is_MemBar() &&
1250	  n->Opcode() == Op_MemBarRelease),
1251	 "expecting a release membar");
1252
1253  if (UseBarriersForVolatile) {
1254    // we need to plant a dmb
1255    return false;
1256  }
1257
1258  MemBarNode *barrier = n->as_MemBar();
1259
1260  if (!barrier->leading()) {
1261    return false;
1262  } else {
1263    Node* trailing = barrier->trailing_membar();
1264    MemBarNode* trailing_mb = trailing->as_MemBar();
1265    assert(trailing_mb->trailing(), "Not a trailing membar?");
1266    assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars");
1267
1268    Node* mem = trailing_mb->in(MemBarNode::Precedent);
1269    if (mem->is_Store()) {
1270      assert(mem->as_Store()->is_release(), "");
1271      assert(trailing_mb->Opcode() == Op_MemBarVolatile, "");
1272      return true;
1273    } else {
1274      assert(mem->is_LoadStore(), "");
1275      assert(trailing_mb->Opcode() == Op_MemBarAcquire, "");
1276      return is_CAS(mem->Opcode());
1277    }
1278  }
1279
1280  return false;
1281}
1282
1283bool unnecessary_volatile(const Node *n)
1284{
1285  // assert n->is_MemBar();
1286  if (UseBarriersForVolatile) {
1287    // we need to plant a dmb
1288    return false;
1289  }
1290
1291  MemBarNode *mbvol = n->as_MemBar();
1292
1293  bool release = mbvol->trailing_store();
1294  assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), "");
1295#ifdef ASSERT
1296  if (release) {
1297    Node* leading = mbvol->leading_membar();
1298    assert(leading->Opcode() == Op_MemBarRelease, "");
1299    assert(leading->as_MemBar()->leading_store(), "");
1300    assert(leading->as_MemBar()->trailing_membar() == mbvol, "");
1301   }
1302#endif
1303
1304  return release;
1305}
1306
1307// predicates controlling emit of str<x>/stlr<x> and associated dmbs
1308
1309bool needs_releasing_store(const Node *n)
1310{
1311  // assert n->is_Store();
1312  if (UseBarriersForVolatile) {
1313    // we use a normal store and dmb combination
1314    return false;
1315  }
1316
1317  StoreNode *st = n->as_Store();
1318
1319  return st->trailing_membar() != NULL;
1320}
1321
1322// predicate controlling translation of CAS
1323//
1324// returns true if CAS needs to use an acquiring load otherwise false
1325
1326bool needs_acquiring_load_exclusive(const Node *n)
1327{
1328  assert(is_CAS(n->Opcode()), "expecting a compare and swap");
1329  if (UseBarriersForVolatile) {
1330    return false;
1331  }
1332
1333  LoadStoreNode* ldst = n->as_LoadStore();
1334  assert(ldst->trailing_membar() != NULL, "expected trailing membar");
1335
1336  // so we can just return true here
1337  return true;
1338}
1339
1340// predicate controlling translation of StoreCM
1341//
1342// returns true if a StoreStore must precede the card write otherwise
1343// false
1344
1345bool unnecessary_storestore(const Node *storecm)
1346{
1347  assert(storecm->Opcode()  == Op_StoreCM, "expecting a StoreCM");
1348
1349  // we need to generate a dmb ishst between an object put and the
1350  // associated card mark when we are using CMS without conditional
1351  // card marking
1352
1353  if (UseConcMarkSweepGC && !UseCondCardMark) {
1354    return false;
1355  }
1356
1357  // a storestore is unnecesary in all other cases
1358
1359  return true;
1360}
1361
1362
1363#define __ _masm.
1364
1365// advance declaratuons for helper functions to convert register
1366// indices to register objects
1367
1368// the ad file has to provide implementations of certain methods
1369// expected by the generic code
1370//
1371// REQUIRED FUNCTIONALITY
1372
1373//=============================================================================
1374
1375// !!!!! Special hack to get all types of calls to specify the byte offset
1376//       from the start of the call to the point where the return address
1377//       will point.
1378
1379int MachCallStaticJavaNode::ret_addr_offset()
1380{
1381  // call should be a simple bl
1382  // unless this is a method handle invoke in which case it is
1383  // mov(rfp, sp), bl, mov(sp, rfp)
1384  int off = 4;
1385  if (_method_handle_invoke) {
1386    off += 4;
1387  }
1388  return off;
1389}
1390
1391int MachCallDynamicJavaNode::ret_addr_offset()
1392{
1393  return 16; // movz, movk, movk, bl
1394}
1395
1396int MachCallRuntimeNode::ret_addr_offset() {
1397  // for generated stubs the call will be
1398  //   bl(addr)
1399  // for real runtime callouts it will be six instructions
1400  // see aarch64_enc_java_to_runtime
1401  //   adr(rscratch2, retaddr)
1402  //   lea(rscratch1, RuntimeAddress(addr)
1403  //   stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)))
1404  //   blr(rscratch1)
1405  CodeBlob *cb = CodeCache::find_blob(_entry_point);
1406  if (cb) {
1407    return MacroAssembler::far_branch_size();
1408  } else {
1409    return 6 * NativeInstruction::instruction_size;
1410  }
1411}
1412
1413// Indicate if the safepoint node needs the polling page as an input
1414
1415// the shared code plants the oop data at the start of the generated
1416// code for the safepoint node and that needs ot be at the load
1417// instruction itself. so we cannot plant a mov of the safepoint poll
1418// address followed by a load. setting this to true means the mov is
1419// scheduled as a prior instruction. that's better for scheduling
1420// anyway.
1421
1422bool SafePointNode::needs_polling_address_input()
1423{
1424  return true;
1425}
1426
1427//=============================================================================
1428
1429#ifndef PRODUCT
1430void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1431  st->print("BREAKPOINT");
1432}
1433#endif
1434
1435void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1436  MacroAssembler _masm(&cbuf);
1437  __ brk(0);
1438}
1439
1440uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1441  return MachNode::size(ra_);
1442}
1443
1444//=============================================================================
1445
1446#ifndef PRODUCT
1447  void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const {
1448    st->print("nop \t# %d bytes pad for loops and calls", _count);
1449  }
1450#endif
1451
1452  void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const {
1453    MacroAssembler _masm(&cbuf);
1454    for (int i = 0; i < _count; i++) {
1455      __ nop();
1456    }
1457  }
1458
1459  uint MachNopNode::size(PhaseRegAlloc*) const {
1460    return _count * NativeInstruction::instruction_size;
1461  }
1462
1463//=============================================================================
1464const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
1465
1466int Compile::ConstantTable::calculate_table_base_offset() const {
1467  return 0;  // absolute addressing, no offset
1468}
1469
1470bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1471void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1472  ShouldNotReachHere();
1473}
1474
1475void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1476  // Empty encoding
1477}
1478
1479uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1480  return 0;
1481}
1482
1483#ifndef PRODUCT
1484void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1485  st->print("-- \t// MachConstantBaseNode (empty encoding)");
1486}
1487#endif
1488
1489#ifndef PRODUCT
1490void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1491  Compile* C = ra_->C;
1492
1493  int framesize = C->frame_slots() << LogBytesPerInt;
1494
1495  if (C->need_stack_bang(framesize))
1496    st->print("# stack bang size=%d\n\t", framesize);
1497
1498  if (framesize == 0) {
1499    // Is this even possible?
1500    st->print("stp  lr, rfp, [sp, #%d]!", -(2 * wordSize));
1501  } else if (framesize < ((1 << 9) + 2 * wordSize)) {
1502    st->print("sub  sp, sp, #%d\n\t", framesize);
1503    st->print("stp  rfp, lr, [sp, #%d]", framesize - 2 * wordSize);
1504  } else {
1505    st->print("stp  lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize));
1506    st->print("mov  rscratch1, #%d\n\t", framesize - 2 * wordSize);
1507    st->print("sub  sp, sp, rscratch1");
1508  }
1509}
1510#endif
1511
1512void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1513  Compile* C = ra_->C;
1514  MacroAssembler _masm(&cbuf);
1515
1516  // n.b. frame size includes space for return pc and rfp
1517  long framesize = ((long)C->frame_slots()) << LogBytesPerInt;
1518  assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment");
1519
1520  // insert a nop at the start of the prolog so we can patch in a
1521  // branch if we need to invalidate the method later
1522  __ nop();
1523
1524  if (C->need_stack_bang(framesize))
1525    __ generate_stack_overflow_check(framesize);
1526
1527  __ build_frame(framesize);
1528
1529  if (VerifyStackAtCalls) {
1530    Unimplemented();
1531  }
1532
1533  C->set_frame_complete(cbuf.insts_size());
1534
1535  if (C->has_mach_constant_base_node()) {
1536    // NOTE: We set the table base offset here because users might be
1537    // emitted before MachConstantBaseNode.
1538    Compile::ConstantTable& constant_table = C->constant_table();
1539    constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1540  }
1541}
1542
1543uint MachPrologNode::size(PhaseRegAlloc* ra_) const
1544{
1545  return MachNode::size(ra_); // too many variables; just compute it
1546                              // the hard way
1547}
1548
1549int MachPrologNode::reloc() const
1550{
1551  return 0;
1552}
1553
1554//=============================================================================
1555
1556#ifndef PRODUCT
1557void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1558  Compile* C = ra_->C;
1559  int framesize = C->frame_slots() << LogBytesPerInt;
1560
1561  st->print("# pop frame %d\n\t",framesize);
1562
1563  if (framesize == 0) {
1564    st->print("ldp  lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1565  } else if (framesize < ((1 << 9) + 2 * wordSize)) {
1566    st->print("ldp  lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize);
1567    st->print("add  sp, sp, #%d\n\t", framesize);
1568  } else {
1569    st->print("mov  rscratch1, #%d\n\t", framesize - 2 * wordSize);
1570    st->print("add  sp, sp, rscratch1\n\t");
1571    st->print("ldp  lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1572  }
1573
1574  if (do_polling() && C->is_method_compilation()) {
1575    st->print("# touch polling page\n\t");
1576    st->print("mov  rscratch1, #" INTPTR_FORMAT "\n\t", p2i(os::get_polling_page()));
1577    st->print("ldr zr, [rscratch1]");
1578  }
1579}
1580#endif
1581
1582void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1583  Compile* C = ra_->C;
1584  MacroAssembler _masm(&cbuf);
1585  int framesize = C->frame_slots() << LogBytesPerInt;
1586
1587  __ remove_frame(framesize);
1588
1589  if (do_polling() && C->is_method_compilation()) {
1590    __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type);
1591  }
1592}
1593
1594uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1595  // Variable size. Determine dynamically.
1596  return MachNode::size(ra_);
1597}
1598
1599int MachEpilogNode::reloc() const {
1600  // Return number of relocatable values contained in this instruction.
1601  return 1; // 1 for polling page.
1602}
1603
1604const Pipeline * MachEpilogNode::pipeline() const {
1605  return MachNode::pipeline_class();
1606}
1607
1608// This method seems to be obsolete. It is declared in machnode.hpp
1609// and defined in all *.ad files, but it is never called. Should we
1610// get rid of it?
1611int MachEpilogNode::safepoint_offset() const {
1612  assert(do_polling(), "no return for this epilog node");
1613  return 4;
1614}
1615
1616//=============================================================================
1617
1618// Figure out which register class each belongs in: rc_int, rc_float or
1619// rc_stack.
1620enum RC { rc_bad, rc_int, rc_float, rc_stack };
1621
1622static enum RC rc_class(OptoReg::Name reg) {
1623
1624  if (reg == OptoReg::Bad) {
1625    return rc_bad;
1626  }
1627
1628  // we have 30 int registers * 2 halves
1629  // (rscratch1 and rscratch2 are omitted)
1630
1631  if (reg < 60) {
1632    return rc_int;
1633  }
1634
1635  // we have 32 float register * 2 halves
1636  if (reg < 60 + 128) {
1637    return rc_float;
1638  }
1639
1640  // Between float regs & stack is the flags regs.
1641  assert(OptoReg::is_stack(reg), "blow up if spilling flags");
1642
1643  return rc_stack;
1644}
1645
1646uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1647  Compile* C = ra_->C;
1648
1649  // Get registers to move.
1650  OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1651  OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1652  OptoReg::Name dst_hi = ra_->get_reg_second(this);
1653  OptoReg::Name dst_lo = ra_->get_reg_first(this);
1654
1655  enum RC src_hi_rc = rc_class(src_hi);
1656  enum RC src_lo_rc = rc_class(src_lo);
1657  enum RC dst_hi_rc = rc_class(dst_hi);
1658  enum RC dst_lo_rc = rc_class(dst_lo);
1659
1660  assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1661
1662  if (src_hi != OptoReg::Bad) {
1663    assert((src_lo&1)==0 && src_lo+1==src_hi &&
1664           (dst_lo&1)==0 && dst_lo+1==dst_hi,
1665           "expected aligned-adjacent pairs");
1666  }
1667
1668  if (src_lo == dst_lo && src_hi == dst_hi) {
1669    return 0;            // Self copy, no move.
1670  }
1671
1672  bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi &&
1673              (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi;
1674  int src_offset = ra_->reg2offset(src_lo);
1675  int dst_offset = ra_->reg2offset(dst_lo);
1676
1677  if (bottom_type()->isa_vect() != NULL) {
1678    uint ireg = ideal_reg();
1679    assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector");
1680    if (cbuf) {
1681      MacroAssembler _masm(cbuf);
1682      assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity");
1683      if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1684        // stack->stack
1685        assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset");
1686        if (ireg == Op_VecD) {
1687          __ unspill(rscratch1, true, src_offset);
1688          __ spill(rscratch1, true, dst_offset);
1689        } else {
1690          __ spill_copy128(src_offset, dst_offset);
1691        }
1692      } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1693        __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1694               ireg == Op_VecD ? __ T8B : __ T16B,
1695               as_FloatRegister(Matcher::_regEncode[src_lo]));
1696      } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1697        __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
1698                       ireg == Op_VecD ? __ D : __ Q,
1699                       ra_->reg2offset(dst_lo));
1700      } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) {
1701        __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1702                       ireg == Op_VecD ? __ D : __ Q,
1703                       ra_->reg2offset(src_lo));
1704      } else {
1705        ShouldNotReachHere();
1706      }
1707    }
1708  } else if (cbuf) {
1709    MacroAssembler _masm(cbuf);
1710    switch (src_lo_rc) {
1711    case rc_int:
1712      if (dst_lo_rc == rc_int) {  // gpr --> gpr copy
1713        if (is64) {
1714            __ mov(as_Register(Matcher::_regEncode[dst_lo]),
1715                   as_Register(Matcher::_regEncode[src_lo]));
1716        } else {
1717            MacroAssembler _masm(cbuf);
1718            __ movw(as_Register(Matcher::_regEncode[dst_lo]),
1719                    as_Register(Matcher::_regEncode[src_lo]));
1720        }
1721      } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
1722        if (is64) {
1723            __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1724                     as_Register(Matcher::_regEncode[src_lo]));
1725        } else {
1726            __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1727                     as_Register(Matcher::_regEncode[src_lo]));
1728        }
1729      } else {                    // gpr --> stack spill
1730        assert(dst_lo_rc == rc_stack, "spill to bad register class");
1731        __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
1732      }
1733      break;
1734    case rc_float:
1735      if (dst_lo_rc == rc_int) {  // fpr --> gpr copy
1736        if (is64) {
1737            __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
1738                     as_FloatRegister(Matcher::_regEncode[src_lo]));
1739        } else {
1740            __ fmovs(as_Register(Matcher::_regEncode[dst_lo]),
1741                     as_FloatRegister(Matcher::_regEncode[src_lo]));
1742        }
1743      } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
1744          if (cbuf) {
1745            __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1746                     as_FloatRegister(Matcher::_regEncode[src_lo]));
1747        } else {
1748            __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1749                     as_FloatRegister(Matcher::_regEncode[src_lo]));
1750        }
1751      } else {                    // fpr --> stack spill
1752        assert(dst_lo_rc == rc_stack, "spill to bad register class");
1753        __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
1754                 is64 ? __ D : __ S, dst_offset);
1755      }
1756      break;
1757    case rc_stack:
1758      if (dst_lo_rc == rc_int) {  // stack --> gpr load
1759        __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
1760      } else if (dst_lo_rc == rc_float) { // stack --> fpr load
1761        __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1762                   is64 ? __ D : __ S, src_offset);
1763      } else {                    // stack --> stack copy
1764        assert(dst_lo_rc == rc_stack, "spill to bad register class");
1765        __ unspill(rscratch1, is64, src_offset);
1766        __ spill(rscratch1, is64, dst_offset);
1767      }
1768      break;
1769    default:
1770      assert(false, "bad rc_class for spill");
1771      ShouldNotReachHere();
1772    }
1773  }
1774
1775  if (st) {
1776    st->print("spill ");
1777    if (src_lo_rc == rc_stack) {
1778      st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo));
1779    } else {
1780      st->print("%s -> ", Matcher::regName[src_lo]);
1781    }
1782    if (dst_lo_rc == rc_stack) {
1783      st->print("[sp, #%d]", ra_->reg2offset(dst_lo));
1784    } else {
1785      st->print("%s", Matcher::regName[dst_lo]);
1786    }
1787    if (bottom_type()->isa_vect() != NULL) {
1788      st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128);
1789    } else {
1790      st->print("\t# spill size = %d", is64 ? 64:32);
1791    }
1792  }
1793
1794  return 0;
1795
1796}
1797
1798#ifndef PRODUCT
1799void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1800  if (!ra_)
1801    st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1802  else
1803    implementation(NULL, ra_, false, st);
1804}
1805#endif
1806
1807void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1808  implementation(&cbuf, ra_, false, NULL);
1809}
1810
1811uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1812  return MachNode::size(ra_);
1813}
1814
1815//=============================================================================
1816
1817#ifndef PRODUCT
1818void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1819  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1820  int reg = ra_->get_reg_first(this);
1821  st->print("add %s, rsp, #%d]\t# box lock",
1822            Matcher::regName[reg], offset);
1823}
1824#endif
1825
1826void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1827  MacroAssembler _masm(&cbuf);
1828
1829  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1830  int reg    = ra_->get_encode(this);
1831
1832  // This add will handle any 24-bit signed offset. 24 bits allows an
1833  // 8 megabyte stack frame.
1834  __ add(as_Register(reg), sp, offset);
1835}
1836
1837uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1838  // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1839  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1840
1841  if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
1842    return NativeInstruction::instruction_size;
1843  } else {
1844    return 2 * NativeInstruction::instruction_size;
1845  }
1846}
1847
1848//=============================================================================
1849
1850#ifndef PRODUCT
1851void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1852{
1853  st->print_cr("# MachUEPNode");
1854  if (UseCompressedClassPointers) {
1855    st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1856    if (Universe::narrow_klass_shift() != 0) {
1857      st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1858    }
1859  } else {
1860   st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1861  }
1862  st->print_cr("\tcmp r0, rscratch1\t # Inline cache check");
1863  st->print_cr("\tbne, SharedRuntime::_ic_miss_stub");
1864}
1865#endif
1866
1867void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1868{
1869  // This is the unverified entry point.
1870  MacroAssembler _masm(&cbuf);
1871
1872  __ cmp_klass(j_rarg0, rscratch2, rscratch1);
1873  Label skip;
1874  // TODO
1875  // can we avoid this skip and still use a reloc?
1876  __ br(Assembler::EQ, skip);
1877  __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1878  __ bind(skip);
1879}
1880
1881uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1882{
1883  return MachNode::size(ra_);
1884}
1885
1886// REQUIRED EMIT CODE
1887
1888//=============================================================================
1889
1890// Emit exception handler code.
1891int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf)
1892{
1893  // mov rscratch1 #exception_blob_entry_point
1894  // br rscratch1
1895  // Note that the code buffer's insts_mark is always relative to insts.
1896  // That's why we must use the macroassembler to generate a handler.
1897  MacroAssembler _masm(&cbuf);
1898  address base = __ start_a_stub(size_exception_handler());
1899  if (base == NULL) {
1900    ciEnv::current()->record_failure("CodeCache is full");
1901    return 0;  // CodeBuffer::expand failed
1902  }
1903  int offset = __ offset();
1904  __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
1905  assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
1906  __ end_a_stub();
1907  return offset;
1908}
1909
1910// Emit deopt handler code.
1911int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf)
1912{
1913  // Note that the code buffer's insts_mark is always relative to insts.
1914  // That's why we must use the macroassembler to generate a handler.
1915  MacroAssembler _masm(&cbuf);
1916  address base = __ start_a_stub(size_deopt_handler());
1917  if (base == NULL) {
1918    ciEnv::current()->record_failure("CodeCache is full");
1919    return 0;  // CodeBuffer::expand failed
1920  }
1921  int offset = __ offset();
1922
1923  __ adr(lr, __ pc());
1924  __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1925
1926  assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1927  __ end_a_stub();
1928  return offset;
1929}
1930
1931// REQUIRED MATCHER CODE
1932
1933//=============================================================================
1934
1935const bool Matcher::match_rule_supported(int opcode) {
1936
1937  // TODO
1938  // identify extra cases that we might want to provide match rules for
1939  // e.g. Op_StrEquals and other intrinsics
1940  if (!has_match_rule(opcode)) {
1941    return false;
1942  }
1943
1944  return true;  // Per default match rules are supported.
1945}
1946
1947int Matcher::regnum_to_fpu_offset(int regnum)
1948{
1949  Unimplemented();
1950  return 0;
1951}
1952
1953// Is this branch offset short enough that a short branch can be used?
1954//
1955// NOTE: If the platform does not provide any short branch variants, then
1956//       this method should return false for offset 0.
1957bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1958  // The passed offset is relative to address of the branch.
1959
1960  return (-32768 <= offset && offset < 32768);
1961}
1962
1963const bool Matcher::isSimpleConstant64(jlong value) {
1964  // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1965  // Probably always true, even if a temp register is required.
1966  return true;
1967}
1968
1969// true just means we have fast l2f conversion
1970const bool Matcher::convL2FSupported(void) {
1971  return true;
1972}
1973
1974// Vector width in bytes.
1975const int Matcher::vector_width_in_bytes(BasicType bt) {
1976  int size = MIN2(16,(int)MaxVectorSize);
1977  // Minimum 2 values in vector
1978  if (size < 2*type2aelembytes(bt)) size = 0;
1979  // But never < 4
1980  if (size < 4) size = 0;
1981  return size;
1982}
1983
1984// Limits on vector size (number of elements) loaded into vector.
1985const int Matcher::max_vector_size(const BasicType bt) {
1986  return vector_width_in_bytes(bt)/type2aelembytes(bt);
1987}
1988const int Matcher::min_vector_size(const BasicType bt) {
1989//  For the moment limit the vector size to 8 bytes
1990    int size = 8 / type2aelembytes(bt);
1991    if (size < 2) size = 2;
1992    return size;
1993}
1994
1995// Vector ideal reg.
1996const uint Matcher::vector_ideal_reg(int len) {
1997  switch(len) {
1998    case  8: return Op_VecD;
1999    case 16: return Op_VecX;
2000  }
2001  ShouldNotReachHere();
2002  return 0;
2003}
2004
2005const uint Matcher::vector_shift_count_ideal_reg(int size) {
2006  switch(size) {
2007    case  8: return Op_VecD;
2008    case 16: return Op_VecX;
2009  }
2010  ShouldNotReachHere();
2011  return 0;
2012}
2013
2014// AES support not yet implemented
2015const bool Matcher::pass_original_key_for_aes() {
2016  return false;
2017}
2018
2019// x86 supports misaligned vectors store/load.
2020const bool Matcher::misaligned_vectors_ok() {
2021  return !AlignVector; // can be changed by flag
2022}
2023
2024// false => size gets scaled to BytesPerLong, ok.
2025const bool Matcher::init_array_count_is_in_bytes = false;
2026
2027// Threshold size for cleararray.
2028const int Matcher::init_array_short_size = 4 * BytesPerLong;
2029
2030// Use conditional move (CMOVL)
2031const int Matcher::long_cmove_cost() {
2032  // long cmoves are no more expensive than int cmoves
2033  return 0;
2034}
2035
2036const int Matcher::float_cmove_cost() {
2037  // float cmoves are no more expensive than int cmoves
2038  return 0;
2039}
2040
2041// Does the CPU require late expand (see block.cpp for description of late expand)?
2042const bool Matcher::require_postalloc_expand = false;
2043
2044// Should the Matcher clone shifts on addressing modes, expecting them
2045// to be subsumed into complex addressing expressions or compute them
2046// into registers?  True for Intel but false for most RISCs
2047const bool Matcher::clone_shift_expressions = false;
2048
2049// Do we need to mask the count passed to shift instructions or does
2050// the cpu only look at the lower 5/6 bits anyway?
2051const bool Matcher::need_masked_shift_count = false;
2052
2053// This affects two different things:
2054//  - how Decode nodes are matched
2055//  - how ImplicitNullCheck opportunities are recognized
2056// If true, the matcher will try to remove all Decodes and match them
2057// (as operands) into nodes. NullChecks are not prepared to deal with
2058// Decodes by final_graph_reshaping().
2059// If false, final_graph_reshaping() forces the decode behind the Cmp
2060// for a NullCheck. The matcher matches the Decode node into a register.
2061// Implicit_null_check optimization moves the Decode along with the
2062// memory operation back up before the NullCheck.
2063bool Matcher::narrow_oop_use_complex_address() {
2064  return Universe::narrow_oop_shift() == 0;
2065}
2066
2067bool Matcher::narrow_klass_use_complex_address() {
2068// TODO
2069// decide whether we need to set this to true
2070  return false;
2071}
2072
2073// Is it better to copy float constants, or load them directly from
2074// memory?  Intel can load a float constant from a direct address,
2075// requiring no extra registers.  Most RISCs will have to materialize
2076// an address into a register first, so they would do better to copy
2077// the constant from stack.
2078const bool Matcher::rematerialize_float_constants = false;
2079
2080// If CPU can load and store mis-aligned doubles directly then no
2081// fixup is needed.  Else we split the double into 2 integer pieces
2082// and move it piece-by-piece.  Only happens when passing doubles into
2083// C code as the Java calling convention forces doubles to be aligned.
2084const bool Matcher::misaligned_doubles_ok = true;
2085
2086// No-op on amd64
2087void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
2088  Unimplemented();
2089}
2090
2091// Advertise here if the CPU requires explicit rounding operations to
2092// implement the UseStrictFP mode.
2093const bool Matcher::strict_fp_requires_explicit_rounding = false;
2094
2095// Are floats converted to double when stored to stack during
2096// deoptimization?
2097bool Matcher::float_in_double() { return true; }
2098
2099// Do ints take an entire long register or just half?
2100// The relevant question is how the int is callee-saved:
2101// the whole long is written but de-opt'ing will have to extract
2102// the relevant 32 bits.
2103const bool Matcher::int_in_long = true;
2104
2105// Return whether or not this register is ever used as an argument.
2106// This function is used on startup to build the trampoline stubs in
2107// generateOptoStub.  Registers not mentioned will be killed by the VM
2108// call in the trampoline, and arguments in those registers not be
2109// available to the callee.
2110bool Matcher::can_be_java_arg(int reg)
2111{
2112  return
2113    reg ==  R0_num || reg == R0_H_num ||
2114    reg ==  R1_num || reg == R1_H_num ||
2115    reg ==  R2_num || reg == R2_H_num ||
2116    reg ==  R3_num || reg == R3_H_num ||
2117    reg ==  R4_num || reg == R4_H_num ||
2118    reg ==  R5_num || reg == R5_H_num ||
2119    reg ==  R6_num || reg == R6_H_num ||
2120    reg ==  R7_num || reg == R7_H_num ||
2121    reg ==  V0_num || reg == V0_H_num ||
2122    reg ==  V1_num || reg == V1_H_num ||
2123    reg ==  V2_num || reg == V2_H_num ||
2124    reg ==  V3_num || reg == V3_H_num ||
2125    reg ==  V4_num || reg == V4_H_num ||
2126    reg ==  V5_num || reg == V5_H_num ||
2127    reg ==  V6_num || reg == V6_H_num ||
2128    reg ==  V7_num || reg == V7_H_num;
2129}
2130
2131bool Matcher::is_spillable_arg(int reg)
2132{
2133  return can_be_java_arg(reg);
2134}
2135
2136bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
2137  return false;
2138}
2139
2140RegMask Matcher::divI_proj_mask() {
2141  ShouldNotReachHere();
2142  return RegMask();
2143}
2144
2145// Register for MODI projection of divmodI.
2146RegMask Matcher::modI_proj_mask() {
2147  ShouldNotReachHere();
2148  return RegMask();
2149}
2150
2151// Register for DIVL projection of divmodL.
2152RegMask Matcher::divL_proj_mask() {
2153  ShouldNotReachHere();
2154  return RegMask();
2155}
2156
2157// Register for MODL projection of divmodL.
2158RegMask Matcher::modL_proj_mask() {
2159  ShouldNotReachHere();
2160  return RegMask();
2161}
2162
2163const RegMask Matcher::method_handle_invoke_SP_save_mask() {
2164  return FP_REG_mask();
2165}
2166
2167bool size_fits_all_mem_uses(AddPNode* addp, int shift) {
2168  for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) {
2169    Node* u = addp->fast_out(i);
2170    if (u->is_LoadStore()) {
2171      // On AArch64, LoadStoreNodes (i.e. compare and swap
2172      // instructions) only take register indirect as an operand, so
2173      // any attempt to use an AddPNode as an input to a LoadStoreNode
2174      // must fail.
2175      return false;
2176    }
2177    if (u->is_Mem()) {
2178      int opsize = u->as_Mem()->memory_size();
2179      assert(opsize > 0, "unexpected memory operand size");
2180      if (u->as_Mem()->memory_size() != (1<<shift)) {
2181        return false;
2182      }
2183    }
2184  }
2185  return true;
2186}
2187
2188#define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN)	\
2189  MacroAssembler _masm(&cbuf);						\
2190  {									\
2191    guarantee(INDEX == -1, "mode not permitted for volatile");		\
2192    guarantee(DISP == 0, "mode not permitted for volatile");		\
2193    guarantee(SCALE == 0, "mode not permitted for volatile");		\
2194    __ INSN(REG, as_Register(BASE));					\
2195  }
2196
2197typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr);
2198typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr);
2199typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
2200                                  MacroAssembler::SIMD_RegVariant T, const Address &adr);
2201
2202  // Used for all non-volatile memory accesses.  The use of
2203  // $mem->opcode() to discover whether this pattern uses sign-extended
2204  // offsets is something of a kludge.
2205  static void loadStore(MacroAssembler masm, mem_insn insn,
2206			 Register reg, int opcode,
2207			 Register base, int index, int size, int disp)
2208  {
2209    Address::extend scale;
2210
2211    // Hooboy, this is fugly.  We need a way to communicate to the
2212    // encoder that the index needs to be sign extended, so we have to
2213    // enumerate all the cases.
2214    switch (opcode) {
2215    case INDINDEXSCALEDOFFSETI2L:
2216    case INDINDEXSCALEDI2L:
2217    case INDINDEXSCALEDOFFSETI2LN:
2218    case INDINDEXSCALEDI2LN:
2219    case INDINDEXOFFSETI2L:
2220    case INDINDEXOFFSETI2LN:
2221      scale = Address::sxtw(size);
2222      break;
2223    default:
2224      scale = Address::lsl(size);
2225    }
2226
2227    if (index == -1) {
2228      (masm.*insn)(reg, Address(base, disp));
2229    } else {
2230      if (disp == 0) {
2231	(masm.*insn)(reg, Address(base, as_Register(index), scale));
2232      } else {
2233	masm.lea(rscratch1, Address(base, disp));
2234	(masm.*insn)(reg, Address(rscratch1, as_Register(index), scale));
2235      }
2236    }
2237  }
2238
2239  static void loadStore(MacroAssembler masm, mem_float_insn insn,
2240			 FloatRegister reg, int opcode,
2241			 Register base, int index, int size, int disp)
2242  {
2243    Address::extend scale;
2244
2245    switch (opcode) {
2246    case INDINDEXSCALEDOFFSETI2L:
2247    case INDINDEXSCALEDI2L:
2248    case INDINDEXSCALEDOFFSETI2LN:
2249    case INDINDEXSCALEDI2LN:
2250      scale = Address::sxtw(size);
2251      break;
2252    default:
2253      scale = Address::lsl(size);
2254    }
2255
2256     if (index == -1) {
2257      (masm.*insn)(reg, Address(base, disp));
2258    } else {
2259      if (disp == 0) {
2260	(masm.*insn)(reg, Address(base, as_Register(index), scale));
2261      } else {
2262	masm.lea(rscratch1, Address(base, disp));
2263	(masm.*insn)(reg, Address(rscratch1, as_Register(index), scale));
2264      }
2265    }
2266  }
2267
2268  static void loadStore(MacroAssembler masm, mem_vector_insn insn,
2269                         FloatRegister reg, MacroAssembler::SIMD_RegVariant T,
2270                         int opcode, Register base, int index, int size, int disp)
2271  {
2272    if (index == -1) {
2273      (masm.*insn)(reg, T, Address(base, disp));
2274    } else {
2275      assert(disp == 0, "unsupported address mode");
2276      (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size)));
2277    }
2278  }
2279
2280%}
2281
2282
2283
2284//----------ENCODING BLOCK-----------------------------------------------------
2285// This block specifies the encoding classes used by the compiler to
2286// output byte streams.  Encoding classes are parameterized macros
2287// used by Machine Instruction Nodes in order to generate the bit
2288// encoding of the instruction.  Operands specify their base encoding
2289// interface with the interface keyword.  There are currently
2290// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
2291// COND_INTER.  REG_INTER causes an operand to generate a function
2292// which returns its register number when queried.  CONST_INTER causes
2293// an operand to generate a function which returns the value of the
2294// constant when queried.  MEMORY_INTER causes an operand to generate
2295// four functions which return the Base Register, the Index Register,
2296// the Scale Value, and the Offset Value of the operand when queried.
2297// COND_INTER causes an operand to generate six functions which return
2298// the encoding code (ie - encoding bits for the instruction)
2299// associated with each basic boolean condition for a conditional
2300// instruction.
2301//
2302// Instructions specify two basic values for encoding.  Again, a
2303// function is available to check if the constant displacement is an
2304// oop. They use the ins_encode keyword to specify their encoding
2305// classes (which must be a sequence of enc_class names, and their
2306// parameters, specified in the encoding block), and they use the
2307// opcode keyword to specify, in order, their primary, secondary, and
2308// tertiary opcode.  Only the opcode sections which a particular
2309// instruction needs for encoding need to be specified.
2310encode %{
2311  // Build emit functions for each basic byte or larger field in the
2312  // intel encoding scheme (opcode, rm, sib, immediate), and call them
2313  // from C++ code in the enc_class source block.  Emit functions will
2314  // live in the main source block for now.  In future, we can
2315  // generalize this by adding a syntax that specifies the sizes of
2316  // fields in an order, so that the adlc can build the emit functions
2317  // automagically
2318
2319  // catch all for unimplemented encodings
2320  enc_class enc_unimplemented %{
2321    MacroAssembler _masm(&cbuf);
2322    __ unimplemented("C2 catch all");
2323  %}
2324
2325  // BEGIN Non-volatile memory access
2326
2327  enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{
2328    Register dst_reg = as_Register($dst$$reg);
2329    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(),
2330               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2331  %}
2332
2333  enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{
2334    Register dst_reg = as_Register($dst$$reg);
2335    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(),
2336               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2337  %}
2338
2339  enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{
2340    Register dst_reg = as_Register($dst$$reg);
2341    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2342               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2343  %}
2344
2345  enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{
2346    Register dst_reg = as_Register($dst$$reg);
2347    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2348               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2349  %}
2350
2351  enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{
2352    Register dst_reg = as_Register($dst$$reg);
2353    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(),
2354               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2355  %}
2356
2357  enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{
2358    Register dst_reg = as_Register($dst$$reg);
2359    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(),
2360               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2361  %}
2362
2363  enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{
2364    Register dst_reg = as_Register($dst$$reg);
2365    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2366               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2367  %}
2368
2369  enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{
2370    Register dst_reg = as_Register($dst$$reg);
2371    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2372               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2373  %}
2374
2375  enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{
2376    Register dst_reg = as_Register($dst$$reg);
2377    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2378               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2379  %}
2380
2381  enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{
2382    Register dst_reg = as_Register($dst$$reg);
2383    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2384               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2385  %}
2386
2387  enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{
2388    Register dst_reg = as_Register($dst$$reg);
2389    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(),
2390               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2391  %}
2392
2393  enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{
2394    Register dst_reg = as_Register($dst$$reg);
2395    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(),
2396               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2397  %}
2398
2399  enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{
2400    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2401    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(),
2402               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2403  %}
2404
2405  enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{
2406    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2407    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(),
2408               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2409  %}
2410
2411  enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{
2412    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2413    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S,
2414       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2415  %}
2416
2417  enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{
2418    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2419    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D,
2420       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2421  %}
2422
2423  enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{
2424    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2425    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q,
2426       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2427  %}
2428
2429  enc_class aarch64_enc_strb(iRegI src, memory mem) %{
2430    Register src_reg = as_Register($src$$reg);
2431    loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(),
2432               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2433  %}
2434
2435  enc_class aarch64_enc_strb0(memory mem) %{
2436    MacroAssembler _masm(&cbuf);
2437    loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(),
2438               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2439  %}
2440
2441  enc_class aarch64_enc_strb0_ordered(memory mem) %{
2442    MacroAssembler _masm(&cbuf);
2443    __ membar(Assembler::StoreStore);
2444    loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(),
2445               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2446  %}
2447
2448  enc_class aarch64_enc_strh(iRegI src, memory mem) %{
2449    Register src_reg = as_Register($src$$reg);
2450    loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(),
2451               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2452  %}
2453
2454  enc_class aarch64_enc_strh0(memory mem) %{
2455    MacroAssembler _masm(&cbuf);
2456    loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(),
2457               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2458  %}
2459
2460  enc_class aarch64_enc_strw(iRegI src, memory mem) %{
2461    Register src_reg = as_Register($src$$reg);
2462    loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(),
2463               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2464  %}
2465
2466  enc_class aarch64_enc_strw0(memory mem) %{
2467    MacroAssembler _masm(&cbuf);
2468    loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(),
2469               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2470  %}
2471
2472  enc_class aarch64_enc_str(iRegL src, memory mem) %{
2473    Register src_reg = as_Register($src$$reg);
2474    // we sometimes get asked to store the stack pointer into the
2475    // current thread -- we cannot do that directly on AArch64
2476    if (src_reg == r31_sp) {
2477      MacroAssembler _masm(&cbuf);
2478      assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
2479      __ mov(rscratch2, sp);
2480      src_reg = rscratch2;
2481    }
2482    loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(),
2483               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2484  %}
2485
2486  enc_class aarch64_enc_str0(memory mem) %{
2487    MacroAssembler _masm(&cbuf);
2488    loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(),
2489               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2490  %}
2491
2492  enc_class aarch64_enc_strs(vRegF src, memory mem) %{
2493    FloatRegister src_reg = as_FloatRegister($src$$reg);
2494    loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(),
2495               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2496  %}
2497
2498  enc_class aarch64_enc_strd(vRegD src, memory mem) %{
2499    FloatRegister src_reg = as_FloatRegister($src$$reg);
2500    loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(),
2501               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2502  %}
2503
2504  enc_class aarch64_enc_strvS(vecD src, memory mem) %{
2505    FloatRegister src_reg = as_FloatRegister($src$$reg);
2506    loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S,
2507       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2508  %}
2509
2510  enc_class aarch64_enc_strvD(vecD src, memory mem) %{
2511    FloatRegister src_reg = as_FloatRegister($src$$reg);
2512    loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D,
2513       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2514  %}
2515
2516  enc_class aarch64_enc_strvQ(vecX src, memory mem) %{
2517    FloatRegister src_reg = as_FloatRegister($src$$reg);
2518    loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q,
2519       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2520  %}
2521
2522  // END Non-volatile memory access
2523
2524  // this encoding writes the address of the first instruction in the
2525  // call sequence for the runtime call into the anchor pc slot. this
2526  // address allows the runtime to i) locate the code buffer for the
2527  // caller (any address in the buffer would do) and ii) find the oop
2528  // map associated with the call (has to address the instruction
2529  // following the call). note that we have to store the address which
2530  // follows the actual call.
2531  //
2532  // the offset from the current pc can be computed by considering
2533  // what gets generated between this point up to and including the
2534  // call. it looks like this
2535  //
2536  //   movz xscratch1 0xnnnn        <-- current pc is here
2537  //   movk xscratch1 0xnnnn
2538  //   movk xscratch1 0xnnnn
2539  //   str xscratch1, [xthread,#anchor_pc_off]
2540  //   mov xscratch2, sp
2541  //   str xscratch2, [xthread,#anchor_sp_off
2542  //   mov x0, x1
2543  //   . . .
2544  //   mov xn-1, xn
2545  //   mov xn, thread            <-- always passed
2546  //   mov xn+1, rfp             <-- optional iff primary == 1
2547  //   movz xscratch1 0xnnnn
2548  //   movk xscratch1 0xnnnn
2549  //   movk xscratch1 0xnnnn
2550  //   blr  xscratch1
2551  //   . . .
2552  //
2553  // where the called routine has n args (including the thread and,
2554  // possibly the stub's caller return address currently in rfp).  we
2555  // can compute n by looking at the number of args passed into the
2556  // stub. we assert that nargs is < 7.
2557  //
2558  // so the offset we need to add to the pc (in 32-bit words) is
2559  //   3 +        <-- load 48-bit constant return pc
2560  //   1 +        <-- write anchor pc
2561  //   1 +        <-- copy sp
2562  //   1 +        <-- write anchor sp
2563  //   nargs +    <-- java stub arg count
2564  //   1 +        <-- extra thread arg
2565  // [ 1 + ]      <-- optional ret address of stub caller
2566  //   3 +        <-- load 64 bit call target address
2567  //   1          <-- blr instruction
2568  //
2569  // i.e we need to add (nargs + 11) * 4 bytes or (nargs + 12) * 4 bytes
2570  //
2571
2572  enc_class aarch64_enc_save_pc() %{
2573    Compile* C = ra_->C;
2574    int nargs = C->tf()->domain()->cnt() - TypeFunc::Parms;
2575    if ($primary) { nargs++; }
2576    assert(nargs <= 8, "opto runtime stub has more than 8 args!");
2577    MacroAssembler _masm(&cbuf);
2578    address pc = __ pc();
2579    int call_offset = (nargs + 11) * 4;
2580    int field_offset = in_bytes(JavaThread::frame_anchor_offset()) +
2581                       in_bytes(JavaFrameAnchor::last_Java_pc_offset());
2582    __ lea(rscratch1, InternalAddress(pc + call_offset));
2583    __ str(rscratch1, Address(rthread, field_offset));
2584  %}
2585
2586  // volatile loads and stores
2587
2588  enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{
2589    MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2590		 rscratch1, stlrb);
2591    if (VM_Version::cpu_cpuFeatures() & VM_Version::CPU_DMB_ATOMICS)
2592      __ dmb(__ ISH);
2593  %}
2594
2595  enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{
2596    MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2597		 rscratch1, stlrh);
2598    if (VM_Version::cpu_cpuFeatures() & VM_Version::CPU_DMB_ATOMICS)
2599      __ dmb(__ ISH);
2600  %}
2601
2602  enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{
2603    MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2604		 rscratch1, stlrw);
2605    if (VM_Version::cpu_cpuFeatures() & VM_Version::CPU_DMB_ATOMICS)
2606      __ dmb(__ ISH);
2607  %}
2608
2609
2610  enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{
2611    Register dst_reg = as_Register($dst$$reg);
2612    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2613	     rscratch1, ldarb);
2614    __ sxtbw(dst_reg, dst_reg);
2615  %}
2616
2617  enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{
2618    Register dst_reg = as_Register($dst$$reg);
2619    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2620	     rscratch1, ldarb);
2621    __ sxtb(dst_reg, dst_reg);
2622  %}
2623
2624  enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{
2625    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2626	     rscratch1, ldarb);
2627  %}
2628
2629  enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{
2630    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2631	     rscratch1, ldarb);
2632  %}
2633
2634  enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{
2635    Register dst_reg = as_Register($dst$$reg);
2636    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2637	     rscratch1, ldarh);
2638    __ sxthw(dst_reg, dst_reg);
2639  %}
2640
2641  enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{
2642    Register dst_reg = as_Register($dst$$reg);
2643    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2644	     rscratch1, ldarh);
2645    __ sxth(dst_reg, dst_reg);
2646  %}
2647
2648  enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{
2649    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2650	     rscratch1, ldarh);
2651  %}
2652
2653  enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{
2654    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2655	     rscratch1, ldarh);
2656  %}
2657
2658  enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{
2659    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2660	     rscratch1, ldarw);
2661  %}
2662
2663  enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{
2664    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2665	     rscratch1, ldarw);
2666  %}
2667
2668  enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{
2669    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2670	     rscratch1, ldar);
2671  %}
2672
2673  enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{
2674    MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2675	     rscratch1, ldarw);
2676    __ fmovs(as_FloatRegister($dst$$reg), rscratch1);
2677  %}
2678
2679  enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{
2680    MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2681	     rscratch1, ldar);
2682    __ fmovd(as_FloatRegister($dst$$reg), rscratch1);
2683  %}
2684
2685  enc_class aarch64_enc_stlr(iRegL src, memory mem) %{
2686    Register src_reg = as_Register($src$$reg);
2687    // we sometimes get asked to store the stack pointer into the
2688    // current thread -- we cannot do that directly on AArch64
2689    if (src_reg == r31_sp) {
2690 	MacroAssembler _masm(&cbuf);
2691      assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
2692      __ mov(rscratch2, sp);
2693      src_reg = rscratch2;
2694    }
2695    MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2696		 rscratch1, stlr);
2697    if (VM_Version::cpu_cpuFeatures() & VM_Version::CPU_DMB_ATOMICS)
2698      __ dmb(__ ISH);
2699  %}
2700
2701  enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{
2702    {
2703      MacroAssembler _masm(&cbuf);
2704      FloatRegister src_reg = as_FloatRegister($src$$reg);
2705      __ fmovs(rscratch2, src_reg);
2706    }
2707    MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2708		 rscratch1, stlrw);
2709    if (VM_Version::cpu_cpuFeatures() & VM_Version::CPU_DMB_ATOMICS)
2710      __ dmb(__ ISH);
2711  %}
2712
2713  enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{
2714    {
2715      MacroAssembler _masm(&cbuf);
2716      FloatRegister src_reg = as_FloatRegister($src$$reg);
2717      __ fmovd(rscratch2, src_reg);
2718    }
2719    MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2720		 rscratch1, stlr);
2721    if (VM_Version::cpu_cpuFeatures() & VM_Version::CPU_DMB_ATOMICS)
2722      __ dmb(__ ISH);
2723  %}
2724
2725  // synchronized read/update encodings
2726
2727  enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{
2728    MacroAssembler _masm(&cbuf);
2729    Register dst_reg = as_Register($dst$$reg);
2730    Register base = as_Register($mem$$base);
2731    int index = $mem$$index;
2732    int scale = $mem$$scale;
2733    int disp = $mem$$disp;
2734    if (index == -1) {
2735       if (disp != 0) {
2736        __ lea(rscratch1, Address(base, disp));
2737        __ ldaxr(dst_reg, rscratch1);
2738      } else {
2739        // TODO
2740        // should we ever get anything other than this case?
2741        __ ldaxr(dst_reg, base);
2742      }
2743    } else {
2744      Register index_reg = as_Register(index);
2745      if (disp == 0) {
2746        __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale)));
2747        __ ldaxr(dst_reg, rscratch1);
2748      } else {
2749        __ lea(rscratch1, Address(base, disp));
2750        __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale)));
2751	__ ldaxr(dst_reg, rscratch1);
2752      }
2753    }
2754  %}
2755
2756  enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{
2757    MacroAssembler _masm(&cbuf);
2758    Register src_reg = as_Register($src$$reg);
2759    Register base = as_Register($mem$$base);
2760    int index = $mem$$index;
2761    int scale = $mem$$scale;
2762    int disp = $mem$$disp;
2763    if (index == -1) {
2764       if (disp != 0) {
2765        __ lea(rscratch2, Address(base, disp));
2766        __ stlxr(rscratch1, src_reg, rscratch2);
2767      } else {
2768        // TODO
2769        // should we ever get anything other than this case?
2770        __ stlxr(rscratch1, src_reg, base);
2771      }
2772    } else {
2773      Register index_reg = as_Register(index);
2774      if (disp == 0) {
2775        __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale)));
2776        __ stlxr(rscratch1, src_reg, rscratch2);
2777      } else {
2778        __ lea(rscratch2, Address(base, disp));
2779        __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale)));
2780	__ stlxr(rscratch1, src_reg, rscratch2);
2781      }
2782    }
2783    __ cmpw(rscratch1, zr);
2784  %}
2785
2786  enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
2787    MacroAssembler _masm(&cbuf);
2788    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2789    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2790               Assembler::xword, /*acquire*/ false, /*release*/ true);
2791  %}
2792
2793  enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2794    MacroAssembler _masm(&cbuf);
2795    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2796    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2797               Assembler::word, /*acquire*/ false, /*release*/ true);
2798  %}
2799
2800
2801  // The only difference between aarch64_enc_cmpxchg and
2802  // aarch64_enc_cmpxchg_acq is that we use load-acquire in the
2803  // CompareAndSwap sequence to serve as a barrier on acquiring a
2804  // lock.
2805  enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
2806    MacroAssembler _masm(&cbuf);
2807    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2808    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2809               Assembler::xword, /*acquire*/ true, /*release*/ true);
2810  %}
2811
2812  enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2813    MacroAssembler _masm(&cbuf);
2814    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2815    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2816               Assembler::word, /*acquire*/ true, /*release*/ true);
2817  %}
2818
2819  // auxiliary used for CompareAndSwapX to set result register
2820  enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
2821    MacroAssembler _masm(&cbuf);
2822    Register res_reg = as_Register($res$$reg);
2823    __ cset(res_reg, Assembler::EQ);
2824  %}
2825
2826  // prefetch encodings
2827
2828  enc_class aarch64_enc_prefetchr(memory mem) %{
2829    MacroAssembler _masm(&cbuf);
2830    Register base = as_Register($mem$$base);
2831    int index = $mem$$index;
2832    int scale = $mem$$scale;
2833    int disp = $mem$$disp;
2834    if (index == -1) {
2835      __ prfm(Address(base, disp), PLDL1KEEP);
2836    } else {
2837      Register index_reg = as_Register(index);
2838      if (disp == 0) {
2839        __ prfm(Address(base, index_reg, Address::lsl(scale)), PLDL1KEEP);
2840      } else {
2841        __ lea(rscratch1, Address(base, disp));
2842	__ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PLDL1KEEP);
2843      }
2844    }
2845  %}
2846
2847  enc_class aarch64_enc_prefetchw(memory mem) %{
2848    MacroAssembler _masm(&cbuf);
2849    Register base = as_Register($mem$$base);
2850    int index = $mem$$index;
2851    int scale = $mem$$scale;
2852    int disp = $mem$$disp;
2853    if (index == -1) {
2854      __ prfm(Address(base, disp), PSTL1KEEP);
2855    } else {
2856      Register index_reg = as_Register(index);
2857      if (disp == 0) {
2858        __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP);
2859      } else {
2860        __ lea(rscratch1, Address(base, disp));
2861	__ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP);
2862      }
2863    }
2864  %}
2865
2866  enc_class aarch64_enc_prefetchnta(memory mem) %{
2867    MacroAssembler _masm(&cbuf);
2868    Register base = as_Register($mem$$base);
2869    int index = $mem$$index;
2870    int scale = $mem$$scale;
2871    int disp = $mem$$disp;
2872    if (index == -1) {
2873      __ prfm(Address(base, disp), PSTL1STRM);
2874    } else {
2875      Register index_reg = as_Register(index);
2876      if (disp == 0) {
2877        __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1STRM);
2878        __ nop();
2879      } else {
2880        __ lea(rscratch1, Address(base, disp));
2881	__ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1STRM);
2882      }
2883    }
2884  %}
2885
2886  /// mov envcodings
2887
2888  enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{
2889    MacroAssembler _masm(&cbuf);
2890    u_int32_t con = (u_int32_t)$src$$constant;
2891    Register dst_reg = as_Register($dst$$reg);
2892    if (con == 0) {
2893      __ movw(dst_reg, zr);
2894    } else {
2895      __ movw(dst_reg, con);
2896    }
2897  %}
2898
2899  enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{
2900    MacroAssembler _masm(&cbuf);
2901    Register dst_reg = as_Register($dst$$reg);
2902    u_int64_t con = (u_int64_t)$src$$constant;
2903    if (con == 0) {
2904      __ mov(dst_reg, zr);
2905    } else {
2906      __ mov(dst_reg, con);
2907    }
2908  %}
2909
2910  enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
2911    MacroAssembler _masm(&cbuf);
2912    Register dst_reg = as_Register($dst$$reg);
2913    address con = (address)$src$$constant;
2914    if (con == NULL || con == (address)1) {
2915      ShouldNotReachHere();
2916    } else {
2917      relocInfo::relocType rtype = $src->constant_reloc();
2918      if (rtype == relocInfo::oop_type) {
2919        __ movoop(dst_reg, (jobject)con, /*immediate*/true);
2920      } else if (rtype == relocInfo::metadata_type) {
2921        __ mov_metadata(dst_reg, (Metadata*)con);
2922      } else {
2923        assert(rtype == relocInfo::none, "unexpected reloc type");
2924	if (con < (address)(uintptr_t)os::vm_page_size()) {
2925	  __ mov(dst_reg, con);
2926	} else {
2927	  unsigned long offset;
2928	  __ adrp(dst_reg, con, offset);
2929	  __ add(dst_reg, dst_reg, offset);
2930	}
2931      }
2932    }
2933  %}
2934
2935  enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{
2936    MacroAssembler _masm(&cbuf);
2937    Register dst_reg = as_Register($dst$$reg);
2938    __ mov(dst_reg, zr);
2939  %}
2940
2941  enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{
2942    MacroAssembler _masm(&cbuf);
2943    Register dst_reg = as_Register($dst$$reg);
2944    __ mov(dst_reg, (u_int64_t)1);
2945  %}
2946
2947  enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{
2948    MacroAssembler _masm(&cbuf);
2949    address page = (address)$src$$constant;
2950    Register dst_reg = as_Register($dst$$reg);
2951    unsigned long off;
2952    __ adrp(dst_reg, Address(page, relocInfo::poll_type), off);
2953    assert(off == 0, "assumed offset == 0");
2954  %}
2955
2956  enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{
2957    MacroAssembler _masm(&cbuf);
2958    __ load_byte_map_base($dst$$Register);
2959  %}
2960
2961  enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{
2962    MacroAssembler _masm(&cbuf);
2963    Register dst_reg = as_Register($dst$$reg);
2964    address con = (address)$src$$constant;
2965    if (con == NULL) {
2966      ShouldNotReachHere();
2967    } else {
2968      relocInfo::relocType rtype = $src->constant_reloc();
2969      assert(rtype == relocInfo::oop_type, "unexpected reloc type");
2970      __ set_narrow_oop(dst_reg, (jobject)con);
2971    }
2972  %}
2973
2974  enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{
2975    MacroAssembler _masm(&cbuf);
2976    Register dst_reg = as_Register($dst$$reg);
2977    __ mov(dst_reg, zr);
2978  %}
2979
2980  enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{
2981    MacroAssembler _masm(&cbuf);
2982    Register dst_reg = as_Register($dst$$reg);
2983    address con = (address)$src$$constant;
2984    if (con == NULL) {
2985      ShouldNotReachHere();
2986    } else {
2987      relocInfo::relocType rtype = $src->constant_reloc();
2988      assert(rtype == relocInfo::metadata_type, "unexpected reloc type");
2989      __ set_narrow_klass(dst_reg, (Klass *)con);
2990    }
2991  %}
2992
2993  // arithmetic encodings
2994
2995  enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{
2996    MacroAssembler _masm(&cbuf);
2997    Register dst_reg = as_Register($dst$$reg);
2998    Register src_reg = as_Register($src1$$reg);
2999    int32_t con = (int32_t)$src2$$constant;
3000    // add has primary == 0, subtract has primary == 1
3001    if ($primary) { con = -con; }
3002    if (con < 0) {
3003      __ subw(dst_reg, src_reg, -con);
3004    } else {
3005      __ addw(dst_reg, src_reg, con);
3006    }
3007  %}
3008
3009  enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{
3010    MacroAssembler _masm(&cbuf);
3011    Register dst_reg = as_Register($dst$$reg);
3012    Register src_reg = as_Register($src1$$reg);
3013    int32_t con = (int32_t)$src2$$constant;
3014    // add has primary == 0, subtract has primary == 1
3015    if ($primary) { con = -con; }
3016    if (con < 0) {
3017      __ sub(dst_reg, src_reg, -con);
3018    } else {
3019      __ add(dst_reg, src_reg, con);
3020    }
3021  %}
3022
3023  enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{
3024    MacroAssembler _masm(&cbuf);
3025   Register dst_reg = as_Register($dst$$reg);
3026   Register src1_reg = as_Register($src1$$reg);
3027   Register src2_reg = as_Register($src2$$reg);
3028    __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1);
3029  %}
3030
3031  enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{
3032    MacroAssembler _masm(&cbuf);
3033   Register dst_reg = as_Register($dst$$reg);
3034   Register src1_reg = as_Register($src1$$reg);
3035   Register src2_reg = as_Register($src2$$reg);
3036    __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1);
3037  %}
3038
3039  enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{
3040    MacroAssembler _masm(&cbuf);
3041   Register dst_reg = as_Register($dst$$reg);
3042   Register src1_reg = as_Register($src1$$reg);
3043   Register src2_reg = as_Register($src2$$reg);
3044    __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1);
3045  %}
3046
3047  enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{
3048    MacroAssembler _masm(&cbuf);
3049   Register dst_reg = as_Register($dst$$reg);
3050   Register src1_reg = as_Register($src1$$reg);
3051   Register src2_reg = as_Register($src2$$reg);
3052    __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1);
3053  %}
3054
3055  // compare instruction encodings
3056
3057  enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{
3058    MacroAssembler _masm(&cbuf);
3059    Register reg1 = as_Register($src1$$reg);
3060    Register reg2 = as_Register($src2$$reg);
3061    __ cmpw(reg1, reg2);
3062  %}
3063
3064  enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{
3065    MacroAssembler _masm(&cbuf);
3066    Register reg = as_Register($src1$$reg);
3067    int32_t val = $src2$$constant;
3068    if (val >= 0) {
3069      __ subsw(zr, reg, val);
3070    } else {
3071      __ addsw(zr, reg, -val);
3072    }
3073  %}
3074
3075  enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{
3076    MacroAssembler _masm(&cbuf);
3077    Register reg1 = as_Register($src1$$reg);
3078    u_int32_t val = (u_int32_t)$src2$$constant;
3079    __ movw(rscratch1, val);
3080    __ cmpw(reg1, rscratch1);
3081  %}
3082
3083  enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{
3084    MacroAssembler _masm(&cbuf);
3085    Register reg1 = as_Register($src1$$reg);
3086    Register reg2 = as_Register($src2$$reg);
3087    __ cmp(reg1, reg2);
3088  %}
3089
3090  enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{
3091    MacroAssembler _masm(&cbuf);
3092    Register reg = as_Register($src1$$reg);
3093    int64_t val = $src2$$constant;
3094    if (val >= 0) {
3095      __ subs(zr, reg, val);
3096    } else if (val != -val) {
3097      __ adds(zr, reg, -val);
3098    } else {
3099    // aargh, Long.MIN_VALUE is a special case
3100      __ orr(rscratch1, zr, (u_int64_t)val);
3101      __ subs(zr, reg, rscratch1);
3102    }
3103  %}
3104
3105  enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{
3106    MacroAssembler _masm(&cbuf);
3107    Register reg1 = as_Register($src1$$reg);
3108    u_int64_t val = (u_int64_t)$src2$$constant;
3109    __ mov(rscratch1, val);
3110    __ cmp(reg1, rscratch1);
3111  %}
3112
3113  enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{
3114    MacroAssembler _masm(&cbuf);
3115    Register reg1 = as_Register($src1$$reg);
3116    Register reg2 = as_Register($src2$$reg);
3117    __ cmp(reg1, reg2);
3118  %}
3119
3120  enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{
3121    MacroAssembler _masm(&cbuf);
3122    Register reg1 = as_Register($src1$$reg);
3123    Register reg2 = as_Register($src2$$reg);
3124    __ cmpw(reg1, reg2);
3125  %}
3126
3127  enc_class aarch64_enc_testp(iRegP src) %{
3128    MacroAssembler _masm(&cbuf);
3129    Register reg = as_Register($src$$reg);
3130    __ cmp(reg, zr);
3131  %}
3132
3133  enc_class aarch64_enc_testn(iRegN src) %{
3134    MacroAssembler _masm(&cbuf);
3135    Register reg = as_Register($src$$reg);
3136    __ cmpw(reg, zr);
3137  %}
3138
3139  enc_class aarch64_enc_b(label lbl) %{
3140    MacroAssembler _masm(&cbuf);
3141    Label *L = $lbl$$label;
3142    __ b(*L);
3143  %}
3144
3145  enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{
3146    MacroAssembler _masm(&cbuf);
3147    Label *L = $lbl$$label;
3148    __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3149  %}
3150
3151  enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{
3152    MacroAssembler _masm(&cbuf);
3153    Label *L = $lbl$$label;
3154    __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3155  %}
3156
3157  enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result)
3158  %{
3159     Register sub_reg = as_Register($sub$$reg);
3160     Register super_reg = as_Register($super$$reg);
3161     Register temp_reg = as_Register($temp$$reg);
3162     Register result_reg = as_Register($result$$reg);
3163
3164     Label miss;
3165     MacroAssembler _masm(&cbuf);
3166     __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg,
3167                                     NULL, &miss,
3168                                     /*set_cond_codes:*/ true);
3169     if ($primary) {
3170       __ mov(result_reg, zr);
3171     }
3172     __ bind(miss);
3173  %}
3174
3175  enc_class aarch64_enc_java_static_call(method meth) %{
3176    MacroAssembler _masm(&cbuf);
3177
3178    address mark = __ pc();
3179    address addr = (address)$meth$$method;
3180    address call;
3181    if (!_method) {
3182      // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3183      call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf);
3184    } else if (_optimized_virtual) {
3185      call = __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf);
3186    } else {
3187      call = __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf);
3188    }
3189    if (call == NULL) {
3190      ciEnv::current()->record_failure("CodeCache is full");
3191      return;
3192    }
3193
3194    if (_method) {
3195      // Emit stub for static call
3196      address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark);
3197      if (stub == NULL) {
3198        ciEnv::current()->record_failure("CodeCache is full");
3199        return;
3200      }
3201    }
3202  %}
3203
3204  enc_class aarch64_enc_java_handle_call(method meth) %{
3205    MacroAssembler _masm(&cbuf);
3206    relocInfo::relocType reloc;
3207
3208    // RFP is preserved across all calls, even compiled calls.
3209    // Use it to preserve SP.
3210    __ mov(rfp, sp);
3211
3212    address mark = __ pc();
3213    address addr = (address)$meth$$method;
3214    address call;
3215    if (!_method) {
3216      // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3217      call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf);
3218    } else if (_optimized_virtual) {
3219      call = __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf);
3220    } else {
3221      call = __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf);
3222    }
3223    if (call == NULL) {
3224      ciEnv::current()->record_failure("CodeCache is full");
3225      return;
3226    }
3227
3228    if (_method) {
3229      // Emit stub for static call
3230      address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark);
3231      if (stub == NULL) {
3232        ciEnv::current()->record_failure("CodeCache is full");
3233        return;
3234      }
3235    }
3236
3237    // now restore sp
3238    __ mov(sp, rfp);
3239  %}
3240
3241  enc_class aarch64_enc_java_dynamic_call(method meth) %{
3242    MacroAssembler _masm(&cbuf);
3243    address call = __ ic_call((address)$meth$$method);
3244    if (call == NULL) {
3245      ciEnv::current()->record_failure("CodeCache is full");
3246      return;
3247    }
3248  %}
3249
3250  enc_class aarch64_enc_call_epilog() %{
3251    MacroAssembler _masm(&cbuf);
3252    if (VerifyStackAtCalls) {
3253      // Check that stack depth is unchanged: find majik cookie on stack
3254      __ call_Unimplemented();
3255    }
3256  %}
3257
3258  enc_class aarch64_enc_java_to_runtime(method meth) %{
3259    MacroAssembler _masm(&cbuf);
3260
3261    // some calls to generated routines (arraycopy code) are scheduled
3262    // by C2 as runtime calls. if so we can call them using a br (they
3263    // will be in a reachable segment) otherwise we have to use a blr
3264    // which loads the absolute address into a register.
3265    address entry = (address)$meth$$method;
3266    CodeBlob *cb = CodeCache::find_blob(entry);
3267    if (cb) {
3268      address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type));
3269      if (call == NULL) {
3270        ciEnv::current()->record_failure("CodeCache is full");
3271        return;
3272      }
3273    } else {
3274      Label retaddr;
3275      __ adr(rscratch2, retaddr);
3276      __ lea(rscratch1, RuntimeAddress(entry));
3277      // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc()
3278      __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)));
3279      __ blr(rscratch1);
3280      __ bind(retaddr);
3281      __ add(sp, sp, 2 * wordSize);
3282    }
3283  %}
3284
3285  enc_class aarch64_enc_rethrow() %{
3286    MacroAssembler _masm(&cbuf);
3287    __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub()));
3288  %}
3289
3290  enc_class aarch64_enc_ret() %{
3291    MacroAssembler _masm(&cbuf);
3292    __ ret(lr);
3293  %}
3294
3295  enc_class aarch64_enc_tail_call(iRegP jump_target) %{
3296    MacroAssembler _masm(&cbuf);
3297    Register target_reg = as_Register($jump_target$$reg);
3298    __ br(target_reg);
3299  %}
3300
3301  enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{
3302    MacroAssembler _masm(&cbuf);
3303    Register target_reg = as_Register($jump_target$$reg);
3304    // exception oop should be in r0
3305    // ret addr has been popped into lr
3306    // callee expects it in r3
3307    __ mov(r3, lr);
3308    __ br(target_reg);
3309  %}
3310
3311  enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{
3312    MacroAssembler _masm(&cbuf);
3313    Register oop = as_Register($object$$reg);
3314    Register box = as_Register($box$$reg);
3315    Register disp_hdr = as_Register($tmp$$reg);
3316    Register tmp = as_Register($tmp2$$reg);
3317    Label cont;
3318    Label object_has_monitor;
3319    Label cas_failed;
3320
3321    assert_different_registers(oop, box, tmp, disp_hdr);
3322
3323    // Load markOop from object into displaced_header.
3324    __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
3325
3326    // Always do locking in runtime.
3327    if (EmitSync & 0x01) {
3328      __ cmp(oop, zr);
3329      return;
3330    }
3331
3332    if (UseBiasedLocking && !UseOptoBiasInlining) {
3333      __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont);
3334    }
3335
3336    // Handle existing monitor
3337    if ((EmitSync & 0x02) == 0) {
3338      __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor);
3339    }
3340
3341    // Set tmp to be (markOop of object | UNLOCK_VALUE).
3342    __ orr(tmp, disp_hdr, markOopDesc::unlocked_value);
3343
3344    // Load Compare Value application register.
3345
3346    // Initialize the box. (Must happen before we update the object mark!)
3347    __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3348
3349    // Compare object markOop with an unlocked value (tmp) and if
3350    // equal exchange the stack address of our box with object markOop.
3351    // On failure disp_hdr contains the possibly locked markOop.
3352    if (UseLSE) {
3353      __ mov(disp_hdr, tmp);
3354      __ casal(Assembler::xword, disp_hdr, box, oop);  // Updates disp_hdr
3355      __ cmp(tmp, disp_hdr);
3356      __ br(Assembler::EQ, cont);
3357    } else {
3358      Label retry_load;
3359      if ((VM_Version::cpu_cpuFeatures() & VM_Version::CPU_STXR_PREFETCH))
3360        __ prfm(Address(oop), PSTL1STRM);
3361      __ bind(retry_load);
3362      __ ldaxr(disp_hdr, oop);
3363      __ cmp(tmp, disp_hdr);
3364      __ br(Assembler::NE, cas_failed);
3365      // use stlxr to ensure update is immediately visible
3366      __ stlxr(disp_hdr, box, oop);
3367      __ cbzw(disp_hdr, cont);
3368      __ b(retry_load);
3369    }
3370
3371    assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
3372
3373    // If the compare-and-exchange succeeded, then we found an unlocked
3374    // object, will have now locked it will continue at label cont
3375
3376    __ bind(cas_failed);
3377    // We did not see an unlocked object so try the fast recursive case.
3378
3379    // Check if the owner is self by comparing the value in the
3380    // markOop of object (disp_hdr) with the stack pointer.
3381    __ mov(rscratch1, sp);
3382    __ sub(disp_hdr, disp_hdr, rscratch1);
3383    __ mov(tmp, (address) (~(os::vm_page_size()-1) | (uintptr_t)markOopDesc::lock_mask_in_place));
3384    // If condition is true we are cont and hence we can store 0 as the
3385    // displaced header in the box, which indicates that it is a recursive lock.
3386    __ ands(tmp/*==0?*/, disp_hdr, tmp);
3387    __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3388
3389    // Handle existing monitor.
3390    if ((EmitSync & 0x02) == 0) {
3391      __ b(cont);
3392
3393      __ bind(object_has_monitor);
3394      // The object's monitor m is unlocked iff m->owner == NULL,
3395      // otherwise m->owner may contain a thread or a stack address.
3396      //
3397      // Try to CAS m->owner from NULL to current thread.
3398      __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value));
3399      __ mov(disp_hdr, zr);
3400
3401      if (UseLSE) {
3402        __ mov(rscratch1, disp_hdr);
3403        __ casal(Assembler::xword, rscratch1, rthread, tmp);
3404        __ cmp(rscratch1, disp_hdr);
3405      } else {
3406	Label retry_load, fail;
3407        if ((VM_Version::cpu_cpuFeatures() & VM_Version::CPU_STXR_PREFETCH))
3408          __ prfm(Address(tmp), PSTL1STRM);
3409	__ bind(retry_load);
3410        __ ldaxr(rscratch1, tmp);
3411	__ cmp(disp_hdr, rscratch1);
3412	__ br(Assembler::NE, fail);
3413        // use stlxr to ensure update is immediately visible
3414	__ stlxr(rscratch1, rthread, tmp);
3415	__ cbnzw(rscratch1, retry_load);
3416	__ bind(fail);
3417      }
3418
3419      // Store a non-null value into the box to avoid looking like a re-entrant
3420      // lock. The fast-path monitor unlock code checks for
3421      // markOopDesc::monitor_value so use markOopDesc::unused_mark which has the
3422      // relevant bit set, and also matches ObjectSynchronizer::slow_enter.
3423      __ mov(tmp, (address)markOopDesc::unused_mark());
3424      __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3425    }
3426
3427    __ bind(cont);
3428    // flag == EQ indicates success
3429    // flag == NE indicates failure
3430  %}
3431
3432  enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{
3433    MacroAssembler _masm(&cbuf);
3434    Register oop = as_Register($object$$reg);
3435    Register box = as_Register($box$$reg);
3436    Register disp_hdr = as_Register($tmp$$reg);
3437    Register tmp = as_Register($tmp2$$reg);
3438    Label cont;
3439    Label object_has_monitor;
3440
3441    assert_different_registers(oop, box, tmp, disp_hdr);
3442
3443    // Always do locking in runtime.
3444    if (EmitSync & 0x01) {
3445      __ cmp(oop, zr); // Oop can't be 0 here => always false.
3446      return;
3447    }
3448
3449    if (UseBiasedLocking && !UseOptoBiasInlining) {
3450      __ biased_locking_exit(oop, tmp, cont);
3451    }
3452
3453    // Find the lock address and load the displaced header from the stack.
3454    __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3455
3456    // If the displaced header is 0, we have a recursive unlock.
3457    __ cmp(disp_hdr, zr);
3458    __ br(Assembler::EQ, cont);
3459
3460    // Handle existing monitor.
3461    if ((EmitSync & 0x02) == 0) {
3462      __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
3463      __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor);
3464    }
3465
3466    // Check if it is still a light weight lock, this is is true if we
3467    // see the stack address of the basicLock in the markOop of the
3468    // object.
3469
3470    if (UseLSE) {
3471      __ mov(tmp, box);
3472      __ casl(Assembler::xword, tmp, disp_hdr, oop);
3473      __ cmp(tmp, box);
3474      __ b(cont);
3475    } else {
3476      Label retry_load;
3477      if ((VM_Version::cpu_cpuFeatures() & VM_Version::CPU_STXR_PREFETCH))
3478        __ prfm(Address(oop), PSTL1STRM);
3479      __ bind(retry_load);
3480      __ ldxr(tmp, oop);
3481      __ cmp(box, tmp);
3482      __ br(Assembler::NE, cont);
3483      // use stlxr to ensure update is immediately visible
3484      __ stlxr(tmp, disp_hdr, oop);
3485      __ cbzw(tmp, cont);
3486      __ b(retry_load);
3487    }
3488
3489    assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
3490
3491    // Handle existing monitor.
3492    if ((EmitSync & 0x02) == 0) {
3493      __ bind(object_has_monitor);
3494      __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor
3495      __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
3496      __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes()));
3497      __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner.
3498      __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions
3499      __ cmp(rscratch1, zr);
3500      __ br(Assembler::NE, cont);
3501
3502      __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes()));
3503      __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes()));
3504      __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0.
3505      __ cmp(rscratch1, zr);
3506      __ br(Assembler::NE, cont);
3507      // need a release store here
3508      __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
3509      __ stlr(zr, tmp); // set unowned
3510    }
3511
3512    __ bind(cont);
3513    // flag == EQ indicates success
3514    // flag == NE indicates failure
3515  %}
3516
3517%}
3518
3519//----------FRAME--------------------------------------------------------------
3520// Definition of frame structure and management information.
3521//
3522//  S T A C K   L A Y O U T    Allocators stack-slot number
3523//                             |   (to get allocators register number
3524//  G  Owned by    |        |  v    add OptoReg::stack0())
3525//  r   CALLER     |        |
3526//  o     |        +--------+      pad to even-align allocators stack-slot
3527//  w     V        |  pad0  |        numbers; owned by CALLER
3528//  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
3529//  h     ^        |   in   |  5
3530//        |        |  args  |  4   Holes in incoming args owned by SELF
3531//  |     |        |        |  3
3532//  |     |        +--------+
3533//  V     |        | old out|      Empty on Intel, window on Sparc
3534//        |    old |preserve|      Must be even aligned.
3535//        |     SP-+--------+----> Matcher::_old_SP, even aligned
3536//        |        |   in   |  3   area for Intel ret address
3537//     Owned by    |preserve|      Empty on Sparc.
3538//       SELF      +--------+
3539//        |        |  pad2  |  2   pad to align old SP
3540//        |        +--------+  1
3541//        |        | locks  |  0
3542//        |        +--------+----> OptoReg::stack0(), even aligned
3543//        |        |  pad1  | 11   pad to align new SP
3544//        |        +--------+
3545//        |        |        | 10
3546//        |        | spills |  9   spills
3547//        V        |        |  8   (pad0 slot for callee)
3548//      -----------+--------+----> Matcher::_out_arg_limit, unaligned
3549//        ^        |  out   |  7
3550//        |        |  args  |  6   Holes in outgoing args owned by CALLEE
3551//     Owned by    +--------+
3552//      CALLEE     | new out|  6   Empty on Intel, window on Sparc
3553//        |    new |preserve|      Must be even-aligned.
3554//        |     SP-+--------+----> Matcher::_new_SP, even aligned
3555//        |        |        |
3556//
3557// Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
3558//         known from SELF's arguments and the Java calling convention.
3559//         Region 6-7 is determined per call site.
3560// Note 2: If the calling convention leaves holes in the incoming argument
3561//         area, those holes are owned by SELF.  Holes in the outgoing area
3562//         are owned by the CALLEE.  Holes should not be nessecary in the
3563//         incoming area, as the Java calling convention is completely under
3564//         the control of the AD file.  Doubles can be sorted and packed to
3565//         avoid holes.  Holes in the outgoing arguments may be nessecary for
3566//         varargs C calling conventions.
3567// Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
3568//         even aligned with pad0 as needed.
3569//         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
3570//           (the latter is true on Intel but is it false on AArch64?)
3571//         region 6-11 is even aligned; it may be padded out more so that
3572//         the region from SP to FP meets the minimum stack alignment.
3573// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3574//         alignment.  Region 11, pad1, may be dynamically extended so that
3575//         SP meets the minimum alignment.
3576
3577frame %{
3578  // What direction does stack grow in (assumed to be same for C & Java)
3579  stack_direction(TOWARDS_LOW);
3580
3581  // These three registers define part of the calling convention
3582  // between compiled code and the interpreter.
3583
3584  // Inline Cache Register or methodOop for I2C.
3585  inline_cache_reg(R12);
3586
3587  // Method Oop Register when calling interpreter.
3588  interpreter_method_oop_reg(R12);
3589
3590  // Number of stack slots consumed by locking an object
3591  sync_stack_slots(2);
3592
3593  // Compiled code's Frame Pointer
3594  frame_pointer(R31);
3595
3596  // Interpreter stores its frame pointer in a register which is
3597  // stored to the stack by I2CAdaptors.
3598  // I2CAdaptors convert from interpreted java to compiled java.
3599  interpreter_frame_pointer(R29);
3600
3601  // Stack alignment requirement
3602  stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
3603
3604  // Number of stack slots between incoming argument block and the start of
3605  // a new frame.  The PROLOG must add this many slots to the stack.  The
3606  // EPILOG must remove this many slots. aarch64 needs two slots for
3607  // return address and fp.
3608  // TODO think this is correct but check
3609  in_preserve_stack_slots(4);
3610
3611  // Number of outgoing stack slots killed above the out_preserve_stack_slots
3612  // for calls to C.  Supports the var-args backing area for register parms.
3613  varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
3614
3615  // The after-PROLOG location of the return address.  Location of
3616  // return address specifies a type (REG or STACK) and a number
3617  // representing the register number (i.e. - use a register name) or
3618  // stack slot.
3619  // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3620  // Otherwise, it is above the locks and verification slot and alignment word
3621  // TODO this may well be correct but need to check why that - 2 is there
3622  // ppc port uses 0 but we definitely need to allow for fixed_slots
3623  // which folds in the space used for monitors
3624  return_addr(STACK - 2 +
3625              round_to((Compile::current()->in_preserve_stack_slots() +
3626                        Compile::current()->fixed_slots()),
3627                       stack_alignment_in_slots()));
3628
3629  // Body of function which returns an integer array locating
3630  // arguments either in registers or in stack slots.  Passed an array
3631  // of ideal registers called "sig" and a "length" count.  Stack-slot
3632  // offsets are based on outgoing arguments, i.e. a CALLER setting up
3633  // arguments for a CALLEE.  Incoming stack arguments are
3634  // automatically biased by the preserve_stack_slots field above.
3635
3636  calling_convention
3637  %{
3638    // No difference between ingoing/outgoing just pass false
3639    SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3640  %}
3641
3642  c_calling_convention
3643  %{
3644    // This is obviously always outgoing
3645    (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length);
3646  %}
3647
3648  // Location of compiled Java return values.  Same as C for now.
3649  return_value
3650  %{
3651    // TODO do we allow ideal_reg == Op_RegN???
3652    assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
3653           "only return normal values");
3654
3655    static const int lo[Op_RegL + 1] = { // enum name
3656      0,                                 // Op_Node
3657      0,                                 // Op_Set
3658      R0_num,                            // Op_RegN
3659      R0_num,                            // Op_RegI
3660      R0_num,                            // Op_RegP
3661      V0_num,                            // Op_RegF
3662      V0_num,                            // Op_RegD
3663      R0_num                             // Op_RegL
3664    };
3665
3666    static const int hi[Op_RegL + 1] = { // enum name
3667      0,                                 // Op_Node
3668      0,                                 // Op_Set
3669      OptoReg::Bad,                       // Op_RegN
3670      OptoReg::Bad,                      // Op_RegI
3671      R0_H_num,                          // Op_RegP
3672      OptoReg::Bad,                      // Op_RegF
3673      V0_H_num,                          // Op_RegD
3674      R0_H_num                           // Op_RegL
3675    };
3676
3677    return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
3678  %}
3679%}
3680
3681//----------ATTRIBUTES---------------------------------------------------------
3682//----------Operand Attributes-------------------------------------------------
3683op_attrib op_cost(1);        // Required cost attribute
3684
3685//----------Instruction Attributes---------------------------------------------
3686ins_attrib ins_cost(INSN_COST); // Required cost attribute
3687ins_attrib ins_size(32);        // Required size attribute (in bits)
3688ins_attrib ins_short_branch(0); // Required flag: is this instruction
3689                                // a non-matching short branch variant
3690                                // of some long branch?
3691ins_attrib ins_alignment(4);    // Required alignment attribute (must
3692                                // be a power of 2) specifies the
3693                                // alignment that some part of the
3694                                // instruction (not necessarily the
3695                                // start) requires.  If > 1, a
3696                                // compute_padding() function must be
3697                                // provided for the instruction
3698
3699//----------OPERANDS-----------------------------------------------------------
3700// Operand definitions must precede instruction definitions for correct parsing
3701// in the ADLC because operands constitute user defined types which are used in
3702// instruction definitions.
3703
3704//----------Simple Operands----------------------------------------------------
3705
3706// Integer operands 32 bit
3707// 32 bit immediate
3708operand immI()
3709%{
3710  match(ConI);
3711
3712  op_cost(0);
3713  format %{ %}
3714  interface(CONST_INTER);
3715%}
3716
3717// 32 bit zero
3718operand immI0()
3719%{
3720  predicate(n->get_int() == 0);
3721  match(ConI);
3722
3723  op_cost(0);
3724  format %{ %}
3725  interface(CONST_INTER);
3726%}
3727
3728// 32 bit unit increment
3729operand immI_1()
3730%{
3731  predicate(n->get_int() == 1);
3732  match(ConI);
3733
3734  op_cost(0);
3735  format %{ %}
3736  interface(CONST_INTER);
3737%}
3738
3739// 32 bit unit decrement
3740operand immI_M1()
3741%{
3742  predicate(n->get_int() == -1);
3743  match(ConI);
3744
3745  op_cost(0);
3746  format %{ %}
3747  interface(CONST_INTER);
3748%}
3749
3750operand immI_le_4()
3751%{
3752  predicate(n->get_int() <= 4);
3753  match(ConI);
3754
3755  op_cost(0);
3756  format %{ %}
3757  interface(CONST_INTER);
3758%}
3759
3760operand immI_31()
3761%{
3762  predicate(n->get_int() == 31);
3763  match(ConI);
3764
3765  op_cost(0);
3766  format %{ %}
3767  interface(CONST_INTER);
3768%}
3769
3770operand immI_8()
3771%{
3772  predicate(n->get_int() == 8);
3773  match(ConI);
3774
3775  op_cost(0);
3776  format %{ %}
3777  interface(CONST_INTER);
3778%}
3779
3780operand immI_16()
3781%{
3782  predicate(n->get_int() == 16);
3783  match(ConI);
3784
3785  op_cost(0);
3786  format %{ %}
3787  interface(CONST_INTER);
3788%}
3789
3790operand immI_24()
3791%{
3792  predicate(n->get_int() == 24);
3793  match(ConI);
3794
3795  op_cost(0);
3796  format %{ %}
3797  interface(CONST_INTER);
3798%}
3799
3800operand immI_32()
3801%{
3802  predicate(n->get_int() == 32);
3803  match(ConI);
3804
3805  op_cost(0);
3806  format %{ %}
3807  interface(CONST_INTER);
3808%}
3809
3810operand immI_48()
3811%{
3812  predicate(n->get_int() == 48);
3813  match(ConI);
3814
3815  op_cost(0);
3816  format %{ %}
3817  interface(CONST_INTER);
3818%}
3819
3820operand immI_56()
3821%{
3822  predicate(n->get_int() == 56);
3823  match(ConI);
3824
3825  op_cost(0);
3826  format %{ %}
3827  interface(CONST_INTER);
3828%}
3829
3830operand immI_64()
3831%{
3832  predicate(n->get_int() == 64);
3833  match(ConI);
3834
3835  op_cost(0);
3836  format %{ %}
3837  interface(CONST_INTER);
3838%}
3839
3840operand immI_255()
3841%{
3842  predicate(n->get_int() == 255);
3843  match(ConI);
3844
3845  op_cost(0);
3846  format %{ %}
3847  interface(CONST_INTER);
3848%}
3849
3850operand immI_65535()
3851%{
3852  predicate(n->get_int() == 65535);
3853  match(ConI);
3854
3855  op_cost(0);
3856  format %{ %}
3857  interface(CONST_INTER);
3858%}
3859
3860operand immL_63()
3861%{
3862  predicate(n->get_int() == 63);
3863  match(ConI);
3864
3865  op_cost(0);
3866  format %{ %}
3867  interface(CONST_INTER);
3868%}
3869
3870operand immL_255()
3871%{
3872  predicate(n->get_int() == 255);
3873  match(ConI);
3874
3875  op_cost(0);
3876  format %{ %}
3877  interface(CONST_INTER);
3878%}
3879
3880operand immL_65535()
3881%{
3882  predicate(n->get_long() == 65535L);
3883  match(ConL);
3884
3885  op_cost(0);
3886  format %{ %}
3887  interface(CONST_INTER);
3888%}
3889
3890operand immL_4294967295()
3891%{
3892  predicate(n->get_long() == 4294967295L);
3893  match(ConL);
3894
3895  op_cost(0);
3896  format %{ %}
3897  interface(CONST_INTER);
3898%}
3899
3900operand immL_bitmask()
3901%{
3902  predicate((n->get_long() != 0)
3903            && ((n->get_long() & 0xc000000000000000l) == 0)
3904	    && is_power_of_2(n->get_long() + 1));
3905  match(ConL);
3906
3907  op_cost(0);
3908  format %{ %}
3909  interface(CONST_INTER);
3910%}
3911
3912operand immI_bitmask()
3913%{
3914  predicate((n->get_int() != 0)
3915            && ((n->get_int() & 0xc0000000) == 0)
3916	    && is_power_of_2(n->get_int() + 1));
3917  match(ConI);
3918
3919  op_cost(0);
3920  format %{ %}
3921  interface(CONST_INTER);
3922%}
3923
3924// Scale values for scaled offset addressing modes (up to long but not quad)
3925operand immIScale()
3926%{
3927  predicate(0 <= n->get_int() && (n->get_int() <= 3));
3928  match(ConI);
3929
3930  op_cost(0);
3931  format %{ %}
3932  interface(CONST_INTER);
3933%}
3934
3935// 26 bit signed offset -- for pc-relative branches
3936operand immI26()
3937%{
3938  predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25)));
3939  match(ConI);
3940
3941  op_cost(0);
3942  format %{ %}
3943  interface(CONST_INTER);
3944%}
3945
3946// 19 bit signed offset -- for pc-relative loads
3947operand immI19()
3948%{
3949  predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18)));
3950  match(ConI);
3951
3952  op_cost(0);
3953  format %{ %}
3954  interface(CONST_INTER);
3955%}
3956
3957// 12 bit unsigned offset -- for base plus immediate loads
3958operand immIU12()
3959%{
3960  predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12)));
3961  match(ConI);
3962
3963  op_cost(0);
3964  format %{ %}
3965  interface(CONST_INTER);
3966%}
3967
3968operand immLU12()
3969%{
3970  predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12)));
3971  match(ConL);
3972
3973  op_cost(0);
3974  format %{ %}
3975  interface(CONST_INTER);
3976%}
3977
3978// Offset for scaled or unscaled immediate loads and stores
3979operand immIOffset()
3980%{
3981  predicate(Address::offset_ok_for_immed(n->get_int()));
3982  match(ConI);
3983
3984  op_cost(0);
3985  format %{ %}
3986  interface(CONST_INTER);
3987%}
3988
3989operand immIOffset4()
3990%{
3991  predicate(Address::offset_ok_for_immed(n->get_int(), 2));
3992  match(ConI);
3993
3994  op_cost(0);
3995  format %{ %}
3996  interface(CONST_INTER);
3997%}
3998
3999operand immIOffset8()
4000%{
4001  predicate(Address::offset_ok_for_immed(n->get_int(), 3));
4002  match(ConI);
4003
4004  op_cost(0);
4005  format %{ %}
4006  interface(CONST_INTER);
4007%}
4008
4009operand immIOffset16()
4010%{
4011  predicate(Address::offset_ok_for_immed(n->get_int(), 4));
4012  match(ConI);
4013
4014  op_cost(0);
4015  format %{ %}
4016  interface(CONST_INTER);
4017%}
4018
4019operand immLoffset()
4020%{
4021  predicate(Address::offset_ok_for_immed(n->get_long()));
4022  match(ConL);
4023
4024  op_cost(0);
4025  format %{ %}
4026  interface(CONST_INTER);
4027%}
4028
4029operand immLoffset4()
4030%{
4031  predicate(Address::offset_ok_for_immed(n->get_long(), 2));
4032  match(ConL);
4033
4034  op_cost(0);
4035  format %{ %}
4036  interface(CONST_INTER);
4037%}
4038
4039operand immLoffset8()
4040%{
4041  predicate(Address::offset_ok_for_immed(n->get_long(), 3));
4042  match(ConL);
4043
4044  op_cost(0);
4045  format %{ %}
4046  interface(CONST_INTER);
4047%}
4048
4049operand immLoffset16()
4050%{
4051  predicate(Address::offset_ok_for_immed(n->get_long(), 4));
4052  match(ConL);
4053
4054  op_cost(0);
4055  format %{ %}
4056  interface(CONST_INTER);
4057%}
4058
4059// 32 bit integer valid for add sub immediate
4060operand immIAddSub()
4061%{
4062  predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int()));
4063  match(ConI);
4064  op_cost(0);
4065  format %{ %}
4066  interface(CONST_INTER);
4067%}
4068
4069// 32 bit unsigned integer valid for logical immediate
4070// TODO -- check this is right when e.g the mask is 0x80000000
4071operand immILog()
4072%{
4073  predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int()));
4074  match(ConI);
4075
4076  op_cost(0);
4077  format %{ %}
4078  interface(CONST_INTER);
4079%}
4080
4081// Integer operands 64 bit
4082// 64 bit immediate
4083operand immL()
4084%{
4085  match(ConL);
4086
4087  op_cost(0);
4088  format %{ %}
4089  interface(CONST_INTER);
4090%}
4091
4092// 64 bit zero
4093operand immL0()
4094%{
4095  predicate(n->get_long() == 0);
4096  match(ConL);
4097
4098  op_cost(0);
4099  format %{ %}
4100  interface(CONST_INTER);
4101%}
4102
4103// 64 bit unit increment
4104operand immL_1()
4105%{
4106  predicate(n->get_long() == 1);
4107  match(ConL);
4108
4109  op_cost(0);
4110  format %{ %}
4111  interface(CONST_INTER);
4112%}
4113
4114// 64 bit unit decrement
4115operand immL_M1()
4116%{
4117  predicate(n->get_long() == -1);
4118  match(ConL);
4119
4120  op_cost(0);
4121  format %{ %}
4122  interface(CONST_INTER);
4123%}
4124
4125// 32 bit offset of pc in thread anchor
4126
4127operand immL_pc_off()
4128%{
4129  predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) +
4130                             in_bytes(JavaFrameAnchor::last_Java_pc_offset()));
4131  match(ConL);
4132
4133  op_cost(0);
4134  format %{ %}
4135  interface(CONST_INTER);
4136%}
4137
4138// 64 bit integer valid for add sub immediate
4139operand immLAddSub()
4140%{
4141  predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long()));
4142  match(ConL);
4143  op_cost(0);
4144  format %{ %}
4145  interface(CONST_INTER);
4146%}
4147
4148// 64 bit integer valid for logical immediate
4149operand immLLog()
4150%{
4151  predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long()));
4152  match(ConL);
4153  op_cost(0);
4154  format %{ %}
4155  interface(CONST_INTER);
4156%}
4157
4158// Long Immediate: low 32-bit mask
4159operand immL_32bits()
4160%{
4161  predicate(n->get_long() == 0xFFFFFFFFL);
4162  match(ConL);
4163  op_cost(0);
4164  format %{ %}
4165  interface(CONST_INTER);
4166%}
4167
4168// Pointer operands
4169// Pointer Immediate
4170operand immP()
4171%{
4172  match(ConP);
4173
4174  op_cost(0);
4175  format %{ %}
4176  interface(CONST_INTER);
4177%}
4178
4179// NULL Pointer Immediate
4180operand immP0()
4181%{
4182  predicate(n->get_ptr() == 0);
4183  match(ConP);
4184
4185  op_cost(0);
4186  format %{ %}
4187  interface(CONST_INTER);
4188%}
4189
4190// Pointer Immediate One
4191// this is used in object initialization (initial object header)
4192operand immP_1()
4193%{
4194  predicate(n->get_ptr() == 1);
4195  match(ConP);
4196
4197  op_cost(0);
4198  format %{ %}
4199  interface(CONST_INTER);
4200%}
4201
4202// Polling Page Pointer Immediate
4203operand immPollPage()
4204%{
4205  predicate((address)n->get_ptr() == os::get_polling_page());
4206  match(ConP);
4207
4208  op_cost(0);
4209  format %{ %}
4210  interface(CONST_INTER);
4211%}
4212
4213// Card Table Byte Map Base
4214operand immByteMapBase()
4215%{
4216  // Get base of card map
4217  predicate((jbyte*)n->get_ptr() ==
4218	((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base);
4219  match(ConP);
4220
4221  op_cost(0);
4222  format %{ %}
4223  interface(CONST_INTER);
4224%}
4225
4226// Pointer Immediate Minus One
4227// this is used when we want to write the current PC to the thread anchor
4228operand immP_M1()
4229%{
4230  predicate(n->get_ptr() == -1);
4231  match(ConP);
4232
4233  op_cost(0);
4234  format %{ %}
4235  interface(CONST_INTER);
4236%}
4237
4238// Pointer Immediate Minus Two
4239// this is used when we want to write the current PC to the thread anchor
4240operand immP_M2()
4241%{
4242  predicate(n->get_ptr() == -2);
4243  match(ConP);
4244
4245  op_cost(0);
4246  format %{ %}
4247  interface(CONST_INTER);
4248%}
4249
4250// Float and Double operands
4251// Double Immediate
4252operand immD()
4253%{
4254  match(ConD);
4255  op_cost(0);
4256  format %{ %}
4257  interface(CONST_INTER);
4258%}
4259
4260// constant 'double +0.0'.
4261operand immD0()
4262%{
4263  predicate((n->getd() == 0) &&
4264            (fpclassify(n->getd()) == FP_ZERO) && (signbit(n->getd()) == 0));
4265  match(ConD);
4266  op_cost(0);
4267  format %{ %}
4268  interface(CONST_INTER);
4269%}
4270
4271// constant 'double +0.0'.
4272operand immDPacked()
4273%{
4274  predicate(Assembler::operand_valid_for_float_immediate(n->getd()));
4275  match(ConD);
4276  op_cost(0);
4277  format %{ %}
4278  interface(CONST_INTER);
4279%}
4280
4281// Float Immediate
4282operand immF()
4283%{
4284  match(ConF);
4285  op_cost(0);
4286  format %{ %}
4287  interface(CONST_INTER);
4288%}
4289
4290// constant 'float +0.0'.
4291operand immF0()
4292%{
4293  predicate((n->getf() == 0) &&
4294            (fpclassify(n->getf()) == FP_ZERO) && (signbit(n->getf()) == 0));
4295  match(ConF);
4296  op_cost(0);
4297  format %{ %}
4298  interface(CONST_INTER);
4299%}
4300
4301//
4302operand immFPacked()
4303%{
4304  predicate(Assembler::operand_valid_for_float_immediate((double)n->getf()));
4305  match(ConF);
4306  op_cost(0);
4307  format %{ %}
4308  interface(CONST_INTER);
4309%}
4310
4311// Narrow pointer operands
4312// Narrow Pointer Immediate
4313operand immN()
4314%{
4315  match(ConN);
4316
4317  op_cost(0);
4318  format %{ %}
4319  interface(CONST_INTER);
4320%}
4321
4322// Narrow NULL Pointer Immediate
4323operand immN0()
4324%{
4325  predicate(n->get_narrowcon() == 0);
4326  match(ConN);
4327
4328  op_cost(0);
4329  format %{ %}
4330  interface(CONST_INTER);
4331%}
4332
4333operand immNKlass()
4334%{
4335  match(ConNKlass);
4336
4337  op_cost(0);
4338  format %{ %}
4339  interface(CONST_INTER);
4340%}
4341
4342// Integer 32 bit Register Operands
4343// Integer 32 bitRegister (excludes SP)
4344operand iRegI()
4345%{
4346  constraint(ALLOC_IN_RC(any_reg32));
4347  match(RegI);
4348  match(iRegINoSp);
4349  op_cost(0);
4350  format %{ %}
4351  interface(REG_INTER);
4352%}
4353
4354// Integer 32 bit Register not Special
4355operand iRegINoSp()
4356%{
4357  constraint(ALLOC_IN_RC(no_special_reg32));
4358  match(RegI);
4359  op_cost(0);
4360  format %{ %}
4361  interface(REG_INTER);
4362%}
4363
4364// Integer 64 bit Register Operands
4365// Integer 64 bit Register (includes SP)
4366operand iRegL()
4367%{
4368  constraint(ALLOC_IN_RC(any_reg));
4369  match(RegL);
4370  match(iRegLNoSp);
4371  op_cost(0);
4372  format %{ %}
4373  interface(REG_INTER);
4374%}
4375
4376// Integer 64 bit Register not Special
4377operand iRegLNoSp()
4378%{
4379  constraint(ALLOC_IN_RC(no_special_reg));
4380  match(RegL);
4381  format %{ %}
4382  interface(REG_INTER);
4383%}
4384
4385// Pointer Register Operands
4386// Pointer Register
4387operand iRegP()
4388%{
4389  constraint(ALLOC_IN_RC(ptr_reg));
4390  match(RegP);
4391  match(iRegPNoSp);
4392  match(iRegP_R0);
4393  //match(iRegP_R2);
4394  //match(iRegP_R4);
4395  //match(iRegP_R5);
4396  match(thread_RegP);
4397  op_cost(0);
4398  format %{ %}
4399  interface(REG_INTER);
4400%}
4401
4402// Pointer 64 bit Register not Special
4403operand iRegPNoSp()
4404%{
4405  constraint(ALLOC_IN_RC(no_special_ptr_reg));
4406  match(RegP);
4407  // match(iRegP);
4408  // match(iRegP_R0);
4409  // match(iRegP_R2);
4410  // match(iRegP_R4);
4411  // match(iRegP_R5);
4412  // match(thread_RegP);
4413  op_cost(0);
4414  format %{ %}
4415  interface(REG_INTER);
4416%}
4417
4418// Pointer 64 bit Register R0 only
4419operand iRegP_R0()
4420%{
4421  constraint(ALLOC_IN_RC(r0_reg));
4422  match(RegP);
4423  // match(iRegP);
4424  match(iRegPNoSp);
4425  op_cost(0);
4426  format %{ %}
4427  interface(REG_INTER);
4428%}
4429
4430// Pointer 64 bit Register R1 only
4431operand iRegP_R1()
4432%{
4433  constraint(ALLOC_IN_RC(r1_reg));
4434  match(RegP);
4435  // match(iRegP);
4436  match(iRegPNoSp);
4437  op_cost(0);
4438  format %{ %}
4439  interface(REG_INTER);
4440%}
4441
4442// Pointer 64 bit Register R2 only
4443operand iRegP_R2()
4444%{
4445  constraint(ALLOC_IN_RC(r2_reg));
4446  match(RegP);
4447  // match(iRegP);
4448  match(iRegPNoSp);
4449  op_cost(0);
4450  format %{ %}
4451  interface(REG_INTER);
4452%}
4453
4454// Pointer 64 bit Register R3 only
4455operand iRegP_R3()
4456%{
4457  constraint(ALLOC_IN_RC(r3_reg));
4458  match(RegP);
4459  // match(iRegP);
4460  match(iRegPNoSp);
4461  op_cost(0);
4462  format %{ %}
4463  interface(REG_INTER);
4464%}
4465
4466// Pointer 64 bit Register R4 only
4467operand iRegP_R4()
4468%{
4469  constraint(ALLOC_IN_RC(r4_reg));
4470  match(RegP);
4471  // match(iRegP);
4472  match(iRegPNoSp);
4473  op_cost(0);
4474  format %{ %}
4475  interface(REG_INTER);
4476%}
4477
4478// Pointer 64 bit Register R5 only
4479operand iRegP_R5()
4480%{
4481  constraint(ALLOC_IN_RC(r5_reg));
4482  match(RegP);
4483  // match(iRegP);
4484  match(iRegPNoSp);
4485  op_cost(0);
4486  format %{ %}
4487  interface(REG_INTER);
4488%}
4489
4490// Pointer 64 bit Register R10 only
4491operand iRegP_R10()
4492%{
4493  constraint(ALLOC_IN_RC(r10_reg));
4494  match(RegP);
4495  // match(iRegP);
4496  match(iRegPNoSp);
4497  op_cost(0);
4498  format %{ %}
4499  interface(REG_INTER);
4500%}
4501
4502// Long 64 bit Register R11 only
4503operand iRegL_R11()
4504%{
4505  constraint(ALLOC_IN_RC(r11_reg));
4506  match(RegL);
4507  match(iRegLNoSp);
4508  op_cost(0);
4509  format %{ %}
4510  interface(REG_INTER);
4511%}
4512
4513// Pointer 64 bit Register FP only
4514operand iRegP_FP()
4515%{
4516  constraint(ALLOC_IN_RC(fp_reg));
4517  match(RegP);
4518  // match(iRegP);
4519  op_cost(0);
4520  format %{ %}
4521  interface(REG_INTER);
4522%}
4523
4524// Register R0 only
4525operand iRegI_R0()
4526%{
4527  constraint(ALLOC_IN_RC(int_r0_reg));
4528  match(RegI);
4529  match(iRegINoSp);
4530  op_cost(0);
4531  format %{ %}
4532  interface(REG_INTER);
4533%}
4534
4535// Register R2 only
4536operand iRegI_R2()
4537%{
4538  constraint(ALLOC_IN_RC(int_r2_reg));
4539  match(RegI);
4540  match(iRegINoSp);
4541  op_cost(0);
4542  format %{ %}
4543  interface(REG_INTER);
4544%}
4545
4546// Register R3 only
4547operand iRegI_R3()
4548%{
4549  constraint(ALLOC_IN_RC(int_r3_reg));
4550  match(RegI);
4551  match(iRegINoSp);
4552  op_cost(0);
4553  format %{ %}
4554  interface(REG_INTER);
4555%}
4556
4557
4558// Register R2 only
4559operand iRegI_R4()
4560%{
4561  constraint(ALLOC_IN_RC(int_r4_reg));
4562  match(RegI);
4563  match(iRegINoSp);
4564  op_cost(0);
4565  format %{ %}
4566  interface(REG_INTER);
4567%}
4568
4569
4570// Pointer Register Operands
4571// Narrow Pointer Register
4572operand iRegN()
4573%{
4574  constraint(ALLOC_IN_RC(any_reg32));
4575  match(RegN);
4576  match(iRegNNoSp);
4577  op_cost(0);
4578  format %{ %}
4579  interface(REG_INTER);
4580%}
4581
4582// Integer 64 bit Register not Special
4583operand iRegNNoSp()
4584%{
4585  constraint(ALLOC_IN_RC(no_special_reg32));
4586  match(RegN);
4587  op_cost(0);
4588  format %{ %}
4589  interface(REG_INTER);
4590%}
4591
4592// heap base register -- used for encoding immN0
4593
4594operand iRegIHeapbase()
4595%{
4596  constraint(ALLOC_IN_RC(heapbase_reg));
4597  match(RegI);
4598  op_cost(0);
4599  format %{ %}
4600  interface(REG_INTER);
4601%}
4602
4603// Float Register
4604// Float register operands
4605operand vRegF()
4606%{
4607  constraint(ALLOC_IN_RC(float_reg));
4608  match(RegF);
4609
4610  op_cost(0);
4611  format %{ %}
4612  interface(REG_INTER);
4613%}
4614
4615// Double Register
4616// Double register operands
4617operand vRegD()
4618%{
4619  constraint(ALLOC_IN_RC(double_reg));
4620  match(RegD);
4621
4622  op_cost(0);
4623  format %{ %}
4624  interface(REG_INTER);
4625%}
4626
4627operand vecD()
4628%{
4629  constraint(ALLOC_IN_RC(vectord_reg));
4630  match(VecD);
4631
4632  op_cost(0);
4633  format %{ %}
4634  interface(REG_INTER);
4635%}
4636
4637operand vecX()
4638%{
4639  constraint(ALLOC_IN_RC(vectorx_reg));
4640  match(VecX);
4641
4642  op_cost(0);
4643  format %{ %}
4644  interface(REG_INTER);
4645%}
4646
4647operand vRegD_V0()
4648%{
4649  constraint(ALLOC_IN_RC(v0_reg));
4650  match(RegD);
4651  op_cost(0);
4652  format %{ %}
4653  interface(REG_INTER);
4654%}
4655
4656operand vRegD_V1()
4657%{
4658  constraint(ALLOC_IN_RC(v1_reg));
4659  match(RegD);
4660  op_cost(0);
4661  format %{ %}
4662  interface(REG_INTER);
4663%}
4664
4665operand vRegD_V2()
4666%{
4667  constraint(ALLOC_IN_RC(v2_reg));
4668  match(RegD);
4669  op_cost(0);
4670  format %{ %}
4671  interface(REG_INTER);
4672%}
4673
4674operand vRegD_V3()
4675%{
4676  constraint(ALLOC_IN_RC(v3_reg));
4677  match(RegD);
4678  op_cost(0);
4679  format %{ %}
4680  interface(REG_INTER);
4681%}
4682
4683// Flags register, used as output of signed compare instructions
4684
4685// note that on AArch64 we also use this register as the output for
4686// for floating point compare instructions (CmpF CmpD). this ensures
4687// that ordered inequality tests use GT, GE, LT or LE none of which
4688// pass through cases where the result is unordered i.e. one or both
4689// inputs to the compare is a NaN. this means that the ideal code can
4690// replace e.g. a GT with an LE and not end up capturing the NaN case
4691// (where the comparison should always fail). EQ and NE tests are
4692// always generated in ideal code so that unordered folds into the NE
4693// case, matching the behaviour of AArch64 NE.
4694//
4695// This differs from x86 where the outputs of FP compares use a
4696// special FP flags registers and where compares based on this
4697// register are distinguished into ordered inequalities (cmpOpUCF) and
4698// EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests
4699// to explicitly handle the unordered case in branches. x86 also has
4700// to include extra CMoveX rules to accept a cmpOpUCF input.
4701
4702operand rFlagsReg()
4703%{
4704  constraint(ALLOC_IN_RC(int_flags));
4705  match(RegFlags);
4706
4707  op_cost(0);
4708  format %{ "RFLAGS" %}
4709  interface(REG_INTER);
4710%}
4711
4712// Flags register, used as output of unsigned compare instructions
4713operand rFlagsRegU()
4714%{
4715  constraint(ALLOC_IN_RC(int_flags));
4716  match(RegFlags);
4717
4718  op_cost(0);
4719  format %{ "RFLAGSU" %}
4720  interface(REG_INTER);
4721%}
4722
4723// Special Registers
4724
4725// Method Register
4726operand inline_cache_RegP(iRegP reg)
4727%{
4728  constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg
4729  match(reg);
4730  match(iRegPNoSp);
4731  op_cost(0);
4732  format %{ %}
4733  interface(REG_INTER);
4734%}
4735
4736operand interpreter_method_oop_RegP(iRegP reg)
4737%{
4738  constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg
4739  match(reg);
4740  match(iRegPNoSp);
4741  op_cost(0);
4742  format %{ %}
4743  interface(REG_INTER);
4744%}
4745
4746// Thread Register
4747operand thread_RegP(iRegP reg)
4748%{
4749  constraint(ALLOC_IN_RC(thread_reg)); // link_reg
4750  match(reg);
4751  op_cost(0);
4752  format %{ %}
4753  interface(REG_INTER);
4754%}
4755
4756operand lr_RegP(iRegP reg)
4757%{
4758  constraint(ALLOC_IN_RC(lr_reg)); // link_reg
4759  match(reg);
4760  op_cost(0);
4761  format %{ %}
4762  interface(REG_INTER);
4763%}
4764
4765//----------Memory Operands----------------------------------------------------
4766
4767operand indirect(iRegP reg)
4768%{
4769  constraint(ALLOC_IN_RC(ptr_reg));
4770  match(reg);
4771  op_cost(0);
4772  format %{ "[$reg]" %}
4773  interface(MEMORY_INTER) %{
4774    base($reg);
4775    index(0xffffffff);
4776    scale(0x0);
4777    disp(0x0);
4778  %}
4779%}
4780
4781operand indIndexScaledOffsetI(iRegP reg, iRegL lreg, immIScale scale, immIU12 off)
4782%{
4783  predicate(size_fits_all_mem_uses(n->as_AddP(),
4784                                   n->in(AddPNode::Address)->in(AddPNode::Offset)->in(2)->get_int()));
4785  constraint(ALLOC_IN_RC(ptr_reg));
4786  match(AddP (AddP reg (LShiftL lreg scale)) off);
4787  op_cost(INSN_COST);
4788  format %{ "$reg, $lreg lsl($scale), $off" %}
4789  interface(MEMORY_INTER) %{
4790    base($reg);
4791    index($lreg);
4792    scale($scale);
4793    disp($off);
4794  %}
4795%}
4796
4797operand indIndexScaledOffsetL(iRegP reg, iRegL lreg, immIScale scale, immLU12 off)
4798%{
4799  predicate(size_fits_all_mem_uses(n->as_AddP(),
4800                                   n->in(AddPNode::Address)->in(AddPNode::Offset)->in(2)->get_int()));
4801  constraint(ALLOC_IN_RC(ptr_reg));
4802  match(AddP (AddP reg (LShiftL lreg scale)) off);
4803  op_cost(INSN_COST);
4804  format %{ "$reg, $lreg lsl($scale), $off" %}
4805  interface(MEMORY_INTER) %{
4806    base($reg);
4807    index($lreg);
4808    scale($scale);
4809    disp($off);
4810  %}
4811%}
4812
4813operand indIndexOffsetI2L(iRegP reg, iRegI ireg, immLU12 off)
4814%{
4815  constraint(ALLOC_IN_RC(ptr_reg));
4816  match(AddP (AddP reg (ConvI2L ireg)) off);
4817  op_cost(INSN_COST);
4818  format %{ "$reg, $ireg, $off I2L" %}
4819  interface(MEMORY_INTER) %{
4820    base($reg);
4821    index($ireg);
4822    scale(0x0);
4823    disp($off);
4824  %}
4825%}
4826
4827operand indIndexScaledOffsetI2L(iRegP reg, iRegI ireg, immIScale scale, immLU12 off)
4828%{
4829  predicate(size_fits_all_mem_uses(n->as_AddP(),
4830                                   n->in(AddPNode::Address)->in(AddPNode::Offset)->in(2)->get_int()));
4831  constraint(ALLOC_IN_RC(ptr_reg));
4832  match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
4833  op_cost(INSN_COST);
4834  format %{ "$reg, $ireg sxtw($scale), $off I2L" %}
4835  interface(MEMORY_INTER) %{
4836    base($reg);
4837    index($ireg);
4838    scale($scale);
4839    disp($off);
4840  %}
4841%}
4842
4843operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale)
4844%{
4845  predicate(size_fits_all_mem_uses(n->as_AddP(),
4846                                   n->in(AddPNode::Offset)->in(2)->get_int()));
4847  constraint(ALLOC_IN_RC(ptr_reg));
4848  match(AddP reg (LShiftL (ConvI2L ireg) scale));
4849  op_cost(0);
4850  format %{ "$reg, $ireg sxtw($scale), 0, I2L" %}
4851  interface(MEMORY_INTER) %{
4852    base($reg);
4853    index($ireg);
4854    scale($scale);
4855    disp(0x0);
4856  %}
4857%}
4858
4859operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale)
4860%{
4861  predicate(size_fits_all_mem_uses(n->as_AddP(),
4862                                   n->in(AddPNode::Offset)->in(2)->get_int()));
4863  constraint(ALLOC_IN_RC(ptr_reg));
4864  match(AddP reg (LShiftL lreg scale));
4865  op_cost(0);
4866  format %{ "$reg, $lreg lsl($scale)" %}
4867  interface(MEMORY_INTER) %{
4868    base($reg);
4869    index($lreg);
4870    scale($scale);
4871    disp(0x0);
4872  %}
4873%}
4874
4875operand indIndex(iRegP reg, iRegL lreg)
4876%{
4877  constraint(ALLOC_IN_RC(ptr_reg));
4878  match(AddP reg lreg);
4879  op_cost(0);
4880  format %{ "$reg, $lreg" %}
4881  interface(MEMORY_INTER) %{
4882    base($reg);
4883    index($lreg);
4884    scale(0x0);
4885    disp(0x0);
4886  %}
4887%}
4888
4889operand indOffI(iRegP reg, immIOffset off)
4890%{
4891  constraint(ALLOC_IN_RC(ptr_reg));
4892  match(AddP reg off);
4893  op_cost(0);
4894  format %{ "[$reg, $off]" %}
4895  interface(MEMORY_INTER) %{
4896    base($reg);
4897    index(0xffffffff);
4898    scale(0x0);
4899    disp($off);
4900  %}
4901%}
4902
4903operand indOffI4(iRegP reg, immIOffset4 off)
4904%{
4905  constraint(ALLOC_IN_RC(ptr_reg));
4906  match(AddP reg off);
4907  op_cost(0);
4908  format %{ "[$reg, $off]" %}
4909  interface(MEMORY_INTER) %{
4910    base($reg);
4911    index(0xffffffff);
4912    scale(0x0);
4913    disp($off);
4914  %}
4915%}
4916
4917operand indOffI8(iRegP reg, immIOffset8 off)
4918%{
4919  constraint(ALLOC_IN_RC(ptr_reg));
4920  match(AddP reg off);
4921  op_cost(0);
4922  format %{ "[$reg, $off]" %}
4923  interface(MEMORY_INTER) %{
4924    base($reg);
4925    index(0xffffffff);
4926    scale(0x0);
4927    disp($off);
4928  %}
4929%}
4930
4931operand indOffI16(iRegP reg, immIOffset16 off)
4932%{
4933  constraint(ALLOC_IN_RC(ptr_reg));
4934  match(AddP reg off);
4935  op_cost(0);
4936  format %{ "[$reg, $off]" %}
4937  interface(MEMORY_INTER) %{
4938    base($reg);
4939    index(0xffffffff);
4940    scale(0x0);
4941    disp($off);
4942  %}
4943%}
4944
4945operand indOffL(iRegP reg, immLoffset off)
4946%{
4947  constraint(ALLOC_IN_RC(ptr_reg));
4948  match(AddP reg off);
4949  op_cost(0);
4950  format %{ "[$reg, $off]" %}
4951  interface(MEMORY_INTER) %{
4952    base($reg);
4953    index(0xffffffff);
4954    scale(0x0);
4955    disp($off);
4956  %}
4957%}
4958
4959operand indOffL4(iRegP reg, immLoffset4 off)
4960%{
4961  constraint(ALLOC_IN_RC(ptr_reg));
4962  match(AddP reg off);
4963  op_cost(0);
4964  format %{ "[$reg, $off]" %}
4965  interface(MEMORY_INTER) %{
4966    base($reg);
4967    index(0xffffffff);
4968    scale(0x0);
4969    disp($off);
4970  %}
4971%}
4972
4973operand indOffL8(iRegP reg, immLoffset8 off)
4974%{
4975  constraint(ALLOC_IN_RC(ptr_reg));
4976  match(AddP reg off);
4977  op_cost(0);
4978  format %{ "[$reg, $off]" %}
4979  interface(MEMORY_INTER) %{
4980    base($reg);
4981    index(0xffffffff);
4982    scale(0x0);
4983    disp($off);
4984  %}
4985%}
4986
4987operand indOffL16(iRegP reg, immLoffset16 off)
4988%{
4989  constraint(ALLOC_IN_RC(ptr_reg));
4990  match(AddP reg off);
4991  op_cost(0);
4992  format %{ "[$reg, $off]" %}
4993  interface(MEMORY_INTER) %{
4994    base($reg);
4995    index(0xffffffff);
4996    scale(0x0);
4997    disp($off);
4998  %}
4999%}
5000
5001operand indirectN(iRegN reg)
5002%{
5003  predicate(Universe::narrow_oop_shift() == 0);
5004  constraint(ALLOC_IN_RC(ptr_reg));
5005  match(DecodeN reg);
5006  op_cost(0);
5007  format %{ "[$reg]\t# narrow" %}
5008  interface(MEMORY_INTER) %{
5009    base($reg);
5010    index(0xffffffff);
5011    scale(0x0);
5012    disp(0x0);
5013  %}
5014%}
5015
5016operand indIndexScaledOffsetIN(iRegN reg, iRegL lreg, immIScale scale, immIU12 off)
5017%{
5018  predicate(Universe::narrow_oop_shift() == 0 &&
5019            size_fits_all_mem_uses(n->as_AddP(),
5020                                   n->in(AddPNode::Address)->in(AddPNode::Offset)->in(2)->get_int()));
5021  constraint(ALLOC_IN_RC(ptr_reg));
5022  match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
5023  op_cost(0);
5024  format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %}
5025  interface(MEMORY_INTER) %{
5026    base($reg);
5027    index($lreg);
5028    scale($scale);
5029    disp($off);
5030  %}
5031%}
5032
5033operand indIndexScaledOffsetLN(iRegN reg, iRegL lreg, immIScale scale, immLU12 off)
5034%{
5035  predicate(Universe::narrow_oop_shift() == 0 &&
5036            size_fits_all_mem_uses(n->as_AddP(),
5037                                   n->in(AddPNode::Address)->in(AddPNode::Offset)->in(2)->get_int()));
5038  constraint(ALLOC_IN_RC(ptr_reg));
5039  match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
5040  op_cost(INSN_COST);
5041  format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %}
5042  interface(MEMORY_INTER) %{
5043    base($reg);
5044    index($lreg);
5045    scale($scale);
5046    disp($off);
5047  %}
5048%}
5049
5050operand indIndexOffsetI2LN(iRegN reg, iRegI ireg, immLU12 off)
5051%{
5052  predicate(Universe::narrow_oop_shift() == 0);
5053  constraint(ALLOC_IN_RC(ptr_reg));
5054  match(AddP (AddP (DecodeN reg) (ConvI2L ireg)) off);
5055  op_cost(INSN_COST);
5056  format %{ "$reg, $ireg, $off I2L\t# narrow" %}
5057  interface(MEMORY_INTER) %{
5058    base($reg);
5059    index($ireg);
5060    scale(0x0);
5061    disp($off);
5062  %}
5063%}
5064
5065operand indIndexScaledOffsetI2LN(iRegN reg, iRegI ireg, immIScale scale, immLU12 off)
5066%{
5067  predicate(Universe::narrow_oop_shift() == 0 &&
5068            size_fits_all_mem_uses(n->as_AddP(),
5069                                   n->in(AddPNode::Address)->in(AddPNode::Offset)->in(2)->get_int()));
5070  constraint(ALLOC_IN_RC(ptr_reg));
5071  match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)) off);
5072  op_cost(INSN_COST);
5073  format %{ "$reg, $ireg sxtw($scale), $off I2L\t# narrow" %}
5074  interface(MEMORY_INTER) %{
5075    base($reg);
5076    index($ireg);
5077    scale($scale);
5078    disp($off);
5079  %}
5080%}
5081
5082operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale)
5083%{
5084  predicate(Universe::narrow_oop_shift() == 0 &&
5085            size_fits_all_mem_uses(n->as_AddP(),
5086                                   n->in(AddPNode::Offset)->in(2)->get_int()));
5087  constraint(ALLOC_IN_RC(ptr_reg));
5088  match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale));
5089  op_cost(0);
5090  format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %}
5091  interface(MEMORY_INTER) %{
5092    base($reg);
5093    index($ireg);
5094    scale($scale);
5095    disp(0x0);
5096  %}
5097%}
5098
5099operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale)
5100%{
5101  predicate(Universe::narrow_oop_shift() == 0 &&
5102            size_fits_all_mem_uses(n->as_AddP(),
5103                                   n->in(AddPNode::Offset)->in(2)->get_int()));
5104  constraint(ALLOC_IN_RC(ptr_reg));
5105  match(AddP (DecodeN reg) (LShiftL lreg scale));
5106  op_cost(0);
5107  format %{ "$reg, $lreg lsl($scale)\t# narrow" %}
5108  interface(MEMORY_INTER) %{
5109    base($reg);
5110    index($lreg);
5111    scale($scale);
5112    disp(0x0);
5113  %}
5114%}
5115
5116operand indIndexN(iRegN reg, iRegL lreg)
5117%{
5118  predicate(Universe::narrow_oop_shift() == 0);
5119  constraint(ALLOC_IN_RC(ptr_reg));
5120  match(AddP (DecodeN reg) lreg);
5121  op_cost(0);
5122  format %{ "$reg, $lreg\t# narrow" %}
5123  interface(MEMORY_INTER) %{
5124    base($reg);
5125    index($lreg);
5126    scale(0x0);
5127    disp(0x0);
5128  %}
5129%}
5130
5131operand indOffIN(iRegN reg, immIOffset off)
5132%{
5133  predicate(Universe::narrow_oop_shift() == 0);
5134  constraint(ALLOC_IN_RC(ptr_reg));
5135  match(AddP (DecodeN reg) off);
5136  op_cost(0);
5137  format %{ "[$reg, $off]\t# narrow" %}
5138  interface(MEMORY_INTER) %{
5139    base($reg);
5140    index(0xffffffff);
5141    scale(0x0);
5142    disp($off);
5143  %}
5144%}
5145
5146operand indOffLN(iRegN reg, immLoffset off)
5147%{
5148  predicate(Universe::narrow_oop_shift() == 0);
5149  constraint(ALLOC_IN_RC(ptr_reg));
5150  match(AddP (DecodeN reg) off);
5151  op_cost(0);
5152  format %{ "[$reg, $off]\t# narrow" %}
5153  interface(MEMORY_INTER) %{
5154    base($reg);
5155    index(0xffffffff);
5156    scale(0x0);
5157    disp($off);
5158  %}
5159%}
5160
5161
5162
5163// AArch64 opto stubs need to write to the pc slot in the thread anchor
5164operand thread_anchor_pc(thread_RegP reg, immL_pc_off off)
5165%{
5166  constraint(ALLOC_IN_RC(ptr_reg));
5167  match(AddP reg off);
5168  op_cost(0);
5169  format %{ "[$reg, $off]" %}
5170  interface(MEMORY_INTER) %{
5171    base($reg);
5172    index(0xffffffff);
5173    scale(0x0);
5174    disp($off);
5175  %}
5176%}
5177
5178//----------Special Memory Operands--------------------------------------------
5179// Stack Slot Operand - This operand is used for loading and storing temporary
5180//                      values on the stack where a match requires a value to
5181//                      flow through memory.
5182operand stackSlotP(sRegP reg)
5183%{
5184  constraint(ALLOC_IN_RC(stack_slots));
5185  op_cost(100);
5186  // No match rule because this operand is only generated in matching
5187  // match(RegP);
5188  format %{ "[$reg]" %}
5189  interface(MEMORY_INTER) %{
5190    base(0x1e);  // RSP
5191    index(0x0);  // No Index
5192    scale(0x0);  // No Scale
5193    disp($reg);  // Stack Offset
5194  %}
5195%}
5196
5197operand stackSlotI(sRegI reg)
5198%{
5199  constraint(ALLOC_IN_RC(stack_slots));
5200  // No match rule because this operand is only generated in matching
5201  // match(RegI);
5202  format %{ "[$reg]" %}
5203  interface(MEMORY_INTER) %{
5204    base(0x1e);  // RSP
5205    index(0x0);  // No Index
5206    scale(0x0);  // No Scale
5207    disp($reg);  // Stack Offset
5208  %}
5209%}
5210
5211operand stackSlotF(sRegF reg)
5212%{
5213  constraint(ALLOC_IN_RC(stack_slots));
5214  // No match rule because this operand is only generated in matching
5215  // match(RegF);
5216  format %{ "[$reg]" %}
5217  interface(MEMORY_INTER) %{
5218    base(0x1e);  // RSP
5219    index(0x0);  // No Index
5220    scale(0x0);  // No Scale
5221    disp($reg);  // Stack Offset
5222  %}
5223%}
5224
5225operand stackSlotD(sRegD reg)
5226%{
5227  constraint(ALLOC_IN_RC(stack_slots));
5228  // No match rule because this operand is only generated in matching
5229  // match(RegD);
5230  format %{ "[$reg]" %}
5231  interface(MEMORY_INTER) %{
5232    base(0x1e);  // RSP
5233    index(0x0);  // No Index
5234    scale(0x0);  // No Scale
5235    disp($reg);  // Stack Offset
5236  %}
5237%}
5238
5239operand stackSlotL(sRegL reg)
5240%{
5241  constraint(ALLOC_IN_RC(stack_slots));
5242  // No match rule because this operand is only generated in matching
5243  // match(RegL);
5244  format %{ "[$reg]" %}
5245  interface(MEMORY_INTER) %{
5246    base(0x1e);  // RSP
5247    index(0x0);  // No Index
5248    scale(0x0);  // No Scale
5249    disp($reg);  // Stack Offset
5250  %}
5251%}
5252
5253// Operands for expressing Control Flow
5254// NOTE: Label is a predefined operand which should not be redefined in
5255//       the AD file. It is generically handled within the ADLC.
5256
5257//----------Conditional Branch Operands----------------------------------------
5258// Comparison Op  - This is the operation of the comparison, and is limited to
5259//                  the following set of codes:
5260//                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5261//
5262// Other attributes of the comparison, such as unsignedness, are specified
5263// by the comparison instruction that sets a condition code flags register.
5264// That result is represented by a flags operand whose subtype is appropriate
5265// to the unsignedness (etc.) of the comparison.
5266//
5267// Later, the instruction which matches both the Comparison Op (a Bool) and
5268// the flags (produced by the Cmp) specifies the coding of the comparison op
5269// by matching a specific subtype of Bool operand below, such as cmpOpU.
5270
5271// used for signed integral comparisons and fp comparisons
5272
5273operand cmpOp()
5274%{
5275  match(Bool);
5276
5277  format %{ "" %}
5278  interface(COND_INTER) %{
5279    equal(0x0, "eq");
5280    not_equal(0x1, "ne");
5281    less(0xb, "lt");
5282    greater_equal(0xa, "ge");
5283    less_equal(0xd, "le");
5284    greater(0xc, "gt");
5285    overflow(0x6, "vs");
5286    no_overflow(0x7, "vc");
5287  %}
5288%}
5289
5290// used for unsigned integral comparisons
5291
5292operand cmpOpU()
5293%{
5294  match(Bool);
5295
5296  format %{ "" %}
5297  interface(COND_INTER) %{
5298    equal(0x0, "eq");
5299    not_equal(0x1, "ne");
5300    less(0x3, "lo");
5301    greater_equal(0x2, "hs");
5302    less_equal(0x9, "ls");
5303    greater(0x8, "hi");
5304    overflow(0x6, "vs");
5305    no_overflow(0x7, "vc");
5306  %}
5307%}
5308
5309// Special operand allowing long args to int ops to be truncated for free
5310
5311operand iRegL2I(iRegL reg) %{
5312
5313  op_cost(0);
5314
5315  match(ConvL2I reg);
5316
5317  format %{ "l2i($reg)" %}
5318
5319  interface(REG_INTER)
5320%}
5321
5322opclass vmem4(indirect, indIndex, indOffI4, indOffL4);
5323opclass vmem8(indirect, indIndex, indOffI8, indOffL8);
5324opclass vmem16(indirect, indIndex, indOffI16, indOffL16);
5325
5326//----------OPERAND CLASSES----------------------------------------------------
5327// Operand Classes are groups of operands that are used as to simplify
5328// instruction definitions by not requiring the AD writer to specify
5329// separate instructions for every form of operand when the
5330// instruction accepts multiple operand types with the same basic
5331// encoding and format. The classic case of this is memory operands.
5332
5333// memory is used to define read/write location for load/store
5334// instruction defs. we can turn a memory op into an Address
5335
5336opclass memory(indirect, indIndexScaledOffsetI, indIndexScaledOffsetL, indIndexOffsetI2L, indIndexScaledOffsetI2L, indIndexScaled, indIndexScaledI2L, indIndex, indOffI, indOffL,
5337               indirectN, indIndexScaledOffsetIN, indIndexScaledOffsetLN, indIndexOffsetI2LN, indIndexScaledOffsetI2LN, indIndexScaledN, indIndexScaledI2LN, indIndexN, indOffIN, indOffLN);
5338
5339 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5340
5341
5342// iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5343// operations. it allows the src to be either an iRegI or a (ConvL2I
5344// iRegL). in the latter case the l2i normally planted for a ConvL2I
5345// can be elided because the 32-bit instruction will just employ the
5346// lower 32 bits anyway.
5347//
5348// n.b. this does not elide all L2I conversions. if the truncated
5349// value is consumed by more than one operation then the ConvL2I
5350// cannot be bundled into the consuming nodes so an l2i gets planted
5351// (actually a movw $dst $src) and the downstream instructions consume
5352// the result of the l2i as an iRegI input. That's a shame since the
5353// movw is actually redundant but its not too costly.
5354
5355opclass iRegIorL2I(iRegI, iRegL2I);
5356
5357//----------PIPELINE-----------------------------------------------------------
5358// Rules which define the behavior of the target architectures pipeline.
5359
5360// For specific pipelines, eg A53, define the stages of that pipeline
5361//pipe_desc(ISS, EX1, EX2, WR);
5362#define ISS S0
5363#define EX1 S1
5364#define EX2 S2
5365#define WR  S3
5366
5367// Integer ALU reg operation
5368pipeline %{
5369
5370attributes %{
5371  // ARM instructions are of fixed length
5372  fixed_size_instructions;        // Fixed size instructions TODO does
5373  max_instructions_per_bundle = 2;   // A53 = 2, A57 = 4
5374  // ARM instructions come in 32-bit word units
5375  instruction_unit_size = 4;         // An instruction is 4 bytes long
5376  instruction_fetch_unit_size = 64;  // The processor fetches one line
5377  instruction_fetch_units = 1;       // of 64 bytes
5378
5379  // List of nop instructions
5380  nops( MachNop );
5381%}
5382
5383// We don't use an actual pipeline model so don't care about resources
5384// or description. we do use pipeline classes to introduce fixed
5385// latencies
5386
5387//----------RESOURCES----------------------------------------------------------
5388// Resources are the functional units available to the machine
5389
5390resources( INS0, INS1, INS01 = INS0 | INS1,
5391           ALU0, ALU1, ALU = ALU0 | ALU1,
5392           MAC,
5393           DIV,
5394           BRANCH,
5395           LDST,
5396           NEON_FP);
5397
5398//----------PIPELINE DESCRIPTION-----------------------------------------------
5399// Pipeline Description specifies the stages in the machine's pipeline
5400
5401// Define the pipeline as a generic 6 stage pipeline
5402pipe_desc(S0, S1, S2, S3, S4, S5);
5403
5404//----------PIPELINE CLASSES---------------------------------------------------
5405// Pipeline Classes describe the stages in which input and output are
5406// referenced by the hardware pipeline.
5407
5408pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2)
5409%{
5410  single_instruction;
5411  src1   : S1(read);
5412  src2   : S2(read);
5413  dst    : S5(write);
5414  INS01  : ISS;
5415  NEON_FP : S5;
5416%}
5417
5418pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2)
5419%{
5420  single_instruction;
5421  src1   : S1(read);
5422  src2   : S2(read);
5423  dst    : S5(write);
5424  INS01  : ISS;
5425  NEON_FP : S5;
5426%}
5427
5428pipe_class fp_uop_s(vRegF dst, vRegF src)
5429%{
5430  single_instruction;
5431  src    : S1(read);
5432  dst    : S5(write);
5433  INS01  : ISS;
5434  NEON_FP : S5;
5435%}
5436
5437pipe_class fp_uop_d(vRegD dst, vRegD src)
5438%{
5439  single_instruction;
5440  src    : S1(read);
5441  dst    : S5(write);
5442  INS01  : ISS;
5443  NEON_FP : S5;
5444%}
5445
5446pipe_class fp_d2f(vRegF dst, vRegD src)
5447%{
5448  single_instruction;
5449  src    : S1(read);
5450  dst    : S5(write);
5451  INS01  : ISS;
5452  NEON_FP : S5;
5453%}
5454
5455pipe_class fp_f2d(vRegD dst, vRegF src)
5456%{
5457  single_instruction;
5458  src    : S1(read);
5459  dst    : S5(write);
5460  INS01  : ISS;
5461  NEON_FP : S5;
5462%}
5463
5464pipe_class fp_f2i(iRegINoSp dst, vRegF src)
5465%{
5466  single_instruction;
5467  src    : S1(read);
5468  dst    : S5(write);
5469  INS01  : ISS;
5470  NEON_FP : S5;
5471%}
5472
5473pipe_class fp_f2l(iRegLNoSp dst, vRegF src)
5474%{
5475  single_instruction;
5476  src    : S1(read);
5477  dst    : S5(write);
5478  INS01  : ISS;
5479  NEON_FP : S5;
5480%}
5481
5482pipe_class fp_i2f(vRegF dst, iRegIorL2I src)
5483%{
5484  single_instruction;
5485  src    : S1(read);
5486  dst    : S5(write);
5487  INS01  : ISS;
5488  NEON_FP : S5;
5489%}
5490
5491pipe_class fp_l2f(vRegF dst, iRegL src)
5492%{
5493  single_instruction;
5494  src    : S1(read);
5495  dst    : S5(write);
5496  INS01  : ISS;
5497  NEON_FP : S5;
5498%}
5499
5500pipe_class fp_d2i(iRegINoSp dst, vRegD src)
5501%{
5502  single_instruction;
5503  src    : S1(read);
5504  dst    : S5(write);
5505  INS01  : ISS;
5506  NEON_FP : S5;
5507%}
5508
5509pipe_class fp_d2l(iRegLNoSp dst, vRegD src)
5510%{
5511  single_instruction;
5512  src    : S1(read);
5513  dst    : S5(write);
5514  INS01  : ISS;
5515  NEON_FP : S5;
5516%}
5517
5518pipe_class fp_i2d(vRegD dst, iRegIorL2I src)
5519%{
5520  single_instruction;
5521  src    : S1(read);
5522  dst    : S5(write);
5523  INS01  : ISS;
5524  NEON_FP : S5;
5525%}
5526
5527pipe_class fp_l2d(vRegD dst, iRegIorL2I src)
5528%{
5529  single_instruction;
5530  src    : S1(read);
5531  dst    : S5(write);
5532  INS01  : ISS;
5533  NEON_FP : S5;
5534%}
5535
5536pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2)
5537%{
5538  single_instruction;
5539  src1   : S1(read);
5540  src2   : S2(read);
5541  dst    : S5(write);
5542  INS0   : ISS;
5543  NEON_FP : S5;
5544%}
5545
5546pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2)
5547%{
5548  single_instruction;
5549  src1   : S1(read);
5550  src2   : S2(read);
5551  dst    : S5(write);
5552  INS0   : ISS;
5553  NEON_FP : S5;
5554%}
5555
5556pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr)
5557%{
5558  single_instruction;
5559  cr     : S1(read);
5560  src1   : S1(read);
5561  src2   : S1(read);
5562  dst    : S3(write);
5563  INS01  : ISS;
5564  NEON_FP : S3;
5565%}
5566
5567pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr)
5568%{
5569  single_instruction;
5570  cr     : S1(read);
5571  src1   : S1(read);
5572  src2   : S1(read);
5573  dst    : S3(write);
5574  INS01  : ISS;
5575  NEON_FP : S3;
5576%}
5577
5578pipe_class fp_imm_s(vRegF dst)
5579%{
5580  single_instruction;
5581  dst    : S3(write);
5582  INS01  : ISS;
5583  NEON_FP : S3;
5584%}
5585
5586pipe_class fp_imm_d(vRegD dst)
5587%{
5588  single_instruction;
5589  dst    : S3(write);
5590  INS01  : ISS;
5591  NEON_FP : S3;
5592%}
5593
5594pipe_class fp_load_constant_s(vRegF dst)
5595%{
5596  single_instruction;
5597  dst    : S4(write);
5598  INS01  : ISS;
5599  NEON_FP : S4;
5600%}
5601
5602pipe_class fp_load_constant_d(vRegD dst)
5603%{
5604  single_instruction;
5605  dst    : S4(write);
5606  INS01  : ISS;
5607  NEON_FP : S4;
5608%}
5609
5610pipe_class vmul64(vecD dst, vecD src1, vecD src2)
5611%{
5612  single_instruction;
5613  dst    : S5(write);
5614  src1   : S1(read);
5615  src2   : S1(read);
5616  INS01  : ISS;
5617  NEON_FP : S5;
5618%}
5619
5620pipe_class vmul128(vecX dst, vecX src1, vecX src2)
5621%{
5622  single_instruction;
5623  dst    : S5(write);
5624  src1   : S1(read);
5625  src2   : S1(read);
5626  INS0   : ISS;
5627  NEON_FP : S5;
5628%}
5629
5630pipe_class vmla64(vecD dst, vecD src1, vecD src2)
5631%{
5632  single_instruction;
5633  dst    : S5(write);
5634  src1   : S1(read);
5635  src2   : S1(read);
5636  dst    : S1(read);
5637  INS01  : ISS;
5638  NEON_FP : S5;
5639%}
5640
5641pipe_class vmla128(vecX dst, vecX src1, vecX src2)
5642%{
5643  single_instruction;
5644  dst    : S5(write);
5645  src1   : S1(read);
5646  src2   : S1(read);
5647  dst    : S1(read);
5648  INS0   : ISS;
5649  NEON_FP : S5;
5650%}
5651
5652pipe_class vdop64(vecD dst, vecD src1, vecD src2)
5653%{
5654  single_instruction;
5655  dst    : S4(write);
5656  src1   : S2(read);
5657  src2   : S2(read);
5658  INS01  : ISS;
5659  NEON_FP : S4;
5660%}
5661
5662pipe_class vdop128(vecX dst, vecX src1, vecX src2)
5663%{
5664  single_instruction;
5665  dst    : S4(write);
5666  src1   : S2(read);
5667  src2   : S2(read);
5668  INS0   : ISS;
5669  NEON_FP : S4;
5670%}
5671
5672pipe_class vlogical64(vecD dst, vecD src1, vecD src2)
5673%{
5674  single_instruction;
5675  dst    : S3(write);
5676  src1   : S2(read);
5677  src2   : S2(read);
5678  INS01  : ISS;
5679  NEON_FP : S3;
5680%}
5681
5682pipe_class vlogical128(vecX dst, vecX src1, vecX src2)
5683%{
5684  single_instruction;
5685  dst    : S3(write);
5686  src1   : S2(read);
5687  src2   : S2(read);
5688  INS0   : ISS;
5689  NEON_FP : S3;
5690%}
5691
5692pipe_class vshift64(vecD dst, vecD src, vecX shift)
5693%{
5694  single_instruction;
5695  dst    : S3(write);
5696  src    : S1(read);
5697  shift  : S1(read);
5698  INS01  : ISS;
5699  NEON_FP : S3;
5700%}
5701
5702pipe_class vshift128(vecX dst, vecX src, vecX shift)
5703%{
5704  single_instruction;
5705  dst    : S3(write);
5706  src    : S1(read);
5707  shift  : S1(read);
5708  INS0   : ISS;
5709  NEON_FP : S3;
5710%}
5711
5712pipe_class vshift64_imm(vecD dst, vecD src, immI shift)
5713%{
5714  single_instruction;
5715  dst    : S3(write);
5716  src    : S1(read);
5717  INS01  : ISS;
5718  NEON_FP : S3;
5719%}
5720
5721pipe_class vshift128_imm(vecX dst, vecX src, immI shift)
5722%{
5723  single_instruction;
5724  dst    : S3(write);
5725  src    : S1(read);
5726  INS0   : ISS;
5727  NEON_FP : S3;
5728%}
5729
5730pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2)
5731%{
5732  single_instruction;
5733  dst    : S5(write);
5734  src1   : S1(read);
5735  src2   : S1(read);
5736  INS01  : ISS;
5737  NEON_FP : S5;
5738%}
5739
5740pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2)
5741%{
5742  single_instruction;
5743  dst    : S5(write);
5744  src1   : S1(read);
5745  src2   : S1(read);
5746  INS0   : ISS;
5747  NEON_FP : S5;
5748%}
5749
5750pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2)
5751%{
5752  single_instruction;
5753  dst    : S5(write);
5754  src1   : S1(read);
5755  src2   : S1(read);
5756  INS0   : ISS;
5757  NEON_FP : S5;
5758%}
5759
5760pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2)
5761%{
5762  single_instruction;
5763  dst    : S5(write);
5764  src1   : S1(read);
5765  src2   : S1(read);
5766  INS0   : ISS;
5767  NEON_FP : S5;
5768%}
5769
5770pipe_class vsqrt_fp128(vecX dst, vecX src)
5771%{
5772  single_instruction;
5773  dst    : S5(write);
5774  src    : S1(read);
5775  INS0   : ISS;
5776  NEON_FP : S5;
5777%}
5778
5779pipe_class vunop_fp64(vecD dst, vecD src)
5780%{
5781  single_instruction;
5782  dst    : S5(write);
5783  src    : S1(read);
5784  INS01  : ISS;
5785  NEON_FP : S5;
5786%}
5787
5788pipe_class vunop_fp128(vecX dst, vecX src)
5789%{
5790  single_instruction;
5791  dst    : S5(write);
5792  src    : S1(read);
5793  INS0   : ISS;
5794  NEON_FP : S5;
5795%}
5796
5797pipe_class vdup_reg_reg64(vecD dst, iRegI src)
5798%{
5799  single_instruction;
5800  dst    : S3(write);
5801  src    : S1(read);
5802  INS01  : ISS;
5803  NEON_FP : S3;
5804%}
5805
5806pipe_class vdup_reg_reg128(vecX dst, iRegI src)
5807%{
5808  single_instruction;
5809  dst    : S3(write);
5810  src    : S1(read);
5811  INS01  : ISS;
5812  NEON_FP : S3;
5813%}
5814
5815pipe_class vdup_reg_freg64(vecD dst, vRegF src)
5816%{
5817  single_instruction;
5818  dst    : S3(write);
5819  src    : S1(read);
5820  INS01  : ISS;
5821  NEON_FP : S3;
5822%}
5823
5824pipe_class vdup_reg_freg128(vecX dst, vRegF src)
5825%{
5826  single_instruction;
5827  dst    : S3(write);
5828  src    : S1(read);
5829  INS01  : ISS;
5830  NEON_FP : S3;
5831%}
5832
5833pipe_class vdup_reg_dreg128(vecX dst, vRegD src)
5834%{
5835  single_instruction;
5836  dst    : S3(write);
5837  src    : S1(read);
5838  INS01  : ISS;
5839  NEON_FP : S3;
5840%}
5841
5842pipe_class vmovi_reg_imm64(vecD dst)
5843%{
5844  single_instruction;
5845  dst    : S3(write);
5846  INS01  : ISS;
5847  NEON_FP : S3;
5848%}
5849
5850pipe_class vmovi_reg_imm128(vecX dst)
5851%{
5852  single_instruction;
5853  dst    : S3(write);
5854  INS0   : ISS;
5855  NEON_FP : S3;
5856%}
5857
5858pipe_class vload_reg_mem64(vecD dst, vmem8 mem)
5859%{
5860  single_instruction;
5861  dst    : S5(write);
5862  mem    : ISS(read);
5863  INS01  : ISS;
5864  NEON_FP : S3;
5865%}
5866
5867pipe_class vload_reg_mem128(vecX dst, vmem16 mem)
5868%{
5869  single_instruction;
5870  dst    : S5(write);
5871  mem    : ISS(read);
5872  INS01  : ISS;
5873  NEON_FP : S3;
5874%}
5875
5876pipe_class vstore_reg_mem64(vecD src, vmem8 mem)
5877%{
5878  single_instruction;
5879  mem    : ISS(read);
5880  src    : S2(read);
5881  INS01  : ISS;
5882  NEON_FP : S3;
5883%}
5884
5885pipe_class vstore_reg_mem128(vecD src, vmem16 mem)
5886%{
5887  single_instruction;
5888  mem    : ISS(read);
5889  src    : S2(read);
5890  INS01  : ISS;
5891  NEON_FP : S3;
5892%}
5893
5894//------- Integer ALU operations --------------------------
5895
5896// Integer ALU reg-reg operation
5897// Operands needed in EX1, result generated in EX2
5898// Eg.	ADD	x0, x1, x2
5899pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2)
5900%{
5901  single_instruction;
5902  dst    : EX2(write);
5903  src1   : EX1(read);
5904  src2   : EX1(read);
5905  INS01  : ISS; // Dual issue as instruction 0 or 1
5906  ALU    : EX2;
5907%}
5908
5909// Integer ALU reg-reg operation with constant shift
5910// Shifted register must be available in LATE_ISS instead of EX1
5911// Eg.	ADD	x0, x1, x2, LSL #2
5912pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift)
5913%{
5914  single_instruction;
5915  dst    : EX2(write);
5916  src1   : EX1(read);
5917  src2   : ISS(read);
5918  INS01  : ISS;
5919  ALU    : EX2;
5920%}
5921
5922// Integer ALU reg operation with constant shift
5923// Eg.	LSL	x0, x1, #shift
5924pipe_class ialu_reg_shift(iRegI dst, iRegI src1)
5925%{
5926  single_instruction;
5927  dst    : EX2(write);
5928  src1   : ISS(read);
5929  INS01  : ISS;
5930  ALU    : EX2;
5931%}
5932
5933// Integer ALU reg-reg operation with variable shift
5934// Both operands must be available in LATE_ISS instead of EX1
5935// Result is available in EX1 instead of EX2
5936// Eg.	LSLV	x0, x1, x2
5937pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2)
5938%{
5939  single_instruction;
5940  dst    : EX1(write);
5941  src1   : ISS(read);
5942  src2   : ISS(read);
5943  INS01  : ISS;
5944  ALU    : EX1;
5945%}
5946
5947// Integer ALU reg-reg operation with extract
5948// As for _vshift above, but result generated in EX2
5949// Eg.	EXTR	x0, x1, x2, #N
5950pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2)
5951%{
5952  single_instruction;
5953  dst    : EX2(write);
5954  src1   : ISS(read);
5955  src2   : ISS(read);
5956  INS1   : ISS; // Can only dual issue as Instruction 1
5957  ALU    : EX1;
5958%}
5959
5960// Integer ALU reg operation
5961// Eg.	NEG	x0, x1
5962pipe_class ialu_reg(iRegI dst, iRegI src)
5963%{
5964  single_instruction;
5965  dst    : EX2(write);
5966  src    : EX1(read);
5967  INS01  : ISS;
5968  ALU    : EX2;
5969%}
5970
5971// Integer ALU reg mmediate operation
5972// Eg.	ADD	x0, x1, #N
5973pipe_class ialu_reg_imm(iRegI dst, iRegI src1)
5974%{
5975  single_instruction;
5976  dst    : EX2(write);
5977  src1   : EX1(read);
5978  INS01  : ISS;
5979  ALU    : EX2;
5980%}
5981
5982// Integer ALU immediate operation (no source operands)
5983// Eg.	MOV	x0, #N
5984pipe_class ialu_imm(iRegI dst)
5985%{
5986  single_instruction;
5987  dst    : EX1(write);
5988  INS01  : ISS;
5989  ALU    : EX1;
5990%}
5991
5992//------- Compare operation -------------------------------
5993
5994// Compare reg-reg
5995// Eg.	CMP	x0, x1
5996pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
5997%{
5998  single_instruction;
5999//  fixed_latency(16);
6000  cr     : EX2(write);
6001  op1    : EX1(read);
6002  op2    : EX1(read);
6003  INS01  : ISS;
6004  ALU    : EX2;
6005%}
6006
6007// Compare reg-reg
6008// Eg.	CMP	x0, #N
6009pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1)
6010%{
6011  single_instruction;
6012//  fixed_latency(16);
6013  cr     : EX2(write);
6014  op1    : EX1(read);
6015  INS01  : ISS;
6016  ALU    : EX2;
6017%}
6018
6019//------- Conditional instructions ------------------------
6020
6021// Conditional no operands
6022// Eg.	CSINC	x0, zr, zr, <cond>
6023pipe_class icond_none(iRegI dst, rFlagsReg cr)
6024%{
6025  single_instruction;
6026  cr     : EX1(read);
6027  dst    : EX2(write);
6028  INS01  : ISS;
6029  ALU    : EX2;
6030%}
6031
6032// Conditional 2 operand
6033// EG.	CSEL	X0, X1, X2, <cond>
6034pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr)
6035%{
6036  single_instruction;
6037  cr     : EX1(read);
6038  src1   : EX1(read);
6039  src2   : EX1(read);
6040  dst    : EX2(write);
6041  INS01  : ISS;
6042  ALU    : EX2;
6043%}
6044
6045// Conditional 2 operand
6046// EG.	CSEL	X0, X1, X2, <cond>
6047pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr)
6048%{
6049  single_instruction;
6050  cr     : EX1(read);
6051  src    : EX1(read);
6052  dst    : EX2(write);
6053  INS01  : ISS;
6054  ALU    : EX2;
6055%}
6056
6057//------- Multiply pipeline operations --------------------
6058
6059// Multiply reg-reg
6060// Eg.	MUL	w0, w1, w2
6061pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6062%{
6063  single_instruction;
6064  dst    : WR(write);
6065  src1   : ISS(read);
6066  src2   : ISS(read);
6067  INS01  : ISS;
6068  MAC    : WR;
6069%}
6070
6071// Multiply accumulate
6072// Eg.	MADD	w0, w1, w2, w3
6073pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6074%{
6075  single_instruction;
6076  dst    : WR(write);
6077  src1   : ISS(read);
6078  src2   : ISS(read);
6079  src3   : ISS(read);
6080  INS01  : ISS;
6081  MAC    : WR;
6082%}
6083
6084// Eg.	MUL	w0, w1, w2
6085pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6086%{
6087  single_instruction;
6088  fixed_latency(3); // Maximum latency for 64 bit mul
6089  dst    : WR(write);
6090  src1   : ISS(read);
6091  src2   : ISS(read);
6092  INS01  : ISS;
6093  MAC    : WR;
6094%}
6095
6096// Multiply accumulate
6097// Eg.	MADD	w0, w1, w2, w3
6098pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6099%{
6100  single_instruction;
6101  fixed_latency(3); // Maximum latency for 64 bit mul
6102  dst    : WR(write);
6103  src1   : ISS(read);
6104  src2   : ISS(read);
6105  src3   : ISS(read);
6106  INS01  : ISS;
6107  MAC    : WR;
6108%}
6109
6110//------- Divide pipeline operations --------------------
6111
6112// Eg.	SDIV	w0, w1, w2
6113pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6114%{
6115  single_instruction;
6116  fixed_latency(8); // Maximum latency for 32 bit divide
6117  dst    : WR(write);
6118  src1   : ISS(read);
6119  src2   : ISS(read);
6120  INS0   : ISS; // Can only dual issue as instruction 0
6121  DIV    : WR;
6122%}
6123
6124// Eg.	SDIV	x0, x1, x2
6125pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6126%{
6127  single_instruction;
6128  fixed_latency(16); // Maximum latency for 64 bit divide
6129  dst    : WR(write);
6130  src1   : ISS(read);
6131  src2   : ISS(read);
6132  INS0   : ISS; // Can only dual issue as instruction 0
6133  DIV    : WR;
6134%}
6135
6136//------- Load pipeline operations ------------------------
6137
6138// Load - prefetch
6139// Eg.	PFRM	<mem>
6140pipe_class iload_prefetch(memory mem)
6141%{
6142  single_instruction;
6143  mem    : ISS(read);
6144  INS01  : ISS;
6145  LDST   : WR;
6146%}
6147
6148// Load - reg, mem
6149// Eg.	LDR	x0, <mem>
6150pipe_class iload_reg_mem(iRegI dst, memory mem)
6151%{
6152  single_instruction;
6153  dst    : WR(write);
6154  mem    : ISS(read);
6155  INS01  : ISS;
6156  LDST   : WR;
6157%}
6158
6159// Load - reg, reg
6160// Eg.	LDR	x0, [sp, x1]
6161pipe_class iload_reg_reg(iRegI dst, iRegI src)
6162%{
6163  single_instruction;
6164  dst    : WR(write);
6165  src    : ISS(read);
6166  INS01  : ISS;
6167  LDST   : WR;
6168%}
6169
6170//------- Store pipeline operations -----------------------
6171
6172// Store - zr, mem
6173// Eg.	STR	zr, <mem>
6174pipe_class istore_mem(memory mem)
6175%{
6176  single_instruction;
6177  mem    : ISS(read);
6178  INS01  : ISS;
6179  LDST   : WR;
6180%}
6181
6182// Store - reg, mem
6183// Eg.	STR	x0, <mem>
6184pipe_class istore_reg_mem(iRegI src, memory mem)
6185%{
6186  single_instruction;
6187  mem    : ISS(read);
6188  src    : EX2(read);
6189  INS01  : ISS;
6190  LDST   : WR;
6191%}
6192
6193// Store - reg, reg
6194// Eg. STR	x0, [sp, x1]
6195pipe_class istore_reg_reg(iRegI dst, iRegI src)
6196%{
6197  single_instruction;
6198  dst    : ISS(read);
6199  src    : EX2(read);
6200  INS01  : ISS;
6201  LDST   : WR;
6202%}
6203
6204//------- Store pipeline operations -----------------------
6205
6206// Branch
6207pipe_class pipe_branch()
6208%{
6209  single_instruction;
6210  INS01  : ISS;
6211  BRANCH : EX1;
6212%}
6213
6214// Conditional branch
6215pipe_class pipe_branch_cond(rFlagsReg cr)
6216%{
6217  single_instruction;
6218  cr     : EX1(read);
6219  INS01  : ISS;
6220  BRANCH : EX1;
6221%}
6222
6223// Compare & Branch
6224// EG.	CBZ/CBNZ
6225pipe_class pipe_cmp_branch(iRegI op1)
6226%{
6227  single_instruction;
6228  op1    : EX1(read);
6229  INS01  : ISS;
6230  BRANCH : EX1;
6231%}
6232
6233//------- Synchronisation operations ----------------------
6234
6235// Any operation requiring serialization.
6236// EG.	DMB/Atomic Ops/Load Acquire/Str Release
6237pipe_class pipe_serial()
6238%{
6239  single_instruction;
6240  force_serialization;
6241  fixed_latency(16);
6242  INS01  : ISS(2); // Cannot dual issue with any other instruction
6243  LDST   : WR;
6244%}
6245
6246// Generic big/slow expanded idiom - also serialized
6247pipe_class pipe_slow()
6248%{
6249  instruction_count(10);
6250  multiple_bundles;
6251  force_serialization;
6252  fixed_latency(16);
6253  INS01  : ISS(2); // Cannot dual issue with any other instruction
6254  LDST   : WR;
6255%}
6256
6257// Empty pipeline class
6258pipe_class pipe_class_empty()
6259%{
6260  single_instruction;
6261  fixed_latency(0);
6262%}
6263
6264// Default pipeline class.
6265pipe_class pipe_class_default()
6266%{
6267  single_instruction;
6268  fixed_latency(2);
6269%}
6270
6271// Pipeline class for compares.
6272pipe_class pipe_class_compare()
6273%{
6274  single_instruction;
6275  fixed_latency(16);
6276%}
6277
6278// Pipeline class for memory operations.
6279pipe_class pipe_class_memory()
6280%{
6281  single_instruction;
6282  fixed_latency(16);
6283%}
6284
6285// Pipeline class for call.
6286pipe_class pipe_class_call()
6287%{
6288  single_instruction;
6289  fixed_latency(100);
6290%}
6291
6292// Define the class for the Nop node.
6293define %{
6294   MachNop = pipe_class_empty;
6295%}
6296
6297%}
6298//----------INSTRUCTIONS-------------------------------------------------------
6299//
6300// match      -- States which machine-independent subtree may be replaced
6301//               by this instruction.
6302// ins_cost   -- The estimated cost of this instruction is used by instruction
6303//               selection to identify a minimum cost tree of machine
6304//               instructions that matches a tree of machine-independent
6305//               instructions.
6306// format     -- A string providing the disassembly for this instruction.
6307//               The value of an instruction's operand may be inserted
6308//               by referring to it with a '$' prefix.
6309// opcode     -- Three instruction opcodes may be provided.  These are referred
6310//               to within an encode class as $primary, $secondary, and $tertiary
6311//               rrspectively.  The primary opcode is commonly used to
6312//               indicate the type of machine instruction, while secondary
6313//               and tertiary are often used for prefix options or addressing
6314//               modes.
6315// ins_encode -- A list of encode classes with parameters. The encode class
6316//               name must have been defined in an 'enc_class' specification
6317//               in the encode section of the architecture description.
6318
6319// ============================================================================
6320// Memory (Load/Store) Instructions
6321
6322// Load Instructions
6323
6324// Load Byte (8 bit signed)
6325instruct loadB(iRegINoSp dst, memory mem)
6326%{
6327  match(Set dst (LoadB mem));
6328  predicate(!needs_acquiring_load(n));
6329
6330  ins_cost(4 * INSN_COST);
6331  format %{ "ldrsbw  $dst, $mem\t# byte" %}
6332
6333  ins_encode(aarch64_enc_ldrsbw(dst, mem));
6334
6335  ins_pipe(iload_reg_mem);
6336%}
6337
6338// Load Byte (8 bit signed) into long
6339instruct loadB2L(iRegLNoSp dst, memory mem)
6340%{
6341  match(Set dst (ConvI2L (LoadB mem)));
6342  predicate(!needs_acquiring_load(n->in(1)));
6343
6344  ins_cost(4 * INSN_COST);
6345  format %{ "ldrsb  $dst, $mem\t# byte" %}
6346
6347  ins_encode(aarch64_enc_ldrsb(dst, mem));
6348
6349  ins_pipe(iload_reg_mem);
6350%}
6351
6352// Load Byte (8 bit unsigned)
6353instruct loadUB(iRegINoSp dst, memory mem)
6354%{
6355  match(Set dst (LoadUB mem));
6356  predicate(!needs_acquiring_load(n));
6357
6358  ins_cost(4 * INSN_COST);
6359  format %{ "ldrbw  $dst, $mem\t# byte" %}
6360
6361  ins_encode(aarch64_enc_ldrb(dst, mem));
6362
6363  ins_pipe(iload_reg_mem);
6364%}
6365
6366// Load Byte (8 bit unsigned) into long
6367instruct loadUB2L(iRegLNoSp dst, memory mem)
6368%{
6369  match(Set dst (ConvI2L (LoadUB mem)));
6370  predicate(!needs_acquiring_load(n->in(1)));
6371
6372  ins_cost(4 * INSN_COST);
6373  format %{ "ldrb  $dst, $mem\t# byte" %}
6374
6375  ins_encode(aarch64_enc_ldrb(dst, mem));
6376
6377  ins_pipe(iload_reg_mem);
6378%}
6379
6380// Load Short (16 bit signed)
6381instruct loadS(iRegINoSp dst, memory mem)
6382%{
6383  match(Set dst (LoadS mem));
6384  predicate(!needs_acquiring_load(n));
6385
6386  ins_cost(4 * INSN_COST);
6387  format %{ "ldrshw  $dst, $mem\t# short" %}
6388
6389  ins_encode(aarch64_enc_ldrshw(dst, mem));
6390
6391  ins_pipe(iload_reg_mem);
6392%}
6393
6394// Load Short (16 bit signed) into long
6395instruct loadS2L(iRegLNoSp dst, memory mem)
6396%{
6397  match(Set dst (ConvI2L (LoadS mem)));
6398  predicate(!needs_acquiring_load(n->in(1)));
6399
6400  ins_cost(4 * INSN_COST);
6401  format %{ "ldrsh  $dst, $mem\t# short" %}
6402
6403  ins_encode(aarch64_enc_ldrsh(dst, mem));
6404
6405  ins_pipe(iload_reg_mem);
6406%}
6407
6408// Load Char (16 bit unsigned)
6409instruct loadUS(iRegINoSp dst, memory mem)
6410%{
6411  match(Set dst (LoadUS mem));
6412  predicate(!needs_acquiring_load(n));
6413
6414  ins_cost(4 * INSN_COST);
6415  format %{ "ldrh  $dst, $mem\t# short" %}
6416
6417  ins_encode(aarch64_enc_ldrh(dst, mem));
6418
6419  ins_pipe(iload_reg_mem);
6420%}
6421
6422// Load Short/Char (16 bit unsigned) into long
6423instruct loadUS2L(iRegLNoSp dst, memory mem)
6424%{
6425  match(Set dst (ConvI2L (LoadUS mem)));
6426  predicate(!needs_acquiring_load(n->in(1)));
6427
6428  ins_cost(4 * INSN_COST);
6429  format %{ "ldrh  $dst, $mem\t# short" %}
6430
6431  ins_encode(aarch64_enc_ldrh(dst, mem));
6432
6433  ins_pipe(iload_reg_mem);
6434%}
6435
6436// Load Integer (32 bit signed)
6437instruct loadI(iRegINoSp dst, memory mem)
6438%{
6439  match(Set dst (LoadI mem));
6440  predicate(!needs_acquiring_load(n));
6441
6442  ins_cost(4 * INSN_COST);
6443  format %{ "ldrw  $dst, $mem\t# int" %}
6444
6445  ins_encode(aarch64_enc_ldrw(dst, mem));
6446
6447  ins_pipe(iload_reg_mem);
6448%}
6449
6450// Load Integer (32 bit signed) into long
6451instruct loadI2L(iRegLNoSp dst, memory mem)
6452%{
6453  match(Set dst (ConvI2L (LoadI mem)));
6454  predicate(!needs_acquiring_load(n->in(1)));
6455
6456  ins_cost(4 * INSN_COST);
6457  format %{ "ldrsw  $dst, $mem\t# int" %}
6458
6459  ins_encode(aarch64_enc_ldrsw(dst, mem));
6460
6461  ins_pipe(iload_reg_mem);
6462%}
6463
6464// Load Integer (32 bit unsigned) into long
6465instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask)
6466%{
6467  match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
6468  predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load()));
6469
6470  ins_cost(4 * INSN_COST);
6471  format %{ "ldrw  $dst, $mem\t# int" %}
6472
6473  ins_encode(aarch64_enc_ldrw(dst, mem));
6474
6475  ins_pipe(iload_reg_mem);
6476%}
6477
6478// Load Long (64 bit signed)
6479instruct loadL(iRegLNoSp dst, memory mem)
6480%{
6481  match(Set dst (LoadL mem));
6482  predicate(!needs_acquiring_load(n));
6483
6484  ins_cost(4 * INSN_COST);
6485  format %{ "ldr  $dst, $mem\t# int" %}
6486
6487  ins_encode(aarch64_enc_ldr(dst, mem));
6488
6489  ins_pipe(iload_reg_mem);
6490%}
6491
6492// Load Range
6493instruct loadRange(iRegINoSp dst, memory mem)
6494%{
6495  match(Set dst (LoadRange mem));
6496
6497  ins_cost(4 * INSN_COST);
6498  format %{ "ldrw  $dst, $mem\t# range" %}
6499
6500  ins_encode(aarch64_enc_ldrw(dst, mem));
6501
6502  ins_pipe(iload_reg_mem);
6503%}
6504
6505// Load Pointer
6506instruct loadP(iRegPNoSp dst, memory mem)
6507%{
6508  match(Set dst (LoadP mem));
6509  predicate(!needs_acquiring_load(n));
6510
6511  ins_cost(4 * INSN_COST);
6512  format %{ "ldr  $dst, $mem\t# ptr" %}
6513
6514  ins_encode(aarch64_enc_ldr(dst, mem));
6515
6516  ins_pipe(iload_reg_mem);
6517%}
6518
6519// Load Compressed Pointer
6520instruct loadN(iRegNNoSp dst, memory mem)
6521%{
6522  match(Set dst (LoadN mem));
6523  predicate(!needs_acquiring_load(n));
6524
6525  ins_cost(4 * INSN_COST);
6526  format %{ "ldrw  $dst, $mem\t# compressed ptr" %}
6527
6528  ins_encode(aarch64_enc_ldrw(dst, mem));
6529
6530  ins_pipe(iload_reg_mem);
6531%}
6532
6533// Load Klass Pointer
6534instruct loadKlass(iRegPNoSp dst, memory mem)
6535%{
6536  match(Set dst (LoadKlass mem));
6537  predicate(!needs_acquiring_load(n));
6538
6539  ins_cost(4 * INSN_COST);
6540  format %{ "ldr  $dst, $mem\t# class" %}
6541
6542  ins_encode(aarch64_enc_ldr(dst, mem));
6543
6544  ins_pipe(iload_reg_mem);
6545%}
6546
6547// Load Narrow Klass Pointer
6548instruct loadNKlass(iRegNNoSp dst, memory mem)
6549%{
6550  match(Set dst (LoadNKlass mem));
6551  predicate(!needs_acquiring_load(n));
6552
6553  ins_cost(4 * INSN_COST);
6554  format %{ "ldrw  $dst, $mem\t# compressed class ptr" %}
6555
6556  ins_encode(aarch64_enc_ldrw(dst, mem));
6557
6558  ins_pipe(iload_reg_mem);
6559%}
6560
6561// Load Float
6562instruct loadF(vRegF dst, memory mem)
6563%{
6564  match(Set dst (LoadF mem));
6565  predicate(!needs_acquiring_load(n));
6566
6567  ins_cost(4 * INSN_COST);
6568  format %{ "ldrs  $dst, $mem\t# float" %}
6569
6570  ins_encode( aarch64_enc_ldrs(dst, mem) );
6571
6572  ins_pipe(pipe_class_memory);
6573%}
6574
6575// Load Double
6576instruct loadD(vRegD dst, memory mem)
6577%{
6578  match(Set dst (LoadD mem));
6579  predicate(!needs_acquiring_load(n));
6580
6581  ins_cost(4 * INSN_COST);
6582  format %{ "ldrd  $dst, $mem\t# double" %}
6583
6584  ins_encode( aarch64_enc_ldrd(dst, mem) );
6585
6586  ins_pipe(pipe_class_memory);
6587%}
6588
6589
6590// Load Int Constant
6591instruct loadConI(iRegINoSp dst, immI src)
6592%{
6593  match(Set dst src);
6594
6595  ins_cost(INSN_COST);
6596  format %{ "mov $dst, $src\t# int" %}
6597
6598  ins_encode( aarch64_enc_movw_imm(dst, src) );
6599
6600  ins_pipe(ialu_imm);
6601%}
6602
6603// Load Long Constant
6604instruct loadConL(iRegLNoSp dst, immL src)
6605%{
6606  match(Set dst src);
6607
6608  ins_cost(INSN_COST);
6609  format %{ "mov $dst, $src\t# long" %}
6610
6611  ins_encode( aarch64_enc_mov_imm(dst, src) );
6612
6613  ins_pipe(ialu_imm);
6614%}
6615
6616// Load Pointer Constant
6617
6618instruct loadConP(iRegPNoSp dst, immP con)
6619%{
6620  match(Set dst con);
6621
6622  ins_cost(INSN_COST * 4);
6623  format %{
6624    "mov  $dst, $con\t# ptr\n\t"
6625  %}
6626
6627  ins_encode(aarch64_enc_mov_p(dst, con));
6628
6629  ins_pipe(ialu_imm);
6630%}
6631
6632// Load Null Pointer Constant
6633
6634instruct loadConP0(iRegPNoSp dst, immP0 con)
6635%{
6636  match(Set dst con);
6637
6638  ins_cost(INSN_COST);
6639  format %{ "mov  $dst, $con\t# NULL ptr" %}
6640
6641  ins_encode(aarch64_enc_mov_p0(dst, con));
6642
6643  ins_pipe(ialu_imm);
6644%}
6645
6646// Load Pointer Constant One
6647
6648instruct loadConP1(iRegPNoSp dst, immP_1 con)
6649%{
6650  match(Set dst con);
6651
6652  ins_cost(INSN_COST);
6653  format %{ "mov  $dst, $con\t# NULL ptr" %}
6654
6655  ins_encode(aarch64_enc_mov_p1(dst, con));
6656
6657  ins_pipe(ialu_imm);
6658%}
6659
6660// Load Poll Page Constant
6661
6662instruct loadConPollPage(iRegPNoSp dst, immPollPage con)
6663%{
6664  match(Set dst con);
6665
6666  ins_cost(INSN_COST);
6667  format %{ "adr  $dst, $con\t# Poll Page Ptr" %}
6668
6669  ins_encode(aarch64_enc_mov_poll_page(dst, con));
6670
6671  ins_pipe(ialu_imm);
6672%}
6673
6674// Load Byte Map Base Constant
6675
6676instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con)
6677%{
6678  match(Set dst con);
6679
6680  ins_cost(INSN_COST);
6681  format %{ "adr  $dst, $con\t# Byte Map Base" %}
6682
6683  ins_encode(aarch64_enc_mov_byte_map_base(dst, con));
6684
6685  ins_pipe(ialu_imm);
6686%}
6687
6688// Load Narrow Pointer Constant
6689
6690instruct loadConN(iRegNNoSp dst, immN con)
6691%{
6692  match(Set dst con);
6693
6694  ins_cost(INSN_COST * 4);
6695  format %{ "mov  $dst, $con\t# compressed ptr" %}
6696
6697  ins_encode(aarch64_enc_mov_n(dst, con));
6698
6699  ins_pipe(ialu_imm);
6700%}
6701
6702// Load Narrow Null Pointer Constant
6703
6704instruct loadConN0(iRegNNoSp dst, immN0 con)
6705%{
6706  match(Set dst con);
6707
6708  ins_cost(INSN_COST);
6709  format %{ "mov  $dst, $con\t# compressed NULL ptr" %}
6710
6711  ins_encode(aarch64_enc_mov_n0(dst, con));
6712
6713  ins_pipe(ialu_imm);
6714%}
6715
6716// Load Narrow Klass Constant
6717
6718instruct loadConNKlass(iRegNNoSp dst, immNKlass con)
6719%{
6720  match(Set dst con);
6721
6722  ins_cost(INSN_COST);
6723  format %{ "mov  $dst, $con\t# compressed klass ptr" %}
6724
6725  ins_encode(aarch64_enc_mov_nk(dst, con));
6726
6727  ins_pipe(ialu_imm);
6728%}
6729
6730// Load Packed Float Constant
6731
6732instruct loadConF_packed(vRegF dst, immFPacked con) %{
6733  match(Set dst con);
6734  ins_cost(INSN_COST * 4);
6735  format %{ "fmovs  $dst, $con"%}
6736  ins_encode %{
6737    __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant);
6738  %}
6739
6740  ins_pipe(fp_imm_s);
6741%}
6742
6743// Load Float Constant
6744
6745instruct loadConF(vRegF dst, immF con) %{
6746  match(Set dst con);
6747
6748  ins_cost(INSN_COST * 4);
6749
6750  format %{
6751    "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
6752  %}
6753
6754  ins_encode %{
6755    __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con));
6756  %}
6757
6758  ins_pipe(fp_load_constant_s);
6759%}
6760
6761// Load Packed Double Constant
6762
6763instruct loadConD_packed(vRegD dst, immDPacked con) %{
6764  match(Set dst con);
6765  ins_cost(INSN_COST);
6766  format %{ "fmovd  $dst, $con"%}
6767  ins_encode %{
6768    __ fmovd(as_FloatRegister($dst$$reg), $con$$constant);
6769  %}
6770
6771  ins_pipe(fp_imm_d);
6772%}
6773
6774// Load Double Constant
6775
6776instruct loadConD(vRegD dst, immD con) %{
6777  match(Set dst con);
6778
6779  ins_cost(INSN_COST * 5);
6780  format %{
6781    "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
6782  %}
6783
6784  ins_encode %{
6785    __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con));
6786  %}
6787
6788  ins_pipe(fp_load_constant_d);
6789%}
6790
6791// Store Instructions
6792
6793// Store CMS card-mark Immediate
6794instruct storeimmCM0(immI0 zero, memory mem)
6795%{
6796  match(Set mem (StoreCM mem zero));
6797  predicate(unnecessary_storestore(n));
6798
6799  ins_cost(INSN_COST);
6800  format %{ "strb zr, $mem\t# byte" %}
6801
6802  ins_encode(aarch64_enc_strb0(mem));
6803
6804  ins_pipe(istore_mem);
6805%}
6806
6807// Store CMS card-mark Immediate with intervening StoreStore
6808// needed when using CMS with no conditional card marking
6809instruct storeimmCM0_ordered(immI0 zero, memory mem)
6810%{
6811  match(Set mem (StoreCM mem zero));
6812
6813  ins_cost(INSN_COST * 2);
6814  format %{ "dmb ishst"
6815      "\n\tstrb zr, $mem\t# byte" %}
6816
6817  ins_encode(aarch64_enc_strb0_ordered(mem));
6818
6819  ins_pipe(istore_mem);
6820%}
6821
6822// Store Byte
6823instruct storeB(iRegIorL2I src, memory mem)
6824%{
6825  match(Set mem (StoreB mem src));
6826  predicate(!needs_releasing_store(n));
6827
6828  ins_cost(INSN_COST);
6829  format %{ "strb  $src, $mem\t# byte" %}
6830
6831  ins_encode(aarch64_enc_strb(src, mem));
6832
6833  ins_pipe(istore_reg_mem);
6834%}
6835
6836
6837instruct storeimmB0(immI0 zero, memory mem)
6838%{
6839  match(Set mem (StoreB mem zero));
6840  predicate(!needs_releasing_store(n));
6841
6842  ins_cost(INSN_COST);
6843  format %{ "strb zr, $mem\t# byte" %}
6844
6845  ins_encode(aarch64_enc_strb0(mem));
6846
6847  ins_pipe(istore_mem);
6848%}
6849
6850// Store Char/Short
6851instruct storeC(iRegIorL2I src, memory mem)
6852%{
6853  match(Set mem (StoreC mem src));
6854  predicate(!needs_releasing_store(n));
6855
6856  ins_cost(INSN_COST);
6857  format %{ "strh  $src, $mem\t# short" %}
6858
6859  ins_encode(aarch64_enc_strh(src, mem));
6860
6861  ins_pipe(istore_reg_mem);
6862%}
6863
6864instruct storeimmC0(immI0 zero, memory mem)
6865%{
6866  match(Set mem (StoreC mem zero));
6867  predicate(!needs_releasing_store(n));
6868
6869  ins_cost(INSN_COST);
6870  format %{ "strh  zr, $mem\t# short" %}
6871
6872  ins_encode(aarch64_enc_strh0(mem));
6873
6874  ins_pipe(istore_mem);
6875%}
6876
6877// Store Integer
6878
6879instruct storeI(iRegIorL2I src, memory mem)
6880%{
6881  match(Set mem(StoreI mem src));
6882  predicate(!needs_releasing_store(n));
6883
6884  ins_cost(INSN_COST);
6885  format %{ "strw  $src, $mem\t# int" %}
6886
6887  ins_encode(aarch64_enc_strw(src, mem));
6888
6889  ins_pipe(istore_reg_mem);
6890%}
6891
6892instruct storeimmI0(immI0 zero, memory mem)
6893%{
6894  match(Set mem(StoreI mem zero));
6895  predicate(!needs_releasing_store(n));
6896
6897  ins_cost(INSN_COST);
6898  format %{ "strw  zr, $mem\t# int" %}
6899
6900  ins_encode(aarch64_enc_strw0(mem));
6901
6902  ins_pipe(istore_mem);
6903%}
6904
6905// Store Long (64 bit signed)
6906instruct storeL(iRegL src, memory mem)
6907%{
6908  match(Set mem (StoreL mem src));
6909  predicate(!needs_releasing_store(n));
6910
6911  ins_cost(INSN_COST);
6912  format %{ "str  $src, $mem\t# int" %}
6913
6914  ins_encode(aarch64_enc_str(src, mem));
6915
6916  ins_pipe(istore_reg_mem);
6917%}
6918
6919// Store Long (64 bit signed)
6920instruct storeimmL0(immL0 zero, memory mem)
6921%{
6922  match(Set mem (StoreL mem zero));
6923  predicate(!needs_releasing_store(n));
6924
6925  ins_cost(INSN_COST);
6926  format %{ "str  zr, $mem\t# int" %}
6927
6928  ins_encode(aarch64_enc_str0(mem));
6929
6930  ins_pipe(istore_mem);
6931%}
6932
6933// Store Pointer
6934instruct storeP(iRegP src, memory mem)
6935%{
6936  match(Set mem (StoreP mem src));
6937  predicate(!needs_releasing_store(n));
6938
6939  ins_cost(INSN_COST);
6940  format %{ "str  $src, $mem\t# ptr" %}
6941
6942  ins_encode(aarch64_enc_str(src, mem));
6943
6944  ins_pipe(istore_reg_mem);
6945%}
6946
6947// Store Pointer
6948instruct storeimmP0(immP0 zero, memory mem)
6949%{
6950  match(Set mem (StoreP mem zero));
6951  predicate(!needs_releasing_store(n));
6952
6953  ins_cost(INSN_COST);
6954  format %{ "str zr, $mem\t# ptr" %}
6955
6956  ins_encode(aarch64_enc_str0(mem));
6957
6958  ins_pipe(istore_mem);
6959%}
6960
6961// Store Compressed Pointer
6962instruct storeN(iRegN src, memory mem)
6963%{
6964  match(Set mem (StoreN mem src));
6965  predicate(!needs_releasing_store(n));
6966
6967  ins_cost(INSN_COST);
6968  format %{ "strw  $src, $mem\t# compressed ptr" %}
6969
6970  ins_encode(aarch64_enc_strw(src, mem));
6971
6972  ins_pipe(istore_reg_mem);
6973%}
6974
6975instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem)
6976%{
6977  match(Set mem (StoreN mem zero));
6978  predicate(Universe::narrow_oop_base() == NULL &&
6979            Universe::narrow_klass_base() == NULL  &&
6980            (!needs_releasing_store(n)));
6981
6982  ins_cost(INSN_COST);
6983  format %{ "strw  rheapbase, $mem\t# compressed ptr (rheapbase==0)" %}
6984
6985  ins_encode(aarch64_enc_strw(heapbase, mem));
6986
6987  ins_pipe(istore_reg_mem);
6988%}
6989
6990// Store Float
6991instruct storeF(vRegF src, memory mem)
6992%{
6993  match(Set mem (StoreF mem src));
6994  predicate(!needs_releasing_store(n));
6995
6996  ins_cost(INSN_COST);
6997  format %{ "strs  $src, $mem\t# float" %}
6998
6999  ins_encode( aarch64_enc_strs(src, mem) );
7000
7001  ins_pipe(pipe_class_memory);
7002%}
7003
7004// TODO
7005// implement storeImmF0 and storeFImmPacked
7006
7007// Store Double
7008instruct storeD(vRegD src, memory mem)
7009%{
7010  match(Set mem (StoreD mem src));
7011  predicate(!needs_releasing_store(n));
7012
7013  ins_cost(INSN_COST);
7014  format %{ "strd  $src, $mem\t# double" %}
7015
7016  ins_encode( aarch64_enc_strd(src, mem) );
7017
7018  ins_pipe(pipe_class_memory);
7019%}
7020
7021// Store Compressed Klass Pointer
7022instruct storeNKlass(iRegN src, memory mem)
7023%{
7024  predicate(!needs_releasing_store(n));
7025  match(Set mem (StoreNKlass mem src));
7026
7027  ins_cost(INSN_COST);
7028  format %{ "strw  $src, $mem\t# compressed klass ptr" %}
7029
7030  ins_encode(aarch64_enc_strw(src, mem));
7031
7032  ins_pipe(istore_reg_mem);
7033%}
7034
7035// TODO
7036// implement storeImmD0 and storeDImmPacked
7037
7038// prefetch instructions
7039// Must be safe to execute with invalid address (cannot fault).
7040
7041instruct prefetchr( memory mem ) %{
7042  match(PrefetchRead mem);
7043
7044  ins_cost(INSN_COST);
7045  format %{ "prfm $mem, PLDL1KEEP\t# Prefetch into level 1 cache read keep" %}
7046
7047  ins_encode( aarch64_enc_prefetchr(mem) );
7048
7049  ins_pipe(iload_prefetch);
7050%}
7051
7052instruct prefetchw( memory mem ) %{
7053  match(PrefetchAllocation mem);
7054
7055  ins_cost(INSN_COST);
7056  format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %}
7057
7058  ins_encode( aarch64_enc_prefetchw(mem) );
7059
7060  ins_pipe(iload_prefetch);
7061%}
7062
7063instruct prefetchnta( memory mem ) %{
7064  match(PrefetchWrite mem);
7065
7066  ins_cost(INSN_COST);
7067  format %{ "prfm $mem, PSTL1STRM\t# Prefetch into level 1 cache write streaming" %}
7068
7069  ins_encode( aarch64_enc_prefetchnta(mem) );
7070
7071  ins_pipe(iload_prefetch);
7072%}
7073
7074//  ---------------- volatile loads and stores ----------------
7075
7076// Load Byte (8 bit signed)
7077instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7078%{
7079  match(Set dst (LoadB mem));
7080
7081  ins_cost(VOLATILE_REF_COST);
7082  format %{ "ldarsb  $dst, $mem\t# byte" %}
7083
7084  ins_encode(aarch64_enc_ldarsb(dst, mem));
7085
7086  ins_pipe(pipe_serial);
7087%}
7088
7089// Load Byte (8 bit signed) into long
7090instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7091%{
7092  match(Set dst (ConvI2L (LoadB mem)));
7093
7094  ins_cost(VOLATILE_REF_COST);
7095  format %{ "ldarsb  $dst, $mem\t# byte" %}
7096
7097  ins_encode(aarch64_enc_ldarsb(dst, mem));
7098
7099  ins_pipe(pipe_serial);
7100%}
7101
7102// Load Byte (8 bit unsigned)
7103instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7104%{
7105  match(Set dst (LoadUB mem));
7106
7107  ins_cost(VOLATILE_REF_COST);
7108  format %{ "ldarb  $dst, $mem\t# byte" %}
7109
7110  ins_encode(aarch64_enc_ldarb(dst, mem));
7111
7112  ins_pipe(pipe_serial);
7113%}
7114
7115// Load Byte (8 bit unsigned) into long
7116instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7117%{
7118  match(Set dst (ConvI2L (LoadUB mem)));
7119
7120  ins_cost(VOLATILE_REF_COST);
7121  format %{ "ldarb  $dst, $mem\t# byte" %}
7122
7123  ins_encode(aarch64_enc_ldarb(dst, mem));
7124
7125  ins_pipe(pipe_serial);
7126%}
7127
7128// Load Short (16 bit signed)
7129instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7130%{
7131  match(Set dst (LoadS mem));
7132
7133  ins_cost(VOLATILE_REF_COST);
7134  format %{ "ldarshw  $dst, $mem\t# short" %}
7135
7136  ins_encode(aarch64_enc_ldarshw(dst, mem));
7137
7138  ins_pipe(pipe_serial);
7139%}
7140
7141instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7142%{
7143  match(Set dst (LoadUS mem));
7144
7145  ins_cost(VOLATILE_REF_COST);
7146  format %{ "ldarhw  $dst, $mem\t# short" %}
7147
7148  ins_encode(aarch64_enc_ldarhw(dst, mem));
7149
7150  ins_pipe(pipe_serial);
7151%}
7152
7153// Load Short/Char (16 bit unsigned) into long
7154instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7155%{
7156  match(Set dst (ConvI2L (LoadUS mem)));
7157
7158  ins_cost(VOLATILE_REF_COST);
7159  format %{ "ldarh  $dst, $mem\t# short" %}
7160
7161  ins_encode(aarch64_enc_ldarh(dst, mem));
7162
7163  ins_pipe(pipe_serial);
7164%}
7165
7166// Load Short/Char (16 bit signed) into long
7167instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7168%{
7169  match(Set dst (ConvI2L (LoadS mem)));
7170
7171  ins_cost(VOLATILE_REF_COST);
7172  format %{ "ldarh  $dst, $mem\t# short" %}
7173
7174  ins_encode(aarch64_enc_ldarsh(dst, mem));
7175
7176  ins_pipe(pipe_serial);
7177%}
7178
7179// Load Integer (32 bit signed)
7180instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7181%{
7182  match(Set dst (LoadI mem));
7183
7184  ins_cost(VOLATILE_REF_COST);
7185  format %{ "ldarw  $dst, $mem\t# int" %}
7186
7187  ins_encode(aarch64_enc_ldarw(dst, mem));
7188
7189  ins_pipe(pipe_serial);
7190%}
7191
7192// Load Integer (32 bit unsigned) into long
7193instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask)
7194%{
7195  match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
7196
7197  ins_cost(VOLATILE_REF_COST);
7198  format %{ "ldarw  $dst, $mem\t# int" %}
7199
7200  ins_encode(aarch64_enc_ldarw(dst, mem));
7201
7202  ins_pipe(pipe_serial);
7203%}
7204
7205// Load Long (64 bit signed)
7206instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7207%{
7208  match(Set dst (LoadL mem));
7209
7210  ins_cost(VOLATILE_REF_COST);
7211  format %{ "ldar  $dst, $mem\t# int" %}
7212
7213  ins_encode(aarch64_enc_ldar(dst, mem));
7214
7215  ins_pipe(pipe_serial);
7216%}
7217
7218// Load Pointer
7219instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem)
7220%{
7221  match(Set dst (LoadP mem));
7222
7223  ins_cost(VOLATILE_REF_COST);
7224  format %{ "ldar  $dst, $mem\t# ptr" %}
7225
7226  ins_encode(aarch64_enc_ldar(dst, mem));
7227
7228  ins_pipe(pipe_serial);
7229%}
7230
7231// Load Compressed Pointer
7232instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem)
7233%{
7234  match(Set dst (LoadN mem));
7235
7236  ins_cost(VOLATILE_REF_COST);
7237  format %{ "ldarw  $dst, $mem\t# compressed ptr" %}
7238
7239  ins_encode(aarch64_enc_ldarw(dst, mem));
7240
7241  ins_pipe(pipe_serial);
7242%}
7243
7244// Load Float
7245instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem)
7246%{
7247  match(Set dst (LoadF mem));
7248
7249  ins_cost(VOLATILE_REF_COST);
7250  format %{ "ldars  $dst, $mem\t# float" %}
7251
7252  ins_encode( aarch64_enc_fldars(dst, mem) );
7253
7254  ins_pipe(pipe_serial);
7255%}
7256
7257// Load Double
7258instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem)
7259%{
7260  match(Set dst (LoadD mem));
7261
7262  ins_cost(VOLATILE_REF_COST);
7263  format %{ "ldard  $dst, $mem\t# double" %}
7264
7265  ins_encode( aarch64_enc_fldard(dst, mem) );
7266
7267  ins_pipe(pipe_serial);
7268%}
7269
7270// Store Byte
7271instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7272%{
7273  match(Set mem (StoreB mem src));
7274
7275  ins_cost(VOLATILE_REF_COST);
7276  format %{ "stlrb  $src, $mem\t# byte" %}
7277
7278  ins_encode(aarch64_enc_stlrb(src, mem));
7279
7280  ins_pipe(pipe_class_memory);
7281%}
7282
7283// Store Char/Short
7284instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7285%{
7286  match(Set mem (StoreC mem src));
7287
7288  ins_cost(VOLATILE_REF_COST);
7289  format %{ "stlrh  $src, $mem\t# short" %}
7290
7291  ins_encode(aarch64_enc_stlrh(src, mem));
7292
7293  ins_pipe(pipe_class_memory);
7294%}
7295
7296// Store Integer
7297
7298instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7299%{
7300  match(Set mem(StoreI mem src));
7301
7302  ins_cost(VOLATILE_REF_COST);
7303  format %{ "stlrw  $src, $mem\t# int" %}
7304
7305  ins_encode(aarch64_enc_stlrw(src, mem));
7306
7307  ins_pipe(pipe_class_memory);
7308%}
7309
7310// Store Long (64 bit signed)
7311instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem)
7312%{
7313  match(Set mem (StoreL mem src));
7314
7315  ins_cost(VOLATILE_REF_COST);
7316  format %{ "stlr  $src, $mem\t# int" %}
7317
7318  ins_encode(aarch64_enc_stlr(src, mem));
7319
7320  ins_pipe(pipe_class_memory);
7321%}
7322
7323// Store Pointer
7324instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem)
7325%{
7326  match(Set mem (StoreP mem src));
7327
7328  ins_cost(VOLATILE_REF_COST);
7329  format %{ "stlr  $src, $mem\t# ptr" %}
7330
7331  ins_encode(aarch64_enc_stlr(src, mem));
7332
7333  ins_pipe(pipe_class_memory);
7334%}
7335
7336// Store Compressed Pointer
7337instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem)
7338%{
7339  match(Set mem (StoreN mem src));
7340
7341  ins_cost(VOLATILE_REF_COST);
7342  format %{ "stlrw  $src, $mem\t# compressed ptr" %}
7343
7344  ins_encode(aarch64_enc_stlrw(src, mem));
7345
7346  ins_pipe(pipe_class_memory);
7347%}
7348
7349// Store Float
7350instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem)
7351%{
7352  match(Set mem (StoreF mem src));
7353
7354  ins_cost(VOLATILE_REF_COST);
7355  format %{ "stlrs  $src, $mem\t# float" %}
7356
7357  ins_encode( aarch64_enc_fstlrs(src, mem) );
7358
7359  ins_pipe(pipe_class_memory);
7360%}
7361
7362// TODO
7363// implement storeImmF0 and storeFImmPacked
7364
7365// Store Double
7366instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem)
7367%{
7368  match(Set mem (StoreD mem src));
7369
7370  ins_cost(VOLATILE_REF_COST);
7371  format %{ "stlrd  $src, $mem\t# double" %}
7372
7373  ins_encode( aarch64_enc_fstlrd(src, mem) );
7374
7375  ins_pipe(pipe_class_memory);
7376%}
7377
7378//  ---------------- end of volatile loads and stores ----------------
7379
7380// ============================================================================
7381// BSWAP Instructions
7382
7383instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{
7384  match(Set dst (ReverseBytesI src));
7385
7386  ins_cost(INSN_COST);
7387  format %{ "revw  $dst, $src" %}
7388
7389  ins_encode %{
7390    __ revw(as_Register($dst$$reg), as_Register($src$$reg));
7391  %}
7392
7393  ins_pipe(ialu_reg);
7394%}
7395
7396instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{
7397  match(Set dst (ReverseBytesL src));
7398
7399  ins_cost(INSN_COST);
7400  format %{ "rev  $dst, $src" %}
7401
7402  ins_encode %{
7403    __ rev(as_Register($dst$$reg), as_Register($src$$reg));
7404  %}
7405
7406  ins_pipe(ialu_reg);
7407%}
7408
7409instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{
7410  match(Set dst (ReverseBytesUS src));
7411
7412  ins_cost(INSN_COST);
7413  format %{ "rev16w  $dst, $src" %}
7414
7415  ins_encode %{
7416    __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
7417  %}
7418
7419  ins_pipe(ialu_reg);
7420%}
7421
7422instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{
7423  match(Set dst (ReverseBytesS src));
7424
7425  ins_cost(INSN_COST);
7426  format %{ "rev16w  $dst, $src\n\t"
7427            "sbfmw $dst, $dst, #0, #15" %}
7428
7429  ins_encode %{
7430    __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
7431    __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U);
7432  %}
7433
7434  ins_pipe(ialu_reg);
7435%}
7436
7437// ============================================================================
7438// Zero Count Instructions
7439
7440instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{
7441  match(Set dst (CountLeadingZerosI src));
7442
7443  ins_cost(INSN_COST);
7444  format %{ "clzw  $dst, $src" %}
7445  ins_encode %{
7446    __ clzw(as_Register($dst$$reg), as_Register($src$$reg));
7447  %}
7448
7449  ins_pipe(ialu_reg);
7450%}
7451
7452instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{
7453  match(Set dst (CountLeadingZerosL src));
7454
7455  ins_cost(INSN_COST);
7456  format %{ "clz   $dst, $src" %}
7457  ins_encode %{
7458    __ clz(as_Register($dst$$reg), as_Register($src$$reg));
7459  %}
7460
7461  ins_pipe(ialu_reg);
7462%}
7463
7464instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{
7465  match(Set dst (CountTrailingZerosI src));
7466
7467  ins_cost(INSN_COST * 2);
7468  format %{ "rbitw  $dst, $src\n\t"
7469            "clzw   $dst, $dst" %}
7470  ins_encode %{
7471    __ rbitw(as_Register($dst$$reg), as_Register($src$$reg));
7472    __ clzw(as_Register($dst$$reg), as_Register($dst$$reg));
7473  %}
7474
7475  ins_pipe(ialu_reg);
7476%}
7477
7478instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{
7479  match(Set dst (CountTrailingZerosL src));
7480
7481  ins_cost(INSN_COST * 2);
7482  format %{ "rbit   $dst, $src\n\t"
7483            "clz    $dst, $dst" %}
7484  ins_encode %{
7485    __ rbit(as_Register($dst$$reg), as_Register($src$$reg));
7486    __ clz(as_Register($dst$$reg), as_Register($dst$$reg));
7487  %}
7488
7489  ins_pipe(ialu_reg);
7490%}
7491
7492//---------- Population Count Instructions -------------------------------------
7493//
7494
7495instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{
7496  predicate(UsePopCountInstruction);
7497  match(Set dst (PopCountI src));
7498  effect(TEMP tmp);
7499  ins_cost(INSN_COST * 13);
7500
7501  format %{ "movw   $src, $src\n\t"
7502            "mov    $tmp, $src\t# vector (1D)\n\t"
7503            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7504            "addv   $tmp, $tmp\t# vector (8B)\n\t"
7505            "mov    $dst, $tmp\t# vector (1D)" %}
7506  ins_encode %{
7507    __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0
7508    __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register);
7509    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7510    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7511    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7512  %}
7513
7514  ins_pipe(pipe_class_default);
7515%}
7516
7517instruct popCountI_mem(iRegINoSp dst, memory mem, vRegF tmp) %{
7518  predicate(UsePopCountInstruction);
7519  match(Set dst (PopCountI (LoadI mem)));
7520  effect(TEMP tmp);
7521  ins_cost(INSN_COST * 13);
7522
7523  format %{ "ldrs   $tmp, $mem\n\t"
7524            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7525            "addv   $tmp, $tmp\t# vector (8B)\n\t"
7526            "mov    $dst, $tmp\t# vector (1D)" %}
7527  ins_encode %{
7528    FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
7529    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(),
7530               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
7531    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7532    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7533    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7534  %}
7535
7536  ins_pipe(pipe_class_default);
7537%}
7538
7539// Note: Long.bitCount(long) returns an int.
7540instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{
7541  predicate(UsePopCountInstruction);
7542  match(Set dst (PopCountL src));
7543  effect(TEMP tmp);
7544  ins_cost(INSN_COST * 13);
7545
7546  format %{ "mov    $tmp, $src\t# vector (1D)\n\t"
7547            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7548            "addv   $tmp, $tmp\t# vector (8B)\n\t"
7549            "mov    $dst, $tmp\t# vector (1D)" %}
7550  ins_encode %{
7551    __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register);
7552    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7553    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7554    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7555  %}
7556
7557  ins_pipe(pipe_class_default);
7558%}
7559
7560instruct popCountL_mem(iRegINoSp dst, memory mem, vRegD tmp) %{
7561  predicate(UsePopCountInstruction);
7562  match(Set dst (PopCountL (LoadL mem)));
7563  effect(TEMP tmp);
7564  ins_cost(INSN_COST * 13);
7565
7566  format %{ "ldrd   $tmp, $mem\n\t"
7567            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7568            "addv   $tmp, $tmp\t# vector (8B)\n\t"
7569            "mov    $dst, $tmp\t# vector (1D)" %}
7570  ins_encode %{
7571    FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
7572    loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(),
7573               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
7574    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7575    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7576    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7577  %}
7578
7579  ins_pipe(pipe_class_default);
7580%}
7581
7582// ============================================================================
7583// MemBar Instruction
7584
7585instruct load_fence() %{
7586  match(LoadFence);
7587  ins_cost(VOLATILE_REF_COST);
7588
7589  format %{ "load_fence" %}
7590
7591  ins_encode %{
7592    __ membar(Assembler::LoadLoad|Assembler::LoadStore);
7593  %}
7594  ins_pipe(pipe_serial);
7595%}
7596
7597instruct unnecessary_membar_acquire() %{
7598  predicate(unnecessary_acquire(n));
7599  match(MemBarAcquire);
7600  ins_cost(0);
7601
7602  format %{ "membar_acquire (elided)" %}
7603
7604  ins_encode %{
7605    __ block_comment("membar_acquire (elided)");
7606  %}
7607
7608  ins_pipe(pipe_class_empty);
7609%}
7610
7611instruct membar_acquire() %{
7612  match(MemBarAcquire);
7613  ins_cost(VOLATILE_REF_COST);
7614
7615  format %{ "membar_acquire" %}
7616
7617  ins_encode %{
7618    __ block_comment("membar_acquire");
7619    __ membar(Assembler::LoadLoad|Assembler::LoadStore);
7620  %}
7621
7622  ins_pipe(pipe_serial);
7623%}
7624
7625
7626instruct membar_acquire_lock() %{
7627  match(MemBarAcquireLock);
7628  ins_cost(VOLATILE_REF_COST);
7629
7630  format %{ "membar_acquire_lock (elided)" %}
7631
7632  ins_encode %{
7633    __ block_comment("membar_acquire_lock (elided)");
7634  %}
7635
7636  ins_pipe(pipe_serial);
7637%}
7638
7639instruct store_fence() %{
7640  match(StoreFence);
7641  ins_cost(VOLATILE_REF_COST);
7642
7643  format %{ "store_fence" %}
7644
7645  ins_encode %{
7646    __ membar(Assembler::LoadStore|Assembler::StoreStore);
7647  %}
7648  ins_pipe(pipe_serial);
7649%}
7650
7651instruct unnecessary_membar_release() %{
7652  predicate(unnecessary_release(n));
7653  match(MemBarRelease);
7654  ins_cost(0);
7655
7656  format %{ "membar_release (elided)" %}
7657
7658  ins_encode %{
7659    __ block_comment("membar_release (elided)");
7660  %}
7661  ins_pipe(pipe_serial);
7662%}
7663
7664instruct membar_release() %{
7665  match(MemBarRelease);
7666  ins_cost(VOLATILE_REF_COST);
7667
7668  format %{ "membar_release" %}
7669
7670  ins_encode %{
7671    __ block_comment("membar_release");
7672    __ membar(Assembler::LoadStore|Assembler::StoreStore);
7673  %}
7674  ins_pipe(pipe_serial);
7675%}
7676
7677instruct membar_storestore() %{
7678  match(MemBarStoreStore);
7679  ins_cost(VOLATILE_REF_COST);
7680
7681  format %{ "MEMBAR-store-store" %}
7682
7683  ins_encode %{
7684    __ membar(Assembler::StoreStore);
7685  %}
7686  ins_pipe(pipe_serial);
7687%}
7688
7689instruct membar_release_lock() %{
7690  match(MemBarReleaseLock);
7691  ins_cost(VOLATILE_REF_COST);
7692
7693  format %{ "membar_release_lock (elided)" %}
7694
7695  ins_encode %{
7696    __ block_comment("membar_release_lock (elided)");
7697  %}
7698
7699  ins_pipe(pipe_serial);
7700%}
7701
7702instruct unnecessary_membar_volatile() %{
7703  predicate(unnecessary_volatile(n));
7704  match(MemBarVolatile);
7705  ins_cost(0);
7706
7707  format %{ "membar_volatile (elided)" %}
7708
7709  ins_encode %{
7710    __ block_comment("membar_volatile (elided)");
7711  %}
7712
7713  ins_pipe(pipe_serial);
7714%}
7715
7716instruct membar_volatile() %{
7717  match(MemBarVolatile);
7718  ins_cost(VOLATILE_REF_COST*100);
7719
7720  format %{ "membar_volatile" %}
7721
7722  ins_encode %{
7723    __ block_comment("membar_volatile");
7724    __ membar(Assembler::StoreLoad);
7725    %}
7726
7727  ins_pipe(pipe_serial);
7728%}
7729
7730// ============================================================================
7731// Cast/Convert Instructions
7732
7733instruct castX2P(iRegPNoSp dst, iRegL src) %{
7734  match(Set dst (CastX2P src));
7735
7736  ins_cost(INSN_COST);
7737  format %{ "mov $dst, $src\t# long -> ptr" %}
7738
7739  ins_encode %{
7740    if ($dst$$reg != $src$$reg) {
7741      __ mov(as_Register($dst$$reg), as_Register($src$$reg));
7742    }
7743  %}
7744
7745  ins_pipe(ialu_reg);
7746%}
7747
7748instruct castP2X(iRegLNoSp dst, iRegP src) %{
7749  match(Set dst (CastP2X src));
7750
7751  ins_cost(INSN_COST);
7752  format %{ "mov $dst, $src\t# ptr -> long" %}
7753
7754  ins_encode %{
7755    if ($dst$$reg != $src$$reg) {
7756      __ mov(as_Register($dst$$reg), as_Register($src$$reg));
7757    }
7758  %}
7759
7760  ins_pipe(ialu_reg);
7761%}
7762
7763// Convert oop into int for vectors alignment masking
7764instruct convP2I(iRegINoSp dst, iRegP src) %{
7765  match(Set dst (ConvL2I (CastP2X src)));
7766
7767  ins_cost(INSN_COST);
7768  format %{ "movw $dst, $src\t# ptr -> int" %}
7769  ins_encode %{
7770    __ movw($dst$$Register, $src$$Register);
7771  %}
7772
7773  ins_pipe(ialu_reg);
7774%}
7775
7776// Convert compressed oop into int for vectors alignment masking
7777// in case of 32bit oops (heap < 4Gb).
7778instruct convN2I(iRegINoSp dst, iRegN src)
7779%{
7780  predicate(Universe::narrow_oop_shift() == 0);
7781  match(Set dst (ConvL2I (CastP2X (DecodeN src))));
7782
7783  ins_cost(INSN_COST);
7784  format %{ "mov dst, $src\t# compressed ptr -> int" %}
7785  ins_encode %{
7786    __ movw($dst$$Register, $src$$Register);
7787  %}
7788
7789  ins_pipe(ialu_reg);
7790%}
7791
7792
7793// Convert oop pointer into compressed form
7794instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
7795  predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
7796  match(Set dst (EncodeP src));
7797  effect(KILL cr);
7798  ins_cost(INSN_COST * 3);
7799  format %{ "encode_heap_oop $dst, $src" %}
7800  ins_encode %{
7801    Register s = $src$$Register;
7802    Register d = $dst$$Register;
7803    __ encode_heap_oop(d, s);
7804  %}
7805  ins_pipe(ialu_reg);
7806%}
7807
7808instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
7809  predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
7810  match(Set dst (EncodeP src));
7811  ins_cost(INSN_COST * 3);
7812  format %{ "encode_heap_oop_not_null $dst, $src" %}
7813  ins_encode %{
7814    __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
7815  %}
7816  ins_pipe(ialu_reg);
7817%}
7818
7819instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
7820  predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
7821            n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
7822  match(Set dst (DecodeN src));
7823  ins_cost(INSN_COST * 3);
7824  format %{ "decode_heap_oop $dst, $src" %}
7825  ins_encode %{
7826    Register s = $src$$Register;
7827    Register d = $dst$$Register;
7828    __ decode_heap_oop(d, s);
7829  %}
7830  ins_pipe(ialu_reg);
7831%}
7832
7833instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
7834  predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
7835            n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
7836  match(Set dst (DecodeN src));
7837  ins_cost(INSN_COST * 3);
7838  format %{ "decode_heap_oop_not_null $dst, $src" %}
7839  ins_encode %{
7840    Register s = $src$$Register;
7841    Register d = $dst$$Register;
7842    __ decode_heap_oop_not_null(d, s);
7843  %}
7844  ins_pipe(ialu_reg);
7845%}
7846
7847// n.b. AArch64 implementations of encode_klass_not_null and
7848// decode_klass_not_null do not modify the flags register so, unlike
7849// Intel, we don't kill CR as a side effect here
7850
7851instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{
7852  match(Set dst (EncodePKlass src));
7853
7854  ins_cost(INSN_COST * 3);
7855  format %{ "encode_klass_not_null $dst,$src" %}
7856
7857  ins_encode %{
7858    Register src_reg = as_Register($src$$reg);
7859    Register dst_reg = as_Register($dst$$reg);
7860    __ encode_klass_not_null(dst_reg, src_reg);
7861  %}
7862
7863   ins_pipe(ialu_reg);
7864%}
7865
7866instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{
7867  match(Set dst (DecodeNKlass src));
7868
7869  ins_cost(INSN_COST * 3);
7870  format %{ "decode_klass_not_null $dst,$src" %}
7871
7872  ins_encode %{
7873    Register src_reg = as_Register($src$$reg);
7874    Register dst_reg = as_Register($dst$$reg);
7875    if (dst_reg != src_reg) {
7876      __ decode_klass_not_null(dst_reg, src_reg);
7877    } else {
7878      __ decode_klass_not_null(dst_reg);
7879    }
7880  %}
7881
7882   ins_pipe(ialu_reg);
7883%}
7884
7885instruct checkCastPP(iRegPNoSp dst)
7886%{
7887  match(Set dst (CheckCastPP dst));
7888
7889  size(0);
7890  format %{ "# checkcastPP of $dst" %}
7891  ins_encode(/* empty encoding */);
7892  ins_pipe(pipe_class_empty);
7893%}
7894
7895instruct castPP(iRegPNoSp dst)
7896%{
7897  match(Set dst (CastPP dst));
7898
7899  size(0);
7900  format %{ "# castPP of $dst" %}
7901  ins_encode(/* empty encoding */);
7902  ins_pipe(pipe_class_empty);
7903%}
7904
7905instruct castII(iRegI dst)
7906%{
7907  match(Set dst (CastII dst));
7908
7909  size(0);
7910  format %{ "# castII of $dst" %}
7911  ins_encode(/* empty encoding */);
7912  ins_cost(0);
7913  ins_pipe(pipe_class_empty);
7914%}
7915
7916// ============================================================================
7917// Atomic operation instructions
7918//
7919// Intel and SPARC both implement Ideal Node LoadPLocked and
7920// Store{PIL}Conditional instructions using a normal load for the
7921// LoadPLocked and a CAS for the Store{PIL}Conditional.
7922//
7923// The ideal code appears only to use LoadPLocked/StorePLocked as a
7924// pair to lock object allocations from Eden space when not using
7925// TLABs.
7926//
7927// There does not appear to be a Load{IL}Locked Ideal Node and the
7928// Ideal code appears to use Store{IL}Conditional as an alias for CAS
7929// and to use StoreIConditional only for 32-bit and StoreLConditional
7930// only for 64-bit.
7931//
7932// We implement LoadPLocked and StorePLocked instructions using,
7933// respectively the AArch64 hw load-exclusive and store-conditional
7934// instructions. Whereas we must implement each of
7935// Store{IL}Conditional using a CAS which employs a pair of
7936// instructions comprising a load-exclusive followed by a
7937// store-conditional.
7938
7939
7940// Locked-load (linked load) of the current heap-top
7941// used when updating the eden heap top
7942// implemented using ldaxr on AArch64
7943
7944instruct loadPLocked(iRegPNoSp dst, indirect mem)
7945%{
7946  match(Set dst (LoadPLocked mem));
7947
7948  ins_cost(VOLATILE_REF_COST);
7949
7950  format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %}
7951
7952  ins_encode(aarch64_enc_ldaxr(dst, mem));
7953
7954  ins_pipe(pipe_serial);
7955%}
7956
7957// Conditional-store of the updated heap-top.
7958// Used during allocation of the shared heap.
7959// Sets flag (EQ) on success.
7960// implemented using stlxr on AArch64.
7961
7962instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr)
7963%{
7964  match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
7965
7966  ins_cost(VOLATILE_REF_COST);
7967
7968 // TODO
7969 // do we need to do a store-conditional release or can we just use a
7970 // plain store-conditional?
7971
7972  format %{
7973    "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release"
7974    "cmpw rscratch1, zr\t# EQ on successful write"
7975  %}
7976
7977  ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr));
7978
7979  ins_pipe(pipe_serial);
7980%}
7981
7982
7983// storeLConditional is used by PhaseMacroExpand::expand_lock_node
7984// when attempting to rebias a lock towards the current thread.  We
7985// must use the acquire form of cmpxchg in order to guarantee acquire
7986// semantics in this case.
7987instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr)
7988%{
7989  match(Set cr (StoreLConditional mem (Binary oldval newval)));
7990
7991  ins_cost(VOLATILE_REF_COST);
7992
7993  format %{
7994    "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
7995    "cmpw rscratch1, zr\t# EQ on successful write"
7996  %}
7997
7998  ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval));
7999
8000  ins_pipe(pipe_slow);
8001%}
8002
8003// storeIConditional also has acquire semantics, for no better reason
8004// than matching storeLConditional.  At the time of writing this
8005// comment storeIConditional was not used anywhere by AArch64.
8006instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr)
8007%{
8008  match(Set cr (StoreIConditional mem (Binary oldval newval)));
8009
8010  ins_cost(VOLATILE_REF_COST);
8011
8012  format %{
8013    "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
8014    "cmpw rscratch1, zr\t# EQ on successful write"
8015  %}
8016
8017  ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval));
8018
8019  ins_pipe(pipe_slow);
8020%}
8021
8022// XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher
8023// can't match them
8024
8025// standard CompareAndSwapX when we are using barriers
8026// these have higher priority than the rules selected by a predicate
8027
8028instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8029
8030  match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8031  ins_cost(2 * VOLATILE_REF_COST);
8032
8033  effect(KILL cr);
8034
8035 format %{
8036    "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8037    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8038 %}
8039
8040 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8041            aarch64_enc_cset_eq(res));
8042
8043  ins_pipe(pipe_slow);
8044%}
8045
8046instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8047
8048  match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8049  ins_cost(2 * VOLATILE_REF_COST);
8050
8051  effect(KILL cr);
8052
8053 format %{
8054    "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8055    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8056 %}
8057
8058 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8059            aarch64_enc_cset_eq(res));
8060
8061  ins_pipe(pipe_slow);
8062%}
8063
8064instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8065
8066  match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8067  ins_cost(2 * VOLATILE_REF_COST);
8068
8069  effect(KILL cr);
8070
8071 format %{
8072    "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8073    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8074 %}
8075
8076 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8077            aarch64_enc_cset_eq(res));
8078
8079  ins_pipe(pipe_slow);
8080%}
8081
8082instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8083
8084  match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8085  ins_cost(2 * VOLATILE_REF_COST);
8086
8087  effect(KILL cr);
8088
8089 format %{
8090    "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8091    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8092 %}
8093
8094 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8095            aarch64_enc_cset_eq(res));
8096
8097  ins_pipe(pipe_slow);
8098%}
8099
8100
8101// alternative CompareAndSwapX when we are eliding barriers
8102
8103instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8104
8105  predicate(needs_acquiring_load_exclusive(n));
8106  match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8107  ins_cost(VOLATILE_REF_COST);
8108
8109  effect(KILL cr);
8110
8111 format %{
8112    "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8113    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8114 %}
8115
8116 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8117            aarch64_enc_cset_eq(res));
8118
8119  ins_pipe(pipe_slow);
8120%}
8121
8122instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8123
8124  predicate(needs_acquiring_load_exclusive(n));
8125  match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8126  ins_cost(VOLATILE_REF_COST);
8127
8128  effect(KILL cr);
8129
8130 format %{
8131    "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8132    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8133 %}
8134
8135 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8136            aarch64_enc_cset_eq(res));
8137
8138  ins_pipe(pipe_slow);
8139%}
8140
8141instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8142
8143  predicate(needs_acquiring_load_exclusive(n));
8144  match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8145  ins_cost(VOLATILE_REF_COST);
8146
8147  effect(KILL cr);
8148
8149 format %{
8150    "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8151    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8152 %}
8153
8154 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8155            aarch64_enc_cset_eq(res));
8156
8157  ins_pipe(pipe_slow);
8158%}
8159
8160instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8161
8162  predicate(needs_acquiring_load_exclusive(n));
8163  match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8164  ins_cost(VOLATILE_REF_COST);
8165
8166  effect(KILL cr);
8167
8168 format %{
8169    "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8170    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8171 %}
8172
8173 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8174            aarch64_enc_cset_eq(res));
8175
8176  ins_pipe(pipe_slow);
8177%}
8178
8179
8180instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
8181  match(Set prev (GetAndSetI mem newv));
8182  ins_cost(2 * VOLATILE_REF_COST);
8183  format %{ "atomic_xchgw  $prev, $newv, [$mem]" %}
8184  ins_encode %{
8185    __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8186  %}
8187  ins_pipe(pipe_serial);
8188%}
8189
8190instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{
8191  match(Set prev (GetAndSetL mem newv));
8192  ins_cost(2 * VOLATILE_REF_COST);
8193  format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
8194  ins_encode %{
8195    __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
8196  %}
8197  ins_pipe(pipe_serial);
8198%}
8199
8200instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{
8201  match(Set prev (GetAndSetN mem newv));
8202  ins_cost(2 * VOLATILE_REF_COST);
8203  format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
8204  ins_encode %{
8205    __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8206  %}
8207  ins_pipe(pipe_serial);
8208%}
8209
8210instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
8211  match(Set prev (GetAndSetP mem newv));
8212  ins_cost(2 * VOLATILE_REF_COST);
8213  format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
8214  ins_encode %{
8215    __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
8216  %}
8217  ins_pipe(pipe_serial);
8218%}
8219
8220instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{
8221  predicate(needs_acquiring_load_exclusive(n));
8222  match(Set prev (GetAndSetI mem newv));
8223  ins_cost(VOLATILE_REF_COST);
8224  format %{ "atomic_xchgw_acq  $prev, $newv, [$mem]" %}
8225  ins_encode %{
8226    __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8227  %}
8228  ins_pipe(pipe_serial);
8229%}
8230
8231instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{
8232  predicate(needs_acquiring_load_exclusive(n));
8233  match(Set prev (GetAndSetL mem newv));
8234  ins_cost(VOLATILE_REF_COST);
8235  format %{ "atomic_xchg_acq  $prev, $newv, [$mem]" %}
8236  ins_encode %{
8237    __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
8238  %}
8239  ins_pipe(pipe_serial);
8240%}
8241
8242instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{
8243  predicate(needs_acquiring_load_exclusive(n));
8244  match(Set prev (GetAndSetN mem newv));
8245  ins_cost(VOLATILE_REF_COST);
8246  format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %}
8247  ins_encode %{
8248    __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8249  %}
8250  ins_pipe(pipe_serial);
8251%}
8252
8253instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{
8254  predicate(needs_acquiring_load_exclusive(n));
8255  match(Set prev (GetAndSetP mem newv));
8256  ins_cost(VOLATILE_REF_COST);
8257  format %{ "atomic_xchg_acq  $prev, $newv, [$mem]" %}
8258  ins_encode %{
8259    __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
8260  %}
8261  ins_pipe(pipe_serial);
8262%}
8263
8264
8265instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{
8266  match(Set newval (GetAndAddL mem incr));
8267  ins_cost(2 * VOLATILE_REF_COST + 1);
8268  format %{ "get_and_addL $newval, [$mem], $incr" %}
8269  ins_encode %{
8270    __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base));
8271  %}
8272  ins_pipe(pipe_serial);
8273%}
8274
8275instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{
8276  predicate(n->as_LoadStore()->result_not_used());
8277  match(Set dummy (GetAndAddL mem incr));
8278  ins_cost(2 * VOLATILE_REF_COST);
8279  format %{ "get_and_addL [$mem], $incr" %}
8280  ins_encode %{
8281    __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base));
8282  %}
8283  ins_pipe(pipe_serial);
8284%}
8285
8286instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
8287  match(Set newval (GetAndAddL mem incr));
8288  ins_cost(2 * VOLATILE_REF_COST + 1);
8289  format %{ "get_and_addL $newval, [$mem], $incr" %}
8290  ins_encode %{
8291    __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base));
8292  %}
8293  ins_pipe(pipe_serial);
8294%}
8295
8296instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{
8297  predicate(n->as_LoadStore()->result_not_used());
8298  match(Set dummy (GetAndAddL mem incr));
8299  ins_cost(2 * VOLATILE_REF_COST);
8300  format %{ "get_and_addL [$mem], $incr" %}
8301  ins_encode %{
8302    __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base));
8303  %}
8304  ins_pipe(pipe_serial);
8305%}
8306
8307instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
8308  match(Set newval (GetAndAddI mem incr));
8309  ins_cost(2 * VOLATILE_REF_COST + 1);
8310  format %{ "get_and_addI $newval, [$mem], $incr" %}
8311  ins_encode %{
8312    __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base));
8313  %}
8314  ins_pipe(pipe_serial);
8315%}
8316
8317instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{
8318  predicate(n->as_LoadStore()->result_not_used());
8319  match(Set dummy (GetAndAddI mem incr));
8320  ins_cost(2 * VOLATILE_REF_COST);
8321  format %{ "get_and_addI [$mem], $incr" %}
8322  ins_encode %{
8323    __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base));
8324  %}
8325  ins_pipe(pipe_serial);
8326%}
8327
8328instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{
8329  match(Set newval (GetAndAddI mem incr));
8330  ins_cost(2 * VOLATILE_REF_COST + 1);
8331  format %{ "get_and_addI $newval, [$mem], $incr" %}
8332  ins_encode %{
8333    __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base));
8334  %}
8335  ins_pipe(pipe_serial);
8336%}
8337
8338instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{
8339  predicate(n->as_LoadStore()->result_not_used());
8340  match(Set dummy (GetAndAddI mem incr));
8341  ins_cost(2 * VOLATILE_REF_COST);
8342  format %{ "get_and_addI [$mem], $incr" %}
8343  ins_encode %{
8344    __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base));
8345  %}
8346  ins_pipe(pipe_serial);
8347%}
8348
8349instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{
8350  predicate(needs_acquiring_load_exclusive(n));
8351  match(Set newval (GetAndAddL mem incr));
8352  ins_cost(VOLATILE_REF_COST + 1);
8353  format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
8354  ins_encode %{
8355    __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base));
8356  %}
8357  ins_pipe(pipe_serial);
8358%}
8359
8360instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{
8361  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
8362  match(Set dummy (GetAndAddL mem incr));
8363  ins_cost(VOLATILE_REF_COST);
8364  format %{ "get_and_addL_acq [$mem], $incr" %}
8365  ins_encode %{
8366    __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base));
8367  %}
8368  ins_pipe(pipe_serial);
8369%}
8370
8371instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
8372  predicate(needs_acquiring_load_exclusive(n));
8373  match(Set newval (GetAndAddL mem incr));
8374  ins_cost(VOLATILE_REF_COST + 1);
8375  format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
8376  ins_encode %{
8377    __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base));
8378  %}
8379  ins_pipe(pipe_serial);
8380%}
8381
8382instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{
8383  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
8384  match(Set dummy (GetAndAddL mem incr));
8385  ins_cost(VOLATILE_REF_COST);
8386  format %{ "get_and_addL_acq [$mem], $incr" %}
8387  ins_encode %{
8388    __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base));
8389  %}
8390  ins_pipe(pipe_serial);
8391%}
8392
8393instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
8394  predicate(needs_acquiring_load_exclusive(n));
8395  match(Set newval (GetAndAddI mem incr));
8396  ins_cost(VOLATILE_REF_COST + 1);
8397  format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
8398  ins_encode %{
8399    __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base));
8400  %}
8401  ins_pipe(pipe_serial);
8402%}
8403
8404instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{
8405  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
8406  match(Set dummy (GetAndAddI mem incr));
8407  ins_cost(VOLATILE_REF_COST);
8408  format %{ "get_and_addI_acq [$mem], $incr" %}
8409  ins_encode %{
8410    __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base));
8411  %}
8412  ins_pipe(pipe_serial);
8413%}
8414
8415instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{
8416  predicate(needs_acquiring_load_exclusive(n));
8417  match(Set newval (GetAndAddI mem incr));
8418  ins_cost(VOLATILE_REF_COST + 1);
8419  format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
8420  ins_encode %{
8421    __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base));
8422  %}
8423  ins_pipe(pipe_serial);
8424%}
8425
8426instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{
8427  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
8428  match(Set dummy (GetAndAddI mem incr));
8429  ins_cost(VOLATILE_REF_COST);
8430  format %{ "get_and_addI_acq [$mem], $incr" %}
8431  ins_encode %{
8432    __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base));
8433  %}
8434  ins_pipe(pipe_serial);
8435%}
8436
8437// ============================================================================
8438// Conditional Move Instructions
8439
8440// n.b. we have identical rules for both a signed compare op (cmpOp)
8441// and an unsigned compare op (cmpOpU). it would be nice if we could
8442// define an op class which merged both inputs and use it to type the
8443// argument to a single rule. unfortunatelyt his fails because the
8444// opclass does not live up to the COND_INTER interface of its
8445// component operands. When the generic code tries to negate the
8446// operand it ends up running the generci Machoper::negate method
8447// which throws a ShouldNotHappen. So, we have to provide two flavours
8448// of each rule, one for a cmpOp and a second for a cmpOpU (sigh).
8449
8450instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
8451  match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
8452
8453  ins_cost(INSN_COST * 2);
8454  format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int"  %}
8455
8456  ins_encode %{
8457    __ cselw(as_Register($dst$$reg),
8458             as_Register($src2$$reg),
8459             as_Register($src1$$reg),
8460             (Assembler::Condition)$cmp$$cmpcode);
8461  %}
8462
8463  ins_pipe(icond_reg_reg);
8464%}
8465
8466instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
8467  match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
8468
8469  ins_cost(INSN_COST * 2);
8470  format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int"  %}
8471
8472  ins_encode %{
8473    __ cselw(as_Register($dst$$reg),
8474             as_Register($src2$$reg),
8475             as_Register($src1$$reg),
8476             (Assembler::Condition)$cmp$$cmpcode);
8477  %}
8478
8479  ins_pipe(icond_reg_reg);
8480%}
8481
8482// special cases where one arg is zero
8483
8484// n.b. this is selected in preference to the rule above because it
8485// avoids loading constant 0 into a source register
8486
8487// TODO
8488// we ought only to be able to cull one of these variants as the ideal
8489// transforms ought always to order the zero consistently (to left/right?)
8490
8491instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
8492  match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
8493
8494  ins_cost(INSN_COST * 2);
8495  format %{ "cselw $dst, $src, zr $cmp\t# signed, int"  %}
8496
8497  ins_encode %{
8498    __ cselw(as_Register($dst$$reg),
8499             as_Register($src$$reg),
8500             zr,
8501             (Assembler::Condition)$cmp$$cmpcode);
8502  %}
8503
8504  ins_pipe(icond_reg);
8505%}
8506
8507instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
8508  match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
8509
8510  ins_cost(INSN_COST * 2);
8511  format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int"  %}
8512
8513  ins_encode %{
8514    __ cselw(as_Register($dst$$reg),
8515             as_Register($src$$reg),
8516             zr,
8517             (Assembler::Condition)$cmp$$cmpcode);
8518  %}
8519
8520  ins_pipe(icond_reg);
8521%}
8522
8523instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
8524  match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
8525
8526  ins_cost(INSN_COST * 2);
8527  format %{ "cselw $dst, zr, $src $cmp\t# signed, int"  %}
8528
8529  ins_encode %{
8530    __ cselw(as_Register($dst$$reg),
8531             zr,
8532             as_Register($src$$reg),
8533             (Assembler::Condition)$cmp$$cmpcode);
8534  %}
8535
8536  ins_pipe(icond_reg);
8537%}
8538
8539instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
8540  match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
8541
8542  ins_cost(INSN_COST * 2);
8543  format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int"  %}
8544
8545  ins_encode %{
8546    __ cselw(as_Register($dst$$reg),
8547             zr,
8548             as_Register($src$$reg),
8549             (Assembler::Condition)$cmp$$cmpcode);
8550  %}
8551
8552  ins_pipe(icond_reg);
8553%}
8554
8555// special case for creating a boolean 0 or 1
8556
8557// n.b. this is selected in preference to the rule above because it
8558// avoids loading constants 0 and 1 into a source register
8559
8560instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
8561  match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
8562
8563  ins_cost(INSN_COST * 2);
8564  format %{ "csincw $dst, zr, zr $cmp\t# signed, int"  %}
8565
8566  ins_encode %{
8567    // equivalently
8568    // cset(as_Register($dst$$reg),
8569    //      negate_condition((Assembler::Condition)$cmp$$cmpcode));
8570    __ csincw(as_Register($dst$$reg),
8571	     zr,
8572	     zr,
8573             (Assembler::Condition)$cmp$$cmpcode);
8574  %}
8575
8576  ins_pipe(icond_none);
8577%}
8578
8579instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
8580  match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
8581
8582  ins_cost(INSN_COST * 2);
8583  format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int"  %}
8584
8585  ins_encode %{
8586    // equivalently
8587    // cset(as_Register($dst$$reg),
8588    //      negate_condition((Assembler::Condition)$cmp$$cmpcode));
8589    __ csincw(as_Register($dst$$reg),
8590	     zr,
8591	     zr,
8592             (Assembler::Condition)$cmp$$cmpcode);
8593  %}
8594
8595  ins_pipe(icond_none);
8596%}
8597
8598instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
8599  match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
8600
8601  ins_cost(INSN_COST * 2);
8602  format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long"  %}
8603
8604  ins_encode %{
8605    __ csel(as_Register($dst$$reg),
8606            as_Register($src2$$reg),
8607            as_Register($src1$$reg),
8608            (Assembler::Condition)$cmp$$cmpcode);
8609  %}
8610
8611  ins_pipe(icond_reg_reg);
8612%}
8613
8614instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
8615  match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
8616
8617  ins_cost(INSN_COST * 2);
8618  format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long"  %}
8619
8620  ins_encode %{
8621    __ csel(as_Register($dst$$reg),
8622            as_Register($src2$$reg),
8623            as_Register($src1$$reg),
8624            (Assembler::Condition)$cmp$$cmpcode);
8625  %}
8626
8627  ins_pipe(icond_reg_reg);
8628%}
8629
8630// special cases where one arg is zero
8631
8632instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
8633  match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
8634
8635  ins_cost(INSN_COST * 2);
8636  format %{ "csel $dst, zr, $src $cmp\t# signed, long"  %}
8637
8638  ins_encode %{
8639    __ csel(as_Register($dst$$reg),
8640            zr,
8641            as_Register($src$$reg),
8642            (Assembler::Condition)$cmp$$cmpcode);
8643  %}
8644
8645  ins_pipe(icond_reg);
8646%}
8647
8648instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
8649  match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
8650
8651  ins_cost(INSN_COST * 2);
8652  format %{ "csel $dst, zr, $src $cmp\t# unsigned, long"  %}
8653
8654  ins_encode %{
8655    __ csel(as_Register($dst$$reg),
8656            zr,
8657            as_Register($src$$reg),
8658            (Assembler::Condition)$cmp$$cmpcode);
8659  %}
8660
8661  ins_pipe(icond_reg);
8662%}
8663
8664instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
8665  match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
8666
8667  ins_cost(INSN_COST * 2);
8668  format %{ "csel $dst, $src, zr $cmp\t# signed, long"  %}
8669
8670  ins_encode %{
8671    __ csel(as_Register($dst$$reg),
8672            as_Register($src$$reg),
8673            zr,
8674            (Assembler::Condition)$cmp$$cmpcode);
8675  %}
8676
8677  ins_pipe(icond_reg);
8678%}
8679
8680instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
8681  match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
8682
8683  ins_cost(INSN_COST * 2);
8684  format %{ "csel $dst, $src, zr $cmp\t# unsigned, long"  %}
8685
8686  ins_encode %{
8687    __ csel(as_Register($dst$$reg),
8688            as_Register($src$$reg),
8689            zr,
8690            (Assembler::Condition)$cmp$$cmpcode);
8691  %}
8692
8693  ins_pipe(icond_reg);
8694%}
8695
8696instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
8697  match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
8698
8699  ins_cost(INSN_COST * 2);
8700  format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr"  %}
8701
8702  ins_encode %{
8703    __ csel(as_Register($dst$$reg),
8704            as_Register($src2$$reg),
8705            as_Register($src1$$reg),
8706            (Assembler::Condition)$cmp$$cmpcode);
8707  %}
8708
8709  ins_pipe(icond_reg_reg);
8710%}
8711
8712instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
8713  match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
8714
8715  ins_cost(INSN_COST * 2);
8716  format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr"  %}
8717
8718  ins_encode %{
8719    __ csel(as_Register($dst$$reg),
8720            as_Register($src2$$reg),
8721            as_Register($src1$$reg),
8722            (Assembler::Condition)$cmp$$cmpcode);
8723  %}
8724
8725  ins_pipe(icond_reg_reg);
8726%}
8727
8728// special cases where one arg is zero
8729
8730instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
8731  match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
8732
8733  ins_cost(INSN_COST * 2);
8734  format %{ "csel $dst, zr, $src $cmp\t# signed, ptr"  %}
8735
8736  ins_encode %{
8737    __ csel(as_Register($dst$$reg),
8738            zr,
8739            as_Register($src$$reg),
8740            (Assembler::Condition)$cmp$$cmpcode);
8741  %}
8742
8743  ins_pipe(icond_reg);
8744%}
8745
8746instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
8747  match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
8748
8749  ins_cost(INSN_COST * 2);
8750  format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr"  %}
8751
8752  ins_encode %{
8753    __ csel(as_Register($dst$$reg),
8754            zr,
8755            as_Register($src$$reg),
8756            (Assembler::Condition)$cmp$$cmpcode);
8757  %}
8758
8759  ins_pipe(icond_reg);
8760%}
8761
8762instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
8763  match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
8764
8765  ins_cost(INSN_COST * 2);
8766  format %{ "csel $dst, $src, zr $cmp\t# signed, ptr"  %}
8767
8768  ins_encode %{
8769    __ csel(as_Register($dst$$reg),
8770            as_Register($src$$reg),
8771            zr,
8772            (Assembler::Condition)$cmp$$cmpcode);
8773  %}
8774
8775  ins_pipe(icond_reg);
8776%}
8777
8778instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
8779  match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
8780
8781  ins_cost(INSN_COST * 2);
8782  format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr"  %}
8783
8784  ins_encode %{
8785    __ csel(as_Register($dst$$reg),
8786            as_Register($src$$reg),
8787            zr,
8788            (Assembler::Condition)$cmp$$cmpcode);
8789  %}
8790
8791  ins_pipe(icond_reg);
8792%}
8793
8794instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
8795  match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
8796
8797  ins_cost(INSN_COST * 2);
8798  format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr"  %}
8799
8800  ins_encode %{
8801    __ cselw(as_Register($dst$$reg),
8802             as_Register($src2$$reg),
8803             as_Register($src1$$reg),
8804             (Assembler::Condition)$cmp$$cmpcode);
8805  %}
8806
8807  ins_pipe(icond_reg_reg);
8808%}
8809
8810instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
8811  match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
8812
8813  ins_cost(INSN_COST * 2);
8814  format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr"  %}
8815
8816  ins_encode %{
8817    __ cselw(as_Register($dst$$reg),
8818             as_Register($src2$$reg),
8819             as_Register($src1$$reg),
8820             (Assembler::Condition)$cmp$$cmpcode);
8821  %}
8822
8823  ins_pipe(icond_reg_reg);
8824%}
8825
8826// special cases where one arg is zero
8827
8828instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
8829  match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
8830
8831  ins_cost(INSN_COST * 2);
8832  format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr"  %}
8833
8834  ins_encode %{
8835    __ cselw(as_Register($dst$$reg),
8836             zr,
8837             as_Register($src$$reg),
8838             (Assembler::Condition)$cmp$$cmpcode);
8839  %}
8840
8841  ins_pipe(icond_reg);
8842%}
8843
8844instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
8845  match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
8846
8847  ins_cost(INSN_COST * 2);
8848  format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr"  %}
8849
8850  ins_encode %{
8851    __ cselw(as_Register($dst$$reg),
8852             zr,
8853             as_Register($src$$reg),
8854             (Assembler::Condition)$cmp$$cmpcode);
8855  %}
8856
8857  ins_pipe(icond_reg);
8858%}
8859
8860instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
8861  match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
8862
8863  ins_cost(INSN_COST * 2);
8864  format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr"  %}
8865
8866  ins_encode %{
8867    __ cselw(as_Register($dst$$reg),
8868             as_Register($src$$reg),
8869             zr,
8870             (Assembler::Condition)$cmp$$cmpcode);
8871  %}
8872
8873  ins_pipe(icond_reg);
8874%}
8875
8876instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
8877  match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
8878
8879  ins_cost(INSN_COST * 2);
8880  format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr"  %}
8881
8882  ins_encode %{
8883    __ cselw(as_Register($dst$$reg),
8884             as_Register($src$$reg),
8885             zr,
8886             (Assembler::Condition)$cmp$$cmpcode);
8887  %}
8888
8889  ins_pipe(icond_reg);
8890%}
8891
8892instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1,  vRegF src2)
8893%{
8894  match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
8895
8896  ins_cost(INSN_COST * 3);
8897
8898  format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
8899  ins_encode %{
8900    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
8901    __ fcsels(as_FloatRegister($dst$$reg),
8902              as_FloatRegister($src2$$reg),
8903              as_FloatRegister($src1$$reg),
8904              cond);
8905  %}
8906
8907  ins_pipe(fp_cond_reg_reg_s);
8908%}
8909
8910instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1,  vRegF src2)
8911%{
8912  match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
8913
8914  ins_cost(INSN_COST * 3);
8915
8916  format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
8917  ins_encode %{
8918    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
8919    __ fcsels(as_FloatRegister($dst$$reg),
8920              as_FloatRegister($src2$$reg),
8921              as_FloatRegister($src1$$reg),
8922              cond);
8923  %}
8924
8925  ins_pipe(fp_cond_reg_reg_s);
8926%}
8927
8928instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1,  vRegD src2)
8929%{
8930  match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
8931
8932  ins_cost(INSN_COST * 3);
8933
8934  format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
8935  ins_encode %{
8936    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
8937    __ fcseld(as_FloatRegister($dst$$reg),
8938              as_FloatRegister($src2$$reg),
8939              as_FloatRegister($src1$$reg),
8940              cond);
8941  %}
8942
8943  ins_pipe(fp_cond_reg_reg_d);
8944%}
8945
8946instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1,  vRegD src2)
8947%{
8948  match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
8949
8950  ins_cost(INSN_COST * 3);
8951
8952  format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
8953  ins_encode %{
8954    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
8955    __ fcseld(as_FloatRegister($dst$$reg),
8956              as_FloatRegister($src2$$reg),
8957              as_FloatRegister($src1$$reg),
8958              cond);
8959  %}
8960
8961  ins_pipe(fp_cond_reg_reg_d);
8962%}
8963
8964// ============================================================================
8965// Arithmetic Instructions
8966//
8967
8968// Integer Addition
8969
8970// TODO
8971// these currently employ operations which do not set CR and hence are
8972// not flagged as killing CR but we would like to isolate the cases
8973// where we want to set flags from those where we don't. need to work
8974// out how to do that.
8975
8976instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
8977  match(Set dst (AddI src1 src2));
8978
8979  ins_cost(INSN_COST);
8980  format %{ "addw  $dst, $src1, $src2" %}
8981
8982  ins_encode %{
8983    __ addw(as_Register($dst$$reg),
8984            as_Register($src1$$reg),
8985            as_Register($src2$$reg));
8986  %}
8987
8988  ins_pipe(ialu_reg_reg);
8989%}
8990
8991instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
8992  match(Set dst (AddI src1 src2));
8993
8994  ins_cost(INSN_COST);
8995  format %{ "addw $dst, $src1, $src2" %}
8996
8997  // use opcode to indicate that this is an add not a sub
8998  opcode(0x0);
8999
9000  ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
9001
9002  ins_pipe(ialu_reg_imm);
9003%}
9004
9005instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{
9006  match(Set dst (AddI (ConvL2I src1) src2));
9007
9008  ins_cost(INSN_COST);
9009  format %{ "addw $dst, $src1, $src2" %}
9010
9011  // use opcode to indicate that this is an add not a sub
9012  opcode(0x0);
9013
9014  ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
9015
9016  ins_pipe(ialu_reg_imm);
9017%}
9018
9019// Pointer Addition
9020instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{
9021  match(Set dst (AddP src1 src2));
9022
9023  ins_cost(INSN_COST);
9024  format %{ "add $dst, $src1, $src2\t# ptr" %}
9025
9026  ins_encode %{
9027    __ add(as_Register($dst$$reg),
9028           as_Register($src1$$reg),
9029           as_Register($src2$$reg));
9030  %}
9031
9032  ins_pipe(ialu_reg_reg);
9033%}
9034
9035instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{
9036  match(Set dst (AddP src1 (ConvI2L src2)));
9037
9038  ins_cost(1.9 * INSN_COST);
9039  format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %}
9040
9041  ins_encode %{
9042    __ add(as_Register($dst$$reg),
9043           as_Register($src1$$reg),
9044           as_Register($src2$$reg), ext::sxtw);
9045  %}
9046
9047  ins_pipe(ialu_reg_reg);
9048%}
9049
9050instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{
9051  match(Set dst (AddP src1 (LShiftL src2 scale)));
9052
9053  ins_cost(1.9 * INSN_COST);
9054  format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %}
9055
9056  ins_encode %{
9057    __ lea(as_Register($dst$$reg),
9058	   Address(as_Register($src1$$reg), as_Register($src2$$reg),
9059		   Address::lsl($scale$$constant)));
9060  %}
9061
9062  ins_pipe(ialu_reg_reg_shift);
9063%}
9064
9065instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{
9066  match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale)));
9067
9068  ins_cost(1.9 * INSN_COST);
9069  format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %}
9070
9071  ins_encode %{
9072    __ lea(as_Register($dst$$reg),
9073	   Address(as_Register($src1$$reg), as_Register($src2$$reg),
9074		   Address::sxtw($scale$$constant)));
9075  %}
9076
9077  ins_pipe(ialu_reg_reg_shift);
9078%}
9079
9080instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{
9081  match(Set dst (LShiftL (ConvI2L src) scale));
9082
9083  ins_cost(INSN_COST);
9084  format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %}
9085
9086  ins_encode %{
9087    __ sbfiz(as_Register($dst$$reg),
9088          as_Register($src$$reg),
9089          $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63));
9090  %}
9091
9092  ins_pipe(ialu_reg_shift);
9093%}
9094
9095// Pointer Immediate Addition
9096// n.b. this needs to be more expensive than using an indirect memory
9097// operand
9098instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{
9099  match(Set dst (AddP src1 src2));
9100
9101  ins_cost(INSN_COST);
9102  format %{ "add $dst, $src1, $src2\t# ptr" %}
9103
9104  // use opcode to indicate that this is an add not a sub
9105  opcode(0x0);
9106
9107  ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
9108
9109  ins_pipe(ialu_reg_imm);
9110%}
9111
9112// Long Addition
9113instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9114
9115  match(Set dst (AddL src1 src2));
9116
9117  ins_cost(INSN_COST);
9118  format %{ "add  $dst, $src1, $src2" %}
9119
9120  ins_encode %{
9121    __ add(as_Register($dst$$reg),
9122           as_Register($src1$$reg),
9123           as_Register($src2$$reg));
9124  %}
9125
9126  ins_pipe(ialu_reg_reg);
9127%}
9128
9129// No constant pool entries requiredLong Immediate Addition.
9130instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
9131  match(Set dst (AddL src1 src2));
9132
9133  ins_cost(INSN_COST);
9134  format %{ "add $dst, $src1, $src2" %}
9135
9136  // use opcode to indicate that this is an add not a sub
9137  opcode(0x0);
9138
9139  ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
9140
9141  ins_pipe(ialu_reg_imm);
9142%}
9143
9144// Integer Subtraction
9145instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9146  match(Set dst (SubI src1 src2));
9147
9148  ins_cost(INSN_COST);
9149  format %{ "subw  $dst, $src1, $src2" %}
9150
9151  ins_encode %{
9152    __ subw(as_Register($dst$$reg),
9153            as_Register($src1$$reg),
9154            as_Register($src2$$reg));
9155  %}
9156
9157  ins_pipe(ialu_reg_reg);
9158%}
9159
9160// Immediate Subtraction
9161instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
9162  match(Set dst (SubI src1 src2));
9163
9164  ins_cost(INSN_COST);
9165  format %{ "subw $dst, $src1, $src2" %}
9166
9167  // use opcode to indicate that this is a sub not an add
9168  opcode(0x1);
9169
9170  ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
9171
9172  ins_pipe(ialu_reg_imm);
9173%}
9174
9175// Long Subtraction
9176instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9177
9178  match(Set dst (SubL src1 src2));
9179
9180  ins_cost(INSN_COST);
9181  format %{ "sub  $dst, $src1, $src2" %}
9182
9183  ins_encode %{
9184    __ sub(as_Register($dst$$reg),
9185           as_Register($src1$$reg),
9186           as_Register($src2$$reg));
9187  %}
9188
9189  ins_pipe(ialu_reg_reg);
9190%}
9191
9192// No constant pool entries requiredLong Immediate Subtraction.
9193instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
9194  match(Set dst (SubL src1 src2));
9195
9196  ins_cost(INSN_COST);
9197  format %{ "sub$dst, $src1, $src2" %}
9198
9199  // use opcode to indicate that this is a sub not an add
9200  opcode(0x1);
9201
9202  ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
9203
9204  ins_pipe(ialu_reg_imm);
9205%}
9206
9207// Integer Negation (special case for sub)
9208
9209instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{
9210  match(Set dst (SubI zero src));
9211
9212  ins_cost(INSN_COST);
9213  format %{ "negw $dst, $src\t# int" %}
9214
9215  ins_encode %{
9216    __ negw(as_Register($dst$$reg),
9217	    as_Register($src$$reg));
9218  %}
9219
9220  ins_pipe(ialu_reg);
9221%}
9222
9223// Long Negation
9224
9225instruct negL_reg(iRegLNoSp dst, iRegIorL2I src, immL0 zero, rFlagsReg cr) %{
9226  match(Set dst (SubL zero src));
9227
9228  ins_cost(INSN_COST);
9229  format %{ "neg $dst, $src\t# long" %}
9230
9231  ins_encode %{
9232    __ neg(as_Register($dst$$reg),
9233	   as_Register($src$$reg));
9234  %}
9235
9236  ins_pipe(ialu_reg);
9237%}
9238
9239// Integer Multiply
9240
9241instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9242  match(Set dst (MulI src1 src2));
9243
9244  ins_cost(INSN_COST * 3);
9245  format %{ "mulw  $dst, $src1, $src2" %}
9246
9247  ins_encode %{
9248    __ mulw(as_Register($dst$$reg),
9249            as_Register($src1$$reg),
9250            as_Register($src2$$reg));
9251  %}
9252
9253  ins_pipe(imul_reg_reg);
9254%}
9255
9256instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9257  match(Set dst (MulL (ConvI2L src1) (ConvI2L src2)));
9258
9259  ins_cost(INSN_COST * 3);
9260  format %{ "smull  $dst, $src1, $src2" %}
9261
9262  ins_encode %{
9263    __ smull(as_Register($dst$$reg),
9264	     as_Register($src1$$reg),
9265	     as_Register($src2$$reg));
9266  %}
9267
9268  ins_pipe(imul_reg_reg);
9269%}
9270
9271// Long Multiply
9272
9273instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9274  match(Set dst (MulL src1 src2));
9275
9276  ins_cost(INSN_COST * 5);
9277  format %{ "mul  $dst, $src1, $src2" %}
9278
9279  ins_encode %{
9280    __ mul(as_Register($dst$$reg),
9281           as_Register($src1$$reg),
9282           as_Register($src2$$reg));
9283  %}
9284
9285  ins_pipe(lmul_reg_reg);
9286%}
9287
9288instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr)
9289%{
9290  match(Set dst (MulHiL src1 src2));
9291
9292  ins_cost(INSN_COST * 7);
9293  format %{ "smulh   $dst, $src1, $src2, \t# mulhi" %}
9294
9295  ins_encode %{
9296    __ smulh(as_Register($dst$$reg),
9297             as_Register($src1$$reg),
9298	     as_Register($src2$$reg));
9299  %}
9300
9301  ins_pipe(lmul_reg_reg);
9302%}
9303
9304// Combined Integer Multiply & Add/Sub
9305
9306instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
9307  match(Set dst (AddI src3 (MulI src1 src2)));
9308
9309  ins_cost(INSN_COST * 3);
9310  format %{ "madd  $dst, $src1, $src2, $src3" %}
9311
9312  ins_encode %{
9313    __ maddw(as_Register($dst$$reg),
9314             as_Register($src1$$reg),
9315             as_Register($src2$$reg),
9316             as_Register($src3$$reg));
9317  %}
9318
9319  ins_pipe(imac_reg_reg);
9320%}
9321
9322instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
9323  match(Set dst (SubI src3 (MulI src1 src2)));
9324
9325  ins_cost(INSN_COST * 3);
9326  format %{ "msub  $dst, $src1, $src2, $src3" %}
9327
9328  ins_encode %{
9329    __ msubw(as_Register($dst$$reg),
9330             as_Register($src1$$reg),
9331             as_Register($src2$$reg),
9332             as_Register($src3$$reg));
9333  %}
9334
9335  ins_pipe(imac_reg_reg);
9336%}
9337
9338// Combined Long Multiply & Add/Sub
9339
9340instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
9341  match(Set dst (AddL src3 (MulL src1 src2)));
9342
9343  ins_cost(INSN_COST * 5);
9344  format %{ "madd  $dst, $src1, $src2, $src3" %}
9345
9346  ins_encode %{
9347    __ madd(as_Register($dst$$reg),
9348            as_Register($src1$$reg),
9349            as_Register($src2$$reg),
9350            as_Register($src3$$reg));
9351  %}
9352
9353  ins_pipe(lmac_reg_reg);
9354%}
9355
9356instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
9357  match(Set dst (SubL src3 (MulL src1 src2)));
9358
9359  ins_cost(INSN_COST * 5);
9360  format %{ "msub  $dst, $src1, $src2, $src3" %}
9361
9362  ins_encode %{
9363    __ msub(as_Register($dst$$reg),
9364            as_Register($src1$$reg),
9365            as_Register($src2$$reg),
9366            as_Register($src3$$reg));
9367  %}
9368
9369  ins_pipe(lmac_reg_reg);
9370%}
9371
9372// Integer Divide
9373
9374instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9375  match(Set dst (DivI src1 src2));
9376
9377  ins_cost(INSN_COST * 19);
9378  format %{ "sdivw  $dst, $src1, $src2" %}
9379
9380  ins_encode(aarch64_enc_divw(dst, src1, src2));
9381  ins_pipe(idiv_reg_reg);
9382%}
9383
9384instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{
9385  match(Set dst (URShiftI (RShiftI src1 div1) div2));
9386  ins_cost(INSN_COST);
9387  format %{ "lsrw $dst, $src1, $div1" %}
9388  ins_encode %{
9389    __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31);
9390  %}
9391  ins_pipe(ialu_reg_shift);
9392%}
9393
9394instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{
9395  match(Set dst (AddI src (URShiftI (RShiftI src div1) div2)));
9396  ins_cost(INSN_COST);
9397  format %{ "addw $dst, $src, LSR $div1" %}
9398
9399  ins_encode %{
9400    __ addw(as_Register($dst$$reg),
9401	      as_Register($src$$reg),
9402	      as_Register($src$$reg),
9403	      Assembler::LSR, 31);
9404  %}
9405  ins_pipe(ialu_reg);
9406%}
9407
9408// Long Divide
9409
9410instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9411  match(Set dst (DivL src1 src2));
9412
9413  ins_cost(INSN_COST * 35);
9414  format %{ "sdiv   $dst, $src1, $src2" %}
9415
9416  ins_encode(aarch64_enc_div(dst, src1, src2));
9417  ins_pipe(ldiv_reg_reg);
9418%}
9419
9420instruct signExtractL(iRegLNoSp dst, iRegL src1, immL_63 div1, immL_63 div2) %{
9421  match(Set dst (URShiftL (RShiftL src1 div1) div2));
9422  ins_cost(INSN_COST);
9423  format %{ "lsr $dst, $src1, $div1" %}
9424  ins_encode %{
9425    __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63);
9426  %}
9427  ins_pipe(ialu_reg_shift);
9428%}
9429
9430instruct div2RoundL(iRegLNoSp dst, iRegL src, immL_63 div1, immL_63 div2) %{
9431  match(Set dst (AddL src (URShiftL (RShiftL src div1) div2)));
9432  ins_cost(INSN_COST);
9433  format %{ "add $dst, $src, $div1" %}
9434
9435  ins_encode %{
9436    __ add(as_Register($dst$$reg),
9437	      as_Register($src$$reg),
9438	      as_Register($src$$reg),
9439	      Assembler::LSR, 63);
9440  %}
9441  ins_pipe(ialu_reg);
9442%}
9443
9444// Integer Remainder
9445
9446instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9447  match(Set dst (ModI src1 src2));
9448
9449  ins_cost(INSN_COST * 22);
9450  format %{ "sdivw  rscratch1, $src1, $src2\n\t"
9451            "msubw($dst, rscratch1, $src2, $src1" %}
9452
9453  ins_encode(aarch64_enc_modw(dst, src1, src2));
9454  ins_pipe(idiv_reg_reg);
9455%}
9456
9457// Long Remainder
9458
9459instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9460  match(Set dst (ModL src1 src2));
9461
9462  ins_cost(INSN_COST * 38);
9463  format %{ "sdiv   rscratch1, $src1, $src2\n"
9464            "msub($dst, rscratch1, $src2, $src1" %}
9465
9466  ins_encode(aarch64_enc_mod(dst, src1, src2));
9467  ins_pipe(ldiv_reg_reg);
9468%}
9469
9470// Integer Shifts
9471
9472// Shift Left Register
9473instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9474  match(Set dst (LShiftI src1 src2));
9475
9476  ins_cost(INSN_COST * 2);
9477  format %{ "lslvw  $dst, $src1, $src2" %}
9478
9479  ins_encode %{
9480    __ lslvw(as_Register($dst$$reg),
9481             as_Register($src1$$reg),
9482             as_Register($src2$$reg));
9483  %}
9484
9485  ins_pipe(ialu_reg_reg_vshift);
9486%}
9487
9488// Shift Left Immediate
9489instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
9490  match(Set dst (LShiftI src1 src2));
9491
9492  ins_cost(INSN_COST);
9493  format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %}
9494
9495  ins_encode %{
9496    __ lslw(as_Register($dst$$reg),
9497            as_Register($src1$$reg),
9498            $src2$$constant & 0x1f);
9499  %}
9500
9501  ins_pipe(ialu_reg_shift);
9502%}
9503
9504// Shift Right Logical Register
9505instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9506  match(Set dst (URShiftI src1 src2));
9507
9508  ins_cost(INSN_COST * 2);
9509  format %{ "lsrvw  $dst, $src1, $src2" %}
9510
9511  ins_encode %{
9512    __ lsrvw(as_Register($dst$$reg),
9513             as_Register($src1$$reg),
9514             as_Register($src2$$reg));
9515  %}
9516
9517  ins_pipe(ialu_reg_reg_vshift);
9518%}
9519
9520// Shift Right Logical Immediate
9521instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
9522  match(Set dst (URShiftI src1 src2));
9523
9524  ins_cost(INSN_COST);
9525  format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %}
9526
9527  ins_encode %{
9528    __ lsrw(as_Register($dst$$reg),
9529            as_Register($src1$$reg),
9530            $src2$$constant & 0x1f);
9531  %}
9532
9533  ins_pipe(ialu_reg_shift);
9534%}
9535
9536// Shift Right Arithmetic Register
9537instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9538  match(Set dst (RShiftI src1 src2));
9539
9540  ins_cost(INSN_COST * 2);
9541  format %{ "asrvw  $dst, $src1, $src2" %}
9542
9543  ins_encode %{
9544    __ asrvw(as_Register($dst$$reg),
9545             as_Register($src1$$reg),
9546             as_Register($src2$$reg));
9547  %}
9548
9549  ins_pipe(ialu_reg_reg_vshift);
9550%}
9551
9552// Shift Right Arithmetic Immediate
9553instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
9554  match(Set dst (RShiftI src1 src2));
9555
9556  ins_cost(INSN_COST);
9557  format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %}
9558
9559  ins_encode %{
9560    __ asrw(as_Register($dst$$reg),
9561            as_Register($src1$$reg),
9562            $src2$$constant & 0x1f);
9563  %}
9564
9565  ins_pipe(ialu_reg_shift);
9566%}
9567
9568// Combined Int Mask and Right Shift (using UBFM)
9569// TODO
9570
9571// Long Shifts
9572
9573// Shift Left Register
9574instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
9575  match(Set dst (LShiftL src1 src2));
9576
9577  ins_cost(INSN_COST * 2);
9578  format %{ "lslv  $dst, $src1, $src2" %}
9579
9580  ins_encode %{
9581    __ lslv(as_Register($dst$$reg),
9582            as_Register($src1$$reg),
9583            as_Register($src2$$reg));
9584  %}
9585
9586  ins_pipe(ialu_reg_reg_vshift);
9587%}
9588
9589// Shift Left Immediate
9590instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
9591  match(Set dst (LShiftL src1 src2));
9592
9593  ins_cost(INSN_COST);
9594  format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %}
9595
9596  ins_encode %{
9597    __ lsl(as_Register($dst$$reg),
9598            as_Register($src1$$reg),
9599            $src2$$constant & 0x3f);
9600  %}
9601
9602  ins_pipe(ialu_reg_shift);
9603%}
9604
9605// Shift Right Logical Register
9606instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
9607  match(Set dst (URShiftL src1 src2));
9608
9609  ins_cost(INSN_COST * 2);
9610  format %{ "lsrv  $dst, $src1, $src2" %}
9611
9612  ins_encode %{
9613    __ lsrv(as_Register($dst$$reg),
9614            as_Register($src1$$reg),
9615            as_Register($src2$$reg));
9616  %}
9617
9618  ins_pipe(ialu_reg_reg_vshift);
9619%}
9620
9621// Shift Right Logical Immediate
9622instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
9623  match(Set dst (URShiftL src1 src2));
9624
9625  ins_cost(INSN_COST);
9626  format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %}
9627
9628  ins_encode %{
9629    __ lsr(as_Register($dst$$reg),
9630           as_Register($src1$$reg),
9631           $src2$$constant & 0x3f);
9632  %}
9633
9634  ins_pipe(ialu_reg_shift);
9635%}
9636
9637// A special-case pattern for card table stores.
9638instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{
9639  match(Set dst (URShiftL (CastP2X src1) src2));
9640
9641  ins_cost(INSN_COST);
9642  format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %}
9643
9644  ins_encode %{
9645    __ lsr(as_Register($dst$$reg),
9646           as_Register($src1$$reg),
9647           $src2$$constant & 0x3f);
9648  %}
9649
9650  ins_pipe(ialu_reg_shift);
9651%}
9652
9653// Shift Right Arithmetic Register
9654instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
9655  match(Set dst (RShiftL src1 src2));
9656
9657  ins_cost(INSN_COST * 2);
9658  format %{ "asrv  $dst, $src1, $src2" %}
9659
9660  ins_encode %{
9661    __ asrv(as_Register($dst$$reg),
9662            as_Register($src1$$reg),
9663            as_Register($src2$$reg));
9664  %}
9665
9666  ins_pipe(ialu_reg_reg_vshift);
9667%}
9668
9669// Shift Right Arithmetic Immediate
9670instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
9671  match(Set dst (RShiftL src1 src2));
9672
9673  ins_cost(INSN_COST);
9674  format %{ "asr $dst, $src1, ($src2 & 0x3f)" %}
9675
9676  ins_encode %{
9677    __ asr(as_Register($dst$$reg),
9678           as_Register($src1$$reg),
9679           $src2$$constant & 0x3f);
9680  %}
9681
9682  ins_pipe(ialu_reg_shift);
9683%}
9684
9685// BEGIN This section of the file is automatically generated. Do not edit --------------
9686
9687instruct regL_not_reg(iRegLNoSp dst,
9688                         iRegL src1, immL_M1 m1,
9689                         rFlagsReg cr) %{
9690  match(Set dst (XorL src1 m1));
9691  ins_cost(INSN_COST);
9692  format %{ "eon  $dst, $src1, zr" %}
9693
9694  ins_encode %{
9695    __ eon(as_Register($dst$$reg),
9696              as_Register($src1$$reg),
9697              zr,
9698              Assembler::LSL, 0);
9699  %}
9700
9701  ins_pipe(ialu_reg);
9702%}
9703instruct regI_not_reg(iRegINoSp dst,
9704                         iRegIorL2I src1, immI_M1 m1,
9705                         rFlagsReg cr) %{
9706  match(Set dst (XorI src1 m1));
9707  ins_cost(INSN_COST);
9708  format %{ "eonw  $dst, $src1, zr" %}
9709
9710  ins_encode %{
9711    __ eonw(as_Register($dst$$reg),
9712              as_Register($src1$$reg),
9713              zr,
9714              Assembler::LSL, 0);
9715  %}
9716
9717  ins_pipe(ialu_reg);
9718%}
9719
9720instruct AndI_reg_not_reg(iRegINoSp dst,
9721                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
9722                         rFlagsReg cr) %{
9723  match(Set dst (AndI src1 (XorI src2 m1)));
9724  ins_cost(INSN_COST);
9725  format %{ "bicw  $dst, $src1, $src2" %}
9726
9727  ins_encode %{
9728    __ bicw(as_Register($dst$$reg),
9729              as_Register($src1$$reg),
9730              as_Register($src2$$reg),
9731              Assembler::LSL, 0);
9732  %}
9733
9734  ins_pipe(ialu_reg_reg);
9735%}
9736
9737instruct AndL_reg_not_reg(iRegLNoSp dst,
9738                         iRegL src1, iRegL src2, immL_M1 m1,
9739                         rFlagsReg cr) %{
9740  match(Set dst (AndL src1 (XorL src2 m1)));
9741  ins_cost(INSN_COST);
9742  format %{ "bic  $dst, $src1, $src2" %}
9743
9744  ins_encode %{
9745    __ bic(as_Register($dst$$reg),
9746              as_Register($src1$$reg),
9747              as_Register($src2$$reg),
9748              Assembler::LSL, 0);
9749  %}
9750
9751  ins_pipe(ialu_reg_reg);
9752%}
9753
9754instruct OrI_reg_not_reg(iRegINoSp dst,
9755                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
9756                         rFlagsReg cr) %{
9757  match(Set dst (OrI src1 (XorI src2 m1)));
9758  ins_cost(INSN_COST);
9759  format %{ "ornw  $dst, $src1, $src2" %}
9760
9761  ins_encode %{
9762    __ ornw(as_Register($dst$$reg),
9763              as_Register($src1$$reg),
9764              as_Register($src2$$reg),
9765              Assembler::LSL, 0);
9766  %}
9767
9768  ins_pipe(ialu_reg_reg);
9769%}
9770
9771instruct OrL_reg_not_reg(iRegLNoSp dst,
9772                         iRegL src1, iRegL src2, immL_M1 m1,
9773                         rFlagsReg cr) %{
9774  match(Set dst (OrL src1 (XorL src2 m1)));
9775  ins_cost(INSN_COST);
9776  format %{ "orn  $dst, $src1, $src2" %}
9777
9778  ins_encode %{
9779    __ orn(as_Register($dst$$reg),
9780              as_Register($src1$$reg),
9781              as_Register($src2$$reg),
9782              Assembler::LSL, 0);
9783  %}
9784
9785  ins_pipe(ialu_reg_reg);
9786%}
9787
9788instruct XorI_reg_not_reg(iRegINoSp dst,
9789                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
9790                         rFlagsReg cr) %{
9791  match(Set dst (XorI m1 (XorI src2 src1)));
9792  ins_cost(INSN_COST);
9793  format %{ "eonw  $dst, $src1, $src2" %}
9794
9795  ins_encode %{
9796    __ eonw(as_Register($dst$$reg),
9797              as_Register($src1$$reg),
9798              as_Register($src2$$reg),
9799              Assembler::LSL, 0);
9800  %}
9801
9802  ins_pipe(ialu_reg_reg);
9803%}
9804
9805instruct XorL_reg_not_reg(iRegLNoSp dst,
9806                         iRegL src1, iRegL src2, immL_M1 m1,
9807                         rFlagsReg cr) %{
9808  match(Set dst (XorL m1 (XorL src2 src1)));
9809  ins_cost(INSN_COST);
9810  format %{ "eon  $dst, $src1, $src2" %}
9811
9812  ins_encode %{
9813    __ eon(as_Register($dst$$reg),
9814              as_Register($src1$$reg),
9815              as_Register($src2$$reg),
9816              Assembler::LSL, 0);
9817  %}
9818
9819  ins_pipe(ialu_reg_reg);
9820%}
9821
9822instruct AndI_reg_URShift_not_reg(iRegINoSp dst,
9823                         iRegIorL2I src1, iRegIorL2I src2,
9824                         immI src3, immI_M1 src4, rFlagsReg cr) %{
9825  match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4)));
9826  ins_cost(1.9 * INSN_COST);
9827  format %{ "bicw  $dst, $src1, $src2, LSR $src3" %}
9828
9829  ins_encode %{
9830    __ bicw(as_Register($dst$$reg),
9831              as_Register($src1$$reg),
9832              as_Register($src2$$reg),
9833              Assembler::LSR,
9834              $src3$$constant & 0x1f);
9835  %}
9836
9837  ins_pipe(ialu_reg_reg_shift);
9838%}
9839
9840instruct AndL_reg_URShift_not_reg(iRegLNoSp dst,
9841                         iRegL src1, iRegL src2,
9842                         immI src3, immL_M1 src4, rFlagsReg cr) %{
9843  match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4)));
9844  ins_cost(1.9 * INSN_COST);
9845  format %{ "bic  $dst, $src1, $src2, LSR $src3" %}
9846
9847  ins_encode %{
9848    __ bic(as_Register($dst$$reg),
9849              as_Register($src1$$reg),
9850              as_Register($src2$$reg),
9851              Assembler::LSR,
9852              $src3$$constant & 0x3f);
9853  %}
9854
9855  ins_pipe(ialu_reg_reg_shift);
9856%}
9857
9858instruct AndI_reg_RShift_not_reg(iRegINoSp dst,
9859                         iRegIorL2I src1, iRegIorL2I src2,
9860                         immI src3, immI_M1 src4, rFlagsReg cr) %{
9861  match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4)));
9862  ins_cost(1.9 * INSN_COST);
9863  format %{ "bicw  $dst, $src1, $src2, ASR $src3" %}
9864
9865  ins_encode %{
9866    __ bicw(as_Register($dst$$reg),
9867              as_Register($src1$$reg),
9868              as_Register($src2$$reg),
9869              Assembler::ASR,
9870              $src3$$constant & 0x1f);
9871  %}
9872
9873  ins_pipe(ialu_reg_reg_shift);
9874%}
9875
9876instruct AndL_reg_RShift_not_reg(iRegLNoSp dst,
9877                         iRegL src1, iRegL src2,
9878                         immI src3, immL_M1 src4, rFlagsReg cr) %{
9879  match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4)));
9880  ins_cost(1.9 * INSN_COST);
9881  format %{ "bic  $dst, $src1, $src2, ASR $src3" %}
9882
9883  ins_encode %{
9884    __ bic(as_Register($dst$$reg),
9885              as_Register($src1$$reg),
9886              as_Register($src2$$reg),
9887              Assembler::ASR,
9888              $src3$$constant & 0x3f);
9889  %}
9890
9891  ins_pipe(ialu_reg_reg_shift);
9892%}
9893
9894instruct AndI_reg_LShift_not_reg(iRegINoSp dst,
9895                         iRegIorL2I src1, iRegIorL2I src2,
9896                         immI src3, immI_M1 src4, rFlagsReg cr) %{
9897  match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4)));
9898  ins_cost(1.9 * INSN_COST);
9899  format %{ "bicw  $dst, $src1, $src2, LSL $src3" %}
9900
9901  ins_encode %{
9902    __ bicw(as_Register($dst$$reg),
9903              as_Register($src1$$reg),
9904              as_Register($src2$$reg),
9905              Assembler::LSL,
9906              $src3$$constant & 0x1f);
9907  %}
9908
9909  ins_pipe(ialu_reg_reg_shift);
9910%}
9911
9912instruct AndL_reg_LShift_not_reg(iRegLNoSp dst,
9913                         iRegL src1, iRegL src2,
9914                         immI src3, immL_M1 src4, rFlagsReg cr) %{
9915  match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4)));
9916  ins_cost(1.9 * INSN_COST);
9917  format %{ "bic  $dst, $src1, $src2, LSL $src3" %}
9918
9919  ins_encode %{
9920    __ bic(as_Register($dst$$reg),
9921              as_Register($src1$$reg),
9922              as_Register($src2$$reg),
9923              Assembler::LSL,
9924              $src3$$constant & 0x3f);
9925  %}
9926
9927  ins_pipe(ialu_reg_reg_shift);
9928%}
9929
9930instruct XorI_reg_URShift_not_reg(iRegINoSp dst,
9931                         iRegIorL2I src1, iRegIorL2I src2,
9932                         immI src3, immI_M1 src4, rFlagsReg cr) %{
9933  match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1)));
9934  ins_cost(1.9 * INSN_COST);
9935  format %{ "eonw  $dst, $src1, $src2, LSR $src3" %}
9936
9937  ins_encode %{
9938    __ eonw(as_Register($dst$$reg),
9939              as_Register($src1$$reg),
9940              as_Register($src2$$reg),
9941              Assembler::LSR,
9942              $src3$$constant & 0x1f);
9943  %}
9944
9945  ins_pipe(ialu_reg_reg_shift);
9946%}
9947
9948instruct XorL_reg_URShift_not_reg(iRegLNoSp dst,
9949                         iRegL src1, iRegL src2,
9950                         immI src3, immL_M1 src4, rFlagsReg cr) %{
9951  match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1)));
9952  ins_cost(1.9 * INSN_COST);
9953  format %{ "eon  $dst, $src1, $src2, LSR $src3" %}
9954
9955  ins_encode %{
9956    __ eon(as_Register($dst$$reg),
9957              as_Register($src1$$reg),
9958              as_Register($src2$$reg),
9959              Assembler::LSR,
9960              $src3$$constant & 0x3f);
9961  %}
9962
9963  ins_pipe(ialu_reg_reg_shift);
9964%}
9965
9966instruct XorI_reg_RShift_not_reg(iRegINoSp dst,
9967                         iRegIorL2I src1, iRegIorL2I src2,
9968                         immI src3, immI_M1 src4, rFlagsReg cr) %{
9969  match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1)));
9970  ins_cost(1.9 * INSN_COST);
9971  format %{ "eonw  $dst, $src1, $src2, ASR $src3" %}
9972
9973  ins_encode %{
9974    __ eonw(as_Register($dst$$reg),
9975              as_Register($src1$$reg),
9976              as_Register($src2$$reg),
9977              Assembler::ASR,
9978              $src3$$constant & 0x1f);
9979  %}
9980
9981  ins_pipe(ialu_reg_reg_shift);
9982%}
9983
9984instruct XorL_reg_RShift_not_reg(iRegLNoSp dst,
9985                         iRegL src1, iRegL src2,
9986                         immI src3, immL_M1 src4, rFlagsReg cr) %{
9987  match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1)));
9988  ins_cost(1.9 * INSN_COST);
9989  format %{ "eon  $dst, $src1, $src2, ASR $src3" %}
9990
9991  ins_encode %{
9992    __ eon(as_Register($dst$$reg),
9993              as_Register($src1$$reg),
9994              as_Register($src2$$reg),
9995              Assembler::ASR,
9996              $src3$$constant & 0x3f);
9997  %}
9998
9999  ins_pipe(ialu_reg_reg_shift);
10000%}
10001
10002instruct XorI_reg_LShift_not_reg(iRegINoSp dst,
10003                         iRegIorL2I src1, iRegIorL2I src2,
10004                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10005  match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1)));
10006  ins_cost(1.9 * INSN_COST);
10007  format %{ "eonw  $dst, $src1, $src2, LSL $src3" %}
10008
10009  ins_encode %{
10010    __ eonw(as_Register($dst$$reg),
10011              as_Register($src1$$reg),
10012              as_Register($src2$$reg),
10013              Assembler::LSL,
10014              $src3$$constant & 0x1f);
10015  %}
10016
10017  ins_pipe(ialu_reg_reg_shift);
10018%}
10019
10020instruct XorL_reg_LShift_not_reg(iRegLNoSp dst,
10021                         iRegL src1, iRegL src2,
10022                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10023  match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1)));
10024  ins_cost(1.9 * INSN_COST);
10025  format %{ "eon  $dst, $src1, $src2, LSL $src3" %}
10026
10027  ins_encode %{
10028    __ eon(as_Register($dst$$reg),
10029              as_Register($src1$$reg),
10030              as_Register($src2$$reg),
10031              Assembler::LSL,
10032              $src3$$constant & 0x3f);
10033  %}
10034
10035  ins_pipe(ialu_reg_reg_shift);
10036%}
10037
10038instruct OrI_reg_URShift_not_reg(iRegINoSp dst,
10039                         iRegIorL2I src1, iRegIorL2I src2,
10040                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10041  match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4)));
10042  ins_cost(1.9 * INSN_COST);
10043  format %{ "ornw  $dst, $src1, $src2, LSR $src3" %}
10044
10045  ins_encode %{
10046    __ ornw(as_Register($dst$$reg),
10047              as_Register($src1$$reg),
10048              as_Register($src2$$reg),
10049              Assembler::LSR,
10050              $src3$$constant & 0x1f);
10051  %}
10052
10053  ins_pipe(ialu_reg_reg_shift);
10054%}
10055
10056instruct OrL_reg_URShift_not_reg(iRegLNoSp dst,
10057                         iRegL src1, iRegL src2,
10058                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10059  match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4)));
10060  ins_cost(1.9 * INSN_COST);
10061  format %{ "orn  $dst, $src1, $src2, LSR $src3" %}
10062
10063  ins_encode %{
10064    __ orn(as_Register($dst$$reg),
10065              as_Register($src1$$reg),
10066              as_Register($src2$$reg),
10067              Assembler::LSR,
10068              $src3$$constant & 0x3f);
10069  %}
10070
10071  ins_pipe(ialu_reg_reg_shift);
10072%}
10073
10074instruct OrI_reg_RShift_not_reg(iRegINoSp dst,
10075                         iRegIorL2I src1, iRegIorL2I src2,
10076                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10077  match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4)));
10078  ins_cost(1.9 * INSN_COST);
10079  format %{ "ornw  $dst, $src1, $src2, ASR $src3" %}
10080
10081  ins_encode %{
10082    __ ornw(as_Register($dst$$reg),
10083              as_Register($src1$$reg),
10084              as_Register($src2$$reg),
10085              Assembler::ASR,
10086              $src3$$constant & 0x1f);
10087  %}
10088
10089  ins_pipe(ialu_reg_reg_shift);
10090%}
10091
10092instruct OrL_reg_RShift_not_reg(iRegLNoSp dst,
10093                         iRegL src1, iRegL src2,
10094                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10095  match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4)));
10096  ins_cost(1.9 * INSN_COST);
10097  format %{ "orn  $dst, $src1, $src2, ASR $src3" %}
10098
10099  ins_encode %{
10100    __ orn(as_Register($dst$$reg),
10101              as_Register($src1$$reg),
10102              as_Register($src2$$reg),
10103              Assembler::ASR,
10104              $src3$$constant & 0x3f);
10105  %}
10106
10107  ins_pipe(ialu_reg_reg_shift);
10108%}
10109
10110instruct OrI_reg_LShift_not_reg(iRegINoSp dst,
10111                         iRegIorL2I src1, iRegIorL2I src2,
10112                         immI src3, immI_M1 src4, rFlagsReg cr) %{
10113  match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4)));
10114  ins_cost(1.9 * INSN_COST);
10115  format %{ "ornw  $dst, $src1, $src2, LSL $src3" %}
10116
10117  ins_encode %{
10118    __ ornw(as_Register($dst$$reg),
10119              as_Register($src1$$reg),
10120              as_Register($src2$$reg),
10121              Assembler::LSL,
10122              $src3$$constant & 0x1f);
10123  %}
10124
10125  ins_pipe(ialu_reg_reg_shift);
10126%}
10127
10128instruct OrL_reg_LShift_not_reg(iRegLNoSp dst,
10129                         iRegL src1, iRegL src2,
10130                         immI src3, immL_M1 src4, rFlagsReg cr) %{
10131  match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4)));
10132  ins_cost(1.9 * INSN_COST);
10133  format %{ "orn  $dst, $src1, $src2, LSL $src3" %}
10134
10135  ins_encode %{
10136    __ orn(as_Register($dst$$reg),
10137              as_Register($src1$$reg),
10138              as_Register($src2$$reg),
10139              Assembler::LSL,
10140              $src3$$constant & 0x3f);
10141  %}
10142
10143  ins_pipe(ialu_reg_reg_shift);
10144%}
10145
10146instruct AndI_reg_URShift_reg(iRegINoSp dst,
10147                         iRegIorL2I src1, iRegIorL2I src2,
10148                         immI src3, rFlagsReg cr) %{
10149  match(Set dst (AndI src1 (URShiftI src2 src3)));
10150
10151  ins_cost(1.9 * INSN_COST);
10152  format %{ "andw  $dst, $src1, $src2, LSR $src3" %}
10153
10154  ins_encode %{
10155    __ andw(as_Register($dst$$reg),
10156              as_Register($src1$$reg),
10157              as_Register($src2$$reg),
10158              Assembler::LSR,
10159              $src3$$constant & 0x1f);
10160  %}
10161
10162  ins_pipe(ialu_reg_reg_shift);
10163%}
10164
10165instruct AndL_reg_URShift_reg(iRegLNoSp dst,
10166                         iRegL src1, iRegL src2,
10167                         immI src3, rFlagsReg cr) %{
10168  match(Set dst (AndL src1 (URShiftL src2 src3)));
10169
10170  ins_cost(1.9 * INSN_COST);
10171  format %{ "andr  $dst, $src1, $src2, LSR $src3" %}
10172
10173  ins_encode %{
10174    __ andr(as_Register($dst$$reg),
10175              as_Register($src1$$reg),
10176              as_Register($src2$$reg),
10177              Assembler::LSR,
10178              $src3$$constant & 0x3f);
10179  %}
10180
10181  ins_pipe(ialu_reg_reg_shift);
10182%}
10183
10184instruct AndI_reg_RShift_reg(iRegINoSp dst,
10185                         iRegIorL2I src1, iRegIorL2I src2,
10186                         immI src3, rFlagsReg cr) %{
10187  match(Set dst (AndI src1 (RShiftI src2 src3)));
10188
10189  ins_cost(1.9 * INSN_COST);
10190  format %{ "andw  $dst, $src1, $src2, ASR $src3" %}
10191
10192  ins_encode %{
10193    __ andw(as_Register($dst$$reg),
10194              as_Register($src1$$reg),
10195              as_Register($src2$$reg),
10196              Assembler::ASR,
10197              $src3$$constant & 0x1f);
10198  %}
10199
10200  ins_pipe(ialu_reg_reg_shift);
10201%}
10202
10203instruct AndL_reg_RShift_reg(iRegLNoSp dst,
10204                         iRegL src1, iRegL src2,
10205                         immI src3, rFlagsReg cr) %{
10206  match(Set dst (AndL src1 (RShiftL src2 src3)));
10207
10208  ins_cost(1.9 * INSN_COST);
10209  format %{ "andr  $dst, $src1, $src2, ASR $src3" %}
10210
10211  ins_encode %{
10212    __ andr(as_Register($dst$$reg),
10213              as_Register($src1$$reg),
10214              as_Register($src2$$reg),
10215              Assembler::ASR,
10216              $src3$$constant & 0x3f);
10217  %}
10218
10219  ins_pipe(ialu_reg_reg_shift);
10220%}
10221
10222instruct AndI_reg_LShift_reg(iRegINoSp dst,
10223                         iRegIorL2I src1, iRegIorL2I src2,
10224                         immI src3, rFlagsReg cr) %{
10225  match(Set dst (AndI src1 (LShiftI src2 src3)));
10226
10227  ins_cost(1.9 * INSN_COST);
10228  format %{ "andw  $dst, $src1, $src2, LSL $src3" %}
10229
10230  ins_encode %{
10231    __ andw(as_Register($dst$$reg),
10232              as_Register($src1$$reg),
10233              as_Register($src2$$reg),
10234              Assembler::LSL,
10235              $src3$$constant & 0x1f);
10236  %}
10237
10238  ins_pipe(ialu_reg_reg_shift);
10239%}
10240
10241instruct AndL_reg_LShift_reg(iRegLNoSp dst,
10242                         iRegL src1, iRegL src2,
10243                         immI src3, rFlagsReg cr) %{
10244  match(Set dst (AndL src1 (LShiftL src2 src3)));
10245
10246  ins_cost(1.9 * INSN_COST);
10247  format %{ "andr  $dst, $src1, $src2, LSL $src3" %}
10248
10249  ins_encode %{
10250    __ andr(as_Register($dst$$reg),
10251              as_Register($src1$$reg),
10252              as_Register($src2$$reg),
10253              Assembler::LSL,
10254              $src3$$constant & 0x3f);
10255  %}
10256
10257  ins_pipe(ialu_reg_reg_shift);
10258%}
10259
10260instruct XorI_reg_URShift_reg(iRegINoSp dst,
10261                         iRegIorL2I src1, iRegIorL2I src2,
10262                         immI src3, rFlagsReg cr) %{
10263  match(Set dst (XorI src1 (URShiftI src2 src3)));
10264
10265  ins_cost(1.9 * INSN_COST);
10266  format %{ "eorw  $dst, $src1, $src2, LSR $src3" %}
10267
10268  ins_encode %{
10269    __ eorw(as_Register($dst$$reg),
10270              as_Register($src1$$reg),
10271              as_Register($src2$$reg),
10272              Assembler::LSR,
10273              $src3$$constant & 0x1f);
10274  %}
10275
10276  ins_pipe(ialu_reg_reg_shift);
10277%}
10278
10279instruct XorL_reg_URShift_reg(iRegLNoSp dst,
10280                         iRegL src1, iRegL src2,
10281                         immI src3, rFlagsReg cr) %{
10282  match(Set dst (XorL src1 (URShiftL src2 src3)));
10283
10284  ins_cost(1.9 * INSN_COST);
10285  format %{ "eor  $dst, $src1, $src2, LSR $src3" %}
10286
10287  ins_encode %{
10288    __ eor(as_Register($dst$$reg),
10289              as_Register($src1$$reg),
10290              as_Register($src2$$reg),
10291              Assembler::LSR,
10292              $src3$$constant & 0x3f);
10293  %}
10294
10295  ins_pipe(ialu_reg_reg_shift);
10296%}
10297
10298instruct XorI_reg_RShift_reg(iRegINoSp dst,
10299                         iRegIorL2I src1, iRegIorL2I src2,
10300                         immI src3, rFlagsReg cr) %{
10301  match(Set dst (XorI src1 (RShiftI src2 src3)));
10302
10303  ins_cost(1.9 * INSN_COST);
10304  format %{ "eorw  $dst, $src1, $src2, ASR $src3" %}
10305
10306  ins_encode %{
10307    __ eorw(as_Register($dst$$reg),
10308              as_Register($src1$$reg),
10309              as_Register($src2$$reg),
10310              Assembler::ASR,
10311              $src3$$constant & 0x1f);
10312  %}
10313
10314  ins_pipe(ialu_reg_reg_shift);
10315%}
10316
10317instruct XorL_reg_RShift_reg(iRegLNoSp dst,
10318                         iRegL src1, iRegL src2,
10319                         immI src3, rFlagsReg cr) %{
10320  match(Set dst (XorL src1 (RShiftL src2 src3)));
10321
10322  ins_cost(1.9 * INSN_COST);
10323  format %{ "eor  $dst, $src1, $src2, ASR $src3" %}
10324
10325  ins_encode %{
10326    __ eor(as_Register($dst$$reg),
10327              as_Register($src1$$reg),
10328              as_Register($src2$$reg),
10329              Assembler::ASR,
10330              $src3$$constant & 0x3f);
10331  %}
10332
10333  ins_pipe(ialu_reg_reg_shift);
10334%}
10335
10336instruct XorI_reg_LShift_reg(iRegINoSp dst,
10337                         iRegIorL2I src1, iRegIorL2I src2,
10338                         immI src3, rFlagsReg cr) %{
10339  match(Set dst (XorI src1 (LShiftI src2 src3)));
10340
10341  ins_cost(1.9 * INSN_COST);
10342  format %{ "eorw  $dst, $src1, $src2, LSL $src3" %}
10343
10344  ins_encode %{
10345    __ eorw(as_Register($dst$$reg),
10346              as_Register($src1$$reg),
10347              as_Register($src2$$reg),
10348              Assembler::LSL,
10349              $src3$$constant & 0x1f);
10350  %}
10351
10352  ins_pipe(ialu_reg_reg_shift);
10353%}
10354
10355instruct XorL_reg_LShift_reg(iRegLNoSp dst,
10356                         iRegL src1, iRegL src2,
10357                         immI src3, rFlagsReg cr) %{
10358  match(Set dst (XorL src1 (LShiftL src2 src3)));
10359
10360  ins_cost(1.9 * INSN_COST);
10361  format %{ "eor  $dst, $src1, $src2, LSL $src3" %}
10362
10363  ins_encode %{
10364    __ eor(as_Register($dst$$reg),
10365              as_Register($src1$$reg),
10366              as_Register($src2$$reg),
10367              Assembler::LSL,
10368              $src3$$constant & 0x3f);
10369  %}
10370
10371  ins_pipe(ialu_reg_reg_shift);
10372%}
10373
10374instruct OrI_reg_URShift_reg(iRegINoSp dst,
10375                         iRegIorL2I src1, iRegIorL2I src2,
10376                         immI src3, rFlagsReg cr) %{
10377  match(Set dst (OrI src1 (URShiftI src2 src3)));
10378
10379  ins_cost(1.9 * INSN_COST);
10380  format %{ "orrw  $dst, $src1, $src2, LSR $src3" %}
10381
10382  ins_encode %{
10383    __ orrw(as_Register($dst$$reg),
10384              as_Register($src1$$reg),
10385              as_Register($src2$$reg),
10386              Assembler::LSR,
10387              $src3$$constant & 0x1f);
10388  %}
10389
10390  ins_pipe(ialu_reg_reg_shift);
10391%}
10392
10393instruct OrL_reg_URShift_reg(iRegLNoSp dst,
10394                         iRegL src1, iRegL src2,
10395                         immI src3, rFlagsReg cr) %{
10396  match(Set dst (OrL src1 (URShiftL src2 src3)));
10397
10398  ins_cost(1.9 * INSN_COST);
10399  format %{ "orr  $dst, $src1, $src2, LSR $src3" %}
10400
10401  ins_encode %{
10402    __ orr(as_Register($dst$$reg),
10403              as_Register($src1$$reg),
10404              as_Register($src2$$reg),
10405              Assembler::LSR,
10406              $src3$$constant & 0x3f);
10407  %}
10408
10409  ins_pipe(ialu_reg_reg_shift);
10410%}
10411
10412instruct OrI_reg_RShift_reg(iRegINoSp dst,
10413                         iRegIorL2I src1, iRegIorL2I src2,
10414                         immI src3, rFlagsReg cr) %{
10415  match(Set dst (OrI src1 (RShiftI src2 src3)));
10416
10417  ins_cost(1.9 * INSN_COST);
10418  format %{ "orrw  $dst, $src1, $src2, ASR $src3" %}
10419
10420  ins_encode %{
10421    __ orrw(as_Register($dst$$reg),
10422              as_Register($src1$$reg),
10423              as_Register($src2$$reg),
10424              Assembler::ASR,
10425              $src3$$constant & 0x1f);
10426  %}
10427
10428  ins_pipe(ialu_reg_reg_shift);
10429%}
10430
10431instruct OrL_reg_RShift_reg(iRegLNoSp dst,
10432                         iRegL src1, iRegL src2,
10433                         immI src3, rFlagsReg cr) %{
10434  match(Set dst (OrL src1 (RShiftL src2 src3)));
10435
10436  ins_cost(1.9 * INSN_COST);
10437  format %{ "orr  $dst, $src1, $src2, ASR $src3" %}
10438
10439  ins_encode %{
10440    __ orr(as_Register($dst$$reg),
10441              as_Register($src1$$reg),
10442              as_Register($src2$$reg),
10443              Assembler::ASR,
10444              $src3$$constant & 0x3f);
10445  %}
10446
10447  ins_pipe(ialu_reg_reg_shift);
10448%}
10449
10450instruct OrI_reg_LShift_reg(iRegINoSp dst,
10451                         iRegIorL2I src1, iRegIorL2I src2,
10452                         immI src3, rFlagsReg cr) %{
10453  match(Set dst (OrI src1 (LShiftI src2 src3)));
10454
10455  ins_cost(1.9 * INSN_COST);
10456  format %{ "orrw  $dst, $src1, $src2, LSL $src3" %}
10457
10458  ins_encode %{
10459    __ orrw(as_Register($dst$$reg),
10460              as_Register($src1$$reg),
10461              as_Register($src2$$reg),
10462              Assembler::LSL,
10463              $src3$$constant & 0x1f);
10464  %}
10465
10466  ins_pipe(ialu_reg_reg_shift);
10467%}
10468
10469instruct OrL_reg_LShift_reg(iRegLNoSp dst,
10470                         iRegL src1, iRegL src2,
10471                         immI src3, rFlagsReg cr) %{
10472  match(Set dst (OrL src1 (LShiftL src2 src3)));
10473
10474  ins_cost(1.9 * INSN_COST);
10475  format %{ "orr  $dst, $src1, $src2, LSL $src3" %}
10476
10477  ins_encode %{
10478    __ orr(as_Register($dst$$reg),
10479              as_Register($src1$$reg),
10480              as_Register($src2$$reg),
10481              Assembler::LSL,
10482              $src3$$constant & 0x3f);
10483  %}
10484
10485  ins_pipe(ialu_reg_reg_shift);
10486%}
10487
10488instruct AddI_reg_URShift_reg(iRegINoSp dst,
10489                         iRegIorL2I src1, iRegIorL2I src2,
10490                         immI src3, rFlagsReg cr) %{
10491  match(Set dst (AddI src1 (URShiftI src2 src3)));
10492
10493  ins_cost(1.9 * INSN_COST);
10494  format %{ "addw  $dst, $src1, $src2, LSR $src3" %}
10495
10496  ins_encode %{
10497    __ addw(as_Register($dst$$reg),
10498              as_Register($src1$$reg),
10499              as_Register($src2$$reg),
10500              Assembler::LSR,
10501              $src3$$constant & 0x1f);
10502  %}
10503
10504  ins_pipe(ialu_reg_reg_shift);
10505%}
10506
10507instruct AddL_reg_URShift_reg(iRegLNoSp dst,
10508                         iRegL src1, iRegL src2,
10509                         immI src3, rFlagsReg cr) %{
10510  match(Set dst (AddL src1 (URShiftL src2 src3)));
10511
10512  ins_cost(1.9 * INSN_COST);
10513  format %{ "add  $dst, $src1, $src2, LSR $src3" %}
10514
10515  ins_encode %{
10516    __ add(as_Register($dst$$reg),
10517              as_Register($src1$$reg),
10518              as_Register($src2$$reg),
10519              Assembler::LSR,
10520              $src3$$constant & 0x3f);
10521  %}
10522
10523  ins_pipe(ialu_reg_reg_shift);
10524%}
10525
10526instruct AddI_reg_RShift_reg(iRegINoSp dst,
10527                         iRegIorL2I src1, iRegIorL2I src2,
10528                         immI src3, rFlagsReg cr) %{
10529  match(Set dst (AddI src1 (RShiftI src2 src3)));
10530
10531  ins_cost(1.9 * INSN_COST);
10532  format %{ "addw  $dst, $src1, $src2, ASR $src3" %}
10533
10534  ins_encode %{
10535    __ addw(as_Register($dst$$reg),
10536              as_Register($src1$$reg),
10537              as_Register($src2$$reg),
10538              Assembler::ASR,
10539              $src3$$constant & 0x1f);
10540  %}
10541
10542  ins_pipe(ialu_reg_reg_shift);
10543%}
10544
10545instruct AddL_reg_RShift_reg(iRegLNoSp dst,
10546                         iRegL src1, iRegL src2,
10547                         immI src3, rFlagsReg cr) %{
10548  match(Set dst (AddL src1 (RShiftL src2 src3)));
10549
10550  ins_cost(1.9 * INSN_COST);
10551  format %{ "add  $dst, $src1, $src2, ASR $src3" %}
10552
10553  ins_encode %{
10554    __ add(as_Register($dst$$reg),
10555              as_Register($src1$$reg),
10556              as_Register($src2$$reg),
10557              Assembler::ASR,
10558              $src3$$constant & 0x3f);
10559  %}
10560
10561  ins_pipe(ialu_reg_reg_shift);
10562%}
10563
10564instruct AddI_reg_LShift_reg(iRegINoSp dst,
10565                         iRegIorL2I src1, iRegIorL2I src2,
10566                         immI src3, rFlagsReg cr) %{
10567  match(Set dst (AddI src1 (LShiftI src2 src3)));
10568
10569  ins_cost(1.9 * INSN_COST);
10570  format %{ "addw  $dst, $src1, $src2, LSL $src3" %}
10571
10572  ins_encode %{
10573    __ addw(as_Register($dst$$reg),
10574              as_Register($src1$$reg),
10575              as_Register($src2$$reg),
10576              Assembler::LSL,
10577              $src3$$constant & 0x1f);
10578  %}
10579
10580  ins_pipe(ialu_reg_reg_shift);
10581%}
10582
10583instruct AddL_reg_LShift_reg(iRegLNoSp dst,
10584                         iRegL src1, iRegL src2,
10585                         immI src3, rFlagsReg cr) %{
10586  match(Set dst (AddL src1 (LShiftL src2 src3)));
10587
10588  ins_cost(1.9 * INSN_COST);
10589  format %{ "add  $dst, $src1, $src2, LSL $src3" %}
10590
10591  ins_encode %{
10592    __ add(as_Register($dst$$reg),
10593              as_Register($src1$$reg),
10594              as_Register($src2$$reg),
10595              Assembler::LSL,
10596              $src3$$constant & 0x3f);
10597  %}
10598
10599  ins_pipe(ialu_reg_reg_shift);
10600%}
10601
10602instruct SubI_reg_URShift_reg(iRegINoSp dst,
10603                         iRegIorL2I src1, iRegIorL2I src2,
10604                         immI src3, rFlagsReg cr) %{
10605  match(Set dst (SubI src1 (URShiftI src2 src3)));
10606
10607  ins_cost(1.9 * INSN_COST);
10608  format %{ "subw  $dst, $src1, $src2, LSR $src3" %}
10609
10610  ins_encode %{
10611    __ subw(as_Register($dst$$reg),
10612              as_Register($src1$$reg),
10613              as_Register($src2$$reg),
10614              Assembler::LSR,
10615              $src3$$constant & 0x1f);
10616  %}
10617
10618  ins_pipe(ialu_reg_reg_shift);
10619%}
10620
10621instruct SubL_reg_URShift_reg(iRegLNoSp dst,
10622                         iRegL src1, iRegL src2,
10623                         immI src3, rFlagsReg cr) %{
10624  match(Set dst (SubL src1 (URShiftL src2 src3)));
10625
10626  ins_cost(1.9 * INSN_COST);
10627  format %{ "sub  $dst, $src1, $src2, LSR $src3" %}
10628
10629  ins_encode %{
10630    __ sub(as_Register($dst$$reg),
10631              as_Register($src1$$reg),
10632              as_Register($src2$$reg),
10633              Assembler::LSR,
10634              $src3$$constant & 0x3f);
10635  %}
10636
10637  ins_pipe(ialu_reg_reg_shift);
10638%}
10639
10640instruct SubI_reg_RShift_reg(iRegINoSp dst,
10641                         iRegIorL2I src1, iRegIorL2I src2,
10642                         immI src3, rFlagsReg cr) %{
10643  match(Set dst (SubI src1 (RShiftI src2 src3)));
10644
10645  ins_cost(1.9 * INSN_COST);
10646  format %{ "subw  $dst, $src1, $src2, ASR $src3" %}
10647
10648  ins_encode %{
10649    __ subw(as_Register($dst$$reg),
10650              as_Register($src1$$reg),
10651              as_Register($src2$$reg),
10652              Assembler::ASR,
10653              $src3$$constant & 0x1f);
10654  %}
10655
10656  ins_pipe(ialu_reg_reg_shift);
10657%}
10658
10659instruct SubL_reg_RShift_reg(iRegLNoSp dst,
10660                         iRegL src1, iRegL src2,
10661                         immI src3, rFlagsReg cr) %{
10662  match(Set dst (SubL src1 (RShiftL src2 src3)));
10663
10664  ins_cost(1.9 * INSN_COST);
10665  format %{ "sub  $dst, $src1, $src2, ASR $src3" %}
10666
10667  ins_encode %{
10668    __ sub(as_Register($dst$$reg),
10669              as_Register($src1$$reg),
10670              as_Register($src2$$reg),
10671              Assembler::ASR,
10672              $src3$$constant & 0x3f);
10673  %}
10674
10675  ins_pipe(ialu_reg_reg_shift);
10676%}
10677
10678instruct SubI_reg_LShift_reg(iRegINoSp dst,
10679                         iRegIorL2I src1, iRegIorL2I src2,
10680                         immI src3, rFlagsReg cr) %{
10681  match(Set dst (SubI src1 (LShiftI src2 src3)));
10682
10683  ins_cost(1.9 * INSN_COST);
10684  format %{ "subw  $dst, $src1, $src2, LSL $src3" %}
10685
10686  ins_encode %{
10687    __ subw(as_Register($dst$$reg),
10688              as_Register($src1$$reg),
10689              as_Register($src2$$reg),
10690              Assembler::LSL,
10691              $src3$$constant & 0x1f);
10692  %}
10693
10694  ins_pipe(ialu_reg_reg_shift);
10695%}
10696
10697instruct SubL_reg_LShift_reg(iRegLNoSp dst,
10698                         iRegL src1, iRegL src2,
10699                         immI src3, rFlagsReg cr) %{
10700  match(Set dst (SubL src1 (LShiftL src2 src3)));
10701
10702  ins_cost(1.9 * INSN_COST);
10703  format %{ "sub  $dst, $src1, $src2, LSL $src3" %}
10704
10705  ins_encode %{
10706    __ sub(as_Register($dst$$reg),
10707              as_Register($src1$$reg),
10708              as_Register($src2$$reg),
10709              Assembler::LSL,
10710              $src3$$constant & 0x3f);
10711  %}
10712
10713  ins_pipe(ialu_reg_reg_shift);
10714%}
10715
10716
10717
10718// Shift Left followed by Shift Right.
10719// This idiom is used by the compiler for the i2b bytecode etc.
10720instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
10721%{
10722  match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count));
10723  // Make sure we are not going to exceed what sbfm can do.
10724  predicate((unsigned int)n->in(2)->get_int() <= 63
10725            && (unsigned int)n->in(1)->in(2)->get_int() <= 63);
10726
10727  ins_cost(INSN_COST * 2);
10728  format %{ "sbfm  $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
10729  ins_encode %{
10730    int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
10731    int s = 63 - lshift;
10732    int r = (rshift - lshift) & 63;
10733    __ sbfm(as_Register($dst$$reg),
10734            as_Register($src$$reg),
10735            r, s);
10736  %}
10737
10738  ins_pipe(ialu_reg_shift);
10739%}
10740
10741// Shift Left followed by Shift Right.
10742// This idiom is used by the compiler for the i2b bytecode etc.
10743instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
10744%{
10745  match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count));
10746  // Make sure we are not going to exceed what sbfmw can do.
10747  predicate((unsigned int)n->in(2)->get_int() <= 31
10748            && (unsigned int)n->in(1)->in(2)->get_int() <= 31);
10749
10750  ins_cost(INSN_COST * 2);
10751  format %{ "sbfmw  $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
10752  ins_encode %{
10753    int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
10754    int s = 31 - lshift;
10755    int r = (rshift - lshift) & 31;
10756    __ sbfmw(as_Register($dst$$reg),
10757            as_Register($src$$reg),
10758            r, s);
10759  %}
10760
10761  ins_pipe(ialu_reg_shift);
10762%}
10763
10764// Shift Left followed by Shift Right.
10765// This idiom is used by the compiler for the i2b bytecode etc.
10766instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
10767%{
10768  match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count));
10769  // Make sure we are not going to exceed what ubfm can do.
10770  predicate((unsigned int)n->in(2)->get_int() <= 63
10771            && (unsigned int)n->in(1)->in(2)->get_int() <= 63);
10772
10773  ins_cost(INSN_COST * 2);
10774  format %{ "ubfm  $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
10775  ins_encode %{
10776    int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
10777    int s = 63 - lshift;
10778    int r = (rshift - lshift) & 63;
10779    __ ubfm(as_Register($dst$$reg),
10780            as_Register($src$$reg),
10781            r, s);
10782  %}
10783
10784  ins_pipe(ialu_reg_shift);
10785%}
10786
10787// Shift Left followed by Shift Right.
10788// This idiom is used by the compiler for the i2b bytecode etc.
10789instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
10790%{
10791  match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count));
10792  // Make sure we are not going to exceed what ubfmw can do.
10793  predicate((unsigned int)n->in(2)->get_int() <= 31
10794            && (unsigned int)n->in(1)->in(2)->get_int() <= 31);
10795
10796  ins_cost(INSN_COST * 2);
10797  format %{ "ubfmw  $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
10798  ins_encode %{
10799    int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
10800    int s = 31 - lshift;
10801    int r = (rshift - lshift) & 31;
10802    __ ubfmw(as_Register($dst$$reg),
10803            as_Register($src$$reg),
10804            r, s);
10805  %}
10806
10807  ins_pipe(ialu_reg_shift);
10808%}
10809// Bitfield extract with shift & mask
10810
10811instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
10812%{
10813  match(Set dst (AndI (URShiftI src rshift) mask));
10814  // Make sure we are not going to exceed what ubfxw can do.
10815  predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
10816
10817  ins_cost(INSN_COST);
10818  format %{ "ubfxw $dst, $src, $mask" %}
10819  ins_encode %{
10820    int rshift = $rshift$$constant & 31;
10821    long mask = $mask$$constant;
10822    int width = exact_log2(mask+1);
10823    __ ubfxw(as_Register($dst$$reg),
10824            as_Register($src$$reg), rshift, width);
10825  %}
10826  ins_pipe(ialu_reg_shift);
10827%}
10828instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask)
10829%{
10830  match(Set dst (AndL (URShiftL src rshift) mask));
10831  // Make sure we are not going to exceed what ubfx can do.
10832  predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1));
10833
10834  ins_cost(INSN_COST);
10835  format %{ "ubfx $dst, $src, $mask" %}
10836  ins_encode %{
10837    int rshift = $rshift$$constant & 63;
10838    long mask = $mask$$constant;
10839    int width = exact_log2_long(mask+1);
10840    __ ubfx(as_Register($dst$$reg),
10841            as_Register($src$$reg), rshift, width);
10842  %}
10843  ins_pipe(ialu_reg_shift);
10844%}
10845
10846// We can use ubfx when extending an And with a mask when we know mask
10847// is positive.  We know that because immI_bitmask guarantees it.
10848instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
10849%{
10850  match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
10851  // Make sure we are not going to exceed what ubfxw can do.
10852  predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
10853
10854  ins_cost(INSN_COST * 2);
10855  format %{ "ubfx $dst, $src, $mask" %}
10856  ins_encode %{
10857    int rshift = $rshift$$constant & 31;
10858    long mask = $mask$$constant;
10859    int width = exact_log2(mask+1);
10860    __ ubfx(as_Register($dst$$reg),
10861            as_Register($src$$reg), rshift, width);
10862  %}
10863  ins_pipe(ialu_reg_shift);
10864%}
10865
10866// Rotations
10867
10868instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
10869%{
10870  match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift)));
10871  predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63));
10872
10873  ins_cost(INSN_COST);
10874  format %{ "extr $dst, $src1, $src2, #$rshift" %}
10875
10876  ins_encode %{
10877    __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
10878            $rshift$$constant & 63);
10879  %}
10880  ins_pipe(ialu_reg_reg_extr);
10881%}
10882
10883instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
10884%{
10885  match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift)));
10886  predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31));
10887
10888  ins_cost(INSN_COST);
10889  format %{ "extr $dst, $src1, $src2, #$rshift" %}
10890
10891  ins_encode %{
10892    __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
10893            $rshift$$constant & 31);
10894  %}
10895  ins_pipe(ialu_reg_reg_extr);
10896%}
10897
10898instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
10899%{
10900  match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift)));
10901  predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63));
10902
10903  ins_cost(INSN_COST);
10904  format %{ "extr $dst, $src1, $src2, #$rshift" %}
10905
10906  ins_encode %{
10907    __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
10908            $rshift$$constant & 63);
10909  %}
10910  ins_pipe(ialu_reg_reg_extr);
10911%}
10912
10913instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
10914%{
10915  match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift)));
10916  predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31));
10917
10918  ins_cost(INSN_COST);
10919  format %{ "extr $dst, $src1, $src2, #$rshift" %}
10920
10921  ins_encode %{
10922    __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
10923            $rshift$$constant & 31);
10924  %}
10925  ins_pipe(ialu_reg_reg_extr);
10926%}
10927
10928
10929// rol expander
10930
10931instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr)
10932%{
10933  effect(DEF dst, USE src, USE shift);
10934
10935  format %{ "rol    $dst, $src, $shift" %}
10936  ins_cost(INSN_COST * 3);
10937  ins_encode %{
10938    __ subw(rscratch1, zr, as_Register($shift$$reg));
10939    __ rorv(as_Register($dst$$reg), as_Register($src$$reg),
10940            rscratch1);
10941    %}
10942  ins_pipe(ialu_reg_reg_vshift);
10943%}
10944
10945// rol expander
10946
10947instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr)
10948%{
10949  effect(DEF dst, USE src, USE shift);
10950
10951  format %{ "rol    $dst, $src, $shift" %}
10952  ins_cost(INSN_COST * 3);
10953  ins_encode %{
10954    __ subw(rscratch1, zr, as_Register($shift$$reg));
10955    __ rorvw(as_Register($dst$$reg), as_Register($src$$reg),
10956            rscratch1);
10957    %}
10958  ins_pipe(ialu_reg_reg_vshift);
10959%}
10960
10961instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr)
10962%{
10963  match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift))));
10964
10965  expand %{
10966    rolL_rReg(dst, src, shift, cr);
10967  %}
10968%}
10969
10970instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr)
10971%{
10972  match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift))));
10973
10974  expand %{
10975    rolL_rReg(dst, src, shift, cr);
10976  %}
10977%}
10978
10979instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr)
10980%{
10981  match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift))));
10982
10983  expand %{
10984    rolI_rReg(dst, src, shift, cr);
10985  %}
10986%}
10987
10988instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr)
10989%{
10990  match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift))));
10991
10992  expand %{
10993    rolI_rReg(dst, src, shift, cr);
10994  %}
10995%}
10996
10997// ror expander
10998
10999instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr)
11000%{
11001  effect(DEF dst, USE src, USE shift);
11002
11003  format %{ "ror    $dst, $src, $shift" %}
11004  ins_cost(INSN_COST);
11005  ins_encode %{
11006    __ rorv(as_Register($dst$$reg), as_Register($src$$reg),
11007            as_Register($shift$$reg));
11008    %}
11009  ins_pipe(ialu_reg_reg_vshift);
11010%}
11011
11012// ror expander
11013
11014instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr)
11015%{
11016  effect(DEF dst, USE src, USE shift);
11017
11018  format %{ "ror    $dst, $src, $shift" %}
11019  ins_cost(INSN_COST);
11020  ins_encode %{
11021    __ rorvw(as_Register($dst$$reg), as_Register($src$$reg),
11022            as_Register($shift$$reg));
11023    %}
11024  ins_pipe(ialu_reg_reg_vshift);
11025%}
11026
11027instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr)
11028%{
11029  match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift))));
11030
11031  expand %{
11032    rorL_rReg(dst, src, shift, cr);
11033  %}
11034%}
11035
11036instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr)
11037%{
11038  match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift))));
11039
11040  expand %{
11041    rorL_rReg(dst, src, shift, cr);
11042  %}
11043%}
11044
11045instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr)
11046%{
11047  match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift))));
11048
11049  expand %{
11050    rorI_rReg(dst, src, shift, cr);
11051  %}
11052%}
11053
11054instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr)
11055%{
11056  match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift))));
11057
11058  expand %{
11059    rorI_rReg(dst, src, shift, cr);
11060  %}
11061%}
11062
11063// Add/subtract (extended)
11064
11065instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
11066%{
11067  match(Set dst (AddL src1 (ConvI2L src2)));
11068  ins_cost(INSN_COST);
11069  format %{ "add  $dst, $src1, sxtw $src2" %}
11070
11071   ins_encode %{
11072     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11073            as_Register($src2$$reg), ext::sxtw);
11074   %}
11075  ins_pipe(ialu_reg_reg);
11076%};
11077
11078instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
11079%{
11080  match(Set dst (SubL src1 (ConvI2L src2)));
11081  ins_cost(INSN_COST);
11082  format %{ "sub  $dst, $src1, sxtw $src2" %}
11083
11084   ins_encode %{
11085     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
11086            as_Register($src2$$reg), ext::sxtw);
11087   %}
11088  ins_pipe(ialu_reg_reg);
11089%};
11090
11091
11092instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr)
11093%{
11094  match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
11095  ins_cost(INSN_COST);
11096  format %{ "add  $dst, $src1, sxth $src2" %}
11097
11098   ins_encode %{
11099     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11100            as_Register($src2$$reg), ext::sxth);
11101   %}
11102  ins_pipe(ialu_reg_reg);
11103%}
11104
11105instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
11106%{
11107  match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
11108  ins_cost(INSN_COST);
11109  format %{ "add  $dst, $src1, sxtb $src2" %}
11110
11111   ins_encode %{
11112     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11113            as_Register($src2$$reg), ext::sxtb);
11114   %}
11115  ins_pipe(ialu_reg_reg);
11116%}
11117
11118instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
11119%{
11120  match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift)));
11121  ins_cost(INSN_COST);
11122  format %{ "add  $dst, $src1, uxtb $src2" %}
11123
11124   ins_encode %{
11125     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11126            as_Register($src2$$reg), ext::uxtb);
11127   %}
11128  ins_pipe(ialu_reg_reg);
11129%}
11130
11131instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr)
11132%{
11133  match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
11134  ins_cost(INSN_COST);
11135  format %{ "add  $dst, $src1, sxth $src2" %}
11136
11137   ins_encode %{
11138     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11139            as_Register($src2$$reg), ext::sxth);
11140   %}
11141  ins_pipe(ialu_reg_reg);
11142%}
11143
11144instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr)
11145%{
11146  match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
11147  ins_cost(INSN_COST);
11148  format %{ "add  $dst, $src1, sxtw $src2" %}
11149
11150   ins_encode %{
11151     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11152            as_Register($src2$$reg), ext::sxtw);
11153   %}
11154  ins_pipe(ialu_reg_reg);
11155%}
11156
11157instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
11158%{
11159  match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
11160  ins_cost(INSN_COST);
11161  format %{ "add  $dst, $src1, sxtb $src2" %}
11162
11163   ins_encode %{
11164     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11165            as_Register($src2$$reg), ext::sxtb);
11166   %}
11167  ins_pipe(ialu_reg_reg);
11168%}
11169
11170instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
11171%{
11172  match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift)));
11173  ins_cost(INSN_COST);
11174  format %{ "add  $dst, $src1, uxtb $src2" %}
11175
11176   ins_encode %{
11177     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11178            as_Register($src2$$reg), ext::uxtb);
11179   %}
11180  ins_pipe(ialu_reg_reg);
11181%}
11182
11183
11184instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
11185%{
11186  match(Set dst (AddI src1 (AndI src2 mask)));
11187  ins_cost(INSN_COST);
11188  format %{ "addw  $dst, $src1, $src2, uxtb" %}
11189
11190   ins_encode %{
11191     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
11192            as_Register($src2$$reg), ext::uxtb);
11193   %}
11194  ins_pipe(ialu_reg_reg);
11195%}
11196
11197instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
11198%{
11199  match(Set dst (AddI src1 (AndI src2 mask)));
11200  ins_cost(INSN_COST);
11201  format %{ "addw  $dst, $src1, $src2, uxth" %}
11202
11203   ins_encode %{
11204     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
11205            as_Register($src2$$reg), ext::uxth);
11206   %}
11207  ins_pipe(ialu_reg_reg);
11208%}
11209
11210instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
11211%{
11212  match(Set dst (AddL src1 (AndL src2 mask)));
11213  ins_cost(INSN_COST);
11214  format %{ "add  $dst, $src1, $src2, uxtb" %}
11215
11216   ins_encode %{
11217     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11218            as_Register($src2$$reg), ext::uxtb);
11219   %}
11220  ins_pipe(ialu_reg_reg);
11221%}
11222
11223instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
11224%{
11225  match(Set dst (AddL src1 (AndL src2 mask)));
11226  ins_cost(INSN_COST);
11227  format %{ "add  $dst, $src1, $src2, uxth" %}
11228
11229   ins_encode %{
11230     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11231            as_Register($src2$$reg), ext::uxth);
11232   %}
11233  ins_pipe(ialu_reg_reg);
11234%}
11235
11236instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
11237%{
11238  match(Set dst (AddL src1 (AndL src2 mask)));
11239  ins_cost(INSN_COST);
11240  format %{ "add  $dst, $src1, $src2, uxtw" %}
11241
11242   ins_encode %{
11243     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11244            as_Register($src2$$reg), ext::uxtw);
11245   %}
11246  ins_pipe(ialu_reg_reg);
11247%}
11248
11249instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
11250%{
11251  match(Set dst (SubI src1 (AndI src2 mask)));
11252  ins_cost(INSN_COST);
11253  format %{ "subw  $dst, $src1, $src2, uxtb" %}
11254
11255   ins_encode %{
11256     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
11257            as_Register($src2$$reg), ext::uxtb);
11258   %}
11259  ins_pipe(ialu_reg_reg);
11260%}
11261
11262instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
11263%{
11264  match(Set dst (SubI src1 (AndI src2 mask)));
11265  ins_cost(INSN_COST);
11266  format %{ "subw  $dst, $src1, $src2, uxth" %}
11267
11268   ins_encode %{
11269     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
11270            as_Register($src2$$reg), ext::uxth);
11271   %}
11272  ins_pipe(ialu_reg_reg);
11273%}
11274
11275instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
11276%{
11277  match(Set dst (SubL src1 (AndL src2 mask)));
11278  ins_cost(INSN_COST);
11279  format %{ "sub  $dst, $src1, $src2, uxtb" %}
11280
11281   ins_encode %{
11282     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
11283            as_Register($src2$$reg), ext::uxtb);
11284   %}
11285  ins_pipe(ialu_reg_reg);
11286%}
11287
11288instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
11289%{
11290  match(Set dst (SubL src1 (AndL src2 mask)));
11291  ins_cost(INSN_COST);
11292  format %{ "sub  $dst, $src1, $src2, uxth" %}
11293
11294   ins_encode %{
11295     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
11296            as_Register($src2$$reg), ext::uxth);
11297   %}
11298  ins_pipe(ialu_reg_reg);
11299%}
11300
11301instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
11302%{
11303  match(Set dst (SubL src1 (AndL src2 mask)));
11304  ins_cost(INSN_COST);
11305  format %{ "sub  $dst, $src1, $src2, uxtw" %}
11306
11307   ins_encode %{
11308     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
11309            as_Register($src2$$reg), ext::uxtw);
11310   %}
11311  ins_pipe(ialu_reg_reg);
11312%}
11313
11314// END This section of the file is automatically generated. Do not edit --------------
11315
11316// ============================================================================
11317// Floating Point Arithmetic Instructions
11318
11319instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
11320  match(Set dst (AddF src1 src2));
11321
11322  ins_cost(INSN_COST * 5);
11323  format %{ "fadds   $dst, $src1, $src2" %}
11324
11325  ins_encode %{
11326    __ fadds(as_FloatRegister($dst$$reg),
11327             as_FloatRegister($src1$$reg),
11328             as_FloatRegister($src2$$reg));
11329  %}
11330
11331  ins_pipe(fp_dop_reg_reg_s);
11332%}
11333
11334instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
11335  match(Set dst (AddD src1 src2));
11336
11337  ins_cost(INSN_COST * 5);
11338  format %{ "faddd   $dst, $src1, $src2" %}
11339
11340  ins_encode %{
11341    __ faddd(as_FloatRegister($dst$$reg),
11342             as_FloatRegister($src1$$reg),
11343             as_FloatRegister($src2$$reg));
11344  %}
11345
11346  ins_pipe(fp_dop_reg_reg_d);
11347%}
11348
11349instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
11350  match(Set dst (SubF src1 src2));
11351
11352  ins_cost(INSN_COST * 5);
11353  format %{ "fsubs   $dst, $src1, $src2" %}
11354
11355  ins_encode %{
11356    __ fsubs(as_FloatRegister($dst$$reg),
11357             as_FloatRegister($src1$$reg),
11358             as_FloatRegister($src2$$reg));
11359  %}
11360
11361  ins_pipe(fp_dop_reg_reg_s);
11362%}
11363
11364instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
11365  match(Set dst (SubD src1 src2));
11366
11367  ins_cost(INSN_COST * 5);
11368  format %{ "fsubd   $dst, $src1, $src2" %}
11369
11370  ins_encode %{
11371    __ fsubd(as_FloatRegister($dst$$reg),
11372             as_FloatRegister($src1$$reg),
11373             as_FloatRegister($src2$$reg));
11374  %}
11375
11376  ins_pipe(fp_dop_reg_reg_d);
11377%}
11378
11379instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
11380  match(Set dst (MulF src1 src2));
11381
11382  ins_cost(INSN_COST * 6);
11383  format %{ "fmuls   $dst, $src1, $src2" %}
11384
11385  ins_encode %{
11386    __ fmuls(as_FloatRegister($dst$$reg),
11387             as_FloatRegister($src1$$reg),
11388             as_FloatRegister($src2$$reg));
11389  %}
11390
11391  ins_pipe(fp_dop_reg_reg_s);
11392%}
11393
11394instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
11395  match(Set dst (MulD src1 src2));
11396
11397  ins_cost(INSN_COST * 6);
11398  format %{ "fmuld   $dst, $src1, $src2" %}
11399
11400  ins_encode %{
11401    __ fmuld(as_FloatRegister($dst$$reg),
11402             as_FloatRegister($src1$$reg),
11403             as_FloatRegister($src2$$reg));
11404  %}
11405
11406  ins_pipe(fp_dop_reg_reg_d);
11407%}
11408
11409// We cannot use these fused mul w add/sub ops because they don't
11410// produce the same result as the equivalent separated ops
11411// (essentially they don't round the intermediate result). that's a
11412// shame. leaving them here in case we can idenitfy cases where it is
11413// legitimate to use them
11414
11415
11416// instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
11417//   match(Set dst (AddF (MulF src1 src2) src3));
11418
11419//   format %{ "fmadds   $dst, $src1, $src2, $src3" %}
11420
11421//   ins_encode %{
11422//     __ fmadds(as_FloatRegister($dst$$reg),
11423//              as_FloatRegister($src1$$reg),
11424//              as_FloatRegister($src2$$reg),
11425//              as_FloatRegister($src3$$reg));
11426//   %}
11427
11428//   ins_pipe(pipe_class_default);
11429// %}
11430
11431// instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
11432//   match(Set dst (AddD (MulD src1 src2) src3));
11433
11434//   format %{ "fmaddd   $dst, $src1, $src2, $src3" %}
11435
11436//   ins_encode %{
11437//     __ fmaddd(as_FloatRegister($dst$$reg),
11438//              as_FloatRegister($src1$$reg),
11439//              as_FloatRegister($src2$$reg),
11440//              as_FloatRegister($src3$$reg));
11441//   %}
11442
11443//   ins_pipe(pipe_class_default);
11444// %}
11445
11446// instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
11447//   match(Set dst (AddF (MulF (NegF src1) src2) src3));
11448//   match(Set dst (AddF (NegF (MulF src1 src2)) src3));
11449
11450//   format %{ "fmsubs   $dst, $src1, $src2, $src3" %}
11451
11452//   ins_encode %{
11453//     __ fmsubs(as_FloatRegister($dst$$reg),
11454//               as_FloatRegister($src1$$reg),
11455//               as_FloatRegister($src2$$reg),
11456//              as_FloatRegister($src3$$reg));
11457//   %}
11458
11459//   ins_pipe(pipe_class_default);
11460// %}
11461
11462// instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
11463//   match(Set dst (AddD (MulD (NegD src1) src2) src3));
11464//   match(Set dst (AddD (NegD (MulD src1 src2)) src3));
11465
11466//   format %{ "fmsubd   $dst, $src1, $src2, $src3" %}
11467
11468//   ins_encode %{
11469//     __ fmsubd(as_FloatRegister($dst$$reg),
11470//               as_FloatRegister($src1$$reg),
11471//               as_FloatRegister($src2$$reg),
11472//               as_FloatRegister($src3$$reg));
11473//   %}
11474
11475//   ins_pipe(pipe_class_default);
11476// %}
11477
11478// instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
11479//   match(Set dst (SubF (MulF (NegF src1) src2) src3));
11480//   match(Set dst (SubF (NegF (MulF src1 src2)) src3));
11481
11482//   format %{ "fnmadds  $dst, $src1, $src2, $src3" %}
11483
11484//   ins_encode %{
11485//     __ fnmadds(as_FloatRegister($dst$$reg),
11486//                as_FloatRegister($src1$$reg),
11487//                as_FloatRegister($src2$$reg),
11488//                as_FloatRegister($src3$$reg));
11489//   %}
11490
11491//   ins_pipe(pipe_class_default);
11492// %}
11493
11494// instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
11495//   match(Set dst (SubD (MulD (NegD src1) src2) src3));
11496//   match(Set dst (SubD (NegD (MulD src1 src2)) src3));
11497
11498//   format %{ "fnmaddd   $dst, $src1, $src2, $src3" %}
11499
11500//   ins_encode %{
11501//     __ fnmaddd(as_FloatRegister($dst$$reg),
11502//                as_FloatRegister($src1$$reg),
11503//                as_FloatRegister($src2$$reg),
11504//                as_FloatRegister($src3$$reg));
11505//   %}
11506
11507//   ins_pipe(pipe_class_default);
11508// %}
11509
11510// instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{
11511//   match(Set dst (SubF (MulF src1 src2) src3));
11512
11513//   format %{ "fnmsubs  $dst, $src1, $src2, $src3" %}
11514
11515//   ins_encode %{
11516//     __ fnmsubs(as_FloatRegister($dst$$reg),
11517//                as_FloatRegister($src1$$reg),
11518//                as_FloatRegister($src2$$reg),
11519//                as_FloatRegister($src3$$reg));
11520//   %}
11521
11522//   ins_pipe(pipe_class_default);
11523// %}
11524
11525// instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{
11526//   match(Set dst (SubD (MulD src1 src2) src3));
11527
11528//   format %{ "fnmsubd   $dst, $src1, $src2, $src3" %}
11529
11530//   ins_encode %{
11531//   // n.b. insn name should be fnmsubd
11532//     __ fnmsub(as_FloatRegister($dst$$reg),
11533//                as_FloatRegister($src1$$reg),
11534//                as_FloatRegister($src2$$reg),
11535//                as_FloatRegister($src3$$reg));
11536//   %}
11537
11538//   ins_pipe(pipe_class_default);
11539// %}
11540
11541
11542instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
11543  match(Set dst (DivF src1  src2));
11544
11545  ins_cost(INSN_COST * 18);
11546  format %{ "fdivs   $dst, $src1, $src2" %}
11547
11548  ins_encode %{
11549    __ fdivs(as_FloatRegister($dst$$reg),
11550             as_FloatRegister($src1$$reg),
11551             as_FloatRegister($src2$$reg));
11552  %}
11553
11554  ins_pipe(fp_div_s);
11555%}
11556
11557instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
11558  match(Set dst (DivD src1  src2));
11559
11560  ins_cost(INSN_COST * 32);
11561  format %{ "fdivd   $dst, $src1, $src2" %}
11562
11563  ins_encode %{
11564    __ fdivd(as_FloatRegister($dst$$reg),
11565             as_FloatRegister($src1$$reg),
11566             as_FloatRegister($src2$$reg));
11567  %}
11568
11569  ins_pipe(fp_div_d);
11570%}
11571
11572instruct negF_reg_reg(vRegF dst, vRegF src) %{
11573  match(Set dst (NegF src));
11574
11575  ins_cost(INSN_COST * 3);
11576  format %{ "fneg   $dst, $src" %}
11577
11578  ins_encode %{
11579    __ fnegs(as_FloatRegister($dst$$reg),
11580             as_FloatRegister($src$$reg));
11581  %}
11582
11583  ins_pipe(fp_uop_s);
11584%}
11585
11586instruct negD_reg_reg(vRegD dst, vRegD src) %{
11587  match(Set dst (NegD src));
11588
11589  ins_cost(INSN_COST * 3);
11590  format %{ "fnegd   $dst, $src" %}
11591
11592  ins_encode %{
11593    __ fnegd(as_FloatRegister($dst$$reg),
11594             as_FloatRegister($src$$reg));
11595  %}
11596
11597  ins_pipe(fp_uop_d);
11598%}
11599
11600instruct absF_reg(vRegF dst, vRegF src) %{
11601  match(Set dst (AbsF src));
11602
11603  ins_cost(INSN_COST * 3);
11604  format %{ "fabss   $dst, $src" %}
11605  ins_encode %{
11606    __ fabss(as_FloatRegister($dst$$reg),
11607             as_FloatRegister($src$$reg));
11608  %}
11609
11610  ins_pipe(fp_uop_s);
11611%}
11612
11613instruct absD_reg(vRegD dst, vRegD src) %{
11614  match(Set dst (AbsD src));
11615
11616  ins_cost(INSN_COST * 3);
11617  format %{ "fabsd   $dst, $src" %}
11618  ins_encode %{
11619    __ fabsd(as_FloatRegister($dst$$reg),
11620             as_FloatRegister($src$$reg));
11621  %}
11622
11623  ins_pipe(fp_uop_d);
11624%}
11625
11626instruct sqrtD_reg(vRegD dst, vRegD src) %{
11627  match(Set dst (SqrtD src));
11628
11629  ins_cost(INSN_COST * 50);
11630  format %{ "fsqrtd  $dst, $src" %}
11631  ins_encode %{
11632    __ fsqrtd(as_FloatRegister($dst$$reg),
11633             as_FloatRegister($src$$reg));
11634  %}
11635
11636  ins_pipe(fp_div_s);
11637%}
11638
11639instruct sqrtF_reg(vRegF dst, vRegF src) %{
11640  match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
11641
11642  ins_cost(INSN_COST * 50);
11643  format %{ "fsqrts  $dst, $src" %}
11644  ins_encode %{
11645    __ fsqrts(as_FloatRegister($dst$$reg),
11646             as_FloatRegister($src$$reg));
11647  %}
11648
11649  ins_pipe(fp_div_d);
11650%}
11651
11652// ============================================================================
11653// Logical Instructions
11654
11655// Integer Logical Instructions
11656
11657// And Instructions
11658
11659
11660instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{
11661  match(Set dst (AndI src1 src2));
11662
11663  format %{ "andw  $dst, $src1, $src2\t# int" %}
11664
11665  ins_cost(INSN_COST);
11666  ins_encode %{
11667    __ andw(as_Register($dst$$reg),
11668	    as_Register($src1$$reg),
11669	    as_Register($src2$$reg));
11670  %}
11671
11672  ins_pipe(ialu_reg_reg);
11673%}
11674
11675instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{
11676  match(Set dst (AndI src1 src2));
11677
11678  format %{ "andsw  $dst, $src1, $src2\t# int" %}
11679
11680  ins_cost(INSN_COST);
11681  ins_encode %{
11682    __ andw(as_Register($dst$$reg),
11683	    as_Register($src1$$reg),
11684	    (unsigned long)($src2$$constant));
11685  %}
11686
11687  ins_pipe(ialu_reg_imm);
11688%}
11689
11690// Or Instructions
11691
11692instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
11693  match(Set dst (OrI src1 src2));
11694
11695  format %{ "orrw  $dst, $src1, $src2\t# int" %}
11696
11697  ins_cost(INSN_COST);
11698  ins_encode %{
11699    __ orrw(as_Register($dst$$reg),
11700            as_Register($src1$$reg),
11701            as_Register($src2$$reg));
11702  %}
11703
11704  ins_pipe(ialu_reg_reg);
11705%}
11706
11707instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
11708  match(Set dst (OrI src1 src2));
11709
11710  format %{ "orrw  $dst, $src1, $src2\t# int" %}
11711
11712  ins_cost(INSN_COST);
11713  ins_encode %{
11714    __ orrw(as_Register($dst$$reg),
11715            as_Register($src1$$reg),
11716            (unsigned long)($src2$$constant));
11717  %}
11718
11719  ins_pipe(ialu_reg_imm);
11720%}
11721
11722// Xor Instructions
11723
11724instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
11725  match(Set dst (XorI src1 src2));
11726
11727  format %{ "eorw  $dst, $src1, $src2\t# int" %}
11728
11729  ins_cost(INSN_COST);
11730  ins_encode %{
11731    __ eorw(as_Register($dst$$reg),
11732            as_Register($src1$$reg),
11733            as_Register($src2$$reg));
11734  %}
11735
11736  ins_pipe(ialu_reg_reg);
11737%}
11738
11739instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
11740  match(Set dst (XorI src1 src2));
11741
11742  format %{ "eorw  $dst, $src1, $src2\t# int" %}
11743
11744  ins_cost(INSN_COST);
11745  ins_encode %{
11746    __ eorw(as_Register($dst$$reg),
11747            as_Register($src1$$reg),
11748            (unsigned long)($src2$$constant));
11749  %}
11750
11751  ins_pipe(ialu_reg_imm);
11752%}
11753
11754// Long Logical Instructions
11755// TODO
11756
11757instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{
11758  match(Set dst (AndL src1 src2));
11759
11760  format %{ "and  $dst, $src1, $src2\t# int" %}
11761
11762  ins_cost(INSN_COST);
11763  ins_encode %{
11764    __ andr(as_Register($dst$$reg),
11765	    as_Register($src1$$reg),
11766	    as_Register($src2$$reg));
11767  %}
11768
11769  ins_pipe(ialu_reg_reg);
11770%}
11771
11772instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{
11773  match(Set dst (AndL src1 src2));
11774
11775  format %{ "and  $dst, $src1, $src2\t# int" %}
11776
11777  ins_cost(INSN_COST);
11778  ins_encode %{
11779    __ andr(as_Register($dst$$reg),
11780            as_Register($src1$$reg),
11781            (unsigned long)($src2$$constant));
11782  %}
11783
11784  ins_pipe(ialu_reg_imm);
11785%}
11786
11787// Or Instructions
11788
11789instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
11790  match(Set dst (OrL src1 src2));
11791
11792  format %{ "orr  $dst, $src1, $src2\t# int" %}
11793
11794  ins_cost(INSN_COST);
11795  ins_encode %{
11796    __ orr(as_Register($dst$$reg),
11797           as_Register($src1$$reg),
11798           as_Register($src2$$reg));
11799  %}
11800
11801  ins_pipe(ialu_reg_reg);
11802%}
11803
11804instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
11805  match(Set dst (OrL src1 src2));
11806
11807  format %{ "orr  $dst, $src1, $src2\t# int" %}
11808
11809  ins_cost(INSN_COST);
11810  ins_encode %{
11811    __ orr(as_Register($dst$$reg),
11812           as_Register($src1$$reg),
11813           (unsigned long)($src2$$constant));
11814  %}
11815
11816  ins_pipe(ialu_reg_imm);
11817%}
11818
11819// Xor Instructions
11820
11821instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
11822  match(Set dst (XorL src1 src2));
11823
11824  format %{ "eor  $dst, $src1, $src2\t# int" %}
11825
11826  ins_cost(INSN_COST);
11827  ins_encode %{
11828    __ eor(as_Register($dst$$reg),
11829           as_Register($src1$$reg),
11830           as_Register($src2$$reg));
11831  %}
11832
11833  ins_pipe(ialu_reg_reg);
11834%}
11835
11836instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
11837  match(Set dst (XorL src1 src2));
11838
11839  ins_cost(INSN_COST);
11840  format %{ "eor  $dst, $src1, $src2\t# int" %}
11841
11842  ins_encode %{
11843    __ eor(as_Register($dst$$reg),
11844           as_Register($src1$$reg),
11845           (unsigned long)($src2$$constant));
11846  %}
11847
11848  ins_pipe(ialu_reg_imm);
11849%}
11850
11851instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src)
11852%{
11853  match(Set dst (ConvI2L src));
11854
11855  ins_cost(INSN_COST);
11856  format %{ "sxtw  $dst, $src\t# i2l" %}
11857  ins_encode %{
11858    __ sbfm($dst$$Register, $src$$Register, 0, 31);
11859  %}
11860  ins_pipe(ialu_reg_shift);
11861%}
11862
11863// this pattern occurs in bigmath arithmetic
11864instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask)
11865%{
11866  match(Set dst (AndL (ConvI2L src) mask));
11867
11868  ins_cost(INSN_COST);
11869  format %{ "ubfm  $dst, $src, 0, 31\t# ui2l" %}
11870  ins_encode %{
11871    __ ubfm($dst$$Register, $src$$Register, 0, 31);
11872  %}
11873
11874  ins_pipe(ialu_reg_shift);
11875%}
11876
11877instruct convL2I_reg(iRegINoSp dst, iRegL src) %{
11878  match(Set dst (ConvL2I src));
11879
11880  ins_cost(INSN_COST);
11881  format %{ "movw  $dst, $src \t// l2i" %}
11882
11883  ins_encode %{
11884    __ movw(as_Register($dst$$reg), as_Register($src$$reg));
11885  %}
11886
11887  ins_pipe(ialu_reg);
11888%}
11889
11890instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr)
11891%{
11892  match(Set dst (Conv2B src));
11893  effect(KILL cr);
11894
11895  format %{
11896    "cmpw $src, zr\n\t"
11897    "cset $dst, ne"
11898  %}
11899
11900  ins_encode %{
11901    __ cmpw(as_Register($src$$reg), zr);
11902    __ cset(as_Register($dst$$reg), Assembler::NE);
11903  %}
11904
11905  ins_pipe(ialu_reg);
11906%}
11907
11908instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr)
11909%{
11910  match(Set dst (Conv2B src));
11911  effect(KILL cr);
11912
11913  format %{
11914    "cmp  $src, zr\n\t"
11915    "cset $dst, ne"
11916  %}
11917
11918  ins_encode %{
11919    __ cmp(as_Register($src$$reg), zr);
11920    __ cset(as_Register($dst$$reg), Assembler::NE);
11921  %}
11922
11923  ins_pipe(ialu_reg);
11924%}
11925
11926instruct convD2F_reg(vRegF dst, vRegD src) %{
11927  match(Set dst (ConvD2F src));
11928
11929  ins_cost(INSN_COST * 5);
11930  format %{ "fcvtd  $dst, $src \t// d2f" %}
11931
11932  ins_encode %{
11933    __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
11934  %}
11935
11936  ins_pipe(fp_d2f);
11937%}
11938
11939instruct convF2D_reg(vRegD dst, vRegF src) %{
11940  match(Set dst (ConvF2D src));
11941
11942  ins_cost(INSN_COST * 5);
11943  format %{ "fcvts  $dst, $src \t// f2d" %}
11944
11945  ins_encode %{
11946    __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
11947  %}
11948
11949  ins_pipe(fp_f2d);
11950%}
11951
11952instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{
11953  match(Set dst (ConvF2I src));
11954
11955  ins_cost(INSN_COST * 5);
11956  format %{ "fcvtzsw  $dst, $src \t// f2i" %}
11957
11958  ins_encode %{
11959    __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
11960  %}
11961
11962  ins_pipe(fp_f2i);
11963%}
11964
11965instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{
11966  match(Set dst (ConvF2L src));
11967
11968  ins_cost(INSN_COST * 5);
11969  format %{ "fcvtzs  $dst, $src \t// f2l" %}
11970
11971  ins_encode %{
11972    __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg));
11973  %}
11974
11975  ins_pipe(fp_f2l);
11976%}
11977
11978instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{
11979  match(Set dst (ConvI2F src));
11980
11981  ins_cost(INSN_COST * 5);
11982  format %{ "scvtfws  $dst, $src \t// i2f" %}
11983
11984  ins_encode %{
11985    __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg));
11986  %}
11987
11988  ins_pipe(fp_i2f);
11989%}
11990
11991instruct convL2F_reg_reg(vRegF dst, iRegL src) %{
11992  match(Set dst (ConvL2F src));
11993
11994  ins_cost(INSN_COST * 5);
11995  format %{ "scvtfs  $dst, $src \t// l2f" %}
11996
11997  ins_encode %{
11998    __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg));
11999  %}
12000
12001  ins_pipe(fp_l2f);
12002%}
12003
12004instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{
12005  match(Set dst (ConvD2I src));
12006
12007  ins_cost(INSN_COST * 5);
12008  format %{ "fcvtzdw  $dst, $src \t// d2i" %}
12009
12010  ins_encode %{
12011    __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
12012  %}
12013
12014  ins_pipe(fp_d2i);
12015%}
12016
12017instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
12018  match(Set dst (ConvD2L src));
12019
12020  ins_cost(INSN_COST * 5);
12021  format %{ "fcvtzd  $dst, $src \t// d2l" %}
12022
12023  ins_encode %{
12024    __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg));
12025  %}
12026
12027  ins_pipe(fp_d2l);
12028%}
12029
12030instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{
12031  match(Set dst (ConvI2D src));
12032
12033  ins_cost(INSN_COST * 5);
12034  format %{ "scvtfwd  $dst, $src \t// i2d" %}
12035
12036  ins_encode %{
12037    __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
12038  %}
12039
12040  ins_pipe(fp_i2d);
12041%}
12042
12043instruct convL2D_reg_reg(vRegD dst, iRegL src) %{
12044  match(Set dst (ConvL2D src));
12045
12046  ins_cost(INSN_COST * 5);
12047  format %{ "scvtfd  $dst, $src \t// l2d" %}
12048
12049  ins_encode %{
12050    __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
12051  %}
12052
12053  ins_pipe(fp_l2d);
12054%}
12055
12056// stack <-> reg and reg <-> reg shuffles with no conversion
12057
12058instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{
12059
12060  match(Set dst (MoveF2I src));
12061
12062  effect(DEF dst, USE src);
12063
12064  ins_cost(4 * INSN_COST);
12065
12066  format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %}
12067
12068  ins_encode %{
12069    __ ldrw($dst$$Register, Address(sp, $src$$disp));
12070  %}
12071
12072  ins_pipe(iload_reg_reg);
12073
12074%}
12075
12076instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{
12077
12078  match(Set dst (MoveI2F src));
12079
12080  effect(DEF dst, USE src);
12081
12082  ins_cost(4 * INSN_COST);
12083
12084  format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %}
12085
12086  ins_encode %{
12087    __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
12088  %}
12089
12090  ins_pipe(pipe_class_memory);
12091
12092%}
12093
12094instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{
12095
12096  match(Set dst (MoveD2L src));
12097
12098  effect(DEF dst, USE src);
12099
12100  ins_cost(4 * INSN_COST);
12101
12102  format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %}
12103
12104  ins_encode %{
12105    __ ldr($dst$$Register, Address(sp, $src$$disp));
12106  %}
12107
12108  ins_pipe(iload_reg_reg);
12109
12110%}
12111
12112instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{
12113
12114  match(Set dst (MoveL2D src));
12115
12116  effect(DEF dst, USE src);
12117
12118  ins_cost(4 * INSN_COST);
12119
12120  format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %}
12121
12122  ins_encode %{
12123    __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
12124  %}
12125
12126  ins_pipe(pipe_class_memory);
12127
12128%}
12129
12130instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{
12131
12132  match(Set dst (MoveF2I src));
12133
12134  effect(DEF dst, USE src);
12135
12136  ins_cost(INSN_COST);
12137
12138  format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %}
12139
12140  ins_encode %{
12141    __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
12142  %}
12143
12144  ins_pipe(pipe_class_memory);
12145
12146%}
12147
12148instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
12149
12150  match(Set dst (MoveI2F src));
12151
12152  effect(DEF dst, USE src);
12153
12154  ins_cost(INSN_COST);
12155
12156  format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %}
12157
12158  ins_encode %{
12159    __ strw($src$$Register, Address(sp, $dst$$disp));
12160  %}
12161
12162  ins_pipe(istore_reg_reg);
12163
12164%}
12165
12166instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{
12167
12168  match(Set dst (MoveD2L src));
12169
12170  effect(DEF dst, USE src);
12171
12172  ins_cost(INSN_COST);
12173
12174  format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %}
12175
12176  ins_encode %{
12177    __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
12178  %}
12179
12180  ins_pipe(pipe_class_memory);
12181
12182%}
12183
12184instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
12185
12186  match(Set dst (MoveL2D src));
12187
12188  effect(DEF dst, USE src);
12189
12190  ins_cost(INSN_COST);
12191
12192  format %{ "str $src, $dst\t# MoveL2D_reg_stack" %}
12193
12194  ins_encode %{
12195    __ str($src$$Register, Address(sp, $dst$$disp));
12196  %}
12197
12198  ins_pipe(istore_reg_reg);
12199
12200%}
12201
12202instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{
12203
12204  match(Set dst (MoveF2I src));
12205
12206  effect(DEF dst, USE src);
12207
12208  ins_cost(INSN_COST);
12209
12210  format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %}
12211
12212  ins_encode %{
12213    __ fmovs($dst$$Register, as_FloatRegister($src$$reg));
12214  %}
12215
12216  ins_pipe(fp_f2i);
12217
12218%}
12219
12220instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{
12221
12222  match(Set dst (MoveI2F src));
12223
12224  effect(DEF dst, USE src);
12225
12226  ins_cost(INSN_COST);
12227
12228  format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %}
12229
12230  ins_encode %{
12231    __ fmovs(as_FloatRegister($dst$$reg), $src$$Register);
12232  %}
12233
12234  ins_pipe(fp_i2f);
12235
12236%}
12237
12238instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
12239
12240  match(Set dst (MoveD2L src));
12241
12242  effect(DEF dst, USE src);
12243
12244  ins_cost(INSN_COST);
12245
12246  format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %}
12247
12248  ins_encode %{
12249    __ fmovd($dst$$Register, as_FloatRegister($src$$reg));
12250  %}
12251
12252  ins_pipe(fp_d2l);
12253
12254%}
12255
12256instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{
12257
12258  match(Set dst (MoveL2D src));
12259
12260  effect(DEF dst, USE src);
12261
12262  ins_cost(INSN_COST);
12263
12264  format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %}
12265
12266  ins_encode %{
12267    __ fmovd(as_FloatRegister($dst$$reg), $src$$Register);
12268  %}
12269
12270  ins_pipe(fp_l2d);
12271
12272%}
12273
12274// ============================================================================
12275// clearing of an array
12276
12277instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
12278%{
12279  match(Set dummy (ClearArray cnt base));
12280  effect(USE_KILL cnt, USE_KILL base, KILL cr);
12281
12282  ins_cost(4 * INSN_COST);
12283  format %{ "ClearArray $cnt, $base" %}
12284
12285  ins_encode %{
12286    __ zero_words($base$$Register, $cnt$$Register);
12287  %}
12288
12289  ins_pipe(pipe_class_memory);
12290%}
12291
12292instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 tmp, Universe dummy, rFlagsReg cr)
12293%{
12294  match(Set dummy (ClearArray cnt base));
12295  effect(USE_KILL base, TEMP tmp, KILL cr);
12296
12297  ins_cost(4 * INSN_COST);
12298  format %{ "ClearArray $cnt, $base" %}
12299
12300  ins_encode %{
12301    __ zero_words($base$$Register, (u_int64_t)$cnt$$constant);
12302  %}
12303
12304  ins_pipe(pipe_class_memory);
12305%}
12306
12307// ============================================================================
12308// Overflow Math Instructions
12309
12310instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
12311%{
12312  match(Set cr (OverflowAddI op1 op2));
12313
12314  format %{ "cmnw  $op1, $op2\t# overflow check int" %}
12315  ins_cost(INSN_COST);
12316  ins_encode %{
12317    __ cmnw($op1$$Register, $op2$$Register);
12318  %}
12319
12320  ins_pipe(icmp_reg_reg);
12321%}
12322
12323instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
12324%{
12325  match(Set cr (OverflowAddI op1 op2));
12326
12327  format %{ "cmnw  $op1, $op2\t# overflow check int" %}
12328  ins_cost(INSN_COST);
12329  ins_encode %{
12330    __ cmnw($op1$$Register, $op2$$constant);
12331  %}
12332
12333  ins_pipe(icmp_reg_imm);
12334%}
12335
12336instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
12337%{
12338  match(Set cr (OverflowAddL op1 op2));
12339
12340  format %{ "cmn   $op1, $op2\t# overflow check long" %}
12341  ins_cost(INSN_COST);
12342  ins_encode %{
12343    __ cmn($op1$$Register, $op2$$Register);
12344  %}
12345
12346  ins_pipe(icmp_reg_reg);
12347%}
12348
12349instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
12350%{
12351  match(Set cr (OverflowAddL op1 op2));
12352
12353  format %{ "cmn   $op1, $op2\t# overflow check long" %}
12354  ins_cost(INSN_COST);
12355  ins_encode %{
12356    __ cmn($op1$$Register, $op2$$constant);
12357  %}
12358
12359  ins_pipe(icmp_reg_imm);
12360%}
12361
12362instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
12363%{
12364  match(Set cr (OverflowSubI op1 op2));
12365
12366  format %{ "cmpw  $op1, $op2\t# overflow check int" %}
12367  ins_cost(INSN_COST);
12368  ins_encode %{
12369    __ cmpw($op1$$Register, $op2$$Register);
12370  %}
12371
12372  ins_pipe(icmp_reg_reg);
12373%}
12374
12375instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
12376%{
12377  match(Set cr (OverflowSubI op1 op2));
12378
12379  format %{ "cmpw  $op1, $op2\t# overflow check int" %}
12380  ins_cost(INSN_COST);
12381  ins_encode %{
12382    __ cmpw($op1$$Register, $op2$$constant);
12383  %}
12384
12385  ins_pipe(icmp_reg_imm);
12386%}
12387
12388instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
12389%{
12390  match(Set cr (OverflowSubL op1 op2));
12391
12392  format %{ "cmp   $op1, $op2\t# overflow check long" %}
12393  ins_cost(INSN_COST);
12394  ins_encode %{
12395    __ cmp($op1$$Register, $op2$$Register);
12396  %}
12397
12398  ins_pipe(icmp_reg_reg);
12399%}
12400
12401instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
12402%{
12403  match(Set cr (OverflowSubL op1 op2));
12404
12405  format %{ "cmp   $op1, $op2\t# overflow check long" %}
12406  ins_cost(INSN_COST);
12407  ins_encode %{
12408    __ cmp($op1$$Register, $op2$$constant);
12409  %}
12410
12411  ins_pipe(icmp_reg_imm);
12412%}
12413
12414instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1)
12415%{
12416  match(Set cr (OverflowSubI zero op1));
12417
12418  format %{ "cmpw  zr, $op1\t# overflow check int" %}
12419  ins_cost(INSN_COST);
12420  ins_encode %{
12421    __ cmpw(zr, $op1$$Register);
12422  %}
12423
12424  ins_pipe(icmp_reg_imm);
12425%}
12426
12427instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1)
12428%{
12429  match(Set cr (OverflowSubL zero op1));
12430
12431  format %{ "cmp   zr, $op1\t# overflow check long" %}
12432  ins_cost(INSN_COST);
12433  ins_encode %{
12434    __ cmp(zr, $op1$$Register);
12435  %}
12436
12437  ins_pipe(icmp_reg_imm);
12438%}
12439
12440instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
12441%{
12442  match(Set cr (OverflowMulI op1 op2));
12443
12444  format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
12445            "cmp   rscratch1, rscratch1, sxtw\n\t"
12446            "movw  rscratch1, #0x80000000\n\t"
12447            "cselw rscratch1, rscratch1, zr, NE\n\t"
12448            "cmpw  rscratch1, #1" %}
12449  ins_cost(5 * INSN_COST);
12450  ins_encode %{
12451    __ smull(rscratch1, $op1$$Register, $op2$$Register);
12452    __ subs(zr, rscratch1, rscratch1, ext::sxtw);      // NE => overflow
12453    __ movw(rscratch1, 0x80000000);                    // Develop 0 (EQ),
12454    __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
12455    __ cmpw(rscratch1, 1);                             // 0x80000000 - 1 => VS
12456  %}
12457
12458  ins_pipe(pipe_slow);
12459%}
12460
12461instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr)
12462%{
12463  match(If cmp (OverflowMulI op1 op2));
12464  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
12465	    || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
12466  effect(USE labl, KILL cr);
12467
12468  format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
12469            "cmp   rscratch1, rscratch1, sxtw\n\t"
12470            "b$cmp   $labl" %}
12471  ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST
12472  ins_encode %{
12473    Label* L = $labl$$label;
12474    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
12475    __ smull(rscratch1, $op1$$Register, $op2$$Register);
12476    __ subs(zr, rscratch1, rscratch1, ext::sxtw);      // NE => overflow
12477    __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
12478  %}
12479
12480  ins_pipe(pipe_serial);
12481%}
12482
12483instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
12484%{
12485  match(Set cr (OverflowMulL op1 op2));
12486
12487  format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
12488            "smulh rscratch2, $op1, $op2\n\t"
12489            "cmp   rscratch2, rscratch1, ASR #63\n\t"
12490            "movw  rscratch1, #0x80000000\n\t"
12491            "cselw rscratch1, rscratch1, zr, NE\n\t"
12492            "cmpw  rscratch1, #1" %}
12493  ins_cost(6 * INSN_COST);
12494  ins_encode %{
12495    __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
12496    __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
12497    __ cmp(rscratch2, rscratch1, Assembler::ASR, 63);    // Top is pure sign ext
12498    __ movw(rscratch1, 0x80000000);                    // Develop 0 (EQ),
12499    __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
12500    __ cmpw(rscratch1, 1);                             // 0x80000000 - 1 => VS
12501  %}
12502
12503  ins_pipe(pipe_slow);
12504%}
12505
12506instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr)
12507%{
12508  match(If cmp (OverflowMulL op1 op2));
12509  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
12510	    || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
12511  effect(USE labl, KILL cr);
12512
12513  format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
12514            "smulh rscratch2, $op1, $op2\n\t"
12515            "cmp   rscratch2, rscratch1, ASR #63\n\t"
12516            "b$cmp $labl" %}
12517  ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST
12518  ins_encode %{
12519    Label* L = $labl$$label;
12520    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
12521    __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
12522    __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
12523    __ cmp(rscratch2, rscratch1, Assembler::ASR, 63);    // Top is pure sign ext
12524    __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
12525  %}
12526
12527  ins_pipe(pipe_serial);
12528%}
12529
12530// ============================================================================
12531// Compare Instructions
12532
12533instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
12534%{
12535  match(Set cr (CmpI op1 op2));
12536
12537  effect(DEF cr, USE op1, USE op2);
12538
12539  ins_cost(INSN_COST);
12540  format %{ "cmpw  $op1, $op2" %}
12541
12542  ins_encode(aarch64_enc_cmpw(op1, op2));
12543
12544  ins_pipe(icmp_reg_reg);
12545%}
12546
12547instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero)
12548%{
12549  match(Set cr (CmpI op1 zero));
12550
12551  effect(DEF cr, USE op1);
12552
12553  ins_cost(INSN_COST);
12554  format %{ "cmpw $op1, 0" %}
12555
12556  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
12557
12558  ins_pipe(icmp_reg_imm);
12559%}
12560
12561instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2)
12562%{
12563  match(Set cr (CmpI op1 op2));
12564
12565  effect(DEF cr, USE op1);
12566
12567  ins_cost(INSN_COST);
12568  format %{ "cmpw  $op1, $op2" %}
12569
12570  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
12571
12572  ins_pipe(icmp_reg_imm);
12573%}
12574
12575instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2)
12576%{
12577  match(Set cr (CmpI op1 op2));
12578
12579  effect(DEF cr, USE op1);
12580
12581  ins_cost(INSN_COST * 2);
12582  format %{ "cmpw  $op1, $op2" %}
12583
12584  ins_encode(aarch64_enc_cmpw_imm(op1, op2));
12585
12586  ins_pipe(icmp_reg_imm);
12587%}
12588
12589// Unsigned compare Instructions; really, same as signed compare
12590// except it should only be used to feed an If or a CMovI which takes a
12591// cmpOpU.
12592
12593instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2)
12594%{
12595  match(Set cr (CmpU op1 op2));
12596
12597  effect(DEF cr, USE op1, USE op2);
12598
12599  ins_cost(INSN_COST);
12600  format %{ "cmpw  $op1, $op2\t# unsigned" %}
12601
12602  ins_encode(aarch64_enc_cmpw(op1, op2));
12603
12604  ins_pipe(icmp_reg_reg);
12605%}
12606
12607instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero)
12608%{
12609  match(Set cr (CmpU op1 zero));
12610
12611  effect(DEF cr, USE op1);
12612
12613  ins_cost(INSN_COST);
12614  format %{ "cmpw $op1, #0\t# unsigned" %}
12615
12616  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
12617
12618  ins_pipe(icmp_reg_imm);
12619%}
12620
12621instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2)
12622%{
12623  match(Set cr (CmpU op1 op2));
12624
12625  effect(DEF cr, USE op1);
12626
12627  ins_cost(INSN_COST);
12628  format %{ "cmpw  $op1, $op2\t# unsigned" %}
12629
12630  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
12631
12632  ins_pipe(icmp_reg_imm);
12633%}
12634
12635instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2)
12636%{
12637  match(Set cr (CmpU op1 op2));
12638
12639  effect(DEF cr, USE op1);
12640
12641  ins_cost(INSN_COST * 2);
12642  format %{ "cmpw  $op1, $op2\t# unsigned" %}
12643
12644  ins_encode(aarch64_enc_cmpw_imm(op1, op2));
12645
12646  ins_pipe(icmp_reg_imm);
12647%}
12648
12649instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
12650%{
12651  match(Set cr (CmpL op1 op2));
12652
12653  effect(DEF cr, USE op1, USE op2);
12654
12655  ins_cost(INSN_COST);
12656  format %{ "cmp  $op1, $op2" %}
12657
12658  ins_encode(aarch64_enc_cmp(op1, op2));
12659
12660  ins_pipe(icmp_reg_reg);
12661%}
12662
12663instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero)
12664%{
12665  match(Set cr (CmpL op1 zero));
12666
12667  effect(DEF cr, USE op1);
12668
12669  ins_cost(INSN_COST);
12670  format %{ "tst  $op1" %}
12671
12672  ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
12673
12674  ins_pipe(icmp_reg_imm);
12675%}
12676
12677instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2)
12678%{
12679  match(Set cr (CmpL op1 op2));
12680
12681  effect(DEF cr, USE op1);
12682
12683  ins_cost(INSN_COST);
12684  format %{ "cmp  $op1, $op2" %}
12685
12686  ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
12687
12688  ins_pipe(icmp_reg_imm);
12689%}
12690
12691instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2)
12692%{
12693  match(Set cr (CmpL op1 op2));
12694
12695  effect(DEF cr, USE op1);
12696
12697  ins_cost(INSN_COST * 2);
12698  format %{ "cmp  $op1, $op2" %}
12699
12700  ins_encode(aarch64_enc_cmp_imm(op1, op2));
12701
12702  ins_pipe(icmp_reg_imm);
12703%}
12704
12705instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2)
12706%{
12707  match(Set cr (CmpUL op1 op2));
12708
12709  effect(DEF cr, USE op1, USE op2);
12710
12711  ins_cost(INSN_COST);
12712  format %{ "cmp  $op1, $op2" %}
12713
12714  ins_encode(aarch64_enc_cmp(op1, op2));
12715
12716  ins_pipe(icmp_reg_reg);
12717%}
12718
12719instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero)
12720%{
12721  match(Set cr (CmpUL op1 zero));
12722
12723  effect(DEF cr, USE op1);
12724
12725  ins_cost(INSN_COST);
12726  format %{ "tst  $op1" %}
12727
12728  ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
12729
12730  ins_pipe(icmp_reg_imm);
12731%}
12732
12733instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2)
12734%{
12735  match(Set cr (CmpUL op1 op2));
12736
12737  effect(DEF cr, USE op1);
12738
12739  ins_cost(INSN_COST);
12740  format %{ "cmp  $op1, $op2" %}
12741
12742  ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
12743
12744  ins_pipe(icmp_reg_imm);
12745%}
12746
12747instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2)
12748%{
12749  match(Set cr (CmpUL op1 op2));
12750
12751  effect(DEF cr, USE op1);
12752
12753  ins_cost(INSN_COST * 2);
12754  format %{ "cmp  $op1, $op2" %}
12755
12756  ins_encode(aarch64_enc_cmp_imm(op1, op2));
12757
12758  ins_pipe(icmp_reg_imm);
12759%}
12760
12761instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2)
12762%{
12763  match(Set cr (CmpP op1 op2));
12764
12765  effect(DEF cr, USE op1, USE op2);
12766
12767  ins_cost(INSN_COST);
12768  format %{ "cmp  $op1, $op2\t // ptr" %}
12769
12770  ins_encode(aarch64_enc_cmpp(op1, op2));
12771
12772  ins_pipe(icmp_reg_reg);
12773%}
12774
12775instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2)
12776%{
12777  match(Set cr (CmpN op1 op2));
12778
12779  effect(DEF cr, USE op1, USE op2);
12780
12781  ins_cost(INSN_COST);
12782  format %{ "cmp  $op1, $op2\t // compressed ptr" %}
12783
12784  ins_encode(aarch64_enc_cmpn(op1, op2));
12785
12786  ins_pipe(icmp_reg_reg);
12787%}
12788
12789instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero)
12790%{
12791  match(Set cr (CmpP op1 zero));
12792
12793  effect(DEF cr, USE op1, USE zero);
12794
12795  ins_cost(INSN_COST);
12796  format %{ "cmp  $op1, 0\t // ptr" %}
12797
12798  ins_encode(aarch64_enc_testp(op1));
12799
12800  ins_pipe(icmp_reg_imm);
12801%}
12802
12803instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero)
12804%{
12805  match(Set cr (CmpN op1 zero));
12806
12807  effect(DEF cr, USE op1, USE zero);
12808
12809  ins_cost(INSN_COST);
12810  format %{ "cmp  $op1, 0\t // compressed ptr" %}
12811
12812  ins_encode(aarch64_enc_testn(op1));
12813
12814  ins_pipe(icmp_reg_imm);
12815%}
12816
12817// FP comparisons
12818//
12819// n.b. CmpF/CmpD set a normal flags reg which then gets compared
12820// using normal cmpOp. See declaration of rFlagsReg for details.
12821
12822instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2)
12823%{
12824  match(Set cr (CmpF src1 src2));
12825
12826  ins_cost(3 * INSN_COST);
12827  format %{ "fcmps $src1, $src2" %}
12828
12829  ins_encode %{
12830    __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
12831  %}
12832
12833  ins_pipe(pipe_class_compare);
12834%}
12835
12836instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2)
12837%{
12838  match(Set cr (CmpF src1 src2));
12839
12840  ins_cost(3 * INSN_COST);
12841  format %{ "fcmps $src1, 0.0" %}
12842
12843  ins_encode %{
12844    __ fcmps(as_FloatRegister($src1$$reg), 0.0);
12845  %}
12846
12847  ins_pipe(pipe_class_compare);
12848%}
12849// FROM HERE
12850
12851instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2)
12852%{
12853  match(Set cr (CmpD src1 src2));
12854
12855  ins_cost(3 * INSN_COST);
12856  format %{ "fcmpd $src1, $src2" %}
12857
12858  ins_encode %{
12859    __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
12860  %}
12861
12862  ins_pipe(pipe_class_compare);
12863%}
12864
12865instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2)
12866%{
12867  match(Set cr (CmpD src1 src2));
12868
12869  ins_cost(3 * INSN_COST);
12870  format %{ "fcmpd $src1, 0.0" %}
12871
12872  ins_encode %{
12873    __ fcmpd(as_FloatRegister($src1$$reg), 0.0);
12874  %}
12875
12876  ins_pipe(pipe_class_compare);
12877%}
12878
12879instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr)
12880%{
12881  match(Set dst (CmpF3 src1 src2));
12882  effect(KILL cr);
12883
12884  ins_cost(5 * INSN_COST);
12885  format %{ "fcmps $src1, $src2\n\t"
12886            "csinvw($dst, zr, zr, eq\n\t"
12887            "csnegw($dst, $dst, $dst, lt)"
12888  %}
12889
12890  ins_encode %{
12891    Label done;
12892    FloatRegister s1 = as_FloatRegister($src1$$reg);
12893    FloatRegister s2 = as_FloatRegister($src2$$reg);
12894    Register d = as_Register($dst$$reg);
12895    __ fcmps(s1, s2);
12896    // installs 0 if EQ else -1
12897    __ csinvw(d, zr, zr, Assembler::EQ);
12898    // keeps -1 if less or unordered else installs 1
12899    __ csnegw(d, d, d, Assembler::LT);
12900    __ bind(done);
12901  %}
12902
12903  ins_pipe(pipe_class_default);
12904
12905%}
12906
12907instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr)
12908%{
12909  match(Set dst (CmpD3 src1 src2));
12910  effect(KILL cr);
12911
12912  ins_cost(5 * INSN_COST);
12913  format %{ "fcmpd $src1, $src2\n\t"
12914            "csinvw($dst, zr, zr, eq\n\t"
12915            "csnegw($dst, $dst, $dst, lt)"
12916  %}
12917
12918  ins_encode %{
12919    Label done;
12920    FloatRegister s1 = as_FloatRegister($src1$$reg);
12921    FloatRegister s2 = as_FloatRegister($src2$$reg);
12922    Register d = as_Register($dst$$reg);
12923    __ fcmpd(s1, s2);
12924    // installs 0 if EQ else -1
12925    __ csinvw(d, zr, zr, Assembler::EQ);
12926    // keeps -1 if less or unordered else installs 1
12927    __ csnegw(d, d, d, Assembler::LT);
12928    __ bind(done);
12929  %}
12930  ins_pipe(pipe_class_default);
12931
12932%}
12933
12934instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr)
12935%{
12936  match(Set dst (CmpF3 src1 zero));
12937  effect(KILL cr);
12938
12939  ins_cost(5 * INSN_COST);
12940  format %{ "fcmps $src1, 0.0\n\t"
12941            "csinvw($dst, zr, zr, eq\n\t"
12942            "csnegw($dst, $dst, $dst, lt)"
12943  %}
12944
12945  ins_encode %{
12946    Label done;
12947    FloatRegister s1 = as_FloatRegister($src1$$reg);
12948    Register d = as_Register($dst$$reg);
12949    __ fcmps(s1, 0.0);
12950    // installs 0 if EQ else -1
12951    __ csinvw(d, zr, zr, Assembler::EQ);
12952    // keeps -1 if less or unordered else installs 1
12953    __ csnegw(d, d, d, Assembler::LT);
12954    __ bind(done);
12955  %}
12956
12957  ins_pipe(pipe_class_default);
12958
12959%}
12960
12961instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr)
12962%{
12963  match(Set dst (CmpD3 src1 zero));
12964  effect(KILL cr);
12965
12966  ins_cost(5 * INSN_COST);
12967  format %{ "fcmpd $src1, 0.0\n\t"
12968            "csinvw($dst, zr, zr, eq\n\t"
12969            "csnegw($dst, $dst, $dst, lt)"
12970  %}
12971
12972  ins_encode %{
12973    Label done;
12974    FloatRegister s1 = as_FloatRegister($src1$$reg);
12975    Register d = as_Register($dst$$reg);
12976    __ fcmpd(s1, 0.0);
12977    // installs 0 if EQ else -1
12978    __ csinvw(d, zr, zr, Assembler::EQ);
12979    // keeps -1 if less or unordered else installs 1
12980    __ csnegw(d, d, d, Assembler::LT);
12981    __ bind(done);
12982  %}
12983  ins_pipe(pipe_class_default);
12984
12985%}
12986
12987// Manifest a CmpL result in an integer register.
12988// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
12989instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
12990%{
12991  match(Set dst (CmpL3 src1 src2));
12992  effect(KILL flags);
12993
12994  ins_cost(INSN_COST * 6);
12995  format %{
12996      "cmp $src1, $src2"
12997      "csetw $dst, ne"
12998      "cnegw $dst, lt"
12999  %}
13000  // format %{ "CmpL3 $dst, $src1, $src2" %}
13001  ins_encode %{
13002    __ cmp($src1$$Register, $src2$$Register);
13003    __ csetw($dst$$Register, Assembler::NE);
13004    __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
13005  %}
13006
13007  ins_pipe(ialu_reg_reg);
13008%}
13009
13010instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr)
13011%{
13012  match(Set dst (CmpLTMask p q));
13013  effect(KILL cr);
13014
13015  ins_cost(3 * INSN_COST);
13016
13017  format %{ "cmpw $p, $q\t# cmpLTMask\n\t"
13018            "csetw $dst, lt\n\t"
13019            "subw $dst, zr, $dst"
13020  %}
13021
13022  ins_encode %{
13023    __ cmpw(as_Register($p$$reg), as_Register($q$$reg));
13024    __ csetw(as_Register($dst$$reg), Assembler::LT);
13025    __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg));
13026  %}
13027
13028  ins_pipe(ialu_reg_reg);
13029%}
13030
13031instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr)
13032%{
13033  match(Set dst (CmpLTMask src zero));
13034  effect(KILL cr);
13035
13036  ins_cost(INSN_COST);
13037
13038  format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %}
13039
13040  ins_encode %{
13041    __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31);
13042  %}
13043
13044  ins_pipe(ialu_reg_shift);
13045%}
13046
13047// ============================================================================
13048// Max and Min
13049
13050instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
13051%{
13052  match(Set dst (MinI src1 src2));
13053
13054  effect(DEF dst, USE src1, USE src2, KILL cr);
13055  size(8);
13056
13057  ins_cost(INSN_COST * 3);
13058  format %{
13059    "cmpw $src1 $src2\t signed int\n\t"
13060    "cselw $dst, $src1, $src2 lt\t"
13061  %}
13062
13063  ins_encode %{
13064    __ cmpw(as_Register($src1$$reg),
13065            as_Register($src2$$reg));
13066    __ cselw(as_Register($dst$$reg),
13067             as_Register($src1$$reg),
13068             as_Register($src2$$reg),
13069             Assembler::LT);
13070  %}
13071
13072  ins_pipe(ialu_reg_reg);
13073%}
13074// FROM HERE
13075
13076instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
13077%{
13078  match(Set dst (MaxI src1 src2));
13079
13080  effect(DEF dst, USE src1, USE src2, KILL cr);
13081  size(8);
13082
13083  ins_cost(INSN_COST * 3);
13084  format %{
13085    "cmpw $src1 $src2\t signed int\n\t"
13086    "cselw $dst, $src1, $src2 gt\t"
13087  %}
13088
13089  ins_encode %{
13090    __ cmpw(as_Register($src1$$reg),
13091            as_Register($src2$$reg));
13092    __ cselw(as_Register($dst$$reg),
13093             as_Register($src1$$reg),
13094             as_Register($src2$$reg),
13095             Assembler::GT);
13096  %}
13097
13098  ins_pipe(ialu_reg_reg);
13099%}
13100
13101// ============================================================================
13102// Branch Instructions
13103
13104// Direct Branch.
13105instruct branch(label lbl)
13106%{
13107  match(Goto);
13108
13109  effect(USE lbl);
13110
13111  ins_cost(BRANCH_COST);
13112  format %{ "b  $lbl" %}
13113
13114  ins_encode(aarch64_enc_b(lbl));
13115
13116  ins_pipe(pipe_branch);
13117%}
13118
13119// Conditional Near Branch
13120instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl)
13121%{
13122  // Same match rule as `branchConFar'.
13123  match(If cmp cr);
13124
13125  effect(USE lbl);
13126
13127  ins_cost(BRANCH_COST);
13128  // If set to 1 this indicates that the current instruction is a
13129  // short variant of a long branch. This avoids using this
13130  // instruction in first-pass matching. It will then only be used in
13131  // the `Shorten_branches' pass.
13132  // ins_short_branch(1);
13133  format %{ "b$cmp  $lbl" %}
13134
13135  ins_encode(aarch64_enc_br_con(cmp, lbl));
13136
13137  ins_pipe(pipe_branch_cond);
13138%}
13139
13140// Conditional Near Branch Unsigned
13141instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl)
13142%{
13143  // Same match rule as `branchConFar'.
13144  match(If cmp cr);
13145
13146  effect(USE lbl);
13147
13148  ins_cost(BRANCH_COST);
13149  // If set to 1 this indicates that the current instruction is a
13150  // short variant of a long branch. This avoids using this
13151  // instruction in first-pass matching. It will then only be used in
13152  // the `Shorten_branches' pass.
13153  // ins_short_branch(1);
13154  format %{ "b$cmp  $lbl\t# unsigned" %}
13155
13156  ins_encode(aarch64_enc_br_conU(cmp, lbl));
13157
13158  ins_pipe(pipe_branch_cond);
13159%}
13160
13161// Make use of CBZ and CBNZ.  These instructions, as well as being
13162// shorter than (cmp; branch), have the additional benefit of not
13163// killing the flags.
13164
13165instruct cmpI_imm0_branch(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{
13166  match(If cmp (CmpI op1 op2));
13167  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
13168	    || n->in(1)->as_Bool()->_test._test == BoolTest::eq);
13169  effect(USE labl);
13170
13171  ins_cost(BRANCH_COST);
13172  format %{ "cbw$cmp   $op1, $labl" %}
13173  ins_encode %{
13174    Label* L = $labl$$label;
13175    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13176    if (cond == Assembler::EQ)
13177      __ cbzw($op1$$Register, *L);
13178    else
13179      __ cbnzw($op1$$Register, *L);
13180  %}
13181  ins_pipe(pipe_cmp_branch);
13182%}
13183
13184instruct cmpL_imm0_branch(cmpOp cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{
13185  match(If cmp (CmpL op1 op2));
13186  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
13187	    || n->in(1)->as_Bool()->_test._test == BoolTest::eq);
13188  effect(USE labl);
13189
13190  ins_cost(BRANCH_COST);
13191  format %{ "cb$cmp   $op1, $labl" %}
13192  ins_encode %{
13193    Label* L = $labl$$label;
13194    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13195    if (cond == Assembler::EQ)
13196      __ cbz($op1$$Register, *L);
13197    else
13198      __ cbnz($op1$$Register, *L);
13199  %}
13200  ins_pipe(pipe_cmp_branch);
13201%}
13202
13203instruct cmpP_imm0_branch(cmpOp cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{
13204  match(If cmp (CmpP op1 op2));
13205  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
13206	    || n->in(1)->as_Bool()->_test._test == BoolTest::eq);
13207  effect(USE labl);
13208
13209  ins_cost(BRANCH_COST);
13210  format %{ "cb$cmp   $op1, $labl" %}
13211  ins_encode %{
13212    Label* L = $labl$$label;
13213    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13214    if (cond == Assembler::EQ)
13215      __ cbz($op1$$Register, *L);
13216    else
13217      __ cbnz($op1$$Register, *L);
13218  %}
13219  ins_pipe(pipe_cmp_branch);
13220%}
13221
13222instruct cmpN_imm0_branch(cmpOp cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{
13223  match(If cmp (CmpN op1 op2));
13224  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
13225	    || n->in(1)->as_Bool()->_test._test == BoolTest::eq);
13226  effect(USE labl);
13227
13228  ins_cost(BRANCH_COST);
13229  format %{ "cbw$cmp   $op1, $labl" %}
13230  ins_encode %{
13231    Label* L = $labl$$label;
13232    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13233    if (cond == Assembler::EQ)
13234      __ cbzw($op1$$Register, *L);
13235    else
13236      __ cbnzw($op1$$Register, *L);
13237  %}
13238  ins_pipe(pipe_cmp_branch);
13239%}
13240
13241instruct cmpP_narrowOop_imm0_branch(cmpOp cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{
13242  match(If cmp (CmpP (DecodeN oop) zero));
13243  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
13244            || n->in(1)->as_Bool()->_test._test == BoolTest::eq);
13245  effect(USE labl);
13246
13247  ins_cost(BRANCH_COST);
13248  format %{ "cb$cmp   $oop, $labl" %}
13249  ins_encode %{
13250    Label* L = $labl$$label;
13251    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13252    if (cond == Assembler::EQ)
13253      __ cbzw($oop$$Register, *L);
13254    else
13255      __ cbnzw($oop$$Register, *L);
13256  %}
13257  ins_pipe(pipe_cmp_branch);
13258%}
13259
13260instruct cmpUI_imm0_branch(cmpOpU cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{
13261  match(If cmp (CmpU op1 op2));
13262  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
13263            || n->in(1)->as_Bool()->_test._test == BoolTest::eq
13264            || n->in(1)->as_Bool()->_test._test == BoolTest::gt
13265            ||  n->in(1)->as_Bool()->_test._test == BoolTest::le);
13266  effect(USE labl);
13267
13268  ins_cost(BRANCH_COST);
13269  format %{ "cbw$cmp   $op1, $labl" %}
13270  ins_encode %{
13271    Label* L = $labl$$label;
13272    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13273    if (cond == Assembler::EQ || cond == Assembler::LS)
13274      __ cbzw($op1$$Register, *L);
13275    else
13276      __ cbnzw($op1$$Register, *L);
13277  %}
13278  ins_pipe(pipe_cmp_branch);
13279%}
13280
13281instruct cmpUL_imm0_branch(cmpOpU cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{
13282  match(If cmp (CmpUL op1 op2));
13283  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
13284            || n->in(1)->as_Bool()->_test._test == BoolTest::eq
13285            || n->in(1)->as_Bool()->_test._test == BoolTest::gt
13286            || n->in(1)->as_Bool()->_test._test == BoolTest::le);
13287  effect(USE labl);
13288
13289  ins_cost(BRANCH_COST);
13290  format %{ "cb$cmp   $op1, $labl" %}
13291  ins_encode %{
13292    Label* L = $labl$$label;
13293    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13294    if (cond == Assembler::EQ || cond == Assembler::LS)
13295      __ cbz($op1$$Register, *L);
13296    else
13297      __ cbnz($op1$$Register, *L);
13298  %}
13299  ins_pipe(pipe_cmp_branch);
13300%}
13301
13302// Test bit and Branch
13303
13304// Patterns for short (< 32KiB) variants
13305instruct cmpL_branch_sign(cmpOp cmp, iRegL op1, immL0 op2, label labl) %{
13306  match(If cmp (CmpL op1 op2));
13307  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt
13308            || n->in(1)->as_Bool()->_test._test == BoolTest::ge);
13309  effect(USE labl);
13310
13311  ins_cost(BRANCH_COST);
13312  format %{ "cb$cmp   $op1, $labl # long" %}
13313  ins_encode %{
13314    Label* L = $labl$$label;
13315    Assembler::Condition cond =
13316      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
13317    __ tbr(cond, $op1$$Register, 63, *L);
13318  %}
13319  ins_pipe(pipe_cmp_branch);
13320  ins_short_branch(1);
13321%}
13322
13323instruct cmpI_branch_sign(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl) %{
13324  match(If cmp (CmpI op1 op2));
13325  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt
13326            || n->in(1)->as_Bool()->_test._test == BoolTest::ge);
13327  effect(USE labl);
13328
13329  ins_cost(BRANCH_COST);
13330  format %{ "cb$cmp   $op1, $labl # int" %}
13331  ins_encode %{
13332    Label* L = $labl$$label;
13333    Assembler::Condition cond =
13334      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
13335    __ tbr(cond, $op1$$Register, 31, *L);
13336  %}
13337  ins_pipe(pipe_cmp_branch);
13338  ins_short_branch(1);
13339%}
13340
13341instruct cmpL_branch_bit(cmpOp cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
13342  match(If cmp (CmpL (AndL op1 op2) op3));
13343  predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne
13344            || n->in(1)->as_Bool()->_test._test == BoolTest::eq)
13345            && is_power_of_2(n->in(2)->in(1)->in(2)->get_long()));
13346  effect(USE labl);
13347
13348  ins_cost(BRANCH_COST);
13349  format %{ "tb$cmp   $op1, $op2, $labl" %}
13350  ins_encode %{
13351    Label* L = $labl$$label;
13352    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13353    int bit = exact_log2($op2$$constant);
13354    __ tbr(cond, $op1$$Register, bit, *L);
13355  %}
13356  ins_pipe(pipe_cmp_branch);
13357  ins_short_branch(1);
13358%}
13359
13360instruct cmpI_branch_bit(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
13361  match(If cmp (CmpI (AndI op1 op2) op3));
13362  predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne
13363            || n->in(1)->as_Bool()->_test._test == BoolTest::eq)
13364            && is_power_of_2(n->in(2)->in(1)->in(2)->get_int()));
13365  effect(USE labl);
13366
13367  ins_cost(BRANCH_COST);
13368  format %{ "tb$cmp   $op1, $op2, $labl" %}
13369  ins_encode %{
13370    Label* L = $labl$$label;
13371    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13372    int bit = exact_log2($op2$$constant);
13373    __ tbr(cond, $op1$$Register, bit, *L);
13374  %}
13375  ins_pipe(pipe_cmp_branch);
13376  ins_short_branch(1);
13377%}
13378
13379// And far variants
13380instruct far_cmpL_branch_sign(cmpOp cmp, iRegL op1, immL0 op2, label labl) %{
13381  match(If cmp (CmpL op1 op2));
13382  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt
13383            || n->in(1)->as_Bool()->_test._test == BoolTest::ge);
13384  effect(USE labl);
13385
13386  ins_cost(BRANCH_COST);
13387  format %{ "cb$cmp   $op1, $labl # long" %}
13388  ins_encode %{
13389    Label* L = $labl$$label;
13390    Assembler::Condition cond =
13391      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
13392    __ tbr(cond, $op1$$Register, 63, *L, /*far*/true);
13393  %}
13394  ins_pipe(pipe_cmp_branch);
13395%}
13396
13397instruct far_cmpI_branch_sign(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl) %{
13398  match(If cmp (CmpI op1 op2));
13399  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt
13400            || n->in(1)->as_Bool()->_test._test == BoolTest::ge);
13401  effect(USE labl);
13402
13403  ins_cost(BRANCH_COST);
13404  format %{ "cb$cmp   $op1, $labl # int" %}
13405  ins_encode %{
13406    Label* L = $labl$$label;
13407    Assembler::Condition cond =
13408      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
13409    __ tbr(cond, $op1$$Register, 31, *L, /*far*/true);
13410  %}
13411  ins_pipe(pipe_cmp_branch);
13412%}
13413
13414instruct far_cmpL_branch_bit(cmpOp cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
13415  match(If cmp (CmpL (AndL op1 op2) op3));
13416  predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne
13417            || n->in(1)->as_Bool()->_test._test == BoolTest::eq)
13418            && is_power_of_2(n->in(2)->in(1)->in(2)->get_long()));
13419  effect(USE labl);
13420
13421  ins_cost(BRANCH_COST);
13422  format %{ "tb$cmp   $op1, $op2, $labl" %}
13423  ins_encode %{
13424    Label* L = $labl$$label;
13425    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13426    int bit = exact_log2($op2$$constant);
13427    __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
13428  %}
13429  ins_pipe(pipe_cmp_branch);
13430%}
13431
13432instruct far_cmpI_branch_bit(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
13433  match(If cmp (CmpI (AndI op1 op2) op3));
13434  predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne
13435            || n->in(1)->as_Bool()->_test._test == BoolTest::eq)
13436            && is_power_of_2(n->in(2)->in(1)->in(2)->get_int()));
13437  effect(USE labl);
13438
13439  ins_cost(BRANCH_COST);
13440  format %{ "tb$cmp   $op1, $op2, $labl" %}
13441  ins_encode %{
13442    Label* L = $labl$$label;
13443    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13444    int bit = exact_log2($op2$$constant);
13445    __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
13446  %}
13447  ins_pipe(pipe_cmp_branch);
13448%}
13449
13450// Test bits
13451
13452instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{
13453  match(Set cr (CmpL (AndL op1 op2) op3));
13454  predicate(Assembler::operand_valid_for_logical_immediate
13455            (/*is_32*/false, n->in(1)->in(2)->get_long()));
13456
13457  ins_cost(INSN_COST);
13458  format %{ "tst $op1, $op2 # long" %}
13459  ins_encode %{
13460    __ tst($op1$$Register, $op2$$constant);
13461  %}
13462  ins_pipe(ialu_reg_reg);
13463%}
13464
13465instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{
13466  match(Set cr (CmpI (AndI op1 op2) op3));
13467  predicate(Assembler::operand_valid_for_logical_immediate
13468            (/*is_32*/true, n->in(1)->in(2)->get_int()));
13469
13470  ins_cost(INSN_COST);
13471  format %{ "tst $op1, $op2 # int" %}
13472  ins_encode %{
13473    __ tstw($op1$$Register, $op2$$constant);
13474  %}
13475  ins_pipe(ialu_reg_reg);
13476%}
13477
13478instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{
13479  match(Set cr (CmpL (AndL op1 op2) op3));
13480
13481  ins_cost(INSN_COST);
13482  format %{ "tst $op1, $op2 # long" %}
13483  ins_encode %{
13484    __ tst($op1$$Register, $op2$$Register);
13485  %}
13486  ins_pipe(ialu_reg_reg);
13487%}
13488
13489instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{
13490  match(Set cr (CmpI (AndI op1 op2) op3));
13491
13492  ins_cost(INSN_COST);
13493  format %{ "tstw $op1, $op2 # int" %}
13494  ins_encode %{
13495    __ tstw($op1$$Register, $op2$$Register);
13496  %}
13497  ins_pipe(ialu_reg_reg);
13498%}
13499
13500
13501// Conditional Far Branch
13502// Conditional Far Branch Unsigned
13503// TODO: fixme
13504
13505// counted loop end branch near
13506instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl)
13507%{
13508  match(CountedLoopEnd cmp cr);
13509
13510  effect(USE lbl);
13511
13512  ins_cost(BRANCH_COST);
13513  // short variant.
13514  // ins_short_branch(1);
13515  format %{ "b$cmp $lbl \t// counted loop end" %}
13516
13517  ins_encode(aarch64_enc_br_con(cmp, lbl));
13518
13519  ins_pipe(pipe_branch);
13520%}
13521
13522// counted loop end branch near Unsigned
13523instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl)
13524%{
13525  match(CountedLoopEnd cmp cr);
13526
13527  effect(USE lbl);
13528
13529  ins_cost(BRANCH_COST);
13530  // short variant.
13531  // ins_short_branch(1);
13532  format %{ "b$cmp $lbl \t// counted loop end unsigned" %}
13533
13534  ins_encode(aarch64_enc_br_conU(cmp, lbl));
13535
13536  ins_pipe(pipe_branch);
13537%}
13538
13539// counted loop end branch far
13540// counted loop end branch far unsigned
13541// TODO: fixme
13542
13543// ============================================================================
13544// inlined locking and unlocking
13545
13546instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2)
13547%{
13548  match(Set cr (FastLock object box));
13549  effect(TEMP tmp, TEMP tmp2);
13550
13551  // TODO
13552  // identify correct cost
13553  ins_cost(5 * INSN_COST);
13554  format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %}
13555
13556  ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2));
13557
13558  ins_pipe(pipe_serial);
13559%}
13560
13561instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2)
13562%{
13563  match(Set cr (FastUnlock object box));
13564  effect(TEMP tmp, TEMP tmp2);
13565
13566  ins_cost(5 * INSN_COST);
13567  format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %}
13568
13569  ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2));
13570
13571  ins_pipe(pipe_serial);
13572%}
13573
13574
13575// ============================================================================
13576// Safepoint Instructions
13577
13578// TODO
13579// provide a near and far version of this code
13580
13581instruct safePoint(rFlagsReg cr, iRegP poll)
13582%{
13583  match(SafePoint poll);
13584  effect(KILL cr);
13585
13586  format %{
13587    "ldrw zr, [$poll]\t# Safepoint: poll for GC"
13588  %}
13589  ins_encode %{
13590    __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type);
13591  %}
13592  ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem);
13593%}
13594
13595
13596// ============================================================================
13597// Procedure Call/Return Instructions
13598
13599// Call Java Static Instruction
13600
13601instruct CallStaticJavaDirect(method meth)
13602%{
13603  match(CallStaticJava);
13604
13605  effect(USE meth);
13606
13607  predicate(!((CallStaticJavaNode*)n)->is_method_handle_invoke());
13608
13609  ins_cost(CALL_COST);
13610
13611  format %{ "call,static $meth \t// ==> " %}
13612
13613  ins_encode( aarch64_enc_java_static_call(meth),
13614              aarch64_enc_call_epilog );
13615
13616  ins_pipe(pipe_class_call);
13617%}
13618
13619// TO HERE
13620
13621// Call Java Static Instruction (method handle version)
13622
13623instruct CallStaticJavaDirectHandle(method meth, iRegP_FP reg_mh_save)
13624%{
13625  match(CallStaticJava);
13626
13627  effect(USE meth);
13628
13629  predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
13630
13631  ins_cost(CALL_COST);
13632
13633  format %{ "call,static $meth \t// (methodhandle) ==> " %}
13634
13635  ins_encode( aarch64_enc_java_handle_call(meth),
13636              aarch64_enc_call_epilog );
13637
13638  ins_pipe(pipe_class_call);
13639%}
13640
13641// Call Java Dynamic Instruction
13642instruct CallDynamicJavaDirect(method meth)
13643%{
13644  match(CallDynamicJava);
13645
13646  effect(USE meth);
13647
13648  ins_cost(CALL_COST);
13649
13650  format %{ "CALL,dynamic $meth \t// ==> " %}
13651
13652  ins_encode( aarch64_enc_java_dynamic_call(meth),
13653               aarch64_enc_call_epilog );
13654
13655  ins_pipe(pipe_class_call);
13656%}
13657
13658// Call Runtime Instruction
13659
13660instruct CallRuntimeDirect(method meth)
13661%{
13662  match(CallRuntime);
13663
13664  effect(USE meth);
13665
13666  ins_cost(CALL_COST);
13667
13668  format %{ "CALL, runtime $meth" %}
13669
13670  ins_encode( aarch64_enc_java_to_runtime(meth) );
13671
13672  ins_pipe(pipe_class_call);
13673%}
13674
13675// Call Runtime Instruction
13676
13677instruct CallLeafDirect(method meth)
13678%{
13679  match(CallLeaf);
13680
13681  effect(USE meth);
13682
13683  ins_cost(CALL_COST);
13684
13685  format %{ "CALL, runtime leaf $meth" %}
13686
13687  ins_encode( aarch64_enc_java_to_runtime(meth) );
13688
13689  ins_pipe(pipe_class_call);
13690%}
13691
13692// Call Runtime Instruction
13693
13694instruct CallLeafNoFPDirect(method meth)
13695%{
13696  match(CallLeafNoFP);
13697
13698  effect(USE meth);
13699
13700  ins_cost(CALL_COST);
13701
13702  format %{ "CALL, runtime leaf nofp $meth" %}
13703
13704  ins_encode( aarch64_enc_java_to_runtime(meth) );
13705
13706  ins_pipe(pipe_class_call);
13707%}
13708
13709// Tail Call; Jump from runtime stub to Java code.
13710// Also known as an 'interprocedural jump'.
13711// Target of jump will eventually return to caller.
13712// TailJump below removes the return address.
13713instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop)
13714%{
13715  match(TailCall jump_target method_oop);
13716
13717  ins_cost(CALL_COST);
13718
13719  format %{ "br $jump_target\t# $method_oop holds method oop" %}
13720
13721  ins_encode(aarch64_enc_tail_call(jump_target));
13722
13723  ins_pipe(pipe_class_call);
13724%}
13725
13726instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop)
13727%{
13728  match(TailJump jump_target ex_oop);
13729
13730  ins_cost(CALL_COST);
13731
13732  format %{ "br $jump_target\t# $ex_oop holds exception oop" %}
13733
13734  ins_encode(aarch64_enc_tail_jmp(jump_target));
13735
13736  ins_pipe(pipe_class_call);
13737%}
13738
13739// Create exception oop: created by stack-crawling runtime code.
13740// Created exception is now available to this handler, and is setup
13741// just prior to jumping to this handler. No code emitted.
13742// TODO check
13743// should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1
13744instruct CreateException(iRegP_R0 ex_oop)
13745%{
13746  match(Set ex_oop (CreateEx));
13747
13748  format %{ " -- \t// exception oop; no code emitted" %}
13749
13750  size(0);
13751
13752  ins_encode( /*empty*/ );
13753
13754  ins_pipe(pipe_class_empty);
13755%}
13756
13757// Rethrow exception: The exception oop will come in the first
13758// argument position. Then JUMP (not call) to the rethrow stub code.
13759instruct RethrowException() %{
13760  match(Rethrow);
13761  ins_cost(CALL_COST);
13762
13763  format %{ "b rethrow_stub" %}
13764
13765  ins_encode( aarch64_enc_rethrow() );
13766
13767  ins_pipe(pipe_class_call);
13768%}
13769
13770
13771// Return Instruction
13772// epilog node loads ret address into lr as part of frame pop
13773instruct Ret()
13774%{
13775  match(Return);
13776
13777  format %{ "ret\t// return register" %}
13778
13779  ins_encode( aarch64_enc_ret() );
13780
13781  ins_pipe(pipe_branch);
13782%}
13783
13784// Die now.
13785instruct ShouldNotReachHere() %{
13786  match(Halt);
13787
13788  ins_cost(CALL_COST);
13789  format %{ "ShouldNotReachHere" %}
13790
13791  ins_encode %{
13792    // TODO
13793    // implement proper trap call here
13794    __ brk(999);
13795  %}
13796
13797  ins_pipe(pipe_class_default);
13798%}
13799
13800// ============================================================================
13801// Partial Subtype Check
13802//
13803// superklass array for an instance of the superklass.  Set a hidden
13804// internal cache on a hit (cache is checked with exposed code in
13805// gen_subtype_check()).  Return NZ for a miss or zero for a hit.  The
13806// encoding ALSO sets flags.
13807
13808instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr)
13809%{
13810  match(Set result (PartialSubtypeCheck sub super));
13811  effect(KILL cr, KILL temp);
13812
13813  ins_cost(1100);  // slightly larger than the next version
13814  format %{ "partialSubtypeCheck $result, $sub, $super" %}
13815
13816  ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
13817
13818  opcode(0x1); // Force zero of result reg on hit
13819
13820  ins_pipe(pipe_class_memory);
13821%}
13822
13823instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr)
13824%{
13825  match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
13826  effect(KILL temp, KILL result);
13827
13828  ins_cost(1100);  // slightly larger than the next version
13829  format %{ "partialSubtypeCheck $result, $sub, $super == 0" %}
13830
13831  ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
13832
13833  opcode(0x0); // Don't zero result reg on hit
13834
13835  ins_pipe(pipe_class_memory);
13836%}
13837
13838instruct string_compare(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
13839                        iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr)
13840%{
13841  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
13842  effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
13843
13844  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
13845  ins_encode %{
13846    __ string_compare($str1$$Register, $str2$$Register,
13847                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
13848                      $tmp1$$Register);
13849  %}
13850  ins_pipe(pipe_class_memory);
13851%}
13852
13853instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
13854       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
13855%{
13856  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
13857  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
13858         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
13859  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %}
13860
13861  ins_encode %{
13862    __ string_indexof($str1$$Register, $str2$$Register,
13863                      $cnt1$$Register, $cnt2$$Register,
13864                      $tmp1$$Register, $tmp2$$Register,
13865                      $tmp3$$Register, $tmp4$$Register,
13866                      -1, $result$$Register);
13867  %}
13868  ins_pipe(pipe_class_memory);
13869%}
13870
13871instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
13872                 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
13873                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
13874%{
13875  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
13876  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
13877         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
13878  format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result" %}
13879
13880  ins_encode %{
13881    int icnt2 = (int)$int_cnt2$$constant;
13882    __ string_indexof($str1$$Register, $str2$$Register,
13883                      $cnt1$$Register, zr,
13884                      $tmp1$$Register, $tmp2$$Register,
13885                      $tmp3$$Register, $tmp4$$Register,
13886                      icnt2, $result$$Register);
13887  %}
13888  ins_pipe(pipe_class_memory);
13889%}
13890
13891instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
13892                        iRegI_R0 result, iRegP_R10 tmp, rFlagsReg cr)
13893%{
13894  match(Set result (StrEquals (Binary str1 str2) cnt));
13895  effect(KILL tmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
13896
13897  format %{ "String Equals $str1,$str2,$cnt -> $result    // KILL $tmp" %}
13898  ins_encode %{
13899    __ string_equals($str1$$Register, $str2$$Register,
13900		      $cnt$$Register, $result$$Register,
13901                      $tmp$$Register);
13902  %}
13903  ins_pipe(pipe_class_memory);
13904%}
13905
13906instruct array_equals(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
13907                      iRegP_R10 tmp, rFlagsReg cr)
13908%{
13909  match(Set result (AryEq ary1 ary2));
13910  effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, KILL cr);
13911
13912  format %{ "Array Equals $ary1,ary2 -> $result    // KILL $tmp" %}
13913  ins_encode %{
13914    __ char_arrays_equals($ary1$$Register, $ary2$$Register,
13915                          $result$$Register, $tmp$$Register);
13916  %}
13917  ins_pipe(pipe_class_memory);
13918%}
13919
13920// encode char[] to byte[] in ISO_8859_1
13921instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
13922                          vRegD_V0 Vtmp1, vRegD_V1 Vtmp2,
13923                          vRegD_V2 Vtmp3, vRegD_V3 Vtmp4,
13924                          iRegI_R0 result, rFlagsReg cr)
13925%{
13926  match(Set result (EncodeISOArray src (Binary dst len)));
13927  effect(USE_KILL src, USE_KILL dst, USE_KILL len,
13928         KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr);
13929
13930  format %{ "Encode array $src,$dst,$len -> $result" %}
13931  ins_encode %{
13932    __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
13933         $result$$Register, $Vtmp1$$FloatRegister,  $Vtmp2$$FloatRegister,
13934         $Vtmp3$$FloatRegister,  $Vtmp4$$FloatRegister);
13935  %}
13936  ins_pipe( pipe_class_memory );
13937%}
13938
13939// ============================================================================
13940// This name is KNOWN by the ADLC and cannot be changed.
13941// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
13942// for this guy.
13943instruct tlsLoadP(thread_RegP dst)
13944%{
13945  match(Set dst (ThreadLocal));
13946
13947  ins_cost(0);
13948
13949  format %{ " -- \t// $dst=Thread::current(), empty" %}
13950
13951  size(0);
13952
13953  ins_encode( /*empty*/ );
13954
13955  ins_pipe(pipe_class_empty);
13956%}
13957
13958// ====================VECTOR INSTRUCTIONS=====================================
13959
13960// Load vector (32 bits)
13961instruct loadV4(vecD dst, vmem4 mem)
13962%{
13963  predicate(n->as_LoadVector()->memory_size() == 4);
13964  match(Set dst (LoadVector mem));
13965  ins_cost(4 * INSN_COST);
13966  format %{ "ldrs   $dst,$mem\t# vector (32 bits)" %}
13967  ins_encode( aarch64_enc_ldrvS(dst, mem) );
13968  ins_pipe(vload_reg_mem64);
13969%}
13970
13971// Load vector (64 bits)
13972instruct loadV8(vecD dst, vmem8 mem)
13973%{
13974  predicate(n->as_LoadVector()->memory_size() == 8);
13975  match(Set dst (LoadVector mem));
13976  ins_cost(4 * INSN_COST);
13977  format %{ "ldrd   $dst,$mem\t# vector (64 bits)" %}
13978  ins_encode( aarch64_enc_ldrvD(dst, mem) );
13979  ins_pipe(vload_reg_mem64);
13980%}
13981
13982// Load Vector (128 bits)
13983instruct loadV16(vecX dst, vmem16 mem)
13984%{
13985  predicate(n->as_LoadVector()->memory_size() == 16);
13986  match(Set dst (LoadVector mem));
13987  ins_cost(4 * INSN_COST);
13988  format %{ "ldrq   $dst,$mem\t# vector (128 bits)" %}
13989  ins_encode( aarch64_enc_ldrvQ(dst, mem) );
13990  ins_pipe(vload_reg_mem128);
13991%}
13992
13993// Store Vector (32 bits)
13994instruct storeV4(vecD src, vmem4 mem)
13995%{
13996  predicate(n->as_StoreVector()->memory_size() == 4);
13997  match(Set mem (StoreVector mem src));
13998  ins_cost(4 * INSN_COST);
13999  format %{ "strs   $mem,$src\t# vector (32 bits)" %}
14000  ins_encode( aarch64_enc_strvS(src, mem) );
14001  ins_pipe(vstore_reg_mem64);
14002%}
14003
14004// Store Vector (64 bits)
14005instruct storeV8(vecD src, vmem8 mem)
14006%{
14007  predicate(n->as_StoreVector()->memory_size() == 8);
14008  match(Set mem (StoreVector mem src));
14009  ins_cost(4 * INSN_COST);
14010  format %{ "strd   $mem,$src\t# vector (64 bits)" %}
14011  ins_encode( aarch64_enc_strvD(src, mem) );
14012  ins_pipe(vstore_reg_mem64);
14013%}
14014
14015// Store Vector (128 bits)
14016instruct storeV16(vecX src, vmem16 mem)
14017%{
14018  predicate(n->as_StoreVector()->memory_size() == 16);
14019  match(Set mem (StoreVector mem src));
14020  ins_cost(4 * INSN_COST);
14021  format %{ "strq   $mem,$src\t# vector (128 bits)" %}
14022  ins_encode( aarch64_enc_strvQ(src, mem) );
14023  ins_pipe(vstore_reg_mem128);
14024%}
14025
14026instruct replicate8B(vecD dst, iRegIorL2I src)
14027%{
14028  predicate(n->as_Vector()->length() == 4 ||
14029            n->as_Vector()->length() == 8);
14030  match(Set dst (ReplicateB src));
14031  ins_cost(INSN_COST);
14032  format %{ "dup  $dst, $src\t# vector (8B)" %}
14033  ins_encode %{
14034    __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg));
14035  %}
14036  ins_pipe(vdup_reg_reg64);
14037%}
14038
14039instruct replicate16B(vecX dst, iRegIorL2I src)
14040%{
14041  predicate(n->as_Vector()->length() == 16);
14042  match(Set dst (ReplicateB src));
14043  ins_cost(INSN_COST);
14044  format %{ "dup  $dst, $src\t# vector (16B)" %}
14045  ins_encode %{
14046    __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg));
14047  %}
14048  ins_pipe(vdup_reg_reg128);
14049%}
14050
14051instruct replicate8B_imm(vecD dst, immI con)
14052%{
14053  predicate(n->as_Vector()->length() == 4 ||
14054            n->as_Vector()->length() == 8);
14055  match(Set dst (ReplicateB con));
14056  ins_cost(INSN_COST);
14057  format %{ "movi  $dst, $con\t# vector(8B)" %}
14058  ins_encode %{
14059    __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff);
14060  %}
14061  ins_pipe(vmovi_reg_imm64);
14062%}
14063
14064instruct replicate16B_imm(vecX dst, immI con)
14065%{
14066  predicate(n->as_Vector()->length() == 16);
14067  match(Set dst (ReplicateB con));
14068  ins_cost(INSN_COST);
14069  format %{ "movi  $dst, $con\t# vector(16B)" %}
14070  ins_encode %{
14071    __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff);
14072  %}
14073  ins_pipe(vmovi_reg_imm128);
14074%}
14075
14076instruct replicate4S(vecD dst, iRegIorL2I src)
14077%{
14078  predicate(n->as_Vector()->length() == 2 ||
14079            n->as_Vector()->length() == 4);
14080  match(Set dst (ReplicateS src));
14081  ins_cost(INSN_COST);
14082  format %{ "dup  $dst, $src\t# vector (4S)" %}
14083  ins_encode %{
14084    __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg));
14085  %}
14086  ins_pipe(vdup_reg_reg64);
14087%}
14088
14089instruct replicate8S(vecX dst, iRegIorL2I src)
14090%{
14091  predicate(n->as_Vector()->length() == 8);
14092  match(Set dst (ReplicateS src));
14093  ins_cost(INSN_COST);
14094  format %{ "dup  $dst, $src\t# vector (8S)" %}
14095  ins_encode %{
14096    __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg));
14097  %}
14098  ins_pipe(vdup_reg_reg128);
14099%}
14100
14101instruct replicate4S_imm(vecD dst, immI con)
14102%{
14103  predicate(n->as_Vector()->length() == 2 ||
14104            n->as_Vector()->length() == 4);
14105  match(Set dst (ReplicateS con));
14106  ins_cost(INSN_COST);
14107  format %{ "movi  $dst, $con\t# vector(4H)" %}
14108  ins_encode %{
14109    __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff);
14110  %}
14111  ins_pipe(vmovi_reg_imm64);
14112%}
14113
14114instruct replicate8S_imm(vecX dst, immI con)
14115%{
14116  predicate(n->as_Vector()->length() == 8);
14117  match(Set dst (ReplicateS con));
14118  ins_cost(INSN_COST);
14119  format %{ "movi  $dst, $con\t# vector(8H)" %}
14120  ins_encode %{
14121    __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff);
14122  %}
14123  ins_pipe(vmovi_reg_imm128);
14124%}
14125
14126instruct replicate2I(vecD dst, iRegIorL2I src)
14127%{
14128  predicate(n->as_Vector()->length() == 2);
14129  match(Set dst (ReplicateI src));
14130  ins_cost(INSN_COST);
14131  format %{ "dup  $dst, $src\t# vector (2I)" %}
14132  ins_encode %{
14133    __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg));
14134  %}
14135  ins_pipe(vdup_reg_reg64);
14136%}
14137
14138instruct replicate4I(vecX dst, iRegIorL2I src)
14139%{
14140  predicate(n->as_Vector()->length() == 4);
14141  match(Set dst (ReplicateI src));
14142  ins_cost(INSN_COST);
14143  format %{ "dup  $dst, $src\t# vector (4I)" %}
14144  ins_encode %{
14145    __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg));
14146  %}
14147  ins_pipe(vdup_reg_reg128);
14148%}
14149
14150instruct replicate2I_imm(vecD dst, immI con)
14151%{
14152  predicate(n->as_Vector()->length() == 2);
14153  match(Set dst (ReplicateI con));
14154  ins_cost(INSN_COST);
14155  format %{ "movi  $dst, $con\t# vector(2I)" %}
14156  ins_encode %{
14157    __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant);
14158  %}
14159  ins_pipe(vmovi_reg_imm64);
14160%}
14161
14162instruct replicate4I_imm(vecX dst, immI con)
14163%{
14164  predicate(n->as_Vector()->length() == 4);
14165  match(Set dst (ReplicateI con));
14166  ins_cost(INSN_COST);
14167  format %{ "movi  $dst, $con\t# vector(4I)" %}
14168  ins_encode %{
14169    __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant);
14170  %}
14171  ins_pipe(vmovi_reg_imm128);
14172%}
14173
14174instruct replicate2L(vecX dst, iRegL src)
14175%{
14176  predicate(n->as_Vector()->length() == 2);
14177  match(Set dst (ReplicateL src));
14178  ins_cost(INSN_COST);
14179  format %{ "dup  $dst, $src\t# vector (2L)" %}
14180  ins_encode %{
14181    __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg));
14182  %}
14183  ins_pipe(vdup_reg_reg128);
14184%}
14185
14186instruct replicate2L_zero(vecX dst, immI0 zero)
14187%{
14188  predicate(n->as_Vector()->length() == 2);
14189  match(Set dst (ReplicateI zero));
14190  ins_cost(INSN_COST);
14191  format %{ "movi  $dst, $zero\t# vector(4I)" %}
14192  ins_encode %{
14193    __ eor(as_FloatRegister($dst$$reg), __ T16B,
14194           as_FloatRegister($dst$$reg),
14195           as_FloatRegister($dst$$reg));
14196  %}
14197  ins_pipe(vmovi_reg_imm128);
14198%}
14199
14200instruct replicate2F(vecD dst, vRegF src)
14201%{
14202  predicate(n->as_Vector()->length() == 2);
14203  match(Set dst (ReplicateF src));
14204  ins_cost(INSN_COST);
14205  format %{ "dup  $dst, $src\t# vector (2F)" %}
14206  ins_encode %{
14207    __ dup(as_FloatRegister($dst$$reg), __ T2S,
14208           as_FloatRegister($src$$reg));
14209  %}
14210  ins_pipe(vdup_reg_freg64);
14211%}
14212
14213instruct replicate4F(vecX dst, vRegF src)
14214%{
14215  predicate(n->as_Vector()->length() == 4);
14216  match(Set dst (ReplicateF src));
14217  ins_cost(INSN_COST);
14218  format %{ "dup  $dst, $src\t# vector (4F)" %}
14219  ins_encode %{
14220    __ dup(as_FloatRegister($dst$$reg), __ T4S,
14221           as_FloatRegister($src$$reg));
14222  %}
14223  ins_pipe(vdup_reg_freg128);
14224%}
14225
14226instruct replicate2D(vecX dst, vRegD src)
14227%{
14228  predicate(n->as_Vector()->length() == 2);
14229  match(Set dst (ReplicateD src));
14230  ins_cost(INSN_COST);
14231  format %{ "dup  $dst, $src\t# vector (2D)" %}
14232  ins_encode %{
14233    __ dup(as_FloatRegister($dst$$reg), __ T2D,
14234           as_FloatRegister($src$$reg));
14235  %}
14236  ins_pipe(vdup_reg_dreg128);
14237%}
14238
14239// ====================VECTOR ARITHMETIC=======================================
14240
14241// --------------------------------- ADD --------------------------------------
14242
14243instruct vadd8B(vecD dst, vecD src1, vecD src2)
14244%{
14245  predicate(n->as_Vector()->length() == 4 ||
14246            n->as_Vector()->length() == 8);
14247  match(Set dst (AddVB src1 src2));
14248  ins_cost(INSN_COST);
14249  format %{ "addv  $dst,$src1,$src2\t# vector (8B)" %}
14250  ins_encode %{
14251    __ addv(as_FloatRegister($dst$$reg), __ T8B,
14252            as_FloatRegister($src1$$reg),
14253            as_FloatRegister($src2$$reg));
14254  %}
14255  ins_pipe(vdop64);
14256%}
14257
14258instruct vadd16B(vecX dst, vecX src1, vecX src2)
14259%{
14260  predicate(n->as_Vector()->length() == 16);
14261  match(Set dst (AddVB src1 src2));
14262  ins_cost(INSN_COST);
14263  format %{ "addv  $dst,$src1,$src2\t# vector (16B)" %}
14264  ins_encode %{
14265    __ addv(as_FloatRegister($dst$$reg), __ T16B,
14266            as_FloatRegister($src1$$reg),
14267            as_FloatRegister($src2$$reg));
14268  %}
14269  ins_pipe(vdop128);
14270%}
14271
14272instruct vadd4S(vecD dst, vecD src1, vecD src2)
14273%{
14274  predicate(n->as_Vector()->length() == 2 ||
14275            n->as_Vector()->length() == 4);
14276  match(Set dst (AddVS src1 src2));
14277  ins_cost(INSN_COST);
14278  format %{ "addv  $dst,$src1,$src2\t# vector (4H)" %}
14279  ins_encode %{
14280    __ addv(as_FloatRegister($dst$$reg), __ T4H,
14281            as_FloatRegister($src1$$reg),
14282            as_FloatRegister($src2$$reg));
14283  %}
14284  ins_pipe(vdop64);
14285%}
14286
14287instruct vadd8S(vecX dst, vecX src1, vecX src2)
14288%{
14289  predicate(n->as_Vector()->length() == 8);
14290  match(Set dst (AddVS src1 src2));
14291  ins_cost(INSN_COST);
14292  format %{ "addv  $dst,$src1,$src2\t# vector (8H)" %}
14293  ins_encode %{
14294    __ addv(as_FloatRegister($dst$$reg), __ T8H,
14295            as_FloatRegister($src1$$reg),
14296            as_FloatRegister($src2$$reg));
14297  %}
14298  ins_pipe(vdop128);
14299%}
14300
14301instruct vadd2I(vecD dst, vecD src1, vecD src2)
14302%{
14303  predicate(n->as_Vector()->length() == 2);
14304  match(Set dst (AddVI src1 src2));
14305  ins_cost(INSN_COST);
14306  format %{ "addv  $dst,$src1,$src2\t# vector (2S)" %}
14307  ins_encode %{
14308    __ addv(as_FloatRegister($dst$$reg), __ T2S,
14309            as_FloatRegister($src1$$reg),
14310            as_FloatRegister($src2$$reg));
14311  %}
14312  ins_pipe(vdop64);
14313%}
14314
14315instruct vadd4I(vecX dst, vecX src1, vecX src2)
14316%{
14317  predicate(n->as_Vector()->length() == 4);
14318  match(Set dst (AddVI src1 src2));
14319  ins_cost(INSN_COST);
14320  format %{ "addv  $dst,$src1,$src2\t# vector (4S)" %}
14321  ins_encode %{
14322    __ addv(as_FloatRegister($dst$$reg), __ T4S,
14323            as_FloatRegister($src1$$reg),
14324            as_FloatRegister($src2$$reg));
14325  %}
14326  ins_pipe(vdop128);
14327%}
14328
14329instruct vadd2L(vecX dst, vecX src1, vecX src2)
14330%{
14331  predicate(n->as_Vector()->length() == 2);
14332  match(Set dst (AddVL src1 src2));
14333  ins_cost(INSN_COST);
14334  format %{ "addv  $dst,$src1,$src2\t# vector (2L)" %}
14335  ins_encode %{
14336    __ addv(as_FloatRegister($dst$$reg), __ T2D,
14337            as_FloatRegister($src1$$reg),
14338            as_FloatRegister($src2$$reg));
14339  %}
14340  ins_pipe(vdop128);
14341%}
14342
14343instruct vadd2F(vecD dst, vecD src1, vecD src2)
14344%{
14345  predicate(n->as_Vector()->length() == 2);
14346  match(Set dst (AddVF src1 src2));
14347  ins_cost(INSN_COST);
14348  format %{ "fadd  $dst,$src1,$src2\t# vector (2S)" %}
14349  ins_encode %{
14350    __ fadd(as_FloatRegister($dst$$reg), __ T2S,
14351            as_FloatRegister($src1$$reg),
14352            as_FloatRegister($src2$$reg));
14353  %}
14354  ins_pipe(vdop_fp64);
14355%}
14356
14357instruct vadd4F(vecX dst, vecX src1, vecX src2)
14358%{
14359  predicate(n->as_Vector()->length() == 4);
14360  match(Set dst (AddVF src1 src2));
14361  ins_cost(INSN_COST);
14362  format %{ "fadd  $dst,$src1,$src2\t# vector (4S)" %}
14363  ins_encode %{
14364    __ fadd(as_FloatRegister($dst$$reg), __ T4S,
14365            as_FloatRegister($src1$$reg),
14366            as_FloatRegister($src2$$reg));
14367  %}
14368  ins_pipe(vdop_fp128);
14369%}
14370
14371instruct vadd2D(vecX dst, vecX src1, vecX src2)
14372%{
14373  match(Set dst (AddVD src1 src2));
14374  ins_cost(INSN_COST);
14375  format %{ "fadd  $dst,$src1,$src2\t# vector (2D)" %}
14376  ins_encode %{
14377    __ fadd(as_FloatRegister($dst$$reg), __ T2D,
14378            as_FloatRegister($src1$$reg),
14379            as_FloatRegister($src2$$reg));
14380  %}
14381  ins_pipe(vdop_fp128);
14382%}
14383
14384// --------------------------------- SUB --------------------------------------
14385
14386instruct vsub8B(vecD dst, vecD src1, vecD src2)
14387%{
14388  predicate(n->as_Vector()->length() == 4 ||
14389            n->as_Vector()->length() == 8);
14390  match(Set dst (SubVB src1 src2));
14391  ins_cost(INSN_COST);
14392  format %{ "subv  $dst,$src1,$src2\t# vector (8B)" %}
14393  ins_encode %{
14394    __ subv(as_FloatRegister($dst$$reg), __ T8B,
14395            as_FloatRegister($src1$$reg),
14396            as_FloatRegister($src2$$reg));
14397  %}
14398  ins_pipe(vdop64);
14399%}
14400
14401instruct vsub16B(vecX dst, vecX src1, vecX src2)
14402%{
14403  predicate(n->as_Vector()->length() == 16);
14404  match(Set dst (SubVB src1 src2));
14405  ins_cost(INSN_COST);
14406  format %{ "subv  $dst,$src1,$src2\t# vector (16B)" %}
14407  ins_encode %{
14408    __ subv(as_FloatRegister($dst$$reg), __ T16B,
14409            as_FloatRegister($src1$$reg),
14410            as_FloatRegister($src2$$reg));
14411  %}
14412  ins_pipe(vdop128);
14413%}
14414
14415instruct vsub4S(vecD dst, vecD src1, vecD src2)
14416%{
14417  predicate(n->as_Vector()->length() == 2 ||
14418            n->as_Vector()->length() == 4);
14419  match(Set dst (SubVS src1 src2));
14420  ins_cost(INSN_COST);
14421  format %{ "subv  $dst,$src1,$src2\t# vector (4H)" %}
14422  ins_encode %{
14423    __ subv(as_FloatRegister($dst$$reg), __ T4H,
14424            as_FloatRegister($src1$$reg),
14425            as_FloatRegister($src2$$reg));
14426  %}
14427  ins_pipe(vdop64);
14428%}
14429
14430instruct vsub8S(vecX dst, vecX src1, vecX src2)
14431%{
14432  predicate(n->as_Vector()->length() == 8);
14433  match(Set dst (SubVS src1 src2));
14434  ins_cost(INSN_COST);
14435  format %{ "subv  $dst,$src1,$src2\t# vector (8H)" %}
14436  ins_encode %{
14437    __ subv(as_FloatRegister($dst$$reg), __ T8H,
14438            as_FloatRegister($src1$$reg),
14439            as_FloatRegister($src2$$reg));
14440  %}
14441  ins_pipe(vdop128);
14442%}
14443
14444instruct vsub2I(vecD dst, vecD src1, vecD src2)
14445%{
14446  predicate(n->as_Vector()->length() == 2);
14447  match(Set dst (SubVI src1 src2));
14448  ins_cost(INSN_COST);
14449  format %{ "subv  $dst,$src1,$src2\t# vector (2S)" %}
14450  ins_encode %{
14451    __ subv(as_FloatRegister($dst$$reg), __ T2S,
14452            as_FloatRegister($src1$$reg),
14453            as_FloatRegister($src2$$reg));
14454  %}
14455  ins_pipe(vdop64);
14456%}
14457
14458instruct vsub4I(vecX dst, vecX src1, vecX src2)
14459%{
14460  predicate(n->as_Vector()->length() == 4);
14461  match(Set dst (SubVI src1 src2));
14462  ins_cost(INSN_COST);
14463  format %{ "subv  $dst,$src1,$src2\t# vector (4S)" %}
14464  ins_encode %{
14465    __ subv(as_FloatRegister($dst$$reg), __ T4S,
14466            as_FloatRegister($src1$$reg),
14467            as_FloatRegister($src2$$reg));
14468  %}
14469  ins_pipe(vdop128);
14470%}
14471
14472instruct vsub2L(vecX dst, vecX src1, vecX src2)
14473%{
14474  predicate(n->as_Vector()->length() == 2);
14475  match(Set dst (SubVL src1 src2));
14476  ins_cost(INSN_COST);
14477  format %{ "subv  $dst,$src1,$src2\t# vector (2L)" %}
14478  ins_encode %{
14479    __ subv(as_FloatRegister($dst$$reg), __ T2D,
14480            as_FloatRegister($src1$$reg),
14481            as_FloatRegister($src2$$reg));
14482  %}
14483  ins_pipe(vdop128);
14484%}
14485
14486instruct vsub2F(vecD dst, vecD src1, vecD src2)
14487%{
14488  predicate(n->as_Vector()->length() == 2);
14489  match(Set dst (SubVF src1 src2));
14490  ins_cost(INSN_COST);
14491  format %{ "fsub  $dst,$src1,$src2\t# vector (2S)" %}
14492  ins_encode %{
14493    __ fsub(as_FloatRegister($dst$$reg), __ T2S,
14494            as_FloatRegister($src1$$reg),
14495            as_FloatRegister($src2$$reg));
14496  %}
14497  ins_pipe(vdop_fp64);
14498%}
14499
14500instruct vsub4F(vecX dst, vecX src1, vecX src2)
14501%{
14502  predicate(n->as_Vector()->length() == 4);
14503  match(Set dst (SubVF src1 src2));
14504  ins_cost(INSN_COST);
14505  format %{ "fsub  $dst,$src1,$src2\t# vector (4S)" %}
14506  ins_encode %{
14507    __ fsub(as_FloatRegister($dst$$reg), __ T4S,
14508            as_FloatRegister($src1$$reg),
14509            as_FloatRegister($src2$$reg));
14510  %}
14511  ins_pipe(vdop_fp128);
14512%}
14513
14514instruct vsub2D(vecX dst, vecX src1, vecX src2)
14515%{
14516  predicate(n->as_Vector()->length() == 2);
14517  match(Set dst (SubVD src1 src2));
14518  ins_cost(INSN_COST);
14519  format %{ "fsub  $dst,$src1,$src2\t# vector (2D)" %}
14520  ins_encode %{
14521    __ fsub(as_FloatRegister($dst$$reg), __ T2D,
14522            as_FloatRegister($src1$$reg),
14523            as_FloatRegister($src2$$reg));
14524  %}
14525  ins_pipe(vdop_fp128);
14526%}
14527
14528// --------------------------------- MUL --------------------------------------
14529
14530instruct vmul4S(vecD dst, vecD src1, vecD src2)
14531%{
14532  predicate(n->as_Vector()->length() == 2 ||
14533            n->as_Vector()->length() == 4);
14534  match(Set dst (MulVS src1 src2));
14535  ins_cost(INSN_COST);
14536  format %{ "mulv  $dst,$src1,$src2\t# vector (4H)" %}
14537  ins_encode %{
14538    __ mulv(as_FloatRegister($dst$$reg), __ T4H,
14539            as_FloatRegister($src1$$reg),
14540            as_FloatRegister($src2$$reg));
14541  %}
14542  ins_pipe(vmul64);
14543%}
14544
14545instruct vmul8S(vecX dst, vecX src1, vecX src2)
14546%{
14547  predicate(n->as_Vector()->length() == 8);
14548  match(Set dst (MulVS src1 src2));
14549  ins_cost(INSN_COST);
14550  format %{ "mulv  $dst,$src1,$src2\t# vector (8H)" %}
14551  ins_encode %{
14552    __ mulv(as_FloatRegister($dst$$reg), __ T8H,
14553            as_FloatRegister($src1$$reg),
14554            as_FloatRegister($src2$$reg));
14555  %}
14556  ins_pipe(vmul128);
14557%}
14558
14559instruct vmul2I(vecD dst, vecD src1, vecD src2)
14560%{
14561  predicate(n->as_Vector()->length() == 2);
14562  match(Set dst (MulVI src1 src2));
14563  ins_cost(INSN_COST);
14564  format %{ "mulv  $dst,$src1,$src2\t# vector (2S)" %}
14565  ins_encode %{
14566    __ mulv(as_FloatRegister($dst$$reg), __ T2S,
14567            as_FloatRegister($src1$$reg),
14568            as_FloatRegister($src2$$reg));
14569  %}
14570  ins_pipe(vmul64);
14571%}
14572
14573instruct vmul4I(vecX dst, vecX src1, vecX src2)
14574%{
14575  predicate(n->as_Vector()->length() == 4);
14576  match(Set dst (MulVI src1 src2));
14577  ins_cost(INSN_COST);
14578  format %{ "mulv  $dst,$src1,$src2\t# vector (4S)" %}
14579  ins_encode %{
14580    __ mulv(as_FloatRegister($dst$$reg), __ T4S,
14581            as_FloatRegister($src1$$reg),
14582            as_FloatRegister($src2$$reg));
14583  %}
14584  ins_pipe(vmul128);
14585%}
14586
14587instruct vmul2F(vecD dst, vecD src1, vecD src2)
14588%{
14589  predicate(n->as_Vector()->length() == 2);
14590  match(Set dst (MulVF src1 src2));
14591  ins_cost(INSN_COST);
14592  format %{ "fmul  $dst,$src1,$src2\t# vector (2S)" %}
14593  ins_encode %{
14594    __ fmul(as_FloatRegister($dst$$reg), __ T2S,
14595            as_FloatRegister($src1$$reg),
14596            as_FloatRegister($src2$$reg));
14597  %}
14598  ins_pipe(vmuldiv_fp64);
14599%}
14600
14601instruct vmul4F(vecX dst, vecX src1, vecX src2)
14602%{
14603  predicate(n->as_Vector()->length() == 4);
14604  match(Set dst (MulVF src1 src2));
14605  ins_cost(INSN_COST);
14606  format %{ "fmul  $dst,$src1,$src2\t# vector (4S)" %}
14607  ins_encode %{
14608    __ fmul(as_FloatRegister($dst$$reg), __ T4S,
14609            as_FloatRegister($src1$$reg),
14610            as_FloatRegister($src2$$reg));
14611  %}
14612  ins_pipe(vmuldiv_fp128);
14613%}
14614
14615instruct vmul2D(vecX dst, vecX src1, vecX src2)
14616%{
14617  predicate(n->as_Vector()->length() == 2);
14618  match(Set dst (MulVD src1 src2));
14619  ins_cost(INSN_COST);
14620  format %{ "fmul  $dst,$src1,$src2\t# vector (2D)" %}
14621  ins_encode %{
14622    __ fmul(as_FloatRegister($dst$$reg), __ T2D,
14623            as_FloatRegister($src1$$reg),
14624            as_FloatRegister($src2$$reg));
14625  %}
14626  ins_pipe(vmuldiv_fp128);
14627%}
14628
14629// --------------------------------- MLA --------------------------------------
14630
14631instruct vmla4S(vecD dst, vecD src1, vecD src2)
14632%{
14633  predicate(n->as_Vector()->length() == 2 ||
14634            n->as_Vector()->length() == 4);
14635  match(Set dst (AddVS dst (MulVS src1 src2)));
14636  ins_cost(INSN_COST);
14637  format %{ "mlav  $dst,$src1,$src2\t# vector (4H)" %}
14638  ins_encode %{
14639    __ mlav(as_FloatRegister($dst$$reg), __ T4H,
14640            as_FloatRegister($src1$$reg),
14641            as_FloatRegister($src2$$reg));
14642  %}
14643  ins_pipe(vmla64);
14644%}
14645
14646instruct vmla8S(vecX dst, vecX src1, vecX src2)
14647%{
14648  predicate(n->as_Vector()->length() == 8);
14649  match(Set dst (AddVS dst (MulVS src1 src2)));
14650  ins_cost(INSN_COST);
14651  format %{ "mlav  $dst,$src1,$src2\t# vector (8H)" %}
14652  ins_encode %{
14653    __ mlav(as_FloatRegister($dst$$reg), __ T8H,
14654            as_FloatRegister($src1$$reg),
14655            as_FloatRegister($src2$$reg));
14656  %}
14657  ins_pipe(vmla128);
14658%}
14659
14660instruct vmla2I(vecD dst, vecD src1, vecD src2)
14661%{
14662  predicate(n->as_Vector()->length() == 2);
14663  match(Set dst (AddVI dst (MulVI src1 src2)));
14664  ins_cost(INSN_COST);
14665  format %{ "mlav  $dst,$src1,$src2\t# vector (2S)" %}
14666  ins_encode %{
14667    __ mlav(as_FloatRegister($dst$$reg), __ T2S,
14668            as_FloatRegister($src1$$reg),
14669            as_FloatRegister($src2$$reg));
14670  %}
14671  ins_pipe(vmla64);
14672%}
14673
14674instruct vmla4I(vecX dst, vecX src1, vecX src2)
14675%{
14676  predicate(n->as_Vector()->length() == 4);
14677  match(Set dst (AddVI dst (MulVI src1 src2)));
14678  ins_cost(INSN_COST);
14679  format %{ "mlav  $dst,$src1,$src2\t# vector (4S)" %}
14680  ins_encode %{
14681    __ mlav(as_FloatRegister($dst$$reg), __ T4S,
14682            as_FloatRegister($src1$$reg),
14683            as_FloatRegister($src2$$reg));
14684  %}
14685  ins_pipe(vmla128);
14686%}
14687
14688// --------------------------------- MLS --------------------------------------
14689
14690instruct vmls4S(vecD dst, vecD src1, vecD src2)
14691%{
14692  predicate(n->as_Vector()->length() == 2 ||
14693            n->as_Vector()->length() == 4);
14694  match(Set dst (SubVS dst (MulVS src1 src2)));
14695  ins_cost(INSN_COST);
14696  format %{ "mlsv  $dst,$src1,$src2\t# vector (4H)" %}
14697  ins_encode %{
14698    __ mlsv(as_FloatRegister($dst$$reg), __ T4H,
14699            as_FloatRegister($src1$$reg),
14700            as_FloatRegister($src2$$reg));
14701  %}
14702  ins_pipe(vmla64);
14703%}
14704
14705instruct vmls8S(vecX dst, vecX src1, vecX src2)
14706%{
14707  predicate(n->as_Vector()->length() == 8);
14708  match(Set dst (SubVS dst (MulVS src1 src2)));
14709  ins_cost(INSN_COST);
14710  format %{ "mlsv  $dst,$src1,$src2\t# vector (8H)" %}
14711  ins_encode %{
14712    __ mlsv(as_FloatRegister($dst$$reg), __ T8H,
14713            as_FloatRegister($src1$$reg),
14714            as_FloatRegister($src2$$reg));
14715  %}
14716  ins_pipe(vmla128);
14717%}
14718
14719instruct vmls2I(vecD dst, vecD src1, vecD src2)
14720%{
14721  predicate(n->as_Vector()->length() == 2);
14722  match(Set dst (SubVI dst (MulVI src1 src2)));
14723  ins_cost(INSN_COST);
14724  format %{ "mlsv  $dst,$src1,$src2\t# vector (2S)" %}
14725  ins_encode %{
14726    __ mlsv(as_FloatRegister($dst$$reg), __ T2S,
14727            as_FloatRegister($src1$$reg),
14728            as_FloatRegister($src2$$reg));
14729  %}
14730  ins_pipe(vmla64);
14731%}
14732
14733instruct vmls4I(vecX dst, vecX src1, vecX src2)
14734%{
14735  predicate(n->as_Vector()->length() == 4);
14736  match(Set dst (SubVI dst (MulVI src1 src2)));
14737  ins_cost(INSN_COST);
14738  format %{ "mlsv  $dst,$src1,$src2\t# vector (4S)" %}
14739  ins_encode %{
14740    __ mlsv(as_FloatRegister($dst$$reg), __ T4S,
14741            as_FloatRegister($src1$$reg),
14742            as_FloatRegister($src2$$reg));
14743  %}
14744  ins_pipe(vmla128);
14745%}
14746
14747// --------------------------------- DIV --------------------------------------
14748
14749instruct vdiv2F(vecD dst, vecD src1, vecD src2)
14750%{
14751  predicate(n->as_Vector()->length() == 2);
14752  match(Set dst (DivVF src1 src2));
14753  ins_cost(INSN_COST);
14754  format %{ "fdiv  $dst,$src1,$src2\t# vector (2S)" %}
14755  ins_encode %{
14756    __ fdiv(as_FloatRegister($dst$$reg), __ T2S,
14757            as_FloatRegister($src1$$reg),
14758            as_FloatRegister($src2$$reg));
14759  %}
14760  ins_pipe(vmuldiv_fp64);
14761%}
14762
14763instruct vdiv4F(vecX dst, vecX src1, vecX src2)
14764%{
14765  predicate(n->as_Vector()->length() == 4);
14766  match(Set dst (DivVF src1 src2));
14767  ins_cost(INSN_COST);
14768  format %{ "fdiv  $dst,$src1,$src2\t# vector (4S)" %}
14769  ins_encode %{
14770    __ fdiv(as_FloatRegister($dst$$reg), __ T4S,
14771            as_FloatRegister($src1$$reg),
14772            as_FloatRegister($src2$$reg));
14773  %}
14774  ins_pipe(vmuldiv_fp128);
14775%}
14776
14777instruct vdiv2D(vecX dst, vecX src1, vecX src2)
14778%{
14779  predicate(n->as_Vector()->length() == 2);
14780  match(Set dst (DivVD src1 src2));
14781  ins_cost(INSN_COST);
14782  format %{ "fdiv  $dst,$src1,$src2\t# vector (2D)" %}
14783  ins_encode %{
14784    __ fdiv(as_FloatRegister($dst$$reg), __ T2D,
14785            as_FloatRegister($src1$$reg),
14786            as_FloatRegister($src2$$reg));
14787  %}
14788  ins_pipe(vmuldiv_fp128);
14789%}
14790
14791// --------------------------------- AND --------------------------------------
14792
14793instruct vand8B(vecD dst, vecD src1, vecD src2)
14794%{
14795  predicate(n->as_Vector()->length_in_bytes() == 4 ||
14796            n->as_Vector()->length_in_bytes() == 8);
14797  match(Set dst (AndV src1 src2));
14798  ins_cost(INSN_COST);
14799  format %{ "and  $dst,$src1,$src2\t# vector (8B)" %}
14800  ins_encode %{
14801    __ andr(as_FloatRegister($dst$$reg), __ T8B,
14802            as_FloatRegister($src1$$reg),
14803            as_FloatRegister($src2$$reg));
14804  %}
14805  ins_pipe(vlogical64);
14806%}
14807
14808instruct vand16B(vecX dst, vecX src1, vecX src2)
14809%{
14810  predicate(n->as_Vector()->length_in_bytes() == 16);
14811  match(Set dst (AndV src1 src2));
14812  ins_cost(INSN_COST);
14813  format %{ "and  $dst,$src1,$src2\t# vector (16B)" %}
14814  ins_encode %{
14815    __ andr(as_FloatRegister($dst$$reg), __ T16B,
14816            as_FloatRegister($src1$$reg),
14817            as_FloatRegister($src2$$reg));
14818  %}
14819  ins_pipe(vlogical128);
14820%}
14821
14822// --------------------------------- OR ---------------------------------------
14823
14824instruct vor8B(vecD dst, vecD src1, vecD src2)
14825%{
14826  predicate(n->as_Vector()->length_in_bytes() == 4 ||
14827            n->as_Vector()->length_in_bytes() == 8);
14828  match(Set dst (OrV src1 src2));
14829  ins_cost(INSN_COST);
14830  format %{ "and  $dst,$src1,$src2\t# vector (8B)" %}
14831  ins_encode %{
14832    __ orr(as_FloatRegister($dst$$reg), __ T8B,
14833            as_FloatRegister($src1$$reg),
14834            as_FloatRegister($src2$$reg));
14835  %}
14836  ins_pipe(vlogical64);
14837%}
14838
14839instruct vor16B(vecX dst, vecX src1, vecX src2)
14840%{
14841  predicate(n->as_Vector()->length_in_bytes() == 16);
14842  match(Set dst (OrV src1 src2));
14843  ins_cost(INSN_COST);
14844  format %{ "orr  $dst,$src1,$src2\t# vector (16B)" %}
14845  ins_encode %{
14846    __ orr(as_FloatRegister($dst$$reg), __ T16B,
14847            as_FloatRegister($src1$$reg),
14848            as_FloatRegister($src2$$reg));
14849  %}
14850  ins_pipe(vlogical128);
14851%}
14852
14853// --------------------------------- XOR --------------------------------------
14854
14855instruct vxor8B(vecD dst, vecD src1, vecD src2)
14856%{
14857  predicate(n->as_Vector()->length_in_bytes() == 4 ||
14858            n->as_Vector()->length_in_bytes() == 8);
14859  match(Set dst (XorV src1 src2));
14860  ins_cost(INSN_COST);
14861  format %{ "xor  $dst,$src1,$src2\t# vector (8B)" %}
14862  ins_encode %{
14863    __ eor(as_FloatRegister($dst$$reg), __ T8B,
14864            as_FloatRegister($src1$$reg),
14865            as_FloatRegister($src2$$reg));
14866  %}
14867  ins_pipe(vlogical64);
14868%}
14869
14870instruct vxor16B(vecX dst, vecX src1, vecX src2)
14871%{
14872  predicate(n->as_Vector()->length_in_bytes() == 16);
14873  match(Set dst (XorV src1 src2));
14874  ins_cost(INSN_COST);
14875  format %{ "xor  $dst,$src1,$src2\t# vector (16B)" %}
14876  ins_encode %{
14877    __ eor(as_FloatRegister($dst$$reg), __ T16B,
14878            as_FloatRegister($src1$$reg),
14879            as_FloatRegister($src2$$reg));
14880  %}
14881  ins_pipe(vlogical128);
14882%}
14883
14884// ------------------------------ Shift ---------------------------------------
14885instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{
14886  predicate(n->as_Vector()->length_in_bytes() == 8);
14887  match(Set dst (LShiftCntV cnt));
14888  match(Set dst (RShiftCntV cnt));
14889  format %{ "dup  $dst, $cnt\t# shift count vector (8B)" %}
14890  ins_encode %{
14891    __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg));
14892  %}
14893  ins_pipe(vdup_reg_reg64);
14894%}
14895
14896instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{
14897  predicate(n->as_Vector()->length_in_bytes() == 16);
14898  match(Set dst (LShiftCntV cnt));
14899  match(Set dst (RShiftCntV cnt));
14900  format %{ "dup  $dst, $cnt\t# shift count vector (16B)" %}
14901  ins_encode %{
14902    __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg));
14903  %}
14904  ins_pipe(vdup_reg_reg128);
14905%}
14906
14907instruct vsll8B(vecD dst, vecD src, vecD shift) %{
14908  predicate(n->as_Vector()->length() == 4 ||
14909            n->as_Vector()->length() == 8);
14910  match(Set dst (LShiftVB src shift));
14911  ins_cost(INSN_COST);
14912  format %{ "sshl  $dst,$src,$shift\t# vector (8B)" %}
14913  ins_encode %{
14914    __ sshl(as_FloatRegister($dst$$reg), __ T8B,
14915            as_FloatRegister($src$$reg),
14916            as_FloatRegister($shift$$reg));
14917  %}
14918  ins_pipe(vshift64);
14919%}
14920
14921instruct vsll16B(vecX dst, vecX src, vecX shift) %{
14922  predicate(n->as_Vector()->length() == 16);
14923  match(Set dst (LShiftVB src shift));
14924  ins_cost(INSN_COST);
14925  format %{ "sshl  $dst,$src,$shift\t# vector (16B)" %}
14926  ins_encode %{
14927    __ sshl(as_FloatRegister($dst$$reg), __ T16B,
14928            as_FloatRegister($src$$reg),
14929            as_FloatRegister($shift$$reg));
14930  %}
14931  ins_pipe(vshift128);
14932%}
14933
14934// Right shifts with vector shift count on aarch64 SIMD are implemented
14935// as left shift by negative shift count.
14936// There are two cases for vector shift count.
14937//
14938// Case 1: The vector shift count is from replication.
14939//        |            |
14940//    LoadVector  RShiftCntV
14941//        |       /
14942//     RShiftVI
14943// Note: In inner loop, multiple neg instructions are used, which can be
14944// moved to outer loop and merge into one neg instruction.
14945//
14946// Case 2: The vector shift count is from loading.
14947// This case isn't supported by middle-end now. But it's supported by
14948// panama/vectorIntrinsics(JEP 338: Vector API).
14949//        |            |
14950//    LoadVector  LoadVector
14951//        |       /
14952//     RShiftVI
14953//
14954
14955instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{
14956  predicate(n->as_Vector()->length() == 4 ||
14957            n->as_Vector()->length() == 8);
14958  match(Set dst (RShiftVB src shift));
14959  ins_cost(INSN_COST);
14960  effect(TEMP tmp);
14961  format %{ "negr  $tmp,$shift\t"
14962            "sshl  $dst,$src,$tmp\t# vector (8B)" %}
14963  ins_encode %{
14964    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
14965            as_FloatRegister($shift$$reg));
14966    __ sshl(as_FloatRegister($dst$$reg), __ T8B,
14967            as_FloatRegister($src$$reg),
14968            as_FloatRegister($tmp$$reg));
14969  %}
14970  ins_pipe(vshift64);
14971%}
14972
14973instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{
14974  predicate(n->as_Vector()->length() == 16);
14975  match(Set dst (RShiftVB src shift));
14976  ins_cost(INSN_COST);
14977  effect(TEMP tmp);
14978  format %{ "negr  $tmp,$shift\t"
14979            "sshl  $dst,$src,$tmp\t# vector (16B)" %}
14980  ins_encode %{
14981    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
14982            as_FloatRegister($shift$$reg));
14983    __ sshl(as_FloatRegister($dst$$reg), __ T16B,
14984            as_FloatRegister($src$$reg),
14985            as_FloatRegister($tmp$$reg));
14986  %}
14987  ins_pipe(vshift128);
14988%}
14989
14990instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{
14991  predicate(n->as_Vector()->length() == 4 ||
14992            n->as_Vector()->length() == 8);
14993  match(Set dst (URShiftVB src shift));
14994  ins_cost(INSN_COST);
14995  effect(TEMP tmp);
14996  format %{ "negr  $tmp,$shift\t"
14997            "ushl  $dst,$src,$tmp\t# vector (8B)" %}
14998  ins_encode %{
14999    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
15000            as_FloatRegister($shift$$reg));
15001    __ ushl(as_FloatRegister($dst$$reg), __ T8B,
15002            as_FloatRegister($src$$reg),
15003            as_FloatRegister($tmp$$reg));
15004  %}
15005  ins_pipe(vshift64);
15006%}
15007
15008instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{
15009  predicate(n->as_Vector()->length() == 16);
15010  match(Set dst (URShiftVB src shift));
15011  ins_cost(INSN_COST);
15012  effect(TEMP tmp);
15013  format %{ "negr  $tmp,$shift\t"
15014            "ushl  $dst,$src,$tmp\t# vector (16B)" %}
15015  ins_encode %{
15016    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
15017            as_FloatRegister($shift$$reg));
15018    __ ushl(as_FloatRegister($dst$$reg), __ T16B,
15019            as_FloatRegister($src$$reg),
15020            as_FloatRegister($tmp$$reg));
15021  %}
15022  ins_pipe(vshift128);
15023%}
15024
15025instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{
15026  predicate(n->as_Vector()->length() == 4 ||
15027            n->as_Vector()->length() == 8);
15028  match(Set dst (LShiftVB src shift));
15029  ins_cost(INSN_COST);
15030  format %{ "shl    $dst, $src, $shift\t# vector (8B)" %}
15031  ins_encode %{
15032    int sh = (int)$shift$$constant & 31;
15033    if (sh >= 8) {
15034      __ eor(as_FloatRegister($dst$$reg), __ T8B,
15035             as_FloatRegister($src$$reg),
15036             as_FloatRegister($src$$reg));
15037    } else {
15038      __ shl(as_FloatRegister($dst$$reg), __ T8B,
15039             as_FloatRegister($src$$reg), sh);
15040    }
15041  %}
15042  ins_pipe(vshift64_imm);
15043%}
15044
15045instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{
15046  predicate(n->as_Vector()->length() == 16);
15047  match(Set dst (LShiftVB src shift));
15048  ins_cost(INSN_COST);
15049  format %{ "shl    $dst, $src, $shift\t# vector (16B)" %}
15050  ins_encode %{
15051    int sh = (int)$shift$$constant & 31;
15052    if (sh >= 8) {
15053      __ eor(as_FloatRegister($dst$$reg), __ T16B,
15054             as_FloatRegister($src$$reg),
15055             as_FloatRegister($src$$reg));
15056    } else {
15057      __ shl(as_FloatRegister($dst$$reg), __ T16B,
15058             as_FloatRegister($src$$reg), sh);
15059    }
15060  %}
15061  ins_pipe(vshift128_imm);
15062%}
15063
15064instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{
15065  predicate(n->as_Vector()->length() == 4 ||
15066            n->as_Vector()->length() == 8);
15067  match(Set dst (RShiftVB src shift));
15068  ins_cost(INSN_COST);
15069  format %{ "sshr    $dst, $src, $shift\t# vector (8B)" %}
15070  ins_encode %{
15071    int sh = (int)$shift$$constant & 31;
15072    if (sh >= 8) sh = 7;
15073    sh = -sh & 7;
15074    __ sshr(as_FloatRegister($dst$$reg), __ T8B,
15075           as_FloatRegister($src$$reg), sh);
15076  %}
15077  ins_pipe(vshift64_imm);
15078%}
15079
15080instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{
15081  predicate(n->as_Vector()->length() == 16);
15082  match(Set dst (RShiftVB src shift));
15083  ins_cost(INSN_COST);
15084  format %{ "sshr    $dst, $src, $shift\t# vector (16B)" %}
15085  ins_encode %{
15086    int sh = (int)$shift$$constant & 31;
15087    if (sh >= 8) sh = 7;
15088    sh = -sh & 7;
15089    __ sshr(as_FloatRegister($dst$$reg), __ T16B,
15090           as_FloatRegister($src$$reg), sh);
15091  %}
15092  ins_pipe(vshift128_imm);
15093%}
15094
15095instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{
15096  predicate(n->as_Vector()->length() == 4 ||
15097            n->as_Vector()->length() == 8);
15098  match(Set dst (URShiftVB src shift));
15099  ins_cost(INSN_COST);
15100  format %{ "ushr    $dst, $src, $shift\t# vector (8B)" %}
15101  ins_encode %{
15102    int sh = (int)$shift$$constant & 31;
15103    if (sh >= 8) {
15104      __ eor(as_FloatRegister($dst$$reg), __ T8B,
15105             as_FloatRegister($src$$reg),
15106             as_FloatRegister($src$$reg));
15107    } else {
15108      __ ushr(as_FloatRegister($dst$$reg), __ T8B,
15109             as_FloatRegister($src$$reg), -sh & 7);
15110    }
15111  %}
15112  ins_pipe(vshift64_imm);
15113%}
15114
15115instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{
15116  predicate(n->as_Vector()->length() == 16);
15117  match(Set dst (URShiftVB src shift));
15118  ins_cost(INSN_COST);
15119  format %{ "ushr    $dst, $src, $shift\t# vector (16B)" %}
15120  ins_encode %{
15121    int sh = (int)$shift$$constant & 31;
15122    if (sh >= 8) {
15123      __ eor(as_FloatRegister($dst$$reg), __ T16B,
15124             as_FloatRegister($src$$reg),
15125             as_FloatRegister($src$$reg));
15126    } else {
15127      __ ushr(as_FloatRegister($dst$$reg), __ T16B,
15128             as_FloatRegister($src$$reg), -sh & 7);
15129    }
15130  %}
15131  ins_pipe(vshift128_imm);
15132%}
15133
15134instruct vsll4S(vecD dst, vecD src, vecD shift) %{
15135  predicate(n->as_Vector()->length() == 2 ||
15136            n->as_Vector()->length() == 4);
15137  match(Set dst (LShiftVS src shift));
15138  ins_cost(INSN_COST);
15139  format %{ "sshl  $dst,$src,$shift\t# vector (4H)" %}
15140  ins_encode %{
15141    __ sshl(as_FloatRegister($dst$$reg), __ T4H,
15142            as_FloatRegister($src$$reg),
15143            as_FloatRegister($shift$$reg));
15144  %}
15145  ins_pipe(vshift64);
15146%}
15147
15148instruct vsll8S(vecX dst, vecX src, vecX shift) %{
15149  predicate(n->as_Vector()->length() == 8);
15150  match(Set dst (LShiftVS src shift));
15151  ins_cost(INSN_COST);
15152  format %{ "sshl  $dst,$src,$shift\t# vector (8H)" %}
15153  ins_encode %{
15154    __ sshl(as_FloatRegister($dst$$reg), __ T8H,
15155            as_FloatRegister($src$$reg),
15156            as_FloatRegister($shift$$reg));
15157  %}
15158  ins_pipe(vshift128);
15159%}
15160
15161instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{
15162  predicate(n->as_Vector()->length() == 2 ||
15163            n->as_Vector()->length() == 4);
15164  match(Set dst (RShiftVS src shift));
15165  ins_cost(INSN_COST);
15166  effect(TEMP tmp);
15167  format %{ "negr  $tmp,$shift\t"
15168            "sshl  $dst,$src,$tmp\t# vector (4H)" %}
15169  ins_encode %{
15170    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
15171            as_FloatRegister($shift$$reg));
15172    __ sshl(as_FloatRegister($dst$$reg), __ T4H,
15173            as_FloatRegister($src$$reg),
15174            as_FloatRegister($tmp$$reg));
15175  %}
15176  ins_pipe(vshift64);
15177%}
15178
15179instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{
15180  predicate(n->as_Vector()->length() == 8);
15181  match(Set dst (RShiftVS src shift));
15182  ins_cost(INSN_COST);
15183  effect(TEMP tmp);
15184  format %{ "negr  $tmp,$shift\t"
15185            "sshl  $dst,$src,$tmp\t# vector (8H)" %}
15186  ins_encode %{
15187    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
15188            as_FloatRegister($shift$$reg));
15189    __ sshl(as_FloatRegister($dst$$reg), __ T8H,
15190            as_FloatRegister($src$$reg),
15191            as_FloatRegister($tmp$$reg));
15192  %}
15193  ins_pipe(vshift128);
15194%}
15195
15196instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{
15197  predicate(n->as_Vector()->length() == 2 ||
15198            n->as_Vector()->length() == 4);
15199  match(Set dst (URShiftVS src shift));
15200  ins_cost(INSN_COST);
15201  effect(TEMP tmp);
15202  format %{ "negr  $tmp,$shift\t"
15203            "ushl  $dst,$src,$tmp\t# vector (4H)" %}
15204  ins_encode %{
15205    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
15206            as_FloatRegister($shift$$reg));
15207    __ ushl(as_FloatRegister($dst$$reg), __ T4H,
15208            as_FloatRegister($src$$reg),
15209            as_FloatRegister($tmp$$reg));
15210  %}
15211  ins_pipe(vshift64);
15212%}
15213
15214instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{
15215  predicate(n->as_Vector()->length() == 8);
15216  match(Set dst (URShiftVS src shift));
15217  ins_cost(INSN_COST);
15218  effect(TEMP tmp);
15219  format %{ "negr  $tmp,$shift\t"
15220            "ushl  $dst,$src,$tmp\t# vector (8H)" %}
15221  ins_encode %{
15222    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
15223            as_FloatRegister($shift$$reg));
15224    __ ushl(as_FloatRegister($dst$$reg), __ T8H,
15225            as_FloatRegister($src$$reg),
15226            as_FloatRegister($tmp$$reg));
15227  %}
15228  ins_pipe(vshift128);
15229%}
15230
15231instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{
15232  predicate(n->as_Vector()->length() == 2 ||
15233            n->as_Vector()->length() == 4);
15234  match(Set dst (LShiftVS src shift));
15235  ins_cost(INSN_COST);
15236  format %{ "shl    $dst, $src, $shift\t# vector (4H)" %}
15237  ins_encode %{
15238    int sh = (int)$shift$$constant & 31;
15239    if (sh >= 16) {
15240      __ eor(as_FloatRegister($dst$$reg), __ T8B,
15241             as_FloatRegister($src$$reg),
15242             as_FloatRegister($src$$reg));
15243    } else {
15244      __ shl(as_FloatRegister($dst$$reg), __ T4H,
15245             as_FloatRegister($src$$reg), sh);
15246    }
15247  %}
15248  ins_pipe(vshift64_imm);
15249%}
15250
15251instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{
15252  predicate(n->as_Vector()->length() == 8);
15253  match(Set dst (LShiftVS src shift));
15254  ins_cost(INSN_COST);
15255  format %{ "shl    $dst, $src, $shift\t# vector (8H)" %}
15256  ins_encode %{
15257    int sh = (int)$shift$$constant & 31;
15258    if (sh >= 16) {
15259      __ eor(as_FloatRegister($dst$$reg), __ T16B,
15260             as_FloatRegister($src$$reg),
15261             as_FloatRegister($src$$reg));
15262    } else {
15263      __ shl(as_FloatRegister($dst$$reg), __ T8H,
15264             as_FloatRegister($src$$reg), sh);
15265    }
15266  %}
15267  ins_pipe(vshift128_imm);
15268%}
15269
15270instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{
15271  predicate(n->as_Vector()->length() == 2 ||
15272            n->as_Vector()->length() == 4);
15273  match(Set dst (RShiftVS src shift));
15274  ins_cost(INSN_COST);
15275  format %{ "sshr    $dst, $src, $shift\t# vector (4H)" %}
15276  ins_encode %{
15277    int sh = (int)$shift$$constant & 31;
15278    if (sh >= 16) sh = 15;
15279    sh = -sh & 15;
15280    __ sshr(as_FloatRegister($dst$$reg), __ T4H,
15281           as_FloatRegister($src$$reg), sh);
15282  %}
15283  ins_pipe(vshift64_imm);
15284%}
15285
15286instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{
15287  predicate(n->as_Vector()->length() == 8);
15288  match(Set dst (RShiftVS src shift));
15289  ins_cost(INSN_COST);
15290  format %{ "sshr    $dst, $src, $shift\t# vector (8H)" %}
15291  ins_encode %{
15292    int sh = (int)$shift$$constant & 31;
15293    if (sh >= 16) sh = 15;
15294    sh = -sh & 15;
15295    __ sshr(as_FloatRegister($dst$$reg), __ T8H,
15296           as_FloatRegister($src$$reg), sh);
15297  %}
15298  ins_pipe(vshift128_imm);
15299%}
15300
15301instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{
15302  predicate(n->as_Vector()->length() == 2 ||
15303            n->as_Vector()->length() == 4);
15304  match(Set dst (URShiftVS src shift));
15305  ins_cost(INSN_COST);
15306  format %{ "ushr    $dst, $src, $shift\t# vector (4H)" %}
15307  ins_encode %{
15308    int sh = (int)$shift$$constant & 31;
15309    if (sh >= 16) {
15310      __ eor(as_FloatRegister($dst$$reg), __ T8B,
15311             as_FloatRegister($src$$reg),
15312             as_FloatRegister($src$$reg));
15313    } else {
15314      __ ushr(as_FloatRegister($dst$$reg), __ T4H,
15315             as_FloatRegister($src$$reg), -sh & 15);
15316    }
15317  %}
15318  ins_pipe(vshift64_imm);
15319%}
15320
15321instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{
15322  predicate(n->as_Vector()->length() == 8);
15323  match(Set dst (URShiftVS src shift));
15324  ins_cost(INSN_COST);
15325  format %{ "ushr    $dst, $src, $shift\t# vector (8H)" %}
15326  ins_encode %{
15327    int sh = (int)$shift$$constant & 31;
15328    if (sh >= 16) {
15329      __ eor(as_FloatRegister($dst$$reg), __ T16B,
15330             as_FloatRegister($src$$reg),
15331             as_FloatRegister($src$$reg));
15332    } else {
15333      __ ushr(as_FloatRegister($dst$$reg), __ T8H,
15334             as_FloatRegister($src$$reg), -sh & 15);
15335    }
15336  %}
15337  ins_pipe(vshift128_imm);
15338%}
15339
15340instruct vsll2I(vecD dst, vecD src, vecD shift) %{
15341  predicate(n->as_Vector()->length() == 2);
15342  match(Set dst (LShiftVI src shift));
15343  ins_cost(INSN_COST);
15344  format %{ "sshl  $dst,$src,$shift\t# vector (2S)" %}
15345  ins_encode %{
15346    __ sshl(as_FloatRegister($dst$$reg), __ T2S,
15347            as_FloatRegister($src$$reg),
15348            as_FloatRegister($shift$$reg));
15349  %}
15350  ins_pipe(vshift64);
15351%}
15352
15353instruct vsll4I(vecX dst, vecX src, vecX shift) %{
15354  predicate(n->as_Vector()->length() == 4);
15355  match(Set dst (LShiftVI src shift));
15356  ins_cost(INSN_COST);
15357  format %{ "sshl  $dst,$src,$shift\t# vector (4S)" %}
15358  ins_encode %{
15359    __ sshl(as_FloatRegister($dst$$reg), __ T4S,
15360            as_FloatRegister($src$$reg),
15361            as_FloatRegister($shift$$reg));
15362  %}
15363  ins_pipe(vshift128);
15364%}
15365
15366instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{
15367  predicate(n->as_Vector()->length() == 2);
15368  match(Set dst (RShiftVI src shift));
15369  ins_cost(INSN_COST);
15370  effect(TEMP tmp);
15371  format %{ "negr  $tmp,$shift\t"
15372            "sshl  $dst,$src,$tmp\t# vector (2S)" %}
15373  ins_encode %{
15374    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
15375            as_FloatRegister($shift$$reg));
15376    __ sshl(as_FloatRegister($dst$$reg), __ T2S,
15377            as_FloatRegister($src$$reg),
15378            as_FloatRegister($tmp$$reg));
15379  %}
15380  ins_pipe(vshift64);
15381%}
15382
15383instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{
15384  predicate(n->as_Vector()->length() == 4);
15385  match(Set dst (RShiftVI src shift));
15386  ins_cost(INSN_COST);
15387  effect(TEMP tmp);
15388  format %{ "negr  $tmp,$shift\t"
15389            "sshl  $dst,$src,$tmp\t# vector (4S)" %}
15390  ins_encode %{
15391    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
15392            as_FloatRegister($shift$$reg));
15393    __ sshl(as_FloatRegister($dst$$reg), __ T4S,
15394            as_FloatRegister($src$$reg),
15395            as_FloatRegister($tmp$$reg));
15396  %}
15397  ins_pipe(vshift128);
15398%}
15399
15400instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{
15401  predicate(n->as_Vector()->length() == 2);
15402  match(Set dst (URShiftVI src shift));
15403  ins_cost(INSN_COST);
15404  effect(TEMP tmp);
15405  format %{ "negr  $tmp,$shift\t"
15406            "ushl  $dst,$src,$tmp\t# vector (2S)" %}
15407  ins_encode %{
15408    __ negr(as_FloatRegister($tmp$$reg), __ T8B,
15409            as_FloatRegister($shift$$reg));
15410    __ ushl(as_FloatRegister($dst$$reg), __ T2S,
15411            as_FloatRegister($src$$reg),
15412            as_FloatRegister($tmp$$reg));
15413  %}
15414  ins_pipe(vshift64);
15415%}
15416
15417instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{
15418  predicate(n->as_Vector()->length() == 4);
15419  match(Set dst (URShiftVI src shift));
15420  ins_cost(INSN_COST);
15421  effect(TEMP tmp);
15422  format %{ "negr  $tmp,$shift\t"
15423            "ushl  $dst,$src,$tmp\t# vector (4S)" %}
15424  ins_encode %{
15425    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
15426            as_FloatRegister($shift$$reg));
15427    __ ushl(as_FloatRegister($dst$$reg), __ T4S,
15428            as_FloatRegister($src$$reg),
15429            as_FloatRegister($tmp$$reg));
15430  %}
15431  ins_pipe(vshift128);
15432%}
15433
15434instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{
15435  predicate(n->as_Vector()->length() == 2);
15436  match(Set dst (LShiftVI src shift));
15437  ins_cost(INSN_COST);
15438  format %{ "shl    $dst, $src, $shift\t# vector (2S)" %}
15439  ins_encode %{
15440    __ shl(as_FloatRegister($dst$$reg), __ T2S,
15441           as_FloatRegister($src$$reg),
15442           (int)$shift$$constant & 31);
15443  %}
15444  ins_pipe(vshift64_imm);
15445%}
15446
15447instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{
15448  predicate(n->as_Vector()->length() == 4);
15449  match(Set dst (LShiftVI src shift));
15450  ins_cost(INSN_COST);
15451  format %{ "shl    $dst, $src, $shift\t# vector (4S)" %}
15452  ins_encode %{
15453    __ shl(as_FloatRegister($dst$$reg), __ T4S,
15454           as_FloatRegister($src$$reg),
15455           (int)$shift$$constant & 31);
15456  %}
15457  ins_pipe(vshift128_imm);
15458%}
15459
15460instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{
15461  predicate(n->as_Vector()->length() == 2);
15462  match(Set dst (RShiftVI src shift));
15463  ins_cost(INSN_COST);
15464  format %{ "sshr    $dst, $src, $shift\t# vector (2S)" %}
15465  ins_encode %{
15466    __ sshr(as_FloatRegister($dst$$reg), __ T2S,
15467            as_FloatRegister($src$$reg),
15468            -(int)$shift$$constant & 31);
15469  %}
15470  ins_pipe(vshift64_imm);
15471%}
15472
15473instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{
15474  predicate(n->as_Vector()->length() == 4);
15475  match(Set dst (RShiftVI src shift));
15476  ins_cost(INSN_COST);
15477  format %{ "sshr    $dst, $src, $shift\t# vector (4S)" %}
15478  ins_encode %{
15479    __ sshr(as_FloatRegister($dst$$reg), __ T4S,
15480            as_FloatRegister($src$$reg),
15481            -(int)$shift$$constant & 31);
15482  %}
15483  ins_pipe(vshift128_imm);
15484%}
15485
15486instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{
15487  predicate(n->as_Vector()->length() == 2);
15488  match(Set dst (URShiftVI src shift));
15489  ins_cost(INSN_COST);
15490  format %{ "ushr    $dst, $src, $shift\t# vector (2S)" %}
15491  ins_encode %{
15492    __ ushr(as_FloatRegister($dst$$reg), __ T2S,
15493            as_FloatRegister($src$$reg),
15494            -(int)$shift$$constant & 31);
15495  %}
15496  ins_pipe(vshift64_imm);
15497%}
15498
15499instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{
15500  predicate(n->as_Vector()->length() == 4);
15501  match(Set dst (URShiftVI src shift));
15502  ins_cost(INSN_COST);
15503  format %{ "ushr    $dst, $src, $shift\t# vector (4S)" %}
15504  ins_encode %{
15505    __ ushr(as_FloatRegister($dst$$reg), __ T4S,
15506            as_FloatRegister($src$$reg),
15507            -(int)$shift$$constant & 31);
15508  %}
15509  ins_pipe(vshift128_imm);
15510%}
15511
15512instruct vsll2L(vecX dst, vecX src, vecX shift) %{
15513  predicate(n->as_Vector()->length() == 2);
15514  match(Set dst (LShiftVL src shift));
15515  ins_cost(INSN_COST);
15516  format %{ "sshl  $dst,$src,$shift\t# vector (2D)" %}
15517  ins_encode %{
15518    __ sshl(as_FloatRegister($dst$$reg), __ T2D,
15519            as_FloatRegister($src$$reg),
15520            as_FloatRegister($shift$$reg));
15521  %}
15522  ins_pipe(vshift128);
15523%}
15524
15525instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{
15526  predicate(n->as_Vector()->length() == 2);
15527  match(Set dst (RShiftVL src shift));
15528  ins_cost(INSN_COST);
15529  effect(TEMP tmp);
15530  format %{ "negr  $tmp,$shift\t"
15531            "sshl  $dst,$src,$tmp\t# vector (2D)" %}
15532  ins_encode %{
15533    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
15534            as_FloatRegister($shift$$reg));
15535    __ sshl(as_FloatRegister($dst$$reg), __ T2D,
15536            as_FloatRegister($src$$reg),
15537            as_FloatRegister($tmp$$reg));
15538  %}
15539  ins_pipe(vshift128);
15540%}
15541
15542instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{
15543  predicate(n->as_Vector()->length() == 2);
15544  match(Set dst (URShiftVL src shift));
15545  ins_cost(INSN_COST);
15546  effect(TEMP tmp);
15547  format %{ "negr  $tmp,$shift\t"
15548            "ushl  $dst,$src,$tmp\t# vector (2D)" %}
15549  ins_encode %{
15550    __ negr(as_FloatRegister($tmp$$reg), __ T16B,
15551            as_FloatRegister($shift$$reg));
15552    __ ushl(as_FloatRegister($dst$$reg), __ T2D,
15553            as_FloatRegister($src$$reg),
15554            as_FloatRegister($tmp$$reg));
15555  %}
15556  ins_pipe(vshift128);
15557%}
15558
15559instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{
15560  predicate(n->as_Vector()->length() == 2);
15561  match(Set dst (LShiftVL src shift));
15562  ins_cost(INSN_COST);
15563  format %{ "shl    $dst, $src, $shift\t# vector (2D)" %}
15564  ins_encode %{
15565    __ shl(as_FloatRegister($dst$$reg), __ T2D,
15566           as_FloatRegister($src$$reg),
15567           (int)$shift$$constant & 63);
15568  %}
15569  ins_pipe(vshift128_imm);
15570%}
15571
15572instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{
15573  predicate(n->as_Vector()->length() == 2);
15574  match(Set dst (RShiftVL src shift));
15575  ins_cost(INSN_COST);
15576  format %{ "sshr    $dst, $src, $shift\t# vector (2D)" %}
15577  ins_encode %{
15578    __ sshr(as_FloatRegister($dst$$reg), __ T2D,
15579            as_FloatRegister($src$$reg),
15580            -(int)$shift$$constant & 63);
15581  %}
15582  ins_pipe(vshift128_imm);
15583%}
15584
15585instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{
15586  predicate(n->as_Vector()->length() == 2);
15587  match(Set dst (URShiftVL src shift));
15588  ins_cost(INSN_COST);
15589  format %{ "ushr    $dst, $src, $shift\t# vector (2D)" %}
15590  ins_encode %{
15591    __ ushr(as_FloatRegister($dst$$reg), __ T2D,
15592            as_FloatRegister($src$$reg),
15593            -(int)$shift$$constant & 63);
15594  %}
15595  ins_pipe(vshift128_imm);
15596%}
15597
15598//----------PEEPHOLE RULES-----------------------------------------------------
15599// These must follow all instruction definitions as they use the names
15600// defined in the instructions definitions.
15601//
15602// peepmatch ( root_instr_name [preceding_instruction]* );
15603//
15604// peepconstraint %{
15605// (instruction_number.operand_name relational_op instruction_number.operand_name
15606//  [, ...] );
15607// // instruction numbers are zero-based using left to right order in peepmatch
15608//
15609// peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
15610// // provide an instruction_number.operand_name for each operand that appears
15611// // in the replacement instruction's match rule
15612//
15613// ---------VM FLAGS---------------------------------------------------------
15614//
15615// All peephole optimizations can be turned off using -XX:-OptoPeephole
15616//
15617// Each peephole rule is given an identifying number starting with zero and
15618// increasing by one in the order seen by the parser.  An individual peephole
15619// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
15620// on the command-line.
15621//
15622// ---------CURRENT LIMITATIONS----------------------------------------------
15623//
15624// Only match adjacent instructions in same basic block
15625// Only equality constraints
15626// Only constraints between operands, not (0.dest_reg == RAX_enc)
15627// Only one replacement instruction
15628//
15629// ---------EXAMPLE----------------------------------------------------------
15630//
15631// // pertinent parts of existing instructions in architecture description
15632// instruct movI(iRegINoSp dst, iRegI src)
15633// %{
15634//   match(Set dst (CopyI src));
15635// %}
15636//
15637// instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr)
15638// %{
15639//   match(Set dst (AddI dst src));
15640//   effect(KILL cr);
15641// %}
15642//
15643// // Change (inc mov) to lea
15644// peephole %{
15645//   // increment preceeded by register-register move
15646//   peepmatch ( incI_iReg movI );
15647//   // require that the destination register of the increment
15648//   // match the destination register of the move
15649//   peepconstraint ( 0.dst == 1.dst );
15650//   // construct a replacement instruction that sets
15651//   // the destination to ( move's source register + one )
15652//   peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) );
15653// %}
15654//
15655
15656// Implementation no longer uses movX instructions since
15657// machine-independent system no longer uses CopyX nodes.
15658//
15659// peephole
15660// %{
15661//   peepmatch (incI_iReg movI);
15662//   peepconstraint (0.dst == 1.dst);
15663//   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
15664// %}
15665
15666// peephole
15667// %{
15668//   peepmatch (decI_iReg movI);
15669//   peepconstraint (0.dst == 1.dst);
15670//   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
15671// %}
15672
15673// peephole
15674// %{
15675//   peepmatch (addI_iReg_imm movI);
15676//   peepconstraint (0.dst == 1.dst);
15677//   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
15678// %}
15679
15680// peephole
15681// %{
15682//   peepmatch (incL_iReg movL);
15683//   peepconstraint (0.dst == 1.dst);
15684//   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
15685// %}
15686
15687// peephole
15688// %{
15689//   peepmatch (decL_iReg movL);
15690//   peepconstraint (0.dst == 1.dst);
15691//   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
15692// %}
15693
15694// peephole
15695// %{
15696//   peepmatch (addL_iReg_imm movL);
15697//   peepconstraint (0.dst == 1.dst);
15698//   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
15699// %}
15700
15701// peephole
15702// %{
15703//   peepmatch (addP_iReg_imm movP);
15704//   peepconstraint (0.dst == 1.dst);
15705//   peepreplace (leaP_iReg_imm(0.dst 1.src 0.src));
15706// %}
15707
15708// // Change load of spilled value to only a spill
15709// instruct storeI(memory mem, iRegI src)
15710// %{
15711//   match(Set mem (StoreI mem src));
15712// %}
15713//
15714// instruct loadI(iRegINoSp dst, memory mem)
15715// %{
15716//   match(Set dst (LoadI mem));
15717// %}
15718//
15719
15720//----------SMARTSPILL RULES---------------------------------------------------
15721// These must follow all instruction definitions as they use the names
15722// defined in the instructions definitions.
15723
15724// Local Variables:
15725// mode: c++
15726// End:
15727