1 //
2 // Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved.
3 // Copyright (c) 2012, 2026 SAP SE. All rights reserved.
4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 //
6 // This code is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License version 2 only, as
8 // published by the Free Software Foundation.
9 //
10 // This code is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // version 2 for more details (a copy is included in the LICENSE file that
14 // accompanied this code).
15 //
16 // You should have received a copy of the GNU General Public License version
17 // 2 along with this work; if not, write to the Free Software Foundation,
18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 // or visit www.oracle.com if you need additional information or have any
22 // questions.
23 //
24 //
25
26 //
27 // PPC64 Architecture Description File
28 //
29
30 //----------REGISTER DEFINITION BLOCK------------------------------------------
31 // This information is used by the matcher and the register allocator to
32 // describe individual registers and classes of registers within the target
33 // architecture.
34 register %{
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 //
40 // Register Save Types:
41 //
42 // NS = No-Save: The register allocator assumes that these registers
43 // can be used without saving upon entry to the method, &
44 // that they do not need to be saved at call sites.
45 //
46 // SOC = Save-On-Call: The register allocator assumes that these registers
47 // can be used without saving upon entry to the method,
48 // but that they must be saved at call sites.
49 // These are called "volatiles" on ppc.
50 //
51 // SOE = Save-On-Entry: The register allocator assumes that these registers
52 // must be saved before using them upon entry to the
53 // method, but they do not need to be saved at call
54 // sites.
55 // These are called "nonvolatiles" on ppc.
56 //
57 // AS = Always-Save: The register allocator assumes that these registers
58 // must be saved before using them upon entry to the
59 // method, & that they must be saved at call sites.
60 //
61 // Ideal Register Type is used to determine how to save & restore a
62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
64 //
65 // The encoding number is the actual bit-pattern placed into the opcodes.
66 //
67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI
68 // Supplement Version 1.7 as of 2003-10-29.
69 //
70 // For each 64-bit register we must define two registers: the register
71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half',
72 // e.g. R3_H, which is needed by the allocator, but is not used
73 // for stores, loads, etc.
74
75 // ----------------------------
76 // Integer/Long Registers
77 // ----------------------------
78
79 // PPC64 has 32 64-bit integer registers.
80
81 // types: v = volatile, nv = non-volatile, s = system
82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs
83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() );
84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP
85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() );
86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC
87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() );
88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret
89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() );
90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2
91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() );
92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3
93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() );
94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4
95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() );
96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5
97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() );
98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6
99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() );
100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7
101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() );
102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8
103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next());
104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch
105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next());
106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch
107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next());
108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id
109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next());
110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv
111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next());
112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv
113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next());
114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv
115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next());
116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv
117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next());
118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv
119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next());
120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv
121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next());
122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv
123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next());
124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv
125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next());
126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv
127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next());
128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv
129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next());
130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv
131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next());
132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv
133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next());
134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv
135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next());
136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv
137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next());
138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv
139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next());
140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv
141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next());
142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv
143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next());
144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv
145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next());
146
147
148 // ----------------------------
149 // Float/Double Registers
150 // ----------------------------
151
152 // Double Registers
153 // The rules of ADL require that double registers be defined in pairs.
154 // Each pair must be two 32-bit values, but not necessarily a pair of
155 // single float registers. In each pair, ADLC-assigned register numbers
156 // must be adjacent, with the lower number even. Finally, when the
157 // CPU stores such a register pair to memory, the word associated with
158 // the lower ADLC-assigned number must be stored to the lower address.
159
160 // PPC64 has 32 64-bit floating-point registers. Each can store a single
161 // or double precision floating-point value.
162
163 // types: v = volatile, nv = non-volatile, s = system
164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch
165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() );
166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret
167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() );
168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2
169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() );
170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3
171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() );
172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4
173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() );
174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5
175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() );
176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6
177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() );
178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7
179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() );
180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8
181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() );
182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9
183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() );
184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10
185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next());
186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11
187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next());
188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12
189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next());
190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13
191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next());
192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv
193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next());
194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv
195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next());
196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv
197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next());
198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv
199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next());
200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv
201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next());
202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv
203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next());
204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv
205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next());
206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv
207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next());
208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv
209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next());
210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv
211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next());
212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv
213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next());
214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv
215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next());
216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv
217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next());
218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv
219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next());
220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv
221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next());
222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv
223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next());
224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv
225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next());
226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv
227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next());
228
229 // ----------------------------
230 // Special Registers
231 // ----------------------------
232
233 // Condition Codes Flag Registers
234
235 // PPC64 has 8 condition code "registers" which are all contained
236 // in the CR register.
237
238 // types: v = volatile, nv = non-volatile, s = system
239 reg_def CR0(SOC, SOC, Op_RegFlags, 0, CR0->as_VMReg()); // v
240 reg_def CR1(SOC, SOC, Op_RegFlags, 1, CR1->as_VMReg()); // v
241 reg_def CR2(SOC, SOC, Op_RegFlags, 2, CR2->as_VMReg()); // nv
242 reg_def CR3(SOC, SOC, Op_RegFlags, 3, CR3->as_VMReg()); // nv
243 reg_def CR4(SOC, SOC, Op_RegFlags, 4, CR4->as_VMReg()); // nv
244 reg_def CR5(SOC, SOC, Op_RegFlags, 5, CR5->as_VMReg()); // v
245 reg_def CR6(SOC, SOC, Op_RegFlags, 6, CR6->as_VMReg()); // v
246 reg_def CR7(SOC, SOC, Op_RegFlags, 7, CR7->as_VMReg()); // v
247
248 // Special registers of PPC64
249
250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v
251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v
252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v
253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v
254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v
255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v
256
257 // ----------------------------
258 // Vector Registers
259 // ----------------------------
260
261 reg_def VR0 (SOC, SOC, Op_RegF, 0, VR0->as_VMReg() );
262 reg_def VR0_H(SOC, SOC, Op_RegF, 0, VR0->as_VMReg()->next() );
263 reg_def VR0_J(SOC, SOC, Op_RegF, 0, VR0->as_VMReg()->next(2));
264 reg_def VR0_K(SOC, SOC, Op_RegF, 0, VR0->as_VMReg()->next(3));
265
266 reg_def VR1 (SOC, SOC, Op_RegF, 1, VR1->as_VMReg() );
267 reg_def VR1_H(SOC, SOC, Op_RegF, 1, VR1->as_VMReg()->next() );
268 reg_def VR1_J(SOC, SOC, Op_RegF, 1, VR1->as_VMReg()->next(2));
269 reg_def VR1_K(SOC, SOC, Op_RegF, 1, VR1->as_VMReg()->next(3));
270
271 reg_def VR2 (SOC, SOC, Op_RegF, 2, VR2->as_VMReg() );
272 reg_def VR2_H(SOC, SOC, Op_RegF, 2, VR2->as_VMReg()->next() );
273 reg_def VR2_J(SOC, SOC, Op_RegF, 2, VR2->as_VMReg()->next(2));
274 reg_def VR2_K(SOC, SOC, Op_RegF, 2, VR2->as_VMReg()->next(3));
275
276 reg_def VR3 (SOC, SOC, Op_RegF, 3, VR3->as_VMReg() );
277 reg_def VR3_H(SOC, SOC, Op_RegF, 3, VR3->as_VMReg()->next() );
278 reg_def VR3_J(SOC, SOC, Op_RegF, 3, VR3->as_VMReg()->next(2));
279 reg_def VR3_K(SOC, SOC, Op_RegF, 3, VR3->as_VMReg()->next(3));
280
281 reg_def VR4 (SOC, SOC, Op_RegF, 4, VR4->as_VMReg() );
282 reg_def VR4_H(SOC, SOC, Op_RegF, 4, VR4->as_VMReg()->next() );
283 reg_def VR4_J(SOC, SOC, Op_RegF, 4, VR4->as_VMReg()->next(2));
284 reg_def VR4_K(SOC, SOC, Op_RegF, 4, VR4->as_VMReg()->next(3));
285
286 reg_def VR5 (SOC, SOC, Op_RegF, 5, VR5->as_VMReg() );
287 reg_def VR5_H(SOC, SOC, Op_RegF, 5, VR5->as_VMReg()->next() );
288 reg_def VR5_J(SOC, SOC, Op_RegF, 5, VR5->as_VMReg()->next(2));
289 reg_def VR5_K(SOC, SOC, Op_RegF, 5, VR5->as_VMReg()->next(3));
290
291 reg_def VR6 (SOC, SOC, Op_RegF, 6, VR6->as_VMReg() );
292 reg_def VR6_H(SOC, SOC, Op_RegF, 6, VR6->as_VMReg()->next() );
293 reg_def VR6_J(SOC, SOC, Op_RegF, 6, VR6->as_VMReg()->next(2));
294 reg_def VR6_K(SOC, SOC, Op_RegF, 6, VR6->as_VMReg()->next(3));
295
296 reg_def VR7 (SOC, SOC, Op_RegF, 7, VR7->as_VMReg() );
297 reg_def VR7_H(SOC, SOC, Op_RegF, 7, VR7->as_VMReg()->next() );
298 reg_def VR7_J(SOC, SOC, Op_RegF, 7, VR7->as_VMReg()->next(2));
299 reg_def VR7_K(SOC, SOC, Op_RegF, 7, VR7->as_VMReg()->next(3));
300
301 reg_def VR8 (SOC, SOC, Op_RegF, 8, VR8->as_VMReg() );
302 reg_def VR8_H(SOC, SOC, Op_RegF, 8, VR8->as_VMReg()->next() );
303 reg_def VR8_J(SOC, SOC, Op_RegF, 8, VR8->as_VMReg()->next(2));
304 reg_def VR8_K(SOC, SOC, Op_RegF, 8, VR8->as_VMReg()->next(3));
305
306 reg_def VR9 (SOC, SOC, Op_RegF, 9, VR9->as_VMReg() );
307 reg_def VR9_H(SOC, SOC, Op_RegF, 9, VR9->as_VMReg()->next() );
308 reg_def VR9_J(SOC, SOC, Op_RegF, 9, VR9->as_VMReg()->next(2));
309 reg_def VR9_K(SOC, SOC, Op_RegF, 9, VR9->as_VMReg()->next(3));
310
311 reg_def VR10 (SOC, SOC, Op_RegF, 10, VR10->as_VMReg() );
312 reg_def VR10_H(SOC, SOC, Op_RegF, 10, VR10->as_VMReg()->next() );
313 reg_def VR10_J(SOC, SOC, Op_RegF, 10, VR10->as_VMReg()->next(2));
314 reg_def VR10_K(SOC, SOC, Op_RegF, 10, VR10->as_VMReg()->next(3));
315
316 reg_def VR11 (SOC, SOC, Op_RegF, 11, VR11->as_VMReg() );
317 reg_def VR11_H(SOC, SOC, Op_RegF, 11, VR11->as_VMReg()->next() );
318 reg_def VR11_J(SOC, SOC, Op_RegF, 11, VR11->as_VMReg()->next(2));
319 reg_def VR11_K(SOC, SOC, Op_RegF, 11, VR11->as_VMReg()->next(3));
320
321 reg_def VR12 (SOC, SOC, Op_RegF, 12, VR12->as_VMReg() );
322 reg_def VR12_H(SOC, SOC, Op_RegF, 12, VR12->as_VMReg()->next() );
323 reg_def VR12_J(SOC, SOC, Op_RegF, 12, VR12->as_VMReg()->next(2));
324 reg_def VR12_K(SOC, SOC, Op_RegF, 12, VR12->as_VMReg()->next(3));
325
326 reg_def VR13 (SOC, SOC, Op_RegF, 13, VR13->as_VMReg() );
327 reg_def VR13_H(SOC, SOC, Op_RegF, 13, VR13->as_VMReg()->next() );
328 reg_def VR13_J(SOC, SOC, Op_RegF, 13, VR13->as_VMReg()->next(2));
329 reg_def VR13_K(SOC, SOC, Op_RegF, 13, VR13->as_VMReg()->next(3));
330
331 reg_def VR14 (SOC, SOC, Op_RegF, 14, VR14->as_VMReg() );
332 reg_def VR14_H(SOC, SOC, Op_RegF, 14, VR14->as_VMReg()->next() );
333 reg_def VR14_J(SOC, SOC, Op_RegF, 14, VR14->as_VMReg()->next(2));
334 reg_def VR14_K(SOC, SOC, Op_RegF, 14, VR14->as_VMReg()->next(3));
335
336 reg_def VR15 (SOC, SOC, Op_RegF, 15, VR15->as_VMReg() );
337 reg_def VR15_H(SOC, SOC, Op_RegF, 15, VR15->as_VMReg()->next() );
338 reg_def VR15_J(SOC, SOC, Op_RegF, 15, VR15->as_VMReg()->next(2));
339 reg_def VR15_K(SOC, SOC, Op_RegF, 15, VR15->as_VMReg()->next(3));
340
341 reg_def VR16 (SOC, SOC, Op_RegF, 16, VR16->as_VMReg() );
342 reg_def VR16_H(SOC, SOC, Op_RegF, 16, VR16->as_VMReg()->next() );
343 reg_def VR16_J(SOC, SOC, Op_RegF, 16, VR16->as_VMReg()->next(2));
344 reg_def VR16_K(SOC, SOC, Op_RegF, 16, VR16->as_VMReg()->next(3));
345
346 reg_def VR17 (SOC, SOC, Op_RegF, 17, VR17->as_VMReg() );
347 reg_def VR17_H(SOC, SOC, Op_RegF, 17, VR17->as_VMReg()->next() );
348 reg_def VR17_J(SOC, SOC, Op_RegF, 17, VR17->as_VMReg()->next(2));
349 reg_def VR17_K(SOC, SOC, Op_RegF, 17, VR17->as_VMReg()->next(3));
350
351 reg_def VR18 (SOC, SOC, Op_RegF, 18, VR18->as_VMReg() );
352 reg_def VR18_H(SOC, SOC, Op_RegF, 18, VR18->as_VMReg()->next() );
353 reg_def VR18_J(SOC, SOC, Op_RegF, 18, VR18->as_VMReg()->next(2));
354 reg_def VR18_K(SOC, SOC, Op_RegF, 18, VR18->as_VMReg()->next(3));
355
356 reg_def VR19 (SOC, SOC, Op_RegF, 19, VR19->as_VMReg() );
357 reg_def VR19_H(SOC, SOC, Op_RegF, 19, VR19->as_VMReg()->next() );
358 reg_def VR19_J(SOC, SOC, Op_RegF, 19, VR19->as_VMReg()->next(2));
359 reg_def VR19_K(SOC, SOC, Op_RegF, 19, VR19->as_VMReg()->next(3));
360
361 reg_def VR20 (SOC, SOE, Op_RegF, 20, VR20->as_VMReg() );
362 reg_def VR20_H(SOC, SOE, Op_RegF, 20, VR20->as_VMReg()->next() );
363 reg_def VR20_J(SOC, SOE, Op_RegF, 20, VR20->as_VMReg()->next(2));
364 reg_def VR20_K(SOC, SOE, Op_RegF, 20, VR20->as_VMReg()->next(3));
365
366 reg_def VR21 (SOC, SOE, Op_RegF, 21, VR21->as_VMReg() );
367 reg_def VR21_H(SOC, SOE, Op_RegF, 21, VR21->as_VMReg()->next() );
368 reg_def VR21_J(SOC, SOE, Op_RegF, 21, VR21->as_VMReg()->next(2));
369 reg_def VR21_K(SOC, SOE, Op_RegF, 21, VR21->as_VMReg()->next(3));
370
371 reg_def VR22 (SOC, SOE, Op_RegF, 22, VR22->as_VMReg() );
372 reg_def VR22_H(SOC, SOE, Op_RegF, 22, VR22->as_VMReg()->next() );
373 reg_def VR22_J(SOC, SOE, Op_RegF, 22, VR22->as_VMReg()->next(2));
374 reg_def VR22_K(SOC, SOE, Op_RegF, 22, VR22->as_VMReg()->next(3));
375
376 reg_def VR23 (SOC, SOE, Op_RegF, 23, VR23->as_VMReg() );
377 reg_def VR23_H(SOC, SOE, Op_RegF, 23, VR23->as_VMReg()->next() );
378 reg_def VR23_J(SOC, SOE, Op_RegF, 23, VR23->as_VMReg()->next(2));
379 reg_def VR23_K(SOC, SOE, Op_RegF, 23, VR23->as_VMReg()->next(3));
380
381 reg_def VR24 (SOC, SOE, Op_RegF, 24, VR24->as_VMReg() );
382 reg_def VR24_H(SOC, SOE, Op_RegF, 24, VR24->as_VMReg()->next() );
383 reg_def VR24_J(SOC, SOE, Op_RegF, 24, VR24->as_VMReg()->next(2));
384 reg_def VR24_K(SOC, SOE, Op_RegF, 24, VR24->as_VMReg()->next(3));
385
386 reg_def VR25 (SOC, SOE, Op_RegF, 25, VR25->as_VMReg() );
387 reg_def VR25_H(SOC, SOE, Op_RegF, 25, VR25->as_VMReg()->next() );
388 reg_def VR25_J(SOC, SOE, Op_RegF, 25, VR25->as_VMReg()->next(2));
389 reg_def VR25_K(SOC, SOE, Op_RegF, 25, VR25->as_VMReg()->next(3));
390
391 reg_def VR26 (SOC, SOE, Op_RegF, 26, VR26->as_VMReg() );
392 reg_def VR26_H(SOC, SOE, Op_RegF, 26, VR26->as_VMReg()->next() );
393 reg_def VR26_J(SOC, SOE, Op_RegF, 26, VR26->as_VMReg()->next(2));
394 reg_def VR26_K(SOC, SOE, Op_RegF, 26, VR26->as_VMReg()->next(3));
395
396 reg_def VR27 (SOC, SOE, Op_RegF, 27, VR27->as_VMReg() );
397 reg_def VR27_H(SOC, SOE, Op_RegF, 27, VR27->as_VMReg()->next() );
398 reg_def VR27_J(SOC, SOE, Op_RegF, 27, VR27->as_VMReg()->next(2));
399 reg_def VR27_K(SOC, SOE, Op_RegF, 27, VR27->as_VMReg()->next(3));
400
401 reg_def VR28 (SOC, SOE, Op_RegF, 28, VR28->as_VMReg() );
402 reg_def VR28_H(SOC, SOE, Op_RegF, 28, VR28->as_VMReg()->next() );
403 reg_def VR28_J(SOC, SOE, Op_RegF, 28, VR28->as_VMReg()->next(2));
404 reg_def VR28_K(SOC, SOE, Op_RegF, 28, VR28->as_VMReg()->next(3));
405
406 reg_def VR29 (SOC, SOE, Op_RegF, 29, VR29->as_VMReg() );
407 reg_def VR29_H(SOC, SOE, Op_RegF, 29, VR29->as_VMReg()->next() );
408 reg_def VR29_J(SOC, SOE, Op_RegF, 29, VR29->as_VMReg()->next(2));
409 reg_def VR29_K(SOC, SOE, Op_RegF, 29, VR29->as_VMReg()->next(3));
410
411 reg_def VR30 (SOC, SOE, Op_RegF, 30, VR30->as_VMReg() );
412 reg_def VR30_H(SOC, SOE, Op_RegF, 30, VR30->as_VMReg()->next() );
413 reg_def VR30_J(SOC, SOE, Op_RegF, 30, VR30->as_VMReg()->next(2));
414 reg_def VR30_K(SOC, SOE, Op_RegF, 30, VR30->as_VMReg()->next(3));
415
416 reg_def VR31 (SOC, SOE, Op_RegF, 31, VR31->as_VMReg() );
417 reg_def VR31_H(SOC, SOE, Op_RegF, 31, VR31->as_VMReg()->next() );
418 reg_def VR31_J(SOC, SOE, Op_RegF, 31, VR31->as_VMReg()->next(2));
419 reg_def VR31_K(SOC, SOE, Op_RegF, 31, VR31->as_VMReg()->next(3));
420
421 // ----------------------------
422 // Specify priority of register selection within phases of register
423 // allocation. Highest priority is first. A useful heuristic is to
424 // give registers a low priority when they are required by machine
425 // instructions, like EAX and EDX on I486, and choose no-save registers
426 // before save-on-call, & save-on-call before save-on-entry. Registers
427 // which participate in fixed calling sequences should come last.
428 // Registers which are used as pairs must fall on an even boundary.
429
430 // It's worth about 1% on SPEC geomean to get this right.
431
432 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration
433 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g.
434 // R3_num. Therefore, R3_num may not be (and in reality is not)
435 // the same as R3->encoding()! Furthermore, we cannot make any
436 // assumptions on ordering, e.g. R3_num may be less than R2_num.
437 // Additionally, the function
438 // static enum RC rc_class(OptoReg::Name reg )
439 // maps a given <register>_num value to its chunk type (except for flags)
440 // and its current implementation relies on chunk0 and chunk1 having a
441 // size of 64 each.
442
443 // If you change this allocation class, please have a look at the
444 // default values for the parameters RoundRobinIntegerRegIntervalStart
445 // and RoundRobinFloatRegIntervalStart
446
447 alloc_class chunk0 (
448 // Chunk0 contains *all* 64 integer registers halves.
449
450 // "non-volatile" registers
451 R14, R14_H,
452 R15, R15_H,
453 R17, R17_H,
454 R18, R18_H,
455 R19, R19_H,
456 R20, R20_H,
457 R21, R21_H,
458 R22, R22_H,
459 R23, R23_H,
460 R24, R24_H,
461 R25, R25_H,
462 R26, R26_H,
463 R27, R27_H,
464 R28, R28_H,
465 R29, R29_H,
466 R30, R30_H,
467 R31, R31_H,
468
469 // scratch/special registers
470 R11, R11_H,
471 R12, R12_H,
472
473 // argument registers
474 R10, R10_H,
475 R9, R9_H,
476 R8, R8_H,
477 R7, R7_H,
478 R6, R6_H,
479 R5, R5_H,
480 R4, R4_H,
481 R3, R3_H,
482
483 // special registers, not available for allocation
484 R16, R16_H, // R16_thread
485 R13, R13_H, // system thread id
486 R2, R2_H, // may be used for TOC
487 R1, R1_H, // SP
488 R0, R0_H // R0 (scratch)
489 );
490
491 // If you change this allocation class, please have a look at the
492 // default values for the parameters RoundRobinIntegerRegIntervalStart
493 // and RoundRobinFloatRegIntervalStart
494
495 alloc_class chunk1 (
496 // Chunk1 contains *all* 64 floating-point registers halves.
497
498 // scratch register
499 F0, F0_H,
500
501 // argument registers
502 F13, F13_H,
503 F12, F12_H,
504 F11, F11_H,
505 F10, F10_H,
506 F9, F9_H,
507 F8, F8_H,
508 F7, F7_H,
509 F6, F6_H,
510 F5, F5_H,
511 F4, F4_H,
512 F3, F3_H,
513 F2, F2_H,
514 F1, F1_H,
515
516 // non-volatile registers
517 F14, F14_H,
518 F15, F15_H,
519 F16, F16_H,
520 F17, F17_H,
521 F18, F18_H,
522 F19, F19_H,
523 F20, F20_H,
524 F21, F21_H,
525 F22, F22_H,
526 F23, F23_H,
527 F24, F24_H,
528 F25, F25_H,
529 F26, F26_H,
530 F27, F27_H,
531 F28, F28_H,
532 F29, F29_H,
533 F30, F30_H,
534 F31, F31_H
535 );
536
537 alloc_class chunk2 (
538 VR0 , VR0_H , VR0_J , VR0_K ,
539 VR1 , VR1_H , VR1_J , VR1_K ,
540 VR2 , VR2_H , VR2_J , VR2_K ,
541 VR3 , VR3_H , VR3_J , VR3_K ,
542 VR4 , VR4_H , VR4_J , VR4_K ,
543 VR5 , VR5_H , VR5_J , VR5_K ,
544 VR6 , VR6_H , VR6_J , VR6_K ,
545 VR7 , VR7_H , VR7_J , VR7_K ,
546 VR8 , VR8_H , VR8_J , VR8_K ,
547 VR9 , VR9_H , VR9_J , VR9_K ,
548 VR10, VR10_H, VR10_J, VR10_K,
549 VR11, VR11_H, VR11_J, VR11_K,
550 VR12, VR12_H, VR12_J, VR12_K,
551 VR13, VR13_H, VR13_J, VR13_K,
552 VR14, VR14_H, VR14_J, VR14_K,
553 VR15, VR15_H, VR15_J, VR15_K,
554 VR16, VR16_H, VR16_J, VR16_K,
555 VR17, VR17_H, VR17_J, VR17_K,
556 VR18, VR18_H, VR18_J, VR18_K,
557 VR19, VR19_H, VR19_J, VR19_K,
558 VR20, VR20_H, VR20_J, VR20_K,
559 VR21, VR21_H, VR21_J, VR21_K,
560 VR22, VR22_H, VR22_J, VR22_K,
561 VR23, VR23_H, VR23_J, VR23_K,
562 VR24, VR24_H, VR24_J, VR24_K,
563 VR25, VR25_H, VR25_J, VR25_K,
564 VR26, VR26_H, VR26_J, VR26_K,
565 VR27, VR27_H, VR27_J, VR27_K,
566 VR28, VR28_H, VR28_J, VR28_K,
567 VR29, VR29_H, VR29_J, VR29_K,
568 VR30, VR30_H, VR30_J, VR30_K,
569 VR31, VR31_H, VR31_J, VR31_K
570 );
571
572 alloc_class chunk3 (
573 // Chunk2 contains *all* 8 condition code registers.
574 CR0,
575 CR1,
576 CR2,
577 CR3,
578 CR4,
579 CR5,
580 CR6,
581 CR7
582 );
583
584 alloc_class chunk4 (
585 // special registers
586 // These registers are not allocated, but used for nodes generated by postalloc expand.
587 SR_XER,
588 SR_LR,
589 SR_CTR,
590 SR_VRSAVE,
591 SR_SPEFSCR,
592 SR_PPR
593 );
594
595 //-------Architecture Description Register Classes-----------------------
596
597 // Several register classes are automatically defined based upon
598 // information in this architecture description.
599
600 // 1) reg_class inline_cache_reg ( as defined in frame section )
601 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
602 //
603
604 // ----------------------------
605 // 32 Bit Register Classes
606 // ----------------------------
607
608 // We specify registers twice, once as read/write, and once read-only.
609 // We use the read-only registers for source operands. With this, we
610 // can include preset read only registers in this class, as a hard-coded
611 // '0'-register. (We used to simulate this on ppc.)
612
613 // 32 bit registers that can be read and written i.e. these registers
614 // can be dest (or src) of normal instructions.
615 reg_class bits32_reg_rw(
616 /*R0*/ // R0
617 /*R1*/ // SP
618 R2, // TOC
619 R3,
620 R4,
621 R5,
622 R6,
623 R7,
624 R8,
625 R9,
626 R10,
627 R11,
628 R12,
629 /*R13*/ // system thread id
630 R14,
631 R15,
632 /*R16*/ // R16_thread
633 R17,
634 R18,
635 R19,
636 R20,
637 R21,
638 R22,
639 R23,
640 R24,
641 R25,
642 R26,
643 R27,
644 R28,
645 /*R29,*/ // global TOC
646 R30,
647 R31
648 );
649
650 // 32 bit registers that can only be read i.e. these registers can
651 // only be src of all instructions.
652 reg_class bits32_reg_ro(
653 /*R0*/ // R0
654 /*R1*/ // SP
655 R2 // TOC
656 R3,
657 R4,
658 R5,
659 R6,
660 R7,
661 R8,
662 R9,
663 R10,
664 R11,
665 R12,
666 /*R13*/ // system thread id
667 R14,
668 R15,
669 /*R16*/ // R16_thread
670 R17,
671 R18,
672 R19,
673 R20,
674 R21,
675 R22,
676 R23,
677 R24,
678 R25,
679 R26,
680 R27,
681 R28,
682 /*R29,*/
683 R30,
684 R31
685 );
686
687 reg_class rscratch1_bits32_reg(R11);
688 reg_class rscratch2_bits32_reg(R12);
689 reg_class rarg1_bits32_reg(R3);
690 reg_class rarg2_bits32_reg(R4);
691 reg_class rarg3_bits32_reg(R5);
692 reg_class rarg4_bits32_reg(R6);
693
694 // ----------------------------
695 // 64 Bit Register Classes
696 // ----------------------------
697 // 64-bit build means 64-bit pointers means hi/lo pairs
698
699 reg_class rscratch1_bits64_reg(R11_H, R11);
700 reg_class rscratch2_bits64_reg(R12_H, R12);
701 reg_class rarg1_bits64_reg(R3_H, R3);
702 reg_class rarg2_bits64_reg(R4_H, R4);
703 reg_class rarg3_bits64_reg(R5_H, R5);
704 reg_class rarg4_bits64_reg(R6_H, R6);
705 reg_class rarg5_bits64_reg(R7_H, R7);
706 reg_class rarg6_bits64_reg(R8_H, R8);
707 // Thread register, 'written' by tlsLoadP, see there.
708 reg_class thread_bits64_reg(R16_H, R16);
709
710 reg_class r19_bits64_reg(R19_H, R19);
711
712 // 64 bit registers that can be read and written i.e. these registers
713 // can be dest (or src) of normal instructions.
714 reg_class bits64_reg_rw(
715 /*R0_H, R0*/ // R0
716 /*R1_H, R1*/ // SP
717 R2_H, R2, // TOC
718 R3_H, R3,
719 R4_H, R4,
720 R5_H, R5,
721 R6_H, R6,
722 R7_H, R7,
723 R8_H, R8,
724 R9_H, R9,
725 R10_H, R10,
726 R11_H, R11,
727 R12_H, R12,
728 /*R13_H, R13*/ // system thread id
729 R14_H, R14,
730 R15_H, R15,
731 /*R16_H, R16*/ // R16_thread
732 R17_H, R17,
733 R18_H, R18,
734 R19_H, R19,
735 R20_H, R20,
736 R21_H, R21,
737 R22_H, R22,
738 R23_H, R23,
739 R24_H, R24,
740 R25_H, R25,
741 R26_H, R26,
742 R27_H, R27,
743 R28_H, R28,
744 /*R29_H, R29,*/
745 R30_H, R30,
746 R31_H, R31
747 );
748
749 // 64 bit registers used excluding r2, r11 and r12
750 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses
751 // r2, r11 and r12 internally.
752 reg_class bits64_reg_leaf_call(
753 /*R0_H, R0*/ // R0
754 /*R1_H, R1*/ // SP
755 /*R2_H, R2*/ // TOC
756 R3_H, R3,
757 R4_H, R4,
758 R5_H, R5,
759 R6_H, R6,
760 R7_H, R7,
761 R8_H, R8,
762 R9_H, R9,
763 R10_H, R10,
764 /*R11_H, R11*/
765 /*R12_H, R12*/
766 /*R13_H, R13*/ // system thread id
767 R14_H, R14,
768 R15_H, R15,
769 /*R16_H, R16*/ // R16_thread
770 R17_H, R17,
771 R18_H, R18,
772 R19_H, R19,
773 R20_H, R20,
774 R21_H, R21,
775 R22_H, R22,
776 R23_H, R23,
777 R24_H, R24,
778 R25_H, R25,
779 R26_H, R26,
780 R27_H, R27,
781 R28_H, R28,
782 /*R29_H, R29,*/
783 R30_H, R30,
784 R31_H, R31
785 );
786
787 // Used to hold the TOC to avoid collisions with expanded DynamicCall
788 // which uses r19 as inline cache internally and expanded LeafCall which uses
789 // r2, r11 and r12 internally.
790 reg_class bits64_constant_table_base(
791 /*R0_H, R0*/ // R0
792 /*R1_H, R1*/ // SP
793 /*R2_H, R2*/ // TOC
794 R3_H, R3,
795 R4_H, R4,
796 R5_H, R5,
797 R6_H, R6,
798 R7_H, R7,
799 R8_H, R8,
800 R9_H, R9,
801 R10_H, R10,
802 /*R11_H, R11*/
803 /*R12_H, R12*/
804 /*R13_H, R13*/ // system thread id
805 R14_H, R14,
806 R15_H, R15,
807 /*R16_H, R16*/ // R16_thread
808 R17_H, R17,
809 R18_H, R18,
810 /*R19_H, R19*/
811 R20_H, R20,
812 R21_H, R21,
813 R22_H, R22,
814 R23_H, R23,
815 R24_H, R24,
816 R25_H, R25,
817 R26_H, R26,
818 R27_H, R27,
819 R28_H, R28,
820 /*R29_H, R29,*/
821 R30_H, R30,
822 R31_H, R31
823 );
824
825 // 64 bit registers that can only be read i.e. these registers can
826 // only be src of all instructions.
827 reg_class bits64_reg_ro(
828 /*R0_H, R0*/ // R0
829 R1_H, R1,
830 R2_H, R2, // TOC
831 R3_H, R3,
832 R4_H, R4,
833 R5_H, R5,
834 R6_H, R6,
835 R7_H, R7,
836 R8_H, R8,
837 R9_H, R9,
838 R10_H, R10,
839 R11_H, R11,
840 R12_H, R12,
841 /*R13_H, R13*/ // system thread id
842 R14_H, R14,
843 R15_H, R15,
844 R16_H, R16, // R16_thread
845 R17_H, R17,
846 R18_H, R18,
847 R19_H, R19,
848 R20_H, R20,
849 R21_H, R21,
850 R22_H, R22,
851 R23_H, R23,
852 R24_H, R24,
853 R25_H, R25,
854 R26_H, R26,
855 R27_H, R27,
856 R28_H, R28,
857 /*R29_H, R29,*/ // TODO: let allocator handle TOC!!
858 R30_H, R30,
859 R31_H, R31
860 );
861
862
863 // ----------------------------
864 // Special Class for Condition Code Flags Register
865
866 reg_class int_flags(
867 /*CR0*/ // scratch
868 /*CR1*/ // scratch
869 /*CR2*/ // nv!
870 /*CR3*/ // nv!
871 /*CR4*/ // nv!
872 CR5,
873 CR6,
874 CR7
875 );
876
877 reg_class int_flags_ro(
878 CR0,
879 CR1,
880 CR2,
881 CR3,
882 CR4,
883 CR5,
884 CR6,
885 CR7
886 );
887
888 reg_class int_flags_CR0(CR0);
889 reg_class int_flags_CR1(CR1);
890 reg_class int_flags_CR6(CR6);
891 reg_class ctr_reg(SR_CTR);
892
893 // ----------------------------
894 // Float Register Classes
895 // ----------------------------
896
897 reg_class flt_reg(
898 F0,
899 F1,
900 F2,
901 F3,
902 F4,
903 F5,
904 F6,
905 F7,
906 F8,
907 F9,
908 F10,
909 F11,
910 F12,
911 F13,
912 F14, // nv!
913 F15, // nv!
914 F16, // nv!
915 F17, // nv!
916 F18, // nv!
917 F19, // nv!
918 F20, // nv!
919 F21, // nv!
920 F22, // nv!
921 F23, // nv!
922 F24, // nv!
923 F25, // nv!
924 F26, // nv!
925 F27, // nv!
926 F28, // nv!
927 F29, // nv!
928 F30, // nv!
929 F31 // nv!
930 );
931
932 // Double precision float registers have virtual `high halves' that
933 // are needed by the allocator.
934 reg_class dbl_reg(
935 F0, F0_H,
936 F1, F1_H,
937 F2, F2_H,
938 F3, F3_H,
939 F4, F4_H,
940 F5, F5_H,
941 F6, F6_H,
942 F7, F7_H,
943 F8, F8_H,
944 F9, F9_H,
945 F10, F10_H,
946 F11, F11_H,
947 F12, F12_H,
948 F13, F13_H,
949 F14, F14_H, // nv!
950 F15, F15_H, // nv!
951 F16, F16_H, // nv!
952 F17, F17_H, // nv!
953 F18, F18_H, // nv!
954 F19, F19_H, // nv!
955 F20, F20_H, // nv!
956 F21, F21_H, // nv!
957 F22, F22_H, // nv!
958 F23, F23_H, // nv!
959 F24, F24_H, // nv!
960 F25, F25_H, // nv!
961 F26, F26_H, // nv!
962 F27, F27_H, // nv!
963 F28, F28_H, // nv!
964 F29, F29_H, // nv!
965 F30, F30_H, // nv!
966 F31, F31_H // nv!
967 );
968
969 // ----------------------------
970 // Vector-Scalar Register Class
971 // ----------------------------
972
973 reg_class v_reg(
974 VR0 , VR0_H , VR0_J , VR0_K ,
975 VR1 , VR1_H , VR1_J , VR1_K ,
976 VR2 , VR2_H , VR2_J , VR2_K ,
977 VR3 , VR3_H , VR3_J , VR3_K ,
978 VR4 , VR4_H , VR4_J , VR4_K ,
979 VR5 , VR5_H , VR5_J , VR5_K ,
980 VR6 , VR6_H , VR6_J , VR6_K ,
981 VR7 , VR7_H , VR7_J , VR7_K ,
982 VR8 , VR8_H , VR8_J , VR8_K ,
983 VR9 , VR9_H , VR9_J , VR9_K ,
984 VR10, VR10_H, VR10_J, VR10_K,
985 VR11, VR11_H, VR11_J, VR11_K,
986 VR12, VR12_H, VR12_J, VR12_K,
987 VR13, VR13_H, VR13_J, VR13_K,
988 VR14, VR14_H, VR14_J, VR14_K,
989 VR15, VR15_H, VR15_J, VR15_K,
990 VR16, VR16_H, VR16_J, VR16_K,
991 VR17, VR17_H, VR17_J, VR17_K,
992 VR18, VR18_H, VR18_J, VR18_K,
993 VR19, VR19_H, VR19_J, VR19_K,
994 VR20, VR20_H, VR20_J, VR20_K,
995 VR21, VR21_H, VR21_J, VR21_K,
996 VR22, VR22_H, VR22_J, VR22_K,
997 VR23, VR23_H, VR23_J, VR23_K,
998 VR24, VR24_H, VR24_J, VR24_K,
999 VR25, VR25_H, VR25_J, VR25_K,
1000 VR26, VR26_H, VR26_J, VR26_K,
1001 VR27, VR27_H, VR27_J, VR27_K,
1002 VR28, VR28_H, VR28_J, VR28_K,
1003 VR29, VR29_H, VR29_J, VR29_K,
1004 VR30, VR30_H, VR30_J, VR30_K,
1005 VR31, VR31_H, VR31_J, VR31_K
1006 );
1007
1008 %}
1009
1010 //----------DEFINITION BLOCK---------------------------------------------------
1011 // Define name --> value mappings to inform the ADLC of an integer valued name
1012 // Current support includes integer values in the range [0, 0x7FFFFFFF]
1013 // Format:
1014 // int_def <name> ( <int_value>, <expression>);
1015 // Generated Code in ad_<arch>.hpp
1016 // #define <name> (<expression>)
1017 // // value == <int_value>
1018 // Generated code in ad_<arch>.cpp adlc_verification()
1019 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
1020 //
1021 definitions %{
1022 // The default cost (of an ALU instruction).
1023 int_def DEFAULT_COST_LOW ( 30, 30);
1024 int_def DEFAULT_COST ( 100, 100);
1025 int_def HUGE_COST (1000000, 1000000);
1026
1027 // Memory refs
1028 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2);
1029 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3);
1030
1031 // Branches are even more expensive.
1032 int_def BRANCH_COST ( 900, DEFAULT_COST * 9);
1033 int_def CALL_COST ( 1300, DEFAULT_COST * 13);
1034 %}
1035
1036
1037 //----------SOURCE BLOCK-------------------------------------------------------
1038 // This is a block of C++ code which provides values, functions, and
1039 // definitions necessary in the rest of the architecture description.
1040 source_hpp %{
1041 // Header information of the source block.
1042 // Method declarations/definitions which are used outside
1043 // the ad-scope can conveniently be defined here.
1044 //
1045 // To keep related declarations/definitions/uses close together,
1046 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
1047
1048 #include "opto/convertnode.hpp"
1049
1050 // Returns true if Node n is followed by a MemBar node that
1051 // will do an acquire. If so, this node must not do the acquire
1052 // operation.
1053 bool followed_by_acquire(const Node *n);
1054 %}
1055
1056 source %{
1057
1058 #include "opto/c2_CodeStubs.hpp"
1059 #include "oops/klass.inline.hpp"
1060
1061 void PhaseOutput::pd_perform_mach_node_analysis() {
1062 }
1063
1064 int MachNode::pd_alignment_required() const {
1065 return 1;
1066 }
1067
1068 int MachNode::compute_padding(int current_offset) const {
1069 return 0;
1070 }
1071
1072 // Should the matcher clone input 'm' of node 'n'?
1073 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
1074 if (is_encode_and_store_pattern(n, m)) {
1075 mstack.push(m, Visit);
1076 return true;
1077 }
1078 return false;
1079 }
1080
1081 // Should the Matcher clone shifts on addressing modes, expecting them
1082 // to be subsumed into complex addressing expressions or compute them
1083 // into registers?
1084 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
1085 return clone_base_plus_offset_address(m, mstack, address_visited);
1086 }
1087
1088 // Optimize load-acquire.
1089 //
1090 // Check if acquire is unnecessary due to following operation that does
1091 // acquire anyways.
1092 // Walk the pattern:
1093 //
1094 // n: Load.acq
1095 // |
1096 // MemBarAcquire
1097 // | |
1098 // Proj(ctrl) Proj(mem)
1099 // | |
1100 // MemBarRelease/Volatile
1101 //
1102 bool followed_by_acquire(const Node *load) {
1103 assert(load->is_Load(), "So far implemented only for loads.");
1104
1105 // Find MemBarAcquire.
1106 const Node *mba = nullptr;
1107 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) {
1108 const Node *out = load->fast_out(i);
1109 if (out->Opcode() == Op_MemBarAcquire) {
1110 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge.
1111 mba = out;
1112 break;
1113 }
1114 }
1115 if (!mba) return false;
1116
1117 // Find following MemBar node.
1118 //
1119 // The following node must be reachable by control AND memory
1120 // edge to assure no other operations are in between the two nodes.
1121 //
1122 // So first get the Proj node, mem_proj, to use it to iterate forward.
1123 Node *mem_proj = nullptr;
1124 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) {
1125 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found.
1126 assert(mem_proj->is_Proj(), "only projections here");
1127 ProjNode *proj = mem_proj->as_Proj();
1128 if (proj->_con == TypeFunc::Memory &&
1129 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only
1130 break;
1131 }
1132 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken");
1133
1134 // Search MemBar behind Proj. If there are other memory operations
1135 // behind the Proj we lost.
1136 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) {
1137 Node *x = mem_proj->fast_out(j);
1138 // Proj might have an edge to a store or load node which precedes the membar.
1139 if (x->is_Mem()) return false;
1140
1141 // On PPC64 release and volatile are implemented by an instruction
1142 // that also has acquire semantics. I.e. there is no need for an
1143 // acquire before these.
1144 int xop = x->Opcode();
1145 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) {
1146 // Make sure we're not missing Call/Phi/MergeMem by checking
1147 // control edges. The control edge must directly lead back
1148 // to the MemBarAcquire
1149 Node *ctrl_proj = x->in(0);
1150 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) {
1151 return true;
1152 }
1153 }
1154 }
1155
1156 return false;
1157 }
1158
1159 #define __ masm->
1160
1161 // Tertiary op of a LoadP or StoreP encoding.
1162 #define REGP_OP true
1163
1164 // ****************************************************************************
1165
1166 // REQUIRED FUNCTIONALITY
1167
1168 // !!!!! Special hack to get all type of calls to specify the byte offset
1169 // from the start of the call to the point where the return address
1170 // will point.
1171
1172 // PPC port: Removed use of lazy constant construct.
1173
1174 int MachCallStaticJavaNode::ret_addr_offset() {
1175 // It's only a single branch-and-link instruction.
1176 return 4;
1177 }
1178
1179 int MachCallDynamicJavaNode::ret_addr_offset() {
1180 return 12;
1181 }
1182
1183 int MachCallRuntimeNode::ret_addr_offset() {
1184 if (rule() == CallRuntimeDirect_rule) {
1185 // CallRuntimeDirectNode uses call_c.
1186 #if defined(ABI_ELFv2)
1187 return 28;
1188 #else
1189 return 40;
1190 #endif
1191 }
1192 assert(rule() == CallLeafDirect_rule, "unexpected node with rule %u", rule());
1193 // CallLeafDirectNode uses bl.
1194 return 4;
1195 }
1196
1197 //=============================================================================
1198
1199 // condition code conversions
1200
1201 static int cc_to_boint(int cc) {
1202 return Assembler::bcondCRbiIs0 | (cc & 8);
1203 }
1204
1205 static int cc_to_inverse_boint(int cc) {
1206 return Assembler::bcondCRbiIs0 | (8-(cc & 8));
1207 }
1208
1209 static int cc_to_biint(int cc, int flags_reg) {
1210 return (flags_reg << 2) | (cc & 3);
1211 }
1212
1213 //=============================================================================
1214
1215 // Compute padding required for nodes which need alignment. The padding
1216 // is the number of bytes (not instructions) which will be inserted before
1217 // the instruction. The padding must match the size of a NOP instruction.
1218
1219 // Add nop if a prefixed (two-word) instruction is going to cross a 64-byte boundary.
1220 // (See Section 1.6 of Power ISA Version 3.1)
1221 static int compute_prefix_padding(int current_offset) {
1222 assert(PowerArchitecturePPC64 >= 10 && (CodeEntryAlignment & 63) == 0,
1223 "Code buffer must be aligned to a multiple of 64 bytes");
1224 if (is_aligned(current_offset + BytesPerInstWord, 64)) {
1225 return BytesPerInstWord;
1226 }
1227 return 0;
1228 }
1229
1230 int loadConI32Node::compute_padding(int current_offset) const {
1231 return compute_prefix_padding(current_offset);
1232 }
1233
1234 int loadConL34Node::compute_padding(int current_offset) const {
1235 return compute_prefix_padding(current_offset);
1236 }
1237
1238 int addI_reg_imm32Node::compute_padding(int current_offset) const {
1239 return compute_prefix_padding(current_offset);
1240 }
1241
1242 int addL_reg_imm34Node::compute_padding(int current_offset) const {
1243 return compute_prefix_padding(current_offset);
1244 }
1245
1246 int addP_reg_imm34Node::compute_padding(int current_offset) const {
1247 return compute_prefix_padding(current_offset);
1248 }
1249
1250 int cmprb_Whitespace_reg_reg_prefixedNode::compute_padding(int current_offset) const {
1251 return compute_prefix_padding(current_offset);
1252 }
1253
1254
1255 //=============================================================================
1256
1257 // Emit an interrupt that is caught by the debugger (for debugging compiler).
1258 void emit_break(C2_MacroAssembler *masm) {
1259 __ illtrap();
1260 }
1261
1262 #ifndef PRODUCT
1263 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1264 st->print("BREAKPOINT");
1265 }
1266 #endif
1267
1268 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1269 emit_break(masm);
1270 }
1271
1272 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1273 return MachNode::size(ra_);
1274 }
1275
1276 //=============================================================================
1277
1278 void emit_nop(C2_MacroAssembler *masm) {
1279 __ nop();
1280 }
1281
1282 static inline void emit_long(C2_MacroAssembler *masm, int value) {
1283 *((int*)(__ pc())) = value;
1284 __ set_inst_end(__ pc() + BytesPerInstWord);
1285 }
1286
1287 //=============================================================================
1288
1289 %} // interrupt source
1290
1291 source_hpp %{ // Header information of the source block.
1292
1293 //--------------------------------------------------------------
1294 //---< Used for optimization in Compile::Shorten_branches >---
1295 //--------------------------------------------------------------
1296
1297 class C2_MacroAssembler;
1298
1299 class CallStubImpl {
1300
1301 public:
1302
1303 // Size of call trampoline stub.
1304 // This doesn't need to be accurate to the byte, but it
1305 // must be larger than or equal to the real size of the stub.
1306 static uint size_call_trampoline() {
1307 return MacroAssembler::trampoline_stub_size;
1308 }
1309
1310 // number of relocations needed by a call trampoline stub
1311 static uint reloc_call_trampoline() {
1312 return 5;
1313 }
1314
1315 };
1316
1317 %} // end source_hpp
1318
1319 source %{
1320
1321 // Factory for creating loadConL* nodes for large/small constant pool.
1322
1323 static inline jlong replicate_immF(float con) {
1324 // Replicate float con 2 times and pack into vector.
1325 int val = *((int*)&con);
1326 jlong lval = val;
1327 lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1328 return lval;
1329 }
1330
1331 //=============================================================================
1332
1333 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1334 int ConstantTable::calculate_table_base_offset() const {
1335 return 0; // absolute addressing, no offset
1336 }
1337
1338 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1339 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1340 iRegLdstOper *op_dst = new iRegLdstOper();
1341 MachNode *m1 = new loadToc_hiNode();
1342 MachNode *m2 = new loadToc_loNode();
1343
1344 m1->add_req(nullptr);
1345 m2->add_req(nullptr, m1);
1346 m1->_opnds[0] = op_dst;
1347 m2->_opnds[0] = op_dst;
1348 m2->_opnds[1] = op_dst;
1349 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1350 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1351 nodes->push(m1);
1352 nodes->push(m2);
1353 }
1354
1355 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const {
1356 // Is postalloc expanded.
1357 ShouldNotReachHere();
1358 }
1359
1360 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1361 return 0;
1362 }
1363
1364 #ifndef PRODUCT
1365 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1366 st->print("-- \t// MachConstantBaseNode (empty encoding)");
1367 }
1368 #endif
1369
1370 //=============================================================================
1371
1372 #ifndef PRODUCT
1373 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1374 Compile* C = ra_->C;
1375 const long framesize = C->output()->frame_slots() << LogBytesPerInt;
1376
1377 st->print("PROLOG\n\t");
1378 if (C->output()->need_stack_bang(framesize)) {
1379 st->print("stack_overflow_check\n\t");
1380 }
1381
1382 if (!false /* TODO: PPC port C->is_frameless_method()*/) {
1383 st->print("save return pc\n\t");
1384 st->print("push frame %ld\n\t", -framesize);
1385 }
1386
1387 if (C->stub_function() == nullptr) {
1388 st->print("nmethod entry barrier\n\t");
1389 }
1390 }
1391 #endif
1392
1393 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1394 Compile* C = ra_->C;
1395
1396 const long framesize = C->output()->frame_size_in_bytes();
1397 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment");
1398
1399 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1400
1401 const Register return_pc = R20; // Must match return_addr() in frame section.
1402 const Register callers_sp = R21;
1403 const Register push_frame_temp = R22;
1404 const Register toc_temp = R23;
1405 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp);
1406
1407 if (!method_is_frameless) {
1408 // Get return pc.
1409 __ mflr(return_pc);
1410 }
1411
1412 if (C->clinit_barrier_on_entry()) {
1413 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
1414
1415 Label L_skip_barrier;
1416 Register klass = toc_temp;
1417
1418 // Notify OOP recorder (don't need the relocation)
1419 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding());
1420 __ load_const_optimized(klass, md.value(), R0);
1421 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/);
1422
1423 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0);
1424 __ mtctr(klass);
1425 __ bctr();
1426
1427 __ bind(L_skip_barrier);
1428 }
1429
1430 // Calls to C2R adapters often do not accept exceptional returns.
1431 // We require that their callers must bang for them. But be
1432 // careful, because some VM calls (such as call site linkage) can
1433 // use several kilobytes of stack. But the stack safety zone should
1434 // account for that. See bugs 4446381, 4468289, 4497237.
1435
1436 int bangsize = C->output()->bang_size_in_bytes();
1437 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect");
1438 if (C->output()->need_stack_bang(bangsize)) {
1439 // Unfortunately we cannot use the function provided in
1440 // assembler.cpp as we have to emulate the pipes. So I had to
1441 // insert the code of generate_stack_overflow_check(), see
1442 // assembler.cpp for some illuminative comments.
1443 const int page_size = os::vm_page_size();
1444 int bang_end = StackOverflow::stack_shadow_zone_size();
1445
1446 // This is how far the previous frame's stack banging extended.
1447 const int bang_end_safe = bang_end;
1448
1449 if (bangsize > page_size) {
1450 bang_end += bangsize;
1451 }
1452
1453 int bang_offset = bang_end_safe;
1454
1455 while (bang_offset <= bang_end) {
1456 // Need at least one stack bang at end of shadow zone.
1457
1458 // Again I had to copy code, this time from assembler_ppc.cpp,
1459 // bang_stack_with_offset - see there for comments.
1460
1461 // Stack grows down, caller passes positive offset.
1462 assert(bang_offset > 0, "must bang with positive offset");
1463
1464 long stdoffset = -bang_offset;
1465
1466 if (Assembler::is_simm(stdoffset, 16)) {
1467 // Signed 16 bit offset, a simple std is ok.
1468 if (UseLoadInstructionsForStackBangingPPC64) {
1469 __ ld(R0, (int)(signed short)stdoffset, R1_SP);
1470 } else {
1471 __ std(R0, (int)(signed short)stdoffset, R1_SP);
1472 }
1473 } else if (Assembler::is_simm(stdoffset, 31)) {
1474 // Use largeoffset calculations for addis & ld/std.
1475 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset);
1476 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset);
1477
1478 Register tmp = R11;
1479 __ addis(tmp, R1_SP, hi);
1480 if (UseLoadInstructionsForStackBangingPPC64) {
1481 __ ld(R0, lo, tmp);
1482 } else {
1483 __ std(R0, lo, tmp);
1484 }
1485 } else {
1486 ShouldNotReachHere();
1487 }
1488
1489 bang_offset += page_size;
1490 }
1491 // R11 trashed
1492 } // C->output()->need_stack_bang(framesize)
1493
1494 unsigned int bytes = (unsigned int)framesize;
1495 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
1496 ciMethod *currMethod = C->method();
1497
1498 if (!method_is_frameless) {
1499 // Get callers sp.
1500 __ mr(callers_sp, R1_SP);
1501
1502 // Push method's frame, modifies SP.
1503 assert(Assembler::is_uimm(framesize, 32U), "wrong type");
1504 // The ABI is already accounted for in 'framesize' via the
1505 // 'out_preserve' area.
1506 Register tmp = push_frame_temp;
1507 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp).
1508 if (Assembler::is_simm(-offset, 16)) {
1509 __ stdu(R1_SP, -offset, R1_SP);
1510 } else {
1511 long x = -offset;
1512 // Had to insert load_const(tmp, -offset).
1513 __ lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16)));
1514 __ ori( tmp, tmp, ((x >> 32) & 0x0000ffff));
1515 __ sldi(tmp, tmp, 32);
1516 __ oris(tmp, tmp, (x & 0xffff0000) >> 16);
1517 __ ori( tmp, tmp, (x & 0x0000ffff));
1518
1519 __ stdux(R1_SP, R1_SP, tmp);
1520 }
1521 }
1522 #if 0 // TODO: PPC port
1523 // For testing large constant pools, emit a lot of constants to constant pool.
1524 // "Randomize" const_size.
1525 if (ConstantsALot) {
1526 const int num_consts = const_size();
1527 for (int i = 0; i < num_consts; i++) {
1528 __ long_constant(0xB0B5B00BBABE);
1529 }
1530 }
1531 #endif
1532 if (!method_is_frameless) {
1533 // Save return pc.
1534 __ std(return_pc, _abi0(lr), callers_sp);
1535 }
1536
1537 if (C->stub_function() == nullptr) {
1538 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
1539 bs->nmethod_entry_barrier(masm, push_frame_temp);
1540 }
1541
1542 C->output()->set_frame_complete(__ offset());
1543 }
1544
1545 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1546 // Variable size. determine dynamically.
1547 return MachNode::size(ra_);
1548 }
1549
1550 int MachPrologNode::reloc() const {
1551 // Return number of relocatable values contained in this instruction.
1552 return 1; // 1 reloc entry for load_const(toc).
1553 }
1554
1555 //=============================================================================
1556
1557 #ifndef PRODUCT
1558 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1559 Compile* C = ra_->C;
1560
1561 st->print("EPILOG\n\t");
1562 st->print("restore return pc\n\t");
1563 st->print("pop frame\n\t");
1564
1565 if (do_polling() && C->is_method_compilation()) {
1566 st->print("safepoint poll\n\t");
1567 }
1568 }
1569 #endif
1570
1571 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1572 Compile* C = ra_->C;
1573
1574 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt;
1575 assert(framesize >= 0, "negative frame-size?");
1576
1577 const bool method_needs_polling = do_polling() && C->is_method_compilation();
1578 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1579 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
1580 const Register temp = R12;
1581
1582 if (!method_is_frameless) {
1583 // Restore return pc relative to callers' sp.
1584 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP);
1585 // Move return pc to LR.
1586 __ mtlr(return_pc);
1587 // Pop frame (fixed frame-size).
1588 __ addi(R1_SP, R1_SP, (int)framesize);
1589 }
1590
1591 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1592 __ reserved_stack_check(return_pc);
1593 }
1594
1595 if (method_needs_polling) {
1596 Label dummy_label;
1597 Label* code_stub = &dummy_label;
1598 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) {
1599 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1600 C->output()->add_stub(stub);
1601 code_stub = &stub->entry();
1602 __ relocate(relocInfo::poll_return_type);
1603 }
1604 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */);
1605 }
1606 }
1607
1608 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1609 // Variable size. Determine dynamically.
1610 return MachNode::size(ra_);
1611 }
1612
1613 int MachEpilogNode::reloc() const {
1614 // Return number of relocatable values contained in this instruction.
1615 return 1; // 1 for load_from_polling_page.
1616 }
1617
1618 const Pipeline * MachEpilogNode::pipeline() const {
1619 return MachNode::pipeline_class();
1620 }
1621
1622 // =============================================================================
1623
1624 // Figure out which register class each belongs in: rc_int, rc_float, rc_vec or
1625 // rc_stack.
1626 enum RC { rc_bad, rc_int, rc_float, rc_vec, rc_stack };
1627
1628 static enum RC rc_class(OptoReg::Name reg) {
1629 // Return the register class for the given register. The given register
1630 // reg is a <register>_num value, which is an index into the MachRegisterNumbers
1631 // enumeration in adGlobals_ppc.hpp.
1632
1633 if (reg == OptoReg::Bad) return rc_bad;
1634
1635 // We have 64 integer register halves, starting at index 0.
1636 STATIC_ASSERT((int)ConcreteRegisterImpl::max_gpr == (int)MachRegisterNumbers::F0_num);
1637 if (reg < ConcreteRegisterImpl::max_gpr) return rc_int;
1638
1639 // We have 64 floating-point register halves, starting at index 64.
1640 STATIC_ASSERT((int)ConcreteRegisterImpl::max_fpr == (int)MachRegisterNumbers::VR0_num);
1641 if (reg < ConcreteRegisterImpl::max_fpr) return rc_float;
1642
1643 // We have 64 vector-scalar registers, starting at index 128.
1644 STATIC_ASSERT((int)ConcreteRegisterImpl::max_vr == (int)MachRegisterNumbers::CR0_num);
1645 if (reg < ConcreteRegisterImpl::max_vr) return rc_vec;
1646
1647 // Condition and special purpose registers are not allocated. We only accept stack from here.
1648 assert(OptoReg::is_stack(reg), "what else is it?");
1649 return rc_stack;
1650 }
1651
1652 static int ld_st_helper(C2_MacroAssembler *masm, const char *op_str, uint opcode, int reg, int offset,
1653 bool do_print, Compile* C, outputStream *st) {
1654
1655 assert(opcode == Assembler::LD_OPCODE ||
1656 opcode == Assembler::STD_OPCODE ||
1657 opcode == Assembler::LWZ_OPCODE ||
1658 opcode == Assembler::STW_OPCODE ||
1659 opcode == Assembler::LFD_OPCODE ||
1660 opcode == Assembler::STFD_OPCODE ||
1661 opcode == Assembler::LFS_OPCODE ||
1662 opcode == Assembler::STFS_OPCODE,
1663 "opcode not supported");
1664
1665 if (masm) {
1666 int d =
1667 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ?
1668 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/)
1669 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build.
1670 emit_long(masm, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP));
1671 }
1672 #ifndef PRODUCT
1673 else if (do_print) {
1674 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy",
1675 op_str,
1676 Matcher::regName[reg],
1677 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/);
1678 }
1679 #endif
1680 return 4; // size
1681 }
1682
1683 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1684 Compile* C = ra_->C;
1685
1686 // Get registers to move.
1687 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1688 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1689 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1690 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1691
1692 enum RC src_hi_rc = rc_class(src_hi);
1693 enum RC src_lo_rc = rc_class(src_lo);
1694 enum RC dst_hi_rc = rc_class(dst_hi);
1695 enum RC dst_lo_rc = rc_class(dst_lo);
1696
1697 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1698 if (src_hi != OptoReg::Bad)
1699 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1700 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1701 "expected aligned-adjacent pairs");
1702 // Generate spill code!
1703 int size = 0;
1704
1705 if (src_lo == dst_lo && src_hi == dst_hi)
1706 return size; // Self copy, no move.
1707
1708 if (bottom_type()->isa_vect() != nullptr && ideal_reg() == Op_VecX) {
1709 int src_offset = ra_->reg2offset(src_lo);
1710 int dst_offset = ra_->reg2offset(dst_lo);
1711 DEBUG_ONLY(int algm = MIN2(RegMask::num_registers(ideal_reg()), (int)Matcher::stack_alignment_in_slots()) * VMRegImpl::stack_slot_size);
1712 assert((src_lo_rc != rc_stack) || is_aligned(src_offset, algm), "unaligned vector spill sp offset %d (src)", src_offset);
1713 assert((dst_lo_rc != rc_stack) || is_aligned(dst_offset, algm), "unaligned vector spill sp offset %d (dst)", dst_offset);
1714 // Memory->Memory Spill.
1715 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1716 if (masm) {
1717 __ ld(R0, src_offset, R1_SP);
1718 __ std(R0, dst_offset, R1_SP);
1719 __ ld(R0, src_offset+8, R1_SP);
1720 __ std(R0, dst_offset+8, R1_SP);
1721 }
1722 size += 16;
1723 #ifndef PRODUCT
1724 if (st != nullptr) {
1725 st->print("%-7s [R1_SP + #%d] -> [R1_SP + #%d] \t// vector spill copy", "SPILL", src_offset, dst_offset);
1726 }
1727 #endif // !PRODUCT
1728 }
1729 // VectorRegister->Memory Spill.
1730 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_stack) {
1731 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1732 if (masm) {
1733 __ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16
1734 }
1735 size += 4;
1736 #ifndef PRODUCT
1737 if (st != nullptr) {
1738 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "STXV", Matcher::regName[src_lo], dst_offset);
1739 }
1740 #endif // !PRODUCT
1741 }
1742 // Memory->VectorRegister Spill.
1743 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vec) {
1744 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1745 if (masm) {
1746 __ lxv(Rdst, src_offset, R1_SP);
1747 }
1748 size += 4;
1749 #ifndef PRODUCT
1750 if (st != nullptr) {
1751 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "LXV", Matcher::regName[dst_lo], src_offset);
1752 }
1753 #endif // !PRODUCT
1754 }
1755 // VectorRegister->VectorRegister.
1756 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_vec) {
1757 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1758 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1759 if (masm) {
1760 __ xxlor(Rdst, Rsrc, Rsrc);
1761 }
1762 size += 4;
1763 #ifndef PRODUCT
1764 if (st != nullptr) {
1765 st->print("%-7s %s, %s, %s\t// vector spill copy",
1766 "XXLOR", Matcher::regName[dst_lo], Matcher::regName[src_lo], Matcher::regName[src_lo]);
1767 }
1768 #endif // !PRODUCT
1769 }
1770 else {
1771 ShouldNotReachHere(); // No VR spill.
1772 }
1773 return size;
1774 }
1775
1776 // --------------------------------------
1777 // Memory->Memory Spill. Use R0 to hold the value.
1778 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1779 int src_offset = ra_->reg2offset(src_lo);
1780 int dst_offset = ra_->reg2offset(dst_lo);
1781 if (src_hi != OptoReg::Bad) {
1782 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack,
1783 "expected same type of move for high parts");
1784 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st);
1785 if (!masm && !do_size) st->print("\n\t");
1786 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st);
1787 } else {
1788 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st);
1789 if (!masm && !do_size) st->print("\n\t");
1790 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st);
1791 }
1792 return size;
1793 }
1794
1795 // --------------------------------------
1796 // Check for float->int copy; requires a trip through memory.
1797 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1798 Unimplemented();
1799 }
1800
1801 // --------------------------------------
1802 // Check for integer reg-reg copy.
1803 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1804 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1805 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1806 size = (Rsrc != Rdst) ? 4 : 0;
1807
1808 if (masm) {
1809 if (size) {
1810 __ mr(Rdst, Rsrc);
1811 }
1812 }
1813 #ifndef PRODUCT
1814 else if (!do_size) {
1815 if (size) {
1816 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1817 } else {
1818 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1819 }
1820 }
1821 #endif
1822 return size;
1823 }
1824
1825 // Check for integer store.
1826 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1827 int dst_offset = ra_->reg2offset(dst_lo);
1828 if (src_hi != OptoReg::Bad) {
1829 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack,
1830 "expected same type of move for high parts");
1831 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1832 } else {
1833 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st);
1834 }
1835 return size;
1836 }
1837
1838 // Check for integer load.
1839 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1840 int src_offset = ra_->reg2offset(src_lo);
1841 if (src_hi != OptoReg::Bad) {
1842 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack,
1843 "expected same type of move for high parts");
1844 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1845 } else {
1846 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st);
1847 }
1848 return size;
1849 }
1850
1851 // Check for float reg-reg copy.
1852 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1853 if (masm) {
1854 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]);
1855 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]);
1856 __ fmr(Rdst, Rsrc);
1857 }
1858 #ifndef PRODUCT
1859 else if (!do_size) {
1860 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1861 }
1862 #endif
1863 return 4;
1864 }
1865
1866 // Check for float store.
1867 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1868 int dst_offset = ra_->reg2offset(dst_lo);
1869 if (src_hi != OptoReg::Bad) {
1870 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack,
1871 "expected same type of move for high parts");
1872 size += ld_st_helper(masm, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1873 } else {
1874 size += ld_st_helper(masm, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st);
1875 }
1876 return size;
1877 }
1878
1879 // Check for float load.
1880 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1881 int src_offset = ra_->reg2offset(src_lo);
1882 if (src_hi != OptoReg::Bad) {
1883 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack,
1884 "expected same type of move for high parts");
1885 size += ld_st_helper(masm, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1886 } else {
1887 size += ld_st_helper(masm, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st);
1888 }
1889 return size;
1890 }
1891
1892 // --------------------------------------------------------------------
1893 // Check for hi bits still needing moving. Only happens for misaligned
1894 // arguments to native calls.
1895 if (src_hi == dst_hi)
1896 return size; // Self copy; no move.
1897
1898 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad");
1899 ShouldNotReachHere(); // Unimplemented
1900 return 0;
1901 }
1902
1903 #ifndef PRODUCT
1904 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1905 if (!ra_)
1906 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1907 else
1908 implementation(nullptr, ra_, false, st);
1909 }
1910 #endif
1911
1912 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1913 implementation(masm, ra_, false, nullptr);
1914 }
1915
1916 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1917 return implementation(nullptr, ra_, true, nullptr);
1918 }
1919
1920 #ifndef PRODUCT
1921 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1922 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count);
1923 }
1924 #endif
1925
1926 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *) const {
1927 // _count contains the number of nops needed for padding.
1928 for (int i = 0; i < _count; i++) {
1929 __ nop();
1930 }
1931 }
1932
1933 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
1934 return _count * 4;
1935 }
1936
1937 #ifndef PRODUCT
1938 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1939 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1940 char reg_str[128];
1941 ra_->dump_register(this, reg_str, sizeof(reg_str));
1942 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset);
1943 }
1944 #endif
1945
1946 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1947 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1948 int reg = ra_->get_encode(this);
1949
1950 if (Assembler::is_simm(offset, 16)) {
1951 __ addi(as_Register(reg), R1, offset);
1952 } else {
1953 ShouldNotReachHere();
1954 }
1955 }
1956
1957 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1958 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1959 return 4;
1960 }
1961
1962 #ifndef PRODUCT
1963 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1964 st->print_cr("---- MachUEPNode ----");
1965 st->print_cr("...");
1966 }
1967 #endif
1968
1969 void MachUEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1970 // This is the unverified entry point.
1971 __ ic_check(CodeEntryAlignment);
1972 // Argument is valid and klass is as expected, continue.
1973 }
1974
1975 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1976 // Variable size. Determine dynamically.
1977 return MachNode::size(ra_);
1978 }
1979
1980 //=============================================================================
1981
1982 %} // interrupt source
1983
1984 source_hpp %{ // Header information of the source block.
1985
1986 class HandlerImpl {
1987
1988 public:
1989
1990 static int emit_deopt_handler(C2_MacroAssembler* masm);
1991
1992 static uint size_deopt_handler() {
1993 // The deopt_handler is a bl64_patchable.
1994 return MacroAssembler::bl64_patchable_size + BytesPerInstWord;
1995 }
1996
1997 };
1998
1999 class Node::PD {
2000 public:
2001 enum NodeFlags {
2002 _last_flag = Node::_last_flag
2003 };
2004 };
2005
2006 %} // end source_hpp
2007
2008 source %{
2009
2010 // The deopt_handler is like the exception handler, but it calls to
2011 // the deoptimization blob instead of jumping to the exception blob.
2012 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
2013 address base = __ start_a_stub(size_deopt_handler());
2014 if (base == nullptr) {
2015 ciEnv::current()->record_failure("CodeCache is full");
2016 return 0; // CodeBuffer::expand failed
2017 }
2018
2019 int offset = __ offset();
2020
2021 Label start;
2022 __ bind(start);
2023
2024 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
2025 relocInfo::runtime_call_type);
2026
2027 int entry_offset = __ offset();
2028
2029 __ b(start);
2030
2031 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
2032 assert(__ offset() - entry_offset >= NativePostCallNop::first_check_size,
2033 "out of bounds read in post-call NOP check");
2034 __ end_a_stub();
2035
2036 return entry_offset;
2037 }
2038
2039 //=============================================================================
2040
2041 // Use a frame slots bias for frameless methods if accessing the stack.
2042 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) {
2043 if (as_Register(reg_enc) == R1_SP) {
2044 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes();
2045 }
2046 return 0;
2047 }
2048
2049 bool Matcher::match_rule_supported(int opcode) {
2050 if (!has_match_rule(opcode)) {
2051 return false; // no match rule present
2052 }
2053
2054 switch (opcode) {
2055 case Op_CountLeadingZerosI:
2056 case Op_CountLeadingZerosL:
2057 return UseCountLeadingZerosInstructionsPPC64;
2058 case Op_CountTrailingZerosI:
2059 case Op_CountTrailingZerosL:
2060 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64);
2061 case Op_PopCountI:
2062 case Op_PopCountL:
2063 return UsePopCountInstruction;
2064 case Op_ConvF2HF:
2065 case Op_ConvHF2F:
2066 return VM_Version::supports_float16();
2067 case Op_AddVB:
2068 case Op_AddVS:
2069 case Op_AddVI:
2070 case Op_AddVF:
2071 case Op_AddVD:
2072 case Op_SubVB:
2073 case Op_SubVS:
2074 case Op_SubVI:
2075 case Op_SubVF:
2076 case Op_SubVD:
2077 case Op_MulVS:
2078 case Op_MulVF:
2079 case Op_MulVD:
2080 case Op_DivVF:
2081 case Op_DivVD:
2082 case Op_AbsVF:
2083 case Op_AbsVD:
2084 case Op_NegVI:
2085 case Op_NegVF:
2086 case Op_NegVD:
2087 case Op_SqrtVF:
2088 case Op_SqrtVD:
2089 case Op_AddVL:
2090 case Op_SubVL:
2091 case Op_MulVI:
2092 case Op_RoundDoubleModeV:
2093 case Op_MinV:
2094 case Op_MaxV:
2095 case Op_UMinV:
2096 case Op_UMaxV:
2097 case Op_AndV:
2098 case Op_OrV:
2099 case Op_XorV:
2100 case Op_AddReductionVI:
2101 case Op_MulReductionVI:
2102 case Op_AndReductionV:
2103 case Op_OrReductionV:
2104 case Op_XorReductionV:
2105 case Op_MinReductionV:
2106 case Op_MaxReductionV:
2107 return SuperwordUseVSX;
2108 case Op_PopCountVI:
2109 case Op_PopCountVL:
2110 return (SuperwordUseVSX && UsePopCountInstruction);
2111 case Op_CountLeadingZerosV:
2112 return SuperwordUseVSX && UseCountLeadingZerosInstructionsPPC64;
2113 case Op_CountTrailingZerosV:
2114 return SuperwordUseVSX && UseCountTrailingZerosInstructionsPPC64;
2115 case Op_FmaF:
2116 case Op_FmaD:
2117 return UseFMA;
2118 case Op_FmaVF:
2119 case Op_FmaVD:
2120 return (SuperwordUseVSX && UseFMA);
2121
2122 case Op_MinF:
2123 case Op_MaxF:
2124 case Op_MinD:
2125 case Op_MaxD:
2126 return (PowerArchitecturePPC64 >= 9);
2127
2128 case Op_Digit:
2129 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit);
2130 case Op_LowerCase:
2131 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase);
2132 case Op_UpperCase:
2133 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase);
2134 case Op_Whitespace:
2135 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace);
2136
2137 case Op_CacheWB:
2138 case Op_CacheWBPreSync:
2139 case Op_CacheWBPostSync:
2140 return VM_Version::supports_data_cache_line_flush();
2141 }
2142
2143 return true; // Per default match rules are supported.
2144 }
2145
2146 bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
2147 return match_rule_supported_vector(opcode, vlen, bt);
2148 }
2149
2150 bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
2151 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
2152 return false;
2153 }
2154 // Special cases
2155 switch (opcode) {
2156 // Reductions only support INT at the moment.
2157 case Op_AddReductionVI:
2158 case Op_MulReductionVI:
2159 case Op_AndReductionV:
2160 case Op_OrReductionV:
2161 case Op_XorReductionV:
2162 case Op_MinReductionV:
2163 case Op_MaxReductionV:
2164 return bt == T_INT;
2165 // MaxV, MinV need types == INT || LONG.
2166 case Op_MaxV:
2167 case Op_MinV:
2168 case Op_UMinV:
2169 case Op_UMaxV:
2170 return bt == T_INT || bt == T_LONG;
2171 case Op_NegVI:
2172 return bt == T_INT;
2173 }
2174 return true; // Per default match rules are supported.
2175 }
2176
2177 bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
2178 return false;
2179 }
2180
2181 bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
2182 return false;
2183 }
2184
2185 bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
2186 return false;
2187 }
2188
2189 bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
2190 return false;
2191 }
2192
2193 const RegMask* Matcher::predicate_reg_mask(void) {
2194 return nullptr;
2195 }
2196
2197 // Vector calling convention not yet implemented.
2198 bool Matcher::supports_vector_calling_convention(void) {
2199 return false;
2200 }
2201
2202 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2203 Unimplemented();
2204 return OptoRegPair(0, 0);
2205 }
2206
2207 // Vector width in bytes.
2208 int Matcher::vector_width_in_bytes(BasicType bt) {
2209 if (SuperwordUseVSX) {
2210 assert(MaxVectorSize == 16,
2211 "SuperwordUseVSX requires MaxVectorSize 16, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2212 return 16;
2213 } else {
2214 assert(MaxVectorSize == 8,
2215 "expected MaxVectorSize 8, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2216 return 8;
2217 }
2218 }
2219
2220 // Vector ideal reg.
2221 uint Matcher::vector_ideal_reg(int size) {
2222 if (SuperwordUseVSX) {
2223 assert(MaxVectorSize == 16 && size == 16,
2224 "SuperwordUseVSX requires MaxVectorSize 16 and size 16, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2225 (int64_t)MaxVectorSize, size);
2226 return Op_VecX;
2227 } else {
2228 assert(MaxVectorSize == 8 && size == 8,
2229 "expected MaxVectorSize 8 and size 8, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2230 (int64_t)MaxVectorSize, size);
2231 return Op_RegL;
2232 }
2233 }
2234
2235 // Limits on vector size (number of elements) loaded into vector.
2236 int Matcher::max_vector_size(const BasicType bt) {
2237 assert(is_java_primitive(bt), "only primitive type vectors");
2238 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2239 }
2240
2241 int Matcher::min_vector_size(const BasicType bt) {
2242 return max_vector_size(bt); // Same as max.
2243 }
2244
2245 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
2246 return Matcher::max_vector_size(bt);
2247 }
2248
2249 int Matcher::scalable_vector_reg_size(const BasicType bt) {
2250 return -1;
2251 }
2252
2253 // RETURNS: whether this branch offset is short enough that a short
2254 // branch can be used.
2255 //
2256 // If the platform does not provide any short branch variants, then
2257 // this method should return `false' for offset 0.
2258 //
2259 // `Compile::Fill_buffer' will decide on basis of this information
2260 // whether to do the pass `Compile::Shorten_branches' at all.
2261 //
2262 // And `Compile::Shorten_branches' will decide on basis of this
2263 // information whether to replace particular branch sites by short
2264 // ones.
2265 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2266 // Is the offset within the range of a ppc64 pc relative branch?
2267 bool b;
2268
2269 const int safety_zone = 3 * BytesPerInstWord;
2270 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2271 29 - 16 + 1 + 2);
2272 return b;
2273 }
2274
2275 /* TODO: PPC port
2276 // Make a new machine dependent decode node (with its operands).
2277 MachTypeNode *Matcher::make_decode_node() {
2278 assert(CompressedOops::base() == nullptr && CompressedOops::shift() == 0,
2279 "This method is only implemented for unscaled cOops mode so far");
2280 MachTypeNode *decode = new decodeN_unscaledNode();
2281 decode->set_opnd_array(0, new iRegPdstOper());
2282 decode->set_opnd_array(1, new iRegNsrcOper());
2283 return decode;
2284 }
2285 */
2286
2287 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
2288 ShouldNotReachHere(); // generic vector operands not supported
2289 return nullptr;
2290 }
2291
2292 bool Matcher::is_reg2reg_move(MachNode* m) {
2293 ShouldNotReachHere(); // generic vector operands not supported
2294 return false;
2295 }
2296
2297 bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
2298 return false;
2299 }
2300
2301 bool Matcher::is_generic_vector(MachOper* opnd) {
2302 ShouldNotReachHere(); // generic vector operands not supported
2303 return false;
2304 }
2305
2306 #ifdef ASSERT
2307 // Return whether or not this register is ever used as an argument.
2308 bool Matcher::can_be_java_arg(int reg) {
2309 // We must include the virtual halves in order to get STDs and LDs
2310 // instead of STWs and LWs in the trampoline stubs.
2311
2312 if ( reg == R3_num || reg == R3_H_num
2313 || reg == R4_num || reg == R4_H_num
2314 || reg == R5_num || reg == R5_H_num
2315 || reg == R6_num || reg == R6_H_num
2316 || reg == R7_num || reg == R7_H_num
2317 || reg == R8_num || reg == R8_H_num
2318 || reg == R9_num || reg == R9_H_num
2319 || reg == R10_num || reg == R10_H_num)
2320 return true;
2321
2322 if ( reg == F1_num || reg == F1_H_num
2323 || reg == F2_num || reg == F2_H_num
2324 || reg == F3_num || reg == F3_H_num
2325 || reg == F4_num || reg == F4_H_num
2326 || reg == F5_num || reg == F5_H_num
2327 || reg == F6_num || reg == F6_H_num
2328 || reg == F7_num || reg == F7_H_num
2329 || reg == F8_num || reg == F8_H_num
2330 || reg == F9_num || reg == F9_H_num
2331 || reg == F10_num || reg == F10_H_num
2332 || reg == F11_num || reg == F11_H_num
2333 || reg == F12_num || reg == F12_H_num
2334 || reg == F13_num || reg == F13_H_num)
2335 return true;
2336
2337 return false;
2338 }
2339 #endif
2340
2341 uint Matcher::int_pressure_limit()
2342 {
2343 return (INTPRESSURE == -1) ? 26 : INTPRESSURE;
2344 }
2345
2346 uint Matcher::float_pressure_limit()
2347 {
2348 return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE;
2349 }
2350
2351 // Register for DIVI projection of divmodI.
2352 const RegMask& Matcher::divI_proj_mask() {
2353 ShouldNotReachHere();
2354 return RegMask::EMPTY;
2355 }
2356
2357 // Register for MODI projection of divmodI.
2358 const RegMask& Matcher::modI_proj_mask() {
2359 ShouldNotReachHere();
2360 return RegMask::EMPTY;
2361 }
2362
2363 // Register for DIVL projection of divmodL.
2364 const RegMask& Matcher::divL_proj_mask() {
2365 ShouldNotReachHere();
2366 return RegMask::EMPTY;
2367 }
2368
2369 // Register for MODL projection of divmodL.
2370 const RegMask& Matcher::modL_proj_mask() {
2371 ShouldNotReachHere();
2372 return RegMask::EMPTY;
2373 }
2374
2375 %}
2376
2377 //----------ENCODING BLOCK-----------------------------------------------------
2378 // This block specifies the encoding classes used by the compiler to output
2379 // byte streams. Encoding classes are parameterized macros used by
2380 // Machine Instruction Nodes in order to generate the bit encoding of the
2381 // instruction. Operands specify their base encoding interface with the
2382 // interface keyword. There are currently supported four interfaces,
2383 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
2384 // operand to generate a function which returns its register number when
2385 // queried. CONST_INTER causes an operand to generate a function which
2386 // returns the value of the constant when queried. MEMORY_INTER causes an
2387 // operand to generate four functions which return the Base Register, the
2388 // Index Register, the Scale Value, and the Offset Value of the operand when
2389 // queried. COND_INTER causes an operand to generate six functions which
2390 // return the encoding code (ie - encoding bits for the instruction)
2391 // associated with each basic boolean condition for a conditional instruction.
2392 //
2393 // Instructions specify two basic values for encoding. Again, a function
2394 // is available to check if the constant displacement is an oop. They use the
2395 // ins_encode keyword to specify their encoding classes (which must be
2396 // a sequence of enc_class names, and their parameters, specified in
2397 // the encoding block), and they use the
2398 // opcode keyword to specify, in order, their primary, secondary, and
2399 // tertiary opcode. Only the opcode sections which a particular instruction
2400 // needs for encoding need to be specified.
2401 encode %{
2402 enc_class enc_unimplemented %{
2403 __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
2404 %}
2405
2406 enc_class enc_untested %{
2407 #ifdef ASSERT
2408 __ untested("Untested mach node encoding in AD file.");
2409 #else
2410 #endif
2411 %}
2412
2413 enc_class enc_lbz(iRegIdst dst, memory mem) %{
2414 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2415 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2416 %}
2417
2418 // Load acquire.
2419 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
2420 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2421 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2422 __ twi_0($dst$$Register);
2423 __ isync();
2424 %}
2425
2426 enc_class enc_lhz(iRegIdst dst, memory mem) %{
2427 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2428 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2429 %}
2430
2431 // Load acquire.
2432 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
2433 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2434 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2435 __ twi_0($dst$$Register);
2436 __ isync();
2437 %}
2438
2439 enc_class enc_lwz(iRegIdst dst, memory mem) %{
2440 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2441 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2442 %}
2443
2444 // Load acquire.
2445 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
2446 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2447 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2448 __ twi_0($dst$$Register);
2449 __ isync();
2450 %}
2451
2452 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
2453 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2454 // Operand 'ds' requires 4-alignment.
2455 assert((Idisp & 0x3) == 0, "unaligned offset");
2456 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2457 %}
2458
2459 // Load acquire.
2460 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
2461 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2462 // Operand 'ds' requires 4-alignment.
2463 assert((Idisp & 0x3) == 0, "unaligned offset");
2464 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2465 __ twi_0($dst$$Register);
2466 __ isync();
2467 %}
2468
2469 enc_class enc_lfd(RegF dst, memory mem) %{
2470 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2471 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2472 %}
2473
2474 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2475 int toc_offset = 0;
2476
2477 address const_toc_addr;
2478 // Create a non-oop constant, no relocation needed.
2479 // If it is an IC, it has a virtual_call_Relocation.
2480 const_toc_addr = __ long_constant((jlong)$src$$constant);
2481 if (const_toc_addr == nullptr) {
2482 ciEnv::current()->record_out_of_memory_failure();
2483 return;
2484 }
2485
2486 // Get the constant's TOC offset.
2487 toc_offset = __ offset_to_method_toc(const_toc_addr);
2488
2489 // Keep the current instruction offset in mind.
2490 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2491
2492 __ ld($dst$$Register, toc_offset, $toc$$Register);
2493 %}
2494
2495 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2496 if (!ra_->C->output()->in_scratch_emit_size()) {
2497 address const_toc_addr;
2498 // Create a non-oop constant, no relocation needed.
2499 // If it is an IC, it has a virtual_call_Relocation.
2500 const_toc_addr = __ long_constant((jlong)$src$$constant);
2501 if (const_toc_addr == nullptr) {
2502 ciEnv::current()->record_out_of_memory_failure();
2503 return;
2504 }
2505
2506 // Get the constant's TOC offset.
2507 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2508 // Store the toc offset of the constant.
2509 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2510
2511 // Also keep the current instruction offset in mind.
2512 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2513 }
2514
2515 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2516 %}
2517
2518 %} // encode
2519
2520 source %{
2521
2522 typedef struct {
2523 loadConL_hiNode *_large_hi;
2524 loadConL_loNode *_large_lo;
2525 loadConLNode *_small;
2526 MachNode *_last;
2527 } loadConLNodesTuple;
2528
2529 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2530 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2531 loadConLNodesTuple nodes;
2532
2533 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2534 if (large_constant_pool) {
2535 // Create new nodes.
2536 loadConL_hiNode *m1 = new loadConL_hiNode();
2537 loadConL_loNode *m2 = new loadConL_loNode();
2538
2539 // inputs for new nodes
2540 m1->add_req(nullptr, toc);
2541 m2->add_req(nullptr, m1);
2542
2543 // operands for new nodes
2544 m1->_opnds[0] = new iRegLdstOper(); // dst
2545 m1->_opnds[1] = immSrc; // src
2546 m1->_opnds[2] = new iRegLdstOper(); // toc
2547 m2->_opnds[0] = new iRegLdstOper(); // dst
2548 m2->_opnds[1] = immSrc; // src
2549 m2->_opnds[2] = new iRegLdstOper(); // base
2550
2551 // Initialize ins_attrib TOC fields.
2552 m1->_const_toc_offset = -1;
2553 m2->_const_toc_offset_hi_node = m1;
2554
2555 // Initialize ins_attrib instruction offset.
2556 m1->_cbuf_insts_offset = -1;
2557
2558 // register allocation for new nodes
2559 ra_->set_pair(m1->_idx, reg_second, reg_first);
2560 ra_->set_pair(m2->_idx, reg_second, reg_first);
2561
2562 // Create result.
2563 nodes._large_hi = m1;
2564 nodes._large_lo = m2;
2565 nodes._small = nullptr;
2566 nodes._last = nodes._large_lo;
2567 assert(m2->bottom_type()->isa_long(), "must be long");
2568 } else {
2569 loadConLNode *m2 = new loadConLNode();
2570
2571 // inputs for new nodes
2572 m2->add_req(nullptr, toc);
2573
2574 // operands for new nodes
2575 m2->_opnds[0] = new iRegLdstOper(); // dst
2576 m2->_opnds[1] = immSrc; // src
2577 m2->_opnds[2] = new iRegLdstOper(); // toc
2578
2579 // Initialize ins_attrib instruction offset.
2580 m2->_cbuf_insts_offset = -1;
2581
2582 // register allocation for new nodes
2583 ra_->set_pair(m2->_idx, reg_second, reg_first);
2584
2585 // Create result.
2586 nodes._large_hi = nullptr;
2587 nodes._large_lo = nullptr;
2588 nodes._small = m2;
2589 nodes._last = nodes._small;
2590 assert(m2->bottom_type()->isa_long(), "must be long");
2591 }
2592
2593 return nodes;
2594 }
2595
2596 typedef struct {
2597 loadConL_hiNode *_large_hi;
2598 loadConL_loNode *_large_lo;
2599 mtvsrdNode *_moved;
2600 xxspltdNode *_replicated;
2601 loadConLNode *_small;
2602 MachNode *_last;
2603 } loadConLReplicatedNodesTuple;
2604
2605 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2606 vecXOper *dst, immI_0Oper *zero,
2607 OptoReg::Name reg_second, OptoReg::Name reg_first,
2608 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) {
2609 loadConLReplicatedNodesTuple nodes;
2610
2611 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2612 if (large_constant_pool) {
2613 // Create new nodes.
2614 loadConL_hiNode *m1 = new loadConL_hiNode();
2615 loadConL_loNode *m2 = new loadConL_loNode();
2616 mtvsrdNode *m3 = new mtvsrdNode();
2617 xxspltdNode *m4 = new xxspltdNode();
2618
2619 // inputs for new nodes
2620 m1->add_req(nullptr, toc);
2621 m2->add_req(nullptr, m1);
2622 m3->add_req(nullptr, m2);
2623 m4->add_req(nullptr, m3);
2624
2625 // operands for new nodes
2626 m1->_opnds[0] = new iRegLdstOper(); // dst
2627 m1->_opnds[1] = immSrc; // src
2628 m1->_opnds[2] = new iRegLdstOper(); // toc
2629
2630 m2->_opnds[0] = new iRegLdstOper(); // dst
2631 m2->_opnds[1] = immSrc; // src
2632 m2->_opnds[2] = new iRegLdstOper(); // base
2633
2634 m3->_opnds[0] = new vecXOper(); // dst
2635 m3->_opnds[1] = new iRegLdstOper(); // src
2636
2637 m4->_opnds[0] = new vecXOper(); // dst
2638 m4->_opnds[1] = new vecXOper(); // src
2639 m4->_opnds[2] = zero;
2640
2641 // Initialize ins_attrib TOC fields.
2642 m1->_const_toc_offset = -1;
2643 m2->_const_toc_offset_hi_node = m1;
2644
2645 // Initialize ins_attrib instruction offset.
2646 m1->_cbuf_insts_offset = -1;
2647
2648 // register allocation for new nodes
2649 ra_->set_pair(m1->_idx, reg_second, reg_first);
2650 ra_->set_pair(m2->_idx, reg_second, reg_first);
2651 ra_->set1(m3->_idx, reg_second);
2652 ra_->set2(m3->_idx, reg_vec_first);
2653 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2654
2655 // Create result.
2656 nodes._large_hi = m1;
2657 nodes._large_lo = m2;
2658 nodes._moved = m3;
2659 nodes._replicated = m4;
2660 nodes._small = nullptr;
2661 nodes._last = nodes._replicated;
2662 assert(m2->bottom_type()->isa_long(), "must be long");
2663 } else {
2664 loadConLNode *m2 = new loadConLNode();
2665 mtvsrdNode *m3 = new mtvsrdNode();
2666 xxspltdNode *m4 = new xxspltdNode();
2667
2668 // inputs for new nodes
2669 m2->add_req(nullptr, toc);
2670
2671 // operands for new nodes
2672 m2->_opnds[0] = new iRegLdstOper(); // dst
2673 m2->_opnds[1] = immSrc; // src
2674 m2->_opnds[2] = new iRegLdstOper(); // toc
2675
2676 m3->_opnds[0] = new vecXOper(); // dst
2677 m3->_opnds[1] = new iRegLdstOper(); // src
2678
2679 m4->_opnds[0] = new vecXOper(); // dst
2680 m4->_opnds[1] = new vecXOper(); // src
2681 m4->_opnds[2] = zero;
2682
2683 // Initialize ins_attrib instruction offset.
2684 m2->_cbuf_insts_offset = -1;
2685 ra_->set1(m3->_idx, reg_second);
2686 ra_->set2(m3->_idx, reg_vec_first);
2687 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2688
2689 // register allocation for new nodes
2690 ra_->set_pair(m2->_idx, reg_second, reg_first);
2691
2692 // Create result.
2693 nodes._large_hi = nullptr;
2694 nodes._large_lo = nullptr;
2695 nodes._small = m2;
2696 nodes._moved = m3;
2697 nodes._replicated = m4;
2698 nodes._last = nodes._replicated;
2699 assert(m2->bottom_type()->isa_long(), "must be long");
2700 }
2701
2702 return nodes;
2703 }
2704
2705 %} // source
2706
2707 encode %{
2708 // Postalloc expand emitter for loading a long constant from the method's TOC.
2709 // Enc_class needed as consttanttablebase is not supported by postalloc
2710 // expand.
2711 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2712 // Create new nodes.
2713 loadConLNodesTuple loadConLNodes =
2714 loadConLNodesTuple_create(ra_, n_toc, op_src,
2715 ra_->get_reg_second(this), ra_->get_reg_first(this));
2716
2717 // Push new nodes.
2718 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2719 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2720
2721 // some asserts
2722 assert(nodes->length() >= 1, "must have created at least 1 node");
2723 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2724 %}
2725
2726 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2727 int toc_offset = 0;
2728
2729 intptr_t val = $src$$constant;
2730 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2731 address const_toc_addr;
2732 RelocationHolder r; // Initializes type to none.
2733 if (constant_reloc == relocInfo::oop_type) {
2734 // Create an oop constant and a corresponding relocation.
2735 AddressLiteral a = __ constant_oop_address((jobject)val);
2736 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2737 r = a.rspec();
2738 } else if (constant_reloc == relocInfo::metadata_type) {
2739 // Notify OOP recorder (don't need the relocation)
2740 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2741 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2742 } else {
2743 // Create a non-oop constant, no relocation needed.
2744 const_toc_addr = __ long_constant((jlong)$src$$constant);
2745 }
2746
2747 if (const_toc_addr == nullptr) {
2748 ciEnv::current()->record_out_of_memory_failure();
2749 return;
2750 }
2751 __ relocate(r); // If set above.
2752 // Get the constant's TOC offset.
2753 toc_offset = __ offset_to_method_toc(const_toc_addr);
2754
2755 __ ld($dst$$Register, toc_offset, $toc$$Register);
2756 %}
2757
2758 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2759 if (!ra_->C->output()->in_scratch_emit_size()) {
2760 intptr_t val = $src$$constant;
2761 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2762 address const_toc_addr;
2763 RelocationHolder r; // Initializes type to none.
2764 if (constant_reloc == relocInfo::oop_type) {
2765 // Create an oop constant and a corresponding relocation.
2766 AddressLiteral a = __ constant_oop_address((jobject)val);
2767 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2768 r = a.rspec();
2769 } else if (constant_reloc == relocInfo::metadata_type) {
2770 // Notify OOP recorder (don't need the relocation)
2771 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2772 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2773 } else { // non-oop pointers, e.g. card mark base, heap top
2774 // Create a non-oop constant, no relocation needed.
2775 const_toc_addr = __ long_constant((jlong)$src$$constant);
2776 }
2777
2778 if (const_toc_addr == nullptr) {
2779 ciEnv::current()->record_out_of_memory_failure();
2780 return;
2781 }
2782 __ relocate(r); // If set above.
2783 // Get the constant's TOC offset.
2784 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2785 // Store the toc offset of the constant.
2786 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2787 }
2788
2789 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2790 %}
2791
2792 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2793 // Enc_class needed as consttanttablebase is not supported by postalloc
2794 // expand.
2795 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2796 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2797 if (large_constant_pool) {
2798 // Create new nodes.
2799 loadConP_hiNode *m1 = new loadConP_hiNode();
2800 loadConP_loNode *m2 = new loadConP_loNode();
2801
2802 // If this is an oop, both m1 and m2 must be consider oops so postalloc scheduling does not
2803 // put a safepoint between them
2804 m1->_bottom_type = bottom_type();
2805 m2->_bottom_type = bottom_type();
2806
2807 // inputs for new nodes
2808 m1->add_req(nullptr, n_toc);
2809 m2->add_req(nullptr, m1);
2810
2811 // operands for new nodes
2812 m1->_opnds[0] = new iRegPdstOper(); // dst
2813 m1->_opnds[1] = op_src; // src
2814 m1->_opnds[2] = new iRegLdstOper(); // toc
2815
2816 m2->_opnds[0] = new iRegPdstOper(); // dst
2817 m2->_opnds[1] = op_src; // src
2818 m2->_opnds[2] = new iRegLdstOper(); // base
2819
2820 // Initialize ins_attrib TOC fields.
2821 m1->_const_toc_offset = -1;
2822 m2->_const_toc_offset_hi_node = m1;
2823
2824 // Register allocation for new nodes.
2825 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2826 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2827
2828 nodes->push(m1);
2829 nodes->push(m2);
2830 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2831 } else {
2832 loadConPNode *m2 = new loadConPNode();
2833
2834 // inputs for new nodes
2835 m2->add_req(nullptr, n_toc);
2836
2837 // operands for new nodes
2838 m2->_opnds[0] = new iRegPdstOper(); // dst
2839 m2->_opnds[1] = op_src; // src
2840 m2->_opnds[2] = new iRegLdstOper(); // toc
2841
2842 // Register allocation for new nodes.
2843 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2844
2845 nodes->push(m2);
2846 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2847 }
2848 %}
2849
2850 // Enc_class needed as consttanttablebase is not supported by postalloc
2851 // expand.
2852 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2853 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2854
2855 MachNode *m2;
2856 if (large_constant_pool) {
2857 m2 = new loadConFCompNode();
2858 } else {
2859 m2 = new loadConFNode();
2860 }
2861 // inputs for new nodes
2862 m2->add_req(nullptr, n_toc);
2863
2864 // operands for new nodes
2865 m2->_opnds[0] = op_dst;
2866 m2->_opnds[1] = op_src;
2867 m2->_opnds[2] = new iRegLdstOper(); // constanttablebase
2868
2869 // register allocation for new nodes
2870 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2871 nodes->push(m2);
2872 %}
2873
2874 // Enc_class needed as consttanttablebase is not supported by postalloc
2875 // expand.
2876 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2877 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2878
2879 MachNode *m2;
2880 if (large_constant_pool) {
2881 m2 = new loadConDCompNode();
2882 } else {
2883 m2 = new loadConDNode();
2884 }
2885 // inputs for new nodes
2886 m2->add_req(nullptr, n_toc);
2887
2888 // operands for new nodes
2889 m2->_opnds[0] = op_dst;
2890 m2->_opnds[1] = op_src;
2891 m2->_opnds[2] = new iRegLdstOper(); // constanttablebase
2892
2893 // register allocation for new nodes
2894 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2895 nodes->push(m2);
2896 %}
2897
2898 enc_class enc_stw(iRegIsrc src, memory mem) %{
2899 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2900 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2901 %}
2902
2903 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2904 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2905 // Operand 'ds' requires 4-alignment.
2906 assert((Idisp & 0x3) == 0, "unaligned offset");
2907 __ std($src$$Register, Idisp, $mem$$base$$Register);
2908 %}
2909
2910 enc_class enc_stfs(RegF src, memory mem) %{
2911 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2912 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2913 %}
2914
2915 enc_class enc_stfd(RegF src, memory mem) %{
2916 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2917 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2918 %}
2919
2920 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2921 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
2922 encodeP_subNode *n_sub_base = new encodeP_subNode();
2923 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
2924 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode();
2925
2926 n_compare->add_req(n_region, n_src);
2927 n_compare->_opnds[0] = op_crx;
2928 n_compare->_opnds[1] = op_src;
2929 n_compare->_opnds[2] = new immL16Oper(0);
2930
2931 n_sub_base->add_req(n_region, n_src);
2932 n_sub_base->_opnds[0] = op_dst;
2933 n_sub_base->_opnds[1] = op_src;
2934 n_sub_base->_bottom_type = _bottom_type;
2935
2936 n_shift->add_req(n_region, n_sub_base);
2937 n_shift->_opnds[0] = op_dst;
2938 n_shift->_opnds[1] = op_dst;
2939 n_shift->_bottom_type = _bottom_type;
2940
2941 n_cond_set->add_req(n_region, n_compare, n_shift);
2942 n_cond_set->_opnds[0] = op_dst;
2943 n_cond_set->_opnds[1] = op_crx;
2944 n_cond_set->_opnds[2] = op_dst;
2945 n_cond_set->_bottom_type = _bottom_type;
2946
2947 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2948 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2949 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2950 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2951
2952 nodes->push(n_compare);
2953 nodes->push(n_sub_base);
2954 nodes->push(n_shift);
2955 nodes->push(n_cond_set);
2956
2957 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2958 %}
2959
2960 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
2961
2962 encodeP_subNode *n1 = new encodeP_subNode();
2963 n1->add_req(n_region, n_src);
2964 n1->_opnds[0] = op_dst;
2965 n1->_opnds[1] = op_src;
2966 n1->_bottom_type = _bottom_type;
2967
2968 encodeP_shiftNode *n2 = new encodeP_shiftNode();
2969 n2->add_req(n_region, n1);
2970 n2->_opnds[0] = op_dst;
2971 n2->_opnds[1] = op_dst;
2972 n2->_bottom_type = _bottom_type;
2973 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2974 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2975
2976 nodes->push(n1);
2977 nodes->push(n2);
2978 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2979 %}
2980
2981 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
2982 decodeN_shiftNode *n_shift = new decodeN_shiftNode();
2983 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
2984
2985 n_compare->add_req(n_region, n_src);
2986 n_compare->_opnds[0] = op_crx;
2987 n_compare->_opnds[1] = op_src;
2988 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
2989
2990 n_shift->add_req(n_region, n_src);
2991 n_shift->_opnds[0] = op_dst;
2992 n_shift->_opnds[1] = op_src;
2993 n_shift->_bottom_type = _bottom_type;
2994
2995 decodeN_addNode *n_add_base = new decodeN_addNode();
2996 n_add_base->add_req(n_region, n_shift);
2997 n_add_base->_opnds[0] = op_dst;
2998 n_add_base->_opnds[1] = op_dst;
2999 n_add_base->_bottom_type = _bottom_type;
3000
3001 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
3002 n_cond_set->add_req(n_region, n_compare, n_add_base);
3003 n_cond_set->_opnds[0] = op_dst;
3004 n_cond_set->_opnds[1] = op_crx;
3005 n_cond_set->_opnds[2] = op_dst;
3006 n_cond_set->_bottom_type = _bottom_type;
3007
3008 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3009 ra_->set_oop(n_cond_set, true);
3010
3011 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3012 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3013 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3014 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3015
3016 nodes->push(n_compare);
3017 nodes->push(n_shift);
3018 nodes->push(n_add_base);
3019 nodes->push(n_cond_set);
3020
3021 %}
3022
3023 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3024 decodeN_shiftNode *n1 = new decodeN_shiftNode();
3025 n1->add_req(n_region, n_src);
3026 n1->_opnds[0] = op_dst;
3027 n1->_opnds[1] = op_src;
3028 n1->_bottom_type = _bottom_type;
3029
3030 decodeN_addNode *n2 = new decodeN_addNode();
3031 n2->add_req(n_region, n1);
3032 n2->_opnds[0] = op_dst;
3033 n2->_opnds[1] = op_dst;
3034 n2->_bottom_type = _bottom_type;
3035 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3036 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3037
3038 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3039 ra_->set_oop(n2, true);
3040
3041 nodes->push(n1);
3042 nodes->push(n2);
3043 %}
3044
3045
3046 // This enc_class is needed so that scheduler gets proper
3047 // input mapping for latency computation.
3048 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
3049 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
3050 %}
3051
3052 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3053 Label done;
3054 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3055 __ li($dst$$Register, $zero$$constant);
3056 __ beq($crx$$CondRegister, done);
3057 __ li($dst$$Register, $notzero$$constant);
3058 __ bind(done);
3059 %}
3060
3061 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3062 Label done;
3063 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3064 __ li($dst$$Register, $zero$$constant);
3065 __ beq($crx$$CondRegister, done);
3066 __ li($dst$$Register, $notzero$$constant);
3067 __ bind(done);
3068 %}
3069
3070 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3071 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3072 Label done;
3073 __ bso($crx$$CondRegister, done);
3074 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3075 __ bind(done);
3076 %}
3077
3078 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
3079 Label done;
3080 __ bso($crx$$CondRegister, done);
3081 __ mffprd($dst$$Register, $src$$FloatRegister);
3082 __ bind(done);
3083 %}
3084
3085 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3086 Label d; // dummy
3087 __ bind(d);
3088 Label* p = ($lbl$$label);
3089 // `p' is `nullptr' when this encoding class is used only to
3090 // determine the size of the encoded instruction.
3091 Label& l = (nullptr == p)? d : *(p);
3092 int cc = $cmp$$cmpcode;
3093 int flags_reg = $crx$$reg;
3094 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3095 int bhint = Assembler::bhintNoHint;
3096
3097 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3098 if (_prob <= PROB_NEVER) {
3099 bhint = Assembler::bhintIsNotTaken;
3100 } else if (_prob >= PROB_ALWAYS) {
3101 bhint = Assembler::bhintIsTaken;
3102 }
3103 }
3104
3105 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3106 cc_to_biint(cc, flags_reg),
3107 l);
3108 %}
3109
3110 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3111 // The scheduler doesn't know about branch shortening, so we set the opcode
3112 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3113 Label d; // dummy
3114 __ bind(d);
3115 Label* p = ($lbl$$label);
3116 // `p' is `nullptr' when this encoding class is used only to
3117 // determine the size of the encoded instruction.
3118 Label& l = (nullptr == p)? d : *(p);
3119 int cc = $cmp$$cmpcode;
3120 int flags_reg = $crx$$reg;
3121 int bhint = Assembler::bhintNoHint;
3122
3123 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3124 if (_prob <= PROB_NEVER) {
3125 bhint = Assembler::bhintIsNotTaken;
3126 } else if (_prob >= PROB_ALWAYS) {
3127 bhint = Assembler::bhintIsTaken;
3128 }
3129 }
3130
3131 // Tell the conditional far branch to optimize itself when being relocated.
3132 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3133 cc_to_biint(cc, flags_reg),
3134 l,
3135 MacroAssembler::bc_far_optimize_on_relocate);
3136 %}
3137
3138 // Postalloc expand emitter for loading a replicatef float constant from
3139 // the method's TOC.
3140 // Enc_class needed as consttanttablebase is not supported by postalloc
3141 // expand.
3142 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3143 // Create new nodes.
3144
3145 // Make an operand with the bit pattern to load as float.
3146 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3147
3148 loadConLNodesTuple loadConLNodes =
3149 loadConLNodesTuple_create(ra_, n_toc, op_repl,
3150 ra_->get_reg_second(this), ra_->get_reg_first(this));
3151
3152 // Push new nodes.
3153 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3154 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3155
3156 assert(nodes->length() >= 1, "must have created at least 1 node");
3157 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3158 %}
3159
3160 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{
3161 // Create new nodes.
3162
3163 // Make an operand with the bit pattern to load as float.
3164 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3165 immI_0Oper *op_zero = new immI_0Oper(0);
3166
3167 loadConLReplicatedNodesTuple loadConLNodes =
3168 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero,
3169 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp),
3170 ra_->get_reg_second(this), ra_->get_reg_first(this));
3171
3172 // Push new nodes.
3173 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); }
3174 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); }
3175 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); }
3176 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); }
3177
3178 assert(nodes->length() >= 1, "must have created at least 1 node");
3179 %}
3180
3181 // This enc_class is needed so that scheduler gets proper
3182 // input mapping for latency computation.
3183 enc_class enc_poll(immI dst, iRegLdst poll) %{
3184 // Fake operand dst needed for PPC scheduler.
3185 assert($dst$$constant == 0x0, "dst must be 0x0");
3186
3187 // Mark the code position where the load from the safepoint
3188 // polling page was emitted as relocInfo::poll_type.
3189 __ relocate(relocInfo::poll_type);
3190 __ load_from_polling_page($poll$$Register);
3191 %}
3192
3193 // A Java static call or a runtime call.
3194 //
3195 // Branch-and-link relative to a trampoline.
3196 // The trampoline loads the target address and does a long branch to there.
3197 // In case we call java, the trampoline branches to a interpreter_stub
3198 // which loads the inline cache and the real call target from the constant pool.
3199 //
3200 // This basically looks like this:
3201 //
3202 // >>>> consts -+ -+
3203 // | |- offset1
3204 // [call target1] | <-+
3205 // [IC cache] |- offset2
3206 // [call target2] <--+
3207 //
3208 // <<<< consts
3209 // >>>> insts
3210 //
3211 // bl offset16 -+ -+ ??? // How many bits available?
3212 // | |
3213 // <<<< insts | |
3214 // >>>> stubs | |
3215 // | |- trampoline_stub_Reloc
3216 // trampoline stub: | <-+
3217 // r2 = toc |
3218 // r2 = [r2 + offset1] | // Load call target1 from const section
3219 // mtctr r2 |
3220 // bctr |- static_stub_Reloc
3221 // comp_to_interp_stub: <---+
3222 // r1 = toc
3223 // ICreg = [r1 + IC_offset] // Load IC from const section
3224 // r1 = [r1 + offset2] // Load call target2 from const section
3225 // mtctr r1
3226 // bctr
3227 //
3228 // <<<< stubs
3229 //
3230 // The call instruction in the code either
3231 // - Branches directly to a compiled method if the offset is encodable in instruction.
3232 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3233 // - Branches to the compiled_to_interp stub if the target is interpreted.
3234 //
3235 // Further there are three relocations from the loads to the constants in
3236 // the constant section.
3237 //
3238 // Usage of r1 and r2 in the stubs allows to distinguish them.
3239 enc_class enc_java_static_call(method meth) %{
3240 address entry_point = (address)$meth$$method;
3241 address call_pc;
3242
3243 if (!_method) {
3244 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3245 call_pc = __ trampoline_call(AddressLiteral(entry_point, relocInfo::runtime_call_type));
3246 if (call_pc == nullptr) {
3247 ciEnv::current()->record_failure("CodeCache is full");
3248 return;
3249 }
3250 } else {
3251 int method_index = resolved_method_index(masm);
3252 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3253 : static_call_Relocation::spec(method_index);
3254 call_pc = __ trampoline_call(AddressLiteral(entry_point, rspec));
3255 if (call_pc == nullptr) {
3256 ciEnv::current()->record_failure("CodeCache is full");
3257 return;
3258 }
3259
3260 // Emit stub for static call
3261 address stub = CompiledDirectCall::emit_to_interp_stub(masm, call_pc);
3262 if (stub == nullptr) {
3263 ciEnv::current()->record_failure("CodeCache is full");
3264 return;
3265 }
3266 }
3267 __ post_call_nop();
3268 %}
3269
3270 // Compound version of call dynamic
3271 // Toc is only passed so that it can be used in ins_encode statement.
3272 // In the code we have to use $constanttablebase.
3273 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
3274 int start_offset = __ offset();
3275 int method_index = resolved_method_index(masm);
3276 bool scratch_emit = ra_ == nullptr;
3277 Register Rtoc = scratch_emit ? R2_TOC : $constanttablebase;
3278 bool success = __ ic_call(Rtoc, (address)$meth$$method, method_index, scratch_emit, true /*fixed_size*/);
3279 if (!success) {
3280 ciEnv::current()->record_failure("CodeCache is full");
3281 return;
3282 }
3283 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3284 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3285 __ post_call_nop();
3286 %}
3287
3288 // a runtime call
3289 enc_class enc_java_to_runtime_call (method meth) %{
3290 const address start_pc = __ pc();
3291
3292 #if defined(ABI_ELFv2)
3293 address entry= !($meth$$method) ? nullptr : (address)$meth$$method;
3294 __ call_c(entry, relocInfo::runtime_call_type);
3295 __ post_call_nop();
3296 #else
3297 // The function we're going to call.
3298 FunctionDescriptor fdtemp;
3299 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3300
3301 Register Rtoc = R12_scratch2;
3302 // Calculate the method's TOC.
3303 __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3304 // Put entry, env, toc into the constant pool, this needs up to 3 constant
3305 // pool entries; call_c_using_toc will optimize the call.
3306 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3307 if (!success) {
3308 ciEnv::current()->record_out_of_memory_failure();
3309 return;
3310 }
3311 __ post_call_nop();
3312 #endif
3313
3314 // Check the ret_addr_offset.
3315 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3316 "Fix constant in ret_addr_offset()");
3317 %}
3318
3319 // Move to ctr for leaf call.
3320 // This enc_class is needed so that scheduler gets proper
3321 // input mapping for latency computation.
3322 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3323 __ mtctr($src$$Register);
3324 %}
3325
3326 // Postalloc expand emitter for runtime leaf calls.
3327 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3328 loadConLNodesTuple loadConLNodes_Entry;
3329 #if defined(ABI_ELFv2)
3330 jlong entry_address = (jlong) this->entry_point();
3331 assert(entry_address, "need address here");
3332 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3333 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3334 #else
3335 // Get the struct that describes the function we are about to call.
3336 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3337 assert(fd, "need fd here");
3338 jlong entry_address = (jlong) fd->entry();
3339 // new nodes
3340 loadConLNodesTuple loadConLNodes_Env;
3341 loadConLNodesTuple loadConLNodes_Toc;
3342
3343 // Create nodes and operands for loading the entry point.
3344 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3345 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3346
3347
3348 // Create nodes and operands for loading the env pointer.
3349 if (fd->env() != nullptr) {
3350 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3351 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3352 } else {
3353 loadConLNodes_Env._large_hi = nullptr;
3354 loadConLNodes_Env._large_lo = nullptr;
3355 loadConLNodes_Env._small = nullptr;
3356 loadConLNodes_Env._last = new loadConL16Node();
3357 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3358 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3359 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3360 }
3361
3362 // Create nodes and operands for loading the Toc point.
3363 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3364 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3365 #endif // ABI_ELFv2
3366 // mtctr node
3367 MachNode *mtctr = new CallLeafDirect_mtctrNode();
3368
3369 assert(loadConLNodes_Entry._last != nullptr, "entry must exist");
3370 mtctr->add_req(nullptr, loadConLNodes_Entry._last);
3371
3372 mtctr->_opnds[0] = new iRegLdstOper();
3373 mtctr->_opnds[1] = new iRegLdstOper();
3374
3375 // call node
3376 MachCallLeafNode *call = new CallLeafDirectNode();
3377
3378 call->_opnds[0] = _opnds[0];
3379 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3380
3381 // Make the new call node look like the old one.
3382 call->_name = _name;
3383 call->_tf = _tf;
3384 call->_entry_point = _entry_point;
3385 call->_cnt = _cnt;
3386 call->_guaranteed_safepoint = false;
3387 call->_oop_map = _oop_map;
3388 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3389 call->_jvms = nullptr;
3390 call->_jvmadj = _jvmadj;
3391 call->_in_rms = _in_rms;
3392 call->_nesting = _nesting;
3393
3394 // New call needs all inputs of old call.
3395 // Req...
3396 for (uint i = 0; i < req(); ++i) {
3397 if (i != mach_constant_base_node_input()) {
3398 call->add_req(in(i));
3399 }
3400 }
3401
3402 // These must be reqired edges, as the registers are live up to
3403 // the call. Else the constants are handled as kills.
3404 call->add_req(mtctr);
3405 #if !defined(ABI_ELFv2)
3406 call->add_req(loadConLNodes_Env._last);
3407 call->add_req(loadConLNodes_Toc._last);
3408 #endif
3409
3410 // ...as well as prec
3411 for (uint i = req(); i < len(); ++i) {
3412 call->add_prec(in(i));
3413 }
3414
3415 // registers
3416 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3417
3418 // Insert the new nodes.
3419 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3420 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last);
3421 #if !defined(ABI_ELFv2)
3422 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi);
3423 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last);
3424 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi);
3425 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last);
3426 #endif
3427 nodes->push(mtctr);
3428 nodes->push(call);
3429 %}
3430 %}
3431
3432 //----------FRAME--------------------------------------------------------------
3433 // Definition of frame structure and management information.
3434
3435 frame %{
3436 // These two registers define part of the calling convention between
3437 // compiled code and the interpreter.
3438
3439 // Inline Cache Register or method for I2C.
3440 inline_cache_reg(R19); // R19_method
3441
3442 // Optional: name the operand used by cisc-spilling to access
3443 // [stack_pointer + offset].
3444 cisc_spilling_operand_name(indOffset);
3445
3446 // Number of stack slots consumed by a Monitor enter.
3447 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size));
3448
3449 // Compiled code's Frame Pointer.
3450 frame_pointer(R1); // R1_SP
3451
3452 stack_alignment(frame::alignment_in_bytes);
3453
3454 // Number of outgoing stack slots killed above the
3455 // out_preserve_stack_slots for calls to C. Supports the var-args
3456 // backing area for register parms.
3457 //
3458 varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3459
3460 // The after-PROLOG location of the return address. Location of
3461 // return address specifies a type (REG or STACK) and a number
3462 // representing the register number (i.e. - use a register name) or
3463 // stack slot.
3464 //
3465 // A: Link register is stored in stack slot ...
3466 // M: ... but it's in the caller's frame according to PPC-64 ABI.
3467 // J: Therefore, we make sure that the link register is also in R11_scratch1
3468 // at the end of the prolog.
3469 // B: We use R20, now.
3470 //return_addr(REG R20);
3471
3472 // G: After reading the comments made by all the luminaries on their
3473 // failure to tell the compiler where the return address really is,
3474 // I hardly dare to try myself. However, I'm convinced it's in slot
3475 // 4 what apparently works and saves us some spills.
3476 return_addr(STACK 4);
3477
3478 // Location of native (C/C++) and interpreter return values. This
3479 // is specified to be the same as Java. In the 32-bit VM, long
3480 // values are actually returned from native calls in O0:O1 and
3481 // returned to the interpreter in I0:I1. The copying to and from
3482 // the register pairs is done by the appropriate call and epilog
3483 // opcodes. This simplifies the register allocator.
3484 c_return_value %{
3485 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3486 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3487 "only return normal values");
3488 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3489 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3490 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3491 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3492 %}
3493
3494 // Location of compiled Java return values. Same as C
3495 return_value %{
3496 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3497 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3498 "only return normal values");
3499 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3500 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3501 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3502 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3503 %}
3504 %}
3505
3506
3507 //----------ATTRIBUTES---------------------------------------------------------
3508
3509 //----------Operand Attributes-------------------------------------------------
3510 op_attrib op_cost(1); // Required cost attribute.
3511
3512 //----------Instruction Attributes---------------------------------------------
3513
3514 // Cost attribute. required.
3515 ins_attrib ins_cost(DEFAULT_COST);
3516
3517 // Is this instruction a non-matching short branch variant of some
3518 // long branch? Not required.
3519 ins_attrib ins_short_branch(0);
3520
3521 ins_attrib ins_is_TrapBasedCheckNode(true);
3522
3523 // Number of constants.
3524 // This instruction uses the given number of constants
3525 // (optional attribute).
3526 // This is needed to determine in time whether the constant pool will
3527 // exceed 4000 entries. Before postalloc_expand the overall number of constants
3528 // is determined. It's also used to compute the constant pool size
3529 // in Output().
3530 ins_attrib ins_num_consts(0);
3531
3532 // Required alignment attribute (must be a power of 2) specifies the
3533 // alignment that some part of the instruction (not necessarily the
3534 // start) requires. If > 1, a compute_padding() function must be
3535 // provided for the instruction.
3536 ins_attrib ins_alignment(1);
3537
3538 // Enforce/prohibit rematerializations.
3539 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3540 // then rematerialization of that instruction is prohibited and the
3541 // instruction's value will be spilled if necessary.
3542 // Causes that MachNode::rematerialize() returns false.
3543 // - If an instruction is attributed with 'ins_should_rematerialize(true)'
3544 // then rematerialization should be enforced and a copy of the instruction
3545 // should be inserted if possible; rematerialization is not guaranteed.
3546 // Note: this may result in rematerializations in front of every use.
3547 // Causes that MachNode::rematerialize() can return true.
3548 // (optional attribute)
3549 ins_attrib ins_cannot_rematerialize(false);
3550 ins_attrib ins_should_rematerialize(false);
3551
3552 // Instruction has variable size depending on alignment.
3553 ins_attrib ins_variable_size_depending_on_alignment(false);
3554
3555 // Instruction is a nop.
3556 ins_attrib ins_is_nop(false);
3557
3558 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock).
3559 ins_attrib ins_use_mach_if_fast_lock_node(false);
3560
3561 // Field for the toc offset of a constant.
3562 //
3563 // This is needed if the toc offset is not encodable as an immediate in
3564 // the PPC load instruction. If so, the upper (hi) bits of the offset are
3565 // added to the toc, and from this a load with immediate is performed.
3566 // With postalloc expand, we get two nodes that require the same offset
3567 // but which don't know about each other. The offset is only known
3568 // when the constant is added to the constant pool during emitting.
3569 // It is generated in the 'hi'-node adding the upper bits, and saved
3570 // in this node. The 'lo'-node has a link to the 'hi'-node and reads
3571 // the offset from there when it gets encoded.
3572 ins_attrib ins_field_const_toc_offset(0);
3573 ins_attrib ins_field_const_toc_offset_hi_node(0);
3574
3575 // A field that can hold the instructions offset in the code buffer.
3576 // Set in the nodes emitter.
3577 ins_attrib ins_field_cbuf_insts_offset(-1);
3578
3579 // Fields for referencing a call's load-IC-node.
3580 // If the toc offset can not be encoded as an immediate in a load, we
3581 // use two nodes.
3582 ins_attrib ins_field_load_ic_hi_node(0);
3583 ins_attrib ins_field_load_ic_node(0);
3584
3585 // Whether this node is expanded during code emission into a sequence of
3586 // instructions and the first instruction can perform an implicit null check.
3587 ins_attrib ins_is_late_expanded_null_check_candidate(false);
3588
3589 //----------OPERANDS-----------------------------------------------------------
3590 // Operand definitions must precede instruction definitions for correct
3591 // parsing in the ADLC because operands constitute user defined types
3592 // which are used in instruction definitions.
3593 //
3594 // Formats are generated automatically for constants and base registers.
3595
3596 operand vecX() %{
3597 constraint(ALLOC_IN_RC(v_reg));
3598 match(VecX);
3599
3600 format %{ %}
3601 interface(REG_INTER);
3602 %}
3603
3604 //----------Simple Operands----------------------------------------------------
3605 // Immediate Operands
3606
3607 // Integer Immediate: 32-bit
3608 operand immI() %{
3609 match(ConI);
3610 op_cost(40);
3611 format %{ %}
3612 interface(CONST_INTER);
3613 %}
3614
3615 operand immI8() %{
3616 predicate(Assembler::is_simm(n->get_int(), 8));
3617 op_cost(0);
3618 match(ConI);
3619 format %{ %}
3620 interface(CONST_INTER);
3621 %}
3622
3623 // Integer Immediate: 16-bit
3624 operand immI16() %{
3625 predicate(Assembler::is_simm(n->get_int(), 16));
3626 op_cost(0);
3627 match(ConI);
3628 format %{ %}
3629 interface(CONST_INTER);
3630 %}
3631
3632 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000.
3633 operand immIhi16() %{
3634 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0));
3635 match(ConI);
3636 op_cost(0);
3637 format %{ %}
3638 interface(CONST_INTER);
3639 %}
3640
3641 // Integer Immediate: 32-bit immediate for prefixed addi and load/store.
3642 operand immI32() %{
3643 predicate(PowerArchitecturePPC64 >= 10);
3644 op_cost(0);
3645 match(ConI);
3646 format %{ %}
3647 interface(CONST_INTER);
3648 %}
3649
3650 operand immInegpow2() %{
3651 predicate(is_power_of_2(-(juint)(n->get_int())));
3652 match(ConI);
3653 op_cost(0);
3654 format %{ %}
3655 interface(CONST_INTER);
3656 %}
3657
3658 operand immIpow2minus1() %{
3659 predicate(is_power_of_2((juint)(n->get_int()) + 1u));
3660 match(ConI);
3661 op_cost(0);
3662 format %{ %}
3663 interface(CONST_INTER);
3664 %}
3665
3666 operand immIpowerOf2() %{
3667 predicate(is_power_of_2((juint)(n->get_int())));
3668 match(ConI);
3669 op_cost(0);
3670 format %{ %}
3671 interface(CONST_INTER);
3672 %}
3673
3674 // Unsigned Integer Immediate: the values 0-31
3675 operand uimmI5() %{
3676 predicate(Assembler::is_uimm(n->get_int(), 5));
3677 match(ConI);
3678 op_cost(0);
3679 format %{ %}
3680 interface(CONST_INTER);
3681 %}
3682
3683 // Unsigned Integer Immediate: 6-bit
3684 operand uimmI6() %{
3685 predicate(Assembler::is_uimm(n->get_int(), 6));
3686 match(ConI);
3687 op_cost(0);
3688 format %{ %}
3689 interface(CONST_INTER);
3690 %}
3691
3692 // Unsigned Integer Immediate: 6-bit int, greater than 32
3693 operand uimmI6_ge32() %{
3694 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32);
3695 match(ConI);
3696 op_cost(0);
3697 format %{ %}
3698 interface(CONST_INTER);
3699 %}
3700
3701 // Unsigned Integer Immediate: 15-bit
3702 operand uimmI15() %{
3703 predicate(Assembler::is_uimm(n->get_int(), 15));
3704 match(ConI);
3705 op_cost(0);
3706 format %{ %}
3707 interface(CONST_INTER);
3708 %}
3709
3710 // Unsigned Integer Immediate: 16-bit
3711 operand uimmI16() %{
3712 predicate(Assembler::is_uimm(n->get_int(), 16));
3713 match(ConI);
3714 op_cost(0);
3715 format %{ %}
3716 interface(CONST_INTER);
3717 %}
3718
3719 // constant 'int 0'.
3720 operand immI_0() %{
3721 predicate(n->get_int() == 0);
3722 match(ConI);
3723 op_cost(0);
3724 format %{ %}
3725 interface(CONST_INTER);
3726 %}
3727
3728 // constant 'int 1'.
3729 operand immI_1() %{
3730 predicate(n->get_int() == 1);
3731 match(ConI);
3732 op_cost(0);
3733 format %{ %}
3734 interface(CONST_INTER);
3735 %}
3736
3737 // constant 'int -1'.
3738 operand immI_minus1() %{
3739 predicate(n->get_int() == -1);
3740 match(ConI);
3741 op_cost(0);
3742 format %{ %}
3743 interface(CONST_INTER);
3744 %}
3745
3746 // int value 16.
3747 operand immI_16() %{
3748 predicate(n->get_int() == 16);
3749 match(ConI);
3750 op_cost(0);
3751 format %{ %}
3752 interface(CONST_INTER);
3753 %}
3754
3755 // int value 24.
3756 operand immI_24() %{
3757 predicate(n->get_int() == 24);
3758 match(ConI);
3759 op_cost(0);
3760 format %{ %}
3761 interface(CONST_INTER);
3762 %}
3763
3764 // Compressed oops constants
3765 // Pointer Immediate
3766 operand immN() %{
3767 match(ConN);
3768
3769 op_cost(10);
3770 format %{ %}
3771 interface(CONST_INTER);
3772 %}
3773
3774 // nullptr Pointer Immediate
3775 operand immN_0() %{
3776 predicate(n->get_narrowcon() == 0);
3777 match(ConN);
3778
3779 op_cost(0);
3780 format %{ %}
3781 interface(CONST_INTER);
3782 %}
3783
3784 // Compressed klass constants
3785 operand immNKlass() %{
3786 match(ConNKlass);
3787
3788 op_cost(0);
3789 format %{ %}
3790 interface(CONST_INTER);
3791 %}
3792
3793 // This operand can be used to avoid matching of an instruct
3794 // with chain rule.
3795 operand immNKlass_NM() %{
3796 match(ConNKlass);
3797 predicate(false);
3798 op_cost(0);
3799 format %{ %}
3800 interface(CONST_INTER);
3801 %}
3802
3803 // Pointer Immediate: 64-bit
3804 operand immP() %{
3805 match(ConP);
3806 op_cost(0);
3807 format %{ %}
3808 interface(CONST_INTER);
3809 %}
3810
3811 // Operand to avoid match of loadConP.
3812 // This operand can be used to avoid matching of an instruct
3813 // with chain rule.
3814 operand immP_NM() %{
3815 match(ConP);
3816 predicate(false);
3817 op_cost(0);
3818 format %{ %}
3819 interface(CONST_INTER);
3820 %}
3821
3822 // constant 'pointer 0'.
3823 operand immP_0() %{
3824 predicate(n->get_ptr() == 0);
3825 match(ConP);
3826 op_cost(0);
3827 format %{ %}
3828 interface(CONST_INTER);
3829 %}
3830
3831 // pointer 0x0 or 0x1
3832 operand immP_0or1() %{
3833 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
3834 match(ConP);
3835 op_cost(0);
3836 format %{ %}
3837 interface(CONST_INTER);
3838 %}
3839
3840 operand immL() %{
3841 match(ConL);
3842 op_cost(40);
3843 format %{ %}
3844 interface(CONST_INTER);
3845 %}
3846
3847 operand immLmax30() %{
3848 predicate((n->get_long() <= 30));
3849 match(ConL);
3850 op_cost(0);
3851 format %{ %}
3852 interface(CONST_INTER);
3853 %}
3854
3855 // Long Immediate: 16-bit
3856 operand immL16() %{
3857 predicate(Assembler::is_simm(n->get_long(), 16));
3858 match(ConL);
3859 op_cost(0);
3860 format %{ %}
3861 interface(CONST_INTER);
3862 %}
3863
3864 // Long Immediate: 16-bit, 4-aligned
3865 operand immL16Alg4() %{
3866 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
3867 match(ConL);
3868 op_cost(0);
3869 format %{ %}
3870 interface(CONST_INTER);
3871 %}
3872
3873 // Long Immediate: 16-bit, 16-aligned
3874 operand immL16Alg16() %{
3875 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0xf) == 0));
3876 match(ConL);
3877 op_cost(0);
3878 format %{ %}
3879 interface(CONST_INTER);
3880 %}
3881
3882 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
3883 operand immL32hi16() %{
3884 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L));
3885 match(ConL);
3886 op_cost(0);
3887 format %{ %}
3888 interface(CONST_INTER);
3889 %}
3890
3891 // Long Immediate: 32-bit
3892 operand immL32() %{
3893 predicate(Assembler::is_simm(n->get_long(), 32));
3894 match(ConL);
3895 op_cost(0);
3896 format %{ %}
3897 interface(CONST_INTER);
3898 %}
3899
3900 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store.
3901 operand immL34() %{
3902 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34));
3903 match(ConL);
3904 op_cost(0);
3905 format %{ %}
3906 interface(CONST_INTER);
3907 %}
3908
3909 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000.
3910 operand immLhighest16() %{
3911 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L);
3912 match(ConL);
3913 op_cost(0);
3914 format %{ %}
3915 interface(CONST_INTER);
3916 %}
3917
3918 operand immLnegpow2() %{
3919 predicate(is_power_of_2(-(julong)(n->get_long())));
3920 match(ConL);
3921 op_cost(0);
3922 format %{ %}
3923 interface(CONST_INTER);
3924 %}
3925
3926 operand immLpow2minus1() %{
3927 predicate(is_power_of_2((julong)(n->get_long()) + 1ull));
3928 match(ConL);
3929 op_cost(0);
3930 format %{ %}
3931 interface(CONST_INTER);
3932 %}
3933
3934 // constant 'long 0'.
3935 operand immL_0() %{
3936 predicate(n->get_long() == 0L);
3937 match(ConL);
3938 op_cost(0);
3939 format %{ %}
3940 interface(CONST_INTER);
3941 %}
3942
3943 // constat ' long -1'.
3944 operand immL_minus1() %{
3945 predicate(n->get_long() == -1L);
3946 match(ConL);
3947 op_cost(0);
3948 format %{ %}
3949 interface(CONST_INTER);
3950 %}
3951
3952 // Long Immediate: low 32-bit mask
3953 operand immL_32bits() %{
3954 predicate(n->get_long() == 0xFFFFFFFFL);
3955 match(ConL);
3956 op_cost(0);
3957 format %{ %}
3958 interface(CONST_INTER);
3959 %}
3960
3961 // Unsigned Long Immediate: 16-bit
3962 operand uimmL16() %{
3963 predicate(Assembler::is_uimm(n->get_long(), 16));
3964 match(ConL);
3965 op_cost(0);
3966 format %{ %}
3967 interface(CONST_INTER);
3968 %}
3969
3970 // Float Immediate
3971 operand immF() %{
3972 match(ConF);
3973 op_cost(40);
3974 format %{ %}
3975 interface(CONST_INTER);
3976 %}
3977
3978 // Float Immediate: +0.0f.
3979 operand immF_0() %{
3980 predicate(jint_cast(n->getf()) == 0);
3981 match(ConF);
3982
3983 op_cost(0);
3984 format %{ %}
3985 interface(CONST_INTER);
3986 %}
3987
3988 // Double Immediate
3989 operand immD() %{
3990 match(ConD);
3991 op_cost(40);
3992 format %{ %}
3993 interface(CONST_INTER);
3994 %}
3995
3996 // Double Immediate: +0.0d.
3997 operand immD_0() %{
3998 predicate(jlong_cast(n->getd()) == 0);
3999 match(ConD);
4000
4001 op_cost(0);
4002 format %{ %}
4003 interface(CONST_INTER);
4004 %}
4005
4006 // Integer Register Operands
4007 // Integer Destination Register
4008 // See definition of reg_class bits32_reg_rw.
4009 operand iRegIdst() %{
4010 constraint(ALLOC_IN_RC(bits32_reg_rw));
4011 match(RegI);
4012 match(rscratch1RegI);
4013 match(rscratch2RegI);
4014 match(rarg1RegI);
4015 match(rarg2RegI);
4016 match(rarg3RegI);
4017 match(rarg4RegI);
4018 format %{ %}
4019 interface(REG_INTER);
4020 %}
4021
4022 // Integer Source Register
4023 // See definition of reg_class bits32_reg_ro.
4024 operand iRegIsrc() %{
4025 constraint(ALLOC_IN_RC(bits32_reg_ro));
4026 match(RegI);
4027 match(rscratch1RegI);
4028 match(rscratch2RegI);
4029 match(rarg1RegI);
4030 match(rarg2RegI);
4031 match(rarg3RegI);
4032 match(rarg4RegI);
4033 format %{ %}
4034 interface(REG_INTER);
4035 %}
4036
4037 operand rscratch1RegI() %{
4038 constraint(ALLOC_IN_RC(rscratch1_bits32_reg));
4039 match(iRegIdst);
4040 format %{ %}
4041 interface(REG_INTER);
4042 %}
4043
4044 operand rscratch2RegI() %{
4045 constraint(ALLOC_IN_RC(rscratch2_bits32_reg));
4046 match(iRegIdst);
4047 format %{ %}
4048 interface(REG_INTER);
4049 %}
4050
4051 operand rarg1RegI() %{
4052 constraint(ALLOC_IN_RC(rarg1_bits32_reg));
4053 match(iRegIdst);
4054 format %{ %}
4055 interface(REG_INTER);
4056 %}
4057
4058 operand rarg2RegI() %{
4059 constraint(ALLOC_IN_RC(rarg2_bits32_reg));
4060 match(iRegIdst);
4061 format %{ %}
4062 interface(REG_INTER);
4063 %}
4064
4065 operand rarg3RegI() %{
4066 constraint(ALLOC_IN_RC(rarg3_bits32_reg));
4067 match(iRegIdst);
4068 format %{ %}
4069 interface(REG_INTER);
4070 %}
4071
4072 operand rarg4RegI() %{
4073 constraint(ALLOC_IN_RC(rarg4_bits32_reg));
4074 match(iRegIdst);
4075 format %{ %}
4076 interface(REG_INTER);
4077 %}
4078
4079 operand rarg1RegL() %{
4080 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4081 match(iRegLdst);
4082 format %{ %}
4083 interface(REG_INTER);
4084 %}
4085
4086 // Pointer Destination Register
4087 // See definition of reg_class bits64_reg_rw.
4088 operand iRegPdst() %{
4089 constraint(ALLOC_IN_RC(bits64_reg_rw));
4090 match(RegP);
4091 match(rscratch1RegP);
4092 match(rscratch2RegP);
4093 match(rarg1RegP);
4094 match(rarg2RegP);
4095 match(rarg3RegP);
4096 match(rarg4RegP);
4097 format %{ %}
4098 interface(REG_INTER);
4099 %}
4100
4101 // Pointer Destination Register
4102 // Operand not using r11 and r12 (killed in epilog).
4103 operand iRegPdstNoScratch() %{
4104 constraint(ALLOC_IN_RC(bits64_reg_leaf_call));
4105 match(RegP);
4106 match(rarg1RegP);
4107 match(rarg2RegP);
4108 match(rarg3RegP);
4109 match(rarg4RegP);
4110 format %{ %}
4111 interface(REG_INTER);
4112 %}
4113
4114 // Pointer Source Register
4115 // See definition of reg_class bits64_reg_ro.
4116 operand iRegPsrc() %{
4117 constraint(ALLOC_IN_RC(bits64_reg_ro));
4118 match(RegP);
4119 match(iRegPdst);
4120 match(rscratch1RegP);
4121 match(rscratch2RegP);
4122 match(rarg1RegP);
4123 match(rarg2RegP);
4124 match(rarg3RegP);
4125 match(rarg4RegP);
4126 match(rarg5RegP);
4127 match(rarg6RegP);
4128 match(threadRegP);
4129 format %{ %}
4130 interface(REG_INTER);
4131 %}
4132
4133 // Thread operand.
4134 operand threadRegP() %{
4135 constraint(ALLOC_IN_RC(thread_bits64_reg));
4136 match(iRegPdst);
4137 format %{ "R16" %}
4138 interface(REG_INTER);
4139 %}
4140
4141 operand rscratch1RegP() %{
4142 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4143 match(iRegPdst);
4144 format %{ "R11" %}
4145 interface(REG_INTER);
4146 %}
4147
4148 operand rscratch2RegP() %{
4149 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4150 match(iRegPdst);
4151 format %{ %}
4152 interface(REG_INTER);
4153 %}
4154
4155 operand rarg1RegP() %{
4156 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4157 match(iRegPdst);
4158 format %{ %}
4159 interface(REG_INTER);
4160 %}
4161
4162 operand rarg2RegP() %{
4163 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4164 match(iRegPdst);
4165 format %{ %}
4166 interface(REG_INTER);
4167 %}
4168
4169 operand rarg3RegP() %{
4170 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4171 match(iRegPdst);
4172 format %{ %}
4173 interface(REG_INTER);
4174 %}
4175
4176 operand rarg4RegP() %{
4177 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4178 match(iRegPdst);
4179 format %{ %}
4180 interface(REG_INTER);
4181 %}
4182
4183 operand rarg5RegP() %{
4184 constraint(ALLOC_IN_RC(rarg5_bits64_reg));
4185 match(iRegPdst);
4186 format %{ %}
4187 interface(REG_INTER);
4188 %}
4189
4190 operand rarg6RegP() %{
4191 constraint(ALLOC_IN_RC(rarg6_bits64_reg));
4192 match(iRegPdst);
4193 format %{ %}
4194 interface(REG_INTER);
4195 %}
4196
4197 operand iRegNsrc() %{
4198 constraint(ALLOC_IN_RC(bits32_reg_ro));
4199 match(RegN);
4200 match(iRegNdst);
4201
4202 format %{ %}
4203 interface(REG_INTER);
4204 %}
4205
4206 operand iRegNdst() %{
4207 constraint(ALLOC_IN_RC(bits32_reg_rw));
4208 match(RegN);
4209
4210 format %{ %}
4211 interface(REG_INTER);
4212 %}
4213
4214 // Long Destination Register
4215 // See definition of reg_class bits64_reg_rw.
4216 operand iRegLdst() %{
4217 constraint(ALLOC_IN_RC(bits64_reg_rw));
4218 match(RegL);
4219 match(rscratch1RegL);
4220 match(rscratch2RegL);
4221 format %{ %}
4222 interface(REG_INTER);
4223 %}
4224
4225 // Long Source Register
4226 // See definition of reg_class bits64_reg_ro.
4227 operand iRegLsrc() %{
4228 constraint(ALLOC_IN_RC(bits64_reg_ro));
4229 match(RegL);
4230 match(iRegLdst);
4231 match(rscratch1RegL);
4232 match(rscratch2RegL);
4233 format %{ %}
4234 interface(REG_INTER);
4235 %}
4236
4237 // Special operand for ConvL2I.
4238 operand iRegL2Isrc(iRegLsrc reg) %{
4239 constraint(ALLOC_IN_RC(bits64_reg_ro));
4240 match(ConvL2I reg);
4241 format %{ "ConvL2I($reg)" %}
4242 interface(REG_INTER)
4243 %}
4244
4245 operand rscratch1RegL() %{
4246 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4247 match(RegL);
4248 format %{ %}
4249 interface(REG_INTER);
4250 %}
4251
4252 operand rscratch2RegL() %{
4253 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4254 match(RegL);
4255 format %{ %}
4256 interface(REG_INTER);
4257 %}
4258
4259 // Condition Code Flag Registers
4260 operand flagsReg() %{
4261 constraint(ALLOC_IN_RC(int_flags));
4262 match(RegFlags);
4263 format %{ %}
4264 interface(REG_INTER);
4265 %}
4266
4267 operand flagsRegSrc() %{
4268 constraint(ALLOC_IN_RC(int_flags_ro));
4269 match(RegFlags);
4270 match(flagsReg);
4271 match(flagsRegCR0);
4272 format %{ %}
4273 interface(REG_INTER);
4274 %}
4275
4276 // Condition Code Flag Register CR0
4277 operand flagsRegCR0() %{
4278 constraint(ALLOC_IN_RC(int_flags_CR0));
4279 match(RegFlags);
4280 format %{ "CR0" %}
4281 interface(REG_INTER);
4282 %}
4283
4284 operand flagsRegCR1() %{
4285 constraint(ALLOC_IN_RC(int_flags_CR1));
4286 match(RegFlags);
4287 format %{ "CR1" %}
4288 interface(REG_INTER);
4289 %}
4290
4291 operand flagsRegCR6() %{
4292 constraint(ALLOC_IN_RC(int_flags_CR6));
4293 match(RegFlags);
4294 format %{ "CR6" %}
4295 interface(REG_INTER);
4296 %}
4297
4298 operand regCTR() %{
4299 constraint(ALLOC_IN_RC(ctr_reg));
4300 // RegFlags should work. Introducing a RegSpecial type would cause a
4301 // lot of changes.
4302 match(RegFlags);
4303 format %{"SR_CTR" %}
4304 interface(REG_INTER);
4305 %}
4306
4307 operand regD() %{
4308 constraint(ALLOC_IN_RC(dbl_reg));
4309 match(RegD);
4310 format %{ %}
4311 interface(REG_INTER);
4312 %}
4313
4314 operand regF() %{
4315 constraint(ALLOC_IN_RC(flt_reg));
4316 match(RegF);
4317 format %{ %}
4318 interface(REG_INTER);
4319 %}
4320
4321 // Special Registers
4322
4323 // Method Register
4324 operand inline_cache_regP(iRegPdst reg) %{
4325 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg
4326 match(reg);
4327 format %{ %}
4328 interface(REG_INTER);
4329 %}
4330
4331 // Operands to remove register moves in unscaled mode.
4332 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4333 operand iRegP2N(iRegPsrc reg) %{
4334 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0);
4335 constraint(ALLOC_IN_RC(bits64_reg_ro));
4336 match(EncodeP reg);
4337 format %{ "$reg" %}
4338 interface(REG_INTER)
4339 %}
4340
4341 operand iRegN2P(iRegNsrc reg) %{
4342 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4343 constraint(ALLOC_IN_RC(bits32_reg_ro));
4344 match(DecodeN reg);
4345 format %{ "$reg" %}
4346 interface(REG_INTER)
4347 %}
4348
4349 operand iRegN2P_klass(iRegNsrc reg) %{
4350 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4351 constraint(ALLOC_IN_RC(bits32_reg_ro));
4352 match(DecodeNKlass reg);
4353 format %{ "$reg" %}
4354 interface(REG_INTER)
4355 %}
4356
4357 //----------Complex Operands---------------------------------------------------
4358 // Indirect Memory Reference
4359 operand indirect(iRegPsrc reg) %{
4360 constraint(ALLOC_IN_RC(bits64_reg_ro));
4361 match(reg);
4362 op_cost(100);
4363 format %{ "[$reg]" %}
4364 interface(MEMORY_INTER) %{
4365 base($reg);
4366 index(0x0);
4367 scale(0x0);
4368 disp(0x0);
4369 %}
4370 %}
4371
4372 // Indirect with Offset
4373 operand indOffset16(iRegPsrc reg, immL16 offset) %{
4374 constraint(ALLOC_IN_RC(bits64_reg_ro));
4375 match(AddP reg offset);
4376 op_cost(100);
4377 format %{ "[$reg + $offset]" %}
4378 interface(MEMORY_INTER) %{
4379 base($reg);
4380 index(0x0);
4381 scale(0x0);
4382 disp($offset);
4383 %}
4384 %}
4385
4386 // Indirect with 4-aligned Offset
4387 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{
4388 constraint(ALLOC_IN_RC(bits64_reg_ro));
4389 match(AddP reg offset);
4390 op_cost(100);
4391 format %{ "[$reg + $offset]" %}
4392 interface(MEMORY_INTER) %{
4393 base($reg);
4394 index(0x0);
4395 scale(0x0);
4396 disp($offset);
4397 %}
4398 %}
4399
4400 // Indirect with 16-aligned Offset
4401 operand indOffset16Alg16(iRegPsrc reg, immL16Alg16 offset) %{
4402 constraint(ALLOC_IN_RC(bits64_reg_ro));
4403 match(AddP reg offset);
4404 op_cost(100);
4405 format %{ "[$reg + $offset]" %}
4406 interface(MEMORY_INTER) %{
4407 base($reg);
4408 index(0x0);
4409 scale(0x0);
4410 disp($offset);
4411 %}
4412 %}
4413
4414 //----------Complex Operands for Compressed OOPs-------------------------------
4415 // Compressed OOPs with narrow_oop_shift == 0.
4416
4417 // Indirect Memory Reference, compressed OOP
4418 operand indirectNarrow(iRegNsrc reg) %{
4419 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4420 constraint(ALLOC_IN_RC(bits64_reg_ro));
4421 match(DecodeN reg);
4422 op_cost(100);
4423 format %{ "[$reg]" %}
4424 interface(MEMORY_INTER) %{
4425 base($reg);
4426 index(0x0);
4427 scale(0x0);
4428 disp(0x0);
4429 %}
4430 %}
4431
4432 operand indirectNarrow_klass(iRegNsrc reg) %{
4433 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4434 constraint(ALLOC_IN_RC(bits64_reg_ro));
4435 match(DecodeNKlass reg);
4436 op_cost(100);
4437 format %{ "[$reg]" %}
4438 interface(MEMORY_INTER) %{
4439 base($reg);
4440 index(0x0);
4441 scale(0x0);
4442 disp(0x0);
4443 %}
4444 %}
4445
4446 // Indirect with Offset, compressed OOP
4447 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4448 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4449 constraint(ALLOC_IN_RC(bits64_reg_ro));
4450 match(AddP (DecodeN reg) offset);
4451 op_cost(100);
4452 format %{ "[$reg + $offset]" %}
4453 interface(MEMORY_INTER) %{
4454 base($reg);
4455 index(0x0);
4456 scale(0x0);
4457 disp($offset);
4458 %}
4459 %}
4460
4461 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4462 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4463 constraint(ALLOC_IN_RC(bits64_reg_ro));
4464 match(AddP (DecodeNKlass reg) offset);
4465 op_cost(100);
4466 format %{ "[$reg + $offset]" %}
4467 interface(MEMORY_INTER) %{
4468 base($reg);
4469 index(0x0);
4470 scale(0x0);
4471 disp($offset);
4472 %}
4473 %}
4474
4475 // Indirect with 4-aligned Offset, compressed OOP
4476 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4477 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4478 constraint(ALLOC_IN_RC(bits64_reg_ro));
4479 match(AddP (DecodeN reg) offset);
4480 op_cost(100);
4481 format %{ "[$reg + $offset]" %}
4482 interface(MEMORY_INTER) %{
4483 base($reg);
4484 index(0x0);
4485 scale(0x0);
4486 disp($offset);
4487 %}
4488 %}
4489
4490 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4491 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4492 constraint(ALLOC_IN_RC(bits64_reg_ro));
4493 match(AddP (DecodeNKlass reg) offset);
4494 op_cost(100);
4495 format %{ "[$reg + $offset]" %}
4496 interface(MEMORY_INTER) %{
4497 base($reg);
4498 index(0x0);
4499 scale(0x0);
4500 disp($offset);
4501 %}
4502 %}
4503
4504 //----------Special Memory Operands--------------------------------------------
4505 // Stack Slot Operand
4506 //
4507 // This operand is used for loading and storing temporary values on
4508 // the stack where a match requires a value to flow through memory.
4509 operand stackSlotI(sRegI reg) %{
4510 constraint(ALLOC_IN_RC(stack_slots));
4511 op_cost(100);
4512 //match(RegI);
4513 format %{ "[sp+$reg]" %}
4514 interface(MEMORY_INTER) %{
4515 base(0x1); // R1_SP
4516 index(0x0);
4517 scale(0x0);
4518 disp($reg); // Stack Offset
4519 %}
4520 %}
4521
4522 operand stackSlotL(sRegL reg) %{
4523 constraint(ALLOC_IN_RC(stack_slots));
4524 op_cost(100);
4525 //match(RegL);
4526 format %{ "[sp+$reg]" %}
4527 interface(MEMORY_INTER) %{
4528 base(0x1); // R1_SP
4529 index(0x0);
4530 scale(0x0);
4531 disp($reg); // Stack Offset
4532 %}
4533 %}
4534
4535 operand stackSlotP(sRegP reg) %{
4536 constraint(ALLOC_IN_RC(stack_slots));
4537 op_cost(100);
4538 //match(RegP);
4539 format %{ "[sp+$reg]" %}
4540 interface(MEMORY_INTER) %{
4541 base(0x1); // R1_SP
4542 index(0x0);
4543 scale(0x0);
4544 disp($reg); // Stack Offset
4545 %}
4546 %}
4547
4548 operand stackSlotF(sRegF reg) %{
4549 constraint(ALLOC_IN_RC(stack_slots));
4550 op_cost(100);
4551 //match(RegF);
4552 format %{ "[sp+$reg]" %}
4553 interface(MEMORY_INTER) %{
4554 base(0x1); // R1_SP
4555 index(0x0);
4556 scale(0x0);
4557 disp($reg); // Stack Offset
4558 %}
4559 %}
4560
4561 operand stackSlotD(sRegD reg) %{
4562 constraint(ALLOC_IN_RC(stack_slots));
4563 op_cost(100);
4564 //match(RegD);
4565 format %{ "[sp+$reg]" %}
4566 interface(MEMORY_INTER) %{
4567 base(0x1); // R1_SP
4568 index(0x0);
4569 scale(0x0);
4570 disp($reg); // Stack Offset
4571 %}
4572 %}
4573
4574 // Operands for expressing Control Flow
4575 // NOTE: Label is a predefined operand which should not be redefined in
4576 // the AD file. It is generically handled within the ADLC.
4577
4578 //----------Conditional Branch Operands----------------------------------------
4579 // Comparison Op
4580 //
4581 // This is the operation of the comparison, and is limited to the
4582 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE
4583 // (!=).
4584 //
4585 // Other attributes of the comparison, such as unsignedness, are specified
4586 // by the comparison instruction that sets a condition code flags register.
4587 // That result is represented by a flags operand whose subtype is appropriate
4588 // to the unsignedness (etc.) of the comparison.
4589 //
4590 // Later, the instruction which matches both the Comparison Op (a Bool) and
4591 // the flags (produced by the Cmp) specifies the coding of the comparison op
4592 // by matching a specific subtype of Bool operand below.
4593
4594 // When used for floating point comparisons: unordered same as less.
4595 operand cmpOp() %{
4596 match(Bool);
4597 format %{ "" %}
4598 interface(COND_INTER) %{
4599 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'.
4600 // BO & BI
4601 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4602 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4603 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4604 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4605 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4606 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4607 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4608 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4609 %}
4610 %}
4611
4612 //----------OPERAND CLASSES----------------------------------------------------
4613 // Operand Classes are groups of operands that are used to simplify
4614 // instruction definitions by not requiring the AD writer to specify
4615 // separate instructions for every form of operand when the
4616 // instruction accepts multiple operand types with the same basic
4617 // encoding and format. The classic case of this is memory operands.
4618 // Indirect is not included since its use is limited to Compare & Swap.
4619
4620 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4621 // Memory operand where offsets are 4-aligned. Required for ld, std.
4622 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4623 opclass memoryAlg16(indirect, indOffset16Alg16);
4624 opclass indirectMemory(indirect, indirectNarrow);
4625
4626 // Special opclass for I and ConvL2I.
4627 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4628
4629 // Operand classes to match encode and decode. iRegN_P2N is only used
4630 // for storeN. I have never seen an encode node elsewhere.
4631 opclass iRegN_P2N(iRegNsrc, iRegP2N);
4632 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4633
4634 //----------PIPELINE-----------------------------------------------------------
4635
4636 pipeline %{
4637
4638 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4639 // J. Res. & Dev., No. 1, Jan. 2002.
4640
4641 //----------ATTRIBUTES---------------------------------------------------------
4642 attributes %{
4643
4644 // Power4 instructions are of fixed length.
4645 fixed_size_instructions;
4646
4647 // TODO: if `bundle' means number of instructions fetched
4648 // per cycle, this is 8. If `bundle' means Power4 `group', that is
4649 // max instructions issued per cycle, this is 5.
4650 max_instructions_per_bundle = 8;
4651
4652 // A Power4 instruction is 4 bytes long.
4653 instruction_unit_size = 4;
4654
4655 // The Power4 processor fetches 64 bytes...
4656 instruction_fetch_unit_size = 64;
4657
4658 // ...in one line
4659 instruction_fetch_units = 1
4660 %}
4661
4662 //----------RESOURCES----------------------------------------------------------
4663 // Resources are the functional units available to the machine
4664 resources(
4665 PPC_BR, // branch unit
4666 PPC_CR, // condition unit
4667 PPC_FX1, // integer arithmetic unit 1
4668 PPC_FX2, // integer arithmetic unit 2
4669 PPC_LDST1, // load/store unit 1
4670 PPC_LDST2, // load/store unit 2
4671 PPC_FP1, // float arithmetic unit 1
4672 PPC_FP2, // float arithmetic unit 2
4673 PPC_LDST = PPC_LDST1 | PPC_LDST2,
4674 PPC_FX = PPC_FX1 | PPC_FX2,
4675 PPC_FP = PPC_FP1 | PPC_FP2
4676 );
4677
4678 //----------PIPELINE DESCRIPTION-----------------------------------------------
4679 // Pipeline Description specifies the stages in the machine's pipeline
4680 pipe_desc(
4681 // Power4 longest pipeline path
4682 PPC_IF, // instruction fetch
4683 PPC_IC,
4684 //PPC_BP, // branch prediction
4685 PPC_D0, // decode
4686 PPC_D1, // decode
4687 PPC_D2, // decode
4688 PPC_D3, // decode
4689 PPC_Xfer1,
4690 PPC_GD, // group definition
4691 PPC_MP, // map
4692 PPC_ISS, // issue
4693 PPC_RF, // resource fetch
4694 PPC_EX1, // execute (all units)
4695 PPC_EX2, // execute (FP, LDST)
4696 PPC_EX3, // execute (FP, LDST)
4697 PPC_EX4, // execute (FP)
4698 PPC_EX5, // execute (FP)
4699 PPC_EX6, // execute (FP)
4700 PPC_WB, // write back
4701 PPC_Xfer2,
4702 PPC_CP
4703 );
4704
4705 //----------PIPELINE CLASSES---------------------------------------------------
4706 // Pipeline Classes describe the stages in which input and output are
4707 // referenced by the hardware pipeline.
4708
4709 // Simple pipeline classes.
4710
4711 // Default pipeline class.
4712 pipe_class pipe_class_default() %{
4713 single_instruction;
4714 fixed_latency(2);
4715 %}
4716
4717 // Pipeline class for empty instructions.
4718 pipe_class pipe_class_empty() %{
4719 single_instruction;
4720 fixed_latency(0);
4721 %}
4722
4723 // Pipeline class for compares.
4724 pipe_class pipe_class_compare() %{
4725 single_instruction;
4726 fixed_latency(16);
4727 %}
4728
4729 // Pipeline class for traps.
4730 pipe_class pipe_class_trap() %{
4731 single_instruction;
4732 fixed_latency(100);
4733 %}
4734
4735 // Pipeline class for memory operations.
4736 pipe_class pipe_class_memory() %{
4737 single_instruction;
4738 fixed_latency(16);
4739 %}
4740
4741 // Pipeline class for call.
4742 pipe_class pipe_class_call() %{
4743 single_instruction;
4744 fixed_latency(100);
4745 %}
4746
4747 // Define the class for the Nop node.
4748 define %{
4749 MachNop = pipe_class_default;
4750 %}
4751
4752 %}
4753
4754 //----------INSTRUCTIONS-------------------------------------------------------
4755
4756 // Naming of instructions:
4757 // opA_operB / opA_operB_operC:
4758 // Operation 'op' with one or two source operands 'oper'. Result
4759 // type is A, source operand types are B and C.
4760 // Iff A == B == C, B and C are left out.
4761 //
4762 // The instructions are ordered according to the following scheme:
4763 // - loads
4764 // - load constants
4765 // - prefetch
4766 // - store
4767 // - encode/decode
4768 // - membar
4769 // - conditional moves
4770 // - compare & swap
4771 // - arithmetic and logic operations
4772 // * int: Add, Sub, Mul, Div, Mod
4773 // * int: lShift, arShift, urShift, rot
4774 // * float: Add, Sub, Mul, Div
4775 // * and, or, xor ...
4776 // - register moves: float <-> int, reg <-> stack, repl
4777 // - cast (high level type cast, XtoP, castPP, castII, not_null etc.
4778 // - conv (low level type cast requiring bit changes (sign extend etc)
4779 // - compares, range & zero checks.
4780 // - branches
4781 // - complex operations, intrinsics, min, max, replicate
4782 // - lock
4783 // - Calls
4784 //
4785 // If there are similar instructions with different types they are sorted:
4786 // int before float
4787 // small before big
4788 // signed before unsigned
4789 // e.g., loadS before loadUS before loadI before loadF.
4790
4791
4792 //----------Load/Store Instructions--------------------------------------------
4793
4794 //----------Load Instructions--------------------------------------------------
4795
4796 // Converts byte to int.
4797 // As convB2I_reg, but without match rule. The match rule of convB2I_reg
4798 // reuses the 'amount' operand, but adlc expects that operand specification
4799 // and operands in match rule are equivalent.
4800 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
4801 effect(DEF dst, USE src);
4802 format %{ "EXTSB $dst, $src \t// byte->int" %}
4803 size(4);
4804 ins_encode %{
4805 __ extsb($dst$$Register, $src$$Register);
4806 %}
4807 ins_pipe(pipe_class_default);
4808 %}
4809
4810 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{
4811 // match-rule, false predicate
4812 match(Set dst (LoadB mem));
4813 predicate(false);
4814
4815 format %{ "LBZ $dst, $mem" %}
4816 size(4);
4817 ins_encode( enc_lbz(dst, mem) );
4818 ins_pipe(pipe_class_memory);
4819 %}
4820
4821 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{
4822 // match-rule, false predicate
4823 match(Set dst (LoadB mem));
4824 predicate(false);
4825
4826 format %{ "LBZ $dst, $mem\n\t"
4827 "TWI $dst\n\t"
4828 "ISYNC" %}
4829 size(12);
4830 ins_encode( enc_lbz_ac(dst, mem) );
4831 ins_pipe(pipe_class_memory);
4832 %}
4833
4834 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
4835 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{
4836 match(Set dst (LoadB mem));
4837 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4838 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4839 expand %{
4840 iRegIdst tmp;
4841 loadUB_indirect(tmp, mem);
4842 convB2I_reg_2(dst, tmp);
4843 %}
4844 %}
4845
4846 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{
4847 match(Set dst (LoadB mem));
4848 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
4849 expand %{
4850 iRegIdst tmp;
4851 loadUB_indirect_ac(tmp, mem);
4852 convB2I_reg_2(dst, tmp);
4853 %}
4854 %}
4855
4856 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{
4857 // match-rule, false predicate
4858 match(Set dst (LoadB mem));
4859 predicate(false);
4860
4861 format %{ "LBZ $dst, $mem" %}
4862 size(4);
4863 ins_encode( enc_lbz(dst, mem) );
4864 ins_pipe(pipe_class_memory);
4865 %}
4866
4867 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{
4868 // match-rule, false predicate
4869 match(Set dst (LoadB mem));
4870 predicate(false);
4871
4872 format %{ "LBZ $dst, $mem\n\t"
4873 "TWI $dst\n\t"
4874 "ISYNC" %}
4875 size(12);
4876 ins_encode( enc_lbz_ac(dst, mem) );
4877 ins_pipe(pipe_class_memory);
4878 %}
4879
4880 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
4881 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{
4882 match(Set dst (LoadB mem));
4883 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4884 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4885
4886 expand %{
4887 iRegIdst tmp;
4888 loadUB_indOffset16(tmp, mem);
4889 convB2I_reg_2(dst, tmp);
4890 %}
4891 %}
4892
4893 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{
4894 match(Set dst (LoadB mem));
4895 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
4896
4897 expand %{
4898 iRegIdst tmp;
4899 loadUB_indOffset16_ac(tmp, mem);
4900 convB2I_reg_2(dst, tmp);
4901 %}
4902 %}
4903
4904 // Load Unsigned Byte (8bit UNsigned) into an int reg.
4905 instruct loadUB(iRegIdst dst, memory mem) %{
4906 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4907 match(Set dst (LoadUB mem));
4908 ins_cost(MEMORY_REF_COST);
4909
4910 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %}
4911 size(4);
4912 ins_encode( enc_lbz(dst, mem) );
4913 ins_pipe(pipe_class_memory);
4914 %}
4915
4916 // Load Unsigned Byte (8bit UNsigned) acquire.
4917 instruct loadUB_ac(iRegIdst dst, memory mem) %{
4918 match(Set dst (LoadUB mem));
4919 ins_cost(3*MEMORY_REF_COST);
4920
4921 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t"
4922 "TWI $dst\n\t"
4923 "ISYNC" %}
4924 size(12);
4925 ins_encode( enc_lbz_ac(dst, mem) );
4926 ins_pipe(pipe_class_memory);
4927 %}
4928
4929 // Load Unsigned Byte (8bit UNsigned) into a Long Register.
4930 instruct loadUB2L(iRegLdst dst, memory mem) %{
4931 match(Set dst (ConvI2L (LoadUB mem)));
4932 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
4933 ins_cost(MEMORY_REF_COST);
4934
4935 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %}
4936 size(4);
4937 ins_encode( enc_lbz(dst, mem) );
4938 ins_pipe(pipe_class_memory);
4939 %}
4940
4941 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{
4942 match(Set dst (ConvI2L (LoadUB mem)));
4943 ins_cost(3*MEMORY_REF_COST);
4944
4945 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t"
4946 "TWI $dst\n\t"
4947 "ISYNC" %}
4948 size(12);
4949 ins_encode( enc_lbz_ac(dst, mem) );
4950 ins_pipe(pipe_class_memory);
4951 %}
4952
4953 // Load Short (16bit signed)
4954 instruct loadS(iRegIdst dst, memory mem) %{
4955 match(Set dst (LoadS mem));
4956 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4957 ins_cost(MEMORY_REF_COST);
4958
4959 format %{ "LHA $dst, $mem" %}
4960 size(4);
4961 ins_encode %{
4962 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
4963 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
4964 %}
4965 ins_pipe(pipe_class_memory);
4966 %}
4967
4968 // Load Short (16bit signed) acquire.
4969 instruct loadS_ac(iRegIdst dst, memory mem) %{
4970 match(Set dst (LoadS mem));
4971 ins_cost(3*MEMORY_REF_COST);
4972
4973 format %{ "LHA $dst, $mem\t acquire\n\t"
4974 "TWI $dst\n\t"
4975 "ISYNC" %}
4976 size(12);
4977 ins_encode %{
4978 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
4979 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
4980 __ twi_0($dst$$Register);
4981 __ isync();
4982 %}
4983 ins_pipe(pipe_class_memory);
4984 %}
4985
4986 // Load Char (16bit unsigned)
4987 instruct loadUS(iRegIdst dst, memory mem) %{
4988 match(Set dst (LoadUS mem));
4989 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4990 ins_cost(MEMORY_REF_COST);
4991
4992 format %{ "LHZ $dst, $mem" %}
4993 size(4);
4994 ins_encode( enc_lhz(dst, mem) );
4995 ins_pipe(pipe_class_memory);
4996 %}
4997
4998 // Load Char (16bit unsigned) acquire.
4999 instruct loadUS_ac(iRegIdst dst, memory mem) %{
5000 match(Set dst (LoadUS mem));
5001 ins_cost(3*MEMORY_REF_COST);
5002
5003 format %{ "LHZ $dst, $mem \t// acquire\n\t"
5004 "TWI $dst\n\t"
5005 "ISYNC" %}
5006 size(12);
5007 ins_encode( enc_lhz_ac(dst, mem) );
5008 ins_pipe(pipe_class_memory);
5009 %}
5010
5011 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register.
5012 instruct loadUS2L(iRegLdst dst, memory mem) %{
5013 match(Set dst (ConvI2L (LoadUS mem)));
5014 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5015 ins_cost(MEMORY_REF_COST);
5016
5017 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %}
5018 size(4);
5019 ins_encode( enc_lhz(dst, mem) );
5020 ins_pipe(pipe_class_memory);
5021 %}
5022
5023 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire.
5024 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{
5025 match(Set dst (ConvI2L (LoadUS mem)));
5026 ins_cost(3*MEMORY_REF_COST);
5027
5028 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t"
5029 "TWI $dst\n\t"
5030 "ISYNC" %}
5031 size(12);
5032 ins_encode( enc_lhz_ac(dst, mem) );
5033 ins_pipe(pipe_class_memory);
5034 %}
5035
5036 // Load Integer.
5037 instruct loadI(iRegIdst dst, memory mem) %{
5038 match(Set dst (LoadI mem));
5039 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5040 ins_cost(MEMORY_REF_COST);
5041
5042 format %{ "LWZ $dst, $mem" %}
5043 size(4);
5044 ins_encode( enc_lwz(dst, mem) );
5045 ins_pipe(pipe_class_memory);
5046 %}
5047
5048 // Load Integer acquire.
5049 instruct loadI_ac(iRegIdst dst, memory mem) %{
5050 match(Set dst (LoadI mem));
5051 ins_cost(3*MEMORY_REF_COST);
5052
5053 format %{ "LWZ $dst, $mem \t// load acquire\n\t"
5054 "TWI $dst\n\t"
5055 "ISYNC" %}
5056 size(12);
5057 ins_encode( enc_lwz_ac(dst, mem) );
5058 ins_pipe(pipe_class_memory);
5059 %}
5060
5061 // Match loading integer and casting it to unsigned int in
5062 // long register.
5063 // LoadI + ConvI2L + AndL 0xffffffff.
5064 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
5065 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5066 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered());
5067 ins_cost(MEMORY_REF_COST);
5068
5069 format %{ "LWZ $dst, $mem \t// zero-extend to long" %}
5070 size(4);
5071 ins_encode( enc_lwz(dst, mem) );
5072 ins_pipe(pipe_class_memory);
5073 %}
5074
5075 // Match loading integer and casting it to long.
5076 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
5077 match(Set dst (ConvI2L (LoadI mem)));
5078 predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5079 ins_cost(MEMORY_REF_COST);
5080
5081 format %{ "LWA $dst, $mem \t// loadI2L" %}
5082 size(4);
5083 ins_encode %{
5084 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5085 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5086 %}
5087 ins_pipe(pipe_class_memory);
5088 %}
5089
5090 // Match loading integer and casting it to long - acquire.
5091 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
5092 match(Set dst (ConvI2L (LoadI mem)));
5093 ins_cost(3*MEMORY_REF_COST);
5094
5095 format %{ "LWA $dst, $mem \t// loadI2L acquire"
5096 "TWI $dst\n\t"
5097 "ISYNC" %}
5098 size(12);
5099 ins_encode %{
5100 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5101 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5102 __ twi_0($dst$$Register);
5103 __ isync();
5104 %}
5105 ins_pipe(pipe_class_memory);
5106 %}
5107
5108 // Load Long - aligned
5109 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{
5110 match(Set dst (LoadL mem));
5111 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5112 ins_cost(MEMORY_REF_COST);
5113
5114 format %{ "LD $dst, $mem \t// long" %}
5115 size(4);
5116 ins_encode( enc_ld(dst, mem) );
5117 ins_pipe(pipe_class_memory);
5118 %}
5119
5120 // Load Long - aligned acquire.
5121 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{
5122 match(Set dst (LoadL mem));
5123 ins_cost(3*MEMORY_REF_COST);
5124
5125 format %{ "LD $dst, $mem \t// long acquire\n\t"
5126 "TWI $dst\n\t"
5127 "ISYNC" %}
5128 size(12);
5129 ins_encode( enc_ld_ac(dst, mem) );
5130 ins_pipe(pipe_class_memory);
5131 %}
5132
5133 // Load Long - UNaligned
5134 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{
5135 match(Set dst (LoadL_unaligned mem));
5136 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5137 ins_cost(MEMORY_REF_COST);
5138
5139 format %{ "LD $dst, $mem \t// unaligned long" %}
5140 size(4);
5141 ins_encode( enc_ld(dst, mem) );
5142 ins_pipe(pipe_class_memory);
5143 %}
5144
5145 // Load nodes for superwords
5146
5147 // Load Aligned Packed Byte
5148 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{
5149 predicate(n->as_LoadVector()->memory_size() == 8);
5150 match(Set dst (LoadVector mem));
5151 ins_cost(MEMORY_REF_COST);
5152
5153 format %{ "LD $dst, $mem \t// load 8-byte Vector" %}
5154 size(4);
5155 ins_encode( enc_ld(dst, mem) );
5156 ins_pipe(pipe_class_memory);
5157 %}
5158
5159
5160 instruct loadV16(vecX dst, memoryAlg16 mem) %{
5161 predicate(n->as_LoadVector()->memory_size() == 16);
5162 match(Set dst (LoadVector mem));
5163 ins_cost(MEMORY_REF_COST);
5164
5165 format %{ "LXV $dst, $mem \t// load 16-byte Vector" %}
5166 size(4);
5167 ins_encode %{
5168 __ lxv($dst$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
5169 %}
5170 ins_pipe(pipe_class_default);
5171 %}
5172
5173 // Load Range, range = array length (=jint)
5174 instruct loadRange(iRegIdst dst, memory mem) %{
5175 match(Set dst (LoadRange mem));
5176 ins_cost(MEMORY_REF_COST);
5177
5178 format %{ "LWZ $dst, $mem \t// range" %}
5179 size(4);
5180 ins_encode( enc_lwz(dst, mem) );
5181 ins_pipe(pipe_class_memory);
5182 %}
5183
5184 // Load Compressed Pointer
5185 instruct loadN(iRegNdst dst, memory mem) %{
5186 match(Set dst (LoadN mem));
5187 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5188 ins_cost(MEMORY_REF_COST);
5189
5190 format %{ "LWZ $dst, $mem \t// load compressed ptr" %}
5191 size(4);
5192 ins_encode( enc_lwz(dst, mem) );
5193 ins_pipe(pipe_class_memory);
5194 %}
5195
5196 // Load Compressed Pointer acquire.
5197 instruct loadN_ac(iRegNdst dst, memory mem) %{
5198 match(Set dst (LoadN mem));
5199 predicate(n->as_Load()->barrier_data() == 0);
5200 ins_cost(3*MEMORY_REF_COST);
5201
5202 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5203 "TWI $dst\n\t"
5204 "ISYNC" %}
5205 size(12);
5206 ins_encode( enc_lwz_ac(dst, mem) );
5207 ins_pipe(pipe_class_memory);
5208 %}
5209
5210 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5211 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5212 match(Set dst (DecodeN (LoadN mem)));
5213 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0 && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5214 ins_cost(MEMORY_REF_COST);
5215
5216 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5217 size(4);
5218 ins_encode( enc_lwz(dst, mem) );
5219 ins_pipe(pipe_class_memory);
5220 %}
5221
5222 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5223 match(Set dst (DecodeNKlass (LoadNKlass mem)));
5224 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0 &&
5225 _kids[0]->_leaf->as_Load()->is_unordered());
5226 ins_cost(MEMORY_REF_COST);
5227
5228 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5229 size(4);
5230 ins_encode( enc_lwz(dst, mem) );
5231 ins_pipe(pipe_class_memory);
5232 %}
5233
5234 // Load Pointer
5235 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5236 match(Set dst (LoadP mem));
5237 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5238 ins_cost(MEMORY_REF_COST);
5239
5240 format %{ "LD $dst, $mem \t// ptr" %}
5241 size(4);
5242 ins_encode( enc_ld(dst, mem) );
5243 ins_pipe(pipe_class_memory);
5244 %}
5245
5246 // Load Pointer acquire.
5247 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5248 match(Set dst (LoadP mem));
5249 ins_cost(3*MEMORY_REF_COST);
5250
5251 predicate(n->as_Load()->barrier_data() == 0);
5252
5253 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5254 "TWI $dst\n\t"
5255 "ISYNC" %}
5256 size(12);
5257 ins_encode( enc_ld_ac(dst, mem) );
5258 ins_pipe(pipe_class_memory);
5259 %}
5260
5261 // LoadP + CastP2L
5262 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
5263 match(Set dst (CastP2X (LoadP mem)));
5264 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5265 ins_cost(MEMORY_REF_COST);
5266
5267 format %{ "LD $dst, $mem \t// ptr + p2x" %}
5268 size(4);
5269 ins_encode( enc_ld(dst, mem) );
5270 ins_pipe(pipe_class_memory);
5271 %}
5272
5273 // Load compressed klass pointer.
5274 instruct loadNKlass(iRegNdst dst, memory mem) %{
5275 match(Set dst (LoadNKlass mem));
5276 predicate(!UseCompactObjectHeaders);
5277 ins_cost(MEMORY_REF_COST);
5278
5279 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %}
5280 size(4);
5281 ins_encode( enc_lwz(dst, mem) );
5282 ins_pipe(pipe_class_memory);
5283 %}
5284
5285 instruct loadNKlassCompactHeaders(iRegNdst dst, memory mem) %{
5286 match(Set dst (LoadNKlass mem));
5287 predicate(UseCompactObjectHeaders);
5288 ins_cost(MEMORY_REF_COST);
5289
5290 format %{ "load_narrow_klass_compact $dst, $mem \t// compressed class ptr" %}
5291 size(8);
5292 ins_encode %{
5293 assert($mem$$index$$Register == R0, "must not have indexed address: %s[%s]", $mem$$base$$Register.name(), $mem$$index$$Register.name());
5294 __ load_narrow_klass_compact_c2($dst$$Register, $mem$$base$$Register, $mem$$disp);
5295 %}
5296 ins_pipe(pipe_class_memory);
5297 %}
5298
5299 // Load Klass Pointer
5300 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
5301 match(Set dst (LoadKlass mem));
5302 ins_cost(MEMORY_REF_COST);
5303
5304 format %{ "LD $dst, $mem \t// klass ptr" %}
5305 size(4);
5306 ins_encode( enc_ld(dst, mem) );
5307 ins_pipe(pipe_class_memory);
5308 %}
5309
5310 // Load Float
5311 instruct loadF(regF dst, memory mem) %{
5312 match(Set dst (LoadF mem));
5313 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5314 ins_cost(MEMORY_REF_COST);
5315
5316 format %{ "LFS $dst, $mem" %}
5317 size(4);
5318 ins_encode %{
5319 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5320 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5321 %}
5322 ins_pipe(pipe_class_memory);
5323 %}
5324
5325 // Load Float acquire.
5326 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5327 match(Set dst (LoadF mem));
5328 effect(TEMP cr0);
5329 ins_cost(3*MEMORY_REF_COST);
5330
5331 format %{ "LFS $dst, $mem \t// acquire\n\t"
5332 "FCMPU cr0, $dst, $dst\n\t"
5333 "BNE cr0, next\n"
5334 "next:\n\t"
5335 "ISYNC" %}
5336 size(16);
5337 ins_encode %{
5338 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5339 Label next;
5340 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5341 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5342 __ bne(CR0, next);
5343 __ bind(next);
5344 __ isync();
5345 %}
5346 ins_pipe(pipe_class_memory);
5347 %}
5348
5349 // Load Double - aligned
5350 instruct loadD(regD dst, memory mem) %{
5351 match(Set dst (LoadD mem));
5352 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5353 ins_cost(MEMORY_REF_COST);
5354
5355 format %{ "LFD $dst, $mem" %}
5356 size(4);
5357 ins_encode( enc_lfd(dst, mem) );
5358 ins_pipe(pipe_class_memory);
5359 %}
5360
5361 // Load Double - aligned acquire.
5362 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5363 match(Set dst (LoadD mem));
5364 effect(TEMP cr0);
5365 ins_cost(3*MEMORY_REF_COST);
5366
5367 format %{ "LFD $dst, $mem \t// acquire\n\t"
5368 "FCMPU cr0, $dst, $dst\n\t"
5369 "BNE cr0, next\n"
5370 "next:\n\t"
5371 "ISYNC" %}
5372 size(16);
5373 ins_encode %{
5374 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5375 Label next;
5376 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5377 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5378 __ bne(CR0, next);
5379 __ bind(next);
5380 __ isync();
5381 %}
5382 ins_pipe(pipe_class_memory);
5383 %}
5384
5385 // Load Double - UNaligned
5386 instruct loadD_unaligned(regD dst, memory mem) %{
5387 match(Set dst (LoadD_unaligned mem));
5388 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5389 ins_cost(MEMORY_REF_COST);
5390
5391 format %{ "LFD $dst, $mem" %}
5392 size(4);
5393 ins_encode( enc_lfd(dst, mem) );
5394 ins_pipe(pipe_class_memory);
5395 %}
5396
5397 //----------Constants--------------------------------------------------------
5398
5399 // Load MachConstantTableBase: add hi offset to global toc.
5400 // TODO: Handle hidden register r29 in bundler!
5401 instruct loadToc_hi(iRegLdst dst) %{
5402 effect(DEF dst);
5403 ins_cost(DEFAULT_COST);
5404
5405 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %}
5406 size(4);
5407 ins_encode %{
5408 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
5409 %}
5410 ins_pipe(pipe_class_default);
5411 %}
5412
5413 // Load MachConstantTableBase: add lo offset to global toc.
5414 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
5415 effect(DEF dst, USE src);
5416 ins_cost(DEFAULT_COST);
5417
5418 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %}
5419 size(4);
5420 ins_encode %{
5421 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
5422 %}
5423 ins_pipe(pipe_class_default);
5424 %}
5425
5426 // Load 16-bit integer constant 0xssss????
5427 instruct loadConI16(iRegIdst dst, immI16 src) %{
5428 match(Set dst src);
5429
5430 format %{ "LI $dst, $src" %}
5431 size(4);
5432 ins_encode %{
5433 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5434 %}
5435 ins_pipe(pipe_class_default);
5436 %}
5437
5438 // Load integer constant 0x????0000
5439 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
5440 match(Set dst src);
5441 ins_cost(DEFAULT_COST);
5442
5443 format %{ "LIS $dst, $src.hi" %}
5444 size(4);
5445 ins_encode %{
5446 // Lis sign extends 16-bit src then shifts it 16 bit to the left.
5447 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5448 %}
5449 ins_pipe(pipe_class_default);
5450 %}
5451
5452 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted
5453 // and sign extended), this adds the low 16 bits.
5454 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
5455 // no match-rule, false predicate
5456 effect(DEF dst, USE src1, USE src2);
5457 predicate(false);
5458
5459 format %{ "ORI $dst, $src1.hi, $src2.lo" %}
5460 size(4);
5461 ins_encode %{
5462 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5463 %}
5464 ins_pipe(pipe_class_default);
5465 %}
5466
5467 instruct loadConI32(iRegIdst dst, immI32 src) %{
5468 match(Set dst src);
5469 // This macro is valid only in Power 10 and up, but adding the following predicate here
5470 // caused a build error, so we comment it out for now.
5471 // predicate(PowerArchitecturePPC64 >= 10);
5472 ins_cost(DEFAULT_COST+1);
5473
5474 format %{ "PLI $dst, $src" %}
5475 size(8);
5476 ins_encode %{
5477 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5478 __ pli($dst$$Register, $src$$constant);
5479 %}
5480 ins_pipe(pipe_class_default);
5481 ins_alignment(2);
5482 %}
5483
5484 instruct loadConI_Ex(iRegIdst dst, immI src) %{
5485 match(Set dst src);
5486 ins_cost(DEFAULT_COST*2);
5487
5488 expand %{
5489 // Would like to use $src$$constant.
5490 immI16 srcLo %{ _opnds[1]->constant() %}
5491 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5492 immIhi16 srcHi %{ _opnds[1]->constant() %}
5493 iRegIdst tmpI;
5494 loadConIhi16(tmpI, srcHi);
5495 loadConI32_lo16(dst, tmpI, srcLo);
5496 %}
5497 %}
5498
5499 // No constant pool entries required.
5500 instruct loadConL16(iRegLdst dst, immL16 src) %{
5501 match(Set dst src);
5502
5503 format %{ "LI $dst, $src \t// long" %}
5504 size(4);
5505 ins_encode %{
5506 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
5507 %}
5508 ins_pipe(pipe_class_default);
5509 %}
5510
5511 // Load long constant 0xssssssss????0000
5512 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
5513 match(Set dst src);
5514 ins_cost(DEFAULT_COST);
5515
5516 format %{ "LIS $dst, $src.hi \t// long" %}
5517 size(4);
5518 ins_encode %{
5519 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5520 %}
5521 ins_pipe(pipe_class_default);
5522 %}
5523
5524 // To load a 32 bit constant: merge lower 16 bits into already loaded
5525 // high 16 bits.
5526 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
5527 // no match-rule, false predicate
5528 effect(DEF dst, USE src1, USE src2);
5529 predicate(false);
5530
5531 format %{ "ORI $dst, $src1, $src2.lo" %}
5532 size(4);
5533 ins_encode %{
5534 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5535 %}
5536 ins_pipe(pipe_class_default);
5537 %}
5538
5539 // Load 32-bit long constant
5540 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{
5541 match(Set dst src);
5542 ins_cost(DEFAULT_COST*2);
5543
5544 expand %{
5545 // Would like to use $src$$constant.
5546 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%}
5547 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5548 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%}
5549 iRegLdst tmpL;
5550 loadConL32hi16(tmpL, srcHi);
5551 loadConL32_lo16(dst, tmpL, srcLo);
5552 %}
5553 %}
5554
5555 // Load 34-bit long constant using prefixed addi. No constant pool entries required.
5556 instruct loadConL34(iRegLdst dst, immL34 src) %{
5557 match(Set dst src);
5558 // This macro is valid only in Power 10 and up, but adding the following predicate here
5559 // caused a build error, so we comment it out for now.
5560 // predicate(PowerArchitecturePPC64 >= 10);
5561 ins_cost(DEFAULT_COST+1);
5562
5563 format %{ "PLI $dst, $src \t// long" %}
5564 size(8);
5565 ins_encode %{
5566 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5567 __ pli($dst$$Register, $src$$constant);
5568 %}
5569 ins_pipe(pipe_class_default);
5570 ins_alignment(2);
5571 %}
5572
5573 // Load long constant 0x????000000000000.
5574 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{
5575 match(Set dst src);
5576 ins_cost(DEFAULT_COST);
5577
5578 expand %{
5579 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%}
5580 immI shift32 %{ 32 %}
5581 iRegLdst tmpL;
5582 loadConL32hi16(tmpL, srcHi);
5583 lshiftL_regL_immI(dst, tmpL, shift32);
5584 %}
5585 %}
5586
5587 // Expand node for constant pool load: small offset.
5588 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{
5589 effect(DEF dst, USE src, USE toc);
5590 ins_cost(MEMORY_REF_COST);
5591
5592 ins_num_consts(1);
5593 // Needed so that CallDynamicJavaDirect can compute the address of this
5594 // instruction for relocation.
5595 ins_field_cbuf_insts_offset(int);
5596
5597 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %}
5598 size(4);
5599 ins_encode( enc_load_long_constL(dst, src, toc) );
5600 ins_pipe(pipe_class_memory);
5601 %}
5602
5603 // Expand node for constant pool load: large offset.
5604 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{
5605 effect(DEF dst, USE src, USE toc);
5606 predicate(false);
5607
5608 ins_num_consts(1);
5609 ins_field_const_toc_offset(int);
5610 // Needed so that CallDynamicJavaDirect can compute the address of this
5611 // instruction for relocation.
5612 ins_field_cbuf_insts_offset(int);
5613
5614 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %}
5615 size(4);
5616 ins_encode( enc_load_long_constL_hi(dst, toc, src) );
5617 ins_pipe(pipe_class_default);
5618 %}
5619
5620 // Expand node for constant pool load: large offset.
5621 // No constant pool entries required.
5622 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
5623 effect(DEF dst, USE src, USE base);
5624 predicate(false);
5625
5626 ins_field_const_toc_offset_hi_node(loadConL_hiNode*);
5627
5628 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %}
5629 size(4);
5630 ins_encode %{
5631 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5632 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5633 %}
5634 ins_pipe(pipe_class_memory);
5635 %}
5636
5637 // Load long constant from constant table. Expand in case of
5638 // offset > 16 bit is needed.
5639 // Adlc adds toc node MachConstantTableBase.
5640 instruct loadConL_Ex(iRegLdst dst, immL src) %{
5641 match(Set dst src);
5642 ins_cost(MEMORY_REF_COST);
5643
5644 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %}
5645 // We can not inline the enc_class for the expand as that does not support constanttablebase.
5646 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) );
5647 %}
5648
5649 // Load nullptr as compressed oop.
5650 instruct loadConN0(iRegNdst dst, immN_0 src) %{
5651 match(Set dst src);
5652 ins_cost(DEFAULT_COST);
5653
5654 format %{ "LI $dst, $src \t// compressed ptr" %}
5655 size(4);
5656 ins_encode %{
5657 __ li($dst$$Register, 0);
5658 %}
5659 ins_pipe(pipe_class_default);
5660 %}
5661
5662 // Load hi part of compressed oop constant.
5663 instruct loadConN_hi(iRegNdst dst, immN src) %{
5664 effect(DEF dst, USE src);
5665 ins_cost(DEFAULT_COST);
5666
5667 format %{ "LIS $dst, $src \t// narrow oop hi" %}
5668 size(4);
5669 ins_encode %{
5670 __ lis($dst$$Register, 0); // Will get patched.
5671 %}
5672 ins_pipe(pipe_class_default);
5673 %}
5674
5675 // Add lo part of compressed oop constant to already loaded hi part.
5676 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
5677 effect(DEF dst, USE src1, USE src2);
5678 ins_cost(DEFAULT_COST);
5679
5680 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %}
5681 size(4);
5682 ins_encode %{
5683 AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant);
5684 __ relocate(addrlit.rspec(), /*compressed format*/ 1);
5685 __ ori($dst$$Register, $src1$$Register, 0); // Will get patched.
5686 %}
5687 ins_pipe(pipe_class_default);
5688 %}
5689
5690 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
5691 effect(DEF dst, USE src, USE shift, USE mask_begin);
5692
5693 size(4);
5694 ins_encode %{
5695 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
5696 %}
5697 ins_pipe(pipe_class_default);
5698 %}
5699
5700 // Needed to postalloc expand loadConN: ConN is loaded as ConI
5701 // leaving the upper 32 bits with sign-extension bits.
5702 // This clears these bits: dst = src & 0xFFFFFFFF.
5703 // TODO: Eventually call this maskN_regN_FFFFFFFF.
5704 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
5705 effect(DEF dst, USE src);
5706 predicate(false);
5707
5708 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
5709 size(4);
5710 ins_encode %{
5711 __ clrldi($dst$$Register, $src$$Register, 0x20);
5712 %}
5713 ins_pipe(pipe_class_default);
5714 %}
5715
5716 // Optimize DecodeN for disjoint base.
5717 // Load base of compressed oops into a register
5718 instruct loadBase(iRegLdst dst) %{
5719 effect(DEF dst);
5720
5721 format %{ "LoadConst $dst, heapbase" %}
5722 ins_encode %{
5723 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0);
5724 %}
5725 ins_pipe(pipe_class_default);
5726 %}
5727
5728 // Loading ConN must be postalloc expanded so that edges between
5729 // the nodes are safe. They may not interfere with a safepoint.
5730 // GL TODO: This needs three instructions: better put this into the constant pool.
5731 instruct loadConN_Ex(iRegNdst dst, immN src) %{
5732 match(Set dst src);
5733 ins_cost(DEFAULT_COST*2);
5734
5735 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5736 postalloc_expand %{
5737 MachNode *m1 = new loadConN_hiNode();
5738 MachNode *m2 = new loadConN_loNode();
5739 MachNode *m3 = new clearMs32bNode();
5740 m1->_bottom_type = bottom_type();
5741 m2->_bottom_type = bottom_type();
5742 m3->_bottom_type = bottom_type();
5743 m1->add_req(nullptr);
5744 m2->add_req(nullptr, m1);
5745 m3->add_req(nullptr, m2);
5746 m1->_opnds[0] = op_dst;
5747 m1->_opnds[1] = op_src;
5748 m2->_opnds[0] = op_dst;
5749 m2->_opnds[1] = op_dst;
5750 m2->_opnds[2] = op_src;
5751 m3->_opnds[0] = op_dst;
5752 m3->_opnds[1] = op_dst;
5753 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5754 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5755 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5756 nodes->push(m1);
5757 nodes->push(m2);
5758 nodes->push(m3);
5759 %}
5760 %}
5761
5762 // We have seen a safepoint between the hi and lo parts, and this node was handled
5763 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is
5764 // not a narrow oop.
5765 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
5766 match(Set dst src);
5767 effect(DEF dst, USE src);
5768 ins_cost(DEFAULT_COST);
5769
5770 format %{ "LIS $dst, $src \t// narrow klass hi" %}
5771 size(4);
5772 ins_encode %{
5773 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant);
5774 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
5775 %}
5776 ins_pipe(pipe_class_default);
5777 %}
5778
5779 // As loadConNKlass_hi this must be recognized as narrow klass, not oop!
5780 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5781 match(Set dst src1);
5782 effect(TEMP src2);
5783 ins_cost(DEFAULT_COST);
5784
5785 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
5786 size(4);
5787 ins_encode %{
5788 __ clrldi($dst$$Register, $src2$$Register, 0x20);
5789 %}
5790 ins_pipe(pipe_class_default);
5791 %}
5792
5793 // This needs a match rule so that build_oop_map knows this is
5794 // not a narrow oop.
5795 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5796 match(Set dst src1);
5797 effect(TEMP src2);
5798 ins_cost(DEFAULT_COST);
5799
5800 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
5801 size(4);
5802 ins_encode %{
5803 // Notify OOP recorder (don't need the relocation)
5804 AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant);
5805 intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value());
5806 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
5807 %}
5808 ins_pipe(pipe_class_default);
5809 %}
5810
5811 // Loading ConNKlass must be postalloc expanded so that edges between
5812 // the nodes are safe. They may not interfere with a safepoint.
5813 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
5814 match(Set dst src);
5815 ins_cost(DEFAULT_COST*2);
5816
5817 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5818 postalloc_expand %{
5819 // Load high bits into register. Sign extended.
5820 MachNode *m1 = new loadConNKlass_hiNode();
5821 m1->_bottom_type = bottom_type();
5822 m1->add_req(nullptr);
5823 m1->_opnds[0] = op_dst;
5824 m1->_opnds[1] = op_src;
5825 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5826 nodes->push(m1);
5827
5828 MachNode *m2 = m1;
5829 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) {
5830 // Value might be 1-extended. Mask out these bits.
5831 m2 = new loadConNKlass_maskNode();
5832 m2->_bottom_type = bottom_type();
5833 m2->add_req(nullptr, m1);
5834 m2->_opnds[0] = op_dst;
5835 m2->_opnds[1] = op_src;
5836 m2->_opnds[2] = op_dst;
5837 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5838 nodes->push(m2);
5839 }
5840
5841 MachNode *m3 = new loadConNKlass_loNode();
5842 m3->_bottom_type = bottom_type();
5843 m3->add_req(nullptr, m2);
5844 m3->_opnds[0] = op_dst;
5845 m3->_opnds[1] = op_src;
5846 m3->_opnds[2] = op_dst;
5847 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5848 nodes->push(m3);
5849 %}
5850 %}
5851
5852 // 0x1 is used in object initialization (initial object header).
5853 // No constant pool entries required.
5854 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
5855 match(Set dst src);
5856
5857 format %{ "LI $dst, $src \t// ptr" %}
5858 size(4);
5859 ins_encode %{
5860 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5861 %}
5862 ins_pipe(pipe_class_default);
5863 %}
5864
5865 // Expand node for constant pool load: small offset.
5866 // The match rule is needed to generate the correct bottom_type(),
5867 // however this node should never match. The use of predicate is not
5868 // possible since ADLC forbids predicates for chain rules. The higher
5869 // costs do not prevent matching in this case. For that reason the
5870 // operand immP_NM with predicate(false) is used.
5871 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{
5872 match(Set dst src);
5873 effect(TEMP toc);
5874
5875 ins_num_consts(1);
5876
5877 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %}
5878 size(4);
5879 ins_encode( enc_load_long_constP(dst, src, toc) );
5880 ins_pipe(pipe_class_memory);
5881 %}
5882
5883 // Expand node for constant pool load: large offset.
5884 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{
5885 effect(DEF dst, USE src, USE toc);
5886 predicate(false);
5887
5888 ins_num_consts(1);
5889 ins_field_const_toc_offset(int);
5890
5891 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %}
5892 size(4);
5893 ins_encode( enc_load_long_constP_hi(dst, src, toc) );
5894 ins_pipe(pipe_class_default);
5895 %}
5896
5897 // Expand node for constant pool load: large offset.
5898 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
5899 match(Set dst src);
5900 effect(TEMP base);
5901
5902 ins_field_const_toc_offset_hi_node(loadConP_hiNode*);
5903
5904 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
5905 size(4);
5906 ins_encode %{
5907 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5908 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5909 %}
5910 ins_pipe(pipe_class_memory);
5911 %}
5912
5913 // Load pointer constant from constant table. Expand in case an
5914 // offset > 16 bit is needed.
5915 // Adlc adds toc node MachConstantTableBase.
5916 instruct loadConP_Ex(iRegPdst dst, immP src) %{
5917 match(Set dst src);
5918 ins_cost(MEMORY_REF_COST);
5919
5920 // This rule does not use "expand" because then
5921 // the result type is not known to be an Oop. An ADLC
5922 // enhancement will be needed to make that work - not worth it!
5923
5924 // If this instruction rematerializes, it prolongs the live range
5925 // of the toc node, causing illegal graphs.
5926 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule().
5927 ins_cannot_rematerialize(true);
5928
5929 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %}
5930 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) );
5931 %}
5932
5933 // Expand node for constant pool load: small offset.
5934 instruct loadConF(regF dst, immF src, iRegLdst toc) %{
5935 effect(DEF dst, USE src, USE toc);
5936 ins_cost(MEMORY_REF_COST);
5937
5938 ins_num_consts(1);
5939
5940 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %}
5941 size(4);
5942 ins_encode %{
5943 address float_address = __ float_constant($src$$constant);
5944 if (float_address == nullptr) {
5945 ciEnv::current()->record_out_of_memory_failure();
5946 return;
5947 }
5948 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register);
5949 %}
5950 ins_pipe(pipe_class_memory);
5951 %}
5952
5953 // Expand node for constant pool load: large offset.
5954 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
5955 effect(DEF dst, USE src, USE toc);
5956 ins_cost(MEMORY_REF_COST);
5957
5958 ins_num_consts(1);
5959
5960 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
5961 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t"
5962 "ADDIS $toc, $toc, -offset_hi"%}
5963 size(12);
5964 ins_encode %{
5965 FloatRegister Rdst = $dst$$FloatRegister;
5966 Register Rtoc = $toc$$Register;
5967 address float_address = __ float_constant($src$$constant);
5968 if (float_address == nullptr) {
5969 ciEnv::current()->record_out_of_memory_failure();
5970 return;
5971 }
5972 int offset = __ offset_to_method_toc(float_address);
5973 int hi = (offset + (1<<15))>>16;
5974 int lo = offset - hi * (1<<16);
5975
5976 __ addis(Rtoc, Rtoc, hi);
5977 __ lfs(Rdst, lo, Rtoc);
5978 __ addis(Rtoc, Rtoc, -hi);
5979 %}
5980 ins_pipe(pipe_class_memory);
5981 %}
5982
5983 // Adlc adds toc node MachConstantTableBase.
5984 instruct loadConF_Ex(regF dst, immF src) %{
5985 match(Set dst src);
5986 ins_cost(MEMORY_REF_COST);
5987
5988 // See loadConP.
5989 ins_cannot_rematerialize(true);
5990
5991 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
5992 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) );
5993 %}
5994
5995 // Expand node for constant pool load: small offset.
5996 instruct loadConD(regD dst, immD src, iRegLdst toc) %{
5997 effect(DEF dst, USE src, USE toc);
5998 ins_cost(MEMORY_REF_COST);
5999
6000 ins_num_consts(1);
6001
6002 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %}
6003 size(4);
6004 ins_encode %{
6005 address float_address = __ double_constant($src$$constant);
6006 if (float_address == nullptr) {
6007 ciEnv::current()->record_out_of_memory_failure();
6008 return;
6009 }
6010 int offset = __ offset_to_method_toc(float_address);
6011 __ lfd($dst$$FloatRegister, offset, $toc$$Register);
6012 %}
6013 ins_pipe(pipe_class_memory);
6014 %}
6015
6016 // Expand node for constant pool load: large offset.
6017 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
6018 effect(DEF dst, USE src, USE toc);
6019 ins_cost(MEMORY_REF_COST);
6020
6021 ins_num_consts(1);
6022
6023 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6024 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t"
6025 "ADDIS $toc, $toc, -offset_hi" %}
6026 size(12);
6027 ins_encode %{
6028 FloatRegister Rdst = $dst$$FloatRegister;
6029 Register Rtoc = $toc$$Register;
6030 address float_address = __ double_constant($src$$constant);
6031 if (float_address == nullptr) {
6032 ciEnv::current()->record_out_of_memory_failure();
6033 return;
6034 }
6035 int offset = __ offset_to_method_toc(float_address);
6036 int hi = (offset + (1<<15))>>16;
6037 int lo = offset - hi * (1<<16);
6038
6039 __ addis(Rtoc, Rtoc, hi);
6040 __ lfd(Rdst, lo, Rtoc);
6041 __ addis(Rtoc, Rtoc, -hi);
6042 %}
6043 ins_pipe(pipe_class_memory);
6044 %}
6045
6046 // Adlc adds toc node MachConstantTableBase.
6047 instruct loadConD_Ex(regD dst, immD src) %{
6048 match(Set dst src);
6049 ins_cost(MEMORY_REF_COST);
6050
6051 // See loadConP.
6052 ins_cannot_rematerialize(true);
6053
6054 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6055 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) );
6056 %}
6057
6058 // Prefetch instructions.
6059 // Must be safe to execute with invalid address (cannot fault).
6060
6061 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
6062 match(PrefetchAllocation (AddP mem src));
6063 ins_cost(MEMORY_REF_COST);
6064
6065 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
6066 size(4);
6067 ins_encode %{
6068 __ dcbtst($src$$Register, $mem$$base$$Register);
6069 %}
6070 ins_pipe(pipe_class_memory);
6071 %}
6072
6073 instruct prefetch_alloc_no_offset(indirectMemory mem) %{
6074 match(PrefetchAllocation mem);
6075 ins_cost(MEMORY_REF_COST);
6076
6077 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
6078 size(4);
6079 ins_encode %{
6080 __ dcbtst($mem$$base$$Register);
6081 %}
6082 ins_pipe(pipe_class_memory);
6083 %}
6084
6085 //----------Store Instructions-------------------------------------------------
6086
6087 // Store Byte
6088 instruct storeB(memory mem, iRegIsrc src) %{
6089 match(Set mem (StoreB mem src));
6090 ins_cost(MEMORY_REF_COST);
6091
6092 format %{ "STB $src, $mem \t// byte" %}
6093 size(4);
6094 ins_encode %{
6095 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6096 __ stb($src$$Register, Idisp, $mem$$base$$Register);
6097 %}
6098 ins_pipe(pipe_class_memory);
6099 %}
6100
6101 // Store Char/Short
6102 instruct storeC(memory mem, iRegIsrc src) %{
6103 match(Set mem (StoreC mem src));
6104 ins_cost(MEMORY_REF_COST);
6105
6106 format %{ "STH $src, $mem \t// short" %}
6107 size(4);
6108 ins_encode %{
6109 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6110 __ sth($src$$Register, Idisp, $mem$$base$$Register);
6111 %}
6112 ins_pipe(pipe_class_memory);
6113 %}
6114
6115 // Store Integer
6116 instruct storeI(memory mem, iRegIsrc src) %{
6117 match(Set mem (StoreI mem src));
6118 ins_cost(MEMORY_REF_COST);
6119
6120 format %{ "STW $src, $mem" %}
6121 size(4);
6122 ins_encode( enc_stw(src, mem) );
6123 ins_pipe(pipe_class_memory);
6124 %}
6125
6126 // ConvL2I + StoreI.
6127 instruct storeI_convL2I(memory mem, iRegLsrc src) %{
6128 match(Set mem (StoreI mem (ConvL2I src)));
6129 ins_cost(MEMORY_REF_COST);
6130
6131 format %{ "STW l2i($src), $mem" %}
6132 size(4);
6133 ins_encode( enc_stw(src, mem) );
6134 ins_pipe(pipe_class_memory);
6135 %}
6136
6137 // Store Long
6138 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{
6139 match(Set mem (StoreL mem src));
6140 ins_cost(MEMORY_REF_COST);
6141
6142 format %{ "STD $src, $mem \t// long" %}
6143 size(4);
6144 ins_encode( enc_std(src, mem) );
6145 ins_pipe(pipe_class_memory);
6146 %}
6147
6148 // Store super word nodes.
6149
6150 // Store Aligned Packed Byte long register to memory
6151 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{
6152 predicate(n->as_StoreVector()->memory_size() == 8);
6153 match(Set mem (StoreVector mem src));
6154 ins_cost(MEMORY_REF_COST);
6155
6156 format %{ "STD $mem, $src \t// packed8B" %}
6157 size(4);
6158 ins_encode( enc_std(src, mem) );
6159 ins_pipe(pipe_class_memory);
6160 %}
6161
6162
6163 instruct storeV16(memoryAlg16 mem, vecX src) %{
6164 predicate(n->as_StoreVector()->memory_size() == 16);
6165 match(Set mem (StoreVector mem src));
6166 ins_cost(MEMORY_REF_COST);
6167
6168 format %{ "STXV $mem, $src \t// store 16-byte Vector" %}
6169 size(4);
6170 ins_encode %{
6171 __ stxv($src$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
6172 %}
6173 ins_pipe(pipe_class_default);
6174 %}
6175
6176 // Reinterpret: only one vector size used: either L or X
6177 instruct reinterpretL(iRegLdst dst) %{
6178 match(Set dst (VectorReinterpret dst));
6179 ins_cost(0);
6180 format %{ "reinterpret $dst" %}
6181 size(0);
6182 ins_encode( /*empty*/ );
6183 ins_pipe(pipe_class_empty);
6184 %}
6185
6186 instruct reinterpretX(vecX dst) %{
6187 match(Set dst (VectorReinterpret dst));
6188 ins_cost(0);
6189 format %{ "reinterpret $dst" %}
6190 size(0);
6191 ins_encode( /*empty*/ );
6192 ins_pipe(pipe_class_empty);
6193 %}
6194
6195 // Store Compressed Oop
6196 instruct storeN(memory dst, iRegN_P2N src) %{
6197 match(Set dst (StoreN dst src));
6198 predicate(n->as_Store()->barrier_data() == 0);
6199 ins_cost(MEMORY_REF_COST);
6200
6201 format %{ "STW $src, $dst \t// compressed oop" %}
6202 size(4);
6203 ins_encode( enc_stw(src, dst) );
6204 ins_pipe(pipe_class_memory);
6205 %}
6206
6207 // Store Compressed KLass
6208 instruct storeNKlass(memory dst, iRegN_P2N src) %{
6209 match(Set dst (StoreNKlass dst src));
6210 ins_cost(MEMORY_REF_COST);
6211
6212 format %{ "STW $src, $dst \t// compressed klass" %}
6213 size(4);
6214 ins_encode( enc_stw(src, dst) );
6215 ins_pipe(pipe_class_memory);
6216 %}
6217
6218 // Store Pointer
6219 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{
6220 match(Set dst (StoreP dst src));
6221 predicate(n->as_Store()->barrier_data() == 0);
6222 ins_cost(MEMORY_REF_COST);
6223
6224 format %{ "STD $src, $dst \t// ptr" %}
6225 size(4);
6226 ins_encode( enc_std(src, dst) );
6227 ins_pipe(pipe_class_memory);
6228 %}
6229
6230 // Store Float
6231 instruct storeF(memory mem, regF src) %{
6232 match(Set mem (StoreF mem src));
6233 ins_cost(MEMORY_REF_COST);
6234
6235 format %{ "STFS $src, $mem" %}
6236 size(4);
6237 ins_encode( enc_stfs(src, mem) );
6238 ins_pipe(pipe_class_memory);
6239 %}
6240
6241 // Store Double
6242 instruct storeD(memory mem, regD src) %{
6243 match(Set mem (StoreD mem src));
6244 ins_cost(MEMORY_REF_COST);
6245
6246 format %{ "STFD $src, $mem" %}
6247 size(4);
6248 ins_encode( enc_stfd(src, mem) );
6249 ins_pipe(pipe_class_memory);
6250 %}
6251
6252 // Convert oop pointer into compressed form.
6253
6254 // Nodes for postalloc expand.
6255
6256 // Shift node for expand.
6257 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
6258 // The match rule is needed to make it a 'MachTypeNode'!
6259 match(Set dst (EncodeP src));
6260 predicate(false);
6261
6262 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6263 size(4);
6264 ins_encode %{
6265 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6266 %}
6267 ins_pipe(pipe_class_default);
6268 %}
6269
6270 // Add node for expand.
6271 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6272 // The match rule is needed to make it a 'MachTypeNode'!
6273 match(Set dst (EncodeP src));
6274 predicate(false);
6275
6276 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6277 ins_encode %{
6278 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6279 %}
6280 ins_pipe(pipe_class_default);
6281 %}
6282
6283 // Conditional sub base.
6284 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6285 // The match rule is needed to make it a 'MachTypeNode'!
6286 match(Set dst (EncodeP (Binary crx src1)));
6287 predicate(false);
6288
6289 format %{ "BEQ $crx, done\n\t"
6290 "SUB $dst, $src1, heapbase \t// encode: subtract base if != nullptr\n"
6291 "done:" %}
6292 ins_encode %{
6293 Label done;
6294 __ beq($crx$$CondRegister, done);
6295 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0);
6296 __ bind(done);
6297 %}
6298 ins_pipe(pipe_class_default);
6299 %}
6300
6301 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6302 // The match rule is needed to make it a 'MachTypeNode'!
6303 match(Set dst (EncodeP (Binary crx src1)));
6304 predicate(false);
6305
6306 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6307 size(4);
6308 ins_encode %{
6309 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6310 %}
6311 ins_pipe(pipe_class_default);
6312 %}
6313
6314 // Disjoint narrow oop base.
6315 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6316 match(Set dst (EncodeP src));
6317 predicate(CompressedOops::base_disjoint());
6318
6319 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6320 size(4);
6321 ins_encode %{
6322 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32);
6323 %}
6324 ins_pipe(pipe_class_default);
6325 %}
6326
6327 // shift != 0, base != 0
6328 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6329 match(Set dst (EncodeP src));
6330 effect(TEMP crx);
6331 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6332 CompressedOops::shift() != 0 &&
6333 CompressedOops::base_overlaps());
6334
6335 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6336 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6337 %}
6338
6339 // shift != 0, base != 0
6340 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6341 match(Set dst (EncodeP src));
6342 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6343 CompressedOops::shift() != 0 &&
6344 CompressedOops::base_overlaps());
6345
6346 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6347 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6348 %}
6349
6350 // shift != 0, base == 0
6351 // TODO: This is the same as encodeP_shift. Merge!
6352 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6353 match(Set dst (EncodeP src));
6354 predicate(CompressedOops::shift() != 0 &&
6355 CompressedOops::base() == nullptr);
6356
6357 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != nullptr" %}
6358 size(4);
6359 ins_encode %{
6360 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6361 %}
6362 ins_pipe(pipe_class_default);
6363 %}
6364
6365 // Compressed OOPs with narrow_oop_shift == 0.
6366 // shift == 0, base == 0
6367 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
6368 match(Set dst (EncodeP src));
6369 predicate(CompressedOops::shift() == 0);
6370
6371 format %{ "MR $dst, $src \t// Ptr->Narrow" %}
6372 // variable size, 0 or 4.
6373 ins_encode %{
6374 __ mr_if_needed($dst$$Register, $src$$Register);
6375 %}
6376 ins_pipe(pipe_class_default);
6377 %}
6378
6379 // Decode nodes.
6380
6381 // Shift node for expand.
6382 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6383 // The match rule is needed to make it a 'MachTypeNode'!
6384 match(Set dst (DecodeN src));
6385 predicate(false);
6386
6387 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6388 size(4);
6389 ins_encode %{
6390 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6391 %}
6392 ins_pipe(pipe_class_default);
6393 %}
6394
6395 // Add node for expand.
6396 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6397 // The match rule is needed to make it a 'MachTypeNode'!
6398 match(Set dst (DecodeN src));
6399 predicate(false);
6400
6401 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %}
6402 ins_encode %{
6403 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6404 %}
6405 ins_pipe(pipe_class_default);
6406 %}
6407
6408 // conditianal add base for expand
6409 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6410 // The match rule is needed to make it a 'MachTypeNode'!
6411 // NOTICE that the rule is nonsense - we just have to make sure that:
6412 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6413 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6414 match(Set dst (DecodeN (Binary crx src)));
6415 predicate(false);
6416
6417 format %{ "BEQ $crx, done\n\t"
6418 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != nullptr\n"
6419 "done:" %}
6420 ins_encode %{
6421 Label done;
6422 __ beq($crx$$CondRegister, done);
6423 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6424 __ bind(done);
6425 %}
6426 ins_pipe(pipe_class_default);
6427 %}
6428
6429 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6430 // The match rule is needed to make it a 'MachTypeNode'!
6431 // NOTICE that the rule is nonsense - we just have to make sure that:
6432 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6433 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6434 match(Set dst (DecodeN (Binary crx src1)));
6435 predicate(false);
6436
6437 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6438 size(4);
6439 ins_encode %{
6440 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6441 %}
6442 ins_pipe(pipe_class_default);
6443 %}
6444
6445 // shift != 0, base != 0
6446 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6447 match(Set dst (DecodeN src));
6448 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6449 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6450 CompressedOops::shift() != 0 &&
6451 CompressedOops::base() != nullptr);
6452 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6453 effect(TEMP crx);
6454
6455 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6456 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6457 %}
6458
6459 // shift != 0, base == 0
6460 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6461 match(Set dst (DecodeN src));
6462 predicate(CompressedOops::shift() != 0 &&
6463 CompressedOops::base() == nullptr);
6464
6465 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %}
6466 size(4);
6467 ins_encode %{
6468 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6469 %}
6470 ins_pipe(pipe_class_default);
6471 %}
6472
6473 // Optimize DecodeN for disjoint base.
6474 // Shift narrow oop and or it into register that already contains the heap base.
6475 // Base == dst must hold, and is assured by construction in postaloc_expand.
6476 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6477 match(Set dst (DecodeN src));
6478 effect(TEMP base);
6479 predicate(false);
6480
6481 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6482 size(4);
6483 ins_encode %{
6484 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift());
6485 %}
6486 ins_pipe(pipe_class_default);
6487 %}
6488
6489 // Optimize DecodeN for disjoint base.
6490 // This node requires only one cycle on the critical path.
6491 // We must postalloc_expand as we can not express use_def effects where
6492 // the used register is L and the def'ed register P.
6493 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6494 match(Set dst (DecodeN src));
6495 effect(TEMP_DEF dst);
6496 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6497 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6498 CompressedOops::base_disjoint());
6499 ins_cost(DEFAULT_COST);
6500
6501 format %{ "MOV $dst, heapbase \t\n"
6502 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6503 postalloc_expand %{
6504 loadBaseNode *n1 = new loadBaseNode();
6505 n1->add_req(nullptr);
6506 n1->_opnds[0] = op_dst;
6507
6508 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6509 n2->add_req(n_region, n_src, n1);
6510 n2->_opnds[0] = op_dst;
6511 n2->_opnds[1] = op_src;
6512 n2->_opnds[2] = op_dst;
6513 n2->_bottom_type = _bottom_type;
6514
6515 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6516 ra_->set_oop(n2, true);
6517
6518 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6519 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6520
6521 nodes->push(n1);
6522 nodes->push(n2);
6523 %}
6524 %}
6525
6526 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6527 match(Set dst (DecodeN src));
6528 effect(TEMP_DEF dst, TEMP crx);
6529 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6530 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6531 CompressedOops::base_disjoint());
6532 ins_cost(3 * DEFAULT_COST);
6533
6534 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %}
6535 postalloc_expand %{
6536 loadBaseNode *n1 = new loadBaseNode();
6537 n1->add_req(nullptr);
6538 n1->_opnds[0] = op_dst;
6539
6540 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
6541 n_compare->add_req(n_region, n_src);
6542 n_compare->_opnds[0] = op_crx;
6543 n_compare->_opnds[1] = op_src;
6544 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6545
6546 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6547 n2->add_req(n_region, n_src, n1);
6548 n2->_opnds[0] = op_dst;
6549 n2->_opnds[1] = op_src;
6550 n2->_opnds[2] = op_dst;
6551 n2->_bottom_type = _bottom_type;
6552
6553 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6554 n_cond_set->add_req(n_region, n_compare, n2);
6555 n_cond_set->_opnds[0] = op_dst;
6556 n_cond_set->_opnds[1] = op_crx;
6557 n_cond_set->_opnds[2] = op_dst;
6558 n_cond_set->_bottom_type = _bottom_type;
6559
6560 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6561 ra_->set_oop(n_cond_set, true);
6562
6563 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6564 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
6565 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6566 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6567
6568 nodes->push(n1);
6569 nodes->push(n_compare);
6570 nodes->push(n2);
6571 nodes->push(n_cond_set);
6572 %}
6573 %}
6574
6575 // src != 0, shift != 0, base != 0
6576 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6577 match(Set dst (DecodeN src));
6578 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6579 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6580 CompressedOops::shift() != 0 &&
6581 CompressedOops::base() != nullptr);
6582 ins_cost(2 * DEFAULT_COST);
6583
6584 format %{ "DecodeN $dst, $src \t// $src != nullptr, postalloc expanded" %}
6585 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6586 %}
6587
6588 // Compressed OOPs with narrow_oop_shift == 0.
6589 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6590 match(Set dst (DecodeN src));
6591 predicate(CompressedOops::shift() == 0);
6592 ins_cost(DEFAULT_COST);
6593
6594 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %}
6595 // variable size, 0 or 4.
6596 ins_encode %{
6597 __ mr_if_needed($dst$$Register, $src$$Register);
6598 %}
6599 ins_pipe(pipe_class_default);
6600 %}
6601
6602 // Convert compressed oop into int for vectors alignment masking.
6603 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
6604 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6605 predicate(CompressedOops::shift() == 0);
6606 ins_cost(DEFAULT_COST);
6607
6608 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %}
6609 // variable size, 0 or 4.
6610 ins_encode %{
6611 __ mr_if_needed($dst$$Register, $src$$Register);
6612 %}
6613 ins_pipe(pipe_class_default);
6614 %}
6615
6616 // Convert klass pointer into compressed form.
6617
6618 // Nodes for postalloc expand.
6619
6620 // Shift node for expand.
6621 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
6622 // The match rule is needed to make it a 'MachTypeNode'!
6623 match(Set dst (EncodePKlass src));
6624 predicate(false);
6625
6626 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6627 size(4);
6628 ins_encode %{
6629 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6630 %}
6631 ins_pipe(pipe_class_default);
6632 %}
6633
6634 // Add node for expand.
6635 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6636 // The match rule is needed to make it a 'MachTypeNode'!
6637 match(Set dst (EncodePKlass (Binary base src)));
6638 predicate(false);
6639
6640 format %{ "SUB $dst, $base, $src \t// encode" %}
6641 size(4);
6642 ins_encode %{
6643 __ subf($dst$$Register, $base$$Register, $src$$Register);
6644 %}
6645 ins_pipe(pipe_class_default);
6646 %}
6647
6648 // Disjoint narrow oop base.
6649 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
6650 match(Set dst (EncodePKlass src));
6651 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/);
6652
6653 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6654 size(4);
6655 ins_encode %{
6656 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
6657 %}
6658 ins_pipe(pipe_class_default);
6659 %}
6660
6661 // shift != 0, base != 0
6662 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6663 match(Set dst (EncodePKlass (Binary base src)));
6664 predicate(false);
6665
6666 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6667 postalloc_expand %{
6668 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
6669 n1->add_req(n_region, n_base, n_src);
6670 n1->_opnds[0] = op_dst;
6671 n1->_opnds[1] = op_base;
6672 n1->_opnds[2] = op_src;
6673 n1->_bottom_type = _bottom_type;
6674
6675 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode();
6676 n2->add_req(n_region, n1);
6677 n2->_opnds[0] = op_dst;
6678 n2->_opnds[1] = op_dst;
6679 n2->_bottom_type = _bottom_type;
6680 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6681 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6682
6683 nodes->push(n1);
6684 nodes->push(n2);
6685 %}
6686 %}
6687
6688 // shift != 0, base != 0
6689 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
6690 match(Set dst (EncodePKlass src));
6691 //predicate(CompressedKlassPointers::shift() != 0 &&
6692 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/);
6693
6694 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6695 ins_cost(DEFAULT_COST*2); // Don't count constant.
6696 expand %{
6697 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %}
6698 iRegLdst base;
6699 loadConL_Ex(base, baseImm);
6700 encodePKlass_not_null_Ex(dst, base, src);
6701 %}
6702 %}
6703
6704 // Decode nodes.
6705
6706 // Shift node for expand.
6707 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
6708 // The match rule is needed to make it a 'MachTypeNode'!
6709 match(Set dst (DecodeNKlass src));
6710 predicate(false);
6711
6712 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %}
6713 size(4);
6714 ins_encode %{
6715 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6716 %}
6717 ins_pipe(pipe_class_default);
6718 %}
6719
6720 // Add node for expand.
6721
6722 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6723 // The match rule is needed to make it a 'MachTypeNode'!
6724 match(Set dst (DecodeNKlass (Binary base src)));
6725 predicate(false);
6726
6727 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
6728 size(4);
6729 ins_encode %{
6730 __ add($dst$$Register, $base$$Register, $src$$Register);
6731 %}
6732 ins_pipe(pipe_class_default);
6733 %}
6734
6735 // src != 0, shift != 0, base != 0
6736 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
6737 match(Set dst (DecodeNKlass (Binary base src)));
6738 //effect(kill src); // We need a register for the immediate result after shifting.
6739 predicate(false);
6740
6741 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != nullptr, postalloc expanded" %}
6742 postalloc_expand %{
6743 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode();
6744 n1->add_req(n_region, n_base, n_src);
6745 n1->_opnds[0] = op_dst;
6746 n1->_opnds[1] = op_base;
6747 n1->_opnds[2] = op_src;
6748 n1->_bottom_type = _bottom_type;
6749
6750 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode();
6751 n2->add_req(n_region, n1);
6752 n2->_opnds[0] = op_dst;
6753 n2->_opnds[1] = op_dst;
6754 n2->_bottom_type = _bottom_type;
6755
6756 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6757 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6758
6759 nodes->push(n1);
6760 nodes->push(n2);
6761 %}
6762 %}
6763
6764 // src != 0, shift != 0, base != 0
6765 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
6766 match(Set dst (DecodeNKlass src));
6767 // predicate(CompressedKlassPointers::shift() != 0 &&
6768 // CompressedKlassPointers::base() != 0);
6769
6770 //format %{ "DecodeNKlass $dst, $src \t// $src != nullptr, expanded" %}
6771
6772 ins_cost(DEFAULT_COST*2); // Don't count constant.
6773 expand %{
6774 // We add first, then we shift. Like this, we can get along with one register less.
6775 // But we have to load the base pre-shifted.
6776 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %}
6777 iRegLdst base;
6778 loadConL_Ex(base, baseImm);
6779 decodeNKlass_notNull_addBase_Ex(dst, base, src);
6780 %}
6781 %}
6782
6783 //----------MemBar Instructions-----------------------------------------------
6784 // Memory barrier flavors
6785
6786 instruct membar_acquire() %{
6787 match(LoadFence);
6788 ins_cost(4*MEMORY_REF_COST);
6789
6790 format %{ "MEMBAR-acquire" %}
6791 size(4);
6792 ins_encode %{
6793 __ acquire();
6794 %}
6795 ins_pipe(pipe_class_default);
6796 %}
6797
6798 instruct unnecessary_membar_acquire() %{
6799 match(MemBarAcquire);
6800 ins_cost(0);
6801
6802 format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
6803 size(0);
6804 ins_encode( /*empty*/ );
6805 ins_pipe(pipe_class_default);
6806 %}
6807
6808 instruct membar_acquire_lock() %{
6809 match(MemBarAcquireLock);
6810 ins_cost(0);
6811
6812 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
6813 size(0);
6814 ins_encode( /*empty*/ );
6815 ins_pipe(pipe_class_default);
6816 %}
6817
6818 instruct membar_release() %{
6819 match(MemBarRelease);
6820 match(StoreFence);
6821 ins_cost(4*MEMORY_REF_COST);
6822
6823 format %{ "MEMBAR-release" %}
6824 size(4);
6825 ins_encode %{
6826 __ release();
6827 %}
6828 ins_pipe(pipe_class_default);
6829 %}
6830
6831 instruct membar_storestore() %{
6832 match(MemBarStoreStore);
6833 match(StoreStoreFence);
6834 ins_cost(4*MEMORY_REF_COST);
6835
6836 format %{ "MEMBAR-store-store" %}
6837 size(4);
6838 ins_encode %{
6839 __ membar(Assembler::StoreStore);
6840 %}
6841 ins_pipe(pipe_class_default);
6842 %}
6843
6844 instruct membar_release_lock() %{
6845 match(MemBarReleaseLock);
6846 ins_cost(0);
6847
6848 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
6849 size(0);
6850 ins_encode( /*empty*/ );
6851 ins_pipe(pipe_class_default);
6852 %}
6853
6854 instruct membar_storeload() %{
6855 match(MemBarStoreLoad);
6856 ins_cost(4*MEMORY_REF_COST);
6857
6858 format %{ "MEMBAR-store-load" %}
6859 size(4);
6860 ins_encode %{
6861 __ fence();
6862 %}
6863 ins_pipe(pipe_class_default);
6864 %}
6865
6866 instruct membar_volatile() %{
6867 match(MemBarVolatile);
6868 ins_cost(4*MEMORY_REF_COST);
6869
6870 format %{ "MEMBAR-volatile" %}
6871 size(4);
6872 ins_encode %{
6873 __ fence();
6874 %}
6875 ins_pipe(pipe_class_default);
6876 %}
6877
6878 // This optimization is wrong on PPC. The following pattern is not supported:
6879 // MemBarVolatile
6880 // ^ ^
6881 // | |
6882 // CtrlProj MemProj
6883 // ^ ^
6884 // | |
6885 // | Load
6886 // |
6887 // MemBarVolatile
6888 //
6889 // The first MemBarVolatile could get optimized out! According to
6890 // Vladimir, this pattern can not occur on Oracle platforms.
6891 // However, it does occur on PPC64 (because of membars in
6892 // inline_unsafe_load_store).
6893 //
6894 // Add this node again if we found a good solution for inline_unsafe_load_store().
6895 // Don't forget to look at the implementation of post_store_load_barrier again,
6896 // we did other fixes in that method.
6897 //instruct unnecessary_membar_volatile() %{
6898 // match(MemBarVolatile);
6899 // predicate(Matcher::post_store_load_barrier(n));
6900 // ins_cost(0);
6901 //
6902 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
6903 // size(0);
6904 // ins_encode( /*empty*/ );
6905 // ins_pipe(pipe_class_default);
6906 //%}
6907
6908 instruct membar_full() %{
6909 match(MemBarFull);
6910 ins_cost(4*MEMORY_REF_COST);
6911
6912 format %{ "MEMBAR-full" %}
6913 size(4);
6914 ins_encode %{
6915 __ fence();
6916 %}
6917 ins_pipe(pipe_class_default);
6918 %}
6919
6920 instruct membar_CPUOrder() %{
6921 match(MemBarCPUOrder);
6922 ins_cost(0);
6923
6924 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
6925 size(0);
6926 ins_encode( /*empty*/ );
6927 ins_pipe(pipe_class_default);
6928 %}
6929
6930 //----------Conditional Move---------------------------------------------------
6931
6932 // Cmove using isel.
6933 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
6934 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
6935 ins_cost(DEFAULT_COST);
6936
6937 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6938 size(4);
6939 ins_encode %{
6940 int cc = $cmp$$cmpcode;
6941 __ isel($dst$$Register, $crx$$CondRegister,
6942 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6943 %}
6944 ins_pipe(pipe_class_default);
6945 %}
6946
6947 // Cmove using isel.
6948 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
6949 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
6950 ins_cost(DEFAULT_COST);
6951
6952 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6953 size(4);
6954 ins_encode %{
6955 int cc = $cmp$$cmpcode;
6956 __ isel($dst$$Register, $crx$$CondRegister,
6957 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6958 %}
6959 ins_pipe(pipe_class_default);
6960 %}
6961
6962 // Cmove using isel.
6963 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
6964 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
6965 ins_cost(DEFAULT_COST);
6966
6967 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6968 size(4);
6969 ins_encode %{
6970 int cc = $cmp$$cmpcode;
6971 __ isel($dst$$Register, $crx$$CondRegister,
6972 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6973 %}
6974 ins_pipe(pipe_class_default);
6975 %}
6976
6977 // Cmove using isel.
6978 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
6979 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
6980 ins_cost(DEFAULT_COST);
6981
6982 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6983 size(4);
6984 ins_encode %{
6985 int cc = $cmp$$cmpcode;
6986 __ isel($dst$$Register, $crx$$CondRegister,
6987 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6988 %}
6989 ins_pipe(pipe_class_default);
6990 %}
6991
6992 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
6993 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
6994 ins_cost(DEFAULT_COST+BRANCH_COST);
6995
6996 ins_variable_size_depending_on_alignment(true);
6997
6998 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
6999 size(8);
7000 ins_encode %{
7001 Label done;
7002 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7003 // Branch if not (cmp crx).
7004 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7005 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7006 __ bind(done);
7007 %}
7008 ins_pipe(pipe_class_default);
7009 %}
7010
7011 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7012 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7013 ins_cost(DEFAULT_COST+BRANCH_COST);
7014
7015 ins_variable_size_depending_on_alignment(true);
7016
7017 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7018 size(8);
7019 ins_encode %{
7020 Label done;
7021 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7022 // Branch if not (cmp crx).
7023 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7024 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7025 __ bind(done);
7026 %}
7027 ins_pipe(pipe_class_default);
7028 %}
7029
7030 instruct cmovF_cmpF(cmpOp cop, regF op1, regF op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7031 match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7032 predicate(PowerArchitecturePPC64 >= 9);
7033 effect(TEMP tmp);
7034 ins_cost(2*DEFAULT_COST);
7035 format %{ "cmovF_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7036 size(8);
7037 ins_encode %{
7038 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7039 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7040 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7041 $tmp$$FloatRegister->to_vsr());
7042 %}
7043 ins_pipe(pipe_class_default);
7044 %}
7045
7046 instruct cmovF_cmpD(cmpOp cop, regD op1, regD op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7047 match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7048 predicate(PowerArchitecturePPC64 >= 9);
7049 effect(TEMP tmp);
7050 ins_cost(2*DEFAULT_COST);
7051 format %{ "cmovF_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7052 size(8);
7053 ins_encode %{
7054 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7055 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7056 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7057 $tmp$$FloatRegister->to_vsr());
7058 %}
7059 ins_pipe(pipe_class_default);
7060 %}
7061
7062 instruct cmovD_cmpD(cmpOp cop, regD op1, regD op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7063 match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7064 predicate(PowerArchitecturePPC64 >= 9);
7065 effect(TEMP tmp);
7066 ins_cost(2*DEFAULT_COST);
7067 format %{ "cmovD_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7068 size(8);
7069 ins_encode %{
7070 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7071 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7072 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7073 $tmp$$FloatRegister->to_vsr());
7074 %}
7075 ins_pipe(pipe_class_default);
7076 %}
7077
7078 instruct cmovD_cmpF(cmpOp cop, regF op1, regF op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7079 match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7080 predicate(PowerArchitecturePPC64 >= 9);
7081 effect(TEMP tmp);
7082 ins_cost(2*DEFAULT_COST);
7083 format %{ "cmovD_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7084 size(8);
7085 ins_encode %{
7086 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7087 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7088 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7089 $tmp$$FloatRegister->to_vsr());
7090 %}
7091 ins_pipe(pipe_class_default);
7092 %}
7093
7094 //----------Compare-And-Swap---------------------------------------------------
7095
7096 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7097 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7098 // matched.
7099
7100 // Strong versions:
7101
7102 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7103 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7104 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7105 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7106 ins_encode %{
7107 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7108 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7109 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7110 $res$$Register, nullptr, true);
7111 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7112 __ isync();
7113 } else {
7114 __ sync();
7115 }
7116 %}
7117 ins_pipe(pipe_class_default);
7118 %}
7119
7120 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7121 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7122 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7123 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7124 ins_encode %{
7125 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7126 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7127 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7128 $res$$Register, nullptr, true);
7129 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7130 __ isync();
7131 } else {
7132 __ sync();
7133 }
7134 %}
7135 ins_pipe(pipe_class_default);
7136 %}
7137
7138 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7139 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7140 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7141 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7142 ins_encode %{
7143 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7144 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7145 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7146 $res$$Register, nullptr, true);
7147 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7148 __ isync();
7149 } else {
7150 __ sync();
7151 }
7152 %}
7153 ins_pipe(pipe_class_default);
7154 %}
7155
7156 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7157 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7158 predicate(n->as_LoadStore()->barrier_data() == 0);
7159 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7160 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7161 ins_encode %{
7162 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7163 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7164 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7165 $res$$Register, nullptr, true);
7166 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7167 __ isync();
7168 } else {
7169 __ sync();
7170 }
7171 %}
7172 ins_pipe(pipe_class_default);
7173 %}
7174
7175 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7176 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7177 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7178 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7179 ins_encode %{
7180 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7181 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7182 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7183 $res$$Register, nullptr, true);
7184 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7185 __ isync();
7186 } else {
7187 __ sync();
7188 }
7189 %}
7190 ins_pipe(pipe_class_default);
7191 %}
7192
7193 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7194 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7195 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7196 predicate(n->as_LoadStore()->barrier_data() == 0);
7197 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7198 ins_encode %{
7199 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7200 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7201 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7202 $res$$Register, nullptr, true);
7203 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7204 __ isync();
7205 } else {
7206 __ sync();
7207 }
7208 %}
7209 ins_pipe(pipe_class_default);
7210 %}
7211
7212 // Weak versions:
7213
7214 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7215 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7216 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7217 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7218 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7219 ins_encode %{
7220 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7221 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7222 MacroAssembler::MemBarNone,
7223 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7224 %}
7225 ins_pipe(pipe_class_default);
7226 %}
7227
7228 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7229 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7230 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) );
7231 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7232 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7233 ins_encode %{
7234 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7235 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7236 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7237 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7238 %}
7239 ins_pipe(pipe_class_default);
7240 %}
7241
7242 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7243 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7244 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7245 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7246 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7247 ins_encode %{
7248 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7249 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7250 MacroAssembler::MemBarNone,
7251 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7252 %}
7253 ins_pipe(pipe_class_default);
7254 %}
7255
7256 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7257 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7258 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7259 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7260 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7261 ins_encode %{
7262 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7263 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7264 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7265 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7266 %}
7267 ins_pipe(pipe_class_default);
7268 %}
7269
7270 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7271 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7272 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7273 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7274 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7275 ins_encode %{
7276 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7277 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7278 MacroAssembler::MemBarNone,
7279 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7280 %}
7281 ins_pipe(pipe_class_default);
7282 %}
7283
7284 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7285 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7286 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7287 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7288 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7289 ins_encode %{
7290 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7291 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7292 // value is never passed to caller.
7293 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7294 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7295 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7296 %}
7297 ins_pipe(pipe_class_default);
7298 %}
7299
7300 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7301 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7302 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7303 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7304 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7305 ins_encode %{
7306 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7307 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7308 MacroAssembler::MemBarNone,
7309 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7310 %}
7311 ins_pipe(pipe_class_default);
7312 %}
7313
7314 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7315 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7316 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7317 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7318 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7319 ins_encode %{
7320 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7321 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7322 // value is never passed to caller.
7323 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7324 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7325 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7326 %}
7327 ins_pipe(pipe_class_default);
7328 %}
7329
7330 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7331 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7332 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7333 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7334 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7335 ins_encode %{
7336 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7337 // value is never passed to caller.
7338 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7339 MacroAssembler::MemBarNone,
7340 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7341 %}
7342 ins_pipe(pipe_class_default);
7343 %}
7344
7345 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7346 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7347 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7348 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7349 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7350 ins_encode %{
7351 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7352 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7353 // value is never passed to caller.
7354 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7355 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7356 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7357 %}
7358 ins_pipe(pipe_class_default);
7359 %}
7360
7361 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7362 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7363 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7364 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7365 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7366 ins_encode %{
7367 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7368 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7369 MacroAssembler::MemBarNone,
7370 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7371 %}
7372 ins_pipe(pipe_class_default);
7373 %}
7374
7375 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7376 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7377 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7378 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7379 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7380 ins_encode %{
7381 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7382 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7383 // value is never passed to caller.
7384 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7385 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7386 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7387 %}
7388 ins_pipe(pipe_class_default);
7389 %}
7390
7391 // CompareAndExchange
7392
7393 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7394 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7395 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7396 effect(TEMP_DEF res, TEMP cr0);
7397 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7398 ins_encode %{
7399 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7400 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7401 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7402 noreg, nullptr, true);
7403 %}
7404 ins_pipe(pipe_class_default);
7405 %}
7406
7407 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7408 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7409 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7410 effect(TEMP_DEF res, TEMP cr0);
7411 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7412 ins_encode %{
7413 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7414 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7415 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7416 noreg, nullptr, true);
7417 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7418 __ isync();
7419 } else {
7420 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7421 __ sync();
7422 }
7423 %}
7424 ins_pipe(pipe_class_default);
7425 %}
7426
7427
7428 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7429 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7430 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7431 effect(TEMP_DEF res, TEMP cr0);
7432 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7433 ins_encode %{
7434 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7435 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7436 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7437 noreg, nullptr, true);
7438 %}
7439 ins_pipe(pipe_class_default);
7440 %}
7441
7442 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7443 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7444 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7445 effect(TEMP_DEF res, TEMP cr0);
7446 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7447 ins_encode %{
7448 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7449 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7450 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7451 noreg, nullptr, true);
7452 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7453 __ isync();
7454 } else {
7455 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7456 __ sync();
7457 }
7458 %}
7459 ins_pipe(pipe_class_default);
7460 %}
7461
7462 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7463 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7464 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7465 effect(TEMP_DEF res, TEMP cr0);
7466 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
7467 ins_encode %{
7468 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7469 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7470 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7471 noreg, nullptr, true);
7472 %}
7473 ins_pipe(pipe_class_default);
7474 %}
7475
7476 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7477 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7478 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7479 effect(TEMP_DEF res, TEMP cr0);
7480 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
7481 ins_encode %{
7482 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7483 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7484 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7485 noreg, nullptr, true);
7486 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7487 __ isync();
7488 } else {
7489 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7490 __ sync();
7491 }
7492 %}
7493 ins_pipe(pipe_class_default);
7494 %}
7495
7496 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7497 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7498 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7499 effect(TEMP_DEF res, TEMP cr0);
7500 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7501 ins_encode %{
7502 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7503 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7504 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7505 noreg, nullptr, true);
7506 %}
7507 ins_pipe(pipe_class_default);
7508 %}
7509
7510 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7511 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7512 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7513 effect(TEMP_DEF res, TEMP cr0);
7514 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7515 ins_encode %{
7516 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7517 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7518 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7519 noreg, nullptr, true);
7520 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7521 __ isync();
7522 } else {
7523 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7524 __ sync();
7525 }
7526 %}
7527 ins_pipe(pipe_class_default);
7528 %}
7529
7530 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7531 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7532 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7533 effect(TEMP_DEF res, TEMP cr0);
7534 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
7535 ins_encode %{
7536 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7537 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7538 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7539 noreg, nullptr, true);
7540 %}
7541 ins_pipe(pipe_class_default);
7542 %}
7543
7544 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7545 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7546 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7547 effect(TEMP_DEF res, TEMP cr0);
7548 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
7549 ins_encode %{
7550 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7551 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7552 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7553 noreg, nullptr, true);
7554 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7555 __ isync();
7556 } else {
7557 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7558 __ sync();
7559 }
7560 %}
7561 ins_pipe(pipe_class_default);
7562 %}
7563
7564 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7565 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7566 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst)
7567 && n->as_LoadStore()->barrier_data() == 0);
7568 effect(TEMP_DEF res, TEMP cr0);
7569 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7570 ins_encode %{
7571 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7572 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7573 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7574 noreg, nullptr, true);
7575 %}
7576 ins_pipe(pipe_class_default);
7577 %}
7578
7579 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7580 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7581 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst)
7582 && n->as_LoadStore()->barrier_data() == 0);
7583 effect(TEMP_DEF res, TEMP cr0);
7584 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7585 ins_encode %{
7586 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7587 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7588 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7589 noreg, nullptr, true);
7590 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7591 __ isync();
7592 } else {
7593 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7594 __ sync();
7595 }
7596 %}
7597 ins_pipe(pipe_class_default);
7598 %}
7599
7600 // Special RMW
7601
7602 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7603 match(Set res (GetAndAddB mem_ptr src));
7604 effect(TEMP_DEF res, TEMP cr0);
7605 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
7606 ins_encode %{
7607 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
7608 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7609 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7610 __ isync();
7611 } else {
7612 __ sync();
7613 }
7614 %}
7615 ins_pipe(pipe_class_default);
7616 %}
7617
7618 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7619 match(Set res (GetAndAddS mem_ptr src));
7620 effect(TEMP_DEF res, TEMP cr0);
7621 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
7622 ins_encode %{
7623 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
7624 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7625 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7626 __ isync();
7627 } else {
7628 __ sync();
7629 }
7630 %}
7631 ins_pipe(pipe_class_default);
7632 %}
7633
7634
7635 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7636 match(Set res (GetAndAddI mem_ptr src));
7637 effect(TEMP_DEF res, TEMP cr0);
7638 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
7639 ins_encode %{
7640 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
7641 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7642 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7643 __ isync();
7644 } else {
7645 __ sync();
7646 }
7647 %}
7648 ins_pipe(pipe_class_default);
7649 %}
7650
7651 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7652 match(Set res (GetAndAddL mem_ptr src));
7653 effect(TEMP_DEF res, TEMP cr0);
7654 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
7655 ins_encode %{
7656 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
7657 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7658 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7659 __ isync();
7660 } else {
7661 __ sync();
7662 }
7663 %}
7664 ins_pipe(pipe_class_default);
7665 %}
7666
7667 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7668 match(Set res (GetAndSetB mem_ptr src));
7669 effect(TEMP_DEF res, TEMP cr0);
7670 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
7671 ins_encode %{
7672 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
7673 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7674 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7675 __ isync();
7676 } else {
7677 __ sync();
7678 }
7679 %}
7680 ins_pipe(pipe_class_default);
7681 %}
7682
7683 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7684 match(Set res (GetAndSetS mem_ptr src));
7685 effect(TEMP_DEF res, TEMP cr0);
7686 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
7687 ins_encode %{
7688 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
7689 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7690 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7691 __ isync();
7692 } else {
7693 __ sync();
7694 }
7695 %}
7696 ins_pipe(pipe_class_default);
7697 %}
7698
7699
7700 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7701 match(Set res (GetAndSetI mem_ptr src));
7702 effect(TEMP_DEF res, TEMP cr0);
7703 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
7704 ins_encode %{
7705 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7706 MacroAssembler::cmpxchgx_hint_atomic_update());
7707 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7708 __ isync();
7709 } else {
7710 __ sync();
7711 }
7712 %}
7713 ins_pipe(pipe_class_default);
7714 %}
7715
7716 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7717 match(Set res (GetAndSetL mem_ptr src));
7718 effect(TEMP_DEF res, TEMP cr0);
7719 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
7720 ins_encode %{
7721 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7722 MacroAssembler::cmpxchgx_hint_atomic_update());
7723 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7724 __ isync();
7725 } else {
7726 __ sync();
7727 }
7728 %}
7729 ins_pipe(pipe_class_default);
7730 %}
7731
7732 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
7733 match(Set res (GetAndSetP mem_ptr src));
7734 predicate(n->as_LoadStore()->barrier_data() == 0);
7735 effect(TEMP_DEF res, TEMP cr0);
7736 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
7737 ins_encode %{
7738 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7739 MacroAssembler::cmpxchgx_hint_atomic_update());
7740 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7741 __ isync();
7742 } else {
7743 __ sync();
7744 }
7745 %}
7746 ins_pipe(pipe_class_default);
7747 %}
7748
7749 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
7750 match(Set res (GetAndSetN mem_ptr src));
7751 predicate(n->as_LoadStore()->barrier_data() == 0);
7752 effect(TEMP_DEF res, TEMP cr0);
7753 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
7754 ins_encode %{
7755 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7756 MacroAssembler::cmpxchgx_hint_atomic_update());
7757 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7758 __ isync();
7759 } else {
7760 __ sync();
7761 }
7762 %}
7763 ins_pipe(pipe_class_default);
7764 %}
7765
7766 //----------Arithmetic Instructions--------------------------------------------
7767 // Addition Instructions
7768
7769 // Register Addition
7770 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
7771 match(Set dst (AddI src1 src2));
7772 format %{ "ADD $dst, $src1, $src2" %}
7773 size(4);
7774 ins_encode %{
7775 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7776 %}
7777 ins_pipe(pipe_class_default);
7778 %}
7779
7780 // Expand does not work with above instruct. (??)
7781 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7782 // no match-rule
7783 effect(DEF dst, USE src1, USE src2);
7784 format %{ "ADD $dst, $src1, $src2" %}
7785 size(4);
7786 ins_encode %{
7787 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7788 %}
7789 ins_pipe(pipe_class_default);
7790 %}
7791
7792 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
7793 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
7794 ins_cost(DEFAULT_COST*3);
7795
7796 expand %{
7797 // FIXME: we should do this in the ideal world.
7798 iRegIdst tmp1;
7799 iRegIdst tmp2;
7800 addI_reg_reg(tmp1, src1, src2);
7801 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
7802 addI_reg_reg(dst, tmp1, tmp2);
7803 %}
7804 %}
7805
7806 // Immediate Addition
7807 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
7808 match(Set dst (AddI src1 src2));
7809 format %{ "ADDI $dst, $src1, $src2" %}
7810 size(4);
7811 ins_encode %{
7812 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7813 %}
7814 ins_pipe(pipe_class_default);
7815 %}
7816
7817 // Immediate Addition with 16-bit shifted operand
7818 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
7819 match(Set dst (AddI src1 src2));
7820 format %{ "ADDIS $dst, $src1, $src2" %}
7821 size(4);
7822 ins_encode %{
7823 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7824 %}
7825 ins_pipe(pipe_class_default);
7826 %}
7827
7828 // Immediate Addition using prefixed addi
7829 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{
7830 match(Set dst (AddI src1 src2));
7831 predicate(PowerArchitecturePPC64 >= 10);
7832 ins_cost(DEFAULT_COST+1);
7833 format %{ "PADDI $dst, $src1, $src2" %}
7834 size(8);
7835 ins_encode %{
7836 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7837 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7838 %}
7839 ins_pipe(pipe_class_default);
7840 ins_alignment(2);
7841 %}
7842
7843 // Long Addition
7844 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7845 match(Set dst (AddL src1 src2));
7846 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7847 size(4);
7848 ins_encode %{
7849 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7850 %}
7851 ins_pipe(pipe_class_default);
7852 %}
7853
7854 // Expand does not work with above instruct. (??)
7855 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7856 // no match-rule
7857 effect(DEF dst, USE src1, USE src2);
7858 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7859 size(4);
7860 ins_encode %{
7861 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7862 %}
7863 ins_pipe(pipe_class_default);
7864 %}
7865
7866 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
7867 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
7868 ins_cost(DEFAULT_COST*3);
7869
7870 expand %{
7871 // FIXME: we should do this in the ideal world.
7872 iRegLdst tmp1;
7873 iRegLdst tmp2;
7874 addL_reg_reg(tmp1, src1, src2);
7875 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
7876 addL_reg_reg(dst, tmp1, tmp2);
7877 %}
7878 %}
7879
7880 // AddL + ConvL2I.
7881 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
7882 match(Set dst (ConvL2I (AddL src1 src2)));
7883
7884 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %}
7885 size(4);
7886 ins_encode %{
7887 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7888 %}
7889 ins_pipe(pipe_class_default);
7890 %}
7891
7892 // No constant pool entries required.
7893 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
7894 match(Set dst (AddL src1 src2));
7895
7896 format %{ "ADDI $dst, $src1, $src2" %}
7897 size(4);
7898 ins_encode %{
7899 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7900 %}
7901 ins_pipe(pipe_class_default);
7902 %}
7903
7904 // Long Immediate Addition with 16-bit shifted operand.
7905 // No constant pool entries required.
7906 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
7907 match(Set dst (AddL src1 src2));
7908
7909 format %{ "ADDIS $dst, $src1, $src2" %}
7910 size(4);
7911 ins_encode %{
7912 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7913 %}
7914 ins_pipe(pipe_class_default);
7915 %}
7916
7917 // Long Immediate Addition using prefixed addi
7918 // No constant pool entries required.
7919 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{
7920 match(Set dst (AddL src1 src2));
7921 predicate(PowerArchitecturePPC64 >= 10);
7922 ins_cost(DEFAULT_COST+1);
7923
7924 format %{ "PADDI $dst, $src1, $src2" %}
7925 size(8);
7926 ins_encode %{
7927 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7928 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7929 %}
7930 ins_pipe(pipe_class_default);
7931 ins_alignment(2);
7932 %}
7933
7934 // Pointer Register Addition
7935 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
7936 match(Set dst (AddP src1 src2));
7937 format %{ "ADD $dst, $src1, $src2" %}
7938 size(4);
7939 ins_encode %{
7940 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7941 %}
7942 ins_pipe(pipe_class_default);
7943 %}
7944
7945 // Pointer Immediate Addition
7946 // No constant pool entries required.
7947 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
7948 match(Set dst (AddP src1 src2));
7949
7950 format %{ "ADDI $dst, $src1, $src2" %}
7951 size(4);
7952 ins_encode %{
7953 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7954 %}
7955 ins_pipe(pipe_class_default);
7956 %}
7957
7958 // Pointer Immediate Addition with 16-bit shifted operand.
7959 // No constant pool entries required.
7960 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
7961 match(Set dst (AddP src1 src2));
7962
7963 format %{ "ADDIS $dst, $src1, $src2" %}
7964 size(4);
7965 ins_encode %{
7966 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7967 %}
7968 ins_pipe(pipe_class_default);
7969 %}
7970
7971 // Pointer Immediate Addition using prefixed addi
7972 // No constant pool entries required.
7973 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{
7974 match(Set dst (AddP src1 src2));
7975 predicate(PowerArchitecturePPC64 >= 10);
7976 ins_cost(DEFAULT_COST+1);
7977
7978 format %{ "PADDI $dst, $src1, $src2" %}
7979 size(8);
7980 ins_encode %{
7981 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7982 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7983 %}
7984 ins_pipe(pipe_class_default);
7985 ins_alignment(2);
7986 %}
7987
7988 //---------------------
7989 // Subtraction Instructions
7990
7991 // Register Subtraction
7992 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7993 match(Set dst (SubI src1 src2));
7994 format %{ "SUBF $dst, $src2, $src1" %}
7995 size(4);
7996 ins_encode %{
7997 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7998 %}
7999 ins_pipe(pipe_class_default);
8000 %}
8001
8002 // Immediate Subtraction
8003 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
8004 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
8005
8006 // SubI from constant (using subfic).
8007 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
8008 match(Set dst (SubI src1 src2));
8009 format %{ "SUBI $dst, $src1, $src2" %}
8010
8011 size(4);
8012 ins_encode %{
8013 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
8014 %}
8015 ins_pipe(pipe_class_default);
8016 %}
8017
8018 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
8019 // positive integers and 0xF...F for negative ones.
8020 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
8021 // no match-rule, false predicate
8022 effect(DEF dst, USE src);
8023 predicate(false);
8024
8025 format %{ "SRAWI $dst, $src, #31" %}
8026 size(4);
8027 ins_encode %{
8028 __ srawi($dst$$Register, $src$$Register, 0x1f);
8029 %}
8030 ins_pipe(pipe_class_default);
8031 %}
8032
8033 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
8034 match(Set dst (AbsI src));
8035 ins_cost(DEFAULT_COST*3);
8036
8037 expand %{
8038 iRegIdst tmp1;
8039 iRegIdst tmp2;
8040 signmask32I_regI(tmp1, src);
8041 xorI_reg_reg(tmp2, tmp1, src);
8042 subI_reg_reg(dst, tmp2, tmp1);
8043 %}
8044 %}
8045
8046 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
8047 match(Set dst (SubI zero src2));
8048 format %{ "NEG $dst, $src2" %}
8049 size(4);
8050 ins_encode %{
8051 __ neg($dst$$Register, $src2$$Register);
8052 %}
8053 ins_pipe(pipe_class_default);
8054 %}
8055
8056 // Long subtraction
8057 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8058 match(Set dst (SubL src1 src2));
8059 format %{ "SUBF $dst, $src2, $src1 \t// long" %}
8060 size(4);
8061 ins_encode %{
8062 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8063 %}
8064 ins_pipe(pipe_class_default);
8065 %}
8066
8067 // SubL + convL2I.
8068 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8069 match(Set dst (ConvL2I (SubL src1 src2)));
8070
8071 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
8072 size(4);
8073 ins_encode %{
8074 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8075 %}
8076 ins_pipe(pipe_class_default);
8077 %}
8078
8079 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8080 // positive longs and 0xF...F for negative ones.
8081 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8082 // no match-rule, false predicate
8083 effect(DEF dst, USE src);
8084 predicate(false);
8085
8086 format %{ "SRADI $dst, $src, #63" %}
8087 size(4);
8088 ins_encode %{
8089 __ sradi($dst$$Register, $src$$Register, 0x3f);
8090 %}
8091 ins_pipe(pipe_class_default);
8092 %}
8093
8094 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8095 // positive longs and 0xF...F for negative ones.
8096 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8097 // no match-rule, false predicate
8098 effect(DEF dst, USE src);
8099 predicate(false);
8100
8101 format %{ "SRADI $dst, $src, #63" %}
8102 size(4);
8103 ins_encode %{
8104 __ sradi($dst$$Register, $src$$Register, 0x3f);
8105 %}
8106 ins_pipe(pipe_class_default);
8107 %}
8108
8109 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{
8110 match(Set dst (AbsL src));
8111 ins_cost(DEFAULT_COST*3);
8112
8113 expand %{
8114 iRegLdst tmp1;
8115 iRegLdst tmp2;
8116 signmask64L_regL(tmp1, src);
8117 xorL_reg_reg(tmp2, tmp1, src);
8118 subL_reg_reg(dst, tmp2, tmp1);
8119 %}
8120 %}
8121
8122 // Long negation
8123 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8124 match(Set dst (SubL zero src2));
8125 format %{ "NEG $dst, $src2 \t// long" %}
8126 size(4);
8127 ins_encode %{
8128 __ neg($dst$$Register, $src2$$Register);
8129 %}
8130 ins_pipe(pipe_class_default);
8131 %}
8132
8133 // NegL + ConvL2I.
8134 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8135 match(Set dst (ConvL2I (SubL zero src2)));
8136
8137 format %{ "NEG $dst, $src2 \t// long + l2i" %}
8138 size(4);
8139 ins_encode %{
8140 __ neg($dst$$Register, $src2$$Register);
8141 %}
8142 ins_pipe(pipe_class_default);
8143 %}
8144
8145 // Multiplication Instructions
8146 // Integer Multiplication
8147
8148 // Register Multiplication
8149 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8150 match(Set dst (MulI src1 src2));
8151 ins_cost(DEFAULT_COST);
8152
8153 format %{ "MULLW $dst, $src1, $src2" %}
8154 size(4);
8155 ins_encode %{
8156 __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8157 %}
8158 ins_pipe(pipe_class_default);
8159 %}
8160
8161 // Immediate Multiplication
8162 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8163 match(Set dst (MulI src1 src2));
8164 ins_cost(DEFAULT_COST);
8165
8166 format %{ "MULLI $dst, $src1, $src2" %}
8167 size(4);
8168 ins_encode %{
8169 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8170 %}
8171 ins_pipe(pipe_class_default);
8172 %}
8173
8174 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8175 match(Set dst (MulL src1 src2));
8176 ins_cost(DEFAULT_COST);
8177
8178 format %{ "MULLD $dst $src1, $src2 \t// long" %}
8179 size(4);
8180 ins_encode %{
8181 __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8182 %}
8183 ins_pipe(pipe_class_default);
8184 %}
8185
8186 // Multiply high for optimized long division by constant.
8187 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8188 match(Set dst (MulHiL src1 src2));
8189 ins_cost(DEFAULT_COST);
8190
8191 format %{ "MULHD $dst $src1, $src2 \t// long" %}
8192 size(4);
8193 ins_encode %{
8194 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8195 %}
8196 ins_pipe(pipe_class_default);
8197 %}
8198
8199 instruct uMulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8200 match(Set dst (UMulHiL src1 src2));
8201 ins_cost(DEFAULT_COST);
8202
8203 format %{ "MULHDU $dst $src1, $src2 \t// unsigned long" %}
8204 size(4);
8205 ins_encode %{
8206 __ mulhdu($dst$$Register, $src1$$Register, $src2$$Register);
8207 %}
8208 ins_pipe(pipe_class_default);
8209 %}
8210
8211 // Immediate Multiplication
8212 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8213 match(Set dst (MulL src1 src2));
8214 ins_cost(DEFAULT_COST);
8215
8216 format %{ "MULLI $dst, $src1, $src2" %}
8217 size(4);
8218 ins_encode %{
8219 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8220 %}
8221 ins_pipe(pipe_class_default);
8222 %}
8223
8224 // Integer Division with Immediate -1: Negate.
8225 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8226 match(Set dst (DivI src1 src2));
8227 ins_cost(DEFAULT_COST);
8228
8229 format %{ "NEG $dst, $src1 \t// /-1" %}
8230 size(4);
8231 ins_encode %{
8232 __ neg($dst$$Register, $src1$$Register);
8233 %}
8234 ins_pipe(pipe_class_default);
8235 %}
8236
8237 // Integer Division with constant, but not -1.
8238 // We should be able to improve this by checking the type of src2.
8239 // It might well be that src2 is known to be positive.
8240 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8241 match(Set dst (DivI src1 src2));
8242 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8243 ins_cost(2*DEFAULT_COST);
8244
8245 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8246 size(4);
8247 ins_encode %{
8248 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8249 %}
8250 ins_pipe(pipe_class_default);
8251 %}
8252
8253 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8254 effect(USE_DEF dst, USE src1, USE crx);
8255 predicate(false);
8256
8257 ins_variable_size_depending_on_alignment(true);
8258
8259 format %{ "CMOVE $dst, neg($src1), $crx" %}
8260 size(8);
8261 ins_encode %{
8262 Label done;
8263 __ bne($crx$$CondRegister, done);
8264 __ neg($dst$$Register, $src1$$Register);
8265 __ bind(done);
8266 %}
8267 ins_pipe(pipe_class_default);
8268 %}
8269
8270 // Integer Division with Registers not containing constants.
8271 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8272 match(Set dst (DivI src1 src2));
8273 ins_cost(10*DEFAULT_COST);
8274
8275 expand %{
8276 immI16 imm %{ (int)-1 %}
8277 flagsReg tmp1;
8278 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8279 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8280 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8281 %}
8282 %}
8283
8284 // Long Division with Immediate -1: Negate.
8285 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8286 match(Set dst (DivL src1 src2));
8287 ins_cost(DEFAULT_COST);
8288
8289 format %{ "NEG $dst, $src1 \t// /-1, long" %}
8290 size(4);
8291 ins_encode %{
8292 __ neg($dst$$Register, $src1$$Register);
8293 %}
8294 ins_pipe(pipe_class_default);
8295 %}
8296
8297 // Long Division with constant, but not -1.
8298 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8299 match(Set dst (DivL src1 src2));
8300 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8301 ins_cost(2*DEFAULT_COST);
8302
8303 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8304 size(4);
8305 ins_encode %{
8306 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8307 %}
8308 ins_pipe(pipe_class_default);
8309 %}
8310
8311 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8312 effect(USE_DEF dst, USE src1, USE crx);
8313 predicate(false);
8314
8315 ins_variable_size_depending_on_alignment(true);
8316
8317 format %{ "CMOVE $dst, neg($src1), $crx" %}
8318 size(8);
8319 ins_encode %{
8320 Label done;
8321 __ bne($crx$$CondRegister, done);
8322 __ neg($dst$$Register, $src1$$Register);
8323 __ bind(done);
8324 %}
8325 ins_pipe(pipe_class_default);
8326 %}
8327
8328 // Long Division with Registers not containing constants.
8329 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8330 match(Set dst (DivL src1 src2));
8331 ins_cost(10*DEFAULT_COST);
8332
8333 expand %{
8334 immL16 imm %{ (int)-1 %}
8335 flagsReg tmp1;
8336 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8337 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8338 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8339 %}
8340 %}
8341
8342 // Integer Remainder with registers.
8343 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8344 match(Set dst (ModI src1 src2));
8345 ins_cost(10*DEFAULT_COST);
8346
8347 expand %{
8348 immI16 imm %{ (int)-1 %}
8349 flagsReg tmp1;
8350 iRegIdst tmp2;
8351 iRegIdst tmp3;
8352 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8353 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8354 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8355 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8356 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8357 %}
8358 %}
8359
8360 // Long Remainder with registers
8361 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8362 match(Set dst (ModL src1 src2));
8363 ins_cost(10*DEFAULT_COST);
8364
8365 expand %{
8366 immL16 imm %{ (int)-1 %}
8367 flagsReg tmp1;
8368 iRegLdst tmp2;
8369 iRegLdst tmp3;
8370 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8371 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8372 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8373 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8374 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8375 %}
8376 %}
8377
8378 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8379 match(Set dst (UDivI src1 src2));
8380 format %{ "DIVWU $dst, $src1, $src2" %}
8381 size(4);
8382 ins_encode %{
8383 __ divwu($dst$$Register, $src1$$Register, $src2$$Register);
8384 %}
8385 ins_pipe(pipe_class_default);
8386 %}
8387
8388 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8389 match(Set dst (UModI src1 src2));
8390 expand %{
8391 iRegIdst tmp1;
8392 iRegIdst tmp2;
8393 udivI_reg_reg(tmp1, src1, src2);
8394 // Compute lower 32 bit result using signed instructions as suggested by ISA.
8395 // Upper 32 bit will contain garbage.
8396 mulI_reg_reg(tmp2, src2, tmp1);
8397 subI_reg_reg(dst, src1, tmp2);
8398 %}
8399 %}
8400
8401 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8402 match(Set dst (UDivL src1 src2));
8403 format %{ "DIVDU $dst, $src1, $src2" %}
8404 size(4);
8405 ins_encode %{
8406 __ divdu($dst$$Register, $src1$$Register, $src2$$Register);
8407 %}
8408 ins_pipe(pipe_class_default);
8409 %}
8410
8411 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8412 match(Set dst (UModL src1 src2));
8413 expand %{
8414 iRegLdst tmp1;
8415 iRegLdst tmp2;
8416 udivL_reg_reg(tmp1, src1, src2);
8417 mulL_reg_reg(tmp2, src2, tmp1);
8418 subL_reg_reg(dst, src1, tmp2);
8419 %}
8420 %}
8421
8422 // Integer Shift Instructions
8423
8424 // Register Shift Left
8425
8426 // Clear all but the lowest #mask bits.
8427 // Used to normalize shift amounts in registers.
8428 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
8429 // no match-rule, false predicate
8430 effect(DEF dst, USE src, USE mask);
8431 predicate(false);
8432
8433 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %}
8434 size(4);
8435 ins_encode %{
8436 __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
8437 %}
8438 ins_pipe(pipe_class_default);
8439 %}
8440
8441 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8442 // no match-rule, false predicate
8443 effect(DEF dst, USE src1, USE src2);
8444 predicate(false);
8445
8446 format %{ "SLW $dst, $src1, $src2" %}
8447 size(4);
8448 ins_encode %{
8449 __ slw($dst$$Register, $src1$$Register, $src2$$Register);
8450 %}
8451 ins_pipe(pipe_class_default);
8452 %}
8453
8454 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8455 match(Set dst (LShiftI src1 src2));
8456 ins_cost(DEFAULT_COST*2);
8457 expand %{
8458 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8459 iRegIdst tmpI;
8460 maskI_reg_imm(tmpI, src2, mask);
8461 lShiftI_reg_reg(dst, src1, tmpI);
8462 %}
8463 %}
8464
8465 // Register Shift Left Immediate
8466 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8467 match(Set dst (LShiftI src1 src2));
8468
8469 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %}
8470 size(4);
8471 ins_encode %{
8472 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8473 %}
8474 ins_pipe(pipe_class_default);
8475 %}
8476
8477 // AndI with negpow2-constant + LShiftI
8478 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8479 match(Set dst (LShiftI (AndI src1 src2) src3));
8480 predicate(UseRotateAndMaskInstructionsPPC64);
8481
8482 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %}
8483 size(4);
8484 ins_encode %{
8485 long src3 = $src3$$constant;
8486 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8487 if (maskbits >= 32) {
8488 __ li($dst$$Register, 0); // addi
8489 } else {
8490 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
8491 }
8492 %}
8493 ins_pipe(pipe_class_default);
8494 %}
8495
8496 // RShiftI + AndI with negpow2-constant + LShiftI
8497 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8498 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
8499 predicate(UseRotateAndMaskInstructionsPPC64);
8500
8501 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
8502 size(4);
8503 ins_encode %{
8504 long src3 = $src3$$constant;
8505 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8506 if (maskbits >= 32) {
8507 __ li($dst$$Register, 0); // addi
8508 } else {
8509 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
8510 }
8511 %}
8512 ins_pipe(pipe_class_default);
8513 %}
8514
8515 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8516 // no match-rule, false predicate
8517 effect(DEF dst, USE src1, USE src2);
8518 predicate(false);
8519
8520 format %{ "SLD $dst, $src1, $src2" %}
8521 size(4);
8522 ins_encode %{
8523 __ sld($dst$$Register, $src1$$Register, $src2$$Register);
8524 %}
8525 ins_pipe(pipe_class_default);
8526 %}
8527
8528 // Register Shift Left
8529 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8530 match(Set dst (LShiftL src1 src2));
8531 ins_cost(DEFAULT_COST*2);
8532 expand %{
8533 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8534 iRegIdst tmpI;
8535 maskI_reg_imm(tmpI, src2, mask);
8536 lShiftL_regL_regI(dst, src1, tmpI);
8537 %}
8538 %}
8539
8540 // Register Shift Left Immediate
8541 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8542 match(Set dst (LShiftL src1 src2));
8543 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %}
8544 size(4);
8545 ins_encode %{
8546 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8547 %}
8548 ins_pipe(pipe_class_default);
8549 %}
8550
8551 // If we shift more than 32 bits, we need not convert I2L.
8552 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
8553 match(Set dst (LShiftL (ConvI2L src1) src2));
8554 ins_cost(DEFAULT_COST);
8555
8556 size(4);
8557 format %{ "SLDI $dst, i2l($src1), $src2" %}
8558 ins_encode %{
8559 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8560 %}
8561 ins_pipe(pipe_class_default);
8562 %}
8563
8564 // Shift a postivie int to the left.
8565 // Clrlsldi clears the upper 32 bits and shifts.
8566 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
8567 match(Set dst (LShiftL (ConvI2L src1) src2));
8568 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
8569
8570 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %}
8571 size(4);
8572 ins_encode %{
8573 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
8574 %}
8575 ins_pipe(pipe_class_default);
8576 %}
8577
8578 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8579 // no match-rule, false predicate
8580 effect(DEF dst, USE src1, USE src2);
8581 predicate(false);
8582
8583 format %{ "SRAW $dst, $src1, $src2" %}
8584 size(4);
8585 ins_encode %{
8586 __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
8587 %}
8588 ins_pipe(pipe_class_default);
8589 %}
8590
8591 // Register Arithmetic Shift Right
8592 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8593 match(Set dst (RShiftI src1 src2));
8594 ins_cost(DEFAULT_COST*2);
8595 expand %{
8596 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8597 iRegIdst tmpI;
8598 maskI_reg_imm(tmpI, src2, mask);
8599 arShiftI_reg_reg(dst, src1, tmpI);
8600 %}
8601 %}
8602
8603 // Register Arithmetic Shift Right Immediate
8604 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8605 match(Set dst (RShiftI src1 src2));
8606
8607 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %}
8608 size(4);
8609 ins_encode %{
8610 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8611 %}
8612 ins_pipe(pipe_class_default);
8613 %}
8614
8615 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8616 // no match-rule, false predicate
8617 effect(DEF dst, USE src1, USE src2);
8618 predicate(false);
8619
8620 format %{ "SRAD $dst, $src1, $src2" %}
8621 size(4);
8622 ins_encode %{
8623 __ srad($dst$$Register, $src1$$Register, $src2$$Register);
8624 %}
8625 ins_pipe(pipe_class_default);
8626 %}
8627
8628 // Register Shift Right Arithmetic Long
8629 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8630 match(Set dst (RShiftL src1 src2));
8631 ins_cost(DEFAULT_COST*2);
8632
8633 expand %{
8634 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8635 iRegIdst tmpI;
8636 maskI_reg_imm(tmpI, src2, mask);
8637 arShiftL_regL_regI(dst, src1, tmpI);
8638 %}
8639 %}
8640
8641 // Register Shift Right Immediate
8642 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8643 match(Set dst (RShiftL src1 src2));
8644
8645 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %}
8646 size(4);
8647 ins_encode %{
8648 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8649 %}
8650 ins_pipe(pipe_class_default);
8651 %}
8652
8653 // RShiftL + ConvL2I
8654 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8655 match(Set dst (ConvL2I (RShiftL src1 src2)));
8656
8657 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8658 size(4);
8659 ins_encode %{
8660 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8661 %}
8662 ins_pipe(pipe_class_default);
8663 %}
8664
8665 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8666 // no match-rule, false predicate
8667 effect(DEF dst, USE src1, USE src2);
8668 predicate(false);
8669
8670 format %{ "SRW $dst, $src1, $src2" %}
8671 size(4);
8672 ins_encode %{
8673 __ srw($dst$$Register, $src1$$Register, $src2$$Register);
8674 %}
8675 ins_pipe(pipe_class_default);
8676 %}
8677
8678 // Register Shift Right
8679 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8680 match(Set dst (URShiftI src1 src2));
8681 ins_cost(DEFAULT_COST*2);
8682
8683 expand %{
8684 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8685 iRegIdst tmpI;
8686 maskI_reg_imm(tmpI, src2, mask);
8687 urShiftI_reg_reg(dst, src1, tmpI);
8688 %}
8689 %}
8690
8691 // Register Shift Right Immediate
8692 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8693 match(Set dst (URShiftI src1 src2));
8694
8695 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %}
8696 size(4);
8697 ins_encode %{
8698 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8699 %}
8700 ins_pipe(pipe_class_default);
8701 %}
8702
8703 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8704 // no match-rule, false predicate
8705 effect(DEF dst, USE src1, USE src2);
8706 predicate(false);
8707
8708 format %{ "SRD $dst, $src1, $src2" %}
8709 size(4);
8710 ins_encode %{
8711 __ srd($dst$$Register, $src1$$Register, $src2$$Register);
8712 %}
8713 ins_pipe(pipe_class_default);
8714 %}
8715
8716 // Register Shift Right
8717 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8718 match(Set dst (URShiftL src1 src2));
8719 ins_cost(DEFAULT_COST*2);
8720
8721 expand %{
8722 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8723 iRegIdst tmpI;
8724 maskI_reg_imm(tmpI, src2, mask);
8725 urShiftL_regL_regI(dst, src1, tmpI);
8726 %}
8727 %}
8728
8729 // Register Shift Right Immediate
8730 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8731 match(Set dst (URShiftL src1 src2));
8732
8733 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %}
8734 size(4);
8735 ins_encode %{
8736 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8737 %}
8738 ins_pipe(pipe_class_default);
8739 %}
8740
8741 // URShiftL + ConvL2I.
8742 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8743 match(Set dst (ConvL2I (URShiftL src1 src2)));
8744
8745 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8746 size(4);
8747 ins_encode %{
8748 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8749 %}
8750 ins_pipe(pipe_class_default);
8751 %}
8752
8753 // Register Shift Right Immediate with a CastP2X
8754 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
8755 match(Set dst (URShiftL (CastP2X src1) src2));
8756
8757 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
8758 size(4);
8759 ins_encode %{
8760 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8761 %}
8762 ins_pipe(pipe_class_default);
8763 %}
8764
8765 // Bitfield Extract: URShiftI + AndI
8766 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
8767 match(Set dst (AndI (URShiftI src1 src2) src3));
8768
8769 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
8770 size(4);
8771 ins_encode %{
8772 int rshift = ($src2$$constant) & 0x1f;
8773 int length = log2i_exact((juint)$src3$$constant + 1u);
8774 if (rshift + length > 32) {
8775 // if necessary, adjust mask to omit rotated bits.
8776 length = 32 - rshift;
8777 }
8778 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8779 %}
8780 ins_pipe(pipe_class_default);
8781 %}
8782
8783 // Bitfield Extract: URShiftL + AndL
8784 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
8785 match(Set dst (AndL (URShiftL src1 src2) src3));
8786
8787 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
8788 size(4);
8789 ins_encode %{
8790 int rshift = ($src2$$constant) & 0x3f;
8791 int length = log2i_exact((julong)$src3$$constant + 1ull);
8792 if (rshift + length > 64) {
8793 // if necessary, adjust mask to omit rotated bits.
8794 length = 64 - rshift;
8795 }
8796 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8797 %}
8798 ins_pipe(pipe_class_default);
8799 %}
8800
8801 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
8802 match(Set dst (ConvL2I (ConvI2L src)));
8803
8804 format %{ "EXTSW $dst, $src \t// int->int" %}
8805 size(4);
8806 ins_encode %{
8807 __ extsw($dst$$Register, $src$$Register);
8808 %}
8809 ins_pipe(pipe_class_default);
8810 %}
8811
8812 //----------Rotate Instructions------------------------------------------------
8813
8814 // Rotate Left by 8-bit immediate
8815 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
8816 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
8817 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8818
8819 format %{ "ROTLWI $dst, $src, $lshift" %}
8820 size(4);
8821 ins_encode %{
8822 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
8823 %}
8824 ins_pipe(pipe_class_default);
8825 %}
8826
8827 // Rotate Right by 8-bit immediate
8828 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
8829 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
8830 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8831
8832 format %{ "ROTRWI $dst, $rshift" %}
8833 size(4);
8834 ins_encode %{
8835 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
8836 %}
8837 ins_pipe(pipe_class_default);
8838 %}
8839
8840 //----------Floating Point Arithmetic Instructions-----------------------------
8841
8842 // Add float single precision
8843 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
8844 match(Set dst (AddF src1 src2));
8845
8846 format %{ "FADDS $dst, $src1, $src2" %}
8847 size(4);
8848 ins_encode %{
8849 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8850 %}
8851 ins_pipe(pipe_class_default);
8852 %}
8853
8854 // Add float double precision
8855 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
8856 match(Set dst (AddD src1 src2));
8857
8858 format %{ "FADD $dst, $src1, $src2" %}
8859 size(4);
8860 ins_encode %{
8861 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8862 %}
8863 ins_pipe(pipe_class_default);
8864 %}
8865
8866 // Sub float single precision
8867 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
8868 match(Set dst (SubF src1 src2));
8869
8870 format %{ "FSUBS $dst, $src1, $src2" %}
8871 size(4);
8872 ins_encode %{
8873 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8874 %}
8875 ins_pipe(pipe_class_default);
8876 %}
8877
8878 // Sub float double precision
8879 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
8880 match(Set dst (SubD src1 src2));
8881 format %{ "FSUB $dst, $src1, $src2" %}
8882 size(4);
8883 ins_encode %{
8884 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8885 %}
8886 ins_pipe(pipe_class_default);
8887 %}
8888
8889 // Mul float single precision
8890 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
8891 match(Set dst (MulF src1 src2));
8892 format %{ "FMULS $dst, $src1, $src2" %}
8893 size(4);
8894 ins_encode %{
8895 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8896 %}
8897 ins_pipe(pipe_class_default);
8898 %}
8899
8900 // Mul float double precision
8901 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
8902 match(Set dst (MulD src1 src2));
8903 format %{ "FMUL $dst, $src1, $src2" %}
8904 size(4);
8905 ins_encode %{
8906 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8907 %}
8908 ins_pipe(pipe_class_default);
8909 %}
8910
8911 // Div float single precision
8912 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
8913 match(Set dst (DivF src1 src2));
8914 format %{ "FDIVS $dst, $src1, $src2" %}
8915 size(4);
8916 ins_encode %{
8917 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8918 %}
8919 ins_pipe(pipe_class_default);
8920 %}
8921
8922 // Div float double precision
8923 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
8924 match(Set dst (DivD src1 src2));
8925 format %{ "FDIV $dst, $src1, $src2" %}
8926 size(4);
8927 ins_encode %{
8928 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8929 %}
8930 ins_pipe(pipe_class_default);
8931 %}
8932
8933 // Absolute float single precision
8934 instruct absF_reg(regF dst, regF src) %{
8935 match(Set dst (AbsF src));
8936 format %{ "FABS $dst, $src \t// float" %}
8937 size(4);
8938 ins_encode %{
8939 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8940 %}
8941 ins_pipe(pipe_class_default);
8942 %}
8943
8944 // Absolute float double precision
8945 instruct absD_reg(regD dst, regD src) %{
8946 match(Set dst (AbsD src));
8947 format %{ "FABS $dst, $src \t// double" %}
8948 size(4);
8949 ins_encode %{
8950 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8951 %}
8952 ins_pipe(pipe_class_default);
8953 %}
8954
8955 instruct negF_reg(regF dst, regF src) %{
8956 match(Set dst (NegF src));
8957 format %{ "FNEG $dst, $src \t// float" %}
8958 size(4);
8959 ins_encode %{
8960 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8961 %}
8962 ins_pipe(pipe_class_default);
8963 %}
8964
8965 instruct negD_reg(regD dst, regD src) %{
8966 match(Set dst (NegD src));
8967 format %{ "FNEG $dst, $src \t// double" %}
8968 size(4);
8969 ins_encode %{
8970 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8971 %}
8972 ins_pipe(pipe_class_default);
8973 %}
8974
8975 // AbsF + NegF.
8976 instruct negF_absF_reg(regF dst, regF src) %{
8977 match(Set dst (NegF (AbsF src)));
8978 format %{ "FNABS $dst, $src \t// float" %}
8979 size(4);
8980 ins_encode %{
8981 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
8982 %}
8983 ins_pipe(pipe_class_default);
8984 %}
8985
8986 // AbsD + NegD.
8987 instruct negD_absD_reg(regD dst, regD src) %{
8988 match(Set dst (NegD (AbsD src)));
8989 format %{ "FNABS $dst, $src \t// double" %}
8990 size(4);
8991 ins_encode %{
8992 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
8993 %}
8994 ins_pipe(pipe_class_default);
8995 %}
8996
8997 // Sqrt float double precision
8998 instruct sqrtD_reg(regD dst, regD src) %{
8999 match(Set dst (SqrtD src));
9000 format %{ "FSQRT $dst, $src" %}
9001 size(4);
9002 ins_encode %{
9003 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
9004 %}
9005 ins_pipe(pipe_class_default);
9006 %}
9007
9008 // Single-precision sqrt.
9009 instruct sqrtF_reg(regF dst, regF src) %{
9010 match(Set dst (SqrtF src));
9011 ins_cost(DEFAULT_COST);
9012
9013 format %{ "FSQRTS $dst, $src" %}
9014 size(4);
9015 ins_encode %{
9016 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
9017 %}
9018 ins_pipe(pipe_class_default);
9019 %}
9020
9021
9022 // Multiply-Accumulate
9023 // src1 * src2 + src3
9024 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9025 match(Set dst (FmaF src3 (Binary src1 src2)));
9026
9027 format %{ "FMADDS $dst, $src1, $src2, $src3" %}
9028 size(4);
9029 ins_encode %{
9030 assert(UseFMA, "Needs FMA instructions support.");
9031 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9032 %}
9033 ins_pipe(pipe_class_default);
9034 %}
9035
9036 // src1 * src2 + src3
9037 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9038 match(Set dst (FmaD src3 (Binary src1 src2)));
9039
9040 format %{ "FMADD $dst, $src1, $src2, $src3" %}
9041 size(4);
9042 ins_encode %{
9043 assert(UseFMA, "Needs FMA instructions support.");
9044 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9045 %}
9046 ins_pipe(pipe_class_default);
9047 %}
9048
9049 // src1 * (-src2) + src3 = -(src1*src2-src3)
9050 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9051 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9052 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
9053
9054 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
9055 size(4);
9056 ins_encode %{
9057 assert(UseFMA, "Needs FMA instructions support.");
9058 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9059 %}
9060 ins_pipe(pipe_class_default);
9061 %}
9062
9063 // src1 * (-src2) + src3 = -(src1*src2-src3)
9064 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9065 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9066 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
9067
9068 format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
9069 size(4);
9070 ins_encode %{
9071 assert(UseFMA, "Needs FMA instructions support.");
9072 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9073 %}
9074 ins_pipe(pipe_class_default);
9075 %}
9076
9077 // src1 * (-src2) - src3 = -(src1*src2+src3)
9078 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9079 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9080 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
9081
9082 format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
9083 size(4);
9084 ins_encode %{
9085 assert(UseFMA, "Needs FMA instructions support.");
9086 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9087 %}
9088 ins_pipe(pipe_class_default);
9089 %}
9090
9091 // src1 * (-src2) - src3 = -(src1*src2+src3)
9092 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9093 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9094 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9095
9096 format %{ "FNMADD $dst, $src1, $src2, $src3" %}
9097 size(4);
9098 ins_encode %{
9099 assert(UseFMA, "Needs FMA instructions support.");
9100 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9101 %}
9102 ins_pipe(pipe_class_default);
9103 %}
9104
9105 // src1 * src2 - src3
9106 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9107 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9108
9109 format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
9110 size(4);
9111 ins_encode %{
9112 assert(UseFMA, "Needs FMA instructions support.");
9113 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9114 %}
9115 ins_pipe(pipe_class_default);
9116 %}
9117
9118 // src1 * src2 - src3
9119 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9120 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9121
9122 format %{ "FMSUB $dst, $src1, $src2, $src3" %}
9123 size(4);
9124 ins_encode %{
9125 assert(UseFMA, "Needs FMA instructions support.");
9126 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9127 %}
9128 ins_pipe(pipe_class_default);
9129 %}
9130
9131
9132 //----------Logical Instructions-----------------------------------------------
9133
9134 // And Instructions
9135
9136 // Register And
9137 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9138 match(Set dst (AndI src1 src2));
9139 format %{ "AND $dst, $src1, $src2" %}
9140 size(4);
9141 ins_encode %{
9142 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9143 %}
9144 ins_pipe(pipe_class_default);
9145 %}
9146
9147 // Left shifted Immediate And
9148 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{
9149 match(Set dst (AndI src1 src2));
9150 effect(KILL cr0);
9151 format %{ "ANDIS $dst, $src1, $src2.hi" %}
9152 size(4);
9153 ins_encode %{
9154 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16)));
9155 %}
9156 ins_pipe(pipe_class_default);
9157 %}
9158
9159 // Immediate And
9160 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{
9161 match(Set dst (AndI src1 src2));
9162 effect(KILL cr0);
9163
9164 format %{ "ANDI $dst, $src1, $src2" %}
9165 size(4);
9166 ins_encode %{
9167 // FIXME: avoid andi_ ?
9168 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9169 %}
9170 ins_pipe(pipe_class_default);
9171 %}
9172
9173 // Immediate And where the immediate is a negative power of 2.
9174 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{
9175 match(Set dst (AndI src1 src2));
9176 format %{ "ANDWI $dst, $src1, $src2" %}
9177 size(4);
9178 ins_encode %{
9179 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant));
9180 %}
9181 ins_pipe(pipe_class_default);
9182 %}
9183
9184 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{
9185 match(Set dst (AndI src1 src2));
9186 format %{ "ANDWI $dst, $src1, $src2" %}
9187 size(4);
9188 ins_encode %{
9189 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u));
9190 %}
9191 ins_pipe(pipe_class_default);
9192 %}
9193
9194 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{
9195 match(Set dst (AndI src1 src2));
9196 predicate(UseRotateAndMaskInstructionsPPC64);
9197 format %{ "ANDWI $dst, $src1, $src2" %}
9198 size(4);
9199 ins_encode %{
9200 int bitpos = 31 - log2i_exact((juint)$src2$$constant);
9201 __ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos);
9202 %}
9203 ins_pipe(pipe_class_default);
9204 %}
9205
9206 // Register And Long
9207 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9208 match(Set dst (AndL src1 src2));
9209 ins_cost(DEFAULT_COST);
9210
9211 format %{ "AND $dst, $src1, $src2 \t// long" %}
9212 size(4);
9213 ins_encode %{
9214 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9215 %}
9216 ins_pipe(pipe_class_default);
9217 %}
9218
9219 // Immediate And long
9220 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
9221 match(Set dst (AndL src1 src2));
9222 effect(KILL cr0);
9223
9224 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9225 size(4);
9226 ins_encode %{
9227 // FIXME: avoid andi_ ?
9228 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9229 %}
9230 ins_pipe(pipe_class_default);
9231 %}
9232
9233 // Immediate And Long where the immediate is a negative power of 2.
9234 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
9235 match(Set dst (AndL src1 src2));
9236 format %{ "ANDDI $dst, $src1, $src2" %}
9237 size(4);
9238 ins_encode %{
9239 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant));
9240 %}
9241 ins_pipe(pipe_class_default);
9242 %}
9243
9244 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9245 match(Set dst (AndL src1 src2));
9246 format %{ "ANDDI $dst, $src1, $src2" %}
9247 size(4);
9248 ins_encode %{
9249 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9250 %}
9251 ins_pipe(pipe_class_default);
9252 %}
9253
9254 // AndL + ConvL2I.
9255 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9256 match(Set dst (ConvL2I (AndL src1 src2)));
9257 ins_cost(DEFAULT_COST);
9258
9259 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %}
9260 size(4);
9261 ins_encode %{
9262 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9263 %}
9264 ins_pipe(pipe_class_default);
9265 %}
9266
9267 // Or Instructions
9268
9269 // Register Or
9270 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9271 match(Set dst (OrI src1 src2));
9272 format %{ "OR $dst, $src1, $src2" %}
9273 size(4);
9274 ins_encode %{
9275 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9276 %}
9277 ins_pipe(pipe_class_default);
9278 %}
9279
9280 // Expand does not work with above instruct. (??)
9281 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9282 // no match-rule
9283 effect(DEF dst, USE src1, USE src2);
9284 format %{ "OR $dst, $src1, $src2" %}
9285 size(4);
9286 ins_encode %{
9287 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9288 %}
9289 ins_pipe(pipe_class_default);
9290 %}
9291
9292 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9293 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9294 ins_cost(DEFAULT_COST*3);
9295
9296 expand %{
9297 // FIXME: we should do this in the ideal world.
9298 iRegIdst tmp1;
9299 iRegIdst tmp2;
9300 orI_reg_reg(tmp1, src1, src2);
9301 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9302 orI_reg_reg(dst, tmp1, tmp2);
9303 %}
9304 %}
9305
9306 // Immediate Or
9307 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9308 match(Set dst (OrI src1 src2));
9309 format %{ "ORI $dst, $src1, $src2" %}
9310 size(4);
9311 ins_encode %{
9312 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9313 %}
9314 ins_pipe(pipe_class_default);
9315 %}
9316
9317 // Register Or Long
9318 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9319 match(Set dst (OrL src1 src2));
9320 ins_cost(DEFAULT_COST);
9321
9322 size(4);
9323 format %{ "OR $dst, $src1, $src2 \t// long" %}
9324 ins_encode %{
9325 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9326 %}
9327 ins_pipe(pipe_class_default);
9328 %}
9329
9330 // OrL + ConvL2I.
9331 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9332 match(Set dst (ConvL2I (OrL src1 src2)));
9333 ins_cost(DEFAULT_COST);
9334
9335 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %}
9336 size(4);
9337 ins_encode %{
9338 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9339 %}
9340 ins_pipe(pipe_class_default);
9341 %}
9342
9343 // Immediate Or long
9344 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9345 match(Set dst (OrL src1 con));
9346 ins_cost(DEFAULT_COST);
9347
9348 format %{ "ORI $dst, $src1, $con \t// long" %}
9349 size(4);
9350 ins_encode %{
9351 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9352 %}
9353 ins_pipe(pipe_class_default);
9354 %}
9355
9356 // Xor Instructions
9357
9358 // Register Xor
9359 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9360 match(Set dst (XorI src1 src2));
9361 format %{ "XOR $dst, $src1, $src2" %}
9362 size(4);
9363 ins_encode %{
9364 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9365 %}
9366 ins_pipe(pipe_class_default);
9367 %}
9368
9369 // Expand does not work with above instruct. (??)
9370 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9371 // no match-rule
9372 effect(DEF dst, USE src1, USE src2);
9373 format %{ "XOR $dst, $src1, $src2" %}
9374 size(4);
9375 ins_encode %{
9376 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9377 %}
9378 ins_pipe(pipe_class_default);
9379 %}
9380
9381 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9382 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
9383 ins_cost(DEFAULT_COST*3);
9384
9385 expand %{
9386 // FIXME: we should do this in the ideal world.
9387 iRegIdst tmp1;
9388 iRegIdst tmp2;
9389 xorI_reg_reg(tmp1, src1, src2);
9390 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
9391 xorI_reg_reg(dst, tmp1, tmp2);
9392 %}
9393 %}
9394
9395 // Immediate Xor
9396 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9397 match(Set dst (XorI src1 src2));
9398 format %{ "XORI $dst, $src1, $src2" %}
9399 size(4);
9400 ins_encode %{
9401 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9402 %}
9403 ins_pipe(pipe_class_default);
9404 %}
9405
9406 // Register Xor Long
9407 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9408 match(Set dst (XorL src1 src2));
9409 ins_cost(DEFAULT_COST);
9410
9411 format %{ "XOR $dst, $src1, $src2 \t// long" %}
9412 size(4);
9413 ins_encode %{
9414 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9415 %}
9416 ins_pipe(pipe_class_default);
9417 %}
9418
9419 // XorL + ConvL2I.
9420 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9421 match(Set dst (ConvL2I (XorL src1 src2)));
9422 ins_cost(DEFAULT_COST);
9423
9424 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %}
9425 size(4);
9426 ins_encode %{
9427 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9428 %}
9429 ins_pipe(pipe_class_default);
9430 %}
9431
9432 // Immediate Xor Long
9433 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
9434 match(Set dst (XorL src1 src2));
9435 ins_cost(DEFAULT_COST);
9436
9437 format %{ "XORI $dst, $src1, $src2 \t// long" %}
9438 size(4);
9439 ins_encode %{
9440 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9441 %}
9442 ins_pipe(pipe_class_default);
9443 %}
9444
9445 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
9446 match(Set dst (XorI src1 src2));
9447 ins_cost(DEFAULT_COST);
9448
9449 format %{ "NOT $dst, $src1 ($src2)" %}
9450 size(4);
9451 ins_encode %{
9452 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9453 %}
9454 ins_pipe(pipe_class_default);
9455 %}
9456
9457 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
9458 match(Set dst (XorL src1 src2));
9459 ins_cost(DEFAULT_COST);
9460
9461 format %{ "NOT $dst, $src1 ($src2) \t// long" %}
9462 size(4);
9463 ins_encode %{
9464 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9465 %}
9466 ins_pipe(pipe_class_default);
9467 %}
9468
9469 // And-complement
9470 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
9471 match(Set dst (AndI (XorI src1 src2) src3));
9472 ins_cost(DEFAULT_COST);
9473
9474 format %{ "ANDW $dst, xori($src1, $src2), $src3" %}
9475 size(4);
9476 ins_encode( enc_andc(dst, src3, src1) );
9477 ins_pipe(pipe_class_default);
9478 %}
9479
9480 // And-complement
9481 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9482 // no match-rule, false predicate
9483 effect(DEF dst, USE src1, USE src2);
9484 predicate(false);
9485
9486 format %{ "ANDC $dst, $src1, $src2" %}
9487 size(4);
9488 ins_encode %{
9489 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
9490 %}
9491 ins_pipe(pipe_class_default);
9492 %}
9493
9494 //----------Moves between int/long and float/double----------------------------
9495 //
9496 // The following rules move values from int/long registers/stack-locations
9497 // to float/double registers/stack-locations and vice versa, without doing any
9498 // conversions. These rules are used to implement the bit-conversion methods
9499 // of java.lang.Float etc., e.g.
9500 // int floatToIntBits(float value)
9501 // float intBitsToFloat(int bits)
9502
9503 instruct moveL2D_reg(regD dst, iRegLsrc src) %{
9504 match(Set dst (MoveL2D src));
9505
9506 format %{ "MTFPRD $dst, $src" %}
9507 size(4);
9508 ins_encode %{
9509 __ mtfprd($dst$$FloatRegister, $src$$Register);
9510 %}
9511 ins_pipe(pipe_class_default);
9512 %}
9513
9514 instruct moveI2D_reg(regD dst, iRegIsrc src) %{
9515 // no match-rule, false predicate
9516 effect(DEF dst, USE src);
9517 predicate(false);
9518
9519 format %{ "MTFPRWA $dst, $src" %}
9520 size(4);
9521 ins_encode %{
9522 __ mtfprwa($dst$$FloatRegister, $src$$Register);
9523 %}
9524 ins_pipe(pipe_class_default);
9525 %}
9526
9527 //---------- Chain stack slots between similar types --------
9528
9529 // These are needed so that the rules below can match.
9530
9531 // Load integer from stack slot
9532 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
9533 match(Set dst src);
9534 ins_cost(MEMORY_REF_COST);
9535
9536 format %{ "LWZ $dst, $src" %}
9537 size(4);
9538 ins_encode( enc_lwz(dst, src) );
9539 ins_pipe(pipe_class_memory);
9540 %}
9541
9542 // Store integer to stack slot
9543 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
9544 match(Set dst src);
9545 ins_cost(MEMORY_REF_COST);
9546
9547 format %{ "STW $src, $dst \t// stk" %}
9548 size(4);
9549 ins_encode( enc_stw(src, dst) ); // rs=rt
9550 ins_pipe(pipe_class_memory);
9551 %}
9552
9553 // Load long from stack slot
9554 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
9555 match(Set dst src);
9556 ins_cost(MEMORY_REF_COST);
9557
9558 format %{ "LD $dst, $src \t// long" %}
9559 size(4);
9560 ins_encode( enc_ld(dst, src) );
9561 ins_pipe(pipe_class_memory);
9562 %}
9563
9564 // Store long to stack slot
9565 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
9566 match(Set dst src);
9567 ins_cost(MEMORY_REF_COST);
9568
9569 format %{ "STD $src, $dst \t// long" %}
9570 size(4);
9571 ins_encode( enc_std(src, dst) ); // rs=rt
9572 ins_pipe(pipe_class_memory);
9573 %}
9574
9575 //----------Moves between int and float
9576
9577 // Move float value from float stack-location to integer register.
9578 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
9579 match(Set dst (MoveF2I src));
9580 ins_cost(MEMORY_REF_COST);
9581
9582 format %{ "LWZ $dst, $src \t// MoveF2I" %}
9583 size(4);
9584 ins_encode( enc_lwz(dst, src) );
9585 ins_pipe(pipe_class_memory);
9586 %}
9587
9588 // Move float value from float register to integer stack-location.
9589 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
9590 match(Set dst (MoveF2I src));
9591 ins_cost(MEMORY_REF_COST);
9592
9593 format %{ "STFS $src, $dst \t// MoveF2I" %}
9594 size(4);
9595 ins_encode( enc_stfs(src, dst) );
9596 ins_pipe(pipe_class_memory);
9597 %}
9598
9599 // Move integer value from integer stack-location to float register.
9600 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
9601 match(Set dst (MoveI2F src));
9602 ins_cost(MEMORY_REF_COST);
9603
9604 format %{ "LFS $dst, $src \t// MoveI2F" %}
9605 size(4);
9606 ins_encode %{
9607 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
9608 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
9609 %}
9610 ins_pipe(pipe_class_memory);
9611 %}
9612
9613 // Move integer value from integer register to float stack-location.
9614 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
9615 match(Set dst (MoveI2F src));
9616 ins_cost(MEMORY_REF_COST);
9617
9618 format %{ "STW $src, $dst \t// MoveI2F" %}
9619 size(4);
9620 ins_encode( enc_stw(src, dst) );
9621 ins_pipe(pipe_class_memory);
9622 %}
9623
9624
9625 //----------Moves between long and double
9626
9627 // Move double value from double stack-location to long register.
9628 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
9629 match(Set dst (MoveD2L src));
9630 ins_cost(MEMORY_REF_COST);
9631 size(4);
9632 format %{ "LD $dst, $src \t// MoveD2L" %}
9633 ins_encode( enc_ld(dst, src) );
9634 ins_pipe(pipe_class_memory);
9635 %}
9636
9637 // Move double value from double register to long stack-location.
9638 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
9639 match(Set dst (MoveD2L src));
9640 effect(DEF dst, USE src);
9641 ins_cost(MEMORY_REF_COST);
9642
9643 format %{ "STFD $src, $dst \t// MoveD2L" %}
9644 size(4);
9645 ins_encode( enc_stfd(src, dst) );
9646 ins_pipe(pipe_class_memory);
9647 %}
9648
9649
9650 //----------Register Move Instructions-----------------------------------------
9651
9652 // Replicate for Superword
9653
9654 instruct moveReg(iRegLdst dst, iRegIsrc src) %{
9655 predicate(false);
9656 effect(DEF dst, USE src);
9657
9658 format %{ "MR $dst, $src \t// replicate " %}
9659 // variable size, 0 or 4.
9660 ins_encode %{
9661 __ mr_if_needed($dst$$Register, $src$$Register);
9662 %}
9663 ins_pipe(pipe_class_default);
9664 %}
9665
9666 //----------Cast instructions (Java-level type cast)---------------------------
9667
9668 // Cast Long to Pointer for unsafe natives.
9669 instruct castX2P(iRegPdst dst, iRegLsrc src) %{
9670 match(Set dst (CastX2P src));
9671
9672 format %{ "MR $dst, $src \t// Long->Ptr" %}
9673 // variable size, 0 or 4.
9674 ins_encode %{
9675 __ mr_if_needed($dst$$Register, $src$$Register);
9676 %}
9677 ins_pipe(pipe_class_default);
9678 %}
9679
9680 // Cast Pointer to Long for unsafe natives.
9681 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
9682 match(Set dst (CastP2X src));
9683
9684 format %{ "MR $dst, $src \t// Ptr->Long" %}
9685 // variable size, 0 or 4.
9686 ins_encode %{
9687 __ mr_if_needed($dst$$Register, $src$$Register);
9688 %}
9689 ins_pipe(pipe_class_default);
9690 %}
9691
9692 instruct castPP(iRegPdst dst) %{
9693 match(Set dst (CastPP dst));
9694 format %{ " -- \t// castPP of $dst" %}
9695 size(0);
9696 ins_encode( /*empty*/ );
9697 ins_pipe(pipe_class_default);
9698 %}
9699
9700 instruct castII(iRegIdst dst) %{
9701 match(Set dst (CastII dst));
9702 format %{ " -- \t// castII of $dst" %}
9703 size(0);
9704 ins_encode( /*empty*/ );
9705 ins_pipe(pipe_class_default);
9706 %}
9707
9708 instruct castLL(iRegLdst dst) %{
9709 match(Set dst (CastLL dst));
9710 format %{ " -- \t// castLL of $dst" %}
9711 size(0);
9712 ins_encode( /*empty*/ );
9713 ins_pipe(pipe_class_default);
9714 %}
9715
9716 instruct castFF(regF dst) %{
9717 match(Set dst (CastFF dst));
9718 format %{ " -- \t// castFF of $dst" %}
9719 size(0);
9720 ins_encode( /*empty*/ );
9721 ins_pipe(pipe_class_default);
9722 %}
9723
9724 instruct castDD(regD dst) %{
9725 match(Set dst (CastDD dst));
9726 format %{ " -- \t// castDD of $dst" %}
9727 size(0);
9728 ins_encode( /*empty*/ );
9729 ins_pipe(pipe_class_default);
9730 %}
9731
9732 instruct castVV8(iRegLdst dst) %{
9733 match(Set dst (CastVV dst));
9734 format %{ " -- \t// castVV of $dst" %}
9735 size(0);
9736 ins_encode( /*empty*/ );
9737 ins_pipe(pipe_class_default);
9738 %}
9739
9740 instruct castVV16(vecX dst) %{
9741 match(Set dst (CastVV dst));
9742 format %{ " -- \t// castVV of $dst" %}
9743 size(0);
9744 ins_encode( /*empty*/ );
9745 ins_pipe(pipe_class_default);
9746 %}
9747
9748 instruct checkCastPP(iRegPdst dst) %{
9749 match(Set dst (CheckCastPP dst));
9750 format %{ " -- \t// checkcastPP of $dst" %}
9751 size(0);
9752 ins_encode( /*empty*/ );
9753 ins_pipe(pipe_class_default);
9754 %}
9755
9756 //----------Convert instructions-----------------------------------------------
9757
9758 // Convert to boolean.
9759
9760 // int_to_bool(src) : { 1 if src != 0
9761 // { 0 else
9762 //
9763 // strategy:
9764 // 1) Count leading zeros of 32 bit-value src,
9765 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
9766 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9767 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9768
9769 // convI2Bool
9770 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
9771 match(Set dst (Conv2B src));
9772 predicate(UseCountLeadingZerosInstructionsPPC64);
9773 ins_cost(DEFAULT_COST);
9774
9775 expand %{
9776 immI shiftAmount %{ 0x5 %}
9777 uimmI16 mask %{ 0x1 %}
9778 iRegIdst tmp1;
9779 iRegIdst tmp2;
9780 countLeadingZerosI(tmp1, src);
9781 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9782 xorI_reg_uimm16(dst, tmp2, mask);
9783 %}
9784 %}
9785
9786 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
9787 match(Set dst (Conv2B src));
9788 effect(TEMP crx);
9789 predicate(!UseCountLeadingZerosInstructionsPPC64);
9790 ins_cost(DEFAULT_COST);
9791
9792 format %{ "CMPWI $crx, $src, #0 \t// convI2B"
9793 "LI $dst, #0\n\t"
9794 "BEQ $crx, done\n\t"
9795 "LI $dst, #1\n"
9796 "done:" %}
9797 size(16);
9798 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
9799 ins_pipe(pipe_class_compare);
9800 %}
9801
9802 // ConvI2B + XorI
9803 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
9804 match(Set dst (XorI (Conv2B src) mask));
9805 predicate(UseCountLeadingZerosInstructionsPPC64);
9806 ins_cost(DEFAULT_COST);
9807
9808 expand %{
9809 immI shiftAmount %{ 0x5 %}
9810 iRegIdst tmp1;
9811 countLeadingZerosI(tmp1, src);
9812 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9813 %}
9814 %}
9815
9816 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
9817 match(Set dst (XorI (Conv2B src) mask));
9818 effect(TEMP crx);
9819 predicate(!UseCountLeadingZerosInstructionsPPC64);
9820 ins_cost(DEFAULT_COST);
9821
9822 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
9823 "LI $dst, #1\n\t"
9824 "BEQ $crx, done\n\t"
9825 "LI $dst, #0\n"
9826 "done:" %}
9827 size(16);
9828 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
9829 ins_pipe(pipe_class_compare);
9830 %}
9831
9832 // AndI 0b0..010..0 + ConvI2B
9833 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
9834 match(Set dst (Conv2B (AndI src mask)));
9835 predicate(UseRotateAndMaskInstructionsPPC64);
9836 ins_cost(DEFAULT_COST);
9837
9838 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
9839 size(4);
9840 ins_encode %{
9841 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31);
9842 %}
9843 ins_pipe(pipe_class_default);
9844 %}
9845
9846 // Convert pointer to boolean.
9847 //
9848 // ptr_to_bool(src) : { 1 if src != 0
9849 // { 0 else
9850 //
9851 // strategy:
9852 // 1) Count leading zeros of 64 bit-value src,
9853 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
9854 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9855 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9856
9857 // ConvP2B
9858 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
9859 match(Set dst (Conv2B src));
9860 predicate(UseCountLeadingZerosInstructionsPPC64);
9861 ins_cost(DEFAULT_COST);
9862
9863 expand %{
9864 immI shiftAmount %{ 0x6 %}
9865 uimmI16 mask %{ 0x1 %}
9866 iRegIdst tmp1;
9867 iRegIdst tmp2;
9868 countLeadingZerosP(tmp1, src);
9869 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9870 xorI_reg_uimm16(dst, tmp2, mask);
9871 %}
9872 %}
9873
9874 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
9875 match(Set dst (Conv2B src));
9876 effect(TEMP crx);
9877 predicate(!UseCountLeadingZerosInstructionsPPC64);
9878 ins_cost(DEFAULT_COST);
9879
9880 format %{ "CMPDI $crx, $src, #0 \t// convP2B"
9881 "LI $dst, #0\n\t"
9882 "BEQ $crx, done\n\t"
9883 "LI $dst, #1\n"
9884 "done:" %}
9885 size(16);
9886 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
9887 ins_pipe(pipe_class_compare);
9888 %}
9889
9890 // ConvP2B + XorI
9891 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
9892 match(Set dst (XorI (Conv2B src) mask));
9893 predicate(UseCountLeadingZerosInstructionsPPC64);
9894 ins_cost(DEFAULT_COST);
9895
9896 expand %{
9897 immI shiftAmount %{ 0x6 %}
9898 iRegIdst tmp1;
9899 countLeadingZerosP(tmp1, src);
9900 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9901 %}
9902 %}
9903
9904 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
9905 match(Set dst (XorI (Conv2B src) mask));
9906 effect(TEMP crx);
9907 predicate(!UseCountLeadingZerosInstructionsPPC64);
9908 ins_cost(DEFAULT_COST);
9909
9910 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
9911 "LI $dst, #1\n\t"
9912 "BEQ $crx, done\n\t"
9913 "LI $dst, #0\n"
9914 "done:" %}
9915 size(16);
9916 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
9917 ins_pipe(pipe_class_compare);
9918 %}
9919
9920 // if src1 < src2, return -1 else return 0
9921 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9922 match(Set dst (CmpLTMask src1 src2));
9923 ins_cost(DEFAULT_COST*4);
9924
9925 expand %{
9926 iRegLdst src1s;
9927 iRegLdst src2s;
9928 iRegLdst diff;
9929 convI2L_reg(src1s, src1); // Ensure proper sign extension.
9930 convI2L_reg(src2s, src2); // Ensure proper sign extension.
9931 subL_reg_reg(diff, src1s, src2s);
9932 // Need to consider >=33 bit result, therefore we need signmaskL.
9933 signmask64I_regL(dst, diff);
9934 %}
9935 %}
9936
9937 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
9938 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
9939 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %}
9940 size(4);
9941 ins_encode %{
9942 __ srawi($dst$$Register, $src1$$Register, 0x1f);
9943 %}
9944 ins_pipe(pipe_class_default);
9945 %}
9946
9947 //----------Arithmetic Conversion Instructions---------------------------------
9948
9949 // Convert to Byte -- nop
9950 // Convert to Short -- nop
9951
9952 // Convert to Int
9953
9954 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
9955 match(Set dst (RShiftI (LShiftI src amount) amount));
9956 format %{ "EXTSB $dst, $src \t// byte->int" %}
9957 size(4);
9958 ins_encode %{
9959 __ extsb($dst$$Register, $src$$Register);
9960 %}
9961 ins_pipe(pipe_class_default);
9962 %}
9963
9964 instruct extsh(iRegIdst dst, iRegIsrc src) %{
9965 effect(DEF dst, USE src);
9966
9967 size(4);
9968 ins_encode %{
9969 __ extsh($dst$$Register, $src$$Register);
9970 %}
9971 ins_pipe(pipe_class_default);
9972 %}
9973
9974 // LShiftI 16 + RShiftI 16 converts short to int.
9975 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
9976 match(Set dst (RShiftI (LShiftI src amount) amount));
9977 format %{ "EXTSH $dst, $src \t// short->int" %}
9978 size(4);
9979 ins_encode %{
9980 __ extsh($dst$$Register, $src$$Register);
9981 %}
9982 ins_pipe(pipe_class_default);
9983 %}
9984
9985 // ConvL2I + ConvI2L: Sign extend int in long register.
9986 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
9987 match(Set dst (ConvI2L (ConvL2I src)));
9988
9989 format %{ "EXTSW $dst, $src \t// long->long" %}
9990 size(4);
9991 ins_encode %{
9992 __ extsw($dst$$Register, $src$$Register);
9993 %}
9994 ins_pipe(pipe_class_default);
9995 %}
9996
9997 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
9998 match(Set dst (ConvL2I src));
9999 format %{ "MR $dst, $src \t// long->int" %}
10000 // variable size, 0 or 4
10001 ins_encode %{
10002 __ mr_if_needed($dst$$Register, $src$$Register);
10003 %}
10004 ins_pipe(pipe_class_default);
10005 %}
10006
10007 instruct convD2IRaw_regD(regD dst, regD src) %{
10008 // no match-rule, false predicate
10009 effect(DEF dst, USE src);
10010 predicate(false);
10011
10012 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
10013 size(4);
10014 ins_encode %{
10015 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10016 %}
10017 ins_pipe(pipe_class_default);
10018 %}
10019
10020 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
10021 // no match-rule, false predicate
10022 effect(DEF dst, USE crx, USE src);
10023 predicate(false);
10024
10025 ins_variable_size_depending_on_alignment(true);
10026
10027 format %{ "CMOVI $crx, $dst, $src" %}
10028 size(8);
10029 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10030 ins_pipe(pipe_class_default);
10031 %}
10032
10033 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
10034 // no match-rule, false predicate
10035 effect(DEF dst, USE crx, USE src);
10036 predicate(false);
10037
10038 ins_variable_size_depending_on_alignment(true);
10039
10040 format %{ "CMOVI $crx, $dst, $src" %}
10041 size(8);
10042 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10043 ins_pipe(pipe_class_default);
10044 %}
10045
10046
10047 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{
10048 // no match-rule, false predicate
10049 effect(DEF dst, USE crx, USE src);
10050 predicate(false);
10051
10052 format %{ "CMOVI $dst, $crx, $src \t// postalloc expanded" %}
10053 postalloc_expand %{
10054 //
10055 // replaces
10056 //
10057 // region dst crx src
10058 // \ | | /
10059 // dst=cmovI_bso_reg_conLvalue0
10060 //
10061 // with
10062 //
10063 // region dst
10064 // \ /
10065 // dst=loadConI16(0)
10066 // |
10067 // ^ region dst crx src
10068 // | \ | | /
10069 // dst=cmovI_bso_reg
10070 //
10071
10072 // Create new nodes.
10073 MachNode *m1 = new loadConI16Node();
10074 MachNode *m2 = new cmovI_bso_regNode();
10075
10076 // inputs for new nodes
10077 m1->add_req(n_region);
10078 m2->add_req(n_region, n_crx, n_src);
10079
10080 // precedences for new nodes
10081 m2->add_prec(m1);
10082
10083 // operands for new nodes
10084 m1->_opnds[0] = op_dst;
10085 m1->_opnds[1] = new immI16Oper(0);
10086
10087 m2->_opnds[0] = op_dst;
10088 m2->_opnds[1] = op_crx;
10089 m2->_opnds[2] = op_src;
10090
10091 // registers for new nodes
10092 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10093 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10094
10095 // Insert new nodes.
10096 nodes->push(m1);
10097 nodes->push(m2);
10098 %}
10099 %}
10100
10101
10102 // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
10103 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
10104 match(Set dst (ConvD2I src));
10105 ins_cost(DEFAULT_COST);
10106
10107 expand %{
10108 regD tmpD;
10109 flagsReg crx;
10110 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10111 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
10112 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10113 %}
10114 %}
10115
10116 instruct convF2IRaw_regF(regF dst, regF src) %{
10117 // no match-rule, false predicate
10118 effect(DEF dst, USE src);
10119 predicate(false);
10120
10121 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
10122 size(4);
10123 ins_encode %{
10124 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10125 %}
10126 ins_pipe(pipe_class_default);
10127 %}
10128
10129
10130 // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
10131 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
10132 match(Set dst (ConvF2I src));
10133 ins_cost(DEFAULT_COST);
10134
10135 expand %{
10136 regF tmpF;
10137 flagsReg crx;
10138 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10139 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10140 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10141 %}
10142 %}
10143
10144 // Convert to Long
10145
10146 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
10147 match(Set dst (ConvI2L src));
10148 format %{ "EXTSW $dst, $src \t// int->long" %}
10149 size(4);
10150 ins_encode %{
10151 __ extsw($dst$$Register, $src$$Register);
10152 %}
10153 ins_pipe(pipe_class_default);
10154 %}
10155
10156 // Zero-extend: convert unsigned int to long (convUI2L).
10157 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
10158 match(Set dst (AndL (ConvI2L src) mask));
10159 ins_cost(DEFAULT_COST);
10160
10161 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10162 size(4);
10163 ins_encode %{
10164 __ clrldi($dst$$Register, $src$$Register, 32);
10165 %}
10166 ins_pipe(pipe_class_default);
10167 %}
10168
10169 // Zero-extend: convert unsigned int to long in long register.
10170 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
10171 match(Set dst (AndL src mask));
10172 ins_cost(DEFAULT_COST);
10173
10174 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10175 size(4);
10176 ins_encode %{
10177 __ clrldi($dst$$Register, $src$$Register, 32);
10178 %}
10179 ins_pipe(pipe_class_default);
10180 %}
10181
10182 instruct convF2LRaw_regF(regF dst, regF src) %{
10183 // no match-rule, false predicate
10184 effect(DEF dst, USE src);
10185 predicate(false);
10186
10187 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10188 size(4);
10189 ins_encode %{
10190 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10191 %}
10192 ins_pipe(pipe_class_default);
10193 %}
10194
10195 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
10196 // no match-rule, false predicate
10197 effect(DEF dst, USE crx, USE src);
10198 predicate(false);
10199
10200 ins_variable_size_depending_on_alignment(true);
10201
10202 format %{ "CMOVL $crx, $dst, $src" %}
10203 size(8);
10204 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10205 ins_pipe(pipe_class_default);
10206 %}
10207
10208 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
10209 // no match-rule, false predicate
10210 effect(DEF dst, USE crx, USE src);
10211 predicate(false);
10212
10213 ins_variable_size_depending_on_alignment(true);
10214
10215 format %{ "CMOVL $crx, $dst, $src" %}
10216 size(8);
10217 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10218 ins_pipe(pipe_class_default);
10219 %}
10220
10221
10222 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{
10223 // no match-rule, false predicate
10224 effect(DEF dst, USE crx, USE src);
10225 predicate(false);
10226
10227 format %{ "CMOVL $dst, $crx, $src \t// postalloc expanded" %}
10228 postalloc_expand %{
10229 //
10230 // replaces
10231 //
10232 // region dst crx src
10233 // \ | | /
10234 // dst=cmovL_bso_reg_conLvalue0
10235 //
10236 // with
10237 //
10238 // region dst
10239 // \ /
10240 // dst=loadConL16(0)
10241 // |
10242 // ^ region dst crx src
10243 // | \ | | /
10244 // dst=cmovL_bso_reg
10245 //
10246
10247 // Create new nodes.
10248 MachNode *m1 = new loadConL16Node();
10249 MachNode *m2 = new cmovL_bso_regNode();
10250
10251 // inputs for new nodes
10252 m1->add_req(n_region);
10253 m2->add_req(n_region, n_crx, n_src);
10254 m2->add_prec(m1);
10255
10256 // operands for new nodes
10257 m1->_opnds[0] = op_dst;
10258 m1->_opnds[1] = new immL16Oper(0);
10259 m2->_opnds[0] = op_dst;
10260 m2->_opnds[1] = op_crx;
10261 m2->_opnds[2] = op_src;
10262
10263 // registers for new nodes
10264 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10265 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10266
10267 // Insert new nodes.
10268 nodes->push(m1);
10269 nodes->push(m2);
10270 %}
10271 %}
10272
10273
10274 // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
10275 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
10276 match(Set dst (ConvF2L src));
10277 ins_cost(DEFAULT_COST);
10278
10279 expand %{
10280 regF tmpF;
10281 flagsReg crx;
10282 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10283 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
10284 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10285 %}
10286 %}
10287
10288 instruct convD2LRaw_regD(regD dst, regD src) %{
10289 // no match-rule, false predicate
10290 effect(DEF dst, USE src);
10291 predicate(false);
10292
10293 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
10294 size(4);
10295 ins_encode %{
10296 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10297 %}
10298 ins_pipe(pipe_class_default);
10299 %}
10300
10301
10302 // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
10303 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
10304 match(Set dst (ConvD2L src));
10305 ins_cost(DEFAULT_COST);
10306
10307 expand %{
10308 regD tmpD;
10309 flagsReg crx;
10310 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10311 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
10312 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10313 %}
10314 %}
10315
10316 // Convert to Float
10317
10318 // Placed here as needed in expand.
10319 instruct convL2DRaw_regD(regD dst, regD src) %{
10320 // no match-rule, false predicate
10321 effect(DEF dst, USE src);
10322 predicate(false);
10323
10324 format %{ "FCFID $dst, $src \t// convL2D" %}
10325 size(4);
10326 ins_encode %{
10327 __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
10328 %}
10329 ins_pipe(pipe_class_default);
10330 %}
10331
10332 // Placed here as needed in expand.
10333 instruct convD2F_reg(regF dst, regD src) %{
10334 match(Set dst (ConvD2F src));
10335 format %{ "FRSP $dst, $src \t// convD2F" %}
10336 size(4);
10337 ins_encode %{
10338 __ frsp($dst$$FloatRegister, $src$$FloatRegister);
10339 %}
10340 ins_pipe(pipe_class_default);
10341 %}
10342
10343 instruct convL2FRaw_regF(regF dst, regD src) %{
10344 // no match-rule, false predicate
10345 effect(DEF dst, USE src);
10346 predicate(false);
10347
10348 format %{ "FCFIDS $dst, $src \t// convL2F" %}
10349 size(4);
10350 ins_encode %{
10351 __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
10352 %}
10353 ins_pipe(pipe_class_default);
10354 %}
10355
10356
10357 // Integer to Float conversion. Special version for Power8.
10358 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
10359 match(Set dst (ConvI2F src));
10360 ins_cost(DEFAULT_COST);
10361
10362 expand %{
10363 regD tmpD;
10364 moveI2D_reg(tmpD, src);
10365 convL2FRaw_regF(dst, tmpD); // Convert to float.
10366 %}
10367 %}
10368
10369
10370 // L2F to avoid runtime call. Special version for Power8.
10371 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
10372 match(Set dst (ConvL2F src));
10373 ins_cost(DEFAULT_COST);
10374
10375 expand %{
10376 regD tmpD;
10377 moveL2D_reg(tmpD, src);
10378 convL2FRaw_regF(dst, tmpD); // Convert to float.
10379 %}
10380 %}
10381
10382 // Moved up as used in expand.
10383 //instruct convD2F_reg(regF dst, regD src) %{%}
10384
10385 // Convert to Double
10386
10387
10388 // Integer to Double conversion. Special version for Power8.
10389 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
10390 match(Set dst (ConvI2D src));
10391 ins_cost(DEFAULT_COST);
10392
10393 expand %{
10394 regD tmpD;
10395 moveI2D_reg(tmpD, src);
10396 convL2DRaw_regD(dst, tmpD); // Convert to double.
10397 %}
10398 %}
10399
10400
10401 // Long to Double conversion. Special version for Power8.
10402 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
10403 match(Set dst (ConvL2D src));
10404 ins_cost(DEFAULT_COST);
10405
10406 expand %{
10407 regD tmpD;
10408 moveL2D_reg(tmpD, src);
10409 convL2DRaw_regD(dst, tmpD); // Convert to double.
10410 %}
10411 %}
10412
10413 instruct convF2D_reg(regD dst, regF src) %{
10414 match(Set dst (ConvF2D src));
10415 format %{ "FMR $dst, $src \t// float->double" %}
10416 // variable size, 0 or 4
10417 ins_encode %{
10418 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
10419 %}
10420 ins_pipe(pipe_class_default);
10421 %}
10422
10423 instruct convF2HF_reg_reg(iRegIdst dst, regF src, regF tmp) %{
10424 match(Set dst (ConvF2HF src));
10425 effect(TEMP tmp);
10426 ins_cost(3 * DEFAULT_COST);
10427 size(12);
10428 format %{ "XSCVDPHP $tmp, $src\t# convert to half precision\n\t"
10429 "MFFPRD $dst, $tmp\t# move result from $tmp to $dst\n\t"
10430 "EXTSH $dst, $dst\t# make it a proper short"
10431 %}
10432 ins_encode %{
10433 __ f2hf($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
10434 %}
10435 ins_pipe(pipe_class_default);
10436 %}
10437
10438 instruct convHF2F_reg_reg(regF dst, iRegIsrc src) %{
10439 match(Set dst (ConvHF2F src));
10440 ins_cost(2 * DEFAULT_COST);
10441 size(8);
10442 format %{ "MTFPRD $dst, $src\t# move source from $src to $dst\n\t"
10443 "XSCVHPDP $dst, $dst\t# convert from half precision"
10444 %}
10445 ins_encode %{
10446 __ hf2f($dst$$FloatRegister, $src$$Register);
10447 %}
10448 ins_pipe(pipe_class_default);
10449 %}
10450
10451 //----------Control Flow Instructions------------------------------------------
10452 // Compare Instructions
10453
10454 // Compare Integers
10455 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10456 match(Set crx (CmpI src1 src2));
10457 size(4);
10458 format %{ "CMPW $crx, $src1, $src2" %}
10459 ins_encode %{
10460 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10461 %}
10462 ins_pipe(pipe_class_compare);
10463 %}
10464
10465 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
10466 match(Set crx (CmpI src1 src2));
10467 format %{ "CMPWI $crx, $src1, $src2" %}
10468 size(4);
10469 ins_encode %{
10470 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10471 %}
10472 ins_pipe(pipe_class_compare);
10473 %}
10474
10475 // (src1 & src2) == 0?
10476 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
10477 match(Set cr0 (CmpI (AndI src1 src2) zero));
10478 // r0 is killed
10479 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
10480 size(4);
10481 ins_encode %{
10482 __ andi_(R0, $src1$$Register, $src2$$constant);
10483 %}
10484 ins_pipe(pipe_class_compare);
10485 %}
10486
10487 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10488 match(Set crx (CmpL src1 src2));
10489 format %{ "CMPD $crx, $src1, $src2" %}
10490 size(4);
10491 ins_encode %{
10492 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
10493 %}
10494 ins_pipe(pipe_class_compare);
10495 %}
10496
10497 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
10498 match(Set crx (CmpL src1 src2));
10499 format %{ "CMPDI $crx, $src1, $src2" %}
10500 size(4);
10501 ins_encode %{
10502 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10503 %}
10504 ins_pipe(pipe_class_compare);
10505 %}
10506
10507 // Added CmpUL for LoopPredicate.
10508 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10509 match(Set crx (CmpUL src1 src2));
10510 format %{ "CMPLD $crx, $src1, $src2" %}
10511 size(4);
10512 ins_encode %{
10513 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10514 %}
10515 ins_pipe(pipe_class_compare);
10516 %}
10517
10518 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
10519 match(Set crx (CmpUL src1 src2));
10520 format %{ "CMPLDI $crx, $src1, $src2" %}
10521 size(4);
10522 ins_encode %{
10523 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10524 %}
10525 ins_pipe(pipe_class_compare);
10526 %}
10527
10528 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
10529 match(Set cr0 (CmpL (AndL src1 src2) zero));
10530 // r0 is killed
10531 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
10532 size(4);
10533 ins_encode %{
10534 __ and_(R0, $src1$$Register, $src2$$Register);
10535 %}
10536 ins_pipe(pipe_class_compare);
10537 %}
10538
10539 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
10540 match(Set cr0 (CmpL (AndL src1 src2) zero));
10541 // r0 is killed
10542 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
10543 size(4);
10544 ins_encode %{
10545 __ andi_(R0, $src1$$Register, $src2$$constant);
10546 %}
10547 ins_pipe(pipe_class_compare);
10548 %}
10549
10550 // Manifest a CmpL3 result in an integer register.
10551 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10552 match(Set dst (CmpL3 src1 src2));
10553 effect(KILL cr0);
10554 ins_cost(DEFAULT_COST * 5);
10555 size((VM_Version::has_brw() ? 16 : 20));
10556
10557 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %}
10558
10559 ins_encode %{
10560 __ cmpd(CR0, $src1$$Register, $src2$$Register);
10561 __ set_cmp3($dst$$Register);
10562 %}
10563 ins_pipe(pipe_class_default);
10564 %}
10565
10566 instruct cmpU3_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
10567 match(Set dst (CmpU3 src1 src2));
10568 effect(KILL cr0);
10569 ins_cost(DEFAULT_COST * 5);
10570 size((VM_Version::has_brw() ? 16 : 20));
10571
10572 format %{ "cmpU3_reg_reg $dst, $src1, $src2" %}
10573
10574 ins_encode %{
10575 __ cmplw(CR0, $src1$$Register, $src2$$Register);
10576 __ set_cmp3($dst$$Register);
10577 %}
10578 ins_pipe(pipe_class_default);
10579 %}
10580
10581 instruct cmpUL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10582 match(Set dst (CmpUL3 src1 src2));
10583 effect(KILL cr0);
10584 ins_cost(DEFAULT_COST * 5);
10585 size((VM_Version::has_brw() ? 16 : 20));
10586
10587 format %{ "cmpUL3_reg_reg $dst, $src1, $src2" %}
10588
10589 ins_encode %{
10590 __ cmpld(CR0, $src1$$Register, $src2$$Register);
10591 __ set_cmp3($dst$$Register);
10592 %}
10593 ins_pipe(pipe_class_default);
10594 %}
10595
10596 // Implicit range checks.
10597 // A range check in the ideal world has one of the following shapes:
10598 // - (If le (CmpU length index)), (IfTrue throw exception)
10599 // - (If lt (CmpU index length)), (IfFalse throw exception)
10600 //
10601 // Match range check 'If le (CmpU length index)'.
10602 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
10603 match(If cmp (CmpU src_length index));
10604 effect(USE labl);
10605 predicate(TrapBasedRangeChecks &&
10606 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
10607 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
10608 (Matcher::branches_to_uncommon_trap(_leaf)));
10609
10610 ins_is_TrapBasedCheckNode(true);
10611
10612 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %}
10613 size(4);
10614 ins_encode %{
10615 if ($cmp$$cmpcode == 0x1 /* less_equal */) {
10616 __ trap_range_check_le($src_length$$Register, $index$$constant);
10617 } else {
10618 // Both successors are uncommon traps, probability is 0.
10619 // Node got flipped during fixup flow.
10620 assert($cmp$$cmpcode == 0x9, "must be greater");
10621 __ trap_range_check_g($src_length$$Register, $index$$constant);
10622 }
10623 %}
10624 ins_pipe(pipe_class_trap);
10625 %}
10626
10627 // Match range check 'If lt (CmpU index length)'.
10628 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
10629 match(If cmp (CmpU src_index src_length));
10630 effect(USE labl);
10631 predicate(TrapBasedRangeChecks &&
10632 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10633 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10634 (Matcher::branches_to_uncommon_trap(_leaf)));
10635
10636 ins_is_TrapBasedCheckNode(true);
10637
10638 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
10639 size(4);
10640 ins_encode %{
10641 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10642 __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
10643 } else {
10644 // Both successors are uncommon traps, probability is 0.
10645 // Node got flipped during fixup flow.
10646 assert($cmp$$cmpcode == 0x8, "must be less");
10647 __ trap_range_check_l($src_index$$Register, $src_length$$Register);
10648 }
10649 %}
10650 ins_pipe(pipe_class_trap);
10651 %}
10652
10653 // Match range check 'If lt (CmpU index length)'.
10654 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
10655 match(If cmp (CmpU src_index length));
10656 effect(USE labl);
10657 predicate(TrapBasedRangeChecks &&
10658 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10659 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10660 (Matcher::branches_to_uncommon_trap(_leaf)));
10661
10662 ins_is_TrapBasedCheckNode(true);
10663
10664 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %}
10665 size(4);
10666 ins_encode %{
10667 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10668 __ trap_range_check_ge($src_index$$Register, $length$$constant);
10669 } else {
10670 // Both successors are uncommon traps, probability is 0.
10671 // Node got flipped during fixup flow.
10672 assert($cmp$$cmpcode == 0x8, "must be less");
10673 __ trap_range_check_l($src_index$$Register, $length$$constant);
10674 }
10675 %}
10676 ins_pipe(pipe_class_trap);
10677 %}
10678
10679 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10680 match(Set crx (CmpU src1 src2));
10681 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %}
10682 size(4);
10683 ins_encode %{
10684 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10685 %}
10686 ins_pipe(pipe_class_compare);
10687 %}
10688
10689 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
10690 match(Set crx (CmpU src1 src2));
10691 size(4);
10692 format %{ "CMPLWI $crx, $src1, $src2" %}
10693 ins_encode %{
10694 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10695 %}
10696 ins_pipe(pipe_class_compare);
10697 %}
10698
10699 // Implicit zero checks (more implicit null checks).
10700 // No constant pool entries required.
10701 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
10702 match(If cmp (CmpN value zero));
10703 effect(USE labl);
10704 predicate(TrapBasedNullChecks &&
10705 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10706 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10707 Matcher::branches_to_uncommon_trap(_leaf));
10708 ins_cost(1);
10709
10710 ins_is_TrapBasedCheckNode(true);
10711
10712 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
10713 size(4);
10714 ins_encode %{
10715 if ($cmp$$cmpcode == 0xA) {
10716 __ trap_null_check($value$$Register);
10717 } else {
10718 // Both successors are uncommon traps, probability is 0.
10719 // Node got flipped during fixup flow.
10720 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10721 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10722 }
10723 %}
10724 ins_pipe(pipe_class_trap);
10725 %}
10726
10727 // Compare narrow oops.
10728 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
10729 match(Set crx (CmpN src1 src2));
10730
10731 size(4);
10732 ins_cost(2);
10733 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %}
10734 ins_encode %{
10735 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10736 %}
10737 ins_pipe(pipe_class_compare);
10738 %}
10739
10740 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
10741 match(Set crx (CmpN src1 src2));
10742 // Make this more expensive than zeroCheckN_iReg_imm0.
10743 ins_cost(2);
10744
10745 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %}
10746 size(4);
10747 ins_encode %{
10748 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10749 %}
10750 ins_pipe(pipe_class_compare);
10751 %}
10752
10753 // Implicit zero checks (more implicit null checks).
10754 // No constant pool entries required.
10755 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
10756 match(If cmp (CmpP value zero));
10757 effect(USE labl);
10758 predicate(TrapBasedNullChecks &&
10759 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10760 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10761 Matcher::branches_to_uncommon_trap(_leaf));
10762 ins_cost(1); // Should not be cheaper than zeroCheckN.
10763
10764 ins_is_TrapBasedCheckNode(true);
10765
10766 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
10767 size(4);
10768 ins_encode %{
10769 if ($cmp$$cmpcode == 0xA) {
10770 __ trap_null_check($value$$Register);
10771 } else {
10772 // Both successors are uncommon traps, probability is 0.
10773 // Node got flipped during fixup flow.
10774 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10775 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10776 }
10777 %}
10778 ins_pipe(pipe_class_trap);
10779 %}
10780
10781 // Compare Pointers
10782 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
10783 match(Set crx (CmpP src1 src2));
10784 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %}
10785 size(4);
10786 ins_encode %{
10787 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10788 %}
10789 ins_pipe(pipe_class_compare);
10790 %}
10791
10792 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
10793 match(Set crx (CmpP src1 src2));
10794 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %}
10795 size(4);
10796 ins_encode %{
10797 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
10798 %}
10799 ins_pipe(pipe_class_compare);
10800 %}
10801
10802 // Used in postalloc expand.
10803 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
10804 // This match rule prevents reordering of node before a safepoint.
10805 // This only makes sense if this instructions is used exclusively
10806 // for the expansion of EncodeP!
10807 match(Set crx (CmpP src1 src2));
10808 predicate(false);
10809
10810 format %{ "CMPDI $crx, $src1, $src2" %}
10811 size(4);
10812 ins_encode %{
10813 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10814 %}
10815 ins_pipe(pipe_class_compare);
10816 %}
10817
10818 //----------Float Compares----------------------------------------------------
10819
10820 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
10821 // Needs matchrule, see cmpDUnordered.
10822 match(Set crx (CmpF src1 src2));
10823 // no match-rule, false predicate
10824 predicate(false);
10825
10826 format %{ "cmpFUrd $crx, $src1, $src2" %}
10827 size(4);
10828 ins_encode %{
10829 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10830 %}
10831 ins_pipe(pipe_class_default);
10832 %}
10833
10834 instruct cmov_bns_less(flagsReg crx) %{
10835 // no match-rule, false predicate
10836 effect(DEF crx);
10837 predicate(false);
10838
10839 ins_variable_size_depending_on_alignment(true);
10840
10841 format %{ "CMOV $crx" %}
10842 size(12);
10843 ins_encode %{
10844 Label done;
10845 __ bns($crx$$CondRegister, done); // not unordered -> keep crx
10846 __ li(R0, 0);
10847 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less'
10848 __ bind(done);
10849 %}
10850 ins_pipe(pipe_class_default);
10851 %}
10852
10853 // Compare floating, generate condition code.
10854 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{
10855 // FIXME: should we match 'If cmp (CmpF src1 src2))' ??
10856 //
10857 // The following code sequence occurs a lot in mpegaudio:
10858 //
10859 // block BXX:
10860 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0):
10861 // cmpFUrd CR6, F11, F9
10862 // 4: instruct cmov_bns_less (cmpF_reg_reg-1):
10863 // cmov CR6
10864 // 8: instruct branchConSched:
10865 // B_FARle CR6, B56 P=0.500000 C=-1.000000
10866 match(Set crx (CmpF src1 src2));
10867 ins_cost(DEFAULT_COST+BRANCH_COST);
10868
10869 format %{ "CMPF $crx, $src1, $src2 \t// postalloc expanded" %}
10870 postalloc_expand %{
10871 //
10872 // replaces
10873 //
10874 // region src1 src2
10875 // \ | |
10876 // crx=cmpF_reg_reg
10877 //
10878 // with
10879 //
10880 // region src1 src2
10881 // \ | |
10882 // crx=cmpFUnordered_reg_reg
10883 // |
10884 // ^ region
10885 // | \
10886 // crx=cmov_bns_less
10887 //
10888
10889 // Create new nodes.
10890 MachNode *m1 = new cmpFUnordered_reg_regNode();
10891 MachNode *m2 = new cmov_bns_lessNode();
10892
10893 // inputs for new nodes
10894 m1->add_req(n_region, n_src1, n_src2);
10895 m2->add_req(n_region);
10896 m2->add_prec(m1);
10897
10898 // operands for new nodes
10899 m1->_opnds[0] = op_crx;
10900 m1->_opnds[1] = op_src1;
10901 m1->_opnds[2] = op_src2;
10902 m2->_opnds[0] = op_crx;
10903
10904 // registers for new nodes
10905 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10906 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10907
10908 // Insert new nodes.
10909 nodes->push(m1);
10910 nodes->push(m2);
10911 %}
10912 %}
10913
10914 // Compare float, generate -1,0,1
10915 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{
10916 match(Set dst (CmpF3 src1 src2));
10917 effect(KILL cr0);
10918 ins_cost(DEFAULT_COST * 6);
10919 size((VM_Version::has_brw() ? 20 : 24));
10920
10921 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %}
10922
10923 ins_encode %{
10924 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
10925 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
10926 %}
10927 ins_pipe(pipe_class_default);
10928 %}
10929
10930 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
10931 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
10932 // node right before the conditional move using it.
10933 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
10934 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
10935 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
10936 // conditional move was supposed to be spilled.
10937 match(Set crx (CmpD src1 src2));
10938 // False predicate, shall not be matched.
10939 predicate(false);
10940
10941 format %{ "cmpFUrd $crx, $src1, $src2" %}
10942 size(4);
10943 ins_encode %{
10944 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10945 %}
10946 ins_pipe(pipe_class_default);
10947 %}
10948
10949 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{
10950 match(Set crx (CmpD src1 src2));
10951 ins_cost(DEFAULT_COST+BRANCH_COST);
10952
10953 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %}
10954 postalloc_expand %{
10955 //
10956 // replaces
10957 //
10958 // region src1 src2
10959 // \ | |
10960 // crx=cmpD_reg_reg
10961 //
10962 // with
10963 //
10964 // region src1 src2
10965 // \ | |
10966 // crx=cmpDUnordered_reg_reg
10967 // |
10968 // ^ region
10969 // | \
10970 // crx=cmov_bns_less
10971 //
10972
10973 // create new nodes
10974 MachNode *m1 = new cmpDUnordered_reg_regNode();
10975 MachNode *m2 = new cmov_bns_lessNode();
10976
10977 // inputs for new nodes
10978 m1->add_req(n_region, n_src1, n_src2);
10979 m2->add_req(n_region);
10980 m2->add_prec(m1);
10981
10982 // operands for new nodes
10983 m1->_opnds[0] = op_crx;
10984 m1->_opnds[1] = op_src1;
10985 m1->_opnds[2] = op_src2;
10986 m2->_opnds[0] = op_crx;
10987
10988 // registers for new nodes
10989 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10990 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10991
10992 // Insert new nodes.
10993 nodes->push(m1);
10994 nodes->push(m2);
10995 %}
10996 %}
10997
10998 // Compare double, generate -1,0,1
10999 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{
11000 match(Set dst (CmpD3 src1 src2));
11001 effect(KILL cr0);
11002 ins_cost(DEFAULT_COST * 6);
11003 size((VM_Version::has_brw() ? 20 : 24));
11004
11005 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %}
11006
11007 ins_encode %{
11008 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
11009 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11010 %}
11011 ins_pipe(pipe_class_default);
11012 %}
11013
11014 // Compare char
11015 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11016 match(Set dst (Digit src1));
11017 effect(TEMP src2, TEMP crx);
11018 ins_cost(3 * DEFAULT_COST);
11019
11020 format %{ "LI $src2, 0x3930\n\t"
11021 "CMPRB $crx, 0, $src1, $src2\n\t"
11022 "SETB $dst, $crx" %}
11023 size(12);
11024 ins_encode %{
11025 // 0x30: 0, 0x39: 9
11026 __ li($src2$$Register, 0x3930);
11027 // compare src1 with ranges 0x30 to 0x39
11028 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11029 __ setb($dst$$Register, $crx$$CondRegister);
11030 %}
11031 ins_pipe(pipe_class_default);
11032 %}
11033
11034 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11035 match(Set dst (LowerCase src1));
11036 effect(TEMP src2, TEMP crx);
11037 ins_cost(12 * DEFAULT_COST);
11038
11039 format %{ "LI $src2, 0x7A61\n\t"
11040 "CMPRB $crx, 0, $src1, $src2\n\t"
11041 "BGT $crx, done\n\t"
11042 "LIS $src2, (signed short)0xF6DF\n\t"
11043 "ORI $src2, $src2, 0xFFF8\n\t"
11044 "CMPRB $crx, 1, $src1, $src2\n\t"
11045 "BGT $crx, done\n\t"
11046 "LIS $src2, (signed short)0xAAB5\n\t"
11047 "ORI $src2, $src2, 0xBABA\n\t"
11048 "INSRDI $src2, $src2, 32, 0\n\t"
11049 "CMPEQB $crx, 1, $src1, $src2\n"
11050 "done:\n\t"
11051 "SETB $dst, $crx" %}
11052
11053 size(48);
11054 ins_encode %{
11055 Label done;
11056 // 0x61: a, 0x7A: z
11057 __ li($src2$$Register, 0x7A61);
11058 // compare src1 with ranges 0x61 to 0x7A
11059 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11060 __ bgt($crx$$CondRegister, done);
11061
11062 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
11063 __ lis($src2$$Register, (signed short)0xF6DF);
11064 __ ori($src2$$Register, $src2$$Register, 0xFFF8);
11065 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
11066 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11067 __ bgt($crx$$CondRegister, done);
11068
11069 // 0xAA: feminine ordinal indicator
11070 // 0xB5: micro sign
11071 // 0xBA: masculine ordinal indicator
11072 __ lis($src2$$Register, (signed short)0xAAB5);
11073 __ ori($src2$$Register, $src2$$Register, 0xBABA);
11074 __ insrdi($src2$$Register, $src2$$Register, 32, 0);
11075 // compare src1 with 0xAA, 0xB5, and 0xBA
11076 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
11077
11078 __ bind(done);
11079 __ setb($dst$$Register, $crx$$CondRegister);
11080 %}
11081 ins_pipe(pipe_class_default);
11082 %}
11083
11084 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11085 match(Set dst (UpperCase src1));
11086 effect(TEMP src2, TEMP crx);
11087 ins_cost(7 * DEFAULT_COST);
11088
11089 format %{ "LI $src2, 0x5A41\n\t"
11090 "CMPRB $crx, 0, $src1, $src2\n\t"
11091 "BGT $crx, done\n\t"
11092 "LIS $src2, (signed short)0xD6C0\n\t"
11093 "ORI $src2, $src2, 0xDED8\n\t"
11094 "CMPRB $crx, 1, $src1, $src2\n"
11095 "done:\n\t"
11096 "SETB $dst, $crx" %}
11097
11098 size(28);
11099 ins_encode %{
11100 Label done;
11101 // 0x41: A, 0x5A: Z
11102 __ li($src2$$Register, 0x5A41);
11103 // compare src1 with a range 0x41 to 0x5A
11104 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11105 __ bgt($crx$$CondRegister, done);
11106
11107 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
11108 __ lis($src2$$Register, (signed short)0xD6C0);
11109 __ ori($src2$$Register, $src2$$Register, 0xDED8);
11110 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
11111 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11112
11113 __ bind(done);
11114 __ setb($dst$$Register, $crx$$CondRegister);
11115 %}
11116 ins_pipe(pipe_class_default);
11117 %}
11118
11119 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11120 match(Set dst (Whitespace src1));
11121 predicate(PowerArchitecturePPC64 <= 9);
11122 effect(TEMP src2, TEMP crx);
11123 ins_cost(4 * DEFAULT_COST);
11124
11125 format %{ "LI $src2, 0x0D09\n\t"
11126 "ADDIS $src2, 0x201C\n\t"
11127 "CMPRB $crx, 1, $src1, $src2\n\t"
11128 "SETB $dst, $crx" %}
11129 size(16);
11130 ins_encode %{
11131 // 0x09 to 0x0D, 0x1C to 0x20
11132 __ li($src2$$Register, 0x0D09);
11133 __ addis($src2$$Register, $src2$$Register, 0x0201C);
11134 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11135 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11136 __ setb($dst$$Register, $crx$$CondRegister);
11137 %}
11138 ins_pipe(pipe_class_default);
11139 %}
11140
11141 // Power 10 version, using prefixed addi to load 32-bit constant
11142 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11143 match(Set dst (Whitespace src1));
11144 predicate(PowerArchitecturePPC64 >= 10);
11145 effect(TEMP src2, TEMP crx);
11146 ins_cost(3 * DEFAULT_COST);
11147
11148 format %{ "PLI $src2, 0x201C0D09\n\t"
11149 "CMPRB $crx, 1, $src1, $src2\n\t"
11150 "SETB $dst, $crx" %}
11151 size(16);
11152 ins_encode %{
11153 // 0x09 to 0x0D, 0x1C to 0x20
11154 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
11155 __ pli($src2$$Register, 0x201C0D09);
11156 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11157 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11158 __ setb($dst$$Register, $crx$$CondRegister);
11159 %}
11160 ins_pipe(pipe_class_default);
11161 ins_alignment(2);
11162 %}
11163
11164 //----------Branches---------------------------------------------------------
11165 // Jump
11166
11167 // Direct Branch.
11168 instruct branch(label labl) %{
11169 match(Goto);
11170 effect(USE labl);
11171 ins_cost(BRANCH_COST);
11172
11173 format %{ "B $labl" %}
11174 size(4);
11175 ins_encode %{
11176 Label d; // dummy
11177 __ bind(d);
11178 Label* p = $labl$$label;
11179 // `p' is `nullptr' when this encoding class is used only to
11180 // determine the size of the encoded instruction.
11181 Label& l = (nullptr == p)? d : *(p);
11182 __ b(l);
11183 %}
11184 ins_pipe(pipe_class_default);
11185 %}
11186
11187 // Conditional Near Branch
11188 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11189 // Same match rule as `branchConFar'.
11190 match(If cmp crx);
11191 effect(USE lbl);
11192 ins_cost(BRANCH_COST);
11193
11194 // If set to 1 this indicates that the current instruction is a
11195 // short variant of a long branch. This avoids using this
11196 // instruction in first-pass matching. It will then only be used in
11197 // the `Shorten_branches' pass.
11198 ins_short_branch(1);
11199
11200 format %{ "B$cmp $crx, $lbl" %}
11201 size(4);
11202 ins_encode( enc_bc(crx, cmp, lbl) );
11203 ins_pipe(pipe_class_default);
11204 %}
11205
11206 // This is for cases when the ppc64 `bc' instruction does not
11207 // reach far enough. So we emit a far branch here, which is more
11208 // expensive.
11209 //
11210 // Conditional Far Branch
11211 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11212 // Same match rule as `branchCon'.
11213 match(If cmp crx);
11214 effect(USE crx, USE lbl);
11215 // Higher cost than `branchCon'.
11216 ins_cost(5*BRANCH_COST);
11217
11218 // This is not a short variant of a branch, but the long variant.
11219 ins_short_branch(0);
11220
11221 format %{ "B_FAR$cmp $crx, $lbl" %}
11222 size(8);
11223 ins_encode( enc_bc_far(crx, cmp, lbl) );
11224 ins_pipe(pipe_class_default);
11225 %}
11226
11227 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
11228 match(CountedLoopEnd cmp crx);
11229 effect(USE labl);
11230 ins_cost(BRANCH_COST);
11231
11232 // short variant.
11233 ins_short_branch(1);
11234
11235 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
11236 size(4);
11237 ins_encode( enc_bc(crx, cmp, labl) );
11238 ins_pipe(pipe_class_default);
11239 %}
11240
11241 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
11242 match(CountedLoopEnd cmp crx);
11243 effect(USE labl);
11244 ins_cost(BRANCH_COST);
11245
11246 // Long variant.
11247 ins_short_branch(0);
11248
11249 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
11250 size(8);
11251 ins_encode( enc_bc_far(crx, cmp, labl) );
11252 ins_pipe(pipe_class_default);
11253 %}
11254
11255 // ============================================================================
11256 // Java runtime operations, intrinsics and other complex operations.
11257
11258 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
11259 // array for an instance of the superklass. Set a hidden internal cache on a
11260 // hit (cache is checked with exposed code in gen_subtype_check()). Return
11261 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
11262 //
11263 // GL TODO: Improve this.
11264 // - result should not be a TEMP
11265 // - Add match rule as on sparc avoiding additional Cmp.
11266 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
11267 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
11268 match(Set result (PartialSubtypeCheck subklass superklass));
11269 predicate(!UseSecondarySupersTable);
11270 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
11271 ins_cost(DEFAULT_COST*10);
11272
11273 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
11274 ins_encode %{
11275 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
11276 $tmp_klass$$Register, nullptr, $result$$Register);
11277 %}
11278 ins_pipe(pipe_class_default);
11279 %}
11280
11281 // Two versions of partialSubtypeCheck, both used when we need to
11282 // search for a super class in the secondary supers array. The first
11283 // is used when we don't know _a priori_ the class being searched
11284 // for. The second, far more common, is used when we do know: this is
11285 // used for instanceof, checkcast, and any case where C2 can determine
11286 // it by constant propagation.
11287 instruct partialSubtypeCheckVarSuper(iRegPsrc sub, iRegPsrc super, iRegPdst result,
11288 iRegPdst tempR1, iRegPdst tempR2, iRegPdst tempR3, iRegPdst tempR4,
11289 flagsRegCR0 cr0, regCTR ctr)
11290 %{
11291 match(Set result (PartialSubtypeCheck sub super));
11292 predicate(UseSecondarySupersTable);
11293 effect(KILL cr0, KILL ctr, TEMP_DEF result, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11294
11295 ins_cost(DEFAULT_COST * 10); // slightly larger than the next version
11296 format %{ "partialSubtypeCheck $result, $sub, $super" %}
11297 ins_encode %{
11298 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register,
11299 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11300 $result$$Register);
11301 %}
11302 ins_pipe(pipe_class_memory);
11303 %}
11304
11305 instruct partialSubtypeCheckConstSuper(rarg3RegP sub, rarg2RegP super_reg, immP super_con, rarg6RegP result,
11306 rarg1RegP tempR1, rarg5RegP tempR2, rarg4RegP tempR3, rscratch1RegP tempR4,
11307 flagsRegCR0 cr0, regCTR ctr)
11308 %{
11309 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
11310 predicate(UseSecondarySupersTable);
11311 effect(KILL cr0, KILL ctr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11312
11313 ins_cost(DEFAULT_COST*8); // smaller than the other version
11314 format %{ "partialSubtypeCheck $result, $sub, $super_reg" %}
11315
11316 ins_encode %{
11317 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
11318 if (InlineSecondarySupersTest) {
11319 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register,
11320 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11321 $result$$Register, super_klass_slot);
11322 } else {
11323 address stub = StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot);
11324 Register r_stub_addr = $tempR1$$Register;
11325 __ add_const_optimized(r_stub_addr, R29_TOC, MacroAssembler::offset_to_global_toc(stub), R0);
11326 __ mtctr(r_stub_addr);
11327 __ bctrl();
11328 }
11329 %}
11330
11331 ins_pipe(pipe_class_memory);
11332 %}
11333
11334 // inlined locking and unlocking
11335
11336 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
11337 predicate(!UseObjectMonitorTable);
11338 match(Set crx (FastLock oop box));
11339 effect(TEMP tmp1, TEMP tmp2);
11340
11341 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %}
11342 ins_encode %{
11343 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11344 $tmp1$$Register, $tmp2$$Register, noreg /*tmp3*/);
11345 // If locking was successful, crx should indicate 'EQ'.
11346 // The compiler generates a branch to the runtime call to
11347 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11348 %}
11349 ins_pipe(pipe_class_compare);
11350 %}
11351
11352 instruct cmpFastLockMonitorTable(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, flagsRegCR1 cr1) %{
11353 predicate(UseObjectMonitorTable);
11354 match(Set crx (FastLock oop box));
11355 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr1);
11356
11357 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3" %}
11358 ins_encode %{
11359 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11360 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11361 // If locking was successful, crx should indicate 'EQ'.
11362 // The compiler generates a branch to the runtime call to
11363 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11364 %}
11365 ins_pipe(pipe_class_compare);
11366 %}
11367
11368 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11369 match(Set crx (FastUnlock oop box));
11370 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11371
11372 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
11373 ins_encode %{
11374 __ fast_unlock($crx$$CondRegister, $oop$$Register, $box$$Register,
11375 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11376 // If unlocking was successful, crx should indicate 'EQ'.
11377 // The compiler generates a branch to the runtime call to
11378 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11379 %}
11380 ins_pipe(pipe_class_compare);
11381 %}
11382
11383 // Align address.
11384 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11385 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11386
11387 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
11388 size(4);
11389 ins_encode %{
11390 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant));
11391 %}
11392 ins_pipe(pipe_class_default);
11393 %}
11394
11395 // Array size computation.
11396 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11397 match(Set dst (SubL (CastP2X end) (CastP2X start)));
11398
11399 format %{ "SUB $dst, $end, $start \t// array size in bytes" %}
11400 size(4);
11401 ins_encode %{
11402 __ subf($dst$$Register, $start$$Register, $end$$Register);
11403 %}
11404 ins_pipe(pipe_class_default);
11405 %}
11406
11407 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
11408 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11409 match(Set dummy (ClearArray cnt base));
11410 effect(USE_KILL base, KILL ctr);
11411 ins_cost(2 * MEMORY_REF_COST);
11412
11413 format %{ "ClearArray $cnt, $base" %}
11414 ins_encode %{
11415 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
11416 %}
11417 ins_pipe(pipe_class_default);
11418 %}
11419
11420 // Clear-array with constant large array length.
11421 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{
11422 match(Set dummy (ClearArray cnt base));
11423 effect(USE_KILL base, TEMP tmp, KILL ctr);
11424 ins_cost(3 * MEMORY_REF_COST);
11425
11426 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
11427 ins_encode %{
11428 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
11429 %}
11430 ins_pipe(pipe_class_default);
11431 %}
11432
11433 // Clear-array with dynamic array length.
11434 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11435 match(Set dummy (ClearArray cnt base));
11436 effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11437 ins_cost(4 * MEMORY_REF_COST);
11438
11439 format %{ "ClearArray $cnt, $base" %}
11440 ins_encode %{
11441 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
11442 %}
11443 ins_pipe(pipe_class_default);
11444 %}
11445
11446 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11447 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11448 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11449 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11450 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11451 ins_cost(300);
11452 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11453 ins_encode %{
11454 __ string_compare($str1$$Register, $str2$$Register,
11455 $cnt1$$Register, $cnt2$$Register,
11456 $tmp$$Register,
11457 $result$$Register, StrIntrinsicNode::LL);
11458 %}
11459 ins_pipe(pipe_class_default);
11460 %}
11461
11462 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11463 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11464 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11465 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11466 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11467 ins_cost(300);
11468 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11469 ins_encode %{
11470 __ string_compare($str1$$Register, $str2$$Register,
11471 $cnt1$$Register, $cnt2$$Register,
11472 $tmp$$Register,
11473 $result$$Register, StrIntrinsicNode::UU);
11474 %}
11475 ins_pipe(pipe_class_default);
11476 %}
11477
11478 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11479 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11480 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11481 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11482 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11483 ins_cost(300);
11484 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11485 ins_encode %{
11486 __ string_compare($str1$$Register, $str2$$Register,
11487 $cnt1$$Register, $cnt2$$Register,
11488 $tmp$$Register,
11489 $result$$Register, StrIntrinsicNode::LU);
11490 %}
11491 ins_pipe(pipe_class_default);
11492 %}
11493
11494 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11495 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11496 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11497 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11498 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11499 ins_cost(300);
11500 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11501 ins_encode %{
11502 __ string_compare($str2$$Register, $str1$$Register,
11503 $cnt2$$Register, $cnt1$$Register,
11504 $tmp$$Register,
11505 $result$$Register, StrIntrinsicNode::UL);
11506 %}
11507 ins_pipe(pipe_class_default);
11508 %}
11509
11510 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11511 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11512 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11513 match(Set result (StrEquals (Binary str1 str2) cnt));
11514 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11515 ins_cost(300);
11516 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11517 ins_encode %{
11518 __ array_equals(false, $str1$$Register, $str2$$Register,
11519 $cnt$$Register, $tmp$$Register,
11520 $result$$Register, true /* byte */);
11521 %}
11522 ins_pipe(pipe_class_default);
11523 %}
11524
11525 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11526 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11527 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11528 match(Set result (AryEq ary1 ary2));
11529 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11530 ins_cost(300);
11531 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11532 ins_encode %{
11533 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11534 $tmp1$$Register, $tmp2$$Register,
11535 $result$$Register, true /* byte */);
11536 %}
11537 ins_pipe(pipe_class_default);
11538 %}
11539
11540 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11541 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11542 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11543 match(Set result (AryEq ary1 ary2));
11544 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11545 ins_cost(300);
11546 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11547 ins_encode %{
11548 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11549 $tmp1$$Register, $tmp2$$Register,
11550 $result$$Register, false /* byte */);
11551 %}
11552 ins_pipe(pipe_class_default);
11553 %}
11554
11555 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11556 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11557 iRegIdst tmp1, iRegIdst tmp2,
11558 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11559 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11560 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11561 // Required for EA: check if it is still a type_array.
11562 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11563 ins_cost(150);
11564
11565 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11566 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11567
11568 ins_encode %{
11569 immPOper *needleOper = (immPOper *)$needleImm;
11570 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11571 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11572 jchar chr;
11573 #ifdef VM_LITTLE_ENDIAN
11574 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11575 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11576 #else
11577 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11578 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11579 #endif
11580 __ string_indexof_char($result$$Register,
11581 $haystack$$Register, $haycnt$$Register,
11582 R0, chr,
11583 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11584 %}
11585 ins_pipe(pipe_class_compare);
11586 %}
11587
11588 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11589 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11590 iRegIdst tmp1, iRegIdst tmp2,
11591 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11592 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11593 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11594 // Required for EA: check if it is still a type_array.
11595 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11596 ins_cost(150);
11597
11598 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11599 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11600
11601 ins_encode %{
11602 immPOper *needleOper = (immPOper *)$needleImm;
11603 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11604 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11605 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11606 __ string_indexof_char($result$$Register,
11607 $haystack$$Register, $haycnt$$Register,
11608 R0, chr,
11609 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11610 %}
11611 ins_pipe(pipe_class_compare);
11612 %}
11613
11614 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11615 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11616 iRegIdst tmp1, iRegIdst tmp2,
11617 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11618 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11619 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11620 // Required for EA: check if it is still a type_array.
11621 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11622 ins_cost(150);
11623
11624 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11625 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11626
11627 ins_encode %{
11628 immPOper *needleOper = (immPOper *)$needleImm;
11629 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11630 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11631 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11632 __ string_indexof_char($result$$Register,
11633 $haystack$$Register, $haycnt$$Register,
11634 R0, chr,
11635 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11636 %}
11637 ins_pipe(pipe_class_compare);
11638 %}
11639
11640 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11641 rscratch2RegP needle, immI_1 needlecntImm,
11642 iRegIdst tmp1, iRegIdst tmp2,
11643 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11644 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11645 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11646 // Required for EA: check if it is still a type_array.
11647 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11648 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11649 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11650 ins_cost(180);
11651
11652 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11653 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11654 ins_encode %{
11655 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11656 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11657 guarantee(needle_values, "sanity");
11658 jchar chr;
11659 #ifdef VM_LITTLE_ENDIAN
11660 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11661 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11662 #else
11663 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11664 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11665 #endif
11666 __ string_indexof_char($result$$Register,
11667 $haystack$$Register, $haycnt$$Register,
11668 R0, chr,
11669 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11670 %}
11671 ins_pipe(pipe_class_compare);
11672 %}
11673
11674 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11675 rscratch2RegP needle, immI_1 needlecntImm,
11676 iRegIdst tmp1, iRegIdst tmp2,
11677 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11678 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11679 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11680 // Required for EA: check if it is still a type_array.
11681 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11682 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11683 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11684 ins_cost(180);
11685
11686 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11687 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11688 ins_encode %{
11689 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11690 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11691 guarantee(needle_values, "sanity");
11692 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11693 __ string_indexof_char($result$$Register,
11694 $haystack$$Register, $haycnt$$Register,
11695 R0, chr,
11696 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11697 %}
11698 ins_pipe(pipe_class_compare);
11699 %}
11700
11701 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11702 rscratch2RegP needle, immI_1 needlecntImm,
11703 iRegIdst tmp1, iRegIdst tmp2,
11704 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11705 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11706 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11707 // Required for EA: check if it is still a type_array.
11708 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11709 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11710 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11711 ins_cost(180);
11712
11713 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11714 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11715 ins_encode %{
11716 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11717 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11718 guarantee(needle_values, "sanity");
11719 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11720 __ string_indexof_char($result$$Register,
11721 $haystack$$Register, $haycnt$$Register,
11722 R0, chr,
11723 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11724 %}
11725 ins_pipe(pipe_class_compare);
11726 %}
11727
11728 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11729 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11730 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11731 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11732 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11733 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
11734 ins_cost(180);
11735
11736 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch"
11737 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11738 ins_encode %{
11739 __ string_indexof_char($result$$Register,
11740 $haystack$$Register, $haycnt$$Register,
11741 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11742 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11743 %}
11744 ins_pipe(pipe_class_compare);
11745 %}
11746
11747 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11748 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11749 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11750 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11751 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11752 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
11753 ins_cost(180);
11754
11755 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch"
11756 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11757 ins_encode %{
11758 __ string_indexof_char($result$$Register,
11759 $haystack$$Register, $haycnt$$Register,
11760 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11761 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11762 %}
11763 ins_pipe(pipe_class_compare);
11764 %}
11765
11766 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11767 iRegPsrc needle, uimmI15 needlecntImm,
11768 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11769 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11770 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11771 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11772 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11773 // Required for EA: check if it is still a type_array.
11774 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11775 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11776 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11777 ins_cost(250);
11778
11779 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11780 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11781 ins_encode %{
11782 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11783 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11784
11785 __ string_indexof($result$$Register,
11786 $haystack$$Register, $haycnt$$Register,
11787 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11788 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11789 %}
11790 ins_pipe(pipe_class_compare);
11791 %}
11792
11793 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11794 iRegPsrc needle, uimmI15 needlecntImm,
11795 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11796 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11797 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11798 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11799 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11800 // Required for EA: check if it is still a type_array.
11801 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11802 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11803 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11804 ins_cost(250);
11805
11806 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11807 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11808 ins_encode %{
11809 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11810 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11811
11812 __ string_indexof($result$$Register,
11813 $haystack$$Register, $haycnt$$Register,
11814 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11815 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11816 %}
11817 ins_pipe(pipe_class_compare);
11818 %}
11819
11820 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11821 iRegPsrc needle, uimmI15 needlecntImm,
11822 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11823 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11824 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11825 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11826 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11827 // Required for EA: check if it is still a type_array.
11828 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11829 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11830 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11831 ins_cost(250);
11832
11833 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11834 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11835 ins_encode %{
11836 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11837 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11838
11839 __ string_indexof($result$$Register,
11840 $haystack$$Register, $haycnt$$Register,
11841 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11842 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11843 %}
11844 ins_pipe(pipe_class_compare);
11845 %}
11846
11847 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11848 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11849 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11850 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11851 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11852 TEMP_DEF result,
11853 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11854 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11855 ins_cost(300);
11856
11857 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11858 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11859 ins_encode %{
11860 __ string_indexof($result$$Register,
11861 $haystack$$Register, $haycnt$$Register,
11862 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11863 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11864 %}
11865 ins_pipe(pipe_class_compare);
11866 %}
11867
11868 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11869 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11870 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11871 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11872 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11873 TEMP_DEF result,
11874 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11875 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11876 ins_cost(300);
11877
11878 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11879 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11880 ins_encode %{
11881 __ string_indexof($result$$Register,
11882 $haystack$$Register, $haycnt$$Register,
11883 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11884 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11885 %}
11886 ins_pipe(pipe_class_compare);
11887 %}
11888
11889 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11890 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11891 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11892 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11893 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11894 TEMP_DEF result,
11895 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11896 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11897 ins_cost(300);
11898
11899 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11900 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11901 ins_encode %{
11902 __ string_indexof($result$$Register,
11903 $haystack$$Register, $haycnt$$Register,
11904 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11905 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11906 %}
11907 ins_pipe(pipe_class_compare);
11908 %}
11909
11910 // char[] to byte[] compression
11911 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11912 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11913 match(Set result (StrCompressedCopy src (Binary dst len)));
11914 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11915 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11916 ins_cost(300);
11917 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11918 ins_encode %{
11919 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11920 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11921 %}
11922 ins_pipe(pipe_class_default);
11923 %}
11924
11925 // byte[] to char[] inflation
11926 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
11927 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11928 match(Set dummy (StrInflatedCopy src (Binary dst len)));
11929 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11930 ins_cost(300);
11931 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11932 ins_encode %{
11933 Label Ldone;
11934 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
11935 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11936 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
11937 __ beq(CR0, Ldone);
11938 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
11939 __ bind(Ldone);
11940 %}
11941 ins_pipe(pipe_class_default);
11942 %}
11943
11944 // StringCoding.java intrinsics
11945 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
11946 regCTR ctr, flagsRegCR0 cr0)
11947 %{
11948 match(Set result (CountPositives ary1 len));
11949 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
11950 ins_cost(300);
11951 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
11952 ins_encode %{
11953 __ count_positives($ary1$$Register, $len$$Register, $result$$Register,
11954 $tmp1$$Register, $tmp2$$Register);
11955 %}
11956 ins_pipe(pipe_class_default);
11957 %}
11958
11959 // encode char[] to byte[] in ISO_8859_1
11960 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11961 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11962 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
11963 match(Set result (EncodeISOArray src (Binary dst len)));
11964 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11965 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11966 ins_cost(300);
11967 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11968 ins_encode %{
11969 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11970 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11971 %}
11972 ins_pipe(pipe_class_default);
11973 %}
11974
11975 // encode char[] to byte[] in ASCII
11976 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11977 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11978 predicate(((EncodeISOArrayNode*)n)->is_ascii());
11979 match(Set result (EncodeISOArray src (Binary dst len)));
11980 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11981 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11982 ins_cost(300);
11983 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11984 ins_encode %{
11985 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11986 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
11987 %}
11988 ins_pipe(pipe_class_default);
11989 %}
11990
11991
11992 //---------- Min/Max Instructions ---------------------------------------------
11993
11994
11995 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
11996 match(Set dst (MinI src1 src2));
11997 effect(KILL cr0);
11998 ins_cost(DEFAULT_COST*2);
11999
12000 size(8);
12001 ins_encode %{
12002 __ cmpw(CR0, $src1$$Register, $src2$$Register);
12003 __ isel($dst$$Register, CR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
12004 %}
12005 ins_pipe(pipe_class_default);
12006 %}
12007
12008
12009 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12010 match(Set dst (MaxI src1 src2));
12011 effect(KILL cr0);
12012 ins_cost(DEFAULT_COST*2);
12013
12014 size(8);
12015 ins_encode %{
12016 __ cmpw(CR0, $src1$$Register, $src2$$Register);
12017 __ isel($dst$$Register, CR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
12018 %}
12019 ins_pipe(pipe_class_default);
12020 %}
12021
12022 instruct minF(regF dst, regF src1, regF src2) %{
12023 match(Set dst (MinF src1 src2));
12024 predicate(PowerArchitecturePPC64 >= 9);
12025 ins_cost(DEFAULT_COST);
12026
12027 format %{ "XSMINJDP $dst, $src1, $src2\t// MinF" %}
12028 size(4);
12029 ins_encode %{
12030 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12031 %}
12032 ins_pipe(pipe_class_default);
12033 %}
12034
12035 instruct minD(regD dst, regD src1, regD src2) %{
12036 match(Set dst (MinD src1 src2));
12037 predicate(PowerArchitecturePPC64 >= 9);
12038 ins_cost(DEFAULT_COST);
12039
12040 format %{ "XSMINJDP $dst, $src1, $src2\t// MinD" %}
12041 size(4);
12042 ins_encode %{
12043 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12044 %}
12045 ins_pipe(pipe_class_default);
12046 %}
12047
12048 instruct maxF(regF dst, regF src1, regF src2) %{
12049 match(Set dst (MaxF src1 src2));
12050 predicate(PowerArchitecturePPC64 >= 9);
12051 ins_cost(DEFAULT_COST);
12052
12053 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxF" %}
12054 size(4);
12055 ins_encode %{
12056 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12057 %}
12058 ins_pipe(pipe_class_default);
12059 %}
12060
12061 instruct maxD(regD dst, regD src1, regD src2) %{
12062 match(Set dst (MaxD src1 src2));
12063 predicate(PowerArchitecturePPC64 >= 9);
12064 ins_cost(DEFAULT_COST);
12065
12066 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxD" %}
12067 size(4);
12068 ins_encode %{
12069 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12070 %}
12071 ins_pipe(pipe_class_default);
12072 %}
12073
12074 //---------- Population Count Instructions ------------------------------------
12075
12076 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
12077 match(Set dst (PopCountI src));
12078 predicate(UsePopCountInstruction);
12079 ins_cost(DEFAULT_COST);
12080
12081 format %{ "POPCNTW $dst, $src" %}
12082 size(4);
12083 ins_encode %{
12084 __ popcntw($dst$$Register, $src$$Register);
12085 %}
12086 ins_pipe(pipe_class_default);
12087 %}
12088
12089 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
12090 predicate(UsePopCountInstruction);
12091 match(Set dst (PopCountL src));
12092 ins_cost(DEFAULT_COST);
12093
12094 format %{ "POPCNTD $dst, $src" %}
12095 size(4);
12096 ins_encode %{
12097 __ popcntd($dst$$Register, $src$$Register);
12098 %}
12099 ins_pipe(pipe_class_default);
12100 %}
12101
12102 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
12103 match(Set dst (CountLeadingZerosI src));
12104 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12105 ins_cost(DEFAULT_COST);
12106
12107 format %{ "CNTLZW $dst, $src" %}
12108 size(4);
12109 ins_encode %{
12110 __ cntlzw($dst$$Register, $src$$Register);
12111 %}
12112 ins_pipe(pipe_class_default);
12113 %}
12114
12115 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
12116 match(Set dst (CountLeadingZerosL src));
12117 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12118 ins_cost(DEFAULT_COST);
12119
12120 format %{ "CNTLZD $dst, $src" %}
12121 size(4);
12122 ins_encode %{
12123 __ cntlzd($dst$$Register, $src$$Register);
12124 %}
12125 ins_pipe(pipe_class_default);
12126 %}
12127
12128 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
12129 // no match-rule, false predicate
12130 effect(DEF dst, USE src);
12131 predicate(false);
12132
12133 format %{ "CNTLZD $dst, $src" %}
12134 size(4);
12135 ins_encode %{
12136 __ cntlzd($dst$$Register, $src$$Register);
12137 %}
12138 ins_pipe(pipe_class_default);
12139 %}
12140
12141 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
12142 match(Set dst (CountTrailingZerosI src));
12143 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12144 ins_cost(DEFAULT_COST);
12145
12146 expand %{
12147 immI16 imm1 %{ (int)-1 %}
12148 immI16 imm2 %{ (int)32 %}
12149 immI_minus1 m1 %{ -1 %}
12150 iRegIdst tmpI1;
12151 iRegIdst tmpI2;
12152 iRegIdst tmpI3;
12153 addI_reg_imm16(tmpI1, src, imm1);
12154 andcI_reg_reg(tmpI2, src, m1, tmpI1);
12155 countLeadingZerosI(tmpI3, tmpI2);
12156 subI_imm16_reg(dst, imm2, tmpI3);
12157 %}
12158 %}
12159
12160 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{
12161 match(Set dst (CountTrailingZerosI src));
12162 predicate(UseCountTrailingZerosInstructionsPPC64);
12163 ins_cost(DEFAULT_COST);
12164
12165 format %{ "CNTTZW $dst, $src" %}
12166 size(4);
12167 ins_encode %{
12168 __ cnttzw($dst$$Register, $src$$Register);
12169 %}
12170 ins_pipe(pipe_class_default);
12171 %}
12172
12173 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
12174 match(Set dst (CountTrailingZerosL src));
12175 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12176 ins_cost(DEFAULT_COST);
12177
12178 expand %{
12179 immL16 imm1 %{ (long)-1 %}
12180 immI16 imm2 %{ (int)64 %}
12181 iRegLdst tmpL1;
12182 iRegLdst tmpL2;
12183 iRegIdst tmpL3;
12184 addL_reg_imm16(tmpL1, src, imm1);
12185 andcL_reg_reg(tmpL2, tmpL1, src);
12186 countLeadingZerosL(tmpL3, tmpL2);
12187 subI_imm16_reg(dst, imm2, tmpL3);
12188 %}
12189 %}
12190
12191 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{
12192 match(Set dst (CountTrailingZerosL src));
12193 predicate(UseCountTrailingZerosInstructionsPPC64);
12194 ins_cost(DEFAULT_COST);
12195
12196 format %{ "CNTTZD $dst, $src" %}
12197 size(4);
12198 ins_encode %{
12199 __ cnttzd($dst$$Register, $src$$Register);
12200 %}
12201 ins_pipe(pipe_class_default);
12202 %}
12203
12204 // Expand nodes for byte_reverse_int/ushort/short.
12205 instruct rlwinm(iRegIdst dst, iRegIsrc src, immI16 shift, immI16 mb, immI16 me) %{
12206 effect(DEF dst, USE src, USE shift, USE mb, USE me);
12207 predicate(false);
12208
12209 format %{ "RLWINM $dst, $src, $shift, $mb, $me" %}
12210 size(4);
12211 ins_encode %{
12212 __ rlwinm($dst$$Register, $src$$Register, $shift$$constant, $mb$$constant, $me$$constant);
12213 %}
12214 ins_pipe(pipe_class_default);
12215 %}
12216
12217 // Expand nodes for byte_reverse_int.
12218 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
12219 effect(DEF dst, USE src, USE n, USE b);
12220 predicate(false);
12221
12222 format %{ "INSRWI $dst, $src, $n, $b" %}
12223 size(4);
12224 ins_encode %{
12225 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
12226 %}
12227 ins_pipe(pipe_class_default);
12228 %}
12229
12230 // As insrwi_a, but with USE_DEF.
12231 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
12232 effect(USE_DEF dst, USE src, USE n, USE b);
12233 predicate(false);
12234
12235 format %{ "INSRWI $dst, $src, $n, $b" %}
12236 size(4);
12237 ins_encode %{
12238 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
12239 %}
12240 ins_pipe(pipe_class_default);
12241 %}
12242
12243 // Just slightly faster than java implementation.
12244 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
12245 match(Set dst (ReverseBytesI src));
12246 predicate(!UseByteReverseInstructions);
12247 ins_cost(7*DEFAULT_COST);
12248
12249 expand %{
12250 immI16 imm24 %{ (int) 24 %}
12251 immI16 imm16 %{ (int) 16 %}
12252 immI16 imm8 %{ (int) 8 %}
12253 immI16 imm4 %{ (int) 4 %}
12254 immI16 imm0 %{ (int) 0 %}
12255 iRegLdst tmpI1;
12256 iRegLdst tmpI2;
12257 iRegLdst tmpI3;
12258
12259 urShiftI_reg_imm(tmpI1, src, imm24);
12260 insrwi_a(dst, tmpI1, imm8, imm24);
12261 urShiftI_reg_imm(tmpI2, src, imm16);
12262 insrwi(dst, tmpI2, imm16, imm8);
12263 urShiftI_reg_imm(tmpI3, src, imm8);
12264 insrwi(dst, tmpI3, imm8, imm8);
12265 insrwi(dst, src, imm8, imm0);
12266 %}
12267 %}
12268
12269 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{
12270 match(Set dst (ReverseBytesI src));
12271 predicate(UseVectorByteReverseInstructionsPPC64);
12272 effect(TEMP tmpV);
12273 ins_cost(DEFAULT_COST*3);
12274 size(12);
12275 format %{ "MTVSRWZ $tmpV, $src\n"
12276 "\tXXBRW $tmpV, $tmpV\n"
12277 "\tMFVSRWZ $dst, $tmpV" %}
12278
12279 ins_encode %{
12280 __ mtvsrwz($tmpV$$VectorRegister.to_vsr(), $src$$Register);
12281 __ xxbrw($tmpV$$VectorRegister.to_vsr(), $tmpV$$VectorRegister->to_vsr());
12282 __ mfvsrwz($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12283 %}
12284 ins_pipe(pipe_class_default);
12285 %}
12286
12287 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{
12288 match(Set dst (ReverseBytesI src));
12289 predicate(UseByteReverseInstructions);
12290 ins_cost(DEFAULT_COST);
12291 size(4);
12292
12293 format %{ "BRW $dst, $src" %}
12294
12295 ins_encode %{
12296 __ brw($dst$$Register, $src$$Register);
12297 %}
12298 ins_pipe(pipe_class_default);
12299 %}
12300
12301 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
12302 match(Set dst (ReverseBytesL src));
12303 predicate(!UseByteReverseInstructions);
12304 ins_cost(15*DEFAULT_COST);
12305
12306 expand %{
12307 immI16 imm56 %{ (int) 56 %}
12308 immI16 imm48 %{ (int) 48 %}
12309 immI16 imm40 %{ (int) 40 %}
12310 immI16 imm32 %{ (int) 32 %}
12311 immI16 imm24 %{ (int) 24 %}
12312 immI16 imm16 %{ (int) 16 %}
12313 immI16 imm8 %{ (int) 8 %}
12314 immI16 imm0 %{ (int) 0 %}
12315 iRegLdst tmpL1;
12316 iRegLdst tmpL2;
12317 iRegLdst tmpL3;
12318 iRegLdst tmpL4;
12319 iRegLdst tmpL5;
12320 iRegLdst tmpL6;
12321
12322 // src : |a|b|c|d|e|f|g|h|
12323 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
12324 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
12325 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
12326 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
12327 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
12328 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
12329 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
12330 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
12331 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
12332 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
12333 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
12334 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
12335 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
12336 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
12337 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
12338 %}
12339 %}
12340
12341 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{
12342 match(Set dst (ReverseBytesL src));
12343 predicate(UseVectorByteReverseInstructionsPPC64);
12344 effect(TEMP tmpV);
12345 ins_cost(DEFAULT_COST*3);
12346 size(12);
12347 format %{ "MTVSRD $tmpV, $src\n"
12348 "\tXXBRD $tmpV, $tmpV\n"
12349 "\tMFVSRD $dst, $tmpV" %}
12350
12351 ins_encode %{
12352 __ mtvsrd($tmpV$$VectorRegister->to_vsr(), $src$$Register);
12353 __ xxbrd($tmpV$$VectorRegister->to_vsr(), $tmpV$$VectorRegister->to_vsr());
12354 __ mfvsrd($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12355 %}
12356 ins_pipe(pipe_class_default);
12357 %}
12358
12359 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{
12360 match(Set dst (ReverseBytesL src));
12361 predicate(UseByteReverseInstructions);
12362 ins_cost(DEFAULT_COST);
12363 size(4);
12364
12365 format %{ "BRD $dst, $src" %}
12366
12367 ins_encode %{
12368 __ brd($dst$$Register, $src$$Register);
12369 %}
12370 ins_pipe(pipe_class_default);
12371 %}
12372
12373 // Need zero extend. Must not use brh only.
12374 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
12375 match(Set dst (ReverseBytesUS src));
12376 ins_cost(2*DEFAULT_COST);
12377
12378 expand %{
12379 immI16 imm31 %{ (int) 31 %}
12380 immI16 imm24 %{ (int) 24 %}
12381 immI16 imm16 %{ (int) 16 %}
12382 immI16 imm8 %{ (int) 8 %}
12383
12384 rlwinm(dst, src, imm24, imm24, imm31);
12385 insrwi(dst, src, imm8, imm16);
12386 %}
12387 %}
12388
12389 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
12390 match(Set dst (ReverseBytesS src));
12391 predicate(!UseByteReverseInstructions);
12392 ins_cost(3*DEFAULT_COST);
12393
12394 expand %{
12395 immI16 imm16 %{ (int) 16 %}
12396 immI16 imm8 %{ (int) 8 %}
12397 iRegLdst tmpI1;
12398
12399 urShiftI_reg_imm(tmpI1, src, imm8);
12400 insrwi(tmpI1, src, imm8, imm16);
12401 extsh(dst, tmpI1);
12402 %}
12403 %}
12404
12405 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{
12406 match(Set dst (ReverseBytesS src));
12407 predicate(UseByteReverseInstructions);
12408 ins_cost(DEFAULT_COST);
12409 size(8);
12410
12411 format %{ "BRH $dst, $src\n\t"
12412 "EXTSH $dst, $dst" %}
12413
12414 ins_encode %{
12415 __ brh($dst$$Register, $src$$Register);
12416 __ extsh($dst$$Register, $dst$$Register);
12417 %}
12418 ins_pipe(pipe_class_default);
12419 %}
12420
12421 // Load Integer reversed byte order
12422 instruct loadI_reversed(iRegIdst dst, indirect mem) %{
12423 match(Set dst (ReverseBytesI (LoadI mem)));
12424 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12425 ins_cost(MEMORY_REF_COST);
12426
12427 size(4);
12428 ins_encode %{
12429 __ lwbrx($dst$$Register, $mem$$Register);
12430 %}
12431 ins_pipe(pipe_class_default);
12432 %}
12433
12434 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{
12435 match(Set dst (ReverseBytesI (LoadI mem)));
12436 ins_cost(2 * MEMORY_REF_COST);
12437
12438 size(12);
12439 ins_encode %{
12440 __ lwbrx($dst$$Register, $mem$$Register);
12441 __ twi_0($dst$$Register);
12442 __ isync();
12443 %}
12444 ins_pipe(pipe_class_default);
12445 %}
12446
12447 // Load Long - aligned and reversed
12448 instruct loadL_reversed(iRegLdst dst, indirect mem) %{
12449 match(Set dst (ReverseBytesL (LoadL mem)));
12450 predicate((n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))));
12451 ins_cost(MEMORY_REF_COST);
12452
12453 size(4);
12454 ins_encode %{
12455 __ ldbrx($dst$$Register, $mem$$Register);
12456 %}
12457 ins_pipe(pipe_class_default);
12458 %}
12459
12460 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{
12461 match(Set dst (ReverseBytesL (LoadL mem)));
12462 ins_cost(2 * MEMORY_REF_COST);
12463
12464 size(12);
12465 ins_encode %{
12466 __ ldbrx($dst$$Register, $mem$$Register);
12467 __ twi_0($dst$$Register);
12468 __ isync();
12469 %}
12470 ins_pipe(pipe_class_default);
12471 %}
12472
12473 // Load unsigned short / char reversed byte order
12474 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
12475 match(Set dst (ReverseBytesUS (LoadUS mem)));
12476 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12477 ins_cost(MEMORY_REF_COST);
12478
12479 size(4);
12480 ins_encode %{
12481 __ lhbrx($dst$$Register, $mem$$Register);
12482 %}
12483 ins_pipe(pipe_class_default);
12484 %}
12485
12486 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{
12487 match(Set dst (ReverseBytesUS (LoadUS mem)));
12488 ins_cost(2 * MEMORY_REF_COST);
12489
12490 size(12);
12491 ins_encode %{
12492 __ lhbrx($dst$$Register, $mem$$Register);
12493 __ twi_0($dst$$Register);
12494 __ isync();
12495 %}
12496 ins_pipe(pipe_class_default);
12497 %}
12498
12499 // Load short reversed byte order
12500 instruct loadS_reversed(iRegIdst dst, indirect mem) %{
12501 match(Set dst (ReverseBytesS (LoadS mem)));
12502 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12503 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
12504
12505 size(8);
12506 ins_encode %{
12507 __ lhbrx($dst$$Register, $mem$$Register);
12508 __ extsh($dst$$Register, $dst$$Register);
12509 %}
12510 ins_pipe(pipe_class_default);
12511 %}
12512
12513 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{
12514 match(Set dst (ReverseBytesS (LoadS mem)));
12515 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12516
12517 size(16);
12518 ins_encode %{
12519 __ lhbrx($dst$$Register, $mem$$Register);
12520 __ twi_0($dst$$Register);
12521 __ extsh($dst$$Register, $dst$$Register);
12522 __ isync();
12523 %}
12524 ins_pipe(pipe_class_default);
12525 %}
12526
12527 // Store Integer reversed byte order
12528 instruct storeI_reversed(iRegIsrc src, indirect mem) %{
12529 match(Set mem (StoreI mem (ReverseBytesI src)));
12530 ins_cost(MEMORY_REF_COST);
12531
12532 size(4);
12533 ins_encode %{
12534 __ stwbrx($src$$Register, $mem$$Register);
12535 %}
12536 ins_pipe(pipe_class_default);
12537 %}
12538
12539 // Store Long reversed byte order
12540 instruct storeL_reversed(iRegLsrc src, indirect mem) %{
12541 match(Set mem (StoreL mem (ReverseBytesL src)));
12542 ins_cost(MEMORY_REF_COST);
12543
12544 size(4);
12545 ins_encode %{
12546 __ stdbrx($src$$Register, $mem$$Register);
12547 %}
12548 ins_pipe(pipe_class_default);
12549 %}
12550
12551 // Store unsigned short / char reversed byte order
12552 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
12553 match(Set mem (StoreC mem (ReverseBytesUS src)));
12554 ins_cost(MEMORY_REF_COST);
12555
12556 size(4);
12557 ins_encode %{
12558 __ sthbrx($src$$Register, $mem$$Register);
12559 %}
12560 ins_pipe(pipe_class_default);
12561 %}
12562
12563 // Store short reversed byte order
12564 instruct storeS_reversed(iRegIsrc src, indirect mem) %{
12565 match(Set mem (StoreC mem (ReverseBytesS src)));
12566 ins_cost(MEMORY_REF_COST);
12567
12568 size(4);
12569 ins_encode %{
12570 __ sthbrx($src$$Register, $mem$$Register);
12571 %}
12572 ins_pipe(pipe_class_default);
12573 %}
12574
12575 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
12576 effect(DEF temp1, USE src);
12577
12578 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %}
12579 size(4);
12580 ins_encode %{
12581 __ mtvsrwz($temp1$$VectorRegister->to_vsr(), $src$$Register);
12582 %}
12583 ins_pipe(pipe_class_default);
12584 %}
12585
12586 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{
12587 effect(DEF dst, USE src, USE imm1);
12588
12589 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %}
12590 size(4);
12591 ins_encode %{
12592 __ xxspltw($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $imm1$$constant);
12593 %}
12594 ins_pipe(pipe_class_default);
12595 %}
12596
12597 instruct xscvdpspn_regF(vecX dst, regF src) %{
12598 effect(DEF dst, USE src);
12599
12600 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %}
12601 size(4);
12602 ins_encode %{
12603 __ xscvdpspn($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr());
12604 %}
12605 ins_pipe(pipe_class_default);
12606 %}
12607
12608 //---------- Replicate Vector Instructions ------------------------------------
12609
12610 // Insrdi does replicate if src == dst.
12611 instruct repl32(iRegLdst dst) %{
12612 predicate(false);
12613 effect(USE_DEF dst);
12614
12615 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %}
12616 size(4);
12617 ins_encode %{
12618 __ insrdi($dst$$Register, $dst$$Register, 32, 0);
12619 %}
12620 ins_pipe(pipe_class_default);
12621 %}
12622
12623 // Insrdi does replicate if src == dst.
12624 instruct repl48(iRegLdst dst) %{
12625 predicate(false);
12626 effect(USE_DEF dst);
12627
12628 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %}
12629 size(4);
12630 ins_encode %{
12631 __ insrdi($dst$$Register, $dst$$Register, 48, 0);
12632 %}
12633 ins_pipe(pipe_class_default);
12634 %}
12635
12636 // Insrdi does replicate if src == dst.
12637 instruct repl56(iRegLdst dst) %{
12638 predicate(false);
12639 effect(USE_DEF dst);
12640
12641 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %}
12642 size(4);
12643 ins_encode %{
12644 __ insrdi($dst$$Register, $dst$$Register, 56, 0);
12645 %}
12646 ins_pipe(pipe_class_default);
12647 %}
12648
12649 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12650 match(Set dst (Replicate src));
12651 predicate(n->as_Vector()->length() == 8 &&
12652 Matcher::vector_element_basic_type(n) == T_BYTE);
12653 expand %{
12654 moveReg(dst, src);
12655 repl56(dst);
12656 repl48(dst);
12657 repl32(dst);
12658 %}
12659 %}
12660
12661 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
12662 match(Set dst (Replicate zero));
12663 predicate(n->as_Vector()->length() == 8 &&
12664 Matcher::vector_element_basic_type(n) == T_BYTE);
12665 format %{ "LI $dst, #0 \t// replicate8B" %}
12666 size(4);
12667 ins_encode %{
12668 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12669 %}
12670 ins_pipe(pipe_class_default);
12671 %}
12672
12673 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
12674 match(Set dst (Replicate src));
12675 predicate(n->as_Vector()->length() == 8 &&
12676 Matcher::vector_element_basic_type(n) == T_BYTE);
12677 format %{ "LI $dst, #-1 \t// replicate8B" %}
12678 size(4);
12679 ins_encode %{
12680 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12681 %}
12682 ins_pipe(pipe_class_default);
12683 %}
12684
12685 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{
12686 match(Set dst (Replicate src));
12687 predicate(n->as_Vector()->length() == 16 &&
12688 Matcher::vector_element_basic_type(n) == T_BYTE);
12689
12690 expand %{
12691 iRegLdst tmpL;
12692 vecX tmpV;
12693 immI8 imm1 %{ (int) 1 %}
12694 moveReg(tmpL, src);
12695 repl56(tmpL);
12696 repl48(tmpL);
12697 mtvsrwz(tmpV, tmpL);
12698 xxspltw(dst, tmpV, imm1);
12699 %}
12700 %}
12701
12702 instruct repl16B_immI0(vecX dst, immI_0 zero) %{
12703 match(Set dst (Replicate zero));
12704 predicate(n->as_Vector()->length() == 16 &&
12705 Matcher::vector_element_basic_type(n) == T_BYTE);
12706
12707 format %{ "XXLXOR $dst, $zero \t// replicate16B" %}
12708 size(4);
12709 ins_encode %{
12710 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12711 %}
12712 ins_pipe(pipe_class_default);
12713 %}
12714
12715 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{
12716 match(Set dst (Replicate src));
12717 predicate(n->as_Vector()->length() == 16 &&
12718 Matcher::vector_element_basic_type(n) == T_BYTE);
12719
12720 format %{ "XXLEQV $dst, $src \t// replicate16B" %}
12721 size(4);
12722 ins_encode %{
12723 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12724 %}
12725 ins_pipe(pipe_class_default);
12726 %}
12727
12728 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12729 match(Set dst (Replicate src));
12730 predicate(n->as_Vector()->length() == 4 &&
12731 Matcher::vector_element_basic_type(n) == T_SHORT);
12732 expand %{
12733 moveReg(dst, src);
12734 repl48(dst);
12735 repl32(dst);
12736 %}
12737 %}
12738
12739 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
12740 match(Set dst (Replicate zero));
12741 predicate(n->as_Vector()->length() == 4 &&
12742 Matcher::vector_element_basic_type(n) == T_SHORT);
12743 format %{ "LI $dst, #0 \t// replicate4S" %}
12744 size(4);
12745 ins_encode %{
12746 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12747 %}
12748 ins_pipe(pipe_class_default);
12749 %}
12750
12751 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
12752 match(Set dst (Replicate src));
12753 predicate(n->as_Vector()->length() == 4 &&
12754 Matcher::vector_element_basic_type(n) == T_SHORT);
12755 format %{ "LI $dst, -1 \t// replicate4S" %}
12756 size(4);
12757 ins_encode %{
12758 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12759 %}
12760 ins_pipe(pipe_class_default);
12761 %}
12762
12763 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{
12764 match(Set dst (Replicate src));
12765 predicate(n->as_Vector()->length() == 8 &&
12766 Matcher::vector_element_basic_type(n) == T_SHORT);
12767
12768 expand %{
12769 iRegLdst tmpL;
12770 vecX tmpV;
12771 immI8 zero %{ (int) 0 %}
12772 moveReg(tmpL, src);
12773 repl48(tmpL);
12774 repl32(tmpL);
12775 mtvsrd(tmpV, tmpL);
12776 xxpermdi(dst, tmpV, tmpV, zero);
12777 %}
12778 %}
12779
12780 instruct repl8S_immI0(vecX dst, immI_0 zero) %{
12781 match(Set dst (Replicate zero));
12782 predicate(n->as_Vector()->length() == 8 &&
12783 Matcher::vector_element_basic_type(n) == T_SHORT);
12784
12785 format %{ "XXLXOR $dst, $zero \t// replicate8S" %}
12786 size(4);
12787 ins_encode %{
12788 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12789 %}
12790 ins_pipe(pipe_class_default);
12791 %}
12792
12793 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{
12794 match(Set dst (Replicate src));
12795 predicate(n->as_Vector()->length() == 8 &&
12796 Matcher::vector_element_basic_type(n) == T_SHORT);
12797
12798 format %{ "XXLEQV $dst, $src \t// replicate8S" %}
12799 size(4);
12800 ins_encode %{
12801 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12802 %}
12803 ins_pipe(pipe_class_default);
12804 %}
12805
12806 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12807 match(Set dst (Replicate src));
12808 predicate(n->as_Vector()->length() == 2 &&
12809 Matcher::vector_element_basic_type(n) == T_INT);
12810 ins_cost(2 * DEFAULT_COST);
12811 expand %{
12812 moveReg(dst, src);
12813 repl32(dst);
12814 %}
12815 %}
12816
12817 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
12818 match(Set dst (Replicate zero));
12819 predicate(n->as_Vector()->length() == 2 &&
12820 Matcher::vector_element_basic_type(n) == T_INT);
12821 format %{ "LI $dst, #0 \t// replicate2I" %}
12822 size(4);
12823 ins_encode %{
12824 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12825 %}
12826 ins_pipe(pipe_class_default);
12827 %}
12828
12829 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
12830 match(Set dst (Replicate src));
12831 predicate(n->as_Vector()->length() == 2 &&
12832 Matcher::vector_element_basic_type(n) == T_INT);
12833 format %{ "LI $dst, -1 \t// replicate2I" %}
12834 size(4);
12835 ins_encode %{
12836 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12837 %}
12838 ins_pipe(pipe_class_default);
12839 %}
12840
12841 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{
12842 match(Set dst (Replicate src));
12843 predicate(n->as_Vector()->length() == 4 &&
12844 Matcher::vector_element_basic_type(n) == T_INT);
12845 ins_cost(2 * DEFAULT_COST);
12846
12847 expand %{
12848 iRegLdst tmpL;
12849 vecX tmpV;
12850 immI8 zero %{ (int) 0 %}
12851 moveReg(tmpL, src);
12852 repl32(tmpL);
12853 mtvsrd(tmpV, tmpL);
12854 xxpermdi(dst, tmpV, tmpV, zero);
12855 %}
12856 %}
12857
12858 instruct repl4I_immI0(vecX dst, immI_0 zero) %{
12859 match(Set dst (Replicate zero));
12860 predicate(n->as_Vector()->length() == 4 &&
12861 Matcher::vector_element_basic_type(n) == T_INT);
12862
12863 format %{ "XXLXOR $dst, $zero \t// replicate4I" %}
12864 size(4);
12865 ins_encode %{
12866 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12867 %}
12868 ins_pipe(pipe_class_default);
12869 %}
12870
12871 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{
12872 match(Set dst (Replicate src));
12873 predicate(n->as_Vector()->length() == 4 &&
12874 Matcher::vector_element_basic_type(n) == T_INT);
12875
12876 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %}
12877 size(4);
12878 ins_encode %{
12879 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12880 %}
12881 ins_pipe(pipe_class_default);
12882 %}
12883
12884 // Move float to int register via stack, replicate.
12885 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
12886 match(Set dst (Replicate src));
12887 predicate(n->as_Vector()->length() == 2 &&
12888 Matcher::vector_element_basic_type(n) == T_FLOAT);
12889 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12890 expand %{
12891 stackSlotL tmpS;
12892 iRegIdst tmpI;
12893 moveF2I_reg_stack(tmpS, src); // Move float to stack.
12894 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
12895 moveReg(dst, tmpI); // Move int to long reg.
12896 repl32(dst); // Replicate bitpattern.
12897 %}
12898 %}
12899
12900 // Replicate scalar constant to packed float values in Double register
12901 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
12902 match(Set dst (Replicate src));
12903 predicate(n->as_Vector()->length() == 2 &&
12904 Matcher::vector_element_basic_type(n) == T_FLOAT);
12905 ins_cost(5 * DEFAULT_COST);
12906
12907 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
12908 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
12909 %}
12910
12911 // Replicate scalar zero constant to packed float values in Double register
12912 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
12913 match(Set dst (Replicate zero));
12914 predicate(n->as_Vector()->length() == 2 &&
12915 Matcher::vector_element_basic_type(n) == T_FLOAT);
12916
12917 format %{ "LI $dst, #0 \t// replicate2F" %}
12918 size(4);
12919 ins_encode %{
12920 __ li($dst$$Register, 0x0);
12921 %}
12922 ins_pipe(pipe_class_default);
12923 %}
12924
12925
12926 //----------Vector Arithmetic Instructions--------------------------------------
12927
12928 // Vector Addition Instructions
12929
12930 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
12931 match(Set dst (AddVB src1 src2));
12932 predicate(n->as_Vector()->length() == 16);
12933 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %}
12934 size(4);
12935 ins_encode %{
12936 __ vaddubm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12937 %}
12938 ins_pipe(pipe_class_default);
12939 %}
12940
12941 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
12942 match(Set dst (AddVS src1 src2));
12943 predicate(n->as_Vector()->length() == 8);
12944 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %}
12945 size(4);
12946 ins_encode %{
12947 __ vadduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12948 %}
12949 ins_pipe(pipe_class_default);
12950 %}
12951
12952 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
12953 match(Set dst (AddVI src1 src2));
12954 predicate(n->as_Vector()->length() == 4);
12955 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %}
12956 size(4);
12957 ins_encode %{
12958 __ vadduwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12959 %}
12960 ins_pipe(pipe_class_default);
12961 %}
12962
12963 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
12964 match(Set dst (AddVF src1 src2));
12965 predicate(n->as_Vector()->length() == 4);
12966 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %}
12967 size(4);
12968 ins_encode %{
12969 __ vaddfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12970 %}
12971 ins_pipe(pipe_class_default);
12972 %}
12973
12974 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
12975 match(Set dst (AddVL src1 src2));
12976 predicate(n->as_Vector()->length() == 2);
12977 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %}
12978 size(4);
12979 ins_encode %{
12980 __ vaddudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12981 %}
12982 ins_pipe(pipe_class_default);
12983 %}
12984
12985 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
12986 match(Set dst (AddVD src1 src2));
12987 predicate(n->as_Vector()->length() == 2);
12988 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %}
12989 size(4);
12990 ins_encode %{
12991 __ xvadddp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12992 %}
12993 ins_pipe(pipe_class_default);
12994 %}
12995
12996 // Vector Subtraction Instructions
12997
12998 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
12999 match(Set dst (SubVB src1 src2));
13000 predicate(n->as_Vector()->length() == 16);
13001 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %}
13002 size(4);
13003 ins_encode %{
13004 __ vsububm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13005 %}
13006 ins_pipe(pipe_class_default);
13007 %}
13008
13009 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
13010 match(Set dst (SubVS src1 src2));
13011 predicate(n->as_Vector()->length() == 8);
13012 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %}
13013 size(4);
13014 ins_encode %{
13015 __ vsubuhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13016 %}
13017 ins_pipe(pipe_class_default);
13018 %}
13019
13020 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
13021 match(Set dst (SubVI src1 src2));
13022 predicate(n->as_Vector()->length() == 4);
13023 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %}
13024 size(4);
13025 ins_encode %{
13026 __ vsubuwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13027 %}
13028 ins_pipe(pipe_class_default);
13029 %}
13030
13031 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
13032 match(Set dst (SubVF src1 src2));
13033 predicate(n->as_Vector()->length() == 4);
13034 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %}
13035 size(4);
13036 ins_encode %{
13037 __ vsubfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13038 %}
13039 ins_pipe(pipe_class_default);
13040 %}
13041
13042 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
13043 match(Set dst (SubVL src1 src2));
13044 predicate(n->as_Vector()->length() == 2);
13045 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %}
13046 size(4);
13047 ins_encode %{
13048 __ vsubudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13049 %}
13050 ins_pipe(pipe_class_default);
13051 %}
13052
13053 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
13054 match(Set dst (SubVD src1 src2));
13055 predicate(n->as_Vector()->length() == 2);
13056 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %}
13057 size(4);
13058 ins_encode %{
13059 __ xvsubdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13060 %}
13061 ins_pipe(pipe_class_default);
13062 %}
13063
13064 // Vector Multiplication Instructions
13065
13066 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
13067 match(Set dst (MulVS src1 src2));
13068 predicate(n->as_Vector()->length() == 8);
13069 effect(TEMP tmp);
13070 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %}
13071 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %}
13072 size(8);
13073 ins_encode %{
13074 __ vspltish($tmp$$VectorRegister, 0);
13075 __ vmladduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister, $tmp$$VectorRegister);
13076 %}
13077 ins_pipe(pipe_class_default);
13078 %}
13079
13080 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
13081 match(Set dst (MulVI src1 src2));
13082 predicate(n->as_Vector()->length() == 4);
13083 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %}
13084 size(4);
13085 ins_encode %{
13086 __ vmuluwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13087 %}
13088 ins_pipe(pipe_class_default);
13089 %}
13090
13091 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
13092 match(Set dst (MulVF src1 src2));
13093 predicate(n->as_Vector()->length() == 4);
13094 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %}
13095 size(4);
13096 ins_encode %{
13097 __ xvmulsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13098 %}
13099 ins_pipe(pipe_class_default);
13100 %}
13101
13102 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
13103 match(Set dst (MulVD src1 src2));
13104 predicate(n->as_Vector()->length() == 2);
13105 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %}
13106 size(4);
13107 ins_encode %{
13108 __ xvmuldp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13109 %}
13110 ins_pipe(pipe_class_default);
13111 %}
13112
13113 // Vector Division Instructions
13114
13115 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
13116 match(Set dst (DivVF src1 src2));
13117 predicate(n->as_Vector()->length() == 4);
13118 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %}
13119 size(4);
13120 ins_encode %{
13121 __ xvdivsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13122 %}
13123 ins_pipe(pipe_class_default);
13124 %}
13125
13126 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
13127 match(Set dst (DivVD src1 src2));
13128 predicate(n->as_Vector()->length() == 2);
13129 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %}
13130 size(4);
13131 ins_encode %{
13132 __ xvdivdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13133 %}
13134 ins_pipe(pipe_class_default);
13135 %}
13136
13137 // Vector Min / Max Instructions
13138
13139 instruct vmin_reg(vecX dst, vecX src1, vecX src2) %{
13140 match(Set dst (MinV src1 src2));
13141 format %{ "VMIN $dst,$src1,$src2\t// vector min" %}
13142 size(4);
13143 ins_encode %{
13144 BasicType bt = Matcher::vector_element_basic_type(this);
13145 switch (bt) {
13146 case T_INT:
13147 __ vminsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13148 break;
13149 case T_LONG:
13150 __ vminsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13151 break;
13152 default:
13153 ShouldNotReachHere();
13154 }
13155 %}
13156 ins_pipe(pipe_class_default);
13157 %}
13158
13159 instruct vmax_reg(vecX dst, vecX src1, vecX src2) %{
13160 match(Set dst (MaxV src1 src2));
13161 format %{ "VMAX $dst,$src1,$src2\t// vector max" %}
13162 size(4);
13163 ins_encode %{
13164 BasicType bt = Matcher::vector_element_basic_type(this);
13165 switch (bt) {
13166 case T_INT:
13167 __ vmaxsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13168 break;
13169 case T_LONG:
13170 __ vmaxsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13171 break;
13172 default:
13173 ShouldNotReachHere();
13174 }
13175 %}
13176 ins_pipe(pipe_class_default);
13177 %}
13178
13179 instruct vminu_reg(vecX dst, vecX src1, vecX src2) %{
13180 match(Set dst (UMinV src1 src2));
13181 format %{ "VMINU $dst,$src1,$src2\t// vector unsigned min" %}
13182 size(4);
13183 ins_encode %{
13184 BasicType bt = Matcher::vector_element_basic_type(this);
13185 switch (bt) {
13186 case T_INT:
13187 __ vminuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13188 break;
13189 case T_LONG:
13190 __ vminud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13191 break;
13192 default:
13193 ShouldNotReachHere();
13194 }
13195 %}
13196 ins_pipe(pipe_class_default);
13197 %}
13198
13199 instruct vmaxu_reg(vecX dst, vecX src1, vecX src2) %{
13200 match(Set dst (UMaxV src1 src2));
13201 format %{ "VMAXU $dst,$src1,$src2\t// vector unsigned max" %}
13202 size(4);
13203 ins_encode %{
13204 BasicType bt = Matcher::vector_element_basic_type(this);
13205 switch (bt) {
13206 case T_INT:
13207 __ vmaxuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13208 break;
13209 case T_LONG:
13210 __ vmaxud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13211 break;
13212 default:
13213 ShouldNotReachHere();
13214 }
13215 %}
13216 ins_pipe(pipe_class_default);
13217 %}
13218
13219 instruct vand(vecX dst, vecX src1, vecX src2) %{
13220 match(Set dst (AndV src1 src2));
13221 size(4);
13222 format %{ "VAND $dst,$src1,$src2\t// and vectors" %}
13223 ins_encode %{
13224 __ vand($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13225 %}
13226 ins_pipe(pipe_class_default);
13227 %}
13228
13229 instruct vor(vecX dst, vecX src1, vecX src2) %{
13230 match(Set dst (OrV src1 src2));
13231 size(4);
13232 format %{ "VOR $dst,$src1,$src2\t// or vectors" %}
13233 ins_encode %{
13234 __ vor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13235 %}
13236 ins_pipe(pipe_class_default);
13237 %}
13238
13239 instruct vxor(vecX dst, vecX src1, vecX src2) %{
13240 match(Set dst (XorV src1 src2));
13241 size(4);
13242 format %{ "VXOR $dst,$src1,$src2\t// xor vectors" %}
13243 ins_encode %{
13244 __ vxor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13245 %}
13246 ins_pipe(pipe_class_default);
13247 %}
13248
13249 instruct reductionI_arith_logic(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2) %{
13250 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13251 match(Set dst (AddReductionVI srcInt srcVec));
13252 match(Set dst (MulReductionVI srcInt srcVec));
13253 match(Set dst (AndReductionV srcInt srcVec));
13254 match(Set dst ( OrReductionV srcInt srcVec));
13255 match(Set dst (XorReductionV srcInt srcVec));
13256 effect(TEMP tmp1, TEMP tmp2);
13257 ins_cost(DEFAULT_COST * 6);
13258 format %{ "REDUCEI_ARITH_LOGIC // $dst,$srcInt,$srcVec,$tmp1,$tmp2\t// reduce vector int add/mul/and/or/xor" %}
13259 size(24);
13260 ins_encode %{
13261 int opcode = this->ideal_Opcode();
13262 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13263 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13264 %}
13265 ins_pipe(pipe_class_default);
13266 %}
13267
13268 instruct reductionI_min_max(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2, flagsRegCR0 cr0) %{
13269 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13270 match(Set dst (MinReductionV srcInt srcVec));
13271 match(Set dst (MaxReductionV srcInt srcVec));
13272 effect(TEMP tmp1, TEMP tmp2, KILL cr0);
13273 ins_cost(DEFAULT_COST * 7);
13274 format %{ "REDUCEI_MINMAX // $dst,$srcInt,$srcVec,$tmp1,$tmp2,cr0\t// reduce vector int min/max" %}
13275 size(28);
13276 ins_encode %{
13277 int opcode = this->ideal_Opcode();
13278 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13279 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13280 %}
13281 ins_pipe(pipe_class_default);
13282 %}
13283
13284 // Vector Absolute Instructions
13285
13286 instruct vabs4F_reg(vecX dst, vecX src) %{
13287 match(Set dst (AbsVF src));
13288 predicate(n->as_Vector()->length() == 4);
13289 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
13290 size(4);
13291 ins_encode %{
13292 __ xvabssp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13293 %}
13294 ins_pipe(pipe_class_default);
13295 %}
13296
13297 instruct vabs2D_reg(vecX dst, vecX src) %{
13298 match(Set dst (AbsVD src));
13299 predicate(n->as_Vector()->length() == 2);
13300 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
13301 size(4);
13302 ins_encode %{
13303 __ xvabsdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13304 %}
13305 ins_pipe(pipe_class_default);
13306 %}
13307
13308 // Round Instructions
13309 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{
13310 match(Set dst (RoundDoubleMode src rmode));
13311 format %{ "RoundDoubleMode $src,$rmode" %}
13312 size(4);
13313 ins_encode %{
13314 switch ($rmode$$constant) {
13315 case RoundDoubleModeNode::rmode_rint:
13316 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr());
13317 break;
13318 case RoundDoubleModeNode::rmode_floor:
13319 __ frim($dst$$FloatRegister, $src$$FloatRegister);
13320 break;
13321 case RoundDoubleModeNode::rmode_ceil:
13322 __ frip($dst$$FloatRegister, $src$$FloatRegister);
13323 break;
13324 default:
13325 ShouldNotReachHere();
13326 }
13327 %}
13328 ins_pipe(pipe_class_default);
13329 %}
13330
13331 // Vector Round Instructions
13332 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
13333 match(Set dst (RoundDoubleModeV src rmode));
13334 predicate(n->as_Vector()->length() == 2);
13335 format %{ "RoundDoubleModeV $src,$rmode" %}
13336 size(4);
13337 ins_encode %{
13338 switch ($rmode$$constant) {
13339 case RoundDoubleModeNode::rmode_rint:
13340 __ xvrdpic($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13341 break;
13342 case RoundDoubleModeNode::rmode_floor:
13343 __ xvrdpim($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13344 break;
13345 case RoundDoubleModeNode::rmode_ceil:
13346 __ xvrdpip($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13347 break;
13348 default:
13349 ShouldNotReachHere();
13350 }
13351 %}
13352 ins_pipe(pipe_class_default);
13353 %}
13354
13355 // Vector Negate Instructions
13356
13357 instruct vneg4F_reg(vecX dst, vecX src) %{
13358 match(Set dst (NegVF src));
13359 predicate(n->as_Vector()->length() == 4);
13360 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
13361 size(4);
13362 ins_encode %{
13363 __ xvnegsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13364 %}
13365 ins_pipe(pipe_class_default);
13366 %}
13367
13368 instruct vneg2D_reg(vecX dst, vecX src) %{
13369 match(Set dst (NegVD src));
13370 predicate(n->as_Vector()->length() == 2);
13371 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
13372 size(4);
13373 ins_encode %{
13374 __ xvnegdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13375 %}
13376 ins_pipe(pipe_class_default);
13377 %}
13378
13379 instruct vneg4I_reg(vecX dst, vecX src) %{
13380 match(Set dst (NegVI src));
13381 predicate(Matcher::vector_element_basic_type(n) == T_INT);
13382 format %{ "VNEGW $dst,$src\t// negate int vector" %}
13383 size(4);
13384 ins_encode %{
13385 __ vnegw($dst$$VectorRegister, $src$$VectorRegister);
13386 %}
13387 ins_pipe(pipe_class_default);
13388 %}
13389
13390 // Vector Square Root Instructions
13391
13392 instruct vsqrt4F_reg(vecX dst, vecX src) %{
13393 match(Set dst (SqrtVF src));
13394 predicate(n->as_Vector()->length() == 4);
13395 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
13396 size(4);
13397 ins_encode %{
13398 __ xvsqrtsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13399 %}
13400 ins_pipe(pipe_class_default);
13401 %}
13402
13403 instruct vsqrt2D_reg(vecX dst, vecX src) %{
13404 match(Set dst (SqrtVD src));
13405 predicate(n->as_Vector()->length() == 2);
13406 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %}
13407 size(4);
13408 ins_encode %{
13409 __ xvsqrtdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13410 %}
13411 ins_pipe(pipe_class_default);
13412 %}
13413
13414 // Vector Population Count and Zeros Count Instructions
13415
13416 instruct vpopcnt_reg(vecX dst, vecX src) %{
13417 match(Set dst (PopCountVI src));
13418 match(Set dst (PopCountVL src));
13419 format %{ "VPOPCNT $dst,$src\t// pop count packed" %}
13420 size(4);
13421 ins_encode %{
13422 BasicType bt = Matcher::vector_element_basic_type(this);
13423 switch (bt) {
13424 case T_BYTE:
13425 __ vpopcntb($dst$$VectorRegister, $src$$VectorRegister);
13426 break;
13427 case T_SHORT:
13428 __ vpopcnth($dst$$VectorRegister, $src$$VectorRegister);
13429 break;
13430 case T_INT:
13431 __ vpopcntw($dst$$VectorRegister, $src$$VectorRegister);
13432 break;
13433 case T_LONG:
13434 __ vpopcntd($dst$$VectorRegister, $src$$VectorRegister);
13435 break;
13436 default:
13437 ShouldNotReachHere();
13438 }
13439 %}
13440 ins_pipe(pipe_class_default);
13441 %}
13442
13443 instruct vcount_leading_zeros_reg(vecX dst, vecX src) %{
13444 match(Set dst (CountLeadingZerosV src));
13445 format %{ "VCLZ $dst,$src\t// leading zeros count packed" %}
13446 size(4);
13447 ins_encode %{
13448 BasicType bt = Matcher::vector_element_basic_type(this);
13449 switch (bt) {
13450 case T_BYTE:
13451 __ vclzb($dst$$VectorRegister, $src$$VectorRegister);
13452 break;
13453 case T_SHORT:
13454 __ vclzh($dst$$VectorRegister, $src$$VectorRegister);
13455 break;
13456 case T_INT:
13457 __ vclzw($dst$$VectorRegister, $src$$VectorRegister);
13458 break;
13459 case T_LONG:
13460 __ vclzd($dst$$VectorRegister, $src$$VectorRegister);
13461 break;
13462 default:
13463 ShouldNotReachHere();
13464 }
13465 %}
13466 ins_pipe(pipe_class_default);
13467 %}
13468
13469 instruct vcount_trailing_zeros_reg(vecX dst, vecX src) %{
13470 match(Set dst (CountTrailingZerosV src));
13471 format %{ "VCTZ $dst,$src\t// trailing zeros count packed" %}
13472 size(4);
13473 ins_encode %{
13474 BasicType bt = Matcher::vector_element_basic_type(this);
13475 switch (bt) {
13476 case T_BYTE:
13477 __ vctzb($dst$$VectorRegister, $src$$VectorRegister);
13478 break;
13479 case T_SHORT:
13480 __ vctzh($dst$$VectorRegister, $src$$VectorRegister);
13481 break;
13482 case T_INT:
13483 __ vctzw($dst$$VectorRegister, $src$$VectorRegister);
13484 break;
13485 case T_LONG:
13486 __ vctzd($dst$$VectorRegister, $src$$VectorRegister);
13487 break;
13488 default:
13489 ShouldNotReachHere();
13490 }
13491 %}
13492 ins_pipe(pipe_class_default);
13493 %}
13494
13495 // --------------------------------- FMA --------------------------------------
13496 // src1 * src2 + dst
13497 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{
13498 match(Set dst (FmaVF dst (Binary src1 src2)));
13499 predicate(n->as_Vector()->length() == 4);
13500
13501 format %{ "XVMADDASP $dst, $src1, $src2" %}
13502
13503 size(4);
13504 ins_encode %{
13505 assert(UseFMA, "Needs FMA instructions support.");
13506 __ xvmaddasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13507 %}
13508 ins_pipe(pipe_class_default);
13509 %}
13510
13511 // src1 * (-src2) + dst
13512 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13513 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{
13514 match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
13515 predicate(n->as_Vector()->length() == 4);
13516
13517 format %{ "XVNMSUBASP $dst, $src1, $src2" %}
13518
13519 size(4);
13520 ins_encode %{
13521 assert(UseFMA, "Needs FMA instructions support.");
13522 __ xvnmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13523 %}
13524 ins_pipe(pipe_class_default);
13525 %}
13526
13527 // src1 * src2 - dst
13528 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{
13529 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2)));
13530 predicate(n->as_Vector()->length() == 4);
13531
13532 format %{ "XVMSUBASP $dst, $src1, $src2" %}
13533
13534 size(4);
13535 ins_encode %{
13536 assert(UseFMA, "Needs FMA instructions support.");
13537 __ xvmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13538 %}
13539 ins_pipe(pipe_class_default);
13540 %}
13541
13542 // src1 * src2 + dst
13543 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{
13544 match(Set dst (FmaVD dst (Binary src1 src2)));
13545 predicate(n->as_Vector()->length() == 2);
13546
13547 format %{ "XVMADDADP $dst, $src1, $src2" %}
13548
13549 size(4);
13550 ins_encode %{
13551 assert(UseFMA, "Needs FMA instructions support.");
13552 __ xvmaddadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13553 %}
13554 ins_pipe(pipe_class_default);
13555 %}
13556
13557 // src1 * (-src2) + dst
13558 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13559 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{
13560 match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
13561 predicate(n->as_Vector()->length() == 2);
13562
13563 format %{ "XVNMSUBADP $dst, $src1, $src2" %}
13564
13565 size(4);
13566 ins_encode %{
13567 assert(UseFMA, "Needs FMA instructions support.");
13568 __ xvnmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13569 %}
13570 ins_pipe(pipe_class_default);
13571 %}
13572
13573 // src1 * src2 - dst
13574 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
13575 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2)));
13576 predicate(n->as_Vector()->length() == 2);
13577
13578 format %{ "XVMSUBADP $dst, $src1, $src2" %}
13579
13580 size(4);
13581 ins_encode %{
13582 assert(UseFMA, "Needs FMA instructions support.");
13583 __ xvmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13584 %}
13585 ins_pipe(pipe_class_default);
13586 %}
13587
13588 //----------Overflow Math Instructions-----------------------------------------
13589
13590 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
13591 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
13592 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
13593
13594 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13595 match(Set cr0 (OverflowAddL op1 op2));
13596
13597 format %{ "ADD_ $op1, $op2\t# overflow check long" %}
13598 size(12);
13599 ins_encode %{
13600 __ li(R0, 0);
13601 __ mtxer(R0); // clear XER.SO
13602 __ addo_(R0, $op1$$Register, $op2$$Register);
13603 %}
13604 ins_pipe(pipe_class_default);
13605 %}
13606
13607 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13608 match(Set cr0 (OverflowSubL op1 op2));
13609
13610 format %{ "SUBFO_ R0, $op2, $op1\t# overflow check long" %}
13611 size(12);
13612 ins_encode %{
13613 __ li(R0, 0);
13614 __ mtxer(R0); // clear XER.SO
13615 __ subfo_(R0, $op2$$Register, $op1$$Register);
13616 %}
13617 ins_pipe(pipe_class_default);
13618 %}
13619
13620 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
13621 match(Set cr0 (OverflowSubL zero op2));
13622
13623 format %{ "NEGO_ R0, $op2\t# overflow check long" %}
13624 size(12);
13625 ins_encode %{
13626 __ li(R0, 0);
13627 __ mtxer(R0); // clear XER.SO
13628 __ nego_(R0, $op2$$Register);
13629 %}
13630 ins_pipe(pipe_class_default);
13631 %}
13632
13633 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13634 match(Set cr0 (OverflowMulL op1 op2));
13635
13636 format %{ "MULLDO_ R0, $op1, $op2\t# overflow check long" %}
13637 size(12);
13638 ins_encode %{
13639 __ li(R0, 0);
13640 __ mtxer(R0); // clear XER.SO
13641 __ mulldo_(R0, $op1$$Register, $op2$$Register);
13642 %}
13643 ins_pipe(pipe_class_default);
13644 %}
13645
13646 instruct repl4F_reg_Ex(vecX dst, regF src) %{
13647 match(Set dst (Replicate src));
13648 predicate(n->as_Vector()->length() == 4 &&
13649 Matcher::vector_element_basic_type(n) == T_FLOAT);
13650 ins_cost(DEFAULT_COST);
13651 expand %{
13652 vecX tmpV;
13653 immI8 zero %{ (int) 0 %}
13654
13655 xscvdpspn_regF(tmpV, src);
13656 xxspltw(dst, tmpV, zero);
13657 %}
13658 %}
13659
13660 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{
13661 match(Set dst (Replicate src));
13662 predicate(n->as_Vector()->length() == 4 &&
13663 Matcher::vector_element_basic_type(n) == T_FLOAT);
13664 effect(TEMP tmp);
13665 ins_cost(10 * DEFAULT_COST);
13666
13667 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) );
13668 %}
13669
13670 instruct repl4F_immF0(vecX dst, immF_0 zero) %{
13671 match(Set dst (Replicate zero));
13672 predicate(n->as_Vector()->length() == 4 &&
13673 Matcher::vector_element_basic_type(n) == T_FLOAT);
13674
13675 format %{ "XXLXOR $dst, $zero \t// replicate4F" %}
13676 size(4);
13677 ins_encode %{
13678 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13679 %}
13680 ins_pipe(pipe_class_default);
13681 %}
13682
13683 instruct repl2D_reg_Ex(vecX dst, regD src) %{
13684 match(Set dst (Replicate src));
13685 predicate(n->as_Vector()->length() == 2 &&
13686 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13687
13688 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %}
13689 size(4);
13690 ins_encode %{
13691 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0);
13692 %}
13693 ins_pipe(pipe_class_default);
13694 %}
13695
13696 instruct repl2D_immD0(vecX dst, immD_0 zero) %{
13697 match(Set dst (Replicate zero));
13698 predicate(n->as_Vector()->length() == 2 &&
13699 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13700
13701 format %{ "XXLXOR $dst, $zero \t// replicate2D" %}
13702 size(4);
13703 ins_encode %{
13704 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13705 %}
13706 ins_pipe(pipe_class_default);
13707 %}
13708
13709 instruct mtvsrd(vecX dst, iRegLsrc src) %{
13710 predicate(false);
13711 effect(DEF dst, USE src);
13712
13713 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %}
13714 size(4);
13715 ins_encode %{
13716 __ mtvsrd($dst$$VectorRegister->to_vsr(), $src$$Register);
13717 %}
13718 ins_pipe(pipe_class_default);
13719 %}
13720
13721 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{
13722 effect(DEF dst, USE src, USE zero);
13723
13724 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %}
13725 size(4);
13726 ins_encode %{
13727 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $zero$$constant);
13728 %}
13729 ins_pipe(pipe_class_default);
13730 %}
13731
13732 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{
13733 effect(DEF dst, USE src1, USE src2, USE zero);
13734
13735 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %}
13736 size(4);
13737 ins_encode %{
13738 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr(), $zero$$constant);
13739 %}
13740 ins_pipe(pipe_class_default);
13741 %}
13742
13743 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{
13744 predicate(Matcher::vector_element_basic_type(n) == T_LONG);
13745 match(Set dst (Replicate src));
13746 predicate(n->as_Vector()->length() == 2);
13747 expand %{
13748 vecX tmpV;
13749 immI8 zero %{ (int) 0 %}
13750 mtvsrd(tmpV, src);
13751 xxpermdi(dst, tmpV, tmpV, zero);
13752 %}
13753 %}
13754
13755 instruct repl2L_immI0(vecX dst, immI_0 zero) %{
13756 match(Set dst (Replicate zero));
13757 predicate(n->as_Vector()->length() == 2 &&
13758 Matcher::vector_element_basic_type(n) == T_LONG);
13759
13760 format %{ "XXLXOR $dst, $zero \t// replicate2L" %}
13761 size(4);
13762 ins_encode %{
13763 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13764 %}
13765 ins_pipe(pipe_class_default);
13766 %}
13767
13768 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{
13769 match(Set dst (Replicate src));
13770 predicate(n->as_Vector()->length() == 2 &&
13771 Matcher::vector_element_basic_type(n) == T_LONG);
13772
13773 format %{ "XXLEQV $dst, $src \t// replicate2L" %}
13774 size(4);
13775 ins_encode %{
13776 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13777 %}
13778 ins_pipe(pipe_class_default);
13779 %}
13780
13781 // ============================================================================
13782 // Safepoint Instruction
13783
13784 instruct safePoint_poll(iRegPdst poll) %{
13785 match(SafePoint poll);
13786
13787 // It caused problems to add the effect that r0 is killed, but this
13788 // effect no longer needs to be mentioned, since r0 is not contained
13789 // in a reg_class.
13790
13791 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
13792 size(4);
13793 ins_encode( enc_poll(0x0, poll) );
13794 ins_pipe(pipe_class_default);
13795 %}
13796
13797 // ============================================================================
13798 // Call Instructions
13799
13800 source %{
13801
13802 #include "runtime/continuation.hpp"
13803
13804 %}
13805
13806 // Call Java Static Instruction
13807
13808 instruct CallStaticJavaDirect(method meth) %{
13809 match(CallStaticJava);
13810 effect(USE meth);
13811 ins_cost(CALL_COST);
13812
13813 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
13814
13815 format %{ "CALL,static $meth \t// ==> " %}
13816 size((Continuations::enabled() ? 8 : 4));
13817 ins_encode( enc_java_static_call(meth) );
13818 ins_pipe(pipe_class_call);
13819 %}
13820
13821 // Call Java Dynamic Instruction
13822
13823 instruct CallDynamicJavaDirect(method meth) %{
13824 match(CallDynamicJava);
13825 effect(USE meth);
13826 ins_cost(CALL_COST);
13827
13828 // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
13829 ins_num_consts(4);
13830
13831 format %{ "CALL,dynamic $meth \t// ==> " %}
13832 ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
13833 ins_pipe(pipe_class_call);
13834 %}
13835
13836 // Call Runtime Instruction
13837
13838 instruct CallRuntimeDirect(method meth) %{
13839 match(CallRuntime);
13840 effect(USE meth);
13841 ins_cost(CALL_COST);
13842
13843 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13844 // env for callee, C-toc.
13845 ins_num_consts(3);
13846
13847 format %{ "CALL,runtime" %}
13848 ins_encode( enc_java_to_runtime_call(meth) );
13849 ins_pipe(pipe_class_call);
13850 %}
13851
13852 // Call Leaf
13853
13854 // Used by postalloc expand of CallLeafDirect_Ex (mtctr).
13855 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
13856 effect(DEF dst, USE src);
13857
13858 ins_num_consts(1);
13859
13860 format %{ "MTCTR $src" %}
13861 size(4);
13862 ins_encode( enc_leaf_call_mtctr(src) );
13863 ins_pipe(pipe_class_default);
13864 %}
13865
13866 // Used by postalloc expand of CallLeafDirect_Ex (actual call).
13867 instruct CallLeafDirect(method meth) %{
13868 match(CallLeaf); // To get the data all the data fields we need ...
13869 effect(USE meth);
13870 predicate(false); // but never match.
13871
13872 format %{ "BCTRL \t// leaf call $meth ==> " %}
13873 size((Continuations::enabled() ? 8 : 4));
13874 ins_encode %{
13875 __ bctrl();
13876 __ post_call_nop();
13877 %}
13878 ins_pipe(pipe_class_call);
13879 %}
13880
13881 // postalloc expand of CallLeafDirect.
13882 // Load address to call from TOC, then bl to it.
13883 instruct CallLeafDirect_Ex(method meth) %{
13884 match(CallLeaf);
13885 effect(USE meth);
13886 ins_cost(CALL_COST);
13887
13888 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
13889 // env for callee, C-toc.
13890 ins_num_consts(3);
13891
13892 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
13893 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13894 %}
13895
13896 // Call runtime without safepoint - same as CallLeaf.
13897 // postalloc expand of CallLeafNoFPDirect.
13898 // Load address to call from TOC, then bl to it.
13899 instruct CallLeafNoFPDirect_Ex(method meth) %{
13900 match(CallLeafNoFP);
13901 effect(USE meth);
13902 ins_cost(CALL_COST);
13903
13904 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13905 // env for callee, C-toc.
13906 ins_num_consts(3);
13907
13908 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
13909 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13910 %}
13911
13912 // Tail Call; Jump from runtime stub to Java code.
13913 // Also known as an 'interprocedural jump'.
13914 // Target of jump will eventually return to caller.
13915 // TailJump below removes the return address.
13916 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{
13917 match(TailCall jump_target method_ptr);
13918 ins_cost(CALL_COST);
13919
13920 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t"
13921 "BCTR \t// tail call" %}
13922 size(8);
13923 ins_encode %{
13924 __ mtctr($jump_target$$Register);
13925 __ bctr();
13926 %}
13927 ins_pipe(pipe_class_call);
13928 %}
13929
13930 // Return Instruction
13931 instruct Ret() %{
13932 match(Return);
13933 format %{ "BLR \t// branch to link register" %}
13934 size(4);
13935 ins_encode %{
13936 // LR is restored in MachEpilogNode. Just do the RET here.
13937 __ blr();
13938 %}
13939 ins_pipe(pipe_class_default);
13940 %}
13941
13942 // Tail Jump; remove the return address; jump to target.
13943 // TailCall above leaves the return address around.
13944 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13945 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13946 // "restore" before this instruction (in Epilogue), we need to materialize it
13947 // in %i0.
13948 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
13949 match(TailJump jump_target ex_oop);
13950 ins_cost(CALL_COST);
13951
13952 format %{ "LD R4_ARG2 = LR\n\t"
13953 "MTCTR $jump_target\n\t"
13954 "BCTR \t// TailJump, exception oop: $ex_oop" %}
13955 size(12);
13956 ins_encode %{
13957 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP);
13958 __ mtctr($jump_target$$Register);
13959 __ bctr();
13960 %}
13961 ins_pipe(pipe_class_call);
13962 %}
13963
13964 // Forward exception.
13965 instruct ForwardExceptionjmp()
13966 %{
13967 match(ForwardException);
13968 ins_cost(CALL_COST);
13969
13970 format %{ "JMP forward_exception_stub" %}
13971 ins_encode %{
13972 __ set_inst_mark();
13973 __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
13974 __ clear_inst_mark();
13975 %}
13976 ins_pipe(pipe_class_call);
13977 %}
13978
13979 // Create exception oop: created by stack-crawling runtime code.
13980 // Created exception is now available to this handler, and is setup
13981 // just prior to jumping to this handler. No code emitted.
13982 instruct CreateException(rarg1RegP ex_oop) %{
13983 match(Set ex_oop (CreateEx));
13984 ins_cost(0);
13985
13986 format %{ " -- \t// exception oop; no code emitted" %}
13987 size(0);
13988 ins_encode( /*empty*/ );
13989 ins_pipe(pipe_class_default);
13990 %}
13991
13992 // Rethrow exception: The exception oop will come in the first
13993 // argument position. Then JUMP (not call) to the rethrow stub code.
13994 instruct RethrowException() %{
13995 match(Rethrow);
13996 ins_cost(CALL_COST);
13997
13998 format %{ "JMP rethrow_stub" %}
13999 ins_encode %{
14000 __ set_inst_mark();
14001 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
14002 __ clear_inst_mark();
14003 %}
14004 ins_pipe(pipe_class_call);
14005 %}
14006
14007 // Die now.
14008 instruct ShouldNotReachHere() %{
14009 match(Halt);
14010 ins_cost(CALL_COST);
14011
14012 format %{ "ShouldNotReachHere" %}
14013 ins_encode %{
14014 if (is_reachable()) {
14015 const char* str = __ code_string(_halt_reason);
14016 __ stop(str);
14017 }
14018 %}
14019 ins_pipe(pipe_class_default);
14020 %}
14021
14022 // This name is KNOWN by the ADLC and cannot be changed. The ADLC
14023 // forces a 'TypeRawPtr::BOTTOM' output type for this guy.
14024 // Get a DEF on threadRegP, no costs, no encoding, use
14025 // 'ins_should_rematerialize(true)' to avoid spilling.
14026 instruct tlsLoadP(threadRegP dst) %{
14027 match(Set dst (ThreadLocal));
14028 ins_cost(0);
14029
14030 ins_should_rematerialize(true);
14031
14032 format %{ " -- \t// $dst=Thread::current(), empty" %}
14033 size(0);
14034 ins_encode( /*empty*/ );
14035 ins_pipe(pipe_class_empty);
14036 %}
14037
14038 //---Some PPC specific nodes---------------------------------------------------
14039
14040 // Nop instructions
14041
14042 instruct fxNop() %{
14043 ins_cost(0);
14044
14045 ins_is_nop(true);
14046
14047 format %{ "fxNop" %}
14048 size(4);
14049 ins_encode %{
14050 __ nop();
14051 %}
14052 ins_pipe(pipe_class_default);
14053 %}
14054
14055 instruct fpNop0() %{
14056 ins_cost(0);
14057
14058 ins_is_nop(true);
14059
14060 format %{ "fpNop0" %}
14061 size(4);
14062 ins_encode %{
14063 __ fpnop0();
14064 %}
14065 ins_pipe(pipe_class_default);
14066 %}
14067
14068 instruct fpNop1() %{
14069 ins_cost(0);
14070
14071 ins_is_nop(true);
14072
14073 format %{ "fpNop1" %}
14074 size(4);
14075 ins_encode %{
14076 __ fpnop1();
14077 %}
14078 ins_pipe(pipe_class_default);
14079 %}
14080
14081 instruct brNop0() %{
14082 ins_cost(0);
14083 size(4);
14084 format %{ "brNop0" %}
14085 ins_encode %{
14086 __ brnop0();
14087 %}
14088 ins_is_nop(true);
14089 ins_pipe(pipe_class_default);
14090 %}
14091
14092 instruct brNop1() %{
14093 ins_cost(0);
14094
14095 ins_is_nop(true);
14096
14097 format %{ "brNop1" %}
14098 size(4);
14099 ins_encode %{
14100 __ brnop1();
14101 %}
14102 ins_pipe(pipe_class_default);
14103 %}
14104
14105 instruct brNop2() %{
14106 ins_cost(0);
14107
14108 ins_is_nop(true);
14109
14110 format %{ "brNop2" %}
14111 size(4);
14112 ins_encode %{
14113 __ brnop2();
14114 %}
14115 ins_pipe(pipe_class_default);
14116 %}
14117
14118 instruct cacheWB(indirect addr)
14119 %{
14120 match(CacheWB addr);
14121
14122 ins_cost(100);
14123 format %{ "cache writeback, address = $addr" %}
14124 ins_encode %{
14125 assert($addr->index_position() < 0, "should be");
14126 assert($addr$$disp == 0, "should be");
14127 __ cache_wb(Address($addr$$base$$Register));
14128 %}
14129 ins_pipe(pipe_class_default);
14130 %}
14131
14132 instruct cacheWBPreSync()
14133 %{
14134 match(CacheWBPreSync);
14135
14136 ins_cost(0);
14137 format %{ "cache writeback presync" %}
14138 ins_encode %{
14139 __ cache_wbsync(true);
14140 %}
14141 ins_pipe(pipe_class_default);
14142 %}
14143
14144 instruct cacheWBPostSync()
14145 %{
14146 match(CacheWBPostSync);
14147
14148 ins_cost(100);
14149 format %{ "cache writeback postsync" %}
14150 ins_encode %{
14151 __ cache_wbsync(false);
14152 %}
14153 ins_pipe(pipe_class_default);
14154 %}
14155
14156 //----------PEEPHOLE RULES-----------------------------------------------------
14157 // These must follow all instruction definitions as they use the names
14158 // defined in the instructions definitions.
14159 //
14160 // peepmatch ( root_instr_name [preceeding_instruction]* );
14161 //
14162 // peepconstraint %{
14163 // (instruction_number.operand_name relational_op instruction_number.operand_name
14164 // [, ...] );
14165 // // instruction numbers are zero-based using left to right order in peepmatch
14166 //
14167 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14168 // // provide an instruction_number.operand_name for each operand that appears
14169 // // in the replacement instruction's match rule
14170 //
14171 // ---------VM FLAGS---------------------------------------------------------
14172 //
14173 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14174 //
14175 // Each peephole rule is given an identifying number starting with zero and
14176 // increasing by one in the order seen by the parser. An individual peephole
14177 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14178 // on the command-line.
14179 //
14180 // ---------CURRENT LIMITATIONS----------------------------------------------
14181 //
14182 // Only match adjacent instructions in same basic block
14183 // Only equality constraints
14184 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14185 // Only one replacement instruction
14186 //
14187 // ---------EXAMPLE----------------------------------------------------------
14188 //
14189 // // pertinent parts of existing instructions in architecture description
14190 // instruct movI(eRegI dst, eRegI src) %{
14191 // match(Set dst (CopyI src));
14192 // %}
14193 //
14194 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14195 // match(Set dst (AddI dst src));
14196 // effect(KILL cr);
14197 // %}
14198 //
14199 // // Change (inc mov) to lea
14200 // peephole %{
14201 // // increment preceded by register-register move
14202 // peepmatch ( incI_eReg movI );
14203 // // require that the destination register of the increment
14204 // // match the destination register of the move
14205 // peepconstraint ( 0.dst == 1.dst );
14206 // // construct a replacement instruction that sets
14207 // // the destination to ( move's source register + one )
14208 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14209 // %}
14210 //
14211 // Implementation no longer uses movX instructions since
14212 // machine-independent system no longer uses CopyX nodes.
14213 //
14214 // peephole %{
14215 // peepmatch ( incI_eReg movI );
14216 // peepconstraint ( 0.dst == 1.dst );
14217 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14218 // %}
14219 //
14220 // peephole %{
14221 // peepmatch ( decI_eReg movI );
14222 // peepconstraint ( 0.dst == 1.dst );
14223 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14224 // %}
14225 //
14226 // peephole %{
14227 // peepmatch ( addI_eReg_imm movI );
14228 // peepconstraint ( 0.dst == 1.dst );
14229 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14230 // %}
14231 //
14232 // peephole %{
14233 // peepmatch ( addP_eReg_imm movP );
14234 // peepconstraint ( 0.dst == 1.dst );
14235 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
14236 // %}
14237
14238 // // Change load of spilled value to only a spill
14239 // instruct storeI(memory mem, eRegI src) %{
14240 // match(Set mem (StoreI mem src));
14241 // %}
14242 //
14243 // instruct loadI(eRegI dst, memory mem) %{
14244 // match(Set dst (LoadI mem));
14245 // %}
14246 //
14247 peephole %{
14248 peepmatch ( loadI storeI );
14249 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14250 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14251 %}
14252
14253 peephole %{
14254 peepmatch ( loadL storeL );
14255 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14256 peepreplace ( storeL( 1.mem 1.mem 1.src ) );
14257 %}
14258
14259 peephole %{
14260 peepmatch ( loadP storeP );
14261 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
14262 peepreplace ( storeP( 1.dst 1.dst 1.src ) );
14263 %}
14264
14265 //----------SMARTSPILL RULES---------------------------------------------------
14266 // These must follow all instruction definitions as they use the names
14267 // defined in the instructions definitions.