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 int MachPrologNode::reloc() const {
1546 // Return number of relocatable values contained in this instruction.
1547 return 1; // 1 reloc entry for load_const(toc).
1548 }
1549
1550 //=============================================================================
1551
1552 #ifndef PRODUCT
1553 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1554 Compile* C = ra_->C;
1555
1556 st->print("EPILOG\n\t");
1557 st->print("restore return pc\n\t");
1558 st->print("pop frame\n\t");
1559
1560 if (do_polling() && C->is_method_compilation()) {
1561 st->print("safepoint poll\n\t");
1562 }
1563 }
1564 #endif
1565
1566 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1567 Compile* C = ra_->C;
1568
1569 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt;
1570 assert(framesize >= 0, "negative frame-size?");
1571
1572 const bool method_needs_polling = do_polling() && C->is_method_compilation();
1573 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1574 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
1575 const Register temp = R12;
1576
1577 if (!method_is_frameless) {
1578 // Restore return pc relative to callers' sp.
1579 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP);
1580 // Move return pc to LR.
1581 __ mtlr(return_pc);
1582 // Pop frame (fixed frame-size).
1583 __ addi(R1_SP, R1_SP, (int)framesize);
1584 }
1585
1586 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1587 __ reserved_stack_check(return_pc);
1588 }
1589
1590 if (method_needs_polling) {
1591 Label dummy_label;
1592 Label* code_stub = &dummy_label;
1593 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) {
1594 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1595 C->output()->add_stub(stub);
1596 code_stub = &stub->entry();
1597 __ relocate(relocInfo::poll_return_type);
1598 }
1599 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */);
1600 }
1601 }
1602
1603 int MachEpilogNode::reloc() const {
1604 // Return number of relocatable values contained in this instruction.
1605 return 1; // 1 for load_from_polling_page.
1606 }
1607
1608 const Pipeline * MachEpilogNode::pipeline() const {
1609 return MachNode::pipeline_class();
1610 }
1611
1612 // =============================================================================
1613
1614 // Figure out which register class each belongs in: rc_int, rc_float, rc_vec or
1615 // rc_stack.
1616 enum RC { rc_bad, rc_int, rc_float, rc_vec, rc_stack };
1617
1618 static enum RC rc_class(OptoReg::Name reg) {
1619 // Return the register class for the given register. The given register
1620 // reg is a <register>_num value, which is an index into the MachRegisterNumbers
1621 // enumeration in adGlobals_ppc.hpp.
1622
1623 if (reg == OptoReg::Bad) return rc_bad;
1624
1625 // We have 64 integer register halves, starting at index 0.
1626 STATIC_ASSERT((int)ConcreteRegisterImpl::max_gpr == (int)MachRegisterNumbers::F0_num);
1627 if (reg < ConcreteRegisterImpl::max_gpr) return rc_int;
1628
1629 // We have 64 floating-point register halves, starting at index 64.
1630 STATIC_ASSERT((int)ConcreteRegisterImpl::max_fpr == (int)MachRegisterNumbers::VR0_num);
1631 if (reg < ConcreteRegisterImpl::max_fpr) return rc_float;
1632
1633 // We have 64 vector-scalar registers, starting at index 128.
1634 STATIC_ASSERT((int)ConcreteRegisterImpl::max_vr == (int)MachRegisterNumbers::CR0_num);
1635 if (reg < ConcreteRegisterImpl::max_vr) return rc_vec;
1636
1637 // Condition and special purpose registers are not allocated. We only accept stack from here.
1638 assert(OptoReg::is_stack(reg), "what else is it?");
1639 return rc_stack;
1640 }
1641
1642 static int ld_st_helper(C2_MacroAssembler *masm, const char *op_str, uint opcode, int reg, int offset,
1643 bool do_print, Compile* C, outputStream *st) {
1644
1645 assert(opcode == Assembler::LD_OPCODE ||
1646 opcode == Assembler::STD_OPCODE ||
1647 opcode == Assembler::LWZ_OPCODE ||
1648 opcode == Assembler::STW_OPCODE ||
1649 opcode == Assembler::LFD_OPCODE ||
1650 opcode == Assembler::STFD_OPCODE ||
1651 opcode == Assembler::LFS_OPCODE ||
1652 opcode == Assembler::STFS_OPCODE,
1653 "opcode not supported");
1654
1655 if (masm) {
1656 int d =
1657 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ?
1658 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/)
1659 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build.
1660 emit_long(masm, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP));
1661 }
1662 #ifndef PRODUCT
1663 else if (do_print) {
1664 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy",
1665 op_str,
1666 Matcher::regName[reg],
1667 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/);
1668 }
1669 #endif
1670 return 4; // size
1671 }
1672
1673 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1674 Compile* C = ra_->C;
1675
1676 // Get registers to move.
1677 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1678 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1679 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1680 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1681
1682 enum RC src_hi_rc = rc_class(src_hi);
1683 enum RC src_lo_rc = rc_class(src_lo);
1684 enum RC dst_hi_rc = rc_class(dst_hi);
1685 enum RC dst_lo_rc = rc_class(dst_lo);
1686
1687 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1688 if (src_hi != OptoReg::Bad)
1689 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1690 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1691 "expected aligned-adjacent pairs");
1692 // Generate spill code!
1693 int size = 0;
1694
1695 if (src_lo == dst_lo && src_hi == dst_hi)
1696 return size; // Self copy, no move.
1697
1698 if (bottom_type()->isa_vect() != nullptr && ideal_reg() == Op_VecX) {
1699 int src_offset = ra_->reg2offset(src_lo);
1700 int dst_offset = ra_->reg2offset(dst_lo);
1701 DEBUG_ONLY(int algm = MIN2(RegMask::num_registers(ideal_reg()), (int)Matcher::stack_alignment_in_slots()) * VMRegImpl::stack_slot_size);
1702 assert((src_lo_rc != rc_stack) || is_aligned(src_offset, algm), "unaligned vector spill sp offset %d (src)", src_offset);
1703 assert((dst_lo_rc != rc_stack) || is_aligned(dst_offset, algm), "unaligned vector spill sp offset %d (dst)", dst_offset);
1704 // Memory->Memory Spill.
1705 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1706 if (masm) {
1707 __ ld(R0, src_offset, R1_SP);
1708 __ std(R0, dst_offset, R1_SP);
1709 __ ld(R0, src_offset+8, R1_SP);
1710 __ std(R0, dst_offset+8, R1_SP);
1711 }
1712 size += 16;
1713 #ifndef PRODUCT
1714 if (st != nullptr) {
1715 st->print("%-7s [R1_SP + #%d] -> [R1_SP + #%d] \t// vector spill copy", "SPILL", src_offset, dst_offset);
1716 }
1717 #endif // !PRODUCT
1718 }
1719 // VectorRegister->Memory Spill.
1720 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_stack) {
1721 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1722 if (masm) {
1723 __ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16
1724 }
1725 size += 4;
1726 #ifndef PRODUCT
1727 if (st != nullptr) {
1728 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "STXV", Matcher::regName[src_lo], dst_offset);
1729 }
1730 #endif // !PRODUCT
1731 }
1732 // Memory->VectorRegister Spill.
1733 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vec) {
1734 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1735 if (masm) {
1736 __ lxv(Rdst, src_offset, R1_SP);
1737 }
1738 size += 4;
1739 #ifndef PRODUCT
1740 if (st != nullptr) {
1741 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "LXV", Matcher::regName[dst_lo], src_offset);
1742 }
1743 #endif // !PRODUCT
1744 }
1745 // VectorRegister->VectorRegister.
1746 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_vec) {
1747 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1748 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1749 if (masm) {
1750 __ xxlor(Rdst, Rsrc, Rsrc);
1751 }
1752 size += 4;
1753 #ifndef PRODUCT
1754 if (st != nullptr) {
1755 st->print("%-7s %s, %s, %s\t// vector spill copy",
1756 "XXLOR", Matcher::regName[dst_lo], Matcher::regName[src_lo], Matcher::regName[src_lo]);
1757 }
1758 #endif // !PRODUCT
1759 }
1760 else {
1761 ShouldNotReachHere(); // No VR spill.
1762 }
1763 return size;
1764 }
1765
1766 // --------------------------------------
1767 // Memory->Memory Spill. Use R0 to hold the value.
1768 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1769 int src_offset = ra_->reg2offset(src_lo);
1770 int dst_offset = ra_->reg2offset(dst_lo);
1771 if (src_hi != OptoReg::Bad) {
1772 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack,
1773 "expected same type of move for high parts");
1774 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st);
1775 if (!masm && !do_size) st->print("\n\t");
1776 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st);
1777 } else {
1778 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st);
1779 if (!masm && !do_size) st->print("\n\t");
1780 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st);
1781 }
1782 return size;
1783 }
1784
1785 // --------------------------------------
1786 // Check for float->int copy; requires a trip through memory.
1787 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1788 Unimplemented();
1789 }
1790
1791 // --------------------------------------
1792 // Check for integer reg-reg copy.
1793 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1794 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1795 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1796 size = (Rsrc != Rdst) ? 4 : 0;
1797
1798 if (masm) {
1799 if (size) {
1800 __ mr(Rdst, Rsrc);
1801 }
1802 }
1803 #ifndef PRODUCT
1804 else if (!do_size) {
1805 if (size) {
1806 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1807 } else {
1808 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1809 }
1810 }
1811 #endif
1812 return size;
1813 }
1814
1815 // Check for integer store.
1816 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1817 int dst_offset = ra_->reg2offset(dst_lo);
1818 if (src_hi != OptoReg::Bad) {
1819 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack,
1820 "expected same type of move for high parts");
1821 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1822 } else {
1823 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st);
1824 }
1825 return size;
1826 }
1827
1828 // Check for integer load.
1829 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1830 int src_offset = ra_->reg2offset(src_lo);
1831 if (src_hi != OptoReg::Bad) {
1832 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack,
1833 "expected same type of move for high parts");
1834 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1835 } else {
1836 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st);
1837 }
1838 return size;
1839 }
1840
1841 // Check for float reg-reg copy.
1842 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1843 if (masm) {
1844 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]);
1845 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]);
1846 __ fmr(Rdst, Rsrc);
1847 }
1848 #ifndef PRODUCT
1849 else if (!do_size) {
1850 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1851 }
1852 #endif
1853 return 4;
1854 }
1855
1856 // Check for float store.
1857 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1858 int dst_offset = ra_->reg2offset(dst_lo);
1859 if (src_hi != OptoReg::Bad) {
1860 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack,
1861 "expected same type of move for high parts");
1862 size += ld_st_helper(masm, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1863 } else {
1864 size += ld_st_helper(masm, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st);
1865 }
1866 return size;
1867 }
1868
1869 // Check for float load.
1870 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1871 int src_offset = ra_->reg2offset(src_lo);
1872 if (src_hi != OptoReg::Bad) {
1873 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack,
1874 "expected same type of move for high parts");
1875 size += ld_st_helper(masm, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1876 } else {
1877 size += ld_st_helper(masm, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st);
1878 }
1879 return size;
1880 }
1881
1882 // --------------------------------------------------------------------
1883 // Check for hi bits still needing moving. Only happens for misaligned
1884 // arguments to native calls.
1885 if (src_hi == dst_hi)
1886 return size; // Self copy; no move.
1887
1888 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad");
1889 ShouldNotReachHere(); // Unimplemented
1890 return 0;
1891 }
1892
1893 #ifndef PRODUCT
1894 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1895 if (!ra_)
1896 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1897 else
1898 implementation(nullptr, ra_, false, st);
1899 }
1900 #endif
1901
1902 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1903 implementation(masm, ra_, false, nullptr);
1904 }
1905
1906 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1907 return implementation(nullptr, ra_, true, nullptr);
1908 }
1909
1910 #ifndef PRODUCT
1911 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1912 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count);
1913 }
1914 #endif
1915
1916 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *) const {
1917 // _count contains the number of nops needed for padding.
1918 for (int i = 0; i < _count; i++) {
1919 __ nop();
1920 }
1921 }
1922
1923 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
1924 return _count * 4;
1925 }
1926
1927 #ifndef PRODUCT
1928 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1929 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1930 char reg_str[128];
1931 ra_->dump_register(this, reg_str, sizeof(reg_str));
1932 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset);
1933 }
1934 #endif
1935
1936 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1937 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1938 int reg = ra_->get_encode(this);
1939
1940 if (Assembler::is_simm(offset, 16)) {
1941 __ addi(as_Register(reg), R1, offset);
1942 } else {
1943 ShouldNotReachHere();
1944 }
1945 }
1946
1947 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1948 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1949 return 4;
1950 }
1951
1952 #ifndef PRODUCT
1953 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1954 {
1955 Unimplemented();
1956 }
1957 #endif
1958
1959 void MachVEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc* ra_) const
1960 {
1961 Unimplemented();
1962 }
1963
1964 #ifndef PRODUCT
1965 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1966 st->print_cr("---- MachUEPNode ----");
1967 st->print_cr("...");
1968 }
1969 #endif
1970
1971 void MachUEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1972 // This is the unverified entry point.
1973 __ ic_check(CodeEntryAlignment);
1974 // Argument is valid and klass is as expected, continue.
1975 }
1976
1977 //=============================================================================
1978
1979 %} // interrupt source
1980
1981 source_hpp %{ // Header information of the source block.
1982
1983 class HandlerImpl {
1984
1985 public:
1986
1987 static int emit_deopt_handler(C2_MacroAssembler* masm);
1988
1989 static uint size_deopt_handler() {
1990 // The deopt_handler is a bl64_patchable.
1991 return MacroAssembler::bl64_patchable_size + BytesPerInstWord;
1992 }
1993
1994 };
1995
1996 class Node::PD {
1997 public:
1998 enum NodeFlags {
1999 _last_flag = Node::_last_flag
2000 };
2001 };
2002
2003 %} // end source_hpp
2004
2005 source %{
2006
2007 // The deopt_handler is like the exception handler, but it calls to
2008 // the deoptimization blob instead of jumping to the exception blob.
2009 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
2010 address base = __ start_a_stub(size_deopt_handler());
2011 if (base == nullptr) {
2012 ciEnv::current()->record_failure("CodeCache is full");
2013 return 0; // CodeBuffer::expand failed
2014 }
2015
2016 int offset = __ offset();
2017
2018 Label start;
2019 __ bind(start);
2020
2021 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
2022 relocInfo::runtime_call_type);
2023
2024 int entry_offset = __ offset();
2025
2026 __ b(start);
2027
2028 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
2029 assert(__ offset() - entry_offset >= NativePostCallNop::first_check_size,
2030 "out of bounds read in post-call NOP check");
2031 __ end_a_stub();
2032
2033 return entry_offset;
2034 }
2035
2036 //=============================================================================
2037
2038 // Use a frame slots bias for frameless methods if accessing the stack.
2039 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) {
2040 if (as_Register(reg_enc) == R1_SP) {
2041 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes();
2042 }
2043 return 0;
2044 }
2045
2046 bool Matcher::match_rule_supported(int opcode) {
2047 if (!has_match_rule(opcode)) {
2048 return false; // no match rule present
2049 }
2050
2051 switch (opcode) {
2052 case Op_CountLeadingZerosI:
2053 case Op_CountLeadingZerosL:
2054 return UseCountLeadingZerosInstructionsPPC64;
2055 case Op_CountTrailingZerosI:
2056 case Op_CountTrailingZerosL:
2057 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64);
2058 case Op_PopCountI:
2059 case Op_PopCountL:
2060 return UsePopCountInstruction;
2061 case Op_ConvF2HF:
2062 case Op_ConvHF2F:
2063 return VM_Version::supports_float16();
2064 case Op_AddVB:
2065 case Op_AddVS:
2066 case Op_AddVI:
2067 case Op_AddVF:
2068 case Op_AddVD:
2069 case Op_SubVB:
2070 case Op_SubVS:
2071 case Op_SubVI:
2072 case Op_SubVF:
2073 case Op_SubVD:
2074 case Op_MulVS:
2075 case Op_MulVF:
2076 case Op_MulVD:
2077 case Op_DivVF:
2078 case Op_DivVD:
2079 case Op_AbsVF:
2080 case Op_AbsVD:
2081 case Op_NegVI:
2082 case Op_NegVF:
2083 case Op_NegVD:
2084 case Op_SqrtVF:
2085 case Op_SqrtVD:
2086 case Op_AddVL:
2087 case Op_SubVL:
2088 case Op_MulVI:
2089 case Op_RoundDoubleModeV:
2090 case Op_MinV:
2091 case Op_MaxV:
2092 case Op_UMinV:
2093 case Op_UMaxV:
2094 case Op_AndV:
2095 case Op_OrV:
2096 case Op_XorV:
2097 case Op_AddReductionVI:
2098 case Op_MulReductionVI:
2099 case Op_AndReductionV:
2100 case Op_OrReductionV:
2101 case Op_XorReductionV:
2102 case Op_MinReductionV:
2103 case Op_MaxReductionV:
2104 return SuperwordUseVSX;
2105 case Op_PopCountVI:
2106 case Op_PopCountVL:
2107 return (SuperwordUseVSX && UsePopCountInstruction);
2108 case Op_CountLeadingZerosV:
2109 return SuperwordUseVSX && UseCountLeadingZerosInstructionsPPC64;
2110 case Op_CountTrailingZerosV:
2111 return SuperwordUseVSX && UseCountTrailingZerosInstructionsPPC64;
2112 case Op_FmaF:
2113 case Op_FmaD:
2114 return UseFMA;
2115 case Op_FmaVF:
2116 case Op_FmaVD:
2117 return (SuperwordUseVSX && UseFMA);
2118
2119 case Op_MinF:
2120 case Op_MaxF:
2121 case Op_MinD:
2122 case Op_MaxD:
2123 return (PowerArchitecturePPC64 >= 9);
2124
2125 case Op_Digit:
2126 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit);
2127 case Op_LowerCase:
2128 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase);
2129 case Op_UpperCase:
2130 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase);
2131 case Op_Whitespace:
2132 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace);
2133
2134 case Op_CacheWB:
2135 case Op_CacheWBPreSync:
2136 case Op_CacheWBPostSync:
2137 return VM_Version::supports_data_cache_line_flush();
2138
2139 case Op_OnSpinWait:
2140 return VM_Version::supports_on_spin_wait();
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 compiled Java return values. Same as C
3479 return_value %{
3480 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3481 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3482 "only return normal values");
3483 // enum names from opcodes.hpp
3484 static int typeToRegLo[Op_RegL+1] = {
3485 0, // Op_Node
3486 0, // Op_Set
3487 R3_num, // Op_RegN
3488 R3_num, // Op_RegI
3489 R3_num, // Op_RegP
3490 F1_num, // Op_RegF
3491 F1_num, // Op_RegD
3492 R3_num, // Op_RegL
3493 };
3494
3495 static int typeToRegHi[Op_RegL+1] = {
3496 0, // Op_Node
3497 0, // Op_Set
3498 OptoReg::Bad, // Op_RegN
3499 OptoReg::Bad, // Op_RegI
3500 R3_H_num, // Op_RegP
3501 OptoReg::Bad, // Op_RegF
3502 F1_H_num, // Op_RegD
3503 R3_H_num // Op_RegL
3504 };
3505
3506 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3507 %}
3508 %}
3509
3510
3511 //----------ATTRIBUTES---------------------------------------------------------
3512
3513 //----------Operand Attributes-------------------------------------------------
3514 op_attrib op_cost(1); // Required cost attribute.
3515
3516 //----------Instruction Attributes---------------------------------------------
3517
3518 // Cost attribute. required.
3519 ins_attrib ins_cost(DEFAULT_COST);
3520
3521 // Is this instruction a non-matching short branch variant of some
3522 // long branch? Not required.
3523 ins_attrib ins_short_branch(0);
3524
3525 ins_attrib ins_is_TrapBasedCheckNode(true);
3526
3527 // Number of constants.
3528 // This instruction uses the given number of constants
3529 // (optional attribute).
3530 // This is needed to determine in time whether the constant pool will
3531 // exceed 4000 entries. Before postalloc_expand the overall number of constants
3532 // is determined. It's also used to compute the constant pool size
3533 // in Output().
3534 ins_attrib ins_num_consts(0);
3535
3536 // Required alignment attribute (must be a power of 2) specifies the
3537 // alignment that some part of the instruction (not necessarily the
3538 // start) requires. If > 1, a compute_padding() function must be
3539 // provided for the instruction.
3540 ins_attrib ins_alignment(1);
3541
3542 // Enforce/prohibit rematerializations.
3543 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3544 // then rematerialization of that instruction is prohibited and the
3545 // instruction's value will be spilled if necessary.
3546 // Causes that MachNode::rematerialize() returns false.
3547 // - If an instruction is attributed with 'ins_should_rematerialize(true)'
3548 // then rematerialization should be enforced and a copy of the instruction
3549 // should be inserted if possible; rematerialization is not guaranteed.
3550 // Note: this may result in rematerializations in front of every use.
3551 // Causes that MachNode::rematerialize() can return true.
3552 // (optional attribute)
3553 ins_attrib ins_cannot_rematerialize(false);
3554 ins_attrib ins_should_rematerialize(false);
3555
3556 // Instruction has variable size depending on alignment.
3557 ins_attrib ins_variable_size_depending_on_alignment(false);
3558
3559 // Instruction is a nop.
3560 ins_attrib ins_is_nop(false);
3561
3562 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock).
3563 ins_attrib ins_use_mach_if_fast_lock_node(false);
3564
3565 // Field for the toc offset of a constant.
3566 //
3567 // This is needed if the toc offset is not encodable as an immediate in
3568 // the PPC load instruction. If so, the upper (hi) bits of the offset are
3569 // added to the toc, and from this a load with immediate is performed.
3570 // With postalloc expand, we get two nodes that require the same offset
3571 // but which don't know about each other. The offset is only known
3572 // when the constant is added to the constant pool during emitting.
3573 // It is generated in the 'hi'-node adding the upper bits, and saved
3574 // in this node. The 'lo'-node has a link to the 'hi'-node and reads
3575 // the offset from there when it gets encoded.
3576 ins_attrib ins_field_const_toc_offset(0);
3577 ins_attrib ins_field_const_toc_offset_hi_node(0);
3578
3579 // A field that can hold the instructions offset in the code buffer.
3580 // Set in the nodes emitter.
3581 ins_attrib ins_field_cbuf_insts_offset(-1);
3582
3583 // Fields for referencing a call's load-IC-node.
3584 // If the toc offset can not be encoded as an immediate in a load, we
3585 // use two nodes.
3586 ins_attrib ins_field_load_ic_hi_node(0);
3587 ins_attrib ins_field_load_ic_node(0);
3588
3589 // Whether this node is expanded during code emission into a sequence of
3590 // instructions and the first instruction can perform an implicit null check.
3591 ins_attrib ins_is_late_expanded_null_check_candidate(false);
3592
3593 //----------OPERANDS-----------------------------------------------------------
3594 // Operand definitions must precede instruction definitions for correct
3595 // parsing in the ADLC because operands constitute user defined types
3596 // which are used in instruction definitions.
3597 //
3598 // Formats are generated automatically for constants and base registers.
3599
3600 operand vecX() %{
3601 constraint(ALLOC_IN_RC(v_reg));
3602 match(VecX);
3603
3604 format %{ %}
3605 interface(REG_INTER);
3606 %}
3607
3608 //----------Simple Operands----------------------------------------------------
3609 // Immediate Operands
3610
3611 // Integer Immediate: 32-bit
3612 operand immI() %{
3613 match(ConI);
3614 op_cost(40);
3615 format %{ %}
3616 interface(CONST_INTER);
3617 %}
3618
3619 operand immI8() %{
3620 predicate(Assembler::is_simm(n->get_int(), 8));
3621 op_cost(0);
3622 match(ConI);
3623 format %{ %}
3624 interface(CONST_INTER);
3625 %}
3626
3627 // Integer Immediate: 16-bit
3628 operand immI16() %{
3629 predicate(Assembler::is_simm(n->get_int(), 16));
3630 op_cost(0);
3631 match(ConI);
3632 format %{ %}
3633 interface(CONST_INTER);
3634 %}
3635
3636 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000.
3637 operand immIhi16() %{
3638 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0));
3639 match(ConI);
3640 op_cost(0);
3641 format %{ %}
3642 interface(CONST_INTER);
3643 %}
3644
3645 // Integer Immediate: 32-bit immediate for prefixed addi and load/store.
3646 operand immI32() %{
3647 predicate(PowerArchitecturePPC64 >= 10);
3648 op_cost(0);
3649 match(ConI);
3650 format %{ %}
3651 interface(CONST_INTER);
3652 %}
3653
3654 operand immInegpow2() %{
3655 predicate(is_power_of_2(-(juint)(n->get_int())));
3656 match(ConI);
3657 op_cost(0);
3658 format %{ %}
3659 interface(CONST_INTER);
3660 %}
3661
3662 operand immIpow2minus1() %{
3663 predicate(is_power_of_2((juint)(n->get_int()) + 1u));
3664 match(ConI);
3665 op_cost(0);
3666 format %{ %}
3667 interface(CONST_INTER);
3668 %}
3669
3670 operand immIpowerOf2() %{
3671 predicate(is_power_of_2((juint)(n->get_int())));
3672 match(ConI);
3673 op_cost(0);
3674 format %{ %}
3675 interface(CONST_INTER);
3676 %}
3677
3678 // Unsigned Integer Immediate: the values 0-31
3679 operand uimmI5() %{
3680 predicate(Assembler::is_uimm(n->get_int(), 5));
3681 match(ConI);
3682 op_cost(0);
3683 format %{ %}
3684 interface(CONST_INTER);
3685 %}
3686
3687 // Unsigned Integer Immediate: 6-bit
3688 operand uimmI6() %{
3689 predicate(Assembler::is_uimm(n->get_int(), 6));
3690 match(ConI);
3691 op_cost(0);
3692 format %{ %}
3693 interface(CONST_INTER);
3694 %}
3695
3696 // Unsigned Integer Immediate: 6-bit int, greater than 32
3697 operand uimmI6_ge32() %{
3698 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32);
3699 match(ConI);
3700 op_cost(0);
3701 format %{ %}
3702 interface(CONST_INTER);
3703 %}
3704
3705 // Unsigned Integer Immediate: 15-bit
3706 operand uimmI15() %{
3707 predicate(Assembler::is_uimm(n->get_int(), 15));
3708 match(ConI);
3709 op_cost(0);
3710 format %{ %}
3711 interface(CONST_INTER);
3712 %}
3713
3714 // Unsigned Integer Immediate: 16-bit
3715 operand uimmI16() %{
3716 predicate(Assembler::is_uimm(n->get_int(), 16));
3717 match(ConI);
3718 op_cost(0);
3719 format %{ %}
3720 interface(CONST_INTER);
3721 %}
3722
3723 // constant 'int 0'.
3724 operand immI_0() %{
3725 predicate(n->get_int() == 0);
3726 match(ConI);
3727 op_cost(0);
3728 format %{ %}
3729 interface(CONST_INTER);
3730 %}
3731
3732 // constant 'int 1'.
3733 operand immI_1() %{
3734 predicate(n->get_int() == 1);
3735 match(ConI);
3736 op_cost(0);
3737 format %{ %}
3738 interface(CONST_INTER);
3739 %}
3740
3741 // constant 'int -1'.
3742 operand immI_minus1() %{
3743 predicate(n->get_int() == -1);
3744 match(ConI);
3745 op_cost(0);
3746 format %{ %}
3747 interface(CONST_INTER);
3748 %}
3749
3750 // int value 16.
3751 operand immI_16() %{
3752 predicate(n->get_int() == 16);
3753 match(ConI);
3754 op_cost(0);
3755 format %{ %}
3756 interface(CONST_INTER);
3757 %}
3758
3759 // int value 24.
3760 operand immI_24() %{
3761 predicate(n->get_int() == 24);
3762 match(ConI);
3763 op_cost(0);
3764 format %{ %}
3765 interface(CONST_INTER);
3766 %}
3767
3768 // Compressed oops constants
3769 // Pointer Immediate
3770 operand immN() %{
3771 match(ConN);
3772
3773 op_cost(10);
3774 format %{ %}
3775 interface(CONST_INTER);
3776 %}
3777
3778 // nullptr Pointer Immediate
3779 operand immN_0() %{
3780 predicate(n->get_narrowcon() == 0);
3781 match(ConN);
3782
3783 op_cost(0);
3784 format %{ %}
3785 interface(CONST_INTER);
3786 %}
3787
3788 // Compressed klass constants
3789 operand immNKlass() %{
3790 match(ConNKlass);
3791
3792 op_cost(0);
3793 format %{ %}
3794 interface(CONST_INTER);
3795 %}
3796
3797 // This operand can be used to avoid matching of an instruct
3798 // with chain rule.
3799 operand immNKlass_NM() %{
3800 match(ConNKlass);
3801 predicate(false);
3802 op_cost(0);
3803 format %{ %}
3804 interface(CONST_INTER);
3805 %}
3806
3807 // Pointer Immediate: 64-bit
3808 operand immP() %{
3809 match(ConP);
3810 op_cost(0);
3811 format %{ %}
3812 interface(CONST_INTER);
3813 %}
3814
3815 // Operand to avoid match of loadConP.
3816 // This operand can be used to avoid matching of an instruct
3817 // with chain rule.
3818 operand immP_NM() %{
3819 match(ConP);
3820 predicate(false);
3821 op_cost(0);
3822 format %{ %}
3823 interface(CONST_INTER);
3824 %}
3825
3826 // constant 'pointer 0'.
3827 operand immP_0() %{
3828 predicate(n->get_ptr() == 0);
3829 match(ConP);
3830 op_cost(0);
3831 format %{ %}
3832 interface(CONST_INTER);
3833 %}
3834
3835 // pointer 0x0 or 0x1
3836 operand immP_0or1() %{
3837 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
3838 match(ConP);
3839 op_cost(0);
3840 format %{ %}
3841 interface(CONST_INTER);
3842 %}
3843
3844 operand immL() %{
3845 match(ConL);
3846 op_cost(40);
3847 format %{ %}
3848 interface(CONST_INTER);
3849 %}
3850
3851 operand immLmax30() %{
3852 predicate((n->get_long() <= 30));
3853 match(ConL);
3854 op_cost(0);
3855 format %{ %}
3856 interface(CONST_INTER);
3857 %}
3858
3859 // Long Immediate: 16-bit
3860 operand immL16() %{
3861 predicate(Assembler::is_simm(n->get_long(), 16));
3862 match(ConL);
3863 op_cost(0);
3864 format %{ %}
3865 interface(CONST_INTER);
3866 %}
3867
3868 // Long Immediate: 16-bit, 4-aligned
3869 operand immL16Alg4() %{
3870 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
3871 match(ConL);
3872 op_cost(0);
3873 format %{ %}
3874 interface(CONST_INTER);
3875 %}
3876
3877 // Long Immediate: 16-bit, 16-aligned
3878 operand immL16Alg16() %{
3879 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0xf) == 0));
3880 match(ConL);
3881 op_cost(0);
3882 format %{ %}
3883 interface(CONST_INTER);
3884 %}
3885
3886 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
3887 operand immL32hi16() %{
3888 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L));
3889 match(ConL);
3890 op_cost(0);
3891 format %{ %}
3892 interface(CONST_INTER);
3893 %}
3894
3895 // Long Immediate: 32-bit
3896 operand immL32() %{
3897 predicate(Assembler::is_simm(n->get_long(), 32));
3898 match(ConL);
3899 op_cost(0);
3900 format %{ %}
3901 interface(CONST_INTER);
3902 %}
3903
3904 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store.
3905 operand immL34() %{
3906 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34));
3907 match(ConL);
3908 op_cost(0);
3909 format %{ %}
3910 interface(CONST_INTER);
3911 %}
3912
3913 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000.
3914 operand immLhighest16() %{
3915 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L);
3916 match(ConL);
3917 op_cost(0);
3918 format %{ %}
3919 interface(CONST_INTER);
3920 %}
3921
3922 operand immLnegpow2() %{
3923 predicate(is_power_of_2(-(julong)(n->get_long())));
3924 match(ConL);
3925 op_cost(0);
3926 format %{ %}
3927 interface(CONST_INTER);
3928 %}
3929
3930 operand immLpow2minus1() %{
3931 predicate(is_power_of_2((julong)(n->get_long()) + 1ull));
3932 match(ConL);
3933 op_cost(0);
3934 format %{ %}
3935 interface(CONST_INTER);
3936 %}
3937
3938 // constant 'long 0'.
3939 operand immL_0() %{
3940 predicate(n->get_long() == 0L);
3941 match(ConL);
3942 op_cost(0);
3943 format %{ %}
3944 interface(CONST_INTER);
3945 %}
3946
3947 // constat ' long -1'.
3948 operand immL_minus1() %{
3949 predicate(n->get_long() == -1L);
3950 match(ConL);
3951 op_cost(0);
3952 format %{ %}
3953 interface(CONST_INTER);
3954 %}
3955
3956 // Long Immediate: low 32-bit mask
3957 operand immL_32bits() %{
3958 predicate(n->get_long() == 0xFFFFFFFFL);
3959 match(ConL);
3960 op_cost(0);
3961 format %{ %}
3962 interface(CONST_INTER);
3963 %}
3964
3965 // Unsigned Long Immediate: 16-bit
3966 operand uimmL16() %{
3967 predicate(Assembler::is_uimm(n->get_long(), 16));
3968 match(ConL);
3969 op_cost(0);
3970 format %{ %}
3971 interface(CONST_INTER);
3972 %}
3973
3974 // Float Immediate
3975 operand immF() %{
3976 match(ConF);
3977 op_cost(40);
3978 format %{ %}
3979 interface(CONST_INTER);
3980 %}
3981
3982 // Float Immediate: +0.0f.
3983 operand immF_0() %{
3984 predicate(jint_cast(n->getf()) == 0);
3985 match(ConF);
3986
3987 op_cost(0);
3988 format %{ %}
3989 interface(CONST_INTER);
3990 %}
3991
3992 // Double Immediate
3993 operand immD() %{
3994 match(ConD);
3995 op_cost(40);
3996 format %{ %}
3997 interface(CONST_INTER);
3998 %}
3999
4000 // Double Immediate: +0.0d.
4001 operand immD_0() %{
4002 predicate(jlong_cast(n->getd()) == 0);
4003 match(ConD);
4004
4005 op_cost(0);
4006 format %{ %}
4007 interface(CONST_INTER);
4008 %}
4009
4010 // Integer Register Operands
4011 // Integer Destination Register
4012 // See definition of reg_class bits32_reg_rw.
4013 operand iRegIdst() %{
4014 constraint(ALLOC_IN_RC(bits32_reg_rw));
4015 match(RegI);
4016 match(rscratch1RegI);
4017 match(rscratch2RegI);
4018 match(rarg1RegI);
4019 match(rarg2RegI);
4020 match(rarg3RegI);
4021 match(rarg4RegI);
4022 format %{ %}
4023 interface(REG_INTER);
4024 %}
4025
4026 // Integer Source Register
4027 // See definition of reg_class bits32_reg_ro.
4028 operand iRegIsrc() %{
4029 constraint(ALLOC_IN_RC(bits32_reg_ro));
4030 match(RegI);
4031 match(rscratch1RegI);
4032 match(rscratch2RegI);
4033 match(rarg1RegI);
4034 match(rarg2RegI);
4035 match(rarg3RegI);
4036 match(rarg4RegI);
4037 format %{ %}
4038 interface(REG_INTER);
4039 %}
4040
4041 operand rscratch1RegI() %{
4042 constraint(ALLOC_IN_RC(rscratch1_bits32_reg));
4043 match(iRegIdst);
4044 format %{ %}
4045 interface(REG_INTER);
4046 %}
4047
4048 operand rscratch2RegI() %{
4049 constraint(ALLOC_IN_RC(rscratch2_bits32_reg));
4050 match(iRegIdst);
4051 format %{ %}
4052 interface(REG_INTER);
4053 %}
4054
4055 operand rarg1RegI() %{
4056 constraint(ALLOC_IN_RC(rarg1_bits32_reg));
4057 match(iRegIdst);
4058 format %{ %}
4059 interface(REG_INTER);
4060 %}
4061
4062 operand rarg2RegI() %{
4063 constraint(ALLOC_IN_RC(rarg2_bits32_reg));
4064 match(iRegIdst);
4065 format %{ %}
4066 interface(REG_INTER);
4067 %}
4068
4069 operand rarg3RegI() %{
4070 constraint(ALLOC_IN_RC(rarg3_bits32_reg));
4071 match(iRegIdst);
4072 format %{ %}
4073 interface(REG_INTER);
4074 %}
4075
4076 operand rarg4RegI() %{
4077 constraint(ALLOC_IN_RC(rarg4_bits32_reg));
4078 match(iRegIdst);
4079 format %{ %}
4080 interface(REG_INTER);
4081 %}
4082
4083 operand rarg1RegL() %{
4084 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4085 match(iRegLdst);
4086 format %{ %}
4087 interface(REG_INTER);
4088 %}
4089
4090 // Pointer Destination Register
4091 // See definition of reg_class bits64_reg_rw.
4092 operand iRegPdst() %{
4093 constraint(ALLOC_IN_RC(bits64_reg_rw));
4094 match(RegP);
4095 match(rscratch1RegP);
4096 match(rscratch2RegP);
4097 match(rarg1RegP);
4098 match(rarg2RegP);
4099 match(rarg3RegP);
4100 match(rarg4RegP);
4101 format %{ %}
4102 interface(REG_INTER);
4103 %}
4104
4105 // Pointer Destination Register
4106 // Operand not using r11 and r12 (killed in epilog).
4107 operand iRegPdstNoScratch() %{
4108 constraint(ALLOC_IN_RC(bits64_reg_leaf_call));
4109 match(RegP);
4110 match(rarg1RegP);
4111 match(rarg2RegP);
4112 match(rarg3RegP);
4113 match(rarg4RegP);
4114 format %{ %}
4115 interface(REG_INTER);
4116 %}
4117
4118 // Pointer Source Register
4119 // See definition of reg_class bits64_reg_ro.
4120 operand iRegPsrc() %{
4121 constraint(ALLOC_IN_RC(bits64_reg_ro));
4122 match(RegP);
4123 match(iRegPdst);
4124 match(rscratch1RegP);
4125 match(rscratch2RegP);
4126 match(rarg1RegP);
4127 match(rarg2RegP);
4128 match(rarg3RegP);
4129 match(rarg4RegP);
4130 match(rarg5RegP);
4131 match(rarg6RegP);
4132 match(threadRegP);
4133 format %{ %}
4134 interface(REG_INTER);
4135 %}
4136
4137 // Thread operand.
4138 operand threadRegP() %{
4139 constraint(ALLOC_IN_RC(thread_bits64_reg));
4140 match(iRegPdst);
4141 format %{ "R16" %}
4142 interface(REG_INTER);
4143 %}
4144
4145 operand rscratch1RegP() %{
4146 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4147 match(iRegPdst);
4148 format %{ "R11" %}
4149 interface(REG_INTER);
4150 %}
4151
4152 operand rscratch2RegP() %{
4153 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4154 match(iRegPdst);
4155 format %{ %}
4156 interface(REG_INTER);
4157 %}
4158
4159 operand rarg1RegP() %{
4160 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4161 match(iRegPdst);
4162 format %{ %}
4163 interface(REG_INTER);
4164 %}
4165
4166 operand rarg2RegP() %{
4167 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4168 match(iRegPdst);
4169 format %{ %}
4170 interface(REG_INTER);
4171 %}
4172
4173 operand rarg3RegP() %{
4174 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4175 match(iRegPdst);
4176 format %{ %}
4177 interface(REG_INTER);
4178 %}
4179
4180 operand rarg4RegP() %{
4181 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4182 match(iRegPdst);
4183 format %{ %}
4184 interface(REG_INTER);
4185 %}
4186
4187 operand rarg5RegP() %{
4188 constraint(ALLOC_IN_RC(rarg5_bits64_reg));
4189 match(iRegPdst);
4190 format %{ %}
4191 interface(REG_INTER);
4192 %}
4193
4194 operand rarg6RegP() %{
4195 constraint(ALLOC_IN_RC(rarg6_bits64_reg));
4196 match(iRegPdst);
4197 format %{ %}
4198 interface(REG_INTER);
4199 %}
4200
4201 operand iRegNsrc() %{
4202 constraint(ALLOC_IN_RC(bits32_reg_ro));
4203 match(RegN);
4204 match(iRegNdst);
4205
4206 format %{ %}
4207 interface(REG_INTER);
4208 %}
4209
4210 operand iRegNdst() %{
4211 constraint(ALLOC_IN_RC(bits32_reg_rw));
4212 match(RegN);
4213
4214 format %{ %}
4215 interface(REG_INTER);
4216 %}
4217
4218 // Long Destination Register
4219 // See definition of reg_class bits64_reg_rw.
4220 operand iRegLdst() %{
4221 constraint(ALLOC_IN_RC(bits64_reg_rw));
4222 match(RegL);
4223 match(rscratch1RegL);
4224 match(rscratch2RegL);
4225 format %{ %}
4226 interface(REG_INTER);
4227 %}
4228
4229 // Long Source Register
4230 // See definition of reg_class bits64_reg_ro.
4231 operand iRegLsrc() %{
4232 constraint(ALLOC_IN_RC(bits64_reg_ro));
4233 match(RegL);
4234 match(iRegLdst);
4235 match(rscratch1RegL);
4236 match(rscratch2RegL);
4237 format %{ %}
4238 interface(REG_INTER);
4239 %}
4240
4241 // Special operand for ConvL2I.
4242 operand iRegL2Isrc(iRegLsrc reg) %{
4243 constraint(ALLOC_IN_RC(bits64_reg_ro));
4244 match(ConvL2I reg);
4245 format %{ "ConvL2I($reg)" %}
4246 interface(REG_INTER)
4247 %}
4248
4249 operand rscratch1RegL() %{
4250 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4251 match(RegL);
4252 format %{ %}
4253 interface(REG_INTER);
4254 %}
4255
4256 operand rscratch2RegL() %{
4257 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4258 match(RegL);
4259 format %{ %}
4260 interface(REG_INTER);
4261 %}
4262
4263 // Condition Code Flag Registers
4264 operand flagsReg() %{
4265 constraint(ALLOC_IN_RC(int_flags));
4266 match(RegFlags);
4267 format %{ %}
4268 interface(REG_INTER);
4269 %}
4270
4271 operand flagsRegSrc() %{
4272 constraint(ALLOC_IN_RC(int_flags_ro));
4273 match(RegFlags);
4274 match(flagsReg);
4275 match(flagsRegCR0);
4276 format %{ %}
4277 interface(REG_INTER);
4278 %}
4279
4280 // Condition Code Flag Register CR0
4281 operand flagsRegCR0() %{
4282 constraint(ALLOC_IN_RC(int_flags_CR0));
4283 match(RegFlags);
4284 format %{ "CR0" %}
4285 interface(REG_INTER);
4286 %}
4287
4288 operand flagsRegCR1() %{
4289 constraint(ALLOC_IN_RC(int_flags_CR1));
4290 match(RegFlags);
4291 format %{ "CR1" %}
4292 interface(REG_INTER);
4293 %}
4294
4295 operand flagsRegCR6() %{
4296 constraint(ALLOC_IN_RC(int_flags_CR6));
4297 match(RegFlags);
4298 format %{ "CR6" %}
4299 interface(REG_INTER);
4300 %}
4301
4302 operand regCTR() %{
4303 constraint(ALLOC_IN_RC(ctr_reg));
4304 // RegFlags should work. Introducing a RegSpecial type would cause a
4305 // lot of changes.
4306 match(RegFlags);
4307 format %{"SR_CTR" %}
4308 interface(REG_INTER);
4309 %}
4310
4311 operand regD() %{
4312 constraint(ALLOC_IN_RC(dbl_reg));
4313 match(RegD);
4314 format %{ %}
4315 interface(REG_INTER);
4316 %}
4317
4318 operand regF() %{
4319 constraint(ALLOC_IN_RC(flt_reg));
4320 match(RegF);
4321 format %{ %}
4322 interface(REG_INTER);
4323 %}
4324
4325 // Special Registers
4326
4327 // Method Register
4328 operand inline_cache_regP(iRegPdst reg) %{
4329 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg
4330 match(reg);
4331 format %{ %}
4332 interface(REG_INTER);
4333 %}
4334
4335 // Operands to remove register moves in unscaled mode.
4336 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4337 operand iRegP2N(iRegPsrc reg) %{
4338 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0);
4339 constraint(ALLOC_IN_RC(bits64_reg_ro));
4340 match(EncodeP reg);
4341 format %{ "$reg" %}
4342 interface(REG_INTER)
4343 %}
4344
4345 operand iRegN2P(iRegNsrc reg) %{
4346 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4347 constraint(ALLOC_IN_RC(bits32_reg_ro));
4348 match(DecodeN reg);
4349 format %{ "$reg" %}
4350 interface(REG_INTER)
4351 %}
4352
4353 operand iRegN2P_klass(iRegNsrc reg) %{
4354 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4355 constraint(ALLOC_IN_RC(bits32_reg_ro));
4356 match(DecodeNKlass reg);
4357 format %{ "$reg" %}
4358 interface(REG_INTER)
4359 %}
4360
4361 //----------Complex Operands---------------------------------------------------
4362 // Indirect Memory Reference
4363 operand indirect(iRegPsrc reg) %{
4364 constraint(ALLOC_IN_RC(bits64_reg_ro));
4365 match(reg);
4366 op_cost(100);
4367 format %{ "[$reg]" %}
4368 interface(MEMORY_INTER) %{
4369 base($reg);
4370 index(0x0);
4371 scale(0x0);
4372 disp(0x0);
4373 %}
4374 %}
4375
4376 // Indirect with Offset
4377 operand indOffset16(iRegPsrc reg, immL16 offset) %{
4378 constraint(ALLOC_IN_RC(bits64_reg_ro));
4379 match(AddP reg offset);
4380 op_cost(100);
4381 format %{ "[$reg + $offset]" %}
4382 interface(MEMORY_INTER) %{
4383 base($reg);
4384 index(0x0);
4385 scale(0x0);
4386 disp($offset);
4387 %}
4388 %}
4389
4390 // Indirect with 4-aligned Offset
4391 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{
4392 constraint(ALLOC_IN_RC(bits64_reg_ro));
4393 match(AddP reg offset);
4394 op_cost(100);
4395 format %{ "[$reg + $offset]" %}
4396 interface(MEMORY_INTER) %{
4397 base($reg);
4398 index(0x0);
4399 scale(0x0);
4400 disp($offset);
4401 %}
4402 %}
4403
4404 // Indirect with 16-aligned Offset
4405 operand indOffset16Alg16(iRegPsrc reg, immL16Alg16 offset) %{
4406 constraint(ALLOC_IN_RC(bits64_reg_ro));
4407 match(AddP reg offset);
4408 op_cost(100);
4409 format %{ "[$reg + $offset]" %}
4410 interface(MEMORY_INTER) %{
4411 base($reg);
4412 index(0x0);
4413 scale(0x0);
4414 disp($offset);
4415 %}
4416 %}
4417
4418 //----------Complex Operands for Compressed OOPs-------------------------------
4419 // Compressed OOPs with narrow_oop_shift == 0.
4420
4421 // Indirect Memory Reference, compressed OOP
4422 operand indirectNarrow(iRegNsrc reg) %{
4423 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4424 constraint(ALLOC_IN_RC(bits64_reg_ro));
4425 match(DecodeN reg);
4426 op_cost(100);
4427 format %{ "[$reg]" %}
4428 interface(MEMORY_INTER) %{
4429 base($reg);
4430 index(0x0);
4431 scale(0x0);
4432 disp(0x0);
4433 %}
4434 %}
4435
4436 operand indirectNarrow_klass(iRegNsrc reg) %{
4437 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4438 constraint(ALLOC_IN_RC(bits64_reg_ro));
4439 match(DecodeNKlass reg);
4440 op_cost(100);
4441 format %{ "[$reg]" %}
4442 interface(MEMORY_INTER) %{
4443 base($reg);
4444 index(0x0);
4445 scale(0x0);
4446 disp(0x0);
4447 %}
4448 %}
4449
4450 // Indirect with Offset, compressed OOP
4451 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4452 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4453 constraint(ALLOC_IN_RC(bits64_reg_ro));
4454 match(AddP (DecodeN reg) offset);
4455 op_cost(100);
4456 format %{ "[$reg + $offset]" %}
4457 interface(MEMORY_INTER) %{
4458 base($reg);
4459 index(0x0);
4460 scale(0x0);
4461 disp($offset);
4462 %}
4463 %}
4464
4465 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4466 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4467 constraint(ALLOC_IN_RC(bits64_reg_ro));
4468 match(AddP (DecodeNKlass reg) offset);
4469 op_cost(100);
4470 format %{ "[$reg + $offset]" %}
4471 interface(MEMORY_INTER) %{
4472 base($reg);
4473 index(0x0);
4474 scale(0x0);
4475 disp($offset);
4476 %}
4477 %}
4478
4479 // Indirect with 4-aligned Offset, compressed OOP
4480 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4481 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4482 constraint(ALLOC_IN_RC(bits64_reg_ro));
4483 match(AddP (DecodeN reg) offset);
4484 op_cost(100);
4485 format %{ "[$reg + $offset]" %}
4486 interface(MEMORY_INTER) %{
4487 base($reg);
4488 index(0x0);
4489 scale(0x0);
4490 disp($offset);
4491 %}
4492 %}
4493
4494 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4495 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4496 constraint(ALLOC_IN_RC(bits64_reg_ro));
4497 match(AddP (DecodeNKlass reg) offset);
4498 op_cost(100);
4499 format %{ "[$reg + $offset]" %}
4500 interface(MEMORY_INTER) %{
4501 base($reg);
4502 index(0x0);
4503 scale(0x0);
4504 disp($offset);
4505 %}
4506 %}
4507
4508 //----------Special Memory Operands--------------------------------------------
4509 // Stack Slot Operand
4510 //
4511 // This operand is used for loading and storing temporary values on
4512 // the stack where a match requires a value to flow through memory.
4513 operand stackSlotI(sRegI reg) %{
4514 constraint(ALLOC_IN_RC(stack_slots));
4515 op_cost(100);
4516 //match(RegI);
4517 format %{ "[sp+$reg]" %}
4518 interface(MEMORY_INTER) %{
4519 base(0x1); // R1_SP
4520 index(0x0);
4521 scale(0x0);
4522 disp($reg); // Stack Offset
4523 %}
4524 %}
4525
4526 operand stackSlotL(sRegL reg) %{
4527 constraint(ALLOC_IN_RC(stack_slots));
4528 op_cost(100);
4529 //match(RegL);
4530 format %{ "[sp+$reg]" %}
4531 interface(MEMORY_INTER) %{
4532 base(0x1); // R1_SP
4533 index(0x0);
4534 scale(0x0);
4535 disp($reg); // Stack Offset
4536 %}
4537 %}
4538
4539 operand stackSlotP(sRegP reg) %{
4540 constraint(ALLOC_IN_RC(stack_slots));
4541 op_cost(100);
4542 //match(RegP);
4543 format %{ "[sp+$reg]" %}
4544 interface(MEMORY_INTER) %{
4545 base(0x1); // R1_SP
4546 index(0x0);
4547 scale(0x0);
4548 disp($reg); // Stack Offset
4549 %}
4550 %}
4551
4552 operand stackSlotF(sRegF reg) %{
4553 constraint(ALLOC_IN_RC(stack_slots));
4554 op_cost(100);
4555 //match(RegF);
4556 format %{ "[sp+$reg]" %}
4557 interface(MEMORY_INTER) %{
4558 base(0x1); // R1_SP
4559 index(0x0);
4560 scale(0x0);
4561 disp($reg); // Stack Offset
4562 %}
4563 %}
4564
4565 operand stackSlotD(sRegD reg) %{
4566 constraint(ALLOC_IN_RC(stack_slots));
4567 op_cost(100);
4568 //match(RegD);
4569 format %{ "[sp+$reg]" %}
4570 interface(MEMORY_INTER) %{
4571 base(0x1); // R1_SP
4572 index(0x0);
4573 scale(0x0);
4574 disp($reg); // Stack Offset
4575 %}
4576 %}
4577
4578 // Operands for expressing Control Flow
4579 // NOTE: Label is a predefined operand which should not be redefined in
4580 // the AD file. It is generically handled within the ADLC.
4581
4582 //----------Conditional Branch Operands----------------------------------------
4583 // Comparison Op
4584 //
4585 // This is the operation of the comparison, and is limited to the
4586 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE
4587 // (!=).
4588 //
4589 // Other attributes of the comparison, such as unsignedness, are specified
4590 // by the comparison instruction that sets a condition code flags register.
4591 // That result is represented by a flags operand whose subtype is appropriate
4592 // to the unsignedness (etc.) of the comparison.
4593 //
4594 // Later, the instruction which matches both the Comparison Op (a Bool) and
4595 // the flags (produced by the Cmp) specifies the coding of the comparison op
4596 // by matching a specific subtype of Bool operand below.
4597
4598 // When used for floating point comparisons: unordered same as less.
4599 operand cmpOp() %{
4600 match(Bool);
4601 format %{ "" %}
4602 interface(COND_INTER) %{
4603 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'.
4604 // BO & BI
4605 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4606 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4607 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4608 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4609 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4610 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4611 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4612 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4613 %}
4614 %}
4615
4616 //----------OPERAND CLASSES----------------------------------------------------
4617 // Operand Classes are groups of operands that are used to simplify
4618 // instruction definitions by not requiring the AD writer to specify
4619 // separate instructions for every form of operand when the
4620 // instruction accepts multiple operand types with the same basic
4621 // encoding and format. The classic case of this is memory operands.
4622 // Indirect is not included since its use is limited to Compare & Swap.
4623
4624 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4625 // Memory operand where offsets are 4-aligned. Required for ld, std.
4626 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4627 opclass memoryAlg16(indirect, indOffset16Alg16);
4628 opclass indirectMemory(indirect, indirectNarrow);
4629
4630 // Special opclass for I and ConvL2I.
4631 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4632
4633 // Operand classes to match encode and decode. iRegN_P2N is only used
4634 // for storeN. I have never seen an encode node elsewhere.
4635 opclass iRegN_P2N(iRegNsrc, iRegP2N);
4636 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4637
4638 //----------PIPELINE-----------------------------------------------------------
4639
4640 pipeline %{
4641
4642 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4643 // J. Res. & Dev., No. 1, Jan. 2002.
4644
4645 //----------ATTRIBUTES---------------------------------------------------------
4646 attributes %{
4647
4648 // Power4 instructions are of fixed length.
4649 fixed_size_instructions;
4650
4651 // TODO: if `bundle' means number of instructions fetched
4652 // per cycle, this is 8. If `bundle' means Power4 `group', that is
4653 // max instructions issued per cycle, this is 5.
4654 max_instructions_per_bundle = 8;
4655
4656 // A Power4 instruction is 4 bytes long.
4657 instruction_unit_size = 4;
4658
4659 // The Power4 processor fetches 64 bytes...
4660 instruction_fetch_unit_size = 64;
4661
4662 // ...in one line
4663 instruction_fetch_units = 1
4664 %}
4665
4666 //----------RESOURCES----------------------------------------------------------
4667 // Resources are the functional units available to the machine
4668 resources(
4669 PPC_BR, // branch unit
4670 PPC_CR, // condition unit
4671 PPC_FX1, // integer arithmetic unit 1
4672 PPC_FX2, // integer arithmetic unit 2
4673 PPC_LDST1, // load/store unit 1
4674 PPC_LDST2, // load/store unit 2
4675 PPC_FP1, // float arithmetic unit 1
4676 PPC_FP2, // float arithmetic unit 2
4677 PPC_LDST = PPC_LDST1 | PPC_LDST2,
4678 PPC_FX = PPC_FX1 | PPC_FX2,
4679 PPC_FP = PPC_FP1 | PPC_FP2
4680 );
4681
4682 //----------PIPELINE DESCRIPTION-----------------------------------------------
4683 // Pipeline Description specifies the stages in the machine's pipeline
4684 pipe_desc(
4685 // Power4 longest pipeline path
4686 PPC_IF, // instruction fetch
4687 PPC_IC,
4688 //PPC_BP, // branch prediction
4689 PPC_D0, // decode
4690 PPC_D1, // decode
4691 PPC_D2, // decode
4692 PPC_D3, // decode
4693 PPC_Xfer1,
4694 PPC_GD, // group definition
4695 PPC_MP, // map
4696 PPC_ISS, // issue
4697 PPC_RF, // resource fetch
4698 PPC_EX1, // execute (all units)
4699 PPC_EX2, // execute (FP, LDST)
4700 PPC_EX3, // execute (FP, LDST)
4701 PPC_EX4, // execute (FP)
4702 PPC_EX5, // execute (FP)
4703 PPC_EX6, // execute (FP)
4704 PPC_WB, // write back
4705 PPC_Xfer2,
4706 PPC_CP
4707 );
4708
4709 //----------PIPELINE CLASSES---------------------------------------------------
4710 // Pipeline Classes describe the stages in which input and output are
4711 // referenced by the hardware pipeline.
4712
4713 // Simple pipeline classes.
4714
4715 // Default pipeline class.
4716 pipe_class pipe_class_default() %{
4717 single_instruction;
4718 fixed_latency(2);
4719 %}
4720
4721 // Pipeline class for empty instructions.
4722 pipe_class pipe_class_empty() %{
4723 single_instruction;
4724 fixed_latency(0);
4725 %}
4726
4727 // Pipeline class for compares.
4728 pipe_class pipe_class_compare() %{
4729 single_instruction;
4730 fixed_latency(16);
4731 %}
4732
4733 // Pipeline class for traps.
4734 pipe_class pipe_class_trap() %{
4735 single_instruction;
4736 fixed_latency(100);
4737 %}
4738
4739 // Pipeline class for memory operations.
4740 pipe_class pipe_class_memory() %{
4741 single_instruction;
4742 fixed_latency(16);
4743 %}
4744
4745 // Pipeline class for call.
4746 pipe_class pipe_class_call() %{
4747 single_instruction;
4748 fixed_latency(100);
4749 %}
4750
4751 // Define the class for the Nop node.
4752 define %{
4753 MachNop = pipe_class_default;
4754 %}
4755
4756 %}
4757
4758 //----------INSTRUCTIONS-------------------------------------------------------
4759
4760 // Naming of instructions:
4761 // opA_operB / opA_operB_operC:
4762 // Operation 'op' with one or two source operands 'oper'. Result
4763 // type is A, source operand types are B and C.
4764 // Iff A == B == C, B and C are left out.
4765 //
4766 // The instructions are ordered according to the following scheme:
4767 // - loads
4768 // - load constants
4769 // - prefetch
4770 // - store
4771 // - encode/decode
4772 // - membar
4773 // - conditional moves
4774 // - compare & swap
4775 // - arithmetic and logic operations
4776 // * int: Add, Sub, Mul, Div, Mod
4777 // * int: lShift, arShift, urShift, rot
4778 // * float: Add, Sub, Mul, Div
4779 // * and, or, xor ...
4780 // - register moves: float <-> int, reg <-> stack, repl
4781 // - cast (high level type cast, XtoP, castPP, castII, not_null etc.
4782 // - conv (low level type cast requiring bit changes (sign extend etc)
4783 // - compares, range & zero checks.
4784 // - branches
4785 // - complex operations, intrinsics, min, max, replicate
4786 // - lock
4787 // - Calls
4788 //
4789 // If there are similar instructions with different types they are sorted:
4790 // int before float
4791 // small before big
4792 // signed before unsigned
4793 // e.g., loadS before loadUS before loadI before loadF.
4794
4795
4796 //----------Load/Store Instructions--------------------------------------------
4797
4798 //----------Load Instructions--------------------------------------------------
4799
4800 // Converts byte to int.
4801 // As convB2I_reg, but without match rule. The match rule of convB2I_reg
4802 // reuses the 'amount' operand, but adlc expects that operand specification
4803 // and operands in match rule are equivalent.
4804 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
4805 effect(DEF dst, USE src);
4806 format %{ "EXTSB $dst, $src \t// byte->int" %}
4807 size(4);
4808 ins_encode %{
4809 __ extsb($dst$$Register, $src$$Register);
4810 %}
4811 ins_pipe(pipe_class_default);
4812 %}
4813
4814 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{
4815 // match-rule, false predicate
4816 match(Set dst (LoadB mem));
4817 predicate(false);
4818
4819 format %{ "LBZ $dst, $mem" %}
4820 size(4);
4821 ins_encode( enc_lbz(dst, mem) );
4822 ins_pipe(pipe_class_memory);
4823 %}
4824
4825 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{
4826 // match-rule, false predicate
4827 match(Set dst (LoadB mem));
4828 predicate(false);
4829
4830 format %{ "LBZ $dst, $mem\n\t"
4831 "TWI $dst\n\t"
4832 "ISYNC" %}
4833 size(12);
4834 ins_encode( enc_lbz_ac(dst, mem) );
4835 ins_pipe(pipe_class_memory);
4836 %}
4837
4838 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
4839 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{
4840 match(Set dst (LoadB mem));
4841 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4842 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4843 expand %{
4844 iRegIdst tmp;
4845 loadUB_indirect(tmp, mem);
4846 convB2I_reg_2(dst, tmp);
4847 %}
4848 %}
4849
4850 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{
4851 match(Set dst (LoadB mem));
4852 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
4853 expand %{
4854 iRegIdst tmp;
4855 loadUB_indirect_ac(tmp, mem);
4856 convB2I_reg_2(dst, tmp);
4857 %}
4858 %}
4859
4860 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{
4861 // match-rule, false predicate
4862 match(Set dst (LoadB mem));
4863 predicate(false);
4864
4865 format %{ "LBZ $dst, $mem" %}
4866 size(4);
4867 ins_encode( enc_lbz(dst, mem) );
4868 ins_pipe(pipe_class_memory);
4869 %}
4870
4871 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{
4872 // match-rule, false predicate
4873 match(Set dst (LoadB mem));
4874 predicate(false);
4875
4876 format %{ "LBZ $dst, $mem\n\t"
4877 "TWI $dst\n\t"
4878 "ISYNC" %}
4879 size(12);
4880 ins_encode( enc_lbz_ac(dst, mem) );
4881 ins_pipe(pipe_class_memory);
4882 %}
4883
4884 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
4885 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{
4886 match(Set dst (LoadB mem));
4887 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4888 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4889
4890 expand %{
4891 iRegIdst tmp;
4892 loadUB_indOffset16(tmp, mem);
4893 convB2I_reg_2(dst, tmp);
4894 %}
4895 %}
4896
4897 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{
4898 match(Set dst (LoadB mem));
4899 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
4900
4901 expand %{
4902 iRegIdst tmp;
4903 loadUB_indOffset16_ac(tmp, mem);
4904 convB2I_reg_2(dst, tmp);
4905 %}
4906 %}
4907
4908 // Load Unsigned Byte (8bit UNsigned) into an int reg.
4909 instruct loadUB(iRegIdst dst, memory mem) %{
4910 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4911 match(Set dst (LoadUB mem));
4912 ins_cost(MEMORY_REF_COST);
4913
4914 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %}
4915 size(4);
4916 ins_encode( enc_lbz(dst, mem) );
4917 ins_pipe(pipe_class_memory);
4918 %}
4919
4920 // Load Unsigned Byte (8bit UNsigned) acquire.
4921 instruct loadUB_ac(iRegIdst dst, memory mem) %{
4922 match(Set dst (LoadUB mem));
4923 ins_cost(3*MEMORY_REF_COST);
4924
4925 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t"
4926 "TWI $dst\n\t"
4927 "ISYNC" %}
4928 size(12);
4929 ins_encode( enc_lbz_ac(dst, mem) );
4930 ins_pipe(pipe_class_memory);
4931 %}
4932
4933 // Load Unsigned Byte (8bit UNsigned) into a Long Register.
4934 instruct loadUB2L(iRegLdst dst, memory mem) %{
4935 match(Set dst (ConvI2L (LoadUB mem)));
4936 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
4937 ins_cost(MEMORY_REF_COST);
4938
4939 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %}
4940 size(4);
4941 ins_encode( enc_lbz(dst, mem) );
4942 ins_pipe(pipe_class_memory);
4943 %}
4944
4945 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{
4946 match(Set dst (ConvI2L (LoadUB mem)));
4947 ins_cost(3*MEMORY_REF_COST);
4948
4949 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t"
4950 "TWI $dst\n\t"
4951 "ISYNC" %}
4952 size(12);
4953 ins_encode( enc_lbz_ac(dst, mem) );
4954 ins_pipe(pipe_class_memory);
4955 %}
4956
4957 // Load Short (16bit signed)
4958 instruct loadS(iRegIdst dst, memory mem) %{
4959 match(Set dst (LoadS mem));
4960 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4961 ins_cost(MEMORY_REF_COST);
4962
4963 format %{ "LHA $dst, $mem" %}
4964 size(4);
4965 ins_encode %{
4966 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
4967 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
4968 %}
4969 ins_pipe(pipe_class_memory);
4970 %}
4971
4972 // Load Short (16bit signed) acquire.
4973 instruct loadS_ac(iRegIdst dst, memory mem) %{
4974 match(Set dst (LoadS mem));
4975 ins_cost(3*MEMORY_REF_COST);
4976
4977 format %{ "LHA $dst, $mem\t acquire\n\t"
4978 "TWI $dst\n\t"
4979 "ISYNC" %}
4980 size(12);
4981 ins_encode %{
4982 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
4983 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
4984 __ twi_0($dst$$Register);
4985 __ isync();
4986 %}
4987 ins_pipe(pipe_class_memory);
4988 %}
4989
4990 // Load Char (16bit unsigned)
4991 instruct loadUS(iRegIdst dst, memory mem) %{
4992 match(Set dst (LoadUS mem));
4993 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4994 ins_cost(MEMORY_REF_COST);
4995
4996 format %{ "LHZ $dst, $mem" %}
4997 size(4);
4998 ins_encode( enc_lhz(dst, mem) );
4999 ins_pipe(pipe_class_memory);
5000 %}
5001
5002 // Load Char (16bit unsigned) acquire.
5003 instruct loadUS_ac(iRegIdst dst, memory mem) %{
5004 match(Set dst (LoadUS mem));
5005 ins_cost(3*MEMORY_REF_COST);
5006
5007 format %{ "LHZ $dst, $mem \t// acquire\n\t"
5008 "TWI $dst\n\t"
5009 "ISYNC" %}
5010 size(12);
5011 ins_encode( enc_lhz_ac(dst, mem) );
5012 ins_pipe(pipe_class_memory);
5013 %}
5014
5015 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register.
5016 instruct loadUS2L(iRegLdst dst, memory mem) %{
5017 match(Set dst (ConvI2L (LoadUS mem)));
5018 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5019 ins_cost(MEMORY_REF_COST);
5020
5021 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %}
5022 size(4);
5023 ins_encode( enc_lhz(dst, mem) );
5024 ins_pipe(pipe_class_memory);
5025 %}
5026
5027 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire.
5028 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{
5029 match(Set dst (ConvI2L (LoadUS mem)));
5030 ins_cost(3*MEMORY_REF_COST);
5031
5032 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t"
5033 "TWI $dst\n\t"
5034 "ISYNC" %}
5035 size(12);
5036 ins_encode( enc_lhz_ac(dst, mem) );
5037 ins_pipe(pipe_class_memory);
5038 %}
5039
5040 // Load Integer.
5041 instruct loadI(iRegIdst dst, memory mem) %{
5042 match(Set dst (LoadI mem));
5043 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5044 ins_cost(MEMORY_REF_COST);
5045
5046 format %{ "LWZ $dst, $mem" %}
5047 size(4);
5048 ins_encode( enc_lwz(dst, mem) );
5049 ins_pipe(pipe_class_memory);
5050 %}
5051
5052 // Load Integer acquire.
5053 instruct loadI_ac(iRegIdst dst, memory mem) %{
5054 match(Set dst (LoadI mem));
5055 ins_cost(3*MEMORY_REF_COST);
5056
5057 format %{ "LWZ $dst, $mem \t// load acquire\n\t"
5058 "TWI $dst\n\t"
5059 "ISYNC" %}
5060 size(12);
5061 ins_encode( enc_lwz_ac(dst, mem) );
5062 ins_pipe(pipe_class_memory);
5063 %}
5064
5065 // Match loading integer and casting it to unsigned int in
5066 // long register.
5067 // LoadI + ConvI2L + AndL 0xffffffff.
5068 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
5069 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5070 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered());
5071 ins_cost(MEMORY_REF_COST);
5072
5073 format %{ "LWZ $dst, $mem \t// zero-extend to long" %}
5074 size(4);
5075 ins_encode( enc_lwz(dst, mem) );
5076 ins_pipe(pipe_class_memory);
5077 %}
5078
5079 // Match loading integer and casting it to long.
5080 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
5081 match(Set dst (ConvI2L (LoadI mem)));
5082 predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5083 ins_cost(MEMORY_REF_COST);
5084
5085 format %{ "LWA $dst, $mem \t// loadI2L" %}
5086 size(4);
5087 ins_encode %{
5088 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5089 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5090 %}
5091 ins_pipe(pipe_class_memory);
5092 %}
5093
5094 // Match loading integer and casting it to long - acquire.
5095 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
5096 match(Set dst (ConvI2L (LoadI mem)));
5097 ins_cost(3*MEMORY_REF_COST);
5098
5099 format %{ "LWA $dst, $mem \t// loadI2L acquire"
5100 "TWI $dst\n\t"
5101 "ISYNC" %}
5102 size(12);
5103 ins_encode %{
5104 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5105 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5106 __ twi_0($dst$$Register);
5107 __ isync();
5108 %}
5109 ins_pipe(pipe_class_memory);
5110 %}
5111
5112 // Load Long - aligned
5113 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{
5114 match(Set dst (LoadL mem));
5115 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5116 ins_cost(MEMORY_REF_COST);
5117
5118 format %{ "LD $dst, $mem \t// long" %}
5119 size(4);
5120 ins_encode( enc_ld(dst, mem) );
5121 ins_pipe(pipe_class_memory);
5122 %}
5123
5124 // Load Long - aligned acquire.
5125 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{
5126 match(Set dst (LoadL mem));
5127 ins_cost(3*MEMORY_REF_COST);
5128
5129 format %{ "LD $dst, $mem \t// long acquire\n\t"
5130 "TWI $dst\n\t"
5131 "ISYNC" %}
5132 size(12);
5133 ins_encode( enc_ld_ac(dst, mem) );
5134 ins_pipe(pipe_class_memory);
5135 %}
5136
5137 // Load Long - UNaligned
5138 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{
5139 match(Set dst (LoadL_unaligned mem));
5140 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5141 ins_cost(MEMORY_REF_COST);
5142
5143 format %{ "LD $dst, $mem \t// unaligned long" %}
5144 size(4);
5145 ins_encode( enc_ld(dst, mem) );
5146 ins_pipe(pipe_class_memory);
5147 %}
5148
5149 // Load nodes for superwords
5150
5151 // Load Aligned Packed Byte
5152 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{
5153 predicate(n->as_LoadVector()->memory_size() == 8);
5154 match(Set dst (LoadVector mem));
5155 ins_cost(MEMORY_REF_COST);
5156
5157 format %{ "LD $dst, $mem \t// load 8-byte Vector" %}
5158 size(4);
5159 ins_encode( enc_ld(dst, mem) );
5160 ins_pipe(pipe_class_memory);
5161 %}
5162
5163
5164 instruct loadV16(vecX dst, memoryAlg16 mem) %{
5165 predicate(n->as_LoadVector()->memory_size() == 16);
5166 match(Set dst (LoadVector mem));
5167 ins_cost(MEMORY_REF_COST);
5168
5169 format %{ "LXV $dst, $mem \t// load 16-byte Vector" %}
5170 size(4);
5171 ins_encode %{
5172 __ lxv($dst$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
5173 %}
5174 ins_pipe(pipe_class_default);
5175 %}
5176
5177 // Load Range, range = array length (=jint)
5178 instruct loadRange(iRegIdst dst, memory mem) %{
5179 match(Set dst (LoadRange mem));
5180 ins_cost(MEMORY_REF_COST);
5181
5182 format %{ "LWZ $dst, $mem \t// range" %}
5183 size(4);
5184 ins_encode( enc_lwz(dst, mem) );
5185 ins_pipe(pipe_class_memory);
5186 %}
5187
5188 // Load Compressed Pointer
5189 instruct loadN(iRegNdst dst, memory mem) %{
5190 match(Set dst (LoadN mem));
5191 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5192 ins_cost(MEMORY_REF_COST);
5193
5194 format %{ "LWZ $dst, $mem \t// load compressed ptr" %}
5195 size(4);
5196 ins_encode( enc_lwz(dst, mem) );
5197 ins_pipe(pipe_class_memory);
5198 %}
5199
5200 // Load Compressed Pointer acquire.
5201 instruct loadN_ac(iRegNdst dst, memory mem) %{
5202 match(Set dst (LoadN mem));
5203 predicate(n->as_Load()->barrier_data() == 0);
5204 ins_cost(3*MEMORY_REF_COST);
5205
5206 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5207 "TWI $dst\n\t"
5208 "ISYNC" %}
5209 size(12);
5210 ins_encode( enc_lwz_ac(dst, mem) );
5211 ins_pipe(pipe_class_memory);
5212 %}
5213
5214 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5215 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5216 match(Set dst (DecodeN (LoadN mem)));
5217 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0 && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5218 ins_cost(MEMORY_REF_COST);
5219
5220 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5221 size(4);
5222 ins_encode( enc_lwz(dst, mem) );
5223 ins_pipe(pipe_class_memory);
5224 %}
5225
5226 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5227 match(Set dst (DecodeNKlass (LoadNKlass mem)));
5228 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0 &&
5229 _kids[0]->_leaf->as_Load()->is_unordered());
5230 ins_cost(MEMORY_REF_COST);
5231
5232 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5233 size(4);
5234 ins_encode( enc_lwz(dst, mem) );
5235 ins_pipe(pipe_class_memory);
5236 %}
5237
5238 // Load Pointer
5239 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5240 match(Set dst (LoadP mem));
5241 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5242 ins_cost(MEMORY_REF_COST);
5243
5244 format %{ "LD $dst, $mem \t// ptr" %}
5245 size(4);
5246 ins_encode( enc_ld(dst, mem) );
5247 ins_pipe(pipe_class_memory);
5248 %}
5249
5250 // Load Pointer acquire.
5251 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5252 match(Set dst (LoadP mem));
5253 ins_cost(3*MEMORY_REF_COST);
5254
5255 predicate(n->as_Load()->barrier_data() == 0);
5256
5257 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5258 "TWI $dst\n\t"
5259 "ISYNC" %}
5260 size(12);
5261 ins_encode( enc_ld_ac(dst, mem) );
5262 ins_pipe(pipe_class_memory);
5263 %}
5264
5265 // LoadP + CastP2L
5266 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
5267 match(Set dst (CastP2X (LoadP mem)));
5268 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5269 ins_cost(MEMORY_REF_COST);
5270
5271 format %{ "LD $dst, $mem \t// ptr + p2x" %}
5272 size(4);
5273 ins_encode( enc_ld(dst, mem) );
5274 ins_pipe(pipe_class_memory);
5275 %}
5276
5277 // Load compressed klass pointer.
5278 instruct loadNKlass(iRegNdst dst, memory mem) %{
5279 match(Set dst (LoadNKlass mem));
5280 predicate(!UseCompactObjectHeaders);
5281 ins_cost(MEMORY_REF_COST);
5282
5283 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %}
5284 size(4);
5285 ins_encode( enc_lwz(dst, mem) );
5286 ins_pipe(pipe_class_memory);
5287 %}
5288
5289 instruct loadNKlassCompactHeaders(iRegNdst dst, memory mem) %{
5290 match(Set dst (LoadNKlass mem));
5291 predicate(UseCompactObjectHeaders);
5292 ins_cost(MEMORY_REF_COST);
5293
5294 format %{ "load_narrow_klass_compact $dst, $mem \t// compressed class ptr" %}
5295 size(8);
5296 ins_encode %{
5297 assert($mem$$index$$Register == R0, "must not have indexed address: %s[%s]", $mem$$base$$Register.name(), $mem$$index$$Register.name());
5298 __ load_narrow_klass_compact_c2($dst$$Register, $mem$$base$$Register, $mem$$disp);
5299 %}
5300 ins_pipe(pipe_class_memory);
5301 %}
5302
5303 // Load Klass Pointer
5304 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
5305 match(Set dst (LoadKlass mem));
5306 ins_cost(MEMORY_REF_COST);
5307
5308 format %{ "LD $dst, $mem \t// klass ptr" %}
5309 size(4);
5310 ins_encode( enc_ld(dst, mem) );
5311 ins_pipe(pipe_class_memory);
5312 %}
5313
5314 // Load Float
5315 instruct loadF(regF dst, memory mem) %{
5316 match(Set dst (LoadF mem));
5317 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5318 ins_cost(MEMORY_REF_COST);
5319
5320 format %{ "LFS $dst, $mem" %}
5321 size(4);
5322 ins_encode %{
5323 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5324 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5325 %}
5326 ins_pipe(pipe_class_memory);
5327 %}
5328
5329 // Load Float acquire.
5330 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5331 match(Set dst (LoadF mem));
5332 effect(TEMP cr0);
5333 ins_cost(3*MEMORY_REF_COST);
5334
5335 format %{ "LFS $dst, $mem \t// acquire\n\t"
5336 "FCMPU cr0, $dst, $dst\n\t"
5337 "BNE cr0, next\n"
5338 "next:\n\t"
5339 "ISYNC" %}
5340 size(16);
5341 ins_encode %{
5342 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5343 Label next;
5344 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5345 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5346 __ bne(CR0, next);
5347 __ bind(next);
5348 __ isync();
5349 %}
5350 ins_pipe(pipe_class_memory);
5351 %}
5352
5353 // Load Double - aligned
5354 instruct loadD(regD dst, memory mem) %{
5355 match(Set dst (LoadD mem));
5356 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5357 ins_cost(MEMORY_REF_COST);
5358
5359 format %{ "LFD $dst, $mem" %}
5360 size(4);
5361 ins_encode( enc_lfd(dst, mem) );
5362 ins_pipe(pipe_class_memory);
5363 %}
5364
5365 // Load Double - aligned acquire.
5366 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5367 match(Set dst (LoadD mem));
5368 effect(TEMP cr0);
5369 ins_cost(3*MEMORY_REF_COST);
5370
5371 format %{ "LFD $dst, $mem \t// acquire\n\t"
5372 "FCMPU cr0, $dst, $dst\n\t"
5373 "BNE cr0, next\n"
5374 "next:\n\t"
5375 "ISYNC" %}
5376 size(16);
5377 ins_encode %{
5378 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5379 Label next;
5380 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5381 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5382 __ bne(CR0, next);
5383 __ bind(next);
5384 __ isync();
5385 %}
5386 ins_pipe(pipe_class_memory);
5387 %}
5388
5389 // Load Double - UNaligned
5390 instruct loadD_unaligned(regD dst, memory mem) %{
5391 match(Set dst (LoadD_unaligned mem));
5392 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5393 ins_cost(MEMORY_REF_COST);
5394
5395 format %{ "LFD $dst, $mem" %}
5396 size(4);
5397 ins_encode( enc_lfd(dst, mem) );
5398 ins_pipe(pipe_class_memory);
5399 %}
5400
5401 //----------Constants--------------------------------------------------------
5402
5403 // Load MachConstantTableBase: add hi offset to global toc.
5404 // TODO: Handle hidden register r29 in bundler!
5405 instruct loadToc_hi(iRegLdst dst) %{
5406 effect(DEF dst);
5407 ins_cost(DEFAULT_COST);
5408
5409 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %}
5410 size(4);
5411 ins_encode %{
5412 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
5413 %}
5414 ins_pipe(pipe_class_default);
5415 %}
5416
5417 // Load MachConstantTableBase: add lo offset to global toc.
5418 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
5419 effect(DEF dst, USE src);
5420 ins_cost(DEFAULT_COST);
5421
5422 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %}
5423 size(4);
5424 ins_encode %{
5425 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
5426 %}
5427 ins_pipe(pipe_class_default);
5428 %}
5429
5430 // Load 16-bit integer constant 0xssss????
5431 instruct loadConI16(iRegIdst dst, immI16 src) %{
5432 match(Set dst src);
5433
5434 format %{ "LI $dst, $src" %}
5435 size(4);
5436 ins_encode %{
5437 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5438 %}
5439 ins_pipe(pipe_class_default);
5440 %}
5441
5442 // Load integer constant 0x????0000
5443 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
5444 match(Set dst src);
5445 ins_cost(DEFAULT_COST);
5446
5447 format %{ "LIS $dst, $src.hi" %}
5448 size(4);
5449 ins_encode %{
5450 // Lis sign extends 16-bit src then shifts it 16 bit to the left.
5451 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5452 %}
5453 ins_pipe(pipe_class_default);
5454 %}
5455
5456 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted
5457 // and sign extended), this adds the low 16 bits.
5458 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
5459 // no match-rule, false predicate
5460 effect(DEF dst, USE src1, USE src2);
5461 predicate(false);
5462
5463 format %{ "ORI $dst, $src1.hi, $src2.lo" %}
5464 size(4);
5465 ins_encode %{
5466 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5467 %}
5468 ins_pipe(pipe_class_default);
5469 %}
5470
5471 instruct loadConI32(iRegIdst dst, immI32 src) %{
5472 match(Set dst src);
5473 // This macro is valid only in Power 10 and up, but adding the following predicate here
5474 // caused a build error, so we comment it out for now.
5475 // predicate(PowerArchitecturePPC64 >= 10);
5476 ins_cost(DEFAULT_COST+1);
5477
5478 format %{ "PLI $dst, $src" %}
5479 size(8);
5480 ins_encode %{
5481 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5482 __ pli($dst$$Register, $src$$constant);
5483 %}
5484 ins_pipe(pipe_class_default);
5485 ins_alignment(2);
5486 %}
5487
5488 instruct loadConI_Ex(iRegIdst dst, immI src) %{
5489 match(Set dst src);
5490 ins_cost(DEFAULT_COST*2);
5491
5492 expand %{
5493 // Would like to use $src$$constant.
5494 immI16 srcLo %{ _opnds[1]->constant() %}
5495 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5496 immIhi16 srcHi %{ _opnds[1]->constant() %}
5497 iRegIdst tmpI;
5498 loadConIhi16(tmpI, srcHi);
5499 loadConI32_lo16(dst, tmpI, srcLo);
5500 %}
5501 %}
5502
5503 // No constant pool entries required.
5504 instruct loadConL16(iRegLdst dst, immL16 src) %{
5505 match(Set dst src);
5506
5507 format %{ "LI $dst, $src \t// long" %}
5508 size(4);
5509 ins_encode %{
5510 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
5511 %}
5512 ins_pipe(pipe_class_default);
5513 %}
5514
5515 // Load long constant 0xssssssss????0000
5516 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
5517 match(Set dst src);
5518 ins_cost(DEFAULT_COST);
5519
5520 format %{ "LIS $dst, $src.hi \t// long" %}
5521 size(4);
5522 ins_encode %{
5523 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5524 %}
5525 ins_pipe(pipe_class_default);
5526 %}
5527
5528 // To load a 32 bit constant: merge lower 16 bits into already loaded
5529 // high 16 bits.
5530 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
5531 // no match-rule, false predicate
5532 effect(DEF dst, USE src1, USE src2);
5533 predicate(false);
5534
5535 format %{ "ORI $dst, $src1, $src2.lo" %}
5536 size(4);
5537 ins_encode %{
5538 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5539 %}
5540 ins_pipe(pipe_class_default);
5541 %}
5542
5543 // Load 32-bit long constant
5544 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{
5545 match(Set dst src);
5546 ins_cost(DEFAULT_COST*2);
5547
5548 expand %{
5549 // Would like to use $src$$constant.
5550 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%}
5551 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5552 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%}
5553 iRegLdst tmpL;
5554 loadConL32hi16(tmpL, srcHi);
5555 loadConL32_lo16(dst, tmpL, srcLo);
5556 %}
5557 %}
5558
5559 // Load 34-bit long constant using prefixed addi. No constant pool entries required.
5560 instruct loadConL34(iRegLdst dst, immL34 src) %{
5561 match(Set dst src);
5562 // This macro is valid only in Power 10 and up, but adding the following predicate here
5563 // caused a build error, so we comment it out for now.
5564 // predicate(PowerArchitecturePPC64 >= 10);
5565 ins_cost(DEFAULT_COST+1);
5566
5567 format %{ "PLI $dst, $src \t// long" %}
5568 size(8);
5569 ins_encode %{
5570 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5571 __ pli($dst$$Register, $src$$constant);
5572 %}
5573 ins_pipe(pipe_class_default);
5574 ins_alignment(2);
5575 %}
5576
5577 // Load long constant 0x????000000000000.
5578 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{
5579 match(Set dst src);
5580 ins_cost(DEFAULT_COST);
5581
5582 expand %{
5583 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%}
5584 immI shift32 %{ 32 %}
5585 iRegLdst tmpL;
5586 loadConL32hi16(tmpL, srcHi);
5587 lshiftL_regL_immI(dst, tmpL, shift32);
5588 %}
5589 %}
5590
5591 // Expand node for constant pool load: small offset.
5592 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{
5593 effect(DEF dst, USE src, USE toc);
5594 ins_cost(MEMORY_REF_COST);
5595
5596 ins_num_consts(1);
5597 // Needed so that CallDynamicJavaDirect can compute the address of this
5598 // instruction for relocation.
5599 ins_field_cbuf_insts_offset(int);
5600
5601 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %}
5602 size(4);
5603 ins_encode( enc_load_long_constL(dst, src, toc) );
5604 ins_pipe(pipe_class_memory);
5605 %}
5606
5607 // Expand node for constant pool load: large offset.
5608 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{
5609 effect(DEF dst, USE src, USE toc);
5610 predicate(false);
5611
5612 ins_num_consts(1);
5613 ins_field_const_toc_offset(int);
5614 // Needed so that CallDynamicJavaDirect can compute the address of this
5615 // instruction for relocation.
5616 ins_field_cbuf_insts_offset(int);
5617
5618 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %}
5619 size(4);
5620 ins_encode( enc_load_long_constL_hi(dst, toc, src) );
5621 ins_pipe(pipe_class_default);
5622 %}
5623
5624 // Expand node for constant pool load: large offset.
5625 // No constant pool entries required.
5626 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
5627 effect(DEF dst, USE src, USE base);
5628 predicate(false);
5629
5630 ins_field_const_toc_offset_hi_node(loadConL_hiNode*);
5631
5632 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %}
5633 size(4);
5634 ins_encode %{
5635 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5636 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5637 %}
5638 ins_pipe(pipe_class_memory);
5639 %}
5640
5641 // Load long constant from constant table. Expand in case of
5642 // offset > 16 bit is needed.
5643 // Adlc adds toc node MachConstantTableBase.
5644 instruct loadConL_Ex(iRegLdst dst, immL src) %{
5645 match(Set dst src);
5646 ins_cost(MEMORY_REF_COST);
5647
5648 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %}
5649 // We can not inline the enc_class for the expand as that does not support constanttablebase.
5650 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) );
5651 %}
5652
5653 // Load nullptr as compressed oop.
5654 instruct loadConN0(iRegNdst dst, immN_0 src) %{
5655 match(Set dst src);
5656 ins_cost(DEFAULT_COST);
5657
5658 format %{ "LI $dst, $src \t// compressed ptr" %}
5659 size(4);
5660 ins_encode %{
5661 __ li($dst$$Register, 0);
5662 %}
5663 ins_pipe(pipe_class_default);
5664 %}
5665
5666 // Load hi part of compressed oop constant.
5667 instruct loadConN_hi(iRegNdst dst, immN src) %{
5668 effect(DEF dst, USE src);
5669 ins_cost(DEFAULT_COST);
5670
5671 format %{ "LIS $dst, $src \t// narrow oop hi" %}
5672 size(4);
5673 ins_encode %{
5674 __ lis($dst$$Register, 0); // Will get patched.
5675 %}
5676 ins_pipe(pipe_class_default);
5677 %}
5678
5679 // Add lo part of compressed oop constant to already loaded hi part.
5680 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
5681 effect(DEF dst, USE src1, USE src2);
5682 ins_cost(DEFAULT_COST);
5683
5684 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %}
5685 size(4);
5686 ins_encode %{
5687 AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant);
5688 __ relocate(addrlit.rspec(), /*compressed format*/ 1);
5689 __ ori($dst$$Register, $src1$$Register, 0); // Will get patched.
5690 %}
5691 ins_pipe(pipe_class_default);
5692 %}
5693
5694 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
5695 effect(DEF dst, USE src, USE shift, USE mask_begin);
5696
5697 size(4);
5698 ins_encode %{
5699 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
5700 %}
5701 ins_pipe(pipe_class_default);
5702 %}
5703
5704 // Needed to postalloc expand loadConN: ConN is loaded as ConI
5705 // leaving the upper 32 bits with sign-extension bits.
5706 // This clears these bits: dst = src & 0xFFFFFFFF.
5707 // TODO: Eventually call this maskN_regN_FFFFFFFF.
5708 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
5709 effect(DEF dst, USE src);
5710 predicate(false);
5711
5712 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
5713 size(4);
5714 ins_encode %{
5715 __ clrldi($dst$$Register, $src$$Register, 0x20);
5716 %}
5717 ins_pipe(pipe_class_default);
5718 %}
5719
5720 // Optimize DecodeN for disjoint base.
5721 // Load base of compressed oops into a register
5722 instruct loadBase(iRegLdst dst) %{
5723 effect(DEF dst);
5724
5725 format %{ "LoadConst $dst, heapbase" %}
5726 ins_encode %{
5727 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0);
5728 %}
5729 ins_pipe(pipe_class_default);
5730 %}
5731
5732 // Loading ConN must be postalloc expanded so that edges between
5733 // the nodes are safe. They may not interfere with a safepoint.
5734 // GL TODO: This needs three instructions: better put this into the constant pool.
5735 instruct loadConN_Ex(iRegNdst dst, immN src) %{
5736 match(Set dst src);
5737 ins_cost(DEFAULT_COST*2);
5738
5739 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5740 postalloc_expand %{
5741 MachNode *m1 = new loadConN_hiNode();
5742 MachNode *m2 = new loadConN_loNode();
5743 MachNode *m3 = new clearMs32bNode();
5744 m1->_bottom_type = bottom_type();
5745 m2->_bottom_type = bottom_type();
5746 m3->_bottom_type = bottom_type();
5747 m1->add_req(nullptr);
5748 m2->add_req(nullptr, m1);
5749 m3->add_req(nullptr, m2);
5750 m1->_opnds[0] = op_dst;
5751 m1->_opnds[1] = op_src;
5752 m2->_opnds[0] = op_dst;
5753 m2->_opnds[1] = op_dst;
5754 m2->_opnds[2] = op_src;
5755 m3->_opnds[0] = op_dst;
5756 m3->_opnds[1] = op_dst;
5757 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5758 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5759 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5760 nodes->push(m1);
5761 nodes->push(m2);
5762 nodes->push(m3);
5763 %}
5764 %}
5765
5766 // We have seen a safepoint between the hi and lo parts, and this node was handled
5767 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is
5768 // not a narrow oop.
5769 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
5770 match(Set dst src);
5771 effect(DEF dst, USE src);
5772 ins_cost(DEFAULT_COST);
5773
5774 format %{ "LIS $dst, $src \t// narrow klass hi" %}
5775 size(4);
5776 ins_encode %{
5777 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant);
5778 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
5779 %}
5780 ins_pipe(pipe_class_default);
5781 %}
5782
5783 // As loadConNKlass_hi this must be recognized as narrow klass, not oop!
5784 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5785 match(Set dst src1);
5786 effect(TEMP src2);
5787 ins_cost(DEFAULT_COST);
5788
5789 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
5790 size(4);
5791 ins_encode %{
5792 __ clrldi($dst$$Register, $src2$$Register, 0x20);
5793 %}
5794 ins_pipe(pipe_class_default);
5795 %}
5796
5797 // This needs a match rule so that build_oop_map knows this is
5798 // not a narrow oop.
5799 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5800 match(Set dst src1);
5801 effect(TEMP src2);
5802 ins_cost(DEFAULT_COST);
5803
5804 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
5805 size(4);
5806 ins_encode %{
5807 // Notify OOP recorder (don't need the relocation)
5808 AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant);
5809 intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value());
5810 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
5811 %}
5812 ins_pipe(pipe_class_default);
5813 %}
5814
5815 // Loading ConNKlass must be postalloc expanded so that edges between
5816 // the nodes are safe. They may not interfere with a safepoint.
5817 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
5818 match(Set dst src);
5819 ins_cost(DEFAULT_COST*2);
5820
5821 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5822 postalloc_expand %{
5823 // Load high bits into register. Sign extended.
5824 MachNode *m1 = new loadConNKlass_hiNode();
5825 m1->_bottom_type = bottom_type();
5826 m1->add_req(nullptr);
5827 m1->_opnds[0] = op_dst;
5828 m1->_opnds[1] = op_src;
5829 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5830 nodes->push(m1);
5831
5832 MachNode *m2 = m1;
5833 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) {
5834 // Value might be 1-extended. Mask out these bits.
5835 m2 = new loadConNKlass_maskNode();
5836 m2->_bottom_type = bottom_type();
5837 m2->add_req(nullptr, m1);
5838 m2->_opnds[0] = op_dst;
5839 m2->_opnds[1] = op_src;
5840 m2->_opnds[2] = op_dst;
5841 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5842 nodes->push(m2);
5843 }
5844
5845 MachNode *m3 = new loadConNKlass_loNode();
5846 m3->_bottom_type = bottom_type();
5847 m3->add_req(nullptr, m2);
5848 m3->_opnds[0] = op_dst;
5849 m3->_opnds[1] = op_src;
5850 m3->_opnds[2] = op_dst;
5851 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5852 nodes->push(m3);
5853 %}
5854 %}
5855
5856 // 0x1 is used in object initialization (initial object header).
5857 // No constant pool entries required.
5858 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
5859 match(Set dst src);
5860
5861 format %{ "LI $dst, $src \t// ptr" %}
5862 size(4);
5863 ins_encode %{
5864 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5865 %}
5866 ins_pipe(pipe_class_default);
5867 %}
5868
5869 // Expand node for constant pool load: small offset.
5870 // The match rule is needed to generate the correct bottom_type(),
5871 // however this node should never match. The use of predicate is not
5872 // possible since ADLC forbids predicates for chain rules. The higher
5873 // costs do not prevent matching in this case. For that reason the
5874 // operand immP_NM with predicate(false) is used.
5875 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{
5876 match(Set dst src);
5877 effect(TEMP toc);
5878
5879 ins_num_consts(1);
5880
5881 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %}
5882 size(4);
5883 ins_encode( enc_load_long_constP(dst, src, toc) );
5884 ins_pipe(pipe_class_memory);
5885 %}
5886
5887 // Expand node for constant pool load: large offset.
5888 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{
5889 effect(DEF dst, USE src, USE toc);
5890 predicate(false);
5891
5892 ins_num_consts(1);
5893 ins_field_const_toc_offset(int);
5894
5895 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %}
5896 size(4);
5897 ins_encode( enc_load_long_constP_hi(dst, src, toc) );
5898 ins_pipe(pipe_class_default);
5899 %}
5900
5901 // Expand node for constant pool load: large offset.
5902 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
5903 match(Set dst src);
5904 effect(TEMP base);
5905
5906 ins_field_const_toc_offset_hi_node(loadConP_hiNode*);
5907
5908 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
5909 size(4);
5910 ins_encode %{
5911 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5912 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5913 %}
5914 ins_pipe(pipe_class_memory);
5915 %}
5916
5917 // Load pointer constant from constant table. Expand in case an
5918 // offset > 16 bit is needed.
5919 // Adlc adds toc node MachConstantTableBase.
5920 instruct loadConP_Ex(iRegPdst dst, immP src) %{
5921 match(Set dst src);
5922 ins_cost(MEMORY_REF_COST);
5923
5924 // This rule does not use "expand" because then
5925 // the result type is not known to be an Oop. An ADLC
5926 // enhancement will be needed to make that work - not worth it!
5927
5928 // If this instruction rematerializes, it prolongs the live range
5929 // of the toc node, causing illegal graphs.
5930 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule().
5931 ins_cannot_rematerialize(true);
5932
5933 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %}
5934 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) );
5935 %}
5936
5937 // Expand node for constant pool load: small offset.
5938 instruct loadConF(regF dst, immF src, iRegLdst toc) %{
5939 effect(DEF dst, USE src, USE toc);
5940 ins_cost(MEMORY_REF_COST);
5941
5942 ins_num_consts(1);
5943
5944 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %}
5945 size(4);
5946 ins_encode %{
5947 address float_address = __ float_constant($src$$constant);
5948 if (float_address == nullptr) {
5949 ciEnv::current()->record_out_of_memory_failure();
5950 return;
5951 }
5952 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register);
5953 %}
5954 ins_pipe(pipe_class_memory);
5955 %}
5956
5957 // Expand node for constant pool load: large offset.
5958 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
5959 effect(DEF dst, USE src, USE toc);
5960 ins_cost(MEMORY_REF_COST);
5961
5962 ins_num_consts(1);
5963
5964 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
5965 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t"
5966 "ADDIS $toc, $toc, -offset_hi"%}
5967 size(12);
5968 ins_encode %{
5969 FloatRegister Rdst = $dst$$FloatRegister;
5970 Register Rtoc = $toc$$Register;
5971 address float_address = __ float_constant($src$$constant);
5972 if (float_address == nullptr) {
5973 ciEnv::current()->record_out_of_memory_failure();
5974 return;
5975 }
5976 int offset = __ offset_to_method_toc(float_address);
5977 int hi = (offset + (1<<15))>>16;
5978 int lo = offset - hi * (1<<16);
5979
5980 __ addis(Rtoc, Rtoc, hi);
5981 __ lfs(Rdst, lo, Rtoc);
5982 __ addis(Rtoc, Rtoc, -hi);
5983 %}
5984 ins_pipe(pipe_class_memory);
5985 %}
5986
5987 // Adlc adds toc node MachConstantTableBase.
5988 instruct loadConF_Ex(regF dst, immF src) %{
5989 match(Set dst src);
5990 ins_cost(MEMORY_REF_COST);
5991
5992 // See loadConP.
5993 ins_cannot_rematerialize(true);
5994
5995 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
5996 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) );
5997 %}
5998
5999 // Expand node for constant pool load: small offset.
6000 instruct loadConD(regD dst, immD src, iRegLdst toc) %{
6001 effect(DEF dst, USE src, USE toc);
6002 ins_cost(MEMORY_REF_COST);
6003
6004 ins_num_consts(1);
6005
6006 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %}
6007 size(4);
6008 ins_encode %{
6009 address float_address = __ double_constant($src$$constant);
6010 if (float_address == nullptr) {
6011 ciEnv::current()->record_out_of_memory_failure();
6012 return;
6013 }
6014 int offset = __ offset_to_method_toc(float_address);
6015 __ lfd($dst$$FloatRegister, offset, $toc$$Register);
6016 %}
6017 ins_pipe(pipe_class_memory);
6018 %}
6019
6020 // Expand node for constant pool load: large offset.
6021 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
6022 effect(DEF dst, USE src, USE toc);
6023 ins_cost(MEMORY_REF_COST);
6024
6025 ins_num_consts(1);
6026
6027 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6028 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t"
6029 "ADDIS $toc, $toc, -offset_hi" %}
6030 size(12);
6031 ins_encode %{
6032 FloatRegister Rdst = $dst$$FloatRegister;
6033 Register Rtoc = $toc$$Register;
6034 address float_address = __ double_constant($src$$constant);
6035 if (float_address == nullptr) {
6036 ciEnv::current()->record_out_of_memory_failure();
6037 return;
6038 }
6039 int offset = __ offset_to_method_toc(float_address);
6040 int hi = (offset + (1<<15))>>16;
6041 int lo = offset - hi * (1<<16);
6042
6043 __ addis(Rtoc, Rtoc, hi);
6044 __ lfd(Rdst, lo, Rtoc);
6045 __ addis(Rtoc, Rtoc, -hi);
6046 %}
6047 ins_pipe(pipe_class_memory);
6048 %}
6049
6050 // Adlc adds toc node MachConstantTableBase.
6051 instruct loadConD_Ex(regD dst, immD src) %{
6052 match(Set dst src);
6053 ins_cost(MEMORY_REF_COST);
6054
6055 // See loadConP.
6056 ins_cannot_rematerialize(true);
6057
6058 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6059 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) );
6060 %}
6061
6062 // Prefetch instructions.
6063 // Must be safe to execute with invalid address (cannot fault).
6064
6065 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
6066 match(PrefetchAllocation (AddP mem src));
6067 ins_cost(MEMORY_REF_COST);
6068
6069 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
6070 size(4);
6071 ins_encode %{
6072 __ dcbtst($src$$Register, $mem$$base$$Register);
6073 %}
6074 ins_pipe(pipe_class_memory);
6075 %}
6076
6077 instruct prefetch_alloc_no_offset(indirectMemory mem) %{
6078 match(PrefetchAllocation mem);
6079 ins_cost(MEMORY_REF_COST);
6080
6081 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
6082 size(4);
6083 ins_encode %{
6084 __ dcbtst($mem$$base$$Register);
6085 %}
6086 ins_pipe(pipe_class_memory);
6087 %}
6088
6089 //----------Store Instructions-------------------------------------------------
6090
6091 // Store Byte
6092 instruct storeB(memory mem, iRegIsrc src) %{
6093 match(Set mem (StoreB mem src));
6094 ins_cost(MEMORY_REF_COST);
6095
6096 format %{ "STB $src, $mem \t// byte" %}
6097 size(4);
6098 ins_encode %{
6099 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6100 __ stb($src$$Register, Idisp, $mem$$base$$Register);
6101 %}
6102 ins_pipe(pipe_class_memory);
6103 %}
6104
6105 // Store Char/Short
6106 instruct storeC(memory mem, iRegIsrc src) %{
6107 match(Set mem (StoreC mem src));
6108 ins_cost(MEMORY_REF_COST);
6109
6110 format %{ "STH $src, $mem \t// short" %}
6111 size(4);
6112 ins_encode %{
6113 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6114 __ sth($src$$Register, Idisp, $mem$$base$$Register);
6115 %}
6116 ins_pipe(pipe_class_memory);
6117 %}
6118
6119 // Store Integer
6120 instruct storeI(memory mem, iRegIsrc src) %{
6121 match(Set mem (StoreI mem src));
6122 ins_cost(MEMORY_REF_COST);
6123
6124 format %{ "STW $src, $mem" %}
6125 size(4);
6126 ins_encode( enc_stw(src, mem) );
6127 ins_pipe(pipe_class_memory);
6128 %}
6129
6130 // ConvL2I + StoreI.
6131 instruct storeI_convL2I(memory mem, iRegLsrc src) %{
6132 match(Set mem (StoreI mem (ConvL2I src)));
6133 ins_cost(MEMORY_REF_COST);
6134
6135 format %{ "STW l2i($src), $mem" %}
6136 size(4);
6137 ins_encode( enc_stw(src, mem) );
6138 ins_pipe(pipe_class_memory);
6139 %}
6140
6141 // Store Long
6142 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{
6143 match(Set mem (StoreL mem src));
6144 ins_cost(MEMORY_REF_COST);
6145
6146 format %{ "STD $src, $mem \t// long" %}
6147 size(4);
6148 ins_encode( enc_std(src, mem) );
6149 ins_pipe(pipe_class_memory);
6150 %}
6151
6152 // Store super word nodes.
6153
6154 // Store Aligned Packed Byte long register to memory
6155 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{
6156 predicate(n->as_StoreVector()->memory_size() == 8);
6157 match(Set mem (StoreVector mem src));
6158 ins_cost(MEMORY_REF_COST);
6159
6160 format %{ "STD $mem, $src \t// packed8B" %}
6161 size(4);
6162 ins_encode( enc_std(src, mem) );
6163 ins_pipe(pipe_class_memory);
6164 %}
6165
6166
6167 instruct storeV16(memoryAlg16 mem, vecX src) %{
6168 predicate(n->as_StoreVector()->memory_size() == 16);
6169 match(Set mem (StoreVector mem src));
6170 ins_cost(MEMORY_REF_COST);
6171
6172 format %{ "STXV $mem, $src \t// store 16-byte Vector" %}
6173 size(4);
6174 ins_encode %{
6175 __ stxv($src$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
6176 %}
6177 ins_pipe(pipe_class_default);
6178 %}
6179
6180 // Reinterpret: only one vector size used: either L or X
6181 instruct reinterpretL(iRegLdst dst) %{
6182 match(Set dst (VectorReinterpret dst));
6183 ins_cost(0);
6184 format %{ "reinterpret $dst" %}
6185 size(0);
6186 ins_encode( /*empty*/ );
6187 ins_pipe(pipe_class_empty);
6188 %}
6189
6190 instruct reinterpretX(vecX dst) %{
6191 match(Set dst (VectorReinterpret dst));
6192 ins_cost(0);
6193 format %{ "reinterpret $dst" %}
6194 size(0);
6195 ins_encode( /*empty*/ );
6196 ins_pipe(pipe_class_empty);
6197 %}
6198
6199 // Store Compressed Oop
6200 instruct storeN(memory dst, iRegN_P2N src) %{
6201 match(Set dst (StoreN dst src));
6202 predicate(n->as_Store()->barrier_data() == 0);
6203 ins_cost(MEMORY_REF_COST);
6204
6205 format %{ "STW $src, $dst \t// compressed oop" %}
6206 size(4);
6207 ins_encode( enc_stw(src, dst) );
6208 ins_pipe(pipe_class_memory);
6209 %}
6210
6211 // Store Compressed KLass
6212 instruct storeNKlass(memory dst, iRegN_P2N src) %{
6213 match(Set dst (StoreNKlass dst src));
6214 ins_cost(MEMORY_REF_COST);
6215
6216 format %{ "STW $src, $dst \t// compressed klass" %}
6217 size(4);
6218 ins_encode( enc_stw(src, dst) );
6219 ins_pipe(pipe_class_memory);
6220 %}
6221
6222 // Store Pointer
6223 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{
6224 match(Set dst (StoreP dst src));
6225 predicate(n->as_Store()->barrier_data() == 0);
6226 ins_cost(MEMORY_REF_COST);
6227
6228 format %{ "STD $src, $dst \t// ptr" %}
6229 size(4);
6230 ins_encode( enc_std(src, dst) );
6231 ins_pipe(pipe_class_memory);
6232 %}
6233
6234 // Store Float
6235 instruct storeF(memory mem, regF src) %{
6236 match(Set mem (StoreF mem src));
6237 ins_cost(MEMORY_REF_COST);
6238
6239 format %{ "STFS $src, $mem" %}
6240 size(4);
6241 ins_encode( enc_stfs(src, mem) );
6242 ins_pipe(pipe_class_memory);
6243 %}
6244
6245 // Store Double
6246 instruct storeD(memory mem, regD src) %{
6247 match(Set mem (StoreD mem src));
6248 ins_cost(MEMORY_REF_COST);
6249
6250 format %{ "STFD $src, $mem" %}
6251 size(4);
6252 ins_encode( enc_stfd(src, mem) );
6253 ins_pipe(pipe_class_memory);
6254 %}
6255
6256 // Convert oop pointer into compressed form.
6257
6258 // Nodes for postalloc expand.
6259
6260 // Shift node for expand.
6261 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
6262 // The match rule is needed to make it a 'MachTypeNode'!
6263 match(Set dst (EncodeP src));
6264 predicate(false);
6265
6266 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6267 size(4);
6268 ins_encode %{
6269 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6270 %}
6271 ins_pipe(pipe_class_default);
6272 %}
6273
6274 // Add node for expand.
6275 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6276 // The match rule is needed to make it a 'MachTypeNode'!
6277 match(Set dst (EncodeP src));
6278 predicate(false);
6279
6280 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6281 ins_encode %{
6282 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6283 %}
6284 ins_pipe(pipe_class_default);
6285 %}
6286
6287 // Conditional sub base.
6288 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6289 // The match rule is needed to make it a 'MachTypeNode'!
6290 match(Set dst (EncodeP (Binary crx src1)));
6291 predicate(false);
6292
6293 format %{ "BEQ $crx, done\n\t"
6294 "SUB $dst, $src1, heapbase \t// encode: subtract base if != nullptr\n"
6295 "done:" %}
6296 ins_encode %{
6297 Label done;
6298 __ beq($crx$$CondRegister, done);
6299 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0);
6300 __ bind(done);
6301 %}
6302 ins_pipe(pipe_class_default);
6303 %}
6304
6305 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6306 // The match rule is needed to make it a 'MachTypeNode'!
6307 match(Set dst (EncodeP (Binary crx src1)));
6308 predicate(false);
6309
6310 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6311 size(4);
6312 ins_encode %{
6313 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6314 %}
6315 ins_pipe(pipe_class_default);
6316 %}
6317
6318 // Disjoint narrow oop base.
6319 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6320 match(Set dst (EncodeP src));
6321 predicate(CompressedOops::base_disjoint());
6322
6323 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6324 size(4);
6325 ins_encode %{
6326 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32);
6327 %}
6328 ins_pipe(pipe_class_default);
6329 %}
6330
6331 // shift != 0, base != 0
6332 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6333 match(Set dst (EncodeP src));
6334 effect(TEMP crx);
6335 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6336 CompressedOops::shift() != 0 &&
6337 CompressedOops::base_overlaps());
6338
6339 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6340 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6341 %}
6342
6343 // shift != 0, base != 0
6344 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6345 match(Set dst (EncodeP src));
6346 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6347 CompressedOops::shift() != 0 &&
6348 CompressedOops::base_overlaps());
6349
6350 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6351 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6352 %}
6353
6354 // shift != 0, base == 0
6355 // TODO: This is the same as encodeP_shift. Merge!
6356 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6357 match(Set dst (EncodeP src));
6358 predicate(CompressedOops::shift() != 0 &&
6359 CompressedOops::base() == nullptr);
6360
6361 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != nullptr" %}
6362 size(4);
6363 ins_encode %{
6364 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6365 %}
6366 ins_pipe(pipe_class_default);
6367 %}
6368
6369 // Compressed OOPs with narrow_oop_shift == 0.
6370 // shift == 0, base == 0
6371 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
6372 match(Set dst (EncodeP src));
6373 predicate(CompressedOops::shift() == 0);
6374
6375 format %{ "MR $dst, $src \t// Ptr->Narrow" %}
6376 // variable size, 0 or 4.
6377 ins_encode %{
6378 __ mr_if_needed($dst$$Register, $src$$Register);
6379 %}
6380 ins_pipe(pipe_class_default);
6381 %}
6382
6383 // Decode nodes.
6384
6385 // Shift node for expand.
6386 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6387 // The match rule is needed to make it a 'MachTypeNode'!
6388 match(Set dst (DecodeN src));
6389 predicate(false);
6390
6391 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6392 size(4);
6393 ins_encode %{
6394 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6395 %}
6396 ins_pipe(pipe_class_default);
6397 %}
6398
6399 // Add node for expand.
6400 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6401 // The match rule is needed to make it a 'MachTypeNode'!
6402 match(Set dst (DecodeN src));
6403 predicate(false);
6404
6405 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %}
6406 ins_encode %{
6407 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6408 %}
6409 ins_pipe(pipe_class_default);
6410 %}
6411
6412 // conditianal add base for expand
6413 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6414 // The match rule is needed to make it a 'MachTypeNode'!
6415 // NOTICE that the rule is nonsense - we just have to make sure that:
6416 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6417 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6418 match(Set dst (DecodeN (Binary crx src)));
6419 predicate(false);
6420
6421 format %{ "BEQ $crx, done\n\t"
6422 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != nullptr\n"
6423 "done:" %}
6424 ins_encode %{
6425 Label done;
6426 __ beq($crx$$CondRegister, done);
6427 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6428 __ bind(done);
6429 %}
6430 ins_pipe(pipe_class_default);
6431 %}
6432
6433 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6434 // The match rule is needed to make it a 'MachTypeNode'!
6435 // NOTICE that the rule is nonsense - we just have to make sure that:
6436 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6437 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6438 match(Set dst (DecodeN (Binary crx src1)));
6439 predicate(false);
6440
6441 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6442 size(4);
6443 ins_encode %{
6444 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6445 %}
6446 ins_pipe(pipe_class_default);
6447 %}
6448
6449 // shift != 0, base != 0
6450 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6451 match(Set dst (DecodeN src));
6452 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6453 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6454 CompressedOops::shift() != 0 &&
6455 CompressedOops::base() != nullptr);
6456 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6457 effect(TEMP crx);
6458
6459 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6460 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6461 %}
6462
6463 // shift != 0, base == 0
6464 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6465 match(Set dst (DecodeN src));
6466 predicate(CompressedOops::shift() != 0 &&
6467 CompressedOops::base() == nullptr);
6468
6469 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %}
6470 size(4);
6471 ins_encode %{
6472 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6473 %}
6474 ins_pipe(pipe_class_default);
6475 %}
6476
6477 // Optimize DecodeN for disjoint base.
6478 // Shift narrow oop and or it into register that already contains the heap base.
6479 // Base == dst must hold, and is assured by construction in postaloc_expand.
6480 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6481 match(Set dst (DecodeN src));
6482 effect(TEMP base);
6483 predicate(false);
6484
6485 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6486 size(4);
6487 ins_encode %{
6488 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift());
6489 %}
6490 ins_pipe(pipe_class_default);
6491 %}
6492
6493 // Optimize DecodeN for disjoint base.
6494 // This node requires only one cycle on the critical path.
6495 // We must postalloc_expand as we can not express use_def effects where
6496 // the used register is L and the def'ed register P.
6497 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6498 match(Set dst (DecodeN src));
6499 effect(TEMP_DEF dst);
6500 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6501 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6502 CompressedOops::base_disjoint());
6503 ins_cost(DEFAULT_COST);
6504
6505 format %{ "MOV $dst, heapbase \t\n"
6506 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6507 postalloc_expand %{
6508 loadBaseNode *n1 = new loadBaseNode();
6509 n1->add_req(nullptr);
6510 n1->_opnds[0] = op_dst;
6511
6512 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6513 n2->add_req(n_region, n_src, n1);
6514 n2->_opnds[0] = op_dst;
6515 n2->_opnds[1] = op_src;
6516 n2->_opnds[2] = op_dst;
6517 n2->_bottom_type = _bottom_type;
6518
6519 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6520 ra_->set_oop(n2, true);
6521
6522 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6523 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6524
6525 nodes->push(n1);
6526 nodes->push(n2);
6527 %}
6528 %}
6529
6530 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6531 match(Set dst (DecodeN src));
6532 effect(TEMP_DEF dst, TEMP crx);
6533 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6534 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6535 CompressedOops::base_disjoint());
6536 ins_cost(3 * DEFAULT_COST);
6537
6538 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %}
6539 postalloc_expand %{
6540 loadBaseNode *n1 = new loadBaseNode();
6541 n1->add_req(nullptr);
6542 n1->_opnds[0] = op_dst;
6543
6544 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
6545 n_compare->add_req(n_region, n_src);
6546 n_compare->_opnds[0] = op_crx;
6547 n_compare->_opnds[1] = op_src;
6548 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6549
6550 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6551 n2->add_req(n_region, n_src, n1);
6552 n2->_opnds[0] = op_dst;
6553 n2->_opnds[1] = op_src;
6554 n2->_opnds[2] = op_dst;
6555 n2->_bottom_type = _bottom_type;
6556
6557 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6558 n_cond_set->add_req(n_region, n_compare, n2);
6559 n_cond_set->_opnds[0] = op_dst;
6560 n_cond_set->_opnds[1] = op_crx;
6561 n_cond_set->_opnds[2] = op_dst;
6562 n_cond_set->_bottom_type = _bottom_type;
6563
6564 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6565 ra_->set_oop(n_cond_set, true);
6566
6567 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6568 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
6569 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6570 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6571
6572 nodes->push(n1);
6573 nodes->push(n_compare);
6574 nodes->push(n2);
6575 nodes->push(n_cond_set);
6576 %}
6577 %}
6578
6579 // src != 0, shift != 0, base != 0
6580 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6581 match(Set dst (DecodeN src));
6582 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6583 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6584 CompressedOops::shift() != 0 &&
6585 CompressedOops::base() != nullptr);
6586 ins_cost(2 * DEFAULT_COST);
6587
6588 format %{ "DecodeN $dst, $src \t// $src != nullptr, postalloc expanded" %}
6589 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6590 %}
6591
6592 // Compressed OOPs with narrow_oop_shift == 0.
6593 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6594 match(Set dst (DecodeN src));
6595 predicate(CompressedOops::shift() == 0);
6596 ins_cost(DEFAULT_COST);
6597
6598 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %}
6599 // variable size, 0 or 4.
6600 ins_encode %{
6601 __ mr_if_needed($dst$$Register, $src$$Register);
6602 %}
6603 ins_pipe(pipe_class_default);
6604 %}
6605
6606 // Convert compressed oop into int for vectors alignment masking.
6607 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
6608 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6609 predicate(CompressedOops::shift() == 0);
6610 ins_cost(DEFAULT_COST);
6611
6612 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %}
6613 // variable size, 0 or 4.
6614 ins_encode %{
6615 __ mr_if_needed($dst$$Register, $src$$Register);
6616 %}
6617 ins_pipe(pipe_class_default);
6618 %}
6619
6620 // Convert klass pointer into compressed form.
6621
6622 // Nodes for postalloc expand.
6623
6624 // Shift node for expand.
6625 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
6626 // The match rule is needed to make it a 'MachTypeNode'!
6627 match(Set dst (EncodePKlass src));
6628 predicate(false);
6629
6630 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6631 size(4);
6632 ins_encode %{
6633 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6634 %}
6635 ins_pipe(pipe_class_default);
6636 %}
6637
6638 // Add node for expand.
6639 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6640 // The match rule is needed to make it a 'MachTypeNode'!
6641 match(Set dst (EncodePKlass (Binary base src)));
6642 predicate(false);
6643
6644 format %{ "SUB $dst, $base, $src \t// encode" %}
6645 size(4);
6646 ins_encode %{
6647 __ subf($dst$$Register, $base$$Register, $src$$Register);
6648 %}
6649 ins_pipe(pipe_class_default);
6650 %}
6651
6652 // Disjoint narrow oop base.
6653 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
6654 match(Set dst (EncodePKlass src));
6655 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/);
6656
6657 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6658 size(4);
6659 ins_encode %{
6660 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
6661 %}
6662 ins_pipe(pipe_class_default);
6663 %}
6664
6665 // shift != 0, base != 0
6666 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6667 match(Set dst (EncodePKlass (Binary base src)));
6668 predicate(false);
6669
6670 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6671 postalloc_expand %{
6672 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
6673 n1->add_req(n_region, n_base, n_src);
6674 n1->_opnds[0] = op_dst;
6675 n1->_opnds[1] = op_base;
6676 n1->_opnds[2] = op_src;
6677 n1->_bottom_type = _bottom_type;
6678
6679 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode();
6680 n2->add_req(n_region, n1);
6681 n2->_opnds[0] = op_dst;
6682 n2->_opnds[1] = op_dst;
6683 n2->_bottom_type = _bottom_type;
6684 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6685 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6686
6687 nodes->push(n1);
6688 nodes->push(n2);
6689 %}
6690 %}
6691
6692 // shift != 0, base != 0
6693 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
6694 match(Set dst (EncodePKlass src));
6695 //predicate(CompressedKlassPointers::shift() != 0 &&
6696 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/);
6697
6698 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6699 ins_cost(DEFAULT_COST*2); // Don't count constant.
6700 expand %{
6701 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %}
6702 iRegLdst base;
6703 loadConL_Ex(base, baseImm);
6704 encodePKlass_not_null_Ex(dst, base, src);
6705 %}
6706 %}
6707
6708 // Decode nodes.
6709
6710 // Shift node for expand.
6711 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
6712 // The match rule is needed to make it a 'MachTypeNode'!
6713 match(Set dst (DecodeNKlass src));
6714 predicate(false);
6715
6716 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %}
6717 size(4);
6718 ins_encode %{
6719 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6720 %}
6721 ins_pipe(pipe_class_default);
6722 %}
6723
6724 // Add node for expand.
6725
6726 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6727 // The match rule is needed to make it a 'MachTypeNode'!
6728 match(Set dst (DecodeNKlass (Binary base src)));
6729 predicate(false);
6730
6731 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
6732 size(4);
6733 ins_encode %{
6734 __ add($dst$$Register, $base$$Register, $src$$Register);
6735 %}
6736 ins_pipe(pipe_class_default);
6737 %}
6738
6739 // src != 0, shift != 0, base != 0
6740 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
6741 match(Set dst (DecodeNKlass (Binary base src)));
6742 //effect(kill src); // We need a register for the immediate result after shifting.
6743 predicate(false);
6744
6745 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != nullptr, postalloc expanded" %}
6746 postalloc_expand %{
6747 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode();
6748 n1->add_req(n_region, n_base, n_src);
6749 n1->_opnds[0] = op_dst;
6750 n1->_opnds[1] = op_base;
6751 n1->_opnds[2] = op_src;
6752 n1->_bottom_type = _bottom_type;
6753
6754 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode();
6755 n2->add_req(n_region, n1);
6756 n2->_opnds[0] = op_dst;
6757 n2->_opnds[1] = op_dst;
6758 n2->_bottom_type = _bottom_type;
6759
6760 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6761 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6762
6763 nodes->push(n1);
6764 nodes->push(n2);
6765 %}
6766 %}
6767
6768 // src != 0, shift != 0, base != 0
6769 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
6770 match(Set dst (DecodeNKlass src));
6771 // predicate(CompressedKlassPointers::shift() != 0 &&
6772 // CompressedKlassPointers::base() != 0);
6773
6774 //format %{ "DecodeNKlass $dst, $src \t// $src != nullptr, expanded" %}
6775
6776 ins_cost(DEFAULT_COST*2); // Don't count constant.
6777 expand %{
6778 // We add first, then we shift. Like this, we can get along with one register less.
6779 // But we have to load the base pre-shifted.
6780 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %}
6781 iRegLdst base;
6782 loadConL_Ex(base, baseImm);
6783 decodeNKlass_notNull_addBase_Ex(dst, base, src);
6784 %}
6785 %}
6786
6787 //----------MemBar Instructions-----------------------------------------------
6788 // Memory barrier flavors
6789
6790 instruct membar_acquire() %{
6791 match(LoadFence);
6792 ins_cost(4*MEMORY_REF_COST);
6793
6794 format %{ "MEMBAR-acquire" %}
6795 size(4);
6796 ins_encode %{
6797 __ acquire();
6798 %}
6799 ins_pipe(pipe_class_default);
6800 %}
6801
6802 instruct unnecessary_membar_acquire() %{
6803 match(MemBarAcquire);
6804 ins_cost(0);
6805
6806 format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
6807 size(0);
6808 ins_encode( /*empty*/ );
6809 ins_pipe(pipe_class_default);
6810 %}
6811
6812 instruct membar_acquire_lock() %{
6813 match(MemBarAcquireLock);
6814 ins_cost(0);
6815
6816 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
6817 size(0);
6818 ins_encode( /*empty*/ );
6819 ins_pipe(pipe_class_default);
6820 %}
6821
6822 instruct membar_release() %{
6823 match(MemBarRelease);
6824 match(StoreFence);
6825 ins_cost(4*MEMORY_REF_COST);
6826
6827 format %{ "MEMBAR-release" %}
6828 size(4);
6829 ins_encode %{
6830 __ release();
6831 %}
6832 ins_pipe(pipe_class_default);
6833 %}
6834
6835 instruct membar_storestore() %{
6836 match(MemBarStoreStore);
6837 match(StoreStoreFence);
6838 ins_cost(4*MEMORY_REF_COST);
6839
6840 format %{ "MEMBAR-store-store" %}
6841 size(4);
6842 ins_encode %{
6843 __ membar(Assembler::StoreStore);
6844 %}
6845 ins_pipe(pipe_class_default);
6846 %}
6847
6848 instruct membar_release_lock() %{
6849 match(MemBarReleaseLock);
6850 ins_cost(0);
6851
6852 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
6853 size(0);
6854 ins_encode( /*empty*/ );
6855 ins_pipe(pipe_class_default);
6856 %}
6857
6858 instruct membar_storeload() %{
6859 match(MemBarStoreLoad);
6860 ins_cost(4*MEMORY_REF_COST);
6861
6862 format %{ "MEMBAR-store-load" %}
6863 size(4);
6864 ins_encode %{
6865 __ fence();
6866 %}
6867 ins_pipe(pipe_class_default);
6868 %}
6869
6870 instruct membar_volatile() %{
6871 match(MemBarVolatile);
6872 ins_cost(4*MEMORY_REF_COST);
6873
6874 format %{ "MEMBAR-volatile" %}
6875 size(4);
6876 ins_encode %{
6877 __ fence();
6878 %}
6879 ins_pipe(pipe_class_default);
6880 %}
6881
6882 // This optimization is wrong on PPC. The following pattern is not supported:
6883 // MemBarVolatile
6884 // ^ ^
6885 // | |
6886 // CtrlProj MemProj
6887 // ^ ^
6888 // | |
6889 // | Load
6890 // |
6891 // MemBarVolatile
6892 //
6893 // The first MemBarVolatile could get optimized out! According to
6894 // Vladimir, this pattern can not occur on Oracle platforms.
6895 // However, it does occur on PPC64 (because of membars in
6896 // inline_unsafe_load_store).
6897 //
6898 // Add this node again if we found a good solution for inline_unsafe_load_store().
6899 // Don't forget to look at the implementation of post_store_load_barrier again,
6900 // we did other fixes in that method.
6901 //instruct unnecessary_membar_volatile() %{
6902 // match(MemBarVolatile);
6903 // predicate(Matcher::post_store_load_barrier(n));
6904 // ins_cost(0);
6905 //
6906 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
6907 // size(0);
6908 // ins_encode( /*empty*/ );
6909 // ins_pipe(pipe_class_default);
6910 //%}
6911
6912 instruct membar_full() %{
6913 match(MemBarFull);
6914 ins_cost(4*MEMORY_REF_COST);
6915
6916 format %{ "MEMBAR-full" %}
6917 size(4);
6918 ins_encode %{
6919 __ fence();
6920 %}
6921 ins_pipe(pipe_class_default);
6922 %}
6923
6924 instruct membar_CPUOrder() %{
6925 match(MemBarCPUOrder);
6926 ins_cost(0);
6927
6928 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
6929 size(0);
6930 ins_encode( /*empty*/ );
6931 ins_pipe(pipe_class_default);
6932 %}
6933
6934 instruct onspinwait() %{
6935 match(OnSpinWait);
6936 ins_cost(DEFAULT_COST);
6937
6938 format %{ "OnSpinWait (smt_prio_low ; smt_prio_medium)" %}
6939 size(8);
6940 ins_encode %{
6941 __ block_comment("spin_wait {");
6942 __ smt_prio_low();
6943 __ smt_prio_medium();
6944 __ block_comment("}");
6945 %}
6946 ins_pipe(pipe_class_default);
6947 %}
6948
6949 //----------Conditional Move---------------------------------------------------
6950
6951 // Cmove using isel.
6952 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
6953 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
6954 ins_cost(DEFAULT_COST);
6955
6956 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6957 size(4);
6958 ins_encode %{
6959 int cc = $cmp$$cmpcode;
6960 __ isel($dst$$Register, $crx$$CondRegister,
6961 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6962 %}
6963 ins_pipe(pipe_class_default);
6964 %}
6965
6966 // Cmove using isel.
6967 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
6968 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
6969 ins_cost(DEFAULT_COST);
6970
6971 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6972 size(4);
6973 ins_encode %{
6974 int cc = $cmp$$cmpcode;
6975 __ isel($dst$$Register, $crx$$CondRegister,
6976 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6977 %}
6978 ins_pipe(pipe_class_default);
6979 %}
6980
6981 // Cmove using isel.
6982 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
6983 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
6984 ins_cost(DEFAULT_COST);
6985
6986 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6987 size(4);
6988 ins_encode %{
6989 int cc = $cmp$$cmpcode;
6990 __ isel($dst$$Register, $crx$$CondRegister,
6991 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6992 %}
6993 ins_pipe(pipe_class_default);
6994 %}
6995
6996 // Cmove using isel.
6997 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
6998 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
6999 ins_cost(DEFAULT_COST);
7000
7001 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7002 size(4);
7003 ins_encode %{
7004 int cc = $cmp$$cmpcode;
7005 __ isel($dst$$Register, $crx$$CondRegister,
7006 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7007 %}
7008 ins_pipe(pipe_class_default);
7009 %}
7010
7011 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
7012 match(Set dst (CMoveF (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 cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7031 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7032 ins_cost(DEFAULT_COST+BRANCH_COST);
7033
7034 ins_variable_size_depending_on_alignment(true);
7035
7036 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7037 size(8);
7038 ins_encode %{
7039 Label done;
7040 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7041 // Branch if not (cmp crx).
7042 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7043 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7044 __ bind(done);
7045 %}
7046 ins_pipe(pipe_class_default);
7047 %}
7048
7049 instruct cmovF_cmpF(cmpOp cop, regF op1, regF op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7050 match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7051 predicate(PowerArchitecturePPC64 >= 9);
7052 effect(TEMP tmp);
7053 ins_cost(2*DEFAULT_COST);
7054 format %{ "cmovF_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7055 size(8);
7056 ins_encode %{
7057 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7058 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7059 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7060 $tmp$$FloatRegister->to_vsr());
7061 %}
7062 ins_pipe(pipe_class_default);
7063 %}
7064
7065 instruct cmovF_cmpD(cmpOp cop, regD op1, regD op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7066 match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7067 predicate(PowerArchitecturePPC64 >= 9);
7068 effect(TEMP tmp);
7069 ins_cost(2*DEFAULT_COST);
7070 format %{ "cmovF_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7071 size(8);
7072 ins_encode %{
7073 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7074 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7075 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7076 $tmp$$FloatRegister->to_vsr());
7077 %}
7078 ins_pipe(pipe_class_default);
7079 %}
7080
7081 instruct cmovD_cmpD(cmpOp cop, regD op1, regD op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7082 match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7083 predicate(PowerArchitecturePPC64 >= 9);
7084 effect(TEMP tmp);
7085 ins_cost(2*DEFAULT_COST);
7086 format %{ "cmovD_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7087 size(8);
7088 ins_encode %{
7089 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7090 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7091 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7092 $tmp$$FloatRegister->to_vsr());
7093 %}
7094 ins_pipe(pipe_class_default);
7095 %}
7096
7097 instruct cmovD_cmpF(cmpOp cop, regF op1, regF op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7098 match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7099 predicate(PowerArchitecturePPC64 >= 9);
7100 effect(TEMP tmp);
7101 ins_cost(2*DEFAULT_COST);
7102 format %{ "cmovD_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7103 size(8);
7104 ins_encode %{
7105 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7106 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7107 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7108 $tmp$$FloatRegister->to_vsr());
7109 %}
7110 ins_pipe(pipe_class_default);
7111 %}
7112
7113 //----------Compare-And-Swap---------------------------------------------------
7114
7115 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7116 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7117 // matched.
7118
7119 // Strong versions:
7120
7121 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7122 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7123 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7124 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7125 ins_encode %{
7126 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7127 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7128 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7129 $res$$Register, nullptr, true);
7130 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7131 __ isync();
7132 } else {
7133 __ sync();
7134 }
7135 %}
7136 ins_pipe(pipe_class_default);
7137 %}
7138
7139 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7140 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7141 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7142 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7143 ins_encode %{
7144 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7145 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7146 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7147 $res$$Register, nullptr, true);
7148 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7149 __ isync();
7150 } else {
7151 __ sync();
7152 }
7153 %}
7154 ins_pipe(pipe_class_default);
7155 %}
7156
7157 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7158 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
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 compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7176 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7177 predicate(n->as_LoadStore()->barrier_data() == 0);
7178 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7179 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7180 ins_encode %{
7181 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7182 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7183 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7184 $res$$Register, nullptr, true);
7185 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7186 __ isync();
7187 } else {
7188 __ sync();
7189 }
7190 %}
7191 ins_pipe(pipe_class_default);
7192 %}
7193
7194 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7195 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7196 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7197 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
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 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7213 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7214 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7215 predicate(n->as_LoadStore()->barrier_data() == 0);
7216 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7217 ins_encode %{
7218 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7219 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7220 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7221 $res$$Register, nullptr, true);
7222 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7223 __ isync();
7224 } else {
7225 __ sync();
7226 }
7227 %}
7228 ins_pipe(pipe_class_default);
7229 %}
7230
7231 // Weak versions:
7232
7233 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7234 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7235 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7236 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7237 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7238 ins_encode %{
7239 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7240 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7241 MacroAssembler::MemBarNone,
7242 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7243 %}
7244 ins_pipe(pipe_class_default);
7245 %}
7246
7247 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7248 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7249 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) );
7250 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7251 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7252 ins_encode %{
7253 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7254 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7255 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7256 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7257 %}
7258 ins_pipe(pipe_class_default);
7259 %}
7260
7261 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7262 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7263 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7264 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7265 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7266 ins_encode %{
7267 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7268 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7269 MacroAssembler::MemBarNone,
7270 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7271 %}
7272 ins_pipe(pipe_class_default);
7273 %}
7274
7275 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7276 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7277 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7278 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7279 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7280 ins_encode %{
7281 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7282 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7283 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7284 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7285 %}
7286 ins_pipe(pipe_class_default);
7287 %}
7288
7289 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7290 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7291 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7292 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7293 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7294 ins_encode %{
7295 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7296 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7297 MacroAssembler::MemBarNone,
7298 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7299 %}
7300 ins_pipe(pipe_class_default);
7301 %}
7302
7303 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7304 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7305 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7306 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7307 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7308 ins_encode %{
7309 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7310 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7311 // value is never passed to caller.
7312 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7313 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7314 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7315 %}
7316 ins_pipe(pipe_class_default);
7317 %}
7318
7319 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7320 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7321 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7322 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7323 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7324 ins_encode %{
7325 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7326 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7327 MacroAssembler::MemBarNone,
7328 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7329 %}
7330 ins_pipe(pipe_class_default);
7331 %}
7332
7333 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7334 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7335 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7336 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7337 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7338 ins_encode %{
7339 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7340 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7341 // value is never passed to caller.
7342 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7343 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7344 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7345 %}
7346 ins_pipe(pipe_class_default);
7347 %}
7348
7349 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7350 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7351 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7352 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7353 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7354 ins_encode %{
7355 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7356 // value is never passed to caller.
7357 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7358 MacroAssembler::MemBarNone,
7359 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7360 %}
7361 ins_pipe(pipe_class_default);
7362 %}
7363
7364 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7365 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7366 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7367 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7368 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7369 ins_encode %{
7370 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7371 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7372 // value is never passed to caller.
7373 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7374 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7375 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7376 %}
7377 ins_pipe(pipe_class_default);
7378 %}
7379
7380 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7381 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7382 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7383 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7384 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7385 ins_encode %{
7386 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7387 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7388 MacroAssembler::MemBarNone,
7389 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7390 %}
7391 ins_pipe(pipe_class_default);
7392 %}
7393
7394 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7395 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7396 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7397 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7398 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7399 ins_encode %{
7400 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7401 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7402 // value is never passed to caller.
7403 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7404 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7405 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7406 %}
7407 ins_pipe(pipe_class_default);
7408 %}
7409
7410 // CompareAndExchange
7411
7412 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7413 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7414 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7415 effect(TEMP_DEF res, TEMP cr0);
7416 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7417 ins_encode %{
7418 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7419 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7420 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7421 noreg, nullptr, true);
7422 %}
7423 ins_pipe(pipe_class_default);
7424 %}
7425
7426 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7427 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7428 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7429 effect(TEMP_DEF res, TEMP cr0);
7430 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7431 ins_encode %{
7432 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7433 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7434 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7435 noreg, nullptr, true);
7436 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7437 __ isync();
7438 } else {
7439 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7440 __ sync();
7441 }
7442 %}
7443 ins_pipe(pipe_class_default);
7444 %}
7445
7446
7447 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7448 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7449 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7450 effect(TEMP_DEF res, TEMP cr0);
7451 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7452 ins_encode %{
7453 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7454 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7455 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7456 noreg, nullptr, true);
7457 %}
7458 ins_pipe(pipe_class_default);
7459 %}
7460
7461 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7462 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7463 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7464 effect(TEMP_DEF res, TEMP cr0);
7465 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7466 ins_encode %{
7467 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7468 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7469 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7470 noreg, nullptr, true);
7471 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7472 __ isync();
7473 } else {
7474 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7475 __ sync();
7476 }
7477 %}
7478 ins_pipe(pipe_class_default);
7479 %}
7480
7481 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7482 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7483 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7484 effect(TEMP_DEF res, TEMP cr0);
7485 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
7486 ins_encode %{
7487 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7488 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7489 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7490 noreg, nullptr, true);
7491 %}
7492 ins_pipe(pipe_class_default);
7493 %}
7494
7495 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7496 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7497 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7498 effect(TEMP_DEF res, TEMP cr0);
7499 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
7500 ins_encode %{
7501 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7502 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7503 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7504 noreg, nullptr, true);
7505 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7506 __ isync();
7507 } else {
7508 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7509 __ sync();
7510 }
7511 %}
7512 ins_pipe(pipe_class_default);
7513 %}
7514
7515 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7516 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7517 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7518 effect(TEMP_DEF res, TEMP cr0);
7519 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7520 ins_encode %{
7521 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7522 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7523 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7524 noreg, nullptr, true);
7525 %}
7526 ins_pipe(pipe_class_default);
7527 %}
7528
7529 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7530 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7531 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7532 effect(TEMP_DEF res, TEMP cr0);
7533 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7534 ins_encode %{
7535 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7536 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7537 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7538 noreg, nullptr, true);
7539 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7540 __ isync();
7541 } else {
7542 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7543 __ sync();
7544 }
7545 %}
7546 ins_pipe(pipe_class_default);
7547 %}
7548
7549 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7550 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7551 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7552 effect(TEMP_DEF res, TEMP cr0);
7553 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
7554 ins_encode %{
7555 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7556 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7557 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7558 noreg, nullptr, true);
7559 %}
7560 ins_pipe(pipe_class_default);
7561 %}
7562
7563 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7564 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7565 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7566 effect(TEMP_DEF res, TEMP cr0);
7567 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
7568 ins_encode %{
7569 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7570 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7571 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7572 noreg, nullptr, true);
7573 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7574 __ isync();
7575 } else {
7576 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7577 __ sync();
7578 }
7579 %}
7580 ins_pipe(pipe_class_default);
7581 %}
7582
7583 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7584 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7585 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst)
7586 && n->as_LoadStore()->barrier_data() == 0);
7587 effect(TEMP_DEF res, TEMP cr0);
7588 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7589 ins_encode %{
7590 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7591 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7592 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7593 noreg, nullptr, true);
7594 %}
7595 ins_pipe(pipe_class_default);
7596 %}
7597
7598 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7599 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7600 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst)
7601 && n->as_LoadStore()->barrier_data() == 0);
7602 effect(TEMP_DEF res, TEMP cr0);
7603 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7604 ins_encode %{
7605 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7606 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7607 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7608 noreg, nullptr, true);
7609 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7610 __ isync();
7611 } else {
7612 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7613 __ sync();
7614 }
7615 %}
7616 ins_pipe(pipe_class_default);
7617 %}
7618
7619 // Special RMW
7620
7621 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7622 match(Set res (GetAndAddB mem_ptr src));
7623 effect(TEMP_DEF res, TEMP cr0);
7624 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
7625 ins_encode %{
7626 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
7627 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7628 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7629 __ isync();
7630 } else {
7631 __ sync();
7632 }
7633 %}
7634 ins_pipe(pipe_class_default);
7635 %}
7636
7637 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7638 match(Set res (GetAndAddS mem_ptr src));
7639 effect(TEMP_DEF res, TEMP cr0);
7640 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
7641 ins_encode %{
7642 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
7643 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7644 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7645 __ isync();
7646 } else {
7647 __ sync();
7648 }
7649 %}
7650 ins_pipe(pipe_class_default);
7651 %}
7652
7653
7654 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7655 match(Set res (GetAndAddI mem_ptr src));
7656 effect(TEMP_DEF res, TEMP cr0);
7657 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
7658 ins_encode %{
7659 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
7660 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7661 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7662 __ isync();
7663 } else {
7664 __ sync();
7665 }
7666 %}
7667 ins_pipe(pipe_class_default);
7668 %}
7669
7670 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7671 match(Set res (GetAndAddL mem_ptr src));
7672 effect(TEMP_DEF res, TEMP cr0);
7673 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
7674 ins_encode %{
7675 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
7676 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7677 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7678 __ isync();
7679 } else {
7680 __ sync();
7681 }
7682 %}
7683 ins_pipe(pipe_class_default);
7684 %}
7685
7686 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7687 match(Set res (GetAndSetB mem_ptr src));
7688 effect(TEMP_DEF res, TEMP cr0);
7689 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
7690 ins_encode %{
7691 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
7692 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7693 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7694 __ isync();
7695 } else {
7696 __ sync();
7697 }
7698 %}
7699 ins_pipe(pipe_class_default);
7700 %}
7701
7702 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7703 match(Set res (GetAndSetS mem_ptr src));
7704 effect(TEMP_DEF res, TEMP cr0);
7705 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
7706 ins_encode %{
7707 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
7708 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7709 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7710 __ isync();
7711 } else {
7712 __ sync();
7713 }
7714 %}
7715 ins_pipe(pipe_class_default);
7716 %}
7717
7718
7719 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7720 match(Set res (GetAndSetI mem_ptr src));
7721 effect(TEMP_DEF res, TEMP cr0);
7722 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
7723 ins_encode %{
7724 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7725 MacroAssembler::cmpxchgx_hint_atomic_update());
7726 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7727 __ isync();
7728 } else {
7729 __ sync();
7730 }
7731 %}
7732 ins_pipe(pipe_class_default);
7733 %}
7734
7735 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7736 match(Set res (GetAndSetL mem_ptr src));
7737 effect(TEMP_DEF res, TEMP cr0);
7738 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
7739 ins_encode %{
7740 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7741 MacroAssembler::cmpxchgx_hint_atomic_update());
7742 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7743 __ isync();
7744 } else {
7745 __ sync();
7746 }
7747 %}
7748 ins_pipe(pipe_class_default);
7749 %}
7750
7751 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
7752 match(Set res (GetAndSetP mem_ptr src));
7753 predicate(n->as_LoadStore()->barrier_data() == 0);
7754 effect(TEMP_DEF res, TEMP cr0);
7755 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
7756 ins_encode %{
7757 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7758 MacroAssembler::cmpxchgx_hint_atomic_update());
7759 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7760 __ isync();
7761 } else {
7762 __ sync();
7763 }
7764 %}
7765 ins_pipe(pipe_class_default);
7766 %}
7767
7768 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
7769 match(Set res (GetAndSetN mem_ptr src));
7770 predicate(n->as_LoadStore()->barrier_data() == 0);
7771 effect(TEMP_DEF res, TEMP cr0);
7772 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
7773 ins_encode %{
7774 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7775 MacroAssembler::cmpxchgx_hint_atomic_update());
7776 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7777 __ isync();
7778 } else {
7779 __ sync();
7780 }
7781 %}
7782 ins_pipe(pipe_class_default);
7783 %}
7784
7785 //----------Arithmetic Instructions--------------------------------------------
7786 // Addition Instructions
7787
7788 // Register Addition
7789 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
7790 match(Set dst (AddI src1 src2));
7791 format %{ "ADD $dst, $src1, $src2" %}
7792 size(4);
7793 ins_encode %{
7794 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7795 %}
7796 ins_pipe(pipe_class_default);
7797 %}
7798
7799 // Expand does not work with above instruct. (??)
7800 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7801 // no match-rule
7802 effect(DEF dst, USE src1, USE src2);
7803 format %{ "ADD $dst, $src1, $src2" %}
7804 size(4);
7805 ins_encode %{
7806 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7807 %}
7808 ins_pipe(pipe_class_default);
7809 %}
7810
7811 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
7812 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
7813 ins_cost(DEFAULT_COST*3);
7814
7815 expand %{
7816 // FIXME: we should do this in the ideal world.
7817 iRegIdst tmp1;
7818 iRegIdst tmp2;
7819 addI_reg_reg(tmp1, src1, src2);
7820 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
7821 addI_reg_reg(dst, tmp1, tmp2);
7822 %}
7823 %}
7824
7825 // Immediate Addition
7826 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
7827 match(Set dst (AddI src1 src2));
7828 format %{ "ADDI $dst, $src1, $src2" %}
7829 size(4);
7830 ins_encode %{
7831 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7832 %}
7833 ins_pipe(pipe_class_default);
7834 %}
7835
7836 // Immediate Addition with 16-bit shifted operand
7837 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
7838 match(Set dst (AddI src1 src2));
7839 format %{ "ADDIS $dst, $src1, $src2" %}
7840 size(4);
7841 ins_encode %{
7842 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7843 %}
7844 ins_pipe(pipe_class_default);
7845 %}
7846
7847 // Immediate Addition using prefixed addi
7848 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{
7849 match(Set dst (AddI src1 src2));
7850 predicate(PowerArchitecturePPC64 >= 10);
7851 ins_cost(DEFAULT_COST+1);
7852 format %{ "PADDI $dst, $src1, $src2" %}
7853 size(8);
7854 ins_encode %{
7855 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7856 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7857 %}
7858 ins_pipe(pipe_class_default);
7859 ins_alignment(2);
7860 %}
7861
7862 // Long Addition
7863 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7864 match(Set dst (AddL src1 src2));
7865 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7866 size(4);
7867 ins_encode %{
7868 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7869 %}
7870 ins_pipe(pipe_class_default);
7871 %}
7872
7873 // Expand does not work with above instruct. (??)
7874 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7875 // no match-rule
7876 effect(DEF dst, USE src1, USE src2);
7877 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7878 size(4);
7879 ins_encode %{
7880 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7881 %}
7882 ins_pipe(pipe_class_default);
7883 %}
7884
7885 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
7886 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
7887 ins_cost(DEFAULT_COST*3);
7888
7889 expand %{
7890 // FIXME: we should do this in the ideal world.
7891 iRegLdst tmp1;
7892 iRegLdst tmp2;
7893 addL_reg_reg(tmp1, src1, src2);
7894 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
7895 addL_reg_reg(dst, tmp1, tmp2);
7896 %}
7897 %}
7898
7899 // AddL + ConvL2I.
7900 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
7901 match(Set dst (ConvL2I (AddL src1 src2)));
7902
7903 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %}
7904 size(4);
7905 ins_encode %{
7906 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7907 %}
7908 ins_pipe(pipe_class_default);
7909 %}
7910
7911 // No constant pool entries required.
7912 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
7913 match(Set dst (AddL src1 src2));
7914
7915 format %{ "ADDI $dst, $src1, $src2" %}
7916 size(4);
7917 ins_encode %{
7918 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7919 %}
7920 ins_pipe(pipe_class_default);
7921 %}
7922
7923 // Long Immediate Addition with 16-bit shifted operand.
7924 // No constant pool entries required.
7925 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
7926 match(Set dst (AddL src1 src2));
7927
7928 format %{ "ADDIS $dst, $src1, $src2" %}
7929 size(4);
7930 ins_encode %{
7931 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7932 %}
7933 ins_pipe(pipe_class_default);
7934 %}
7935
7936 // Long Immediate Addition using prefixed addi
7937 // No constant pool entries required.
7938 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{
7939 match(Set dst (AddL src1 src2));
7940 predicate(PowerArchitecturePPC64 >= 10);
7941 ins_cost(DEFAULT_COST+1);
7942
7943 format %{ "PADDI $dst, $src1, $src2" %}
7944 size(8);
7945 ins_encode %{
7946 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7947 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7948 %}
7949 ins_pipe(pipe_class_default);
7950 ins_alignment(2);
7951 %}
7952
7953 // Pointer Register Addition
7954 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
7955 match(Set dst (AddP src1 src2));
7956 format %{ "ADD $dst, $src1, $src2" %}
7957 size(4);
7958 ins_encode %{
7959 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7960 %}
7961 ins_pipe(pipe_class_default);
7962 %}
7963
7964 // Pointer Immediate Addition
7965 // No constant pool entries required.
7966 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
7967 match(Set dst (AddP src1 src2));
7968
7969 format %{ "ADDI $dst, $src1, $src2" %}
7970 size(4);
7971 ins_encode %{
7972 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7973 %}
7974 ins_pipe(pipe_class_default);
7975 %}
7976
7977 // Pointer Immediate Addition with 16-bit shifted operand.
7978 // No constant pool entries required.
7979 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
7980 match(Set dst (AddP src1 src2));
7981
7982 format %{ "ADDIS $dst, $src1, $src2" %}
7983 size(4);
7984 ins_encode %{
7985 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7986 %}
7987 ins_pipe(pipe_class_default);
7988 %}
7989
7990 // Pointer Immediate Addition using prefixed addi
7991 // No constant pool entries required.
7992 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{
7993 match(Set dst (AddP src1 src2));
7994 predicate(PowerArchitecturePPC64 >= 10);
7995 ins_cost(DEFAULT_COST+1);
7996
7997 format %{ "PADDI $dst, $src1, $src2" %}
7998 size(8);
7999 ins_encode %{
8000 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8001 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8002 %}
8003 ins_pipe(pipe_class_default);
8004 ins_alignment(2);
8005 %}
8006
8007 //---------------------
8008 // Subtraction Instructions
8009
8010 // Register Subtraction
8011 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8012 match(Set dst (SubI src1 src2));
8013 format %{ "SUBF $dst, $src2, $src1" %}
8014 size(4);
8015 ins_encode %{
8016 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8017 %}
8018 ins_pipe(pipe_class_default);
8019 %}
8020
8021 // Immediate Subtraction
8022 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
8023 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
8024
8025 // SubI from constant (using subfic).
8026 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
8027 match(Set dst (SubI src1 src2));
8028 format %{ "SUBI $dst, $src1, $src2" %}
8029
8030 size(4);
8031 ins_encode %{
8032 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
8033 %}
8034 ins_pipe(pipe_class_default);
8035 %}
8036
8037 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
8038 // positive integers and 0xF...F for negative ones.
8039 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
8040 // no match-rule, false predicate
8041 effect(DEF dst, USE src);
8042 predicate(false);
8043
8044 format %{ "SRAWI $dst, $src, #31" %}
8045 size(4);
8046 ins_encode %{
8047 __ srawi($dst$$Register, $src$$Register, 0x1f);
8048 %}
8049 ins_pipe(pipe_class_default);
8050 %}
8051
8052 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
8053 match(Set dst (AbsI src));
8054 ins_cost(DEFAULT_COST*3);
8055
8056 expand %{
8057 iRegIdst tmp1;
8058 iRegIdst tmp2;
8059 signmask32I_regI(tmp1, src);
8060 xorI_reg_reg(tmp2, tmp1, src);
8061 subI_reg_reg(dst, tmp2, tmp1);
8062 %}
8063 %}
8064
8065 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
8066 match(Set dst (SubI zero src2));
8067 format %{ "NEG $dst, $src2" %}
8068 size(4);
8069 ins_encode %{
8070 __ neg($dst$$Register, $src2$$Register);
8071 %}
8072 ins_pipe(pipe_class_default);
8073 %}
8074
8075 // Long subtraction
8076 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8077 match(Set dst (SubL src1 src2));
8078 format %{ "SUBF $dst, $src2, $src1 \t// long" %}
8079 size(4);
8080 ins_encode %{
8081 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8082 %}
8083 ins_pipe(pipe_class_default);
8084 %}
8085
8086 // SubL + convL2I.
8087 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8088 match(Set dst (ConvL2I (SubL src1 src2)));
8089
8090 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
8091 size(4);
8092 ins_encode %{
8093 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8094 %}
8095 ins_pipe(pipe_class_default);
8096 %}
8097
8098 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8099 // positive longs and 0xF...F for negative ones.
8100 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8101 // no match-rule, false predicate
8102 effect(DEF dst, USE src);
8103 predicate(false);
8104
8105 format %{ "SRADI $dst, $src, #63" %}
8106 size(4);
8107 ins_encode %{
8108 __ sradi($dst$$Register, $src$$Register, 0x3f);
8109 %}
8110 ins_pipe(pipe_class_default);
8111 %}
8112
8113 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8114 // positive longs and 0xF...F for negative ones.
8115 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8116 // no match-rule, false predicate
8117 effect(DEF dst, USE src);
8118 predicate(false);
8119
8120 format %{ "SRADI $dst, $src, #63" %}
8121 size(4);
8122 ins_encode %{
8123 __ sradi($dst$$Register, $src$$Register, 0x3f);
8124 %}
8125 ins_pipe(pipe_class_default);
8126 %}
8127
8128 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{
8129 match(Set dst (AbsL src));
8130 ins_cost(DEFAULT_COST*3);
8131
8132 expand %{
8133 iRegLdst tmp1;
8134 iRegLdst tmp2;
8135 signmask64L_regL(tmp1, src);
8136 xorL_reg_reg(tmp2, tmp1, src);
8137 subL_reg_reg(dst, tmp2, tmp1);
8138 %}
8139 %}
8140
8141 // Long negation
8142 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8143 match(Set dst (SubL zero src2));
8144 format %{ "NEG $dst, $src2 \t// long" %}
8145 size(4);
8146 ins_encode %{
8147 __ neg($dst$$Register, $src2$$Register);
8148 %}
8149 ins_pipe(pipe_class_default);
8150 %}
8151
8152 // NegL + ConvL2I.
8153 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8154 match(Set dst (ConvL2I (SubL zero src2)));
8155
8156 format %{ "NEG $dst, $src2 \t// long + l2i" %}
8157 size(4);
8158 ins_encode %{
8159 __ neg($dst$$Register, $src2$$Register);
8160 %}
8161 ins_pipe(pipe_class_default);
8162 %}
8163
8164 // Multiplication Instructions
8165 // Integer Multiplication
8166
8167 // Register Multiplication
8168 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8169 match(Set dst (MulI src1 src2));
8170 ins_cost(DEFAULT_COST);
8171
8172 format %{ "MULLW $dst, $src1, $src2" %}
8173 size(4);
8174 ins_encode %{
8175 __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8176 %}
8177 ins_pipe(pipe_class_default);
8178 %}
8179
8180 // Immediate Multiplication
8181 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8182 match(Set dst (MulI src1 src2));
8183 ins_cost(DEFAULT_COST);
8184
8185 format %{ "MULLI $dst, $src1, $src2" %}
8186 size(4);
8187 ins_encode %{
8188 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8189 %}
8190 ins_pipe(pipe_class_default);
8191 %}
8192
8193 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8194 match(Set dst (MulL src1 src2));
8195 ins_cost(DEFAULT_COST);
8196
8197 format %{ "MULLD $dst $src1, $src2 \t// long" %}
8198 size(4);
8199 ins_encode %{
8200 __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8201 %}
8202 ins_pipe(pipe_class_default);
8203 %}
8204
8205 // Multiply high for optimized long division by constant.
8206 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8207 match(Set dst (MulHiL src1 src2));
8208 ins_cost(DEFAULT_COST);
8209
8210 format %{ "MULHD $dst $src1, $src2 \t// long" %}
8211 size(4);
8212 ins_encode %{
8213 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8214 %}
8215 ins_pipe(pipe_class_default);
8216 %}
8217
8218 instruct uMulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8219 match(Set dst (UMulHiL src1 src2));
8220 ins_cost(DEFAULT_COST);
8221
8222 format %{ "MULHDU $dst $src1, $src2 \t// unsigned long" %}
8223 size(4);
8224 ins_encode %{
8225 __ mulhdu($dst$$Register, $src1$$Register, $src2$$Register);
8226 %}
8227 ins_pipe(pipe_class_default);
8228 %}
8229
8230 // Immediate Multiplication
8231 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8232 match(Set dst (MulL src1 src2));
8233 ins_cost(DEFAULT_COST);
8234
8235 format %{ "MULLI $dst, $src1, $src2" %}
8236 size(4);
8237 ins_encode %{
8238 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8239 %}
8240 ins_pipe(pipe_class_default);
8241 %}
8242
8243 // Integer Division with Immediate -1: Negate.
8244 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8245 match(Set dst (DivI src1 src2));
8246 ins_cost(DEFAULT_COST);
8247
8248 format %{ "NEG $dst, $src1 \t// /-1" %}
8249 size(4);
8250 ins_encode %{
8251 __ neg($dst$$Register, $src1$$Register);
8252 %}
8253 ins_pipe(pipe_class_default);
8254 %}
8255
8256 // Integer Division with constant, but not -1.
8257 // We should be able to improve this by checking the type of src2.
8258 // It might well be that src2 is known to be positive.
8259 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8260 match(Set dst (DivI src1 src2));
8261 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8262 ins_cost(2*DEFAULT_COST);
8263
8264 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8265 size(4);
8266 ins_encode %{
8267 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8268 %}
8269 ins_pipe(pipe_class_default);
8270 %}
8271
8272 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8273 effect(USE_DEF dst, USE src1, USE crx);
8274 predicate(false);
8275
8276 ins_variable_size_depending_on_alignment(true);
8277
8278 format %{ "CMOVE $dst, neg($src1), $crx" %}
8279 size(8);
8280 ins_encode %{
8281 Label done;
8282 __ bne($crx$$CondRegister, done);
8283 __ neg($dst$$Register, $src1$$Register);
8284 __ bind(done);
8285 %}
8286 ins_pipe(pipe_class_default);
8287 %}
8288
8289 // Integer Division with Registers not containing constants.
8290 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8291 match(Set dst (DivI src1 src2));
8292 ins_cost(10*DEFAULT_COST);
8293
8294 expand %{
8295 immI16 imm %{ (int)-1 %}
8296 flagsReg tmp1;
8297 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8298 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8299 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8300 %}
8301 %}
8302
8303 // Long Division with Immediate -1: Negate.
8304 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8305 match(Set dst (DivL src1 src2));
8306 ins_cost(DEFAULT_COST);
8307
8308 format %{ "NEG $dst, $src1 \t// /-1, long" %}
8309 size(4);
8310 ins_encode %{
8311 __ neg($dst$$Register, $src1$$Register);
8312 %}
8313 ins_pipe(pipe_class_default);
8314 %}
8315
8316 // Long Division with constant, but not -1.
8317 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8318 match(Set dst (DivL src1 src2));
8319 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8320 ins_cost(2*DEFAULT_COST);
8321
8322 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8323 size(4);
8324 ins_encode %{
8325 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8326 %}
8327 ins_pipe(pipe_class_default);
8328 %}
8329
8330 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8331 effect(USE_DEF dst, USE src1, USE crx);
8332 predicate(false);
8333
8334 ins_variable_size_depending_on_alignment(true);
8335
8336 format %{ "CMOVE $dst, neg($src1), $crx" %}
8337 size(8);
8338 ins_encode %{
8339 Label done;
8340 __ bne($crx$$CondRegister, done);
8341 __ neg($dst$$Register, $src1$$Register);
8342 __ bind(done);
8343 %}
8344 ins_pipe(pipe_class_default);
8345 %}
8346
8347 // Long Division with Registers not containing constants.
8348 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8349 match(Set dst (DivL src1 src2));
8350 ins_cost(10*DEFAULT_COST);
8351
8352 expand %{
8353 immL16 imm %{ (int)-1 %}
8354 flagsReg tmp1;
8355 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8356 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8357 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8358 %}
8359 %}
8360
8361 // Integer Remainder with registers.
8362 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8363 match(Set dst (ModI src1 src2));
8364 ins_cost(10*DEFAULT_COST);
8365
8366 expand %{
8367 immI16 imm %{ (int)-1 %}
8368 flagsReg tmp1;
8369 iRegIdst tmp2;
8370 iRegIdst tmp3;
8371 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8372 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8373 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8374 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8375 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8376 %}
8377 %}
8378
8379 // Long Remainder with registers
8380 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8381 match(Set dst (ModL src1 src2));
8382 ins_cost(10*DEFAULT_COST);
8383
8384 expand %{
8385 immL16 imm %{ (int)-1 %}
8386 flagsReg tmp1;
8387 iRegLdst tmp2;
8388 iRegLdst tmp3;
8389 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8390 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8391 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8392 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8393 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8394 %}
8395 %}
8396
8397 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8398 match(Set dst (UDivI src1 src2));
8399 format %{ "DIVWU $dst, $src1, $src2" %}
8400 size(4);
8401 ins_encode %{
8402 __ divwu($dst$$Register, $src1$$Register, $src2$$Register);
8403 %}
8404 ins_pipe(pipe_class_default);
8405 %}
8406
8407 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8408 match(Set dst (UModI src1 src2));
8409 expand %{
8410 iRegIdst tmp1;
8411 iRegIdst tmp2;
8412 udivI_reg_reg(tmp1, src1, src2);
8413 // Compute lower 32 bit result using signed instructions as suggested by ISA.
8414 // Upper 32 bit will contain garbage.
8415 mulI_reg_reg(tmp2, src2, tmp1);
8416 subI_reg_reg(dst, src1, tmp2);
8417 %}
8418 %}
8419
8420 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8421 match(Set dst (UDivL src1 src2));
8422 format %{ "DIVDU $dst, $src1, $src2" %}
8423 size(4);
8424 ins_encode %{
8425 __ divdu($dst$$Register, $src1$$Register, $src2$$Register);
8426 %}
8427 ins_pipe(pipe_class_default);
8428 %}
8429
8430 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8431 match(Set dst (UModL src1 src2));
8432 expand %{
8433 iRegLdst tmp1;
8434 iRegLdst tmp2;
8435 udivL_reg_reg(tmp1, src1, src2);
8436 mulL_reg_reg(tmp2, src2, tmp1);
8437 subL_reg_reg(dst, src1, tmp2);
8438 %}
8439 %}
8440
8441 // Integer Shift Instructions
8442
8443 // Register Shift Left
8444
8445 // Clear all but the lowest #mask bits.
8446 // Used to normalize shift amounts in registers.
8447 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
8448 // no match-rule, false predicate
8449 effect(DEF dst, USE src, USE mask);
8450 predicate(false);
8451
8452 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %}
8453 size(4);
8454 ins_encode %{
8455 __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
8456 %}
8457 ins_pipe(pipe_class_default);
8458 %}
8459
8460 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8461 // no match-rule, false predicate
8462 effect(DEF dst, USE src1, USE src2);
8463 predicate(false);
8464
8465 format %{ "SLW $dst, $src1, $src2" %}
8466 size(4);
8467 ins_encode %{
8468 __ slw($dst$$Register, $src1$$Register, $src2$$Register);
8469 %}
8470 ins_pipe(pipe_class_default);
8471 %}
8472
8473 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8474 match(Set dst (LShiftI src1 src2));
8475 ins_cost(DEFAULT_COST*2);
8476 expand %{
8477 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8478 iRegIdst tmpI;
8479 maskI_reg_imm(tmpI, src2, mask);
8480 lShiftI_reg_reg(dst, src1, tmpI);
8481 %}
8482 %}
8483
8484 // Register Shift Left Immediate
8485 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8486 match(Set dst (LShiftI src1 src2));
8487
8488 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %}
8489 size(4);
8490 ins_encode %{
8491 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8492 %}
8493 ins_pipe(pipe_class_default);
8494 %}
8495
8496 // AndI with negpow2-constant + LShiftI
8497 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8498 match(Set dst (LShiftI (AndI src1 src2) src3));
8499 predicate(UseRotateAndMaskInstructionsPPC64);
8500
8501 format %{ "RLWINM $dst, lShiftI(AndI($src1, $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, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
8510 }
8511 %}
8512 ins_pipe(pipe_class_default);
8513 %}
8514
8515 // RShiftI + AndI with negpow2-constant + LShiftI
8516 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8517 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
8518 predicate(UseRotateAndMaskInstructionsPPC64);
8519
8520 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
8521 size(4);
8522 ins_encode %{
8523 long src3 = $src3$$constant;
8524 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8525 if (maskbits >= 32) {
8526 __ li($dst$$Register, 0); // addi
8527 } else {
8528 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
8529 }
8530 %}
8531 ins_pipe(pipe_class_default);
8532 %}
8533
8534 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8535 // no match-rule, false predicate
8536 effect(DEF dst, USE src1, USE src2);
8537 predicate(false);
8538
8539 format %{ "SLD $dst, $src1, $src2" %}
8540 size(4);
8541 ins_encode %{
8542 __ sld($dst$$Register, $src1$$Register, $src2$$Register);
8543 %}
8544 ins_pipe(pipe_class_default);
8545 %}
8546
8547 // Register Shift Left
8548 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8549 match(Set dst (LShiftL src1 src2));
8550 ins_cost(DEFAULT_COST*2);
8551 expand %{
8552 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8553 iRegIdst tmpI;
8554 maskI_reg_imm(tmpI, src2, mask);
8555 lShiftL_regL_regI(dst, src1, tmpI);
8556 %}
8557 %}
8558
8559 // Register Shift Left Immediate
8560 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8561 match(Set dst (LShiftL src1 src2));
8562 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %}
8563 size(4);
8564 ins_encode %{
8565 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8566 %}
8567 ins_pipe(pipe_class_default);
8568 %}
8569
8570 // If we shift more than 32 bits, we need not convert I2L.
8571 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
8572 match(Set dst (LShiftL (ConvI2L src1) src2));
8573 ins_cost(DEFAULT_COST);
8574
8575 size(4);
8576 format %{ "SLDI $dst, i2l($src1), $src2" %}
8577 ins_encode %{
8578 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8579 %}
8580 ins_pipe(pipe_class_default);
8581 %}
8582
8583 // Shift a postivie int to the left.
8584 // Clrlsldi clears the upper 32 bits and shifts.
8585 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
8586 match(Set dst (LShiftL (ConvI2L src1) src2));
8587 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
8588
8589 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %}
8590 size(4);
8591 ins_encode %{
8592 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
8593 %}
8594 ins_pipe(pipe_class_default);
8595 %}
8596
8597 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8598 // no match-rule, false predicate
8599 effect(DEF dst, USE src1, USE src2);
8600 predicate(false);
8601
8602 format %{ "SRAW $dst, $src1, $src2" %}
8603 size(4);
8604 ins_encode %{
8605 __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
8606 %}
8607 ins_pipe(pipe_class_default);
8608 %}
8609
8610 // Register Arithmetic Shift Right
8611 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8612 match(Set dst (RShiftI src1 src2));
8613 ins_cost(DEFAULT_COST*2);
8614 expand %{
8615 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8616 iRegIdst tmpI;
8617 maskI_reg_imm(tmpI, src2, mask);
8618 arShiftI_reg_reg(dst, src1, tmpI);
8619 %}
8620 %}
8621
8622 // Register Arithmetic Shift Right Immediate
8623 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8624 match(Set dst (RShiftI src1 src2));
8625
8626 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %}
8627 size(4);
8628 ins_encode %{
8629 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8630 %}
8631 ins_pipe(pipe_class_default);
8632 %}
8633
8634 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8635 // no match-rule, false predicate
8636 effect(DEF dst, USE src1, USE src2);
8637 predicate(false);
8638
8639 format %{ "SRAD $dst, $src1, $src2" %}
8640 size(4);
8641 ins_encode %{
8642 __ srad($dst$$Register, $src1$$Register, $src2$$Register);
8643 %}
8644 ins_pipe(pipe_class_default);
8645 %}
8646
8647 // Register Shift Right Arithmetic Long
8648 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8649 match(Set dst (RShiftL src1 src2));
8650 ins_cost(DEFAULT_COST*2);
8651
8652 expand %{
8653 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8654 iRegIdst tmpI;
8655 maskI_reg_imm(tmpI, src2, mask);
8656 arShiftL_regL_regI(dst, src1, tmpI);
8657 %}
8658 %}
8659
8660 // Register Shift Right Immediate
8661 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8662 match(Set dst (RShiftL src1 src2));
8663
8664 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %}
8665 size(4);
8666 ins_encode %{
8667 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8668 %}
8669 ins_pipe(pipe_class_default);
8670 %}
8671
8672 // RShiftL + ConvL2I
8673 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8674 match(Set dst (ConvL2I (RShiftL src1 src2)));
8675
8676 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8677 size(4);
8678 ins_encode %{
8679 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8680 %}
8681 ins_pipe(pipe_class_default);
8682 %}
8683
8684 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8685 // no match-rule, false predicate
8686 effect(DEF dst, USE src1, USE src2);
8687 predicate(false);
8688
8689 format %{ "SRW $dst, $src1, $src2" %}
8690 size(4);
8691 ins_encode %{
8692 __ srw($dst$$Register, $src1$$Register, $src2$$Register);
8693 %}
8694 ins_pipe(pipe_class_default);
8695 %}
8696
8697 // Register Shift Right
8698 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8699 match(Set dst (URShiftI src1 src2));
8700 ins_cost(DEFAULT_COST*2);
8701
8702 expand %{
8703 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8704 iRegIdst tmpI;
8705 maskI_reg_imm(tmpI, src2, mask);
8706 urShiftI_reg_reg(dst, src1, tmpI);
8707 %}
8708 %}
8709
8710 // Register Shift Right Immediate
8711 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8712 match(Set dst (URShiftI src1 src2));
8713
8714 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %}
8715 size(4);
8716 ins_encode %{
8717 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8718 %}
8719 ins_pipe(pipe_class_default);
8720 %}
8721
8722 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8723 // no match-rule, false predicate
8724 effect(DEF dst, USE src1, USE src2);
8725 predicate(false);
8726
8727 format %{ "SRD $dst, $src1, $src2" %}
8728 size(4);
8729 ins_encode %{
8730 __ srd($dst$$Register, $src1$$Register, $src2$$Register);
8731 %}
8732 ins_pipe(pipe_class_default);
8733 %}
8734
8735 // Register Shift Right
8736 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8737 match(Set dst (URShiftL src1 src2));
8738 ins_cost(DEFAULT_COST*2);
8739
8740 expand %{
8741 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8742 iRegIdst tmpI;
8743 maskI_reg_imm(tmpI, src2, mask);
8744 urShiftL_regL_regI(dst, src1, tmpI);
8745 %}
8746 %}
8747
8748 // Register Shift Right Immediate
8749 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8750 match(Set dst (URShiftL src1 src2));
8751
8752 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %}
8753 size(4);
8754 ins_encode %{
8755 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8756 %}
8757 ins_pipe(pipe_class_default);
8758 %}
8759
8760 // URShiftL + ConvL2I.
8761 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8762 match(Set dst (ConvL2I (URShiftL src1 src2)));
8763
8764 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8765 size(4);
8766 ins_encode %{
8767 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8768 %}
8769 ins_pipe(pipe_class_default);
8770 %}
8771
8772 // Register Shift Right Immediate with a CastP2X
8773 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
8774 match(Set dst (URShiftL (CastP2X src1) src2));
8775
8776 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
8777 size(4);
8778 ins_encode %{
8779 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8780 %}
8781 ins_pipe(pipe_class_default);
8782 %}
8783
8784 // Bitfield Extract: URShiftI + AndI
8785 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
8786 match(Set dst (AndI (URShiftI src1 src2) src3));
8787
8788 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
8789 size(4);
8790 ins_encode %{
8791 int rshift = ($src2$$constant) & 0x1f;
8792 int length = log2i_exact((juint)$src3$$constant + 1u);
8793 if (rshift + length > 32) {
8794 // if necessary, adjust mask to omit rotated bits.
8795 length = 32 - rshift;
8796 }
8797 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8798 %}
8799 ins_pipe(pipe_class_default);
8800 %}
8801
8802 // Bitfield Extract: URShiftL + AndL
8803 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
8804 match(Set dst (AndL (URShiftL src1 src2) src3));
8805
8806 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
8807 size(4);
8808 ins_encode %{
8809 int rshift = ($src2$$constant) & 0x3f;
8810 int length = log2i_exact((julong)$src3$$constant + 1ull);
8811 if (rshift + length > 64) {
8812 // if necessary, adjust mask to omit rotated bits.
8813 length = 64 - rshift;
8814 }
8815 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8816 %}
8817 ins_pipe(pipe_class_default);
8818 %}
8819
8820 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
8821 match(Set dst (ConvL2I (ConvI2L src)));
8822
8823 format %{ "EXTSW $dst, $src \t// int->int" %}
8824 size(4);
8825 ins_encode %{
8826 __ extsw($dst$$Register, $src$$Register);
8827 %}
8828 ins_pipe(pipe_class_default);
8829 %}
8830
8831 //----------Rotate Instructions------------------------------------------------
8832
8833 // Rotate Left by 8-bit immediate
8834 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
8835 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
8836 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8837
8838 format %{ "ROTLWI $dst, $src, $lshift" %}
8839 size(4);
8840 ins_encode %{
8841 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
8842 %}
8843 ins_pipe(pipe_class_default);
8844 %}
8845
8846 // Rotate Right by 8-bit immediate
8847 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
8848 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
8849 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8850
8851 format %{ "ROTRWI $dst, $rshift" %}
8852 size(4);
8853 ins_encode %{
8854 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
8855 %}
8856 ins_pipe(pipe_class_default);
8857 %}
8858
8859 //----------Floating Point Arithmetic Instructions-----------------------------
8860
8861 // Add float single precision
8862 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
8863 match(Set dst (AddF src1 src2));
8864
8865 format %{ "FADDS $dst, $src1, $src2" %}
8866 size(4);
8867 ins_encode %{
8868 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8869 %}
8870 ins_pipe(pipe_class_default);
8871 %}
8872
8873 // Add float double precision
8874 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
8875 match(Set dst (AddD src1 src2));
8876
8877 format %{ "FADD $dst, $src1, $src2" %}
8878 size(4);
8879 ins_encode %{
8880 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8881 %}
8882 ins_pipe(pipe_class_default);
8883 %}
8884
8885 // Sub float single precision
8886 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
8887 match(Set dst (SubF src1 src2));
8888
8889 format %{ "FSUBS $dst, $src1, $src2" %}
8890 size(4);
8891 ins_encode %{
8892 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8893 %}
8894 ins_pipe(pipe_class_default);
8895 %}
8896
8897 // Sub float double precision
8898 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
8899 match(Set dst (SubD src1 src2));
8900 format %{ "FSUB $dst, $src1, $src2" %}
8901 size(4);
8902 ins_encode %{
8903 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8904 %}
8905 ins_pipe(pipe_class_default);
8906 %}
8907
8908 // Mul float single precision
8909 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
8910 match(Set dst (MulF src1 src2));
8911 format %{ "FMULS $dst, $src1, $src2" %}
8912 size(4);
8913 ins_encode %{
8914 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8915 %}
8916 ins_pipe(pipe_class_default);
8917 %}
8918
8919 // Mul float double precision
8920 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
8921 match(Set dst (MulD src1 src2));
8922 format %{ "FMUL $dst, $src1, $src2" %}
8923 size(4);
8924 ins_encode %{
8925 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8926 %}
8927 ins_pipe(pipe_class_default);
8928 %}
8929
8930 // Div float single precision
8931 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
8932 match(Set dst (DivF src1 src2));
8933 format %{ "FDIVS $dst, $src1, $src2" %}
8934 size(4);
8935 ins_encode %{
8936 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8937 %}
8938 ins_pipe(pipe_class_default);
8939 %}
8940
8941 // Div float double precision
8942 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
8943 match(Set dst (DivD src1 src2));
8944 format %{ "FDIV $dst, $src1, $src2" %}
8945 size(4);
8946 ins_encode %{
8947 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8948 %}
8949 ins_pipe(pipe_class_default);
8950 %}
8951
8952 // Absolute float single precision
8953 instruct absF_reg(regF dst, regF src) %{
8954 match(Set dst (AbsF src));
8955 format %{ "FABS $dst, $src \t// float" %}
8956 size(4);
8957 ins_encode %{
8958 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8959 %}
8960 ins_pipe(pipe_class_default);
8961 %}
8962
8963 // Absolute float double precision
8964 instruct absD_reg(regD dst, regD src) %{
8965 match(Set dst (AbsD src));
8966 format %{ "FABS $dst, $src \t// double" %}
8967 size(4);
8968 ins_encode %{
8969 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8970 %}
8971 ins_pipe(pipe_class_default);
8972 %}
8973
8974 instruct negF_reg(regF dst, regF src) %{
8975 match(Set dst (NegF src));
8976 format %{ "FNEG $dst, $src \t// float" %}
8977 size(4);
8978 ins_encode %{
8979 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8980 %}
8981 ins_pipe(pipe_class_default);
8982 %}
8983
8984 instruct negD_reg(regD dst, regD src) %{
8985 match(Set dst (NegD src));
8986 format %{ "FNEG $dst, $src \t// double" %}
8987 size(4);
8988 ins_encode %{
8989 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8990 %}
8991 ins_pipe(pipe_class_default);
8992 %}
8993
8994 // AbsF + NegF.
8995 instruct negF_absF_reg(regF dst, regF src) %{
8996 match(Set dst (NegF (AbsF src)));
8997 format %{ "FNABS $dst, $src \t// float" %}
8998 size(4);
8999 ins_encode %{
9000 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9001 %}
9002 ins_pipe(pipe_class_default);
9003 %}
9004
9005 // AbsD + NegD.
9006 instruct negD_absD_reg(regD dst, regD src) %{
9007 match(Set dst (NegD (AbsD src)));
9008 format %{ "FNABS $dst, $src \t// double" %}
9009 size(4);
9010 ins_encode %{
9011 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9012 %}
9013 ins_pipe(pipe_class_default);
9014 %}
9015
9016 // Sqrt float double precision
9017 instruct sqrtD_reg(regD dst, regD src) %{
9018 match(Set dst (SqrtD src));
9019 format %{ "FSQRT $dst, $src" %}
9020 size(4);
9021 ins_encode %{
9022 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
9023 %}
9024 ins_pipe(pipe_class_default);
9025 %}
9026
9027 // Single-precision sqrt.
9028 instruct sqrtF_reg(regF dst, regF src) %{
9029 match(Set dst (SqrtF src));
9030 ins_cost(DEFAULT_COST);
9031
9032 format %{ "FSQRTS $dst, $src" %}
9033 size(4);
9034 ins_encode %{
9035 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
9036 %}
9037 ins_pipe(pipe_class_default);
9038 %}
9039
9040
9041 // Multiply-Accumulate
9042 // src1 * src2 + src3
9043 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9044 match(Set dst (FmaF src3 (Binary src1 src2)));
9045
9046 format %{ "FMADDS $dst, $src1, $src2, $src3" %}
9047 size(4);
9048 ins_encode %{
9049 assert(UseFMA, "Needs FMA instructions support.");
9050 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9051 %}
9052 ins_pipe(pipe_class_default);
9053 %}
9054
9055 // src1 * src2 + src3
9056 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9057 match(Set dst (FmaD src3 (Binary src1 src2)));
9058
9059 format %{ "FMADD $dst, $src1, $src2, $src3" %}
9060 size(4);
9061 ins_encode %{
9062 assert(UseFMA, "Needs FMA instructions support.");
9063 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9064 %}
9065 ins_pipe(pipe_class_default);
9066 %}
9067
9068 // src1 * (-src2) + src3 = -(src1*src2-src3)
9069 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9070 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9071 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
9072
9073 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
9074 size(4);
9075 ins_encode %{
9076 assert(UseFMA, "Needs FMA instructions support.");
9077 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9078 %}
9079 ins_pipe(pipe_class_default);
9080 %}
9081
9082 // src1 * (-src2) + src3 = -(src1*src2-src3)
9083 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9084 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9085 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
9086
9087 format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
9088 size(4);
9089 ins_encode %{
9090 assert(UseFMA, "Needs FMA instructions support.");
9091 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9092 %}
9093 ins_pipe(pipe_class_default);
9094 %}
9095
9096 // src1 * (-src2) - src3 = -(src1*src2+src3)
9097 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9098 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9099 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
9100
9101 format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
9102 size(4);
9103 ins_encode %{
9104 assert(UseFMA, "Needs FMA instructions support.");
9105 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9106 %}
9107 ins_pipe(pipe_class_default);
9108 %}
9109
9110 // src1 * (-src2) - src3 = -(src1*src2+src3)
9111 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9112 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9113 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9114
9115 format %{ "FNMADD $dst, $src1, $src2, $src3" %}
9116 size(4);
9117 ins_encode %{
9118 assert(UseFMA, "Needs FMA instructions support.");
9119 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9120 %}
9121 ins_pipe(pipe_class_default);
9122 %}
9123
9124 // src1 * src2 - src3
9125 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9126 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9127
9128 format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
9129 size(4);
9130 ins_encode %{
9131 assert(UseFMA, "Needs FMA instructions support.");
9132 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9133 %}
9134 ins_pipe(pipe_class_default);
9135 %}
9136
9137 // src1 * src2 - src3
9138 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9139 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9140
9141 format %{ "FMSUB $dst, $src1, $src2, $src3" %}
9142 size(4);
9143 ins_encode %{
9144 assert(UseFMA, "Needs FMA instructions support.");
9145 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9146 %}
9147 ins_pipe(pipe_class_default);
9148 %}
9149
9150
9151 //----------Logical Instructions-----------------------------------------------
9152
9153 // And Instructions
9154
9155 // Register And
9156 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9157 match(Set dst (AndI src1 src2));
9158 format %{ "AND $dst, $src1, $src2" %}
9159 size(4);
9160 ins_encode %{
9161 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9162 %}
9163 ins_pipe(pipe_class_default);
9164 %}
9165
9166 // Left shifted Immediate And
9167 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{
9168 match(Set dst (AndI src1 src2));
9169 effect(KILL cr0);
9170 format %{ "ANDIS $dst, $src1, $src2.hi" %}
9171 size(4);
9172 ins_encode %{
9173 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16)));
9174 %}
9175 ins_pipe(pipe_class_default);
9176 %}
9177
9178 // Immediate And
9179 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{
9180 match(Set dst (AndI src1 src2));
9181 effect(KILL cr0);
9182
9183 format %{ "ANDI $dst, $src1, $src2" %}
9184 size(4);
9185 ins_encode %{
9186 // FIXME: avoid andi_ ?
9187 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9188 %}
9189 ins_pipe(pipe_class_default);
9190 %}
9191
9192 // Immediate And where the immediate is a negative power of 2.
9193 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{
9194 match(Set dst (AndI src1 src2));
9195 format %{ "ANDWI $dst, $src1, $src2" %}
9196 size(4);
9197 ins_encode %{
9198 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant));
9199 %}
9200 ins_pipe(pipe_class_default);
9201 %}
9202
9203 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{
9204 match(Set dst (AndI src1 src2));
9205 format %{ "ANDWI $dst, $src1, $src2" %}
9206 size(4);
9207 ins_encode %{
9208 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u));
9209 %}
9210 ins_pipe(pipe_class_default);
9211 %}
9212
9213 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{
9214 match(Set dst (AndI src1 src2));
9215 predicate(UseRotateAndMaskInstructionsPPC64);
9216 format %{ "ANDWI $dst, $src1, $src2" %}
9217 size(4);
9218 ins_encode %{
9219 int bitpos = 31 - log2i_exact((juint)$src2$$constant);
9220 __ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos);
9221 %}
9222 ins_pipe(pipe_class_default);
9223 %}
9224
9225 // Register And Long
9226 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9227 match(Set dst (AndL src1 src2));
9228 ins_cost(DEFAULT_COST);
9229
9230 format %{ "AND $dst, $src1, $src2 \t// long" %}
9231 size(4);
9232 ins_encode %{
9233 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9234 %}
9235 ins_pipe(pipe_class_default);
9236 %}
9237
9238 // Immediate And long
9239 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
9240 match(Set dst (AndL src1 src2));
9241 effect(KILL cr0);
9242
9243 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9244 size(4);
9245 ins_encode %{
9246 // FIXME: avoid andi_ ?
9247 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9248 %}
9249 ins_pipe(pipe_class_default);
9250 %}
9251
9252 // Immediate And Long where the immediate is a negative power of 2.
9253 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
9254 match(Set dst (AndL src1 src2));
9255 format %{ "ANDDI $dst, $src1, $src2" %}
9256 size(4);
9257 ins_encode %{
9258 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant));
9259 %}
9260 ins_pipe(pipe_class_default);
9261 %}
9262
9263 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9264 match(Set dst (AndL src1 src2));
9265 format %{ "ANDDI $dst, $src1, $src2" %}
9266 size(4);
9267 ins_encode %{
9268 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9269 %}
9270 ins_pipe(pipe_class_default);
9271 %}
9272
9273 // AndL + ConvL2I.
9274 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9275 match(Set dst (ConvL2I (AndL src1 src2)));
9276 ins_cost(DEFAULT_COST);
9277
9278 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %}
9279 size(4);
9280 ins_encode %{
9281 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9282 %}
9283 ins_pipe(pipe_class_default);
9284 %}
9285
9286 // Or Instructions
9287
9288 // Register Or
9289 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9290 match(Set dst (OrI src1 src2));
9291 format %{ "OR $dst, $src1, $src2" %}
9292 size(4);
9293 ins_encode %{
9294 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9295 %}
9296 ins_pipe(pipe_class_default);
9297 %}
9298
9299 // Expand does not work with above instruct. (??)
9300 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9301 // no match-rule
9302 effect(DEF dst, USE src1, USE src2);
9303 format %{ "OR $dst, $src1, $src2" %}
9304 size(4);
9305 ins_encode %{
9306 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9307 %}
9308 ins_pipe(pipe_class_default);
9309 %}
9310
9311 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9312 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9313 ins_cost(DEFAULT_COST*3);
9314
9315 expand %{
9316 // FIXME: we should do this in the ideal world.
9317 iRegIdst tmp1;
9318 iRegIdst tmp2;
9319 orI_reg_reg(tmp1, src1, src2);
9320 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9321 orI_reg_reg(dst, tmp1, tmp2);
9322 %}
9323 %}
9324
9325 // Immediate Or
9326 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9327 match(Set dst (OrI src1 src2));
9328 format %{ "ORI $dst, $src1, $src2" %}
9329 size(4);
9330 ins_encode %{
9331 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9332 %}
9333 ins_pipe(pipe_class_default);
9334 %}
9335
9336 // Register Or Long
9337 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9338 match(Set dst (OrL src1 src2));
9339 ins_cost(DEFAULT_COST);
9340
9341 size(4);
9342 format %{ "OR $dst, $src1, $src2 \t// long" %}
9343 ins_encode %{
9344 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9345 %}
9346 ins_pipe(pipe_class_default);
9347 %}
9348
9349 // OrL + ConvL2I.
9350 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9351 match(Set dst (ConvL2I (OrL src1 src2)));
9352 ins_cost(DEFAULT_COST);
9353
9354 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %}
9355 size(4);
9356 ins_encode %{
9357 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9358 %}
9359 ins_pipe(pipe_class_default);
9360 %}
9361
9362 // Immediate Or long
9363 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9364 match(Set dst (OrL src1 con));
9365 ins_cost(DEFAULT_COST);
9366
9367 format %{ "ORI $dst, $src1, $con \t// long" %}
9368 size(4);
9369 ins_encode %{
9370 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9371 %}
9372 ins_pipe(pipe_class_default);
9373 %}
9374
9375 // Xor Instructions
9376
9377 // Register Xor
9378 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9379 match(Set dst (XorI src1 src2));
9380 format %{ "XOR $dst, $src1, $src2" %}
9381 size(4);
9382 ins_encode %{
9383 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9384 %}
9385 ins_pipe(pipe_class_default);
9386 %}
9387
9388 // Expand does not work with above instruct. (??)
9389 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9390 // no match-rule
9391 effect(DEF dst, USE src1, USE src2);
9392 format %{ "XOR $dst, $src1, $src2" %}
9393 size(4);
9394 ins_encode %{
9395 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9396 %}
9397 ins_pipe(pipe_class_default);
9398 %}
9399
9400 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9401 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
9402 ins_cost(DEFAULT_COST*3);
9403
9404 expand %{
9405 // FIXME: we should do this in the ideal world.
9406 iRegIdst tmp1;
9407 iRegIdst tmp2;
9408 xorI_reg_reg(tmp1, src1, src2);
9409 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
9410 xorI_reg_reg(dst, tmp1, tmp2);
9411 %}
9412 %}
9413
9414 // Immediate Xor
9415 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9416 match(Set dst (XorI src1 src2));
9417 format %{ "XORI $dst, $src1, $src2" %}
9418 size(4);
9419 ins_encode %{
9420 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9421 %}
9422 ins_pipe(pipe_class_default);
9423 %}
9424
9425 // Register Xor Long
9426 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9427 match(Set dst (XorL src1 src2));
9428 ins_cost(DEFAULT_COST);
9429
9430 format %{ "XOR $dst, $src1, $src2 \t// long" %}
9431 size(4);
9432 ins_encode %{
9433 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9434 %}
9435 ins_pipe(pipe_class_default);
9436 %}
9437
9438 // XorL + ConvL2I.
9439 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9440 match(Set dst (ConvL2I (XorL src1 src2)));
9441 ins_cost(DEFAULT_COST);
9442
9443 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %}
9444 size(4);
9445 ins_encode %{
9446 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9447 %}
9448 ins_pipe(pipe_class_default);
9449 %}
9450
9451 // Immediate Xor Long
9452 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
9453 match(Set dst (XorL src1 src2));
9454 ins_cost(DEFAULT_COST);
9455
9456 format %{ "XORI $dst, $src1, $src2 \t// long" %}
9457 size(4);
9458 ins_encode %{
9459 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9460 %}
9461 ins_pipe(pipe_class_default);
9462 %}
9463
9464 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
9465 match(Set dst (XorI src1 src2));
9466 ins_cost(DEFAULT_COST);
9467
9468 format %{ "NOT $dst, $src1 ($src2)" %}
9469 size(4);
9470 ins_encode %{
9471 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9472 %}
9473 ins_pipe(pipe_class_default);
9474 %}
9475
9476 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
9477 match(Set dst (XorL src1 src2));
9478 ins_cost(DEFAULT_COST);
9479
9480 format %{ "NOT $dst, $src1 ($src2) \t// long" %}
9481 size(4);
9482 ins_encode %{
9483 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9484 %}
9485 ins_pipe(pipe_class_default);
9486 %}
9487
9488 // And-complement
9489 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
9490 match(Set dst (AndI (XorI src1 src2) src3));
9491 ins_cost(DEFAULT_COST);
9492
9493 format %{ "ANDW $dst, xori($src1, $src2), $src3" %}
9494 size(4);
9495 ins_encode( enc_andc(dst, src3, src1) );
9496 ins_pipe(pipe_class_default);
9497 %}
9498
9499 // And-complement
9500 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9501 // no match-rule, false predicate
9502 effect(DEF dst, USE src1, USE src2);
9503 predicate(false);
9504
9505 format %{ "ANDC $dst, $src1, $src2" %}
9506 size(4);
9507 ins_encode %{
9508 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
9509 %}
9510 ins_pipe(pipe_class_default);
9511 %}
9512
9513 //----------Moves between int/long and float/double----------------------------
9514 //
9515 // The following rules move values from int/long registers/stack-locations
9516 // to float/double registers/stack-locations and vice versa, without doing any
9517 // conversions. These rules are used to implement the bit-conversion methods
9518 // of java.lang.Float etc., e.g.
9519 // int floatToIntBits(float value)
9520 // float intBitsToFloat(int bits)
9521
9522 instruct moveL2D_reg(regD dst, iRegLsrc src) %{
9523 match(Set dst (MoveL2D src));
9524
9525 format %{ "MTFPRD $dst, $src" %}
9526 size(4);
9527 ins_encode %{
9528 __ mtfprd($dst$$FloatRegister, $src$$Register);
9529 %}
9530 ins_pipe(pipe_class_default);
9531 %}
9532
9533 instruct moveI2D_reg(regD dst, iRegIsrc src) %{
9534 // no match-rule, false predicate
9535 effect(DEF dst, USE src);
9536 predicate(false);
9537
9538 format %{ "MTFPRWA $dst, $src" %}
9539 size(4);
9540 ins_encode %{
9541 __ mtfprwa($dst$$FloatRegister, $src$$Register);
9542 %}
9543 ins_pipe(pipe_class_default);
9544 %}
9545
9546 //---------- Chain stack slots between similar types --------
9547
9548 // These are needed so that the rules below can match.
9549
9550 // Load integer from stack slot
9551 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
9552 match(Set dst src);
9553 ins_cost(MEMORY_REF_COST);
9554
9555 format %{ "LWZ $dst, $src" %}
9556 size(4);
9557 ins_encode( enc_lwz(dst, src) );
9558 ins_pipe(pipe_class_memory);
9559 %}
9560
9561 // Store integer to stack slot
9562 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
9563 match(Set dst src);
9564 ins_cost(MEMORY_REF_COST);
9565
9566 format %{ "STW $src, $dst \t// stk" %}
9567 size(4);
9568 ins_encode( enc_stw(src, dst) ); // rs=rt
9569 ins_pipe(pipe_class_memory);
9570 %}
9571
9572 // Load long from stack slot
9573 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
9574 match(Set dst src);
9575 ins_cost(MEMORY_REF_COST);
9576
9577 format %{ "LD $dst, $src \t// long" %}
9578 size(4);
9579 ins_encode( enc_ld(dst, src) );
9580 ins_pipe(pipe_class_memory);
9581 %}
9582
9583 // Store long to stack slot
9584 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
9585 match(Set dst src);
9586 ins_cost(MEMORY_REF_COST);
9587
9588 format %{ "STD $src, $dst \t// long" %}
9589 size(4);
9590 ins_encode( enc_std(src, dst) ); // rs=rt
9591 ins_pipe(pipe_class_memory);
9592 %}
9593
9594 //----------Moves between int and float
9595
9596 // Move float value from float stack-location to integer register.
9597 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
9598 match(Set dst (MoveF2I src));
9599 ins_cost(MEMORY_REF_COST);
9600
9601 format %{ "LWZ $dst, $src \t// MoveF2I" %}
9602 size(4);
9603 ins_encode( enc_lwz(dst, src) );
9604 ins_pipe(pipe_class_memory);
9605 %}
9606
9607 // Move float value from float register to integer stack-location.
9608 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
9609 match(Set dst (MoveF2I src));
9610 ins_cost(MEMORY_REF_COST);
9611
9612 format %{ "STFS $src, $dst \t// MoveF2I" %}
9613 size(4);
9614 ins_encode( enc_stfs(src, dst) );
9615 ins_pipe(pipe_class_memory);
9616 %}
9617
9618 // Move integer value from integer stack-location to float register.
9619 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
9620 match(Set dst (MoveI2F src));
9621 ins_cost(MEMORY_REF_COST);
9622
9623 format %{ "LFS $dst, $src \t// MoveI2F" %}
9624 size(4);
9625 ins_encode %{
9626 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
9627 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
9628 %}
9629 ins_pipe(pipe_class_memory);
9630 %}
9631
9632 // Move integer value from integer register to float stack-location.
9633 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
9634 match(Set dst (MoveI2F src));
9635 ins_cost(MEMORY_REF_COST);
9636
9637 format %{ "STW $src, $dst \t// MoveI2F" %}
9638 size(4);
9639 ins_encode( enc_stw(src, dst) );
9640 ins_pipe(pipe_class_memory);
9641 %}
9642
9643
9644 //----------Moves between long and double
9645
9646 // Move double value from double stack-location to long register.
9647 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
9648 match(Set dst (MoveD2L src));
9649 ins_cost(MEMORY_REF_COST);
9650 size(4);
9651 format %{ "LD $dst, $src \t// MoveD2L" %}
9652 ins_encode( enc_ld(dst, src) );
9653 ins_pipe(pipe_class_memory);
9654 %}
9655
9656 // Move double value from double register to long stack-location.
9657 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
9658 match(Set dst (MoveD2L src));
9659 effect(DEF dst, USE src);
9660 ins_cost(MEMORY_REF_COST);
9661
9662 format %{ "STFD $src, $dst \t// MoveD2L" %}
9663 size(4);
9664 ins_encode( enc_stfd(src, dst) );
9665 ins_pipe(pipe_class_memory);
9666 %}
9667
9668
9669 //----------Register Move Instructions-----------------------------------------
9670
9671 // Replicate for Superword
9672
9673 instruct moveReg(iRegLdst dst, iRegIsrc src) %{
9674 predicate(false);
9675 effect(DEF dst, USE src);
9676
9677 format %{ "MR $dst, $src \t// replicate " %}
9678 // variable size, 0 or 4.
9679 ins_encode %{
9680 __ mr_if_needed($dst$$Register, $src$$Register);
9681 %}
9682 ins_pipe(pipe_class_default);
9683 %}
9684
9685 //----------Cast instructions (Java-level type cast)---------------------------
9686
9687 // Cast Long to Pointer for unsafe natives.
9688 instruct castX2P(iRegPdst dst, iRegLsrc src) %{
9689 match(Set dst (CastX2P src));
9690
9691 format %{ "MR $dst, $src \t// Long->Ptr" %}
9692 // variable size, 0 or 4.
9693 ins_encode %{
9694 __ mr_if_needed($dst$$Register, $src$$Register);
9695 %}
9696 ins_pipe(pipe_class_default);
9697 %}
9698
9699 // Cast Pointer to Long for unsafe natives.
9700 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
9701 match(Set dst (CastP2X src));
9702
9703 format %{ "MR $dst, $src \t// Ptr->Long" %}
9704 // variable size, 0 or 4.
9705 ins_encode %{
9706 __ mr_if_needed($dst$$Register, $src$$Register);
9707 %}
9708 ins_pipe(pipe_class_default);
9709 %}
9710
9711 instruct castN2X(iRegLdst dst, iRegNsrc src) %{
9712 match(Set dst (CastP2X src));
9713
9714 format %{ "MR $dst, $src \t// Ptr->Long" %}
9715 // variable size, 0 or 4.
9716 ins_encode %{
9717 __ mr_if_needed($dst$$Register, $src$$Register);
9718 %}
9719 ins_pipe(pipe_class_default);
9720 %}
9721
9722 instruct castPP(iRegPdst dst) %{
9723 match(Set dst (CastPP dst));
9724 format %{ " -- \t// castPP of $dst" %}
9725 size(0);
9726 ins_encode( /*empty*/ );
9727 ins_pipe(pipe_class_default);
9728 %}
9729
9730 instruct castII(iRegIdst dst) %{
9731 match(Set dst (CastII dst));
9732 format %{ " -- \t// castII of $dst" %}
9733 size(0);
9734 ins_encode( /*empty*/ );
9735 ins_pipe(pipe_class_default);
9736 %}
9737
9738 instruct castLL(iRegLdst dst) %{
9739 match(Set dst (CastLL dst));
9740 format %{ " -- \t// castLL of $dst" %}
9741 size(0);
9742 ins_encode( /*empty*/ );
9743 ins_pipe(pipe_class_default);
9744 %}
9745
9746 instruct castFF(regF dst) %{
9747 match(Set dst (CastFF dst));
9748 format %{ " -- \t// castFF of $dst" %}
9749 size(0);
9750 ins_encode( /*empty*/ );
9751 ins_pipe(pipe_class_default);
9752 %}
9753
9754 instruct castDD(regD dst) %{
9755 match(Set dst (CastDD dst));
9756 format %{ " -- \t// castDD of $dst" %}
9757 size(0);
9758 ins_encode( /*empty*/ );
9759 ins_pipe(pipe_class_default);
9760 %}
9761
9762 instruct castVV8(iRegLdst dst) %{
9763 match(Set dst (CastVV dst));
9764 format %{ " -- \t// castVV of $dst" %}
9765 size(0);
9766 ins_encode( /*empty*/ );
9767 ins_pipe(pipe_class_default);
9768 %}
9769
9770 instruct castVV16(vecX dst) %{
9771 match(Set dst (CastVV dst));
9772 format %{ " -- \t// castVV of $dst" %}
9773 size(0);
9774 ins_encode( /*empty*/ );
9775 ins_pipe(pipe_class_default);
9776 %}
9777
9778 instruct checkCastPP(iRegPdst dst) %{
9779 match(Set dst (CheckCastPP dst));
9780 format %{ " -- \t// checkcastPP of $dst" %}
9781 size(0);
9782 ins_encode( /*empty*/ );
9783 ins_pipe(pipe_class_default);
9784 %}
9785
9786 //----------Convert instructions-----------------------------------------------
9787
9788 // Convert to boolean.
9789
9790 // int_to_bool(src) : { 1 if src != 0
9791 // { 0 else
9792 //
9793 // strategy:
9794 // 1) Count leading zeros of 32 bit-value src,
9795 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
9796 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9797 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9798
9799 // convI2Bool
9800 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
9801 match(Set dst (Conv2B src));
9802 predicate(UseCountLeadingZerosInstructionsPPC64);
9803 ins_cost(DEFAULT_COST);
9804
9805 expand %{
9806 immI shiftAmount %{ 0x5 %}
9807 uimmI16 mask %{ 0x1 %}
9808 iRegIdst tmp1;
9809 iRegIdst tmp2;
9810 countLeadingZerosI(tmp1, src);
9811 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9812 xorI_reg_uimm16(dst, tmp2, mask);
9813 %}
9814 %}
9815
9816 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
9817 match(Set dst (Conv2B src));
9818 effect(TEMP crx);
9819 predicate(!UseCountLeadingZerosInstructionsPPC64);
9820 ins_cost(DEFAULT_COST);
9821
9822 format %{ "CMPWI $crx, $src, #0 \t// convI2B"
9823 "LI $dst, #0\n\t"
9824 "BEQ $crx, done\n\t"
9825 "LI $dst, #1\n"
9826 "done:" %}
9827 size(16);
9828 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
9829 ins_pipe(pipe_class_compare);
9830 %}
9831
9832 // ConvI2B + XorI
9833 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
9834 match(Set dst (XorI (Conv2B src) mask));
9835 predicate(UseCountLeadingZerosInstructionsPPC64);
9836 ins_cost(DEFAULT_COST);
9837
9838 expand %{
9839 immI shiftAmount %{ 0x5 %}
9840 iRegIdst tmp1;
9841 countLeadingZerosI(tmp1, src);
9842 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9843 %}
9844 %}
9845
9846 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
9847 match(Set dst (XorI (Conv2B src) mask));
9848 effect(TEMP crx);
9849 predicate(!UseCountLeadingZerosInstructionsPPC64);
9850 ins_cost(DEFAULT_COST);
9851
9852 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
9853 "LI $dst, #1\n\t"
9854 "BEQ $crx, done\n\t"
9855 "LI $dst, #0\n"
9856 "done:" %}
9857 size(16);
9858 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
9859 ins_pipe(pipe_class_compare);
9860 %}
9861
9862 // AndI 0b0..010..0 + ConvI2B
9863 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
9864 match(Set dst (Conv2B (AndI src mask)));
9865 predicate(UseRotateAndMaskInstructionsPPC64);
9866 ins_cost(DEFAULT_COST);
9867
9868 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
9869 size(4);
9870 ins_encode %{
9871 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31);
9872 %}
9873 ins_pipe(pipe_class_default);
9874 %}
9875
9876 // Convert pointer to boolean.
9877 //
9878 // ptr_to_bool(src) : { 1 if src != 0
9879 // { 0 else
9880 //
9881 // strategy:
9882 // 1) Count leading zeros of 64 bit-value src,
9883 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
9884 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9885 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9886
9887 // ConvP2B
9888 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
9889 match(Set dst (Conv2B src));
9890 predicate(UseCountLeadingZerosInstructionsPPC64);
9891 ins_cost(DEFAULT_COST);
9892
9893 expand %{
9894 immI shiftAmount %{ 0x6 %}
9895 uimmI16 mask %{ 0x1 %}
9896 iRegIdst tmp1;
9897 iRegIdst tmp2;
9898 countLeadingZerosP(tmp1, src);
9899 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9900 xorI_reg_uimm16(dst, tmp2, mask);
9901 %}
9902 %}
9903
9904 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
9905 match(Set dst (Conv2B src));
9906 effect(TEMP crx);
9907 predicate(!UseCountLeadingZerosInstructionsPPC64);
9908 ins_cost(DEFAULT_COST);
9909
9910 format %{ "CMPDI $crx, $src, #0 \t// convP2B"
9911 "LI $dst, #0\n\t"
9912 "BEQ $crx, done\n\t"
9913 "LI $dst, #1\n"
9914 "done:" %}
9915 size(16);
9916 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
9917 ins_pipe(pipe_class_compare);
9918 %}
9919
9920 // ConvP2B + XorI
9921 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
9922 match(Set dst (XorI (Conv2B src) mask));
9923 predicate(UseCountLeadingZerosInstructionsPPC64);
9924 ins_cost(DEFAULT_COST);
9925
9926 expand %{
9927 immI shiftAmount %{ 0x6 %}
9928 iRegIdst tmp1;
9929 countLeadingZerosP(tmp1, src);
9930 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9931 %}
9932 %}
9933
9934 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
9935 match(Set dst (XorI (Conv2B src) mask));
9936 effect(TEMP crx);
9937 predicate(!UseCountLeadingZerosInstructionsPPC64);
9938 ins_cost(DEFAULT_COST);
9939
9940 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
9941 "LI $dst, #1\n\t"
9942 "BEQ $crx, done\n\t"
9943 "LI $dst, #0\n"
9944 "done:" %}
9945 size(16);
9946 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
9947 ins_pipe(pipe_class_compare);
9948 %}
9949
9950 // if src1 < src2, return -1 else return 0
9951 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9952 match(Set dst (CmpLTMask src1 src2));
9953 ins_cost(DEFAULT_COST*4);
9954
9955 expand %{
9956 iRegLdst src1s;
9957 iRegLdst src2s;
9958 iRegLdst diff;
9959 convI2L_reg(src1s, src1); // Ensure proper sign extension.
9960 convI2L_reg(src2s, src2); // Ensure proper sign extension.
9961 subL_reg_reg(diff, src1s, src2s);
9962 // Need to consider >=33 bit result, therefore we need signmaskL.
9963 signmask64I_regL(dst, diff);
9964 %}
9965 %}
9966
9967 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
9968 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
9969 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %}
9970 size(4);
9971 ins_encode %{
9972 __ srawi($dst$$Register, $src1$$Register, 0x1f);
9973 %}
9974 ins_pipe(pipe_class_default);
9975 %}
9976
9977 //----------Arithmetic Conversion Instructions---------------------------------
9978
9979 // Convert to Byte -- nop
9980 // Convert to Short -- nop
9981
9982 // Convert to Int
9983
9984 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
9985 match(Set dst (RShiftI (LShiftI src amount) amount));
9986 format %{ "EXTSB $dst, $src \t// byte->int" %}
9987 size(4);
9988 ins_encode %{
9989 __ extsb($dst$$Register, $src$$Register);
9990 %}
9991 ins_pipe(pipe_class_default);
9992 %}
9993
9994 instruct extsh(iRegIdst dst, iRegIsrc src) %{
9995 effect(DEF dst, USE src);
9996
9997 size(4);
9998 ins_encode %{
9999 __ extsh($dst$$Register, $src$$Register);
10000 %}
10001 ins_pipe(pipe_class_default);
10002 %}
10003
10004 // LShiftI 16 + RShiftI 16 converts short to int.
10005 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
10006 match(Set dst (RShiftI (LShiftI src amount) amount));
10007 format %{ "EXTSH $dst, $src \t// short->int" %}
10008 size(4);
10009 ins_encode %{
10010 __ extsh($dst$$Register, $src$$Register);
10011 %}
10012 ins_pipe(pipe_class_default);
10013 %}
10014
10015 // ConvL2I + ConvI2L: Sign extend int in long register.
10016 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
10017 match(Set dst (ConvI2L (ConvL2I src)));
10018
10019 format %{ "EXTSW $dst, $src \t// long->long" %}
10020 size(4);
10021 ins_encode %{
10022 __ extsw($dst$$Register, $src$$Register);
10023 %}
10024 ins_pipe(pipe_class_default);
10025 %}
10026
10027 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
10028 match(Set dst (ConvL2I src));
10029 format %{ "MR $dst, $src \t// long->int" %}
10030 // variable size, 0 or 4
10031 ins_encode %{
10032 __ mr_if_needed($dst$$Register, $src$$Register);
10033 %}
10034 ins_pipe(pipe_class_default);
10035 %}
10036
10037 instruct convD2IRaw_regD(regD dst, regD src) %{
10038 // no match-rule, false predicate
10039 effect(DEF dst, USE src);
10040 predicate(false);
10041
10042 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
10043 size(4);
10044 ins_encode %{
10045 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10046 %}
10047 ins_pipe(pipe_class_default);
10048 %}
10049
10050 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
10051 // no match-rule, false predicate
10052 effect(DEF dst, USE crx, USE src);
10053 predicate(false);
10054
10055 ins_variable_size_depending_on_alignment(true);
10056
10057 format %{ "CMOVI $crx, $dst, $src" %}
10058 size(8);
10059 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10060 ins_pipe(pipe_class_default);
10061 %}
10062
10063 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
10064 // no match-rule, false predicate
10065 effect(DEF dst, USE crx, USE src);
10066 predicate(false);
10067
10068 ins_variable_size_depending_on_alignment(true);
10069
10070 format %{ "CMOVI $crx, $dst, $src" %}
10071 size(8);
10072 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10073 ins_pipe(pipe_class_default);
10074 %}
10075
10076
10077 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{
10078 // no match-rule, false predicate
10079 effect(DEF dst, USE crx, USE src);
10080 predicate(false);
10081
10082 format %{ "CMOVI $dst, $crx, $src \t// postalloc expanded" %}
10083 postalloc_expand %{
10084 //
10085 // replaces
10086 //
10087 // region dst crx src
10088 // \ | | /
10089 // dst=cmovI_bso_reg_conLvalue0
10090 //
10091 // with
10092 //
10093 // region dst
10094 // \ /
10095 // dst=loadConI16(0)
10096 // |
10097 // ^ region dst crx src
10098 // | \ | | /
10099 // dst=cmovI_bso_reg
10100 //
10101
10102 // Create new nodes.
10103 MachNode *m1 = new loadConI16Node();
10104 MachNode *m2 = new cmovI_bso_regNode();
10105
10106 // inputs for new nodes
10107 m1->add_req(n_region);
10108 m2->add_req(n_region, n_crx, n_src);
10109
10110 // precedences for new nodes
10111 m2->add_prec(m1);
10112
10113 // operands for new nodes
10114 m1->_opnds[0] = op_dst;
10115 m1->_opnds[1] = new immI16Oper(0);
10116
10117 m2->_opnds[0] = op_dst;
10118 m2->_opnds[1] = op_crx;
10119 m2->_opnds[2] = op_src;
10120
10121 // registers for new nodes
10122 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10123 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10124
10125 // Insert new nodes.
10126 nodes->push(m1);
10127 nodes->push(m2);
10128 %}
10129 %}
10130
10131
10132 // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
10133 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
10134 match(Set dst (ConvD2I src));
10135 ins_cost(DEFAULT_COST);
10136
10137 expand %{
10138 regD tmpD;
10139 flagsReg crx;
10140 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10141 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
10142 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10143 %}
10144 %}
10145
10146 instruct convF2IRaw_regF(regF dst, regF src) %{
10147 // no match-rule, false predicate
10148 effect(DEF dst, USE src);
10149 predicate(false);
10150
10151 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
10152 size(4);
10153 ins_encode %{
10154 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10155 %}
10156 ins_pipe(pipe_class_default);
10157 %}
10158
10159
10160 // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
10161 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
10162 match(Set dst (ConvF2I src));
10163 ins_cost(DEFAULT_COST);
10164
10165 expand %{
10166 regF tmpF;
10167 flagsReg crx;
10168 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10169 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10170 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10171 %}
10172 %}
10173
10174 // Convert to Long
10175
10176 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
10177 match(Set dst (ConvI2L src));
10178 format %{ "EXTSW $dst, $src \t// int->long" %}
10179 size(4);
10180 ins_encode %{
10181 __ extsw($dst$$Register, $src$$Register);
10182 %}
10183 ins_pipe(pipe_class_default);
10184 %}
10185
10186 // Zero-extend: convert unsigned int to long (convUI2L).
10187 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
10188 match(Set dst (AndL (ConvI2L src) mask));
10189 ins_cost(DEFAULT_COST);
10190
10191 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10192 size(4);
10193 ins_encode %{
10194 __ clrldi($dst$$Register, $src$$Register, 32);
10195 %}
10196 ins_pipe(pipe_class_default);
10197 %}
10198
10199 // Zero-extend: convert unsigned int to long in long register.
10200 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
10201 match(Set dst (AndL src mask));
10202 ins_cost(DEFAULT_COST);
10203
10204 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10205 size(4);
10206 ins_encode %{
10207 __ clrldi($dst$$Register, $src$$Register, 32);
10208 %}
10209 ins_pipe(pipe_class_default);
10210 %}
10211
10212 instruct convF2LRaw_regF(regF dst, regF src) %{
10213 // no match-rule, false predicate
10214 effect(DEF dst, USE src);
10215 predicate(false);
10216
10217 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10218 size(4);
10219 ins_encode %{
10220 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10221 %}
10222 ins_pipe(pipe_class_default);
10223 %}
10224
10225 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
10226 // no match-rule, false predicate
10227 effect(DEF dst, USE crx, USE src);
10228 predicate(false);
10229
10230 ins_variable_size_depending_on_alignment(true);
10231
10232 format %{ "CMOVL $crx, $dst, $src" %}
10233 size(8);
10234 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10235 ins_pipe(pipe_class_default);
10236 %}
10237
10238 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
10239 // no match-rule, false predicate
10240 effect(DEF dst, USE crx, USE src);
10241 predicate(false);
10242
10243 ins_variable_size_depending_on_alignment(true);
10244
10245 format %{ "CMOVL $crx, $dst, $src" %}
10246 size(8);
10247 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10248 ins_pipe(pipe_class_default);
10249 %}
10250
10251
10252 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{
10253 // no match-rule, false predicate
10254 effect(DEF dst, USE crx, USE src);
10255 predicate(false);
10256
10257 format %{ "CMOVL $dst, $crx, $src \t// postalloc expanded" %}
10258 postalloc_expand %{
10259 //
10260 // replaces
10261 //
10262 // region dst crx src
10263 // \ | | /
10264 // dst=cmovL_bso_reg_conLvalue0
10265 //
10266 // with
10267 //
10268 // region dst
10269 // \ /
10270 // dst=loadConL16(0)
10271 // |
10272 // ^ region dst crx src
10273 // | \ | | /
10274 // dst=cmovL_bso_reg
10275 //
10276
10277 // Create new nodes.
10278 MachNode *m1 = new loadConL16Node();
10279 MachNode *m2 = new cmovL_bso_regNode();
10280
10281 // inputs for new nodes
10282 m1->add_req(n_region);
10283 m2->add_req(n_region, n_crx, n_src);
10284 m2->add_prec(m1);
10285
10286 // operands for new nodes
10287 m1->_opnds[0] = op_dst;
10288 m1->_opnds[1] = new immL16Oper(0);
10289 m2->_opnds[0] = op_dst;
10290 m2->_opnds[1] = op_crx;
10291 m2->_opnds[2] = op_src;
10292
10293 // registers for new nodes
10294 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10295 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10296
10297 // Insert new nodes.
10298 nodes->push(m1);
10299 nodes->push(m2);
10300 %}
10301 %}
10302
10303
10304 // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
10305 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
10306 match(Set dst (ConvF2L src));
10307 ins_cost(DEFAULT_COST);
10308
10309 expand %{
10310 regF tmpF;
10311 flagsReg crx;
10312 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10313 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
10314 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10315 %}
10316 %}
10317
10318 instruct convD2LRaw_regD(regD dst, regD src) %{
10319 // no match-rule, false predicate
10320 effect(DEF dst, USE src);
10321 predicate(false);
10322
10323 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
10324 size(4);
10325 ins_encode %{
10326 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10327 %}
10328 ins_pipe(pipe_class_default);
10329 %}
10330
10331
10332 // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
10333 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
10334 match(Set dst (ConvD2L src));
10335 ins_cost(DEFAULT_COST);
10336
10337 expand %{
10338 regD tmpD;
10339 flagsReg crx;
10340 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10341 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
10342 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10343 %}
10344 %}
10345
10346 // Convert to Float
10347
10348 // Placed here as needed in expand.
10349 instruct convL2DRaw_regD(regD dst, regD src) %{
10350 // no match-rule, false predicate
10351 effect(DEF dst, USE src);
10352 predicate(false);
10353
10354 format %{ "FCFID $dst, $src \t// convL2D" %}
10355 size(4);
10356 ins_encode %{
10357 __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
10358 %}
10359 ins_pipe(pipe_class_default);
10360 %}
10361
10362 // Placed here as needed in expand.
10363 instruct convD2F_reg(regF dst, regD src) %{
10364 match(Set dst (ConvD2F src));
10365 format %{ "FRSP $dst, $src \t// convD2F" %}
10366 size(4);
10367 ins_encode %{
10368 __ frsp($dst$$FloatRegister, $src$$FloatRegister);
10369 %}
10370 ins_pipe(pipe_class_default);
10371 %}
10372
10373 instruct convL2FRaw_regF(regF dst, regD src) %{
10374 // no match-rule, false predicate
10375 effect(DEF dst, USE src);
10376 predicate(false);
10377
10378 format %{ "FCFIDS $dst, $src \t// convL2F" %}
10379 size(4);
10380 ins_encode %{
10381 __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
10382 %}
10383 ins_pipe(pipe_class_default);
10384 %}
10385
10386
10387 // Integer to Float conversion. Special version for Power8.
10388 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
10389 match(Set dst (ConvI2F src));
10390 ins_cost(DEFAULT_COST);
10391
10392 expand %{
10393 regD tmpD;
10394 moveI2D_reg(tmpD, src);
10395 convL2FRaw_regF(dst, tmpD); // Convert to float.
10396 %}
10397 %}
10398
10399
10400 // L2F to avoid runtime call. Special version for Power8.
10401 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
10402 match(Set dst (ConvL2F src));
10403 ins_cost(DEFAULT_COST);
10404
10405 expand %{
10406 regD tmpD;
10407 moveL2D_reg(tmpD, src);
10408 convL2FRaw_regF(dst, tmpD); // Convert to float.
10409 %}
10410 %}
10411
10412 // Moved up as used in expand.
10413 //instruct convD2F_reg(regF dst, regD src) %{%}
10414
10415 // Convert to Double
10416
10417
10418 // Integer to Double conversion. Special version for Power8.
10419 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
10420 match(Set dst (ConvI2D src));
10421 ins_cost(DEFAULT_COST);
10422
10423 expand %{
10424 regD tmpD;
10425 moveI2D_reg(tmpD, src);
10426 convL2DRaw_regD(dst, tmpD); // Convert to double.
10427 %}
10428 %}
10429
10430
10431 // Long to Double conversion. Special version for Power8.
10432 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
10433 match(Set dst (ConvL2D src));
10434 ins_cost(DEFAULT_COST);
10435
10436 expand %{
10437 regD tmpD;
10438 moveL2D_reg(tmpD, src);
10439 convL2DRaw_regD(dst, tmpD); // Convert to double.
10440 %}
10441 %}
10442
10443 instruct convF2D_reg(regD dst, regF src) %{
10444 match(Set dst (ConvF2D src));
10445 format %{ "FMR $dst, $src \t// float->double" %}
10446 // variable size, 0 or 4
10447 ins_encode %{
10448 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
10449 %}
10450 ins_pipe(pipe_class_default);
10451 %}
10452
10453 instruct convF2HF_reg_reg(iRegIdst dst, regF src, regF tmp) %{
10454 match(Set dst (ConvF2HF src));
10455 effect(TEMP tmp);
10456 ins_cost(3 * DEFAULT_COST);
10457 size(12);
10458 format %{ "XSCVDPHP $tmp, $src\t# convert to half precision\n\t"
10459 "MFFPRD $dst, $tmp\t# move result from $tmp to $dst\n\t"
10460 "EXTSH $dst, $dst\t# make it a proper short"
10461 %}
10462 ins_encode %{
10463 __ f2hf($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
10464 %}
10465 ins_pipe(pipe_class_default);
10466 %}
10467
10468 instruct convHF2F_reg_reg(regF dst, iRegIsrc src) %{
10469 match(Set dst (ConvHF2F src));
10470 ins_cost(2 * DEFAULT_COST);
10471 size(8);
10472 format %{ "MTFPRD $dst, $src\t# move source from $src to $dst\n\t"
10473 "XSCVHPDP $dst, $dst\t# convert from half precision"
10474 %}
10475 ins_encode %{
10476 __ hf2f($dst$$FloatRegister, $src$$Register);
10477 %}
10478 ins_pipe(pipe_class_default);
10479 %}
10480
10481 //----------Control Flow Instructions------------------------------------------
10482 // Compare Instructions
10483
10484 // Compare Integers
10485 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10486 match(Set crx (CmpI src1 src2));
10487 size(4);
10488 format %{ "CMPW $crx, $src1, $src2" %}
10489 ins_encode %{
10490 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10491 %}
10492 ins_pipe(pipe_class_compare);
10493 %}
10494
10495 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
10496 match(Set crx (CmpI src1 src2));
10497 format %{ "CMPWI $crx, $src1, $src2" %}
10498 size(4);
10499 ins_encode %{
10500 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10501 %}
10502 ins_pipe(pipe_class_compare);
10503 %}
10504
10505 // (src1 & src2) == 0?
10506 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
10507 match(Set cr0 (CmpI (AndI src1 src2) zero));
10508 // r0 is killed
10509 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
10510 size(4);
10511 ins_encode %{
10512 __ andi_(R0, $src1$$Register, $src2$$constant);
10513 %}
10514 ins_pipe(pipe_class_compare);
10515 %}
10516
10517 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10518 match(Set crx (CmpL src1 src2));
10519 format %{ "CMPD $crx, $src1, $src2" %}
10520 size(4);
10521 ins_encode %{
10522 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
10523 %}
10524 ins_pipe(pipe_class_compare);
10525 %}
10526
10527 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
10528 match(Set crx (CmpL src1 src2));
10529 format %{ "CMPDI $crx, $src1, $src2" %}
10530 size(4);
10531 ins_encode %{
10532 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10533 %}
10534 ins_pipe(pipe_class_compare);
10535 %}
10536
10537 // Added CmpUL for LoopPredicate.
10538 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10539 match(Set crx (CmpUL src1 src2));
10540 format %{ "CMPLD $crx, $src1, $src2" %}
10541 size(4);
10542 ins_encode %{
10543 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10544 %}
10545 ins_pipe(pipe_class_compare);
10546 %}
10547
10548 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
10549 match(Set crx (CmpUL src1 src2));
10550 format %{ "CMPLDI $crx, $src1, $src2" %}
10551 size(4);
10552 ins_encode %{
10553 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10554 %}
10555 ins_pipe(pipe_class_compare);
10556 %}
10557
10558 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
10559 match(Set cr0 (CmpL (AndL src1 src2) zero));
10560 // r0 is killed
10561 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
10562 size(4);
10563 ins_encode %{
10564 __ and_(R0, $src1$$Register, $src2$$Register);
10565 %}
10566 ins_pipe(pipe_class_compare);
10567 %}
10568
10569 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
10570 match(Set cr0 (CmpL (AndL src1 src2) zero));
10571 // r0 is killed
10572 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
10573 size(4);
10574 ins_encode %{
10575 __ andi_(R0, $src1$$Register, $src2$$constant);
10576 %}
10577 ins_pipe(pipe_class_compare);
10578 %}
10579
10580 // Manifest a CmpL3 result in an integer register.
10581 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10582 match(Set dst (CmpL3 src1 src2));
10583 effect(KILL cr0);
10584 ins_cost(DEFAULT_COST * 5);
10585 size((VM_Version::has_brw() ? 16 : 20));
10586
10587 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %}
10588
10589 ins_encode %{
10590 __ cmpd(CR0, $src1$$Register, $src2$$Register);
10591 __ set_cmp3($dst$$Register);
10592 %}
10593 ins_pipe(pipe_class_default);
10594 %}
10595
10596 instruct cmpU3_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
10597 match(Set dst (CmpU3 src1 src2));
10598 effect(KILL cr0);
10599 ins_cost(DEFAULT_COST * 5);
10600 size((VM_Version::has_brw() ? 16 : 20));
10601
10602 format %{ "cmpU3_reg_reg $dst, $src1, $src2" %}
10603
10604 ins_encode %{
10605 __ cmplw(CR0, $src1$$Register, $src2$$Register);
10606 __ set_cmp3($dst$$Register);
10607 %}
10608 ins_pipe(pipe_class_default);
10609 %}
10610
10611 instruct cmpUL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10612 match(Set dst (CmpUL3 src1 src2));
10613 effect(KILL cr0);
10614 ins_cost(DEFAULT_COST * 5);
10615 size((VM_Version::has_brw() ? 16 : 20));
10616
10617 format %{ "cmpUL3_reg_reg $dst, $src1, $src2" %}
10618
10619 ins_encode %{
10620 __ cmpld(CR0, $src1$$Register, $src2$$Register);
10621 __ set_cmp3($dst$$Register);
10622 %}
10623 ins_pipe(pipe_class_default);
10624 %}
10625
10626 // Implicit range checks.
10627 // A range check in the ideal world has one of the following shapes:
10628 // - (If le (CmpU length index)), (IfTrue throw exception)
10629 // - (If lt (CmpU index length)), (IfFalse throw exception)
10630 //
10631 // Match range check 'If le (CmpU length index)'.
10632 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
10633 match(If cmp (CmpU src_length index));
10634 effect(USE labl);
10635 predicate(TrapBasedRangeChecks &&
10636 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
10637 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
10638 (Matcher::branches_to_uncommon_trap(_leaf)));
10639
10640 ins_is_TrapBasedCheckNode(true);
10641
10642 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %}
10643 size(4);
10644 ins_encode %{
10645 if ($cmp$$cmpcode == 0x1 /* less_equal */) {
10646 __ trap_range_check_le($src_length$$Register, $index$$constant);
10647 } else {
10648 // Both successors are uncommon traps, probability is 0.
10649 // Node got flipped during fixup flow.
10650 assert($cmp$$cmpcode == 0x9, "must be greater");
10651 __ trap_range_check_g($src_length$$Register, $index$$constant);
10652 }
10653 %}
10654 ins_pipe(pipe_class_trap);
10655 %}
10656
10657 // Match range check 'If lt (CmpU index length)'.
10658 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
10659 match(If cmp (CmpU src_index src_length));
10660 effect(USE labl);
10661 predicate(TrapBasedRangeChecks &&
10662 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10663 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10664 (Matcher::branches_to_uncommon_trap(_leaf)));
10665
10666 ins_is_TrapBasedCheckNode(true);
10667
10668 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
10669 size(4);
10670 ins_encode %{
10671 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10672 __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
10673 } else {
10674 // Both successors are uncommon traps, probability is 0.
10675 // Node got flipped during fixup flow.
10676 assert($cmp$$cmpcode == 0x8, "must be less");
10677 __ trap_range_check_l($src_index$$Register, $src_length$$Register);
10678 }
10679 %}
10680 ins_pipe(pipe_class_trap);
10681 %}
10682
10683 // Match range check 'If lt (CmpU index length)'.
10684 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
10685 match(If cmp (CmpU src_index length));
10686 effect(USE labl);
10687 predicate(TrapBasedRangeChecks &&
10688 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10689 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10690 (Matcher::branches_to_uncommon_trap(_leaf)));
10691
10692 ins_is_TrapBasedCheckNode(true);
10693
10694 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %}
10695 size(4);
10696 ins_encode %{
10697 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10698 __ trap_range_check_ge($src_index$$Register, $length$$constant);
10699 } else {
10700 // Both successors are uncommon traps, probability is 0.
10701 // Node got flipped during fixup flow.
10702 assert($cmp$$cmpcode == 0x8, "must be less");
10703 __ trap_range_check_l($src_index$$Register, $length$$constant);
10704 }
10705 %}
10706 ins_pipe(pipe_class_trap);
10707 %}
10708
10709 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10710 match(Set crx (CmpU src1 src2));
10711 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %}
10712 size(4);
10713 ins_encode %{
10714 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10715 %}
10716 ins_pipe(pipe_class_compare);
10717 %}
10718
10719 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
10720 match(Set crx (CmpU src1 src2));
10721 size(4);
10722 format %{ "CMPLWI $crx, $src1, $src2" %}
10723 ins_encode %{
10724 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10725 %}
10726 ins_pipe(pipe_class_compare);
10727 %}
10728
10729 // Implicit zero checks (more implicit null checks).
10730 // No constant pool entries required.
10731 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
10732 match(If cmp (CmpN value zero));
10733 effect(USE labl);
10734 predicate(TrapBasedNullChecks &&
10735 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10736 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10737 Matcher::branches_to_uncommon_trap(_leaf));
10738 ins_cost(1);
10739
10740 ins_is_TrapBasedCheckNode(true);
10741
10742 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
10743 size(4);
10744 ins_encode %{
10745 if ($cmp$$cmpcode == 0xA) {
10746 __ trap_null_check($value$$Register);
10747 } else {
10748 // Both successors are uncommon traps, probability is 0.
10749 // Node got flipped during fixup flow.
10750 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10751 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10752 }
10753 %}
10754 ins_pipe(pipe_class_trap);
10755 %}
10756
10757 // Compare narrow oops.
10758 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
10759 match(Set crx (CmpN src1 src2));
10760
10761 size(4);
10762 ins_cost(2);
10763 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %}
10764 ins_encode %{
10765 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10766 %}
10767 ins_pipe(pipe_class_compare);
10768 %}
10769
10770 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
10771 match(Set crx (CmpN src1 src2));
10772 // Make this more expensive than zeroCheckN_iReg_imm0.
10773 ins_cost(2);
10774
10775 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %}
10776 size(4);
10777 ins_encode %{
10778 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10779 %}
10780 ins_pipe(pipe_class_compare);
10781 %}
10782
10783 // Implicit zero checks (more implicit null checks).
10784 // No constant pool entries required.
10785 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
10786 match(If cmp (CmpP value zero));
10787 effect(USE labl);
10788 predicate(TrapBasedNullChecks &&
10789 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10790 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10791 Matcher::branches_to_uncommon_trap(_leaf));
10792 ins_cost(1); // Should not be cheaper than zeroCheckN.
10793
10794 ins_is_TrapBasedCheckNode(true);
10795
10796 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
10797 size(4);
10798 ins_encode %{
10799 if ($cmp$$cmpcode == 0xA) {
10800 __ trap_null_check($value$$Register);
10801 } else {
10802 // Both successors are uncommon traps, probability is 0.
10803 // Node got flipped during fixup flow.
10804 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10805 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10806 }
10807 %}
10808 ins_pipe(pipe_class_trap);
10809 %}
10810
10811 // Compare Pointers
10812 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
10813 match(Set crx (CmpP src1 src2));
10814 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %}
10815 size(4);
10816 ins_encode %{
10817 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10818 %}
10819 ins_pipe(pipe_class_compare);
10820 %}
10821
10822 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
10823 match(Set crx (CmpP src1 src2));
10824 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %}
10825 size(4);
10826 ins_encode %{
10827 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
10828 %}
10829 ins_pipe(pipe_class_compare);
10830 %}
10831
10832 // Used in postalloc expand.
10833 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
10834 // This match rule prevents reordering of node before a safepoint.
10835 // This only makes sense if this instructions is used exclusively
10836 // for the expansion of EncodeP!
10837 match(Set crx (CmpP src1 src2));
10838 predicate(false);
10839
10840 format %{ "CMPDI $crx, $src1, $src2" %}
10841 size(4);
10842 ins_encode %{
10843 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10844 %}
10845 ins_pipe(pipe_class_compare);
10846 %}
10847
10848 //----------Float Compares----------------------------------------------------
10849
10850 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
10851 // Needs matchrule, see cmpDUnordered.
10852 match(Set crx (CmpF src1 src2));
10853 // no match-rule, false predicate
10854 predicate(false);
10855
10856 format %{ "cmpFUrd $crx, $src1, $src2" %}
10857 size(4);
10858 ins_encode %{
10859 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10860 %}
10861 ins_pipe(pipe_class_default);
10862 %}
10863
10864 instruct cmov_bns_less(flagsReg crx) %{
10865 // no match-rule, false predicate
10866 effect(DEF crx);
10867 predicate(false);
10868
10869 ins_variable_size_depending_on_alignment(true);
10870
10871 format %{ "CMOV $crx" %}
10872 size(12);
10873 ins_encode %{
10874 Label done;
10875 __ bns($crx$$CondRegister, done); // not unordered -> keep crx
10876 __ li(R0, 0);
10877 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less'
10878 __ bind(done);
10879 %}
10880 ins_pipe(pipe_class_default);
10881 %}
10882
10883 // Compare floating, generate condition code.
10884 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{
10885 // FIXME: should we match 'If cmp (CmpF src1 src2))' ??
10886 //
10887 // The following code sequence occurs a lot in mpegaudio:
10888 //
10889 // block BXX:
10890 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0):
10891 // cmpFUrd CR6, F11, F9
10892 // 4: instruct cmov_bns_less (cmpF_reg_reg-1):
10893 // cmov CR6
10894 // 8: instruct branchConSched:
10895 // B_FARle CR6, B56 P=0.500000 C=-1.000000
10896 match(Set crx (CmpF src1 src2));
10897 ins_cost(DEFAULT_COST+BRANCH_COST);
10898
10899 format %{ "CMPF $crx, $src1, $src2 \t// postalloc expanded" %}
10900 postalloc_expand %{
10901 //
10902 // replaces
10903 //
10904 // region src1 src2
10905 // \ | |
10906 // crx=cmpF_reg_reg
10907 //
10908 // with
10909 //
10910 // region src1 src2
10911 // \ | |
10912 // crx=cmpFUnordered_reg_reg
10913 // |
10914 // ^ region
10915 // | \
10916 // crx=cmov_bns_less
10917 //
10918
10919 // Create new nodes.
10920 MachNode *m1 = new cmpFUnordered_reg_regNode();
10921 MachNode *m2 = new cmov_bns_lessNode();
10922
10923 // inputs for new nodes
10924 m1->add_req(n_region, n_src1, n_src2);
10925 m2->add_req(n_region);
10926 m2->add_prec(m1);
10927
10928 // operands for new nodes
10929 m1->_opnds[0] = op_crx;
10930 m1->_opnds[1] = op_src1;
10931 m1->_opnds[2] = op_src2;
10932 m2->_opnds[0] = op_crx;
10933
10934 // registers for new nodes
10935 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10936 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10937
10938 // Insert new nodes.
10939 nodes->push(m1);
10940 nodes->push(m2);
10941 %}
10942 %}
10943
10944 // Compare float, generate -1,0,1
10945 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{
10946 match(Set dst (CmpF3 src1 src2));
10947 effect(KILL cr0);
10948 ins_cost(DEFAULT_COST * 6);
10949 size((VM_Version::has_brw() ? 20 : 24));
10950
10951 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %}
10952
10953 ins_encode %{
10954 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
10955 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
10956 %}
10957 ins_pipe(pipe_class_default);
10958 %}
10959
10960 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
10961 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
10962 // node right before the conditional move using it.
10963 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
10964 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
10965 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
10966 // conditional move was supposed to be spilled.
10967 match(Set crx (CmpD src1 src2));
10968 // False predicate, shall not be matched.
10969 predicate(false);
10970
10971 format %{ "cmpFUrd $crx, $src1, $src2" %}
10972 size(4);
10973 ins_encode %{
10974 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10975 %}
10976 ins_pipe(pipe_class_default);
10977 %}
10978
10979 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{
10980 match(Set crx (CmpD src1 src2));
10981 ins_cost(DEFAULT_COST+BRANCH_COST);
10982
10983 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %}
10984 postalloc_expand %{
10985 //
10986 // replaces
10987 //
10988 // region src1 src2
10989 // \ | |
10990 // crx=cmpD_reg_reg
10991 //
10992 // with
10993 //
10994 // region src1 src2
10995 // \ | |
10996 // crx=cmpDUnordered_reg_reg
10997 // |
10998 // ^ region
10999 // | \
11000 // crx=cmov_bns_less
11001 //
11002
11003 // create new nodes
11004 MachNode *m1 = new cmpDUnordered_reg_regNode();
11005 MachNode *m2 = new cmov_bns_lessNode();
11006
11007 // inputs for new nodes
11008 m1->add_req(n_region, n_src1, n_src2);
11009 m2->add_req(n_region);
11010 m2->add_prec(m1);
11011
11012 // operands for new nodes
11013 m1->_opnds[0] = op_crx;
11014 m1->_opnds[1] = op_src1;
11015 m1->_opnds[2] = op_src2;
11016 m2->_opnds[0] = op_crx;
11017
11018 // registers for new nodes
11019 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11020 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11021
11022 // Insert new nodes.
11023 nodes->push(m1);
11024 nodes->push(m2);
11025 %}
11026 %}
11027
11028 // Compare double, generate -1,0,1
11029 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{
11030 match(Set dst (CmpD3 src1 src2));
11031 effect(KILL cr0);
11032 ins_cost(DEFAULT_COST * 6);
11033 size((VM_Version::has_brw() ? 20 : 24));
11034
11035 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %}
11036
11037 ins_encode %{
11038 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
11039 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11040 %}
11041 ins_pipe(pipe_class_default);
11042 %}
11043
11044 // Compare char
11045 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11046 match(Set dst (Digit src1));
11047 effect(TEMP src2, TEMP crx);
11048 ins_cost(3 * DEFAULT_COST);
11049
11050 format %{ "LI $src2, 0x3930\n\t"
11051 "CMPRB $crx, 0, $src1, $src2\n\t"
11052 "SETB $dst, $crx" %}
11053 size(12);
11054 ins_encode %{
11055 // 0x30: 0, 0x39: 9
11056 __ li($src2$$Register, 0x3930);
11057 // compare src1 with ranges 0x30 to 0x39
11058 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11059 __ setb($dst$$Register, $crx$$CondRegister);
11060 %}
11061 ins_pipe(pipe_class_default);
11062 %}
11063
11064 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11065 match(Set dst (LowerCase src1));
11066 effect(TEMP src2, TEMP crx);
11067 ins_cost(12 * DEFAULT_COST);
11068
11069 format %{ "LI $src2, 0x7A61\n\t"
11070 "CMPRB $crx, 0, $src1, $src2\n\t"
11071 "BGT $crx, done\n\t"
11072 "LIS $src2, (signed short)0xF6DF\n\t"
11073 "ORI $src2, $src2, 0xFFF8\n\t"
11074 "CMPRB $crx, 1, $src1, $src2\n\t"
11075 "BGT $crx, done\n\t"
11076 "LIS $src2, (signed short)0xAAB5\n\t"
11077 "ORI $src2, $src2, 0xBABA\n\t"
11078 "INSRDI $src2, $src2, 32, 0\n\t"
11079 "CMPEQB $crx, 1, $src1, $src2\n"
11080 "done:\n\t"
11081 "SETB $dst, $crx" %}
11082
11083 size(48);
11084 ins_encode %{
11085 Label done;
11086 // 0x61: a, 0x7A: z
11087 __ li($src2$$Register, 0x7A61);
11088 // compare src1 with ranges 0x61 to 0x7A
11089 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11090 __ bgt($crx$$CondRegister, done);
11091
11092 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
11093 __ lis($src2$$Register, (signed short)0xF6DF);
11094 __ ori($src2$$Register, $src2$$Register, 0xFFF8);
11095 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
11096 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11097 __ bgt($crx$$CondRegister, done);
11098
11099 // 0xAA: feminine ordinal indicator
11100 // 0xB5: micro sign
11101 // 0xBA: masculine ordinal indicator
11102 __ lis($src2$$Register, (signed short)0xAAB5);
11103 __ ori($src2$$Register, $src2$$Register, 0xBABA);
11104 __ insrdi($src2$$Register, $src2$$Register, 32, 0);
11105 // compare src1 with 0xAA, 0xB5, and 0xBA
11106 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
11107
11108 __ bind(done);
11109 __ setb($dst$$Register, $crx$$CondRegister);
11110 %}
11111 ins_pipe(pipe_class_default);
11112 %}
11113
11114 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11115 match(Set dst (UpperCase src1));
11116 effect(TEMP src2, TEMP crx);
11117 ins_cost(7 * DEFAULT_COST);
11118
11119 format %{ "LI $src2, 0x5A41\n\t"
11120 "CMPRB $crx, 0, $src1, $src2\n\t"
11121 "BGT $crx, done\n\t"
11122 "LIS $src2, (signed short)0xD6C0\n\t"
11123 "ORI $src2, $src2, 0xDED8\n\t"
11124 "CMPRB $crx, 1, $src1, $src2\n"
11125 "done:\n\t"
11126 "SETB $dst, $crx" %}
11127
11128 size(28);
11129 ins_encode %{
11130 Label done;
11131 // 0x41: A, 0x5A: Z
11132 __ li($src2$$Register, 0x5A41);
11133 // compare src1 with a range 0x41 to 0x5A
11134 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11135 __ bgt($crx$$CondRegister, done);
11136
11137 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
11138 __ lis($src2$$Register, (signed short)0xD6C0);
11139 __ ori($src2$$Register, $src2$$Register, 0xDED8);
11140 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
11141 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11142
11143 __ bind(done);
11144 __ setb($dst$$Register, $crx$$CondRegister);
11145 %}
11146 ins_pipe(pipe_class_default);
11147 %}
11148
11149 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11150 match(Set dst (Whitespace src1));
11151 predicate(PowerArchitecturePPC64 <= 9);
11152 effect(TEMP src2, TEMP crx);
11153 ins_cost(4 * DEFAULT_COST);
11154
11155 format %{ "LI $src2, 0x0D09\n\t"
11156 "ADDIS $src2, 0x201C\n\t"
11157 "CMPRB $crx, 1, $src1, $src2\n\t"
11158 "SETB $dst, $crx" %}
11159 size(16);
11160 ins_encode %{
11161 // 0x09 to 0x0D, 0x1C to 0x20
11162 __ li($src2$$Register, 0x0D09);
11163 __ addis($src2$$Register, $src2$$Register, 0x0201C);
11164 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11165 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11166 __ setb($dst$$Register, $crx$$CondRegister);
11167 %}
11168 ins_pipe(pipe_class_default);
11169 %}
11170
11171 // Power 10 version, using prefixed addi to load 32-bit constant
11172 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11173 match(Set dst (Whitespace src1));
11174 predicate(PowerArchitecturePPC64 >= 10);
11175 effect(TEMP src2, TEMP crx);
11176 ins_cost(3 * DEFAULT_COST);
11177
11178 format %{ "PLI $src2, 0x201C0D09\n\t"
11179 "CMPRB $crx, 1, $src1, $src2\n\t"
11180 "SETB $dst, $crx" %}
11181 size(16);
11182 ins_encode %{
11183 // 0x09 to 0x0D, 0x1C to 0x20
11184 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
11185 __ pli($src2$$Register, 0x201C0D09);
11186 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11187 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11188 __ setb($dst$$Register, $crx$$CondRegister);
11189 %}
11190 ins_pipe(pipe_class_default);
11191 ins_alignment(2);
11192 %}
11193
11194 //----------Branches---------------------------------------------------------
11195 // Jump
11196
11197 // Direct Branch.
11198 instruct branch(label labl) %{
11199 match(Goto);
11200 effect(USE labl);
11201 ins_cost(BRANCH_COST);
11202
11203 format %{ "B $labl" %}
11204 size(4);
11205 ins_encode %{
11206 Label d; // dummy
11207 __ bind(d);
11208 Label* p = $labl$$label;
11209 // `p' is `nullptr' when this encoding class is used only to
11210 // determine the size of the encoded instruction.
11211 Label& l = (nullptr == p)? d : *(p);
11212 __ b(l);
11213 %}
11214 ins_pipe(pipe_class_default);
11215 %}
11216
11217 // Conditional Near Branch
11218 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11219 // Same match rule as `branchConFar'.
11220 match(If cmp crx);
11221 effect(USE lbl);
11222 ins_cost(BRANCH_COST);
11223
11224 // If set to 1 this indicates that the current instruction is a
11225 // short variant of a long branch. This avoids using this
11226 // instruction in first-pass matching. It will then only be used in
11227 // the `Shorten_branches' pass.
11228 ins_short_branch(1);
11229
11230 format %{ "B$cmp $crx, $lbl" %}
11231 size(4);
11232 ins_encode( enc_bc(crx, cmp, lbl) );
11233 ins_pipe(pipe_class_default);
11234 %}
11235
11236 // This is for cases when the ppc64 `bc' instruction does not
11237 // reach far enough. So we emit a far branch here, which is more
11238 // expensive.
11239 //
11240 // Conditional Far Branch
11241 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11242 // Same match rule as `branchCon'.
11243 match(If cmp crx);
11244 effect(USE crx, USE lbl);
11245 // Higher cost than `branchCon'.
11246 ins_cost(5*BRANCH_COST);
11247
11248 // This is not a short variant of a branch, but the long variant.
11249 ins_short_branch(0);
11250
11251 format %{ "B_FAR$cmp $crx, $lbl" %}
11252 size(8);
11253 ins_encode( enc_bc_far(crx, cmp, lbl) );
11254 ins_pipe(pipe_class_default);
11255 %}
11256
11257 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
11258 match(CountedLoopEnd cmp crx);
11259 effect(USE labl);
11260 ins_cost(BRANCH_COST);
11261
11262 // short variant.
11263 ins_short_branch(1);
11264
11265 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
11266 size(4);
11267 ins_encode( enc_bc(crx, cmp, labl) );
11268 ins_pipe(pipe_class_default);
11269 %}
11270
11271 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
11272 match(CountedLoopEnd cmp crx);
11273 effect(USE labl);
11274 ins_cost(BRANCH_COST);
11275
11276 // Long variant.
11277 ins_short_branch(0);
11278
11279 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
11280 size(8);
11281 ins_encode( enc_bc_far(crx, cmp, labl) );
11282 ins_pipe(pipe_class_default);
11283 %}
11284
11285 // ============================================================================
11286 // Java runtime operations, intrinsics and other complex operations.
11287
11288 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
11289 // array for an instance of the superklass. Set a hidden internal cache on a
11290 // hit (cache is checked with exposed code in gen_subtype_check()). Return
11291 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
11292 //
11293 // GL TODO: Improve this.
11294 // - result should not be a TEMP
11295 // - Add match rule as on sparc avoiding additional Cmp.
11296 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
11297 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
11298 match(Set result (PartialSubtypeCheck subklass superklass));
11299 predicate(!UseSecondarySupersTable);
11300 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
11301 ins_cost(DEFAULT_COST*10);
11302
11303 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
11304 ins_encode %{
11305 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
11306 $tmp_klass$$Register, nullptr, $result$$Register);
11307 %}
11308 ins_pipe(pipe_class_default);
11309 %}
11310
11311 // Two versions of partialSubtypeCheck, both used when we need to
11312 // search for a super class in the secondary supers array. The first
11313 // is used when we don't know _a priori_ the class being searched
11314 // for. The second, far more common, is used when we do know: this is
11315 // used for instanceof, checkcast, and any case where C2 can determine
11316 // it by constant propagation.
11317 instruct partialSubtypeCheckVarSuper(iRegPsrc sub, iRegPsrc super, iRegPdst result,
11318 iRegPdst tempR1, iRegPdst tempR2, iRegPdst tempR3, iRegPdst tempR4,
11319 flagsRegCR0 cr0, regCTR ctr)
11320 %{
11321 match(Set result (PartialSubtypeCheck sub super));
11322 predicate(UseSecondarySupersTable);
11323 effect(KILL cr0, KILL ctr, TEMP_DEF result, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11324
11325 ins_cost(DEFAULT_COST * 10); // slightly larger than the next version
11326 format %{ "partialSubtypeCheck $result, $sub, $super" %}
11327 ins_encode %{
11328 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register,
11329 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11330 $result$$Register);
11331 %}
11332 ins_pipe(pipe_class_memory);
11333 %}
11334
11335 instruct partialSubtypeCheckConstSuper(rarg3RegP sub, rarg2RegP super_reg, immP super_con, rarg6RegP result,
11336 rarg1RegP tempR1, rarg5RegP tempR2, rarg4RegP tempR3, rscratch1RegP tempR4,
11337 flagsRegCR0 cr0, regCTR ctr)
11338 %{
11339 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
11340 predicate(UseSecondarySupersTable);
11341 effect(KILL cr0, KILL ctr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11342
11343 ins_cost(DEFAULT_COST*8); // smaller than the other version
11344 format %{ "partialSubtypeCheck $result, $sub, $super_reg" %}
11345
11346 ins_encode %{
11347 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
11348 if (InlineSecondarySupersTest) {
11349 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register,
11350 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11351 $result$$Register, super_klass_slot);
11352 } else {
11353 address stub = StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot);
11354 Register r_stub_addr = $tempR1$$Register;
11355 __ add_const_optimized(r_stub_addr, R29_TOC, MacroAssembler::offset_to_global_toc(stub), R0);
11356 __ mtctr(r_stub_addr);
11357 __ bctrl();
11358 }
11359 %}
11360
11361 ins_pipe(pipe_class_memory);
11362 %}
11363
11364 // inlined locking and unlocking
11365
11366 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
11367 predicate(!UseObjectMonitorTable);
11368 match(Set crx (FastLock oop box));
11369 effect(TEMP tmp1, TEMP tmp2);
11370
11371 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %}
11372 ins_encode %{
11373 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11374 $tmp1$$Register, $tmp2$$Register, noreg /*tmp3*/);
11375 // If locking was successful, crx should indicate 'EQ'.
11376 // The compiler generates a branch to the runtime call to
11377 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11378 %}
11379 ins_pipe(pipe_class_compare);
11380 %}
11381
11382 instruct cmpFastLockMonitorTable(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, flagsRegCR1 cr1) %{
11383 predicate(UseObjectMonitorTable);
11384 match(Set crx (FastLock oop box));
11385 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr1);
11386
11387 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3" %}
11388 ins_encode %{
11389 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11390 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11391 // If locking was successful, crx should indicate 'EQ'.
11392 // The compiler generates a branch to the runtime call to
11393 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11394 %}
11395 ins_pipe(pipe_class_compare);
11396 %}
11397
11398 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11399 match(Set crx (FastUnlock oop box));
11400 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11401
11402 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
11403 ins_encode %{
11404 __ fast_unlock($crx$$CondRegister, $oop$$Register, $box$$Register,
11405 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11406 // If unlocking was successful, crx should indicate 'EQ'.
11407 // The compiler generates a branch to the runtime call to
11408 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11409 %}
11410 ins_pipe(pipe_class_compare);
11411 %}
11412
11413 // Align address.
11414 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11415 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11416
11417 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
11418 size(4);
11419 ins_encode %{
11420 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant));
11421 %}
11422 ins_pipe(pipe_class_default);
11423 %}
11424
11425 // Array size computation.
11426 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11427 match(Set dst (SubL (CastP2X end) (CastP2X start)));
11428
11429 format %{ "SUB $dst, $end, $start \t// array size in bytes" %}
11430 size(4);
11431 ins_encode %{
11432 __ subf($dst$$Register, $start$$Register, $end$$Register);
11433 %}
11434 ins_pipe(pipe_class_default);
11435 %}
11436
11437 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
11438 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, immL_0 zero, Universe dummy, regCTR ctr) %{
11439 match(Set dummy (ClearArray (Binary cnt base) zero));
11440 effect(USE_KILL base, KILL ctr);
11441 ins_cost(2 * MEMORY_REF_COST);
11442
11443 format %{ "ClearArray $cnt, $base" %}
11444 ins_encode %{
11445 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
11446 %}
11447 ins_pipe(pipe_class_default);
11448 %}
11449
11450 // Clear-array with constant large array length.
11451 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, immL_0 zero, Universe dummy, iRegLdst tmp, regCTR ctr) %{
11452 match(Set dummy (ClearArray (Binary cnt base) zero));
11453 effect(USE_KILL base, TEMP tmp, KILL ctr);
11454 ins_cost(3 * MEMORY_REF_COST);
11455
11456 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
11457 ins_encode %{
11458 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
11459 %}
11460 ins_pipe(pipe_class_default);
11461 %}
11462
11463 // Clear-array with dynamic array length.
11464 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, immL_0 zero, Universe dummy, regCTR ctr) %{
11465 match(Set dummy (ClearArray (Binary cnt base) zero));
11466 effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11467 ins_cost(4 * MEMORY_REF_COST);
11468
11469 format %{ "ClearArray $cnt, $base" %}
11470 ins_encode %{
11471 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
11472 %}
11473 ins_pipe(pipe_class_default);
11474 %}
11475
11476 // Clear-array with dynamic array length and non-zero value.
11477 instruct inlineCallClearArrayWordCopy(rarg1RegL cnt, rarg2RegP base, iRegLdst val, Universe dummy, regCTR ctr) %{
11478 predicate(((ClearArrayNode*)n)->word_copy_only());
11479 match(Set dummy (ClearArray (Binary cnt base) val));
11480 effect(USE_KILL base, KILL ctr);
11481 ins_cost(8 * MEMORY_REF_COST);
11482
11483 format %{ "ClearArray $cnt, $base, $val" %}
11484 ins_encode %{
11485 __ fill_words($base$$Register, $cnt$$Register, $val$$Register);
11486 %}
11487 ins_pipe(pipe_class_default);
11488 %}
11489
11490 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11491 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11492 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11493 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11494 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11495 ins_cost(300);
11496 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11497 ins_encode %{
11498 __ string_compare($str1$$Register, $str2$$Register,
11499 $cnt1$$Register, $cnt2$$Register,
11500 $tmp$$Register,
11501 $result$$Register, StrIntrinsicNode::LL);
11502 %}
11503 ins_pipe(pipe_class_default);
11504 %}
11505
11506 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11507 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11508 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11509 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11510 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11511 ins_cost(300);
11512 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11513 ins_encode %{
11514 __ string_compare($str1$$Register, $str2$$Register,
11515 $cnt1$$Register, $cnt2$$Register,
11516 $tmp$$Register,
11517 $result$$Register, StrIntrinsicNode::UU);
11518 %}
11519 ins_pipe(pipe_class_default);
11520 %}
11521
11522 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11523 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11524 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11525 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11526 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11527 ins_cost(300);
11528 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11529 ins_encode %{
11530 __ string_compare($str1$$Register, $str2$$Register,
11531 $cnt1$$Register, $cnt2$$Register,
11532 $tmp$$Register,
11533 $result$$Register, StrIntrinsicNode::LU);
11534 %}
11535 ins_pipe(pipe_class_default);
11536 %}
11537
11538 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11539 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11540 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11541 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11542 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11543 ins_cost(300);
11544 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11545 ins_encode %{
11546 __ string_compare($str2$$Register, $str1$$Register,
11547 $cnt2$$Register, $cnt1$$Register,
11548 $tmp$$Register,
11549 $result$$Register, StrIntrinsicNode::UL);
11550 %}
11551 ins_pipe(pipe_class_default);
11552 %}
11553
11554 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11555 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11556 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11557 match(Set result (StrEquals (Binary str1 str2) cnt));
11558 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11559 ins_cost(300);
11560 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11561 ins_encode %{
11562 __ array_equals(false, $str1$$Register, $str2$$Register,
11563 $cnt$$Register, $tmp$$Register,
11564 $result$$Register, true /* byte */);
11565 %}
11566 ins_pipe(pipe_class_default);
11567 %}
11568
11569 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11570 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11571 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11572 match(Set result (AryEq ary1 ary2));
11573 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11574 ins_cost(300);
11575 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11576 ins_encode %{
11577 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11578 $tmp1$$Register, $tmp2$$Register,
11579 $result$$Register, true /* byte */);
11580 %}
11581 ins_pipe(pipe_class_default);
11582 %}
11583
11584 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11585 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11586 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11587 match(Set result (AryEq ary1 ary2));
11588 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11589 ins_cost(300);
11590 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11591 ins_encode %{
11592 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11593 $tmp1$$Register, $tmp2$$Register,
11594 $result$$Register, false /* byte */);
11595 %}
11596 ins_pipe(pipe_class_default);
11597 %}
11598
11599 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11600 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11601 iRegIdst tmp1, iRegIdst tmp2,
11602 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11603 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11604 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11605 // Required for EA: check if it is still a type_array.
11606 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11607 ins_cost(150);
11608
11609 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11610 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11611
11612 ins_encode %{
11613 immPOper *needleOper = (immPOper *)$needleImm;
11614 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11615 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11616 jchar chr;
11617 #ifdef VM_LITTLE_ENDIAN
11618 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11619 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11620 #else
11621 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11622 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11623 #endif
11624 __ string_indexof_char($result$$Register,
11625 $haystack$$Register, $haycnt$$Register,
11626 R0, chr,
11627 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11628 %}
11629 ins_pipe(pipe_class_compare);
11630 %}
11631
11632 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11633 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11634 iRegIdst tmp1, iRegIdst tmp2,
11635 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11636 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11637 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11638 // Required for EA: check if it is still a type_array.
11639 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11640 ins_cost(150);
11641
11642 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11643 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11644
11645 ins_encode %{
11646 immPOper *needleOper = (immPOper *)$needleImm;
11647 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11648 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11649 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11650 __ string_indexof_char($result$$Register,
11651 $haystack$$Register, $haycnt$$Register,
11652 R0, chr,
11653 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11654 %}
11655 ins_pipe(pipe_class_compare);
11656 %}
11657
11658 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11659 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11660 iRegIdst tmp1, iRegIdst tmp2,
11661 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11662 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11663 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11664 // Required for EA: check if it is still a type_array.
11665 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11666 ins_cost(150);
11667
11668 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11669 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11670
11671 ins_encode %{
11672 immPOper *needleOper = (immPOper *)$needleImm;
11673 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11674 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11675 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11676 __ string_indexof_char($result$$Register,
11677 $haystack$$Register, $haycnt$$Register,
11678 R0, chr,
11679 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11680 %}
11681 ins_pipe(pipe_class_compare);
11682 %}
11683
11684 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11685 rscratch2RegP needle, immI_1 needlecntImm,
11686 iRegIdst tmp1, iRegIdst tmp2,
11687 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11688 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11689 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11690 // Required for EA: check if it is still a type_array.
11691 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11692 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11693 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11694 ins_cost(180);
11695
11696 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11697 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11698 ins_encode %{
11699 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11700 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11701 guarantee(needle_values, "sanity");
11702 jchar chr;
11703 #ifdef VM_LITTLE_ENDIAN
11704 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11705 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11706 #else
11707 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11708 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11709 #endif
11710 __ string_indexof_char($result$$Register,
11711 $haystack$$Register, $haycnt$$Register,
11712 R0, chr,
11713 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11714 %}
11715 ins_pipe(pipe_class_compare);
11716 %}
11717
11718 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11719 rscratch2RegP needle, immI_1 needlecntImm,
11720 iRegIdst tmp1, iRegIdst tmp2,
11721 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11722 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11723 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11724 // Required for EA: check if it is still a type_array.
11725 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11726 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11727 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11728 ins_cost(180);
11729
11730 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11731 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11732 ins_encode %{
11733 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11734 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11735 guarantee(needle_values, "sanity");
11736 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11737 __ string_indexof_char($result$$Register,
11738 $haystack$$Register, $haycnt$$Register,
11739 R0, chr,
11740 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11741 %}
11742 ins_pipe(pipe_class_compare);
11743 %}
11744
11745 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11746 rscratch2RegP needle, immI_1 needlecntImm,
11747 iRegIdst tmp1, iRegIdst tmp2,
11748 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11749 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11750 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11751 // Required for EA: check if it is still a type_array.
11752 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11753 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11754 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11755 ins_cost(180);
11756
11757 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11758 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11759 ins_encode %{
11760 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11761 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11762 guarantee(needle_values, "sanity");
11763 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11764 __ string_indexof_char($result$$Register,
11765 $haystack$$Register, $haycnt$$Register,
11766 R0, chr,
11767 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11768 %}
11769 ins_pipe(pipe_class_compare);
11770 %}
11771
11772 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11773 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11774 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11775 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11776 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11777 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
11778 ins_cost(180);
11779
11780 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch"
11781 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11782 ins_encode %{
11783 __ string_indexof_char($result$$Register,
11784 $haystack$$Register, $haycnt$$Register,
11785 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11786 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11787 %}
11788 ins_pipe(pipe_class_compare);
11789 %}
11790
11791 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11792 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11793 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11794 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11795 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11796 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
11797 ins_cost(180);
11798
11799 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch"
11800 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11801 ins_encode %{
11802 __ string_indexof_char($result$$Register,
11803 $haystack$$Register, $haycnt$$Register,
11804 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11805 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11806 %}
11807 ins_pipe(pipe_class_compare);
11808 %}
11809
11810 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11811 iRegPsrc needle, uimmI15 needlecntImm,
11812 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11813 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11814 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11815 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11816 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11817 // Required for EA: check if it is still a type_array.
11818 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11819 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11820 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11821 ins_cost(250);
11822
11823 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11824 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11825 ins_encode %{
11826 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11827 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11828
11829 __ string_indexof($result$$Register,
11830 $haystack$$Register, $haycnt$$Register,
11831 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11832 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11833 %}
11834 ins_pipe(pipe_class_compare);
11835 %}
11836
11837 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11838 iRegPsrc needle, uimmI15 needlecntImm,
11839 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11840 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11841 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11842 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11843 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11844 // Required for EA: check if it is still a type_array.
11845 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11846 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11847 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11848 ins_cost(250);
11849
11850 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11851 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11852 ins_encode %{
11853 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11854 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11855
11856 __ string_indexof($result$$Register,
11857 $haystack$$Register, $haycnt$$Register,
11858 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11859 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11860 %}
11861 ins_pipe(pipe_class_compare);
11862 %}
11863
11864 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11865 iRegPsrc needle, uimmI15 needlecntImm,
11866 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11867 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11868 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11869 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11870 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11871 // Required for EA: check if it is still a type_array.
11872 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11873 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11874 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11875 ins_cost(250);
11876
11877 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11878 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11879 ins_encode %{
11880 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11881 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11882
11883 __ string_indexof($result$$Register,
11884 $haystack$$Register, $haycnt$$Register,
11885 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11886 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11887 %}
11888 ins_pipe(pipe_class_compare);
11889 %}
11890
11891 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11892 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11893 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11894 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11895 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11896 TEMP_DEF result,
11897 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11898 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11899 ins_cost(300);
11900
11901 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11902 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11903 ins_encode %{
11904 __ string_indexof($result$$Register,
11905 $haystack$$Register, $haycnt$$Register,
11906 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11907 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11908 %}
11909 ins_pipe(pipe_class_compare);
11910 %}
11911
11912 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11913 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11914 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11915 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11916 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11917 TEMP_DEF result,
11918 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11919 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11920 ins_cost(300);
11921
11922 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11923 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11924 ins_encode %{
11925 __ string_indexof($result$$Register,
11926 $haystack$$Register, $haycnt$$Register,
11927 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11928 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11929 %}
11930 ins_pipe(pipe_class_compare);
11931 %}
11932
11933 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11934 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11935 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11936 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11937 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11938 TEMP_DEF result,
11939 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11940 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11941 ins_cost(300);
11942
11943 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11944 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11945 ins_encode %{
11946 __ string_indexof($result$$Register,
11947 $haystack$$Register, $haycnt$$Register,
11948 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11949 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11950 %}
11951 ins_pipe(pipe_class_compare);
11952 %}
11953
11954 // char[] to byte[] compression
11955 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11956 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11957 match(Set result (StrCompressedCopy src (Binary dst len)));
11958 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11959 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11960 ins_cost(300);
11961 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11962 ins_encode %{
11963 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11964 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11965 %}
11966 ins_pipe(pipe_class_default);
11967 %}
11968
11969 // byte[] to char[] inflation
11970 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
11971 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11972 match(Set dummy (StrInflatedCopy src (Binary dst len)));
11973 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11974 ins_cost(300);
11975 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11976 ins_encode %{
11977 Label Ldone;
11978 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
11979 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11980 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
11981 __ beq(CR0, Ldone);
11982 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
11983 __ bind(Ldone);
11984 %}
11985 ins_pipe(pipe_class_default);
11986 %}
11987
11988 // StringCoding.java intrinsics
11989 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
11990 regCTR ctr, flagsRegCR0 cr0)
11991 %{
11992 match(Set result (CountPositives ary1 len));
11993 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
11994 ins_cost(300);
11995 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
11996 ins_encode %{
11997 __ count_positives($ary1$$Register, $len$$Register, $result$$Register,
11998 $tmp1$$Register, $tmp2$$Register);
11999 %}
12000 ins_pipe(pipe_class_default);
12001 %}
12002
12003 // encode char[] to byte[] in ISO_8859_1
12004 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12005 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12006 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
12007 match(Set result (EncodeISOArray src (Binary dst len)));
12008 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12009 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12010 ins_cost(300);
12011 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12012 ins_encode %{
12013 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12014 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
12015 %}
12016 ins_pipe(pipe_class_default);
12017 %}
12018
12019 // encode char[] to byte[] in ASCII
12020 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12021 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12022 predicate(((EncodeISOArrayNode*)n)->is_ascii());
12023 match(Set result (EncodeISOArray src (Binary dst len)));
12024 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12025 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12026 ins_cost(300);
12027 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12028 ins_encode %{
12029 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12030 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
12031 %}
12032 ins_pipe(pipe_class_default);
12033 %}
12034
12035
12036 //---------- Min/Max Instructions ---------------------------------------------
12037
12038
12039 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12040 match(Set dst (MinI src1 src2));
12041 effect(KILL cr0);
12042 ins_cost(DEFAULT_COST*2);
12043
12044 size(8);
12045 ins_encode %{
12046 __ cmpw(CR0, $src1$$Register, $src2$$Register);
12047 __ isel($dst$$Register, CR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
12048 %}
12049 ins_pipe(pipe_class_default);
12050 %}
12051
12052
12053 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12054 match(Set dst (MaxI src1 src2));
12055 effect(KILL cr0);
12056 ins_cost(DEFAULT_COST*2);
12057
12058 size(8);
12059 ins_encode %{
12060 __ cmpw(CR0, $src1$$Register, $src2$$Register);
12061 __ isel($dst$$Register, CR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
12062 %}
12063 ins_pipe(pipe_class_default);
12064 %}
12065
12066 instruct minF(regF dst, regF src1, regF src2) %{
12067 match(Set dst (MinF src1 src2));
12068 predicate(PowerArchitecturePPC64 >= 9);
12069 ins_cost(DEFAULT_COST);
12070
12071 format %{ "XSMINJDP $dst, $src1, $src2\t// MinF" %}
12072 size(4);
12073 ins_encode %{
12074 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12075 %}
12076 ins_pipe(pipe_class_default);
12077 %}
12078
12079 instruct minD(regD dst, regD src1, regD src2) %{
12080 match(Set dst (MinD src1 src2));
12081 predicate(PowerArchitecturePPC64 >= 9);
12082 ins_cost(DEFAULT_COST);
12083
12084 format %{ "XSMINJDP $dst, $src1, $src2\t// MinD" %}
12085 size(4);
12086 ins_encode %{
12087 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12088 %}
12089 ins_pipe(pipe_class_default);
12090 %}
12091
12092 instruct maxF(regF dst, regF src1, regF src2) %{
12093 match(Set dst (MaxF src1 src2));
12094 predicate(PowerArchitecturePPC64 >= 9);
12095 ins_cost(DEFAULT_COST);
12096
12097 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxF" %}
12098 size(4);
12099 ins_encode %{
12100 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12101 %}
12102 ins_pipe(pipe_class_default);
12103 %}
12104
12105 instruct maxD(regD dst, regD src1, regD src2) %{
12106 match(Set dst (MaxD src1 src2));
12107 predicate(PowerArchitecturePPC64 >= 9);
12108 ins_cost(DEFAULT_COST);
12109
12110 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxD" %}
12111 size(4);
12112 ins_encode %{
12113 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12114 %}
12115 ins_pipe(pipe_class_default);
12116 %}
12117
12118 //---------- Population Count Instructions ------------------------------------
12119
12120 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
12121 match(Set dst (PopCountI src));
12122 predicate(UsePopCountInstruction);
12123 ins_cost(DEFAULT_COST);
12124
12125 format %{ "POPCNTW $dst, $src" %}
12126 size(4);
12127 ins_encode %{
12128 __ popcntw($dst$$Register, $src$$Register);
12129 %}
12130 ins_pipe(pipe_class_default);
12131 %}
12132
12133 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
12134 predicate(UsePopCountInstruction);
12135 match(Set dst (PopCountL src));
12136 ins_cost(DEFAULT_COST);
12137
12138 format %{ "POPCNTD $dst, $src" %}
12139 size(4);
12140 ins_encode %{
12141 __ popcntd($dst$$Register, $src$$Register);
12142 %}
12143 ins_pipe(pipe_class_default);
12144 %}
12145
12146 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
12147 match(Set dst (CountLeadingZerosI src));
12148 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12149 ins_cost(DEFAULT_COST);
12150
12151 format %{ "CNTLZW $dst, $src" %}
12152 size(4);
12153 ins_encode %{
12154 __ cntlzw($dst$$Register, $src$$Register);
12155 %}
12156 ins_pipe(pipe_class_default);
12157 %}
12158
12159 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
12160 match(Set dst (CountLeadingZerosL src));
12161 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12162 ins_cost(DEFAULT_COST);
12163
12164 format %{ "CNTLZD $dst, $src" %}
12165 size(4);
12166 ins_encode %{
12167 __ cntlzd($dst$$Register, $src$$Register);
12168 %}
12169 ins_pipe(pipe_class_default);
12170 %}
12171
12172 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
12173 // no match-rule, false predicate
12174 effect(DEF dst, USE src);
12175 predicate(false);
12176
12177 format %{ "CNTLZD $dst, $src" %}
12178 size(4);
12179 ins_encode %{
12180 __ cntlzd($dst$$Register, $src$$Register);
12181 %}
12182 ins_pipe(pipe_class_default);
12183 %}
12184
12185 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
12186 match(Set dst (CountTrailingZerosI src));
12187 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12188 ins_cost(DEFAULT_COST);
12189
12190 expand %{
12191 immI16 imm1 %{ (int)-1 %}
12192 immI16 imm2 %{ (int)32 %}
12193 immI_minus1 m1 %{ -1 %}
12194 iRegIdst tmpI1;
12195 iRegIdst tmpI2;
12196 iRegIdst tmpI3;
12197 addI_reg_imm16(tmpI1, src, imm1);
12198 andcI_reg_reg(tmpI2, src, m1, tmpI1);
12199 countLeadingZerosI(tmpI3, tmpI2);
12200 subI_imm16_reg(dst, imm2, tmpI3);
12201 %}
12202 %}
12203
12204 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{
12205 match(Set dst (CountTrailingZerosI src));
12206 predicate(UseCountTrailingZerosInstructionsPPC64);
12207 ins_cost(DEFAULT_COST);
12208
12209 format %{ "CNTTZW $dst, $src" %}
12210 size(4);
12211 ins_encode %{
12212 __ cnttzw($dst$$Register, $src$$Register);
12213 %}
12214 ins_pipe(pipe_class_default);
12215 %}
12216
12217 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
12218 match(Set dst (CountTrailingZerosL src));
12219 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12220 ins_cost(DEFAULT_COST);
12221
12222 expand %{
12223 immL16 imm1 %{ (long)-1 %}
12224 immI16 imm2 %{ (int)64 %}
12225 iRegLdst tmpL1;
12226 iRegLdst tmpL2;
12227 iRegIdst tmpL3;
12228 addL_reg_imm16(tmpL1, src, imm1);
12229 andcL_reg_reg(tmpL2, tmpL1, src);
12230 countLeadingZerosL(tmpL3, tmpL2);
12231 subI_imm16_reg(dst, imm2, tmpL3);
12232 %}
12233 %}
12234
12235 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{
12236 match(Set dst (CountTrailingZerosL src));
12237 predicate(UseCountTrailingZerosInstructionsPPC64);
12238 ins_cost(DEFAULT_COST);
12239
12240 format %{ "CNTTZD $dst, $src" %}
12241 size(4);
12242 ins_encode %{
12243 __ cnttzd($dst$$Register, $src$$Register);
12244 %}
12245 ins_pipe(pipe_class_default);
12246 %}
12247
12248 // Expand nodes for byte_reverse_int/ushort/short.
12249 instruct rlwinm(iRegIdst dst, iRegIsrc src, immI16 shift, immI16 mb, immI16 me) %{
12250 effect(DEF dst, USE src, USE shift, USE mb, USE me);
12251 predicate(false);
12252
12253 format %{ "RLWINM $dst, $src, $shift, $mb, $me" %}
12254 size(4);
12255 ins_encode %{
12256 __ rlwinm($dst$$Register, $src$$Register, $shift$$constant, $mb$$constant, $me$$constant);
12257 %}
12258 ins_pipe(pipe_class_default);
12259 %}
12260
12261 // Expand nodes for byte_reverse_int.
12262 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
12263 effect(DEF dst, USE src, USE n, USE b);
12264 predicate(false);
12265
12266 format %{ "INSRWI $dst, $src, $n, $b" %}
12267 size(4);
12268 ins_encode %{
12269 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
12270 %}
12271 ins_pipe(pipe_class_default);
12272 %}
12273
12274 // As insrwi_a, but with USE_DEF.
12275 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
12276 effect(USE_DEF dst, USE src, USE n, USE b);
12277 predicate(false);
12278
12279 format %{ "INSRWI $dst, $src, $n, $b" %}
12280 size(4);
12281 ins_encode %{
12282 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
12283 %}
12284 ins_pipe(pipe_class_default);
12285 %}
12286
12287 // Just slightly faster than java implementation.
12288 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
12289 match(Set dst (ReverseBytesI src));
12290 predicate(!UseByteReverseInstructions);
12291 ins_cost(7*DEFAULT_COST);
12292
12293 expand %{
12294 immI16 imm24 %{ (int) 24 %}
12295 immI16 imm16 %{ (int) 16 %}
12296 immI16 imm8 %{ (int) 8 %}
12297 immI16 imm4 %{ (int) 4 %}
12298 immI16 imm0 %{ (int) 0 %}
12299 iRegLdst tmpI1;
12300 iRegLdst tmpI2;
12301 iRegLdst tmpI3;
12302
12303 urShiftI_reg_imm(tmpI1, src, imm24);
12304 insrwi_a(dst, tmpI1, imm8, imm24);
12305 urShiftI_reg_imm(tmpI2, src, imm16);
12306 insrwi(dst, tmpI2, imm16, imm8);
12307 urShiftI_reg_imm(tmpI3, src, imm8);
12308 insrwi(dst, tmpI3, imm8, imm8);
12309 insrwi(dst, src, imm8, imm0);
12310 %}
12311 %}
12312
12313 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{
12314 match(Set dst (ReverseBytesI src));
12315 predicate(UseVectorByteReverseInstructionsPPC64);
12316 effect(TEMP tmpV);
12317 ins_cost(DEFAULT_COST*3);
12318 size(12);
12319 format %{ "MTVSRWZ $tmpV, $src\n"
12320 "\tXXBRW $tmpV, $tmpV\n"
12321 "\tMFVSRWZ $dst, $tmpV" %}
12322
12323 ins_encode %{
12324 __ mtvsrwz($tmpV$$VectorRegister.to_vsr(), $src$$Register);
12325 __ xxbrw($tmpV$$VectorRegister.to_vsr(), $tmpV$$VectorRegister->to_vsr());
12326 __ mfvsrwz($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12327 %}
12328 ins_pipe(pipe_class_default);
12329 %}
12330
12331 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{
12332 match(Set dst (ReverseBytesI src));
12333 predicate(UseByteReverseInstructions);
12334 ins_cost(DEFAULT_COST);
12335 size(4);
12336
12337 format %{ "BRW $dst, $src" %}
12338
12339 ins_encode %{
12340 __ brw($dst$$Register, $src$$Register);
12341 %}
12342 ins_pipe(pipe_class_default);
12343 %}
12344
12345 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
12346 match(Set dst (ReverseBytesL src));
12347 predicate(!UseByteReverseInstructions);
12348 ins_cost(15*DEFAULT_COST);
12349
12350 expand %{
12351 immI16 imm56 %{ (int) 56 %}
12352 immI16 imm48 %{ (int) 48 %}
12353 immI16 imm40 %{ (int) 40 %}
12354 immI16 imm32 %{ (int) 32 %}
12355 immI16 imm24 %{ (int) 24 %}
12356 immI16 imm16 %{ (int) 16 %}
12357 immI16 imm8 %{ (int) 8 %}
12358 immI16 imm0 %{ (int) 0 %}
12359 iRegLdst tmpL1;
12360 iRegLdst tmpL2;
12361 iRegLdst tmpL3;
12362 iRegLdst tmpL4;
12363 iRegLdst tmpL5;
12364 iRegLdst tmpL6;
12365
12366 // src : |a|b|c|d|e|f|g|h|
12367 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
12368 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
12369 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
12370 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
12371 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
12372 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
12373 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
12374 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
12375 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
12376 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
12377 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
12378 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
12379 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
12380 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
12381 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
12382 %}
12383 %}
12384
12385 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{
12386 match(Set dst (ReverseBytesL src));
12387 predicate(UseVectorByteReverseInstructionsPPC64);
12388 effect(TEMP tmpV);
12389 ins_cost(DEFAULT_COST*3);
12390 size(12);
12391 format %{ "MTVSRD $tmpV, $src\n"
12392 "\tXXBRD $tmpV, $tmpV\n"
12393 "\tMFVSRD $dst, $tmpV" %}
12394
12395 ins_encode %{
12396 __ mtvsrd($tmpV$$VectorRegister->to_vsr(), $src$$Register);
12397 __ xxbrd($tmpV$$VectorRegister->to_vsr(), $tmpV$$VectorRegister->to_vsr());
12398 __ mfvsrd($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12399 %}
12400 ins_pipe(pipe_class_default);
12401 %}
12402
12403 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{
12404 match(Set dst (ReverseBytesL src));
12405 predicate(UseByteReverseInstructions);
12406 ins_cost(DEFAULT_COST);
12407 size(4);
12408
12409 format %{ "BRD $dst, $src" %}
12410
12411 ins_encode %{
12412 __ brd($dst$$Register, $src$$Register);
12413 %}
12414 ins_pipe(pipe_class_default);
12415 %}
12416
12417 // Need zero extend. Must not use brh only.
12418 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
12419 match(Set dst (ReverseBytesUS src));
12420 ins_cost(2*DEFAULT_COST);
12421
12422 expand %{
12423 immI16 imm31 %{ (int) 31 %}
12424 immI16 imm24 %{ (int) 24 %}
12425 immI16 imm16 %{ (int) 16 %}
12426 immI16 imm8 %{ (int) 8 %}
12427
12428 rlwinm(dst, src, imm24, imm24, imm31);
12429 insrwi(dst, src, imm8, imm16);
12430 %}
12431 %}
12432
12433 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
12434 match(Set dst (ReverseBytesS src));
12435 predicate(!UseByteReverseInstructions);
12436 ins_cost(3*DEFAULT_COST);
12437
12438 expand %{
12439 immI16 imm16 %{ (int) 16 %}
12440 immI16 imm8 %{ (int) 8 %}
12441 iRegLdst tmpI1;
12442
12443 urShiftI_reg_imm(tmpI1, src, imm8);
12444 insrwi(tmpI1, src, imm8, imm16);
12445 extsh(dst, tmpI1);
12446 %}
12447 %}
12448
12449 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{
12450 match(Set dst (ReverseBytesS src));
12451 predicate(UseByteReverseInstructions);
12452 ins_cost(DEFAULT_COST);
12453 size(8);
12454
12455 format %{ "BRH $dst, $src\n\t"
12456 "EXTSH $dst, $dst" %}
12457
12458 ins_encode %{
12459 __ brh($dst$$Register, $src$$Register);
12460 __ extsh($dst$$Register, $dst$$Register);
12461 %}
12462 ins_pipe(pipe_class_default);
12463 %}
12464
12465 // Load Integer reversed byte order
12466 instruct loadI_reversed(iRegIdst dst, indirect mem) %{
12467 match(Set dst (ReverseBytesI (LoadI mem)));
12468 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12469 ins_cost(MEMORY_REF_COST);
12470
12471 size(4);
12472 ins_encode %{
12473 __ lwbrx($dst$$Register, $mem$$Register);
12474 %}
12475 ins_pipe(pipe_class_default);
12476 %}
12477
12478 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{
12479 match(Set dst (ReverseBytesI (LoadI mem)));
12480 ins_cost(2 * MEMORY_REF_COST);
12481
12482 size(12);
12483 ins_encode %{
12484 __ lwbrx($dst$$Register, $mem$$Register);
12485 __ twi_0($dst$$Register);
12486 __ isync();
12487 %}
12488 ins_pipe(pipe_class_default);
12489 %}
12490
12491 // Load Long - aligned and reversed
12492 instruct loadL_reversed(iRegLdst dst, indirect mem) %{
12493 match(Set dst (ReverseBytesL (LoadL mem)));
12494 predicate((n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))));
12495 ins_cost(MEMORY_REF_COST);
12496
12497 size(4);
12498 ins_encode %{
12499 __ ldbrx($dst$$Register, $mem$$Register);
12500 %}
12501 ins_pipe(pipe_class_default);
12502 %}
12503
12504 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{
12505 match(Set dst (ReverseBytesL (LoadL mem)));
12506 ins_cost(2 * MEMORY_REF_COST);
12507
12508 size(12);
12509 ins_encode %{
12510 __ ldbrx($dst$$Register, $mem$$Register);
12511 __ twi_0($dst$$Register);
12512 __ isync();
12513 %}
12514 ins_pipe(pipe_class_default);
12515 %}
12516
12517 // Load unsigned short / char reversed byte order
12518 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
12519 match(Set dst (ReverseBytesUS (LoadUS mem)));
12520 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12521 ins_cost(MEMORY_REF_COST);
12522
12523 size(4);
12524 ins_encode %{
12525 __ lhbrx($dst$$Register, $mem$$Register);
12526 %}
12527 ins_pipe(pipe_class_default);
12528 %}
12529
12530 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{
12531 match(Set dst (ReverseBytesUS (LoadUS mem)));
12532 ins_cost(2 * MEMORY_REF_COST);
12533
12534 size(12);
12535 ins_encode %{
12536 __ lhbrx($dst$$Register, $mem$$Register);
12537 __ twi_0($dst$$Register);
12538 __ isync();
12539 %}
12540 ins_pipe(pipe_class_default);
12541 %}
12542
12543 // Load short reversed byte order
12544 instruct loadS_reversed(iRegIdst dst, indirect mem) %{
12545 match(Set dst (ReverseBytesS (LoadS mem)));
12546 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12547 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
12548
12549 size(8);
12550 ins_encode %{
12551 __ lhbrx($dst$$Register, $mem$$Register);
12552 __ extsh($dst$$Register, $dst$$Register);
12553 %}
12554 ins_pipe(pipe_class_default);
12555 %}
12556
12557 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{
12558 match(Set dst (ReverseBytesS (LoadS mem)));
12559 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12560
12561 size(16);
12562 ins_encode %{
12563 __ lhbrx($dst$$Register, $mem$$Register);
12564 __ twi_0($dst$$Register);
12565 __ extsh($dst$$Register, $dst$$Register);
12566 __ isync();
12567 %}
12568 ins_pipe(pipe_class_default);
12569 %}
12570
12571 // Store Integer reversed byte order
12572 instruct storeI_reversed(iRegIsrc src, indirect mem) %{
12573 match(Set mem (StoreI mem (ReverseBytesI src)));
12574 ins_cost(MEMORY_REF_COST);
12575
12576 size(4);
12577 ins_encode %{
12578 __ stwbrx($src$$Register, $mem$$Register);
12579 %}
12580 ins_pipe(pipe_class_default);
12581 %}
12582
12583 // Store Long reversed byte order
12584 instruct storeL_reversed(iRegLsrc src, indirect mem) %{
12585 match(Set mem (StoreL mem (ReverseBytesL src)));
12586 ins_cost(MEMORY_REF_COST);
12587
12588 size(4);
12589 ins_encode %{
12590 __ stdbrx($src$$Register, $mem$$Register);
12591 %}
12592 ins_pipe(pipe_class_default);
12593 %}
12594
12595 // Store unsigned short / char reversed byte order
12596 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
12597 match(Set mem (StoreC mem (ReverseBytesUS src)));
12598 ins_cost(MEMORY_REF_COST);
12599
12600 size(4);
12601 ins_encode %{
12602 __ sthbrx($src$$Register, $mem$$Register);
12603 %}
12604 ins_pipe(pipe_class_default);
12605 %}
12606
12607 // Store short reversed byte order
12608 instruct storeS_reversed(iRegIsrc src, indirect mem) %{
12609 match(Set mem (StoreC mem (ReverseBytesS src)));
12610 ins_cost(MEMORY_REF_COST);
12611
12612 size(4);
12613 ins_encode %{
12614 __ sthbrx($src$$Register, $mem$$Register);
12615 %}
12616 ins_pipe(pipe_class_default);
12617 %}
12618
12619 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
12620 effect(DEF temp1, USE src);
12621
12622 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %}
12623 size(4);
12624 ins_encode %{
12625 __ mtvsrwz($temp1$$VectorRegister->to_vsr(), $src$$Register);
12626 %}
12627 ins_pipe(pipe_class_default);
12628 %}
12629
12630 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{
12631 effect(DEF dst, USE src, USE imm1);
12632
12633 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %}
12634 size(4);
12635 ins_encode %{
12636 __ xxspltw($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $imm1$$constant);
12637 %}
12638 ins_pipe(pipe_class_default);
12639 %}
12640
12641 instruct xscvdpspn_regF(vecX dst, regF src) %{
12642 effect(DEF dst, USE src);
12643
12644 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %}
12645 size(4);
12646 ins_encode %{
12647 __ xscvdpspn($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr());
12648 %}
12649 ins_pipe(pipe_class_default);
12650 %}
12651
12652 //---------- Replicate Vector Instructions ------------------------------------
12653
12654 // Insrdi does replicate if src == dst.
12655 instruct repl32(iRegLdst dst) %{
12656 predicate(false);
12657 effect(USE_DEF dst);
12658
12659 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %}
12660 size(4);
12661 ins_encode %{
12662 __ insrdi($dst$$Register, $dst$$Register, 32, 0);
12663 %}
12664 ins_pipe(pipe_class_default);
12665 %}
12666
12667 // Insrdi does replicate if src == dst.
12668 instruct repl48(iRegLdst dst) %{
12669 predicate(false);
12670 effect(USE_DEF dst);
12671
12672 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %}
12673 size(4);
12674 ins_encode %{
12675 __ insrdi($dst$$Register, $dst$$Register, 48, 0);
12676 %}
12677 ins_pipe(pipe_class_default);
12678 %}
12679
12680 // Insrdi does replicate if src == dst.
12681 instruct repl56(iRegLdst dst) %{
12682 predicate(false);
12683 effect(USE_DEF dst);
12684
12685 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %}
12686 size(4);
12687 ins_encode %{
12688 __ insrdi($dst$$Register, $dst$$Register, 56, 0);
12689 %}
12690 ins_pipe(pipe_class_default);
12691 %}
12692
12693 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12694 match(Set dst (Replicate src));
12695 predicate(n->as_Vector()->length() == 8 &&
12696 Matcher::vector_element_basic_type(n) == T_BYTE);
12697 expand %{
12698 moveReg(dst, src);
12699 repl56(dst);
12700 repl48(dst);
12701 repl32(dst);
12702 %}
12703 %}
12704
12705 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
12706 match(Set dst (Replicate zero));
12707 predicate(n->as_Vector()->length() == 8 &&
12708 Matcher::vector_element_basic_type(n) == T_BYTE);
12709 format %{ "LI $dst, #0 \t// replicate8B" %}
12710 size(4);
12711 ins_encode %{
12712 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12713 %}
12714 ins_pipe(pipe_class_default);
12715 %}
12716
12717 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
12718 match(Set dst (Replicate src));
12719 predicate(n->as_Vector()->length() == 8 &&
12720 Matcher::vector_element_basic_type(n) == T_BYTE);
12721 format %{ "LI $dst, #-1 \t// replicate8B" %}
12722 size(4);
12723 ins_encode %{
12724 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12725 %}
12726 ins_pipe(pipe_class_default);
12727 %}
12728
12729 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{
12730 match(Set dst (Replicate src));
12731 predicate(n->as_Vector()->length() == 16 &&
12732 Matcher::vector_element_basic_type(n) == T_BYTE);
12733
12734 expand %{
12735 iRegLdst tmpL;
12736 vecX tmpV;
12737 immI8 imm1 %{ (int) 1 %}
12738 moveReg(tmpL, src);
12739 repl56(tmpL);
12740 repl48(tmpL);
12741 mtvsrwz(tmpV, tmpL);
12742 xxspltw(dst, tmpV, imm1);
12743 %}
12744 %}
12745
12746 instruct repl16B_immI0(vecX dst, immI_0 zero) %{
12747 match(Set dst (Replicate zero));
12748 predicate(n->as_Vector()->length() == 16 &&
12749 Matcher::vector_element_basic_type(n) == T_BYTE);
12750
12751 format %{ "XXLXOR $dst, $zero \t// replicate16B" %}
12752 size(4);
12753 ins_encode %{
12754 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12755 %}
12756 ins_pipe(pipe_class_default);
12757 %}
12758
12759 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{
12760 match(Set dst (Replicate src));
12761 predicate(n->as_Vector()->length() == 16 &&
12762 Matcher::vector_element_basic_type(n) == T_BYTE);
12763
12764 format %{ "XXLEQV $dst, $src \t// replicate16B" %}
12765 size(4);
12766 ins_encode %{
12767 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12768 %}
12769 ins_pipe(pipe_class_default);
12770 %}
12771
12772 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12773 match(Set dst (Replicate src));
12774 predicate(n->as_Vector()->length() == 4 &&
12775 Matcher::vector_element_basic_type(n) == T_SHORT);
12776 expand %{
12777 moveReg(dst, src);
12778 repl48(dst);
12779 repl32(dst);
12780 %}
12781 %}
12782
12783 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
12784 match(Set dst (Replicate zero));
12785 predicate(n->as_Vector()->length() == 4 &&
12786 Matcher::vector_element_basic_type(n) == T_SHORT);
12787 format %{ "LI $dst, #0 \t// replicate4S" %}
12788 size(4);
12789 ins_encode %{
12790 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12791 %}
12792 ins_pipe(pipe_class_default);
12793 %}
12794
12795 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
12796 match(Set dst (Replicate src));
12797 predicate(n->as_Vector()->length() == 4 &&
12798 Matcher::vector_element_basic_type(n) == T_SHORT);
12799 format %{ "LI $dst, -1 \t// replicate4S" %}
12800 size(4);
12801 ins_encode %{
12802 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12803 %}
12804 ins_pipe(pipe_class_default);
12805 %}
12806
12807 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{
12808 match(Set dst (Replicate src));
12809 predicate(n->as_Vector()->length() == 8 &&
12810 Matcher::vector_element_basic_type(n) == T_SHORT);
12811
12812 expand %{
12813 iRegLdst tmpL;
12814 vecX tmpV;
12815 immI8 zero %{ (int) 0 %}
12816 moveReg(tmpL, src);
12817 repl48(tmpL);
12818 repl32(tmpL);
12819 mtvsrd(tmpV, tmpL);
12820 xxpermdi(dst, tmpV, tmpV, zero);
12821 %}
12822 %}
12823
12824 instruct repl8S_immI0(vecX dst, immI_0 zero) %{
12825 match(Set dst (Replicate zero));
12826 predicate(n->as_Vector()->length() == 8 &&
12827 Matcher::vector_element_basic_type(n) == T_SHORT);
12828
12829 format %{ "XXLXOR $dst, $zero \t// replicate8S" %}
12830 size(4);
12831 ins_encode %{
12832 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12833 %}
12834 ins_pipe(pipe_class_default);
12835 %}
12836
12837 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{
12838 match(Set dst (Replicate src));
12839 predicate(n->as_Vector()->length() == 8 &&
12840 Matcher::vector_element_basic_type(n) == T_SHORT);
12841
12842 format %{ "XXLEQV $dst, $src \t// replicate8S" %}
12843 size(4);
12844 ins_encode %{
12845 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12846 %}
12847 ins_pipe(pipe_class_default);
12848 %}
12849
12850 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12851 match(Set dst (Replicate src));
12852 predicate(n->as_Vector()->length() == 2 &&
12853 Matcher::vector_element_basic_type(n) == T_INT);
12854 ins_cost(2 * DEFAULT_COST);
12855 expand %{
12856 moveReg(dst, src);
12857 repl32(dst);
12858 %}
12859 %}
12860
12861 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
12862 match(Set dst (Replicate zero));
12863 predicate(n->as_Vector()->length() == 2 &&
12864 Matcher::vector_element_basic_type(n) == T_INT);
12865 format %{ "LI $dst, #0 \t// replicate2I" %}
12866 size(4);
12867 ins_encode %{
12868 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12869 %}
12870 ins_pipe(pipe_class_default);
12871 %}
12872
12873 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
12874 match(Set dst (Replicate src));
12875 predicate(n->as_Vector()->length() == 2 &&
12876 Matcher::vector_element_basic_type(n) == T_INT);
12877 format %{ "LI $dst, -1 \t// replicate2I" %}
12878 size(4);
12879 ins_encode %{
12880 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12881 %}
12882 ins_pipe(pipe_class_default);
12883 %}
12884
12885 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{
12886 match(Set dst (Replicate src));
12887 predicate(n->as_Vector()->length() == 4 &&
12888 Matcher::vector_element_basic_type(n) == T_INT);
12889 ins_cost(2 * DEFAULT_COST);
12890
12891 expand %{
12892 iRegLdst tmpL;
12893 vecX tmpV;
12894 immI8 zero %{ (int) 0 %}
12895 moveReg(tmpL, src);
12896 repl32(tmpL);
12897 mtvsrd(tmpV, tmpL);
12898 xxpermdi(dst, tmpV, tmpV, zero);
12899 %}
12900 %}
12901
12902 instruct repl4I_immI0(vecX dst, immI_0 zero) %{
12903 match(Set dst (Replicate zero));
12904 predicate(n->as_Vector()->length() == 4 &&
12905 Matcher::vector_element_basic_type(n) == T_INT);
12906
12907 format %{ "XXLXOR $dst, $zero \t// replicate4I" %}
12908 size(4);
12909 ins_encode %{
12910 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12911 %}
12912 ins_pipe(pipe_class_default);
12913 %}
12914
12915 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{
12916 match(Set dst (Replicate src));
12917 predicate(n->as_Vector()->length() == 4 &&
12918 Matcher::vector_element_basic_type(n) == T_INT);
12919
12920 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %}
12921 size(4);
12922 ins_encode %{
12923 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12924 %}
12925 ins_pipe(pipe_class_default);
12926 %}
12927
12928 // Move float to int register via stack, replicate.
12929 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
12930 match(Set dst (Replicate src));
12931 predicate(n->as_Vector()->length() == 2 &&
12932 Matcher::vector_element_basic_type(n) == T_FLOAT);
12933 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12934 expand %{
12935 stackSlotL tmpS;
12936 iRegIdst tmpI;
12937 moveF2I_reg_stack(tmpS, src); // Move float to stack.
12938 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
12939 moveReg(dst, tmpI); // Move int to long reg.
12940 repl32(dst); // Replicate bitpattern.
12941 %}
12942 %}
12943
12944 // Replicate scalar constant to packed float values in Double register
12945 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
12946 match(Set dst (Replicate src));
12947 predicate(n->as_Vector()->length() == 2 &&
12948 Matcher::vector_element_basic_type(n) == T_FLOAT);
12949 ins_cost(5 * DEFAULT_COST);
12950
12951 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
12952 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
12953 %}
12954
12955 // Replicate scalar zero constant to packed float values in Double register
12956 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
12957 match(Set dst (Replicate zero));
12958 predicate(n->as_Vector()->length() == 2 &&
12959 Matcher::vector_element_basic_type(n) == T_FLOAT);
12960
12961 format %{ "LI $dst, #0 \t// replicate2F" %}
12962 size(4);
12963 ins_encode %{
12964 __ li($dst$$Register, 0x0);
12965 %}
12966 ins_pipe(pipe_class_default);
12967 %}
12968
12969
12970 //----------Vector Arithmetic Instructions--------------------------------------
12971
12972 // Vector Addition Instructions
12973
12974 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
12975 match(Set dst (AddVB src1 src2));
12976 predicate(n->as_Vector()->length() == 16);
12977 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %}
12978 size(4);
12979 ins_encode %{
12980 __ vaddubm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12981 %}
12982 ins_pipe(pipe_class_default);
12983 %}
12984
12985 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
12986 match(Set dst (AddVS src1 src2));
12987 predicate(n->as_Vector()->length() == 8);
12988 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %}
12989 size(4);
12990 ins_encode %{
12991 __ vadduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12992 %}
12993 ins_pipe(pipe_class_default);
12994 %}
12995
12996 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
12997 match(Set dst (AddVI src1 src2));
12998 predicate(n->as_Vector()->length() == 4);
12999 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %}
13000 size(4);
13001 ins_encode %{
13002 __ vadduwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13003 %}
13004 ins_pipe(pipe_class_default);
13005 %}
13006
13007 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
13008 match(Set dst (AddVF src1 src2));
13009 predicate(n->as_Vector()->length() == 4);
13010 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %}
13011 size(4);
13012 ins_encode %{
13013 __ vaddfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13014 %}
13015 ins_pipe(pipe_class_default);
13016 %}
13017
13018 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
13019 match(Set dst (AddVL src1 src2));
13020 predicate(n->as_Vector()->length() == 2);
13021 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %}
13022 size(4);
13023 ins_encode %{
13024 __ vaddudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13025 %}
13026 ins_pipe(pipe_class_default);
13027 %}
13028
13029 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
13030 match(Set dst (AddVD src1 src2));
13031 predicate(n->as_Vector()->length() == 2);
13032 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %}
13033 size(4);
13034 ins_encode %{
13035 __ xvadddp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13036 %}
13037 ins_pipe(pipe_class_default);
13038 %}
13039
13040 // Vector Subtraction Instructions
13041
13042 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
13043 match(Set dst (SubVB src1 src2));
13044 predicate(n->as_Vector()->length() == 16);
13045 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %}
13046 size(4);
13047 ins_encode %{
13048 __ vsububm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13049 %}
13050 ins_pipe(pipe_class_default);
13051 %}
13052
13053 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
13054 match(Set dst (SubVS src1 src2));
13055 predicate(n->as_Vector()->length() == 8);
13056 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %}
13057 size(4);
13058 ins_encode %{
13059 __ vsubuhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13060 %}
13061 ins_pipe(pipe_class_default);
13062 %}
13063
13064 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
13065 match(Set dst (SubVI src1 src2));
13066 predicate(n->as_Vector()->length() == 4);
13067 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %}
13068 size(4);
13069 ins_encode %{
13070 __ vsubuwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13071 %}
13072 ins_pipe(pipe_class_default);
13073 %}
13074
13075 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
13076 match(Set dst (SubVF src1 src2));
13077 predicate(n->as_Vector()->length() == 4);
13078 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %}
13079 size(4);
13080 ins_encode %{
13081 __ vsubfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13082 %}
13083 ins_pipe(pipe_class_default);
13084 %}
13085
13086 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
13087 match(Set dst (SubVL src1 src2));
13088 predicate(n->as_Vector()->length() == 2);
13089 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %}
13090 size(4);
13091 ins_encode %{
13092 __ vsubudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13093 %}
13094 ins_pipe(pipe_class_default);
13095 %}
13096
13097 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
13098 match(Set dst (SubVD src1 src2));
13099 predicate(n->as_Vector()->length() == 2);
13100 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %}
13101 size(4);
13102 ins_encode %{
13103 __ xvsubdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13104 %}
13105 ins_pipe(pipe_class_default);
13106 %}
13107
13108 // Vector Multiplication Instructions
13109
13110 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
13111 match(Set dst (MulVS src1 src2));
13112 predicate(n->as_Vector()->length() == 8);
13113 effect(TEMP tmp);
13114 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %}
13115 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %}
13116 size(8);
13117 ins_encode %{
13118 __ vspltish($tmp$$VectorRegister, 0);
13119 __ vmladduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister, $tmp$$VectorRegister);
13120 %}
13121 ins_pipe(pipe_class_default);
13122 %}
13123
13124 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
13125 match(Set dst (MulVI src1 src2));
13126 predicate(n->as_Vector()->length() == 4);
13127 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %}
13128 size(4);
13129 ins_encode %{
13130 __ vmuluwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13131 %}
13132 ins_pipe(pipe_class_default);
13133 %}
13134
13135 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
13136 match(Set dst (MulVF src1 src2));
13137 predicate(n->as_Vector()->length() == 4);
13138 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %}
13139 size(4);
13140 ins_encode %{
13141 __ xvmulsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13142 %}
13143 ins_pipe(pipe_class_default);
13144 %}
13145
13146 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
13147 match(Set dst (MulVD src1 src2));
13148 predicate(n->as_Vector()->length() == 2);
13149 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %}
13150 size(4);
13151 ins_encode %{
13152 __ xvmuldp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13153 %}
13154 ins_pipe(pipe_class_default);
13155 %}
13156
13157 // Vector Division Instructions
13158
13159 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
13160 match(Set dst (DivVF src1 src2));
13161 predicate(n->as_Vector()->length() == 4);
13162 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %}
13163 size(4);
13164 ins_encode %{
13165 __ xvdivsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13166 %}
13167 ins_pipe(pipe_class_default);
13168 %}
13169
13170 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
13171 match(Set dst (DivVD src1 src2));
13172 predicate(n->as_Vector()->length() == 2);
13173 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %}
13174 size(4);
13175 ins_encode %{
13176 __ xvdivdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13177 %}
13178 ins_pipe(pipe_class_default);
13179 %}
13180
13181 // Vector Min / Max Instructions
13182
13183 instruct vmin_reg(vecX dst, vecX src1, vecX src2) %{
13184 match(Set dst (MinV src1 src2));
13185 format %{ "VMIN $dst,$src1,$src2\t// vector min" %}
13186 size(4);
13187 ins_encode %{
13188 BasicType bt = Matcher::vector_element_basic_type(this);
13189 switch (bt) {
13190 case T_INT:
13191 __ vminsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13192 break;
13193 case T_LONG:
13194 __ vminsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13195 break;
13196 default:
13197 ShouldNotReachHere();
13198 }
13199 %}
13200 ins_pipe(pipe_class_default);
13201 %}
13202
13203 instruct vmax_reg(vecX dst, vecX src1, vecX src2) %{
13204 match(Set dst (MaxV src1 src2));
13205 format %{ "VMAX $dst,$src1,$src2\t// vector max" %}
13206 size(4);
13207 ins_encode %{
13208 BasicType bt = Matcher::vector_element_basic_type(this);
13209 switch (bt) {
13210 case T_INT:
13211 __ vmaxsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13212 break;
13213 case T_LONG:
13214 __ vmaxsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13215 break;
13216 default:
13217 ShouldNotReachHere();
13218 }
13219 %}
13220 ins_pipe(pipe_class_default);
13221 %}
13222
13223 instruct vminu_reg(vecX dst, vecX src1, vecX src2) %{
13224 match(Set dst (UMinV src1 src2));
13225 format %{ "VMINU $dst,$src1,$src2\t// vector unsigned min" %}
13226 size(4);
13227 ins_encode %{
13228 BasicType bt = Matcher::vector_element_basic_type(this);
13229 switch (bt) {
13230 case T_INT:
13231 __ vminuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13232 break;
13233 case T_LONG:
13234 __ vminud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13235 break;
13236 default:
13237 ShouldNotReachHere();
13238 }
13239 %}
13240 ins_pipe(pipe_class_default);
13241 %}
13242
13243 instruct vmaxu_reg(vecX dst, vecX src1, vecX src2) %{
13244 match(Set dst (UMaxV src1 src2));
13245 format %{ "VMAXU $dst,$src1,$src2\t// vector unsigned max" %}
13246 size(4);
13247 ins_encode %{
13248 BasicType bt = Matcher::vector_element_basic_type(this);
13249 switch (bt) {
13250 case T_INT:
13251 __ vmaxuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13252 break;
13253 case T_LONG:
13254 __ vmaxud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13255 break;
13256 default:
13257 ShouldNotReachHere();
13258 }
13259 %}
13260 ins_pipe(pipe_class_default);
13261 %}
13262
13263 instruct vand(vecX dst, vecX src1, vecX src2) %{
13264 match(Set dst (AndV src1 src2));
13265 size(4);
13266 format %{ "VAND $dst,$src1,$src2\t// and vectors" %}
13267 ins_encode %{
13268 __ vand($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13269 %}
13270 ins_pipe(pipe_class_default);
13271 %}
13272
13273 instruct vor(vecX dst, vecX src1, vecX src2) %{
13274 match(Set dst (OrV src1 src2));
13275 size(4);
13276 format %{ "VOR $dst,$src1,$src2\t// or vectors" %}
13277 ins_encode %{
13278 __ vor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13279 %}
13280 ins_pipe(pipe_class_default);
13281 %}
13282
13283 instruct vxor(vecX dst, vecX src1, vecX src2) %{
13284 match(Set dst (XorV src1 src2));
13285 size(4);
13286 format %{ "VXOR $dst,$src1,$src2\t// xor vectors" %}
13287 ins_encode %{
13288 __ vxor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13289 %}
13290 ins_pipe(pipe_class_default);
13291 %}
13292
13293 instruct reductionI_arith_logic(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2) %{
13294 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13295 match(Set dst (AddReductionVI srcInt srcVec));
13296 match(Set dst (MulReductionVI srcInt srcVec));
13297 match(Set dst (AndReductionV srcInt srcVec));
13298 match(Set dst ( OrReductionV srcInt srcVec));
13299 match(Set dst (XorReductionV srcInt srcVec));
13300 effect(TEMP tmp1, TEMP tmp2);
13301 ins_cost(DEFAULT_COST * 6);
13302 format %{ "REDUCEI_ARITH_LOGIC // $dst,$srcInt,$srcVec,$tmp1,$tmp2\t// reduce vector int add/mul/and/or/xor" %}
13303 size(24);
13304 ins_encode %{
13305 int opcode = this->ideal_Opcode();
13306 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13307 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13308 %}
13309 ins_pipe(pipe_class_default);
13310 %}
13311
13312 instruct reductionI_min_max(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2, flagsRegCR0 cr0) %{
13313 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13314 match(Set dst (MinReductionV srcInt srcVec));
13315 match(Set dst (MaxReductionV srcInt srcVec));
13316 effect(TEMP tmp1, TEMP tmp2, KILL cr0);
13317 ins_cost(DEFAULT_COST * 7);
13318 format %{ "REDUCEI_MINMAX // $dst,$srcInt,$srcVec,$tmp1,$tmp2,cr0\t// reduce vector int min/max" %}
13319 size(28);
13320 ins_encode %{
13321 int opcode = this->ideal_Opcode();
13322 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13323 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13324 %}
13325 ins_pipe(pipe_class_default);
13326 %}
13327
13328 // Vector Absolute Instructions
13329
13330 instruct vabs4F_reg(vecX dst, vecX src) %{
13331 match(Set dst (AbsVF src));
13332 predicate(n->as_Vector()->length() == 4);
13333 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
13334 size(4);
13335 ins_encode %{
13336 __ xvabssp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13337 %}
13338 ins_pipe(pipe_class_default);
13339 %}
13340
13341 instruct vabs2D_reg(vecX dst, vecX src) %{
13342 match(Set dst (AbsVD src));
13343 predicate(n->as_Vector()->length() == 2);
13344 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
13345 size(4);
13346 ins_encode %{
13347 __ xvabsdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13348 %}
13349 ins_pipe(pipe_class_default);
13350 %}
13351
13352 // Round Instructions
13353 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{
13354 match(Set dst (RoundDoubleMode src rmode));
13355 format %{ "RoundDoubleMode $src,$rmode" %}
13356 size(4);
13357 ins_encode %{
13358 switch ($rmode$$constant) {
13359 case RoundDoubleModeNode::rmode_rint:
13360 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr());
13361 break;
13362 case RoundDoubleModeNode::rmode_floor:
13363 __ frim($dst$$FloatRegister, $src$$FloatRegister);
13364 break;
13365 case RoundDoubleModeNode::rmode_ceil:
13366 __ frip($dst$$FloatRegister, $src$$FloatRegister);
13367 break;
13368 default:
13369 ShouldNotReachHere();
13370 }
13371 %}
13372 ins_pipe(pipe_class_default);
13373 %}
13374
13375 // Vector Round Instructions
13376 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
13377 match(Set dst (RoundDoubleModeV src rmode));
13378 predicate(n->as_Vector()->length() == 2);
13379 format %{ "RoundDoubleModeV $src,$rmode" %}
13380 size(4);
13381 ins_encode %{
13382 switch ($rmode$$constant) {
13383 case RoundDoubleModeNode::rmode_rint:
13384 __ xvrdpic($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13385 break;
13386 case RoundDoubleModeNode::rmode_floor:
13387 __ xvrdpim($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13388 break;
13389 case RoundDoubleModeNode::rmode_ceil:
13390 __ xvrdpip($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13391 break;
13392 default:
13393 ShouldNotReachHere();
13394 }
13395 %}
13396 ins_pipe(pipe_class_default);
13397 %}
13398
13399 // Vector Negate Instructions
13400
13401 instruct vneg4F_reg(vecX dst, vecX src) %{
13402 match(Set dst (NegVF src));
13403 predicate(n->as_Vector()->length() == 4);
13404 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
13405 size(4);
13406 ins_encode %{
13407 __ xvnegsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13408 %}
13409 ins_pipe(pipe_class_default);
13410 %}
13411
13412 instruct vneg2D_reg(vecX dst, vecX src) %{
13413 match(Set dst (NegVD src));
13414 predicate(n->as_Vector()->length() == 2);
13415 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
13416 size(4);
13417 ins_encode %{
13418 __ xvnegdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13419 %}
13420 ins_pipe(pipe_class_default);
13421 %}
13422
13423 instruct vneg4I_reg(vecX dst, vecX src) %{
13424 match(Set dst (NegVI src));
13425 predicate(Matcher::vector_element_basic_type(n) == T_INT);
13426 format %{ "VNEGW $dst,$src\t// negate int vector" %}
13427 size(4);
13428 ins_encode %{
13429 __ vnegw($dst$$VectorRegister, $src$$VectorRegister);
13430 %}
13431 ins_pipe(pipe_class_default);
13432 %}
13433
13434 // Vector Square Root Instructions
13435
13436 instruct vsqrt4F_reg(vecX dst, vecX src) %{
13437 match(Set dst (SqrtVF src));
13438 predicate(n->as_Vector()->length() == 4);
13439 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
13440 size(4);
13441 ins_encode %{
13442 __ xvsqrtsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13443 %}
13444 ins_pipe(pipe_class_default);
13445 %}
13446
13447 instruct vsqrt2D_reg(vecX dst, vecX src) %{
13448 match(Set dst (SqrtVD src));
13449 predicate(n->as_Vector()->length() == 2);
13450 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %}
13451 size(4);
13452 ins_encode %{
13453 __ xvsqrtdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13454 %}
13455 ins_pipe(pipe_class_default);
13456 %}
13457
13458 // Vector Population Count and Zeros Count Instructions
13459
13460 instruct vpopcnt_reg(vecX dst, vecX src) %{
13461 match(Set dst (PopCountVI src));
13462 match(Set dst (PopCountVL src));
13463 format %{ "VPOPCNT $dst,$src\t// pop count packed" %}
13464 size(4);
13465 ins_encode %{
13466 BasicType bt = Matcher::vector_element_basic_type(this);
13467 switch (bt) {
13468 case T_BYTE:
13469 __ vpopcntb($dst$$VectorRegister, $src$$VectorRegister);
13470 break;
13471 case T_SHORT:
13472 __ vpopcnth($dst$$VectorRegister, $src$$VectorRegister);
13473 break;
13474 case T_INT:
13475 __ vpopcntw($dst$$VectorRegister, $src$$VectorRegister);
13476 break;
13477 case T_LONG:
13478 __ vpopcntd($dst$$VectorRegister, $src$$VectorRegister);
13479 break;
13480 default:
13481 ShouldNotReachHere();
13482 }
13483 %}
13484 ins_pipe(pipe_class_default);
13485 %}
13486
13487 instruct vcount_leading_zeros_reg(vecX dst, vecX src) %{
13488 match(Set dst (CountLeadingZerosV src));
13489 format %{ "VCLZ $dst,$src\t// leading zeros count packed" %}
13490 size(4);
13491 ins_encode %{
13492 BasicType bt = Matcher::vector_element_basic_type(this);
13493 switch (bt) {
13494 case T_BYTE:
13495 __ vclzb($dst$$VectorRegister, $src$$VectorRegister);
13496 break;
13497 case T_SHORT:
13498 __ vclzh($dst$$VectorRegister, $src$$VectorRegister);
13499 break;
13500 case T_INT:
13501 __ vclzw($dst$$VectorRegister, $src$$VectorRegister);
13502 break;
13503 case T_LONG:
13504 __ vclzd($dst$$VectorRegister, $src$$VectorRegister);
13505 break;
13506 default:
13507 ShouldNotReachHere();
13508 }
13509 %}
13510 ins_pipe(pipe_class_default);
13511 %}
13512
13513 instruct vcount_trailing_zeros_reg(vecX dst, vecX src) %{
13514 match(Set dst (CountTrailingZerosV src));
13515 format %{ "VCTZ $dst,$src\t// trailing zeros count packed" %}
13516 size(4);
13517 ins_encode %{
13518 BasicType bt = Matcher::vector_element_basic_type(this);
13519 switch (bt) {
13520 case T_BYTE:
13521 __ vctzb($dst$$VectorRegister, $src$$VectorRegister);
13522 break;
13523 case T_SHORT:
13524 __ vctzh($dst$$VectorRegister, $src$$VectorRegister);
13525 break;
13526 case T_INT:
13527 __ vctzw($dst$$VectorRegister, $src$$VectorRegister);
13528 break;
13529 case T_LONG:
13530 __ vctzd($dst$$VectorRegister, $src$$VectorRegister);
13531 break;
13532 default:
13533 ShouldNotReachHere();
13534 }
13535 %}
13536 ins_pipe(pipe_class_default);
13537 %}
13538
13539 // --------------------------------- FMA --------------------------------------
13540 // src1 * src2 + dst
13541 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{
13542 match(Set dst (FmaVF dst (Binary src1 src2)));
13543 predicate(n->as_Vector()->length() == 4);
13544
13545 format %{ "XVMADDASP $dst, $src1, $src2" %}
13546
13547 size(4);
13548 ins_encode %{
13549 assert(UseFMA, "Needs FMA instructions support.");
13550 __ xvmaddasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13551 %}
13552 ins_pipe(pipe_class_default);
13553 %}
13554
13555 // src1 * (-src2) + dst
13556 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13557 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{
13558 match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
13559 predicate(n->as_Vector()->length() == 4);
13560
13561 format %{ "XVNMSUBASP $dst, $src1, $src2" %}
13562
13563 size(4);
13564 ins_encode %{
13565 assert(UseFMA, "Needs FMA instructions support.");
13566 __ xvnmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13567 %}
13568 ins_pipe(pipe_class_default);
13569 %}
13570
13571 // src1 * src2 - dst
13572 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{
13573 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2)));
13574 predicate(n->as_Vector()->length() == 4);
13575
13576 format %{ "XVMSUBASP $dst, $src1, $src2" %}
13577
13578 size(4);
13579 ins_encode %{
13580 assert(UseFMA, "Needs FMA instructions support.");
13581 __ xvmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13582 %}
13583 ins_pipe(pipe_class_default);
13584 %}
13585
13586 // src1 * src2 + dst
13587 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{
13588 match(Set dst (FmaVD dst (Binary src1 src2)));
13589 predicate(n->as_Vector()->length() == 2);
13590
13591 format %{ "XVMADDADP $dst, $src1, $src2" %}
13592
13593 size(4);
13594 ins_encode %{
13595 assert(UseFMA, "Needs FMA instructions support.");
13596 __ xvmaddadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13597 %}
13598 ins_pipe(pipe_class_default);
13599 %}
13600
13601 // src1 * (-src2) + dst
13602 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13603 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{
13604 match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
13605 predicate(n->as_Vector()->length() == 2);
13606
13607 format %{ "XVNMSUBADP $dst, $src1, $src2" %}
13608
13609 size(4);
13610 ins_encode %{
13611 assert(UseFMA, "Needs FMA instructions support.");
13612 __ xvnmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13613 %}
13614 ins_pipe(pipe_class_default);
13615 %}
13616
13617 // src1 * src2 - dst
13618 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
13619 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2)));
13620 predicate(n->as_Vector()->length() == 2);
13621
13622 format %{ "XVMSUBADP $dst, $src1, $src2" %}
13623
13624 size(4);
13625 ins_encode %{
13626 assert(UseFMA, "Needs FMA instructions support.");
13627 __ xvmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13628 %}
13629 ins_pipe(pipe_class_default);
13630 %}
13631
13632 //----------Overflow Math Instructions-----------------------------------------
13633
13634 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
13635 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
13636 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
13637
13638 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13639 match(Set cr0 (OverflowAddL op1 op2));
13640
13641 format %{ "ADD_ $op1, $op2\t# overflow check long" %}
13642 size(12);
13643 ins_encode %{
13644 __ li(R0, 0);
13645 __ mtxer(R0); // clear XER.SO
13646 __ addo_(R0, $op1$$Register, $op2$$Register);
13647 %}
13648 ins_pipe(pipe_class_default);
13649 %}
13650
13651 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13652 match(Set cr0 (OverflowSubL op1 op2));
13653
13654 format %{ "SUBFO_ R0, $op2, $op1\t# overflow check long" %}
13655 size(12);
13656 ins_encode %{
13657 __ li(R0, 0);
13658 __ mtxer(R0); // clear XER.SO
13659 __ subfo_(R0, $op2$$Register, $op1$$Register);
13660 %}
13661 ins_pipe(pipe_class_default);
13662 %}
13663
13664 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
13665 match(Set cr0 (OverflowSubL zero op2));
13666
13667 format %{ "NEGO_ R0, $op2\t# overflow check long" %}
13668 size(12);
13669 ins_encode %{
13670 __ li(R0, 0);
13671 __ mtxer(R0); // clear XER.SO
13672 __ nego_(R0, $op2$$Register);
13673 %}
13674 ins_pipe(pipe_class_default);
13675 %}
13676
13677 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13678 match(Set cr0 (OverflowMulL op1 op2));
13679
13680 format %{ "MULLDO_ R0, $op1, $op2\t# overflow check long" %}
13681 size(12);
13682 ins_encode %{
13683 __ li(R0, 0);
13684 __ mtxer(R0); // clear XER.SO
13685 __ mulldo_(R0, $op1$$Register, $op2$$Register);
13686 %}
13687 ins_pipe(pipe_class_default);
13688 %}
13689
13690 instruct repl4F_reg_Ex(vecX dst, regF src) %{
13691 match(Set dst (Replicate src));
13692 predicate(n->as_Vector()->length() == 4 &&
13693 Matcher::vector_element_basic_type(n) == T_FLOAT);
13694 ins_cost(DEFAULT_COST);
13695 expand %{
13696 vecX tmpV;
13697 immI8 zero %{ (int) 0 %}
13698
13699 xscvdpspn_regF(tmpV, src);
13700 xxspltw(dst, tmpV, zero);
13701 %}
13702 %}
13703
13704 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{
13705 match(Set dst (Replicate src));
13706 predicate(n->as_Vector()->length() == 4 &&
13707 Matcher::vector_element_basic_type(n) == T_FLOAT);
13708 effect(TEMP tmp);
13709 ins_cost(10 * DEFAULT_COST);
13710
13711 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) );
13712 %}
13713
13714 instruct repl4F_immF0(vecX dst, immF_0 zero) %{
13715 match(Set dst (Replicate zero));
13716 predicate(n->as_Vector()->length() == 4 &&
13717 Matcher::vector_element_basic_type(n) == T_FLOAT);
13718
13719 format %{ "XXLXOR $dst, $zero \t// replicate4F" %}
13720 size(4);
13721 ins_encode %{
13722 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13723 %}
13724 ins_pipe(pipe_class_default);
13725 %}
13726
13727 instruct repl2D_reg_Ex(vecX dst, regD src) %{
13728 match(Set dst (Replicate src));
13729 predicate(n->as_Vector()->length() == 2 &&
13730 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13731
13732 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %}
13733 size(4);
13734 ins_encode %{
13735 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0);
13736 %}
13737 ins_pipe(pipe_class_default);
13738 %}
13739
13740 instruct repl2D_immD0(vecX dst, immD_0 zero) %{
13741 match(Set dst (Replicate zero));
13742 predicate(n->as_Vector()->length() == 2 &&
13743 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13744
13745 format %{ "XXLXOR $dst, $zero \t// replicate2D" %}
13746 size(4);
13747 ins_encode %{
13748 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13749 %}
13750 ins_pipe(pipe_class_default);
13751 %}
13752
13753 instruct mtvsrd(vecX dst, iRegLsrc src) %{
13754 predicate(false);
13755 effect(DEF dst, USE src);
13756
13757 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %}
13758 size(4);
13759 ins_encode %{
13760 __ mtvsrd($dst$$VectorRegister->to_vsr(), $src$$Register);
13761 %}
13762 ins_pipe(pipe_class_default);
13763 %}
13764
13765 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{
13766 effect(DEF dst, USE src, USE zero);
13767
13768 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %}
13769 size(4);
13770 ins_encode %{
13771 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $zero$$constant);
13772 %}
13773 ins_pipe(pipe_class_default);
13774 %}
13775
13776 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{
13777 effect(DEF dst, USE src1, USE src2, USE zero);
13778
13779 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %}
13780 size(4);
13781 ins_encode %{
13782 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr(), $zero$$constant);
13783 %}
13784 ins_pipe(pipe_class_default);
13785 %}
13786
13787 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{
13788 predicate(Matcher::vector_element_basic_type(n) == T_LONG);
13789 match(Set dst (Replicate src));
13790 predicate(n->as_Vector()->length() == 2);
13791 expand %{
13792 vecX tmpV;
13793 immI8 zero %{ (int) 0 %}
13794 mtvsrd(tmpV, src);
13795 xxpermdi(dst, tmpV, tmpV, zero);
13796 %}
13797 %}
13798
13799 instruct repl2L_immI0(vecX dst, immI_0 zero) %{
13800 match(Set dst (Replicate zero));
13801 predicate(n->as_Vector()->length() == 2 &&
13802 Matcher::vector_element_basic_type(n) == T_LONG);
13803
13804 format %{ "XXLXOR $dst, $zero \t// replicate2L" %}
13805 size(4);
13806 ins_encode %{
13807 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13808 %}
13809 ins_pipe(pipe_class_default);
13810 %}
13811
13812 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{
13813 match(Set dst (Replicate src));
13814 predicate(n->as_Vector()->length() == 2 &&
13815 Matcher::vector_element_basic_type(n) == T_LONG);
13816
13817 format %{ "XXLEQV $dst, $src \t// replicate2L" %}
13818 size(4);
13819 ins_encode %{
13820 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13821 %}
13822 ins_pipe(pipe_class_default);
13823 %}
13824
13825 // ============================================================================
13826 // Safepoint Instruction
13827
13828 instruct safePoint_poll(iRegPdst poll) %{
13829 match(SafePoint poll);
13830
13831 // It caused problems to add the effect that r0 is killed, but this
13832 // effect no longer needs to be mentioned, since r0 is not contained
13833 // in a reg_class.
13834
13835 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
13836 size(4);
13837 ins_encode( enc_poll(0x0, poll) );
13838 ins_pipe(pipe_class_default);
13839 %}
13840
13841 // ============================================================================
13842 // Call Instructions
13843
13844 source %{
13845
13846 #include "runtime/continuation.hpp"
13847
13848 %}
13849
13850 // Call Java Static Instruction
13851
13852 instruct CallStaticJavaDirect(method meth) %{
13853 match(CallStaticJava);
13854 effect(USE meth);
13855 ins_cost(CALL_COST);
13856
13857 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
13858
13859 format %{ "CALL,static $meth \t// ==> " %}
13860 size((Continuations::enabled() ? 8 : 4));
13861 ins_encode( enc_java_static_call(meth) );
13862 ins_pipe(pipe_class_call);
13863 %}
13864
13865 // Call Java Dynamic Instruction
13866
13867 instruct CallDynamicJavaDirect(method meth) %{
13868 match(CallDynamicJava);
13869 effect(USE meth);
13870 ins_cost(CALL_COST);
13871
13872 // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
13873 ins_num_consts(4);
13874
13875 format %{ "CALL,dynamic $meth \t// ==> " %}
13876 ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
13877 ins_pipe(pipe_class_call);
13878 %}
13879
13880 // Call Runtime Instruction
13881
13882 instruct CallRuntimeDirect(method meth) %{
13883 match(CallRuntime);
13884 effect(USE meth);
13885 ins_cost(CALL_COST);
13886
13887 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13888 // env for callee, C-toc.
13889 ins_num_consts(3);
13890
13891 format %{ "CALL,runtime" %}
13892 ins_encode( enc_java_to_runtime_call(meth) );
13893 ins_pipe(pipe_class_call);
13894 %}
13895
13896 // Call Leaf
13897
13898 // Used by postalloc expand of CallLeafDirect_Ex (mtctr).
13899 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
13900 effect(DEF dst, USE src);
13901
13902 ins_num_consts(1);
13903
13904 format %{ "MTCTR $src" %}
13905 size(4);
13906 ins_encode( enc_leaf_call_mtctr(src) );
13907 ins_pipe(pipe_class_default);
13908 %}
13909
13910 // Used by postalloc expand of CallLeafDirect_Ex (actual call).
13911 instruct CallLeafDirect(method meth) %{
13912 match(CallLeaf); // To get the data all the data fields we need ...
13913 effect(USE meth);
13914 predicate(false); // but never match.
13915
13916 format %{ "BCTRL \t// leaf call $meth ==> " %}
13917 size((Continuations::enabled() ? 8 : 4));
13918 ins_encode %{
13919 __ bctrl();
13920 __ post_call_nop();
13921 %}
13922 ins_pipe(pipe_class_call);
13923 %}
13924
13925 // postalloc expand of CallLeafDirect.
13926 // Load address to call from TOC, then bl to it.
13927 instruct CallLeafDirect_Ex(method meth) %{
13928 match(CallLeaf);
13929 effect(USE meth);
13930 ins_cost(CALL_COST);
13931
13932 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
13933 // env for callee, C-toc.
13934 ins_num_consts(3);
13935
13936 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
13937 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13938 %}
13939
13940 // Call runtime without safepoint - same as CallLeaf.
13941 // postalloc expand of CallLeafNoFPDirect.
13942 // Load address to call from TOC, then bl to it.
13943 instruct CallLeafNoFPDirect_Ex(method meth) %{
13944 match(CallLeafNoFP);
13945 effect(USE meth);
13946 ins_cost(CALL_COST);
13947
13948 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13949 // env for callee, C-toc.
13950 ins_num_consts(3);
13951
13952 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
13953 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13954 %}
13955
13956 // Tail Call; Jump from runtime stub to Java code.
13957 // Also known as an 'interprocedural jump'.
13958 // Target of jump will eventually return to caller.
13959 // TailJump below removes the return address.
13960 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{
13961 match(TailCall jump_target method_ptr);
13962 ins_cost(CALL_COST);
13963
13964 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t"
13965 "BCTR \t// tail call" %}
13966 size(8);
13967 ins_encode %{
13968 __ mtctr($jump_target$$Register);
13969 __ bctr();
13970 %}
13971 ins_pipe(pipe_class_call);
13972 %}
13973
13974 // Return Instruction
13975 instruct Ret() %{
13976 match(Return);
13977 format %{ "BLR \t// branch to link register" %}
13978 size(4);
13979 ins_encode %{
13980 // LR is restored in MachEpilogNode. Just do the RET here.
13981 __ blr();
13982 %}
13983 ins_pipe(pipe_class_default);
13984 %}
13985
13986 // Tail Jump; remove the return address; jump to target.
13987 // TailCall above leaves the return address around.
13988 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13989 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13990 // "restore" before this instruction (in Epilogue), we need to materialize it
13991 // in %i0.
13992 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
13993 match(TailJump jump_target ex_oop);
13994 ins_cost(CALL_COST);
13995
13996 format %{ "LD R4_ARG2 = LR\n\t"
13997 "MTCTR $jump_target\n\t"
13998 "BCTR \t// TailJump, exception oop: $ex_oop" %}
13999 size(12);
14000 ins_encode %{
14001 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP);
14002 __ mtctr($jump_target$$Register);
14003 __ bctr();
14004 %}
14005 ins_pipe(pipe_class_call);
14006 %}
14007
14008 // Forward exception.
14009 instruct ForwardExceptionjmp()
14010 %{
14011 match(ForwardException);
14012 ins_cost(CALL_COST);
14013
14014 format %{ "JMP forward_exception_stub" %}
14015 ins_encode %{
14016 __ set_inst_mark();
14017 __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
14018 __ clear_inst_mark();
14019 %}
14020 ins_pipe(pipe_class_call);
14021 %}
14022
14023 // Create exception oop: created by stack-crawling runtime code.
14024 // Created exception is now available to this handler, and is setup
14025 // just prior to jumping to this handler. No code emitted.
14026 instruct CreateException(rarg1RegP ex_oop) %{
14027 match(Set ex_oop (CreateEx));
14028 ins_cost(0);
14029
14030 format %{ " -- \t// exception oop; no code emitted" %}
14031 size(0);
14032 ins_encode( /*empty*/ );
14033 ins_pipe(pipe_class_default);
14034 %}
14035
14036 // Rethrow exception: The exception oop will come in the first
14037 // argument position. Then JUMP (not call) to the rethrow stub code.
14038 instruct RethrowException() %{
14039 match(Rethrow);
14040 ins_cost(CALL_COST);
14041
14042 format %{ "JMP rethrow_stub" %}
14043 ins_encode %{
14044 __ set_inst_mark();
14045 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
14046 __ clear_inst_mark();
14047 %}
14048 ins_pipe(pipe_class_call);
14049 %}
14050
14051 // Die now.
14052 instruct ShouldNotReachHere() %{
14053 match(Halt);
14054 ins_cost(CALL_COST);
14055
14056 format %{ "ShouldNotReachHere" %}
14057 ins_encode %{
14058 if (is_reachable()) {
14059 const char* str = __ code_string(_halt_reason);
14060 __ stop(str);
14061 }
14062 %}
14063 ins_pipe(pipe_class_default);
14064 %}
14065
14066 // This name is KNOWN by the ADLC and cannot be changed. The ADLC
14067 // forces a 'TypeRawPtr::BOTTOM' output type for this guy.
14068 // Get a DEF on threadRegP, no costs, no encoding, use
14069 // 'ins_should_rematerialize(true)' to avoid spilling.
14070 instruct tlsLoadP(threadRegP dst) %{
14071 match(Set dst (ThreadLocal));
14072 ins_cost(0);
14073
14074 ins_should_rematerialize(true);
14075
14076 format %{ " -- \t// $dst=Thread::current(), empty" %}
14077 size(0);
14078 ins_encode( /*empty*/ );
14079 ins_pipe(pipe_class_empty);
14080 %}
14081
14082 //---Some PPC specific nodes---------------------------------------------------
14083
14084 // Nop instructions
14085
14086 instruct fxNop() %{
14087 ins_cost(0);
14088
14089 ins_is_nop(true);
14090
14091 format %{ "fxNop" %}
14092 size(4);
14093 ins_encode %{
14094 __ nop();
14095 %}
14096 ins_pipe(pipe_class_default);
14097 %}
14098
14099 instruct fpNop0() %{
14100 ins_cost(0);
14101
14102 ins_is_nop(true);
14103
14104 format %{ "fpNop0" %}
14105 size(4);
14106 ins_encode %{
14107 __ fpnop0();
14108 %}
14109 ins_pipe(pipe_class_default);
14110 %}
14111
14112 instruct fpNop1() %{
14113 ins_cost(0);
14114
14115 ins_is_nop(true);
14116
14117 format %{ "fpNop1" %}
14118 size(4);
14119 ins_encode %{
14120 __ fpnop1();
14121 %}
14122 ins_pipe(pipe_class_default);
14123 %}
14124
14125 instruct brNop0() %{
14126 ins_cost(0);
14127 size(4);
14128 format %{ "brNop0" %}
14129 ins_encode %{
14130 __ brnop0();
14131 %}
14132 ins_is_nop(true);
14133 ins_pipe(pipe_class_default);
14134 %}
14135
14136 instruct brNop1() %{
14137 ins_cost(0);
14138
14139 ins_is_nop(true);
14140
14141 format %{ "brNop1" %}
14142 size(4);
14143 ins_encode %{
14144 __ brnop1();
14145 %}
14146 ins_pipe(pipe_class_default);
14147 %}
14148
14149 instruct brNop2() %{
14150 ins_cost(0);
14151
14152 ins_is_nop(true);
14153
14154 format %{ "brNop2" %}
14155 size(4);
14156 ins_encode %{
14157 __ brnop2();
14158 %}
14159 ins_pipe(pipe_class_default);
14160 %}
14161
14162 instruct cacheWB(indirect addr)
14163 %{
14164 match(CacheWB addr);
14165
14166 ins_cost(100);
14167 format %{ "cache writeback, address = $addr" %}
14168 ins_encode %{
14169 assert($addr->index_position() < 0, "should be");
14170 assert($addr$$disp == 0, "should be");
14171 __ cache_wb(Address($addr$$base$$Register));
14172 %}
14173 ins_pipe(pipe_class_default);
14174 %}
14175
14176 instruct cacheWBPreSync()
14177 %{
14178 match(CacheWBPreSync);
14179
14180 ins_cost(0);
14181 format %{ "cache writeback presync" %}
14182 ins_encode %{
14183 __ cache_wbsync(true);
14184 %}
14185 ins_pipe(pipe_class_default);
14186 %}
14187
14188 instruct cacheWBPostSync()
14189 %{
14190 match(CacheWBPostSync);
14191
14192 ins_cost(100);
14193 format %{ "cache writeback postsync" %}
14194 ins_encode %{
14195 __ cache_wbsync(false);
14196 %}
14197 ins_pipe(pipe_class_default);
14198 %}
14199
14200 //----------PEEPHOLE RULES-----------------------------------------------------
14201 // These must follow all instruction definitions as they use the names
14202 // defined in the instructions definitions.
14203 //
14204 // peepmatch ( root_instr_name [preceeding_instruction]* );
14205 //
14206 // peepconstraint %{
14207 // (instruction_number.operand_name relational_op instruction_number.operand_name
14208 // [, ...] );
14209 // // instruction numbers are zero-based using left to right order in peepmatch
14210 //
14211 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14212 // // provide an instruction_number.operand_name for each operand that appears
14213 // // in the replacement instruction's match rule
14214 //
14215 // ---------VM FLAGS---------------------------------------------------------
14216 //
14217 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14218 //
14219 // Each peephole rule is given an identifying number starting with zero and
14220 // increasing by one in the order seen by the parser. An individual peephole
14221 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14222 // on the command-line.
14223 //
14224 // ---------CURRENT LIMITATIONS----------------------------------------------
14225 //
14226 // Only match adjacent instructions in same basic block
14227 // Only equality constraints
14228 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14229 // Only one replacement instruction
14230 //
14231 // ---------EXAMPLE----------------------------------------------------------
14232 //
14233 // // pertinent parts of existing instructions in architecture description
14234 // instruct movI(eRegI dst, eRegI src) %{
14235 // match(Set dst (CopyI src));
14236 // %}
14237 //
14238 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14239 // match(Set dst (AddI dst src));
14240 // effect(KILL cr);
14241 // %}
14242 //
14243 // // Change (inc mov) to lea
14244 // peephole %{
14245 // // increment preceded by register-register move
14246 // peepmatch ( incI_eReg movI );
14247 // // require that the destination register of the increment
14248 // // match the destination register of the move
14249 // peepconstraint ( 0.dst == 1.dst );
14250 // // construct a replacement instruction that sets
14251 // // the destination to ( move's source register + one )
14252 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14253 // %}
14254 //
14255 // Implementation no longer uses movX instructions since
14256 // machine-independent system no longer uses CopyX nodes.
14257 //
14258 // peephole %{
14259 // peepmatch ( incI_eReg movI );
14260 // peepconstraint ( 0.dst == 1.dst );
14261 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14262 // %}
14263 //
14264 // peephole %{
14265 // peepmatch ( decI_eReg movI );
14266 // peepconstraint ( 0.dst == 1.dst );
14267 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14268 // %}
14269 //
14270 // peephole %{
14271 // peepmatch ( addI_eReg_imm movI );
14272 // peepconstraint ( 0.dst == 1.dst );
14273 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14274 // %}
14275 //
14276 // peephole %{
14277 // peepmatch ( addP_eReg_imm movP );
14278 // peepconstraint ( 0.dst == 1.dst );
14279 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
14280 // %}
14281
14282 // // Change load of spilled value to only a spill
14283 // instruct storeI(memory mem, eRegI src) %{
14284 // match(Set mem (StoreI mem src));
14285 // %}
14286 //
14287 // instruct loadI(eRegI dst, memory mem) %{
14288 // match(Set dst (LoadI mem));
14289 // %}
14290 //
14291 peephole %{
14292 peepmatch ( loadI storeI );
14293 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14294 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14295 %}
14296
14297 peephole %{
14298 peepmatch ( loadL storeL );
14299 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14300 peepreplace ( storeL( 1.mem 1.mem 1.src ) );
14301 %}
14302
14303 peephole %{
14304 peepmatch ( loadP storeP );
14305 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
14306 peepreplace ( storeP( 1.dst 1.dst 1.src ) );
14307 %}
14308
14309 //----------SMARTSPILL RULES---------------------------------------------------
14310 // These must follow all instruction definitions as they use the names
14311 // defined in the instructions definitions.