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
2140 return true; // Per default match rules are supported.
2141 }
2142
2143 bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
2144 return match_rule_supported_vector(opcode, vlen, bt);
2145 }
2146
2147 bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
2148 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
2149 return false;
2150 }
2151 // Special cases
2152 switch (opcode) {
2153 // Reductions only support INT at the moment.
2154 case Op_AddReductionVI:
2155 case Op_MulReductionVI:
2156 case Op_AndReductionV:
2157 case Op_OrReductionV:
2158 case Op_XorReductionV:
2159 case Op_MinReductionV:
2160 case Op_MaxReductionV:
2161 return bt == T_INT;
2162 // MaxV, MinV need types == INT || LONG.
2163 case Op_MaxV:
2164 case Op_MinV:
2165 case Op_UMinV:
2166 case Op_UMaxV:
2167 return bt == T_INT || bt == T_LONG;
2168 case Op_NegVI:
2169 return bt == T_INT;
2170 }
2171 return true; // Per default match rules are supported.
2172 }
2173
2174 bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
2175 return false;
2176 }
2177
2178 bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
2179 return false;
2180 }
2181
2182 bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
2183 return false;
2184 }
2185
2186 bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
2187 return false;
2188 }
2189
2190 const RegMask* Matcher::predicate_reg_mask(void) {
2191 return nullptr;
2192 }
2193
2194 // Vector calling convention not yet implemented.
2195 bool Matcher::supports_vector_calling_convention(void) {
2196 return false;
2197 }
2198
2199 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2200 Unimplemented();
2201 return OptoRegPair(0, 0);
2202 }
2203
2204 // Vector width in bytes.
2205 int Matcher::vector_width_in_bytes(BasicType bt) {
2206 if (SuperwordUseVSX) {
2207 assert(MaxVectorSize == 16,
2208 "SuperwordUseVSX requires MaxVectorSize 16, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2209 return 16;
2210 } else {
2211 assert(MaxVectorSize == 8,
2212 "expected MaxVectorSize 8, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2213 return 8;
2214 }
2215 }
2216
2217 // Vector ideal reg.
2218 uint Matcher::vector_ideal_reg(int size) {
2219 if (SuperwordUseVSX) {
2220 assert(MaxVectorSize == 16 && size == 16,
2221 "SuperwordUseVSX requires MaxVectorSize 16 and size 16, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2222 (int64_t)MaxVectorSize, size);
2223 return Op_VecX;
2224 } else {
2225 assert(MaxVectorSize == 8 && size == 8,
2226 "expected MaxVectorSize 8 and size 8, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2227 (int64_t)MaxVectorSize, size);
2228 return Op_RegL;
2229 }
2230 }
2231
2232 // Limits on vector size (number of elements) loaded into vector.
2233 int Matcher::max_vector_size(const BasicType bt) {
2234 assert(is_java_primitive(bt), "only primitive type vectors");
2235 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2236 }
2237
2238 int Matcher::min_vector_size(const BasicType bt) {
2239 return max_vector_size(bt); // Same as max.
2240 }
2241
2242 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
2243 return Matcher::max_vector_size(bt);
2244 }
2245
2246 int Matcher::scalable_vector_reg_size(const BasicType bt) {
2247 return -1;
2248 }
2249
2250 // RETURNS: whether this branch offset is short enough that a short
2251 // branch can be used.
2252 //
2253 // If the platform does not provide any short branch variants, then
2254 // this method should return `false' for offset 0.
2255 //
2256 // `Compile::Fill_buffer' will decide on basis of this information
2257 // whether to do the pass `Compile::Shorten_branches' at all.
2258 //
2259 // And `Compile::Shorten_branches' will decide on basis of this
2260 // information whether to replace particular branch sites by short
2261 // ones.
2262 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2263 // Is the offset within the range of a ppc64 pc relative branch?
2264 bool b;
2265
2266 const int safety_zone = 3 * BytesPerInstWord;
2267 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2268 29 - 16 + 1 + 2);
2269 return b;
2270 }
2271
2272 /* TODO: PPC port
2273 // Make a new machine dependent decode node (with its operands).
2274 MachTypeNode *Matcher::make_decode_node() {
2275 assert(CompressedOops::base() == nullptr && CompressedOops::shift() == 0,
2276 "This method is only implemented for unscaled cOops mode so far");
2277 MachTypeNode *decode = new decodeN_unscaledNode();
2278 decode->set_opnd_array(0, new iRegPdstOper());
2279 decode->set_opnd_array(1, new iRegNsrcOper());
2280 return decode;
2281 }
2282 */
2283
2284 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
2285 ShouldNotReachHere(); // generic vector operands not supported
2286 return nullptr;
2287 }
2288
2289 bool Matcher::is_reg2reg_move(MachNode* m) {
2290 ShouldNotReachHere(); // generic vector operands not supported
2291 return false;
2292 }
2293
2294 bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
2295 return false;
2296 }
2297
2298 bool Matcher::is_generic_vector(MachOper* opnd) {
2299 ShouldNotReachHere(); // generic vector operands not supported
2300 return false;
2301 }
2302
2303 #ifdef ASSERT
2304 // Return whether or not this register is ever used as an argument.
2305 bool Matcher::can_be_java_arg(int reg) {
2306 // We must include the virtual halves in order to get STDs and LDs
2307 // instead of STWs and LWs in the trampoline stubs.
2308
2309 if ( reg == R3_num || reg == R3_H_num
2310 || reg == R4_num || reg == R4_H_num
2311 || reg == R5_num || reg == R5_H_num
2312 || reg == R6_num || reg == R6_H_num
2313 || reg == R7_num || reg == R7_H_num
2314 || reg == R8_num || reg == R8_H_num
2315 || reg == R9_num || reg == R9_H_num
2316 || reg == R10_num || reg == R10_H_num)
2317 return true;
2318
2319 if ( reg == F1_num || reg == F1_H_num
2320 || reg == F2_num || reg == F2_H_num
2321 || reg == F3_num || reg == F3_H_num
2322 || reg == F4_num || reg == F4_H_num
2323 || reg == F5_num || reg == F5_H_num
2324 || reg == F6_num || reg == F6_H_num
2325 || reg == F7_num || reg == F7_H_num
2326 || reg == F8_num || reg == F8_H_num
2327 || reg == F9_num || reg == F9_H_num
2328 || reg == F10_num || reg == F10_H_num
2329 || reg == F11_num || reg == F11_H_num
2330 || reg == F12_num || reg == F12_H_num
2331 || reg == F13_num || reg == F13_H_num)
2332 return true;
2333
2334 return false;
2335 }
2336 #endif
2337
2338 uint Matcher::int_pressure_limit()
2339 {
2340 return (INTPRESSURE == -1) ? 26 : INTPRESSURE;
2341 }
2342
2343 uint Matcher::float_pressure_limit()
2344 {
2345 return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE;
2346 }
2347
2348 // Register for DIVI projection of divmodI.
2349 const RegMask& Matcher::divI_proj_mask() {
2350 ShouldNotReachHere();
2351 return RegMask::EMPTY;
2352 }
2353
2354 // Register for MODI projection of divmodI.
2355 const RegMask& Matcher::modI_proj_mask() {
2356 ShouldNotReachHere();
2357 return RegMask::EMPTY;
2358 }
2359
2360 // Register for DIVL projection of divmodL.
2361 const RegMask& Matcher::divL_proj_mask() {
2362 ShouldNotReachHere();
2363 return RegMask::EMPTY;
2364 }
2365
2366 // Register for MODL projection of divmodL.
2367 const RegMask& Matcher::modL_proj_mask() {
2368 ShouldNotReachHere();
2369 return RegMask::EMPTY;
2370 }
2371
2372 %}
2373
2374 //----------ENCODING BLOCK-----------------------------------------------------
2375 // This block specifies the encoding classes used by the compiler to output
2376 // byte streams. Encoding classes are parameterized macros used by
2377 // Machine Instruction Nodes in order to generate the bit encoding of the
2378 // instruction. Operands specify their base encoding interface with the
2379 // interface keyword. There are currently supported four interfaces,
2380 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
2381 // operand to generate a function which returns its register number when
2382 // queried. CONST_INTER causes an operand to generate a function which
2383 // returns the value of the constant when queried. MEMORY_INTER causes an
2384 // operand to generate four functions which return the Base Register, the
2385 // Index Register, the Scale Value, and the Offset Value of the operand when
2386 // queried. COND_INTER causes an operand to generate six functions which
2387 // return the encoding code (ie - encoding bits for the instruction)
2388 // associated with each basic boolean condition for a conditional instruction.
2389 //
2390 // Instructions specify two basic values for encoding. Again, a function
2391 // is available to check if the constant displacement is an oop. They use the
2392 // ins_encode keyword to specify their encoding classes (which must be
2393 // a sequence of enc_class names, and their parameters, specified in
2394 // the encoding block), and they use the
2395 // opcode keyword to specify, in order, their primary, secondary, and
2396 // tertiary opcode. Only the opcode sections which a particular instruction
2397 // needs for encoding need to be specified.
2398 encode %{
2399 enc_class enc_unimplemented %{
2400 __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
2401 %}
2402
2403 enc_class enc_untested %{
2404 #ifdef ASSERT
2405 __ untested("Untested mach node encoding in AD file.");
2406 #else
2407 #endif
2408 %}
2409
2410 enc_class enc_lbz(iRegIdst dst, memory mem) %{
2411 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2412 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2413 %}
2414
2415 // Load acquire.
2416 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
2417 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2418 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2419 __ twi_0($dst$$Register);
2420 __ isync();
2421 %}
2422
2423 enc_class enc_lhz(iRegIdst dst, memory mem) %{
2424 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2425 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2426 %}
2427
2428 // Load acquire.
2429 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
2430 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2431 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2432 __ twi_0($dst$$Register);
2433 __ isync();
2434 %}
2435
2436 enc_class enc_lwz(iRegIdst dst, memory mem) %{
2437 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2438 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2439 %}
2440
2441 // Load acquire.
2442 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
2443 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2444 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2445 __ twi_0($dst$$Register);
2446 __ isync();
2447 %}
2448
2449 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
2450 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2451 // Operand 'ds' requires 4-alignment.
2452 assert((Idisp & 0x3) == 0, "unaligned offset");
2453 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2454 %}
2455
2456 // Load acquire.
2457 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
2458 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2459 // Operand 'ds' requires 4-alignment.
2460 assert((Idisp & 0x3) == 0, "unaligned offset");
2461 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2462 __ twi_0($dst$$Register);
2463 __ isync();
2464 %}
2465
2466 enc_class enc_lfd(RegF dst, memory mem) %{
2467 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2468 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2469 %}
2470
2471 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2472 int toc_offset = 0;
2473
2474 address const_toc_addr;
2475 // Create a non-oop constant, no relocation needed.
2476 // If it is an IC, it has a virtual_call_Relocation.
2477 const_toc_addr = __ long_constant((jlong)$src$$constant);
2478 if (const_toc_addr == nullptr) {
2479 ciEnv::current()->record_out_of_memory_failure();
2480 return;
2481 }
2482
2483 // Get the constant's TOC offset.
2484 toc_offset = __ offset_to_method_toc(const_toc_addr);
2485
2486 // Keep the current instruction offset in mind.
2487 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2488
2489 __ ld($dst$$Register, toc_offset, $toc$$Register);
2490 %}
2491
2492 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2493 if (!ra_->C->output()->in_scratch_emit_size()) {
2494 address const_toc_addr;
2495 // Create a non-oop constant, no relocation needed.
2496 // If it is an IC, it has a virtual_call_Relocation.
2497 const_toc_addr = __ long_constant((jlong)$src$$constant);
2498 if (const_toc_addr == nullptr) {
2499 ciEnv::current()->record_out_of_memory_failure();
2500 return;
2501 }
2502
2503 // Get the constant's TOC offset.
2504 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2505 // Store the toc offset of the constant.
2506 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2507
2508 // Also keep the current instruction offset in mind.
2509 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2510 }
2511
2512 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2513 %}
2514
2515 %} // encode
2516
2517 source %{
2518
2519 typedef struct {
2520 loadConL_hiNode *_large_hi;
2521 loadConL_loNode *_large_lo;
2522 loadConLNode *_small;
2523 MachNode *_last;
2524 } loadConLNodesTuple;
2525
2526 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2527 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2528 loadConLNodesTuple nodes;
2529
2530 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2531 if (large_constant_pool) {
2532 // Create new nodes.
2533 loadConL_hiNode *m1 = new loadConL_hiNode();
2534 loadConL_loNode *m2 = new loadConL_loNode();
2535
2536 // inputs for new nodes
2537 m1->add_req(nullptr, toc);
2538 m2->add_req(nullptr, m1);
2539
2540 // operands for new nodes
2541 m1->_opnds[0] = new iRegLdstOper(); // dst
2542 m1->_opnds[1] = immSrc; // src
2543 m1->_opnds[2] = new iRegLdstOper(); // toc
2544 m2->_opnds[0] = new iRegLdstOper(); // dst
2545 m2->_opnds[1] = immSrc; // src
2546 m2->_opnds[2] = new iRegLdstOper(); // base
2547
2548 // Initialize ins_attrib TOC fields.
2549 m1->_const_toc_offset = -1;
2550 m2->_const_toc_offset_hi_node = m1;
2551
2552 // Initialize ins_attrib instruction offset.
2553 m1->_cbuf_insts_offset = -1;
2554
2555 // register allocation for new nodes
2556 ra_->set_pair(m1->_idx, reg_second, reg_first);
2557 ra_->set_pair(m2->_idx, reg_second, reg_first);
2558
2559 // Create result.
2560 nodes._large_hi = m1;
2561 nodes._large_lo = m2;
2562 nodes._small = nullptr;
2563 nodes._last = nodes._large_lo;
2564 assert(m2->bottom_type()->isa_long(), "must be long");
2565 } else {
2566 loadConLNode *m2 = new loadConLNode();
2567
2568 // inputs for new nodes
2569 m2->add_req(nullptr, toc);
2570
2571 // operands for new nodes
2572 m2->_opnds[0] = new iRegLdstOper(); // dst
2573 m2->_opnds[1] = immSrc; // src
2574 m2->_opnds[2] = new iRegLdstOper(); // toc
2575
2576 // Initialize ins_attrib instruction offset.
2577 m2->_cbuf_insts_offset = -1;
2578
2579 // register allocation for new nodes
2580 ra_->set_pair(m2->_idx, reg_second, reg_first);
2581
2582 // Create result.
2583 nodes._large_hi = nullptr;
2584 nodes._large_lo = nullptr;
2585 nodes._small = m2;
2586 nodes._last = nodes._small;
2587 assert(m2->bottom_type()->isa_long(), "must be long");
2588 }
2589
2590 return nodes;
2591 }
2592
2593 typedef struct {
2594 loadConL_hiNode *_large_hi;
2595 loadConL_loNode *_large_lo;
2596 mtvsrdNode *_moved;
2597 xxspltdNode *_replicated;
2598 loadConLNode *_small;
2599 MachNode *_last;
2600 } loadConLReplicatedNodesTuple;
2601
2602 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2603 vecXOper *dst, immI_0Oper *zero,
2604 OptoReg::Name reg_second, OptoReg::Name reg_first,
2605 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) {
2606 loadConLReplicatedNodesTuple nodes;
2607
2608 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2609 if (large_constant_pool) {
2610 // Create new nodes.
2611 loadConL_hiNode *m1 = new loadConL_hiNode();
2612 loadConL_loNode *m2 = new loadConL_loNode();
2613 mtvsrdNode *m3 = new mtvsrdNode();
2614 xxspltdNode *m4 = new xxspltdNode();
2615
2616 // inputs for new nodes
2617 m1->add_req(nullptr, toc);
2618 m2->add_req(nullptr, m1);
2619 m3->add_req(nullptr, m2);
2620 m4->add_req(nullptr, m3);
2621
2622 // operands for new nodes
2623 m1->_opnds[0] = new iRegLdstOper(); // dst
2624 m1->_opnds[1] = immSrc; // src
2625 m1->_opnds[2] = new iRegLdstOper(); // toc
2626
2627 m2->_opnds[0] = new iRegLdstOper(); // dst
2628 m2->_opnds[1] = immSrc; // src
2629 m2->_opnds[2] = new iRegLdstOper(); // base
2630
2631 m3->_opnds[0] = new vecXOper(); // dst
2632 m3->_opnds[1] = new iRegLdstOper(); // src
2633
2634 m4->_opnds[0] = new vecXOper(); // dst
2635 m4->_opnds[1] = new vecXOper(); // src
2636 m4->_opnds[2] = zero;
2637
2638 // Initialize ins_attrib TOC fields.
2639 m1->_const_toc_offset = -1;
2640 m2->_const_toc_offset_hi_node = m1;
2641
2642 // Initialize ins_attrib instruction offset.
2643 m1->_cbuf_insts_offset = -1;
2644
2645 // register allocation for new nodes
2646 ra_->set_pair(m1->_idx, reg_second, reg_first);
2647 ra_->set_pair(m2->_idx, reg_second, reg_first);
2648 ra_->set1(m3->_idx, reg_second);
2649 ra_->set2(m3->_idx, reg_vec_first);
2650 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2651
2652 // Create result.
2653 nodes._large_hi = m1;
2654 nodes._large_lo = m2;
2655 nodes._moved = m3;
2656 nodes._replicated = m4;
2657 nodes._small = nullptr;
2658 nodes._last = nodes._replicated;
2659 assert(m2->bottom_type()->isa_long(), "must be long");
2660 } else {
2661 loadConLNode *m2 = new loadConLNode();
2662 mtvsrdNode *m3 = new mtvsrdNode();
2663 xxspltdNode *m4 = new xxspltdNode();
2664
2665 // inputs for new nodes
2666 m2->add_req(nullptr, toc);
2667
2668 // operands for new nodes
2669 m2->_opnds[0] = new iRegLdstOper(); // dst
2670 m2->_opnds[1] = immSrc; // src
2671 m2->_opnds[2] = new iRegLdstOper(); // toc
2672
2673 m3->_opnds[0] = new vecXOper(); // dst
2674 m3->_opnds[1] = new iRegLdstOper(); // src
2675
2676 m4->_opnds[0] = new vecXOper(); // dst
2677 m4->_opnds[1] = new vecXOper(); // src
2678 m4->_opnds[2] = zero;
2679
2680 // Initialize ins_attrib instruction offset.
2681 m2->_cbuf_insts_offset = -1;
2682 ra_->set1(m3->_idx, reg_second);
2683 ra_->set2(m3->_idx, reg_vec_first);
2684 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2685
2686 // register allocation for new nodes
2687 ra_->set_pair(m2->_idx, reg_second, reg_first);
2688
2689 // Create result.
2690 nodes._large_hi = nullptr;
2691 nodes._large_lo = nullptr;
2692 nodes._small = m2;
2693 nodes._moved = m3;
2694 nodes._replicated = m4;
2695 nodes._last = nodes._replicated;
2696 assert(m2->bottom_type()->isa_long(), "must be long");
2697 }
2698
2699 return nodes;
2700 }
2701
2702 %} // source
2703
2704 encode %{
2705 // Postalloc expand emitter for loading a long constant from the method's TOC.
2706 // Enc_class needed as consttanttablebase is not supported by postalloc
2707 // expand.
2708 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2709 // Create new nodes.
2710 loadConLNodesTuple loadConLNodes =
2711 loadConLNodesTuple_create(ra_, n_toc, op_src,
2712 ra_->get_reg_second(this), ra_->get_reg_first(this));
2713
2714 // Push new nodes.
2715 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2716 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2717
2718 // some asserts
2719 assert(nodes->length() >= 1, "must have created at least 1 node");
2720 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2721 %}
2722
2723 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2724 int toc_offset = 0;
2725
2726 intptr_t val = $src$$constant;
2727 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2728 address const_toc_addr;
2729 RelocationHolder r; // Initializes type to none.
2730 if (constant_reloc == relocInfo::oop_type) {
2731 // Create an oop constant and a corresponding relocation.
2732 AddressLiteral a = __ constant_oop_address((jobject)val);
2733 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2734 r = a.rspec();
2735 } else if (constant_reloc == relocInfo::metadata_type) {
2736 // Notify OOP recorder (don't need the relocation)
2737 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2738 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2739 } else {
2740 // Create a non-oop constant, no relocation needed.
2741 const_toc_addr = __ long_constant((jlong)$src$$constant);
2742 }
2743
2744 if (const_toc_addr == nullptr) {
2745 ciEnv::current()->record_out_of_memory_failure();
2746 return;
2747 }
2748 __ relocate(r); // If set above.
2749 // Get the constant's TOC offset.
2750 toc_offset = __ offset_to_method_toc(const_toc_addr);
2751
2752 __ ld($dst$$Register, toc_offset, $toc$$Register);
2753 %}
2754
2755 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2756 if (!ra_->C->output()->in_scratch_emit_size()) {
2757 intptr_t val = $src$$constant;
2758 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2759 address const_toc_addr;
2760 RelocationHolder r; // Initializes type to none.
2761 if (constant_reloc == relocInfo::oop_type) {
2762 // Create an oop constant and a corresponding relocation.
2763 AddressLiteral a = __ constant_oop_address((jobject)val);
2764 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2765 r = a.rspec();
2766 } else if (constant_reloc == relocInfo::metadata_type) {
2767 // Notify OOP recorder (don't need the relocation)
2768 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2769 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2770 } else { // non-oop pointers, e.g. card mark base, heap top
2771 // Create a non-oop constant, no relocation needed.
2772 const_toc_addr = __ long_constant((jlong)$src$$constant);
2773 }
2774
2775 if (const_toc_addr == nullptr) {
2776 ciEnv::current()->record_out_of_memory_failure();
2777 return;
2778 }
2779 __ relocate(r); // If set above.
2780 // Get the constant's TOC offset.
2781 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2782 // Store the toc offset of the constant.
2783 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2784 }
2785
2786 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2787 %}
2788
2789 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2790 // Enc_class needed as consttanttablebase is not supported by postalloc
2791 // expand.
2792 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2793 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2794 if (large_constant_pool) {
2795 // Create new nodes.
2796 loadConP_hiNode *m1 = new loadConP_hiNode();
2797 loadConP_loNode *m2 = new loadConP_loNode();
2798
2799 // If this is an oop, both m1 and m2 must be consider oops so postalloc scheduling does not
2800 // put a safepoint between them
2801 m1->_bottom_type = bottom_type();
2802 m2->_bottom_type = bottom_type();
2803
2804 // inputs for new nodes
2805 m1->add_req(nullptr, n_toc);
2806 m2->add_req(nullptr, m1);
2807
2808 // operands for new nodes
2809 m1->_opnds[0] = new iRegPdstOper(); // dst
2810 m1->_opnds[1] = op_src; // src
2811 m1->_opnds[2] = new iRegLdstOper(); // toc
2812
2813 m2->_opnds[0] = new iRegPdstOper(); // dst
2814 m2->_opnds[1] = op_src; // src
2815 m2->_opnds[2] = new iRegLdstOper(); // base
2816
2817 // Initialize ins_attrib TOC fields.
2818 m1->_const_toc_offset = -1;
2819 m2->_const_toc_offset_hi_node = m1;
2820
2821 // Register allocation for new nodes.
2822 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2823 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2824
2825 nodes->push(m1);
2826 nodes->push(m2);
2827 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2828 } else {
2829 loadConPNode *m2 = new loadConPNode();
2830
2831 // inputs for new nodes
2832 m2->add_req(nullptr, n_toc);
2833
2834 // operands for new nodes
2835 m2->_opnds[0] = new iRegPdstOper(); // dst
2836 m2->_opnds[1] = op_src; // src
2837 m2->_opnds[2] = new iRegLdstOper(); // toc
2838
2839 // Register allocation for new nodes.
2840 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2841
2842 nodes->push(m2);
2843 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2844 }
2845 %}
2846
2847 // Enc_class needed as consttanttablebase is not supported by postalloc
2848 // expand.
2849 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2850 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2851
2852 MachNode *m2;
2853 if (large_constant_pool) {
2854 m2 = new loadConFCompNode();
2855 } else {
2856 m2 = new loadConFNode();
2857 }
2858 // inputs for new nodes
2859 m2->add_req(nullptr, n_toc);
2860
2861 // operands for new nodes
2862 m2->_opnds[0] = op_dst;
2863 m2->_opnds[1] = op_src;
2864 m2->_opnds[2] = new iRegLdstOper(); // constanttablebase
2865
2866 // register allocation for new nodes
2867 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2868 nodes->push(m2);
2869 %}
2870
2871 // Enc_class needed as consttanttablebase is not supported by postalloc
2872 // expand.
2873 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2874 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2875
2876 MachNode *m2;
2877 if (large_constant_pool) {
2878 m2 = new loadConDCompNode();
2879 } else {
2880 m2 = new loadConDNode();
2881 }
2882 // inputs for new nodes
2883 m2->add_req(nullptr, n_toc);
2884
2885 // operands for new nodes
2886 m2->_opnds[0] = op_dst;
2887 m2->_opnds[1] = op_src;
2888 m2->_opnds[2] = new iRegLdstOper(); // constanttablebase
2889
2890 // register allocation for new nodes
2891 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2892 nodes->push(m2);
2893 %}
2894
2895 enc_class enc_stw(iRegIsrc src, memory mem) %{
2896 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2897 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2898 %}
2899
2900 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2901 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2902 // Operand 'ds' requires 4-alignment.
2903 assert((Idisp & 0x3) == 0, "unaligned offset");
2904 __ std($src$$Register, Idisp, $mem$$base$$Register);
2905 %}
2906
2907 enc_class enc_stfs(RegF src, memory mem) %{
2908 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2909 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2910 %}
2911
2912 enc_class enc_stfd(RegF src, memory mem) %{
2913 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2914 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2915 %}
2916
2917 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2918 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
2919 encodeP_subNode *n_sub_base = new encodeP_subNode();
2920 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
2921 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode();
2922
2923 n_compare->add_req(n_region, n_src);
2924 n_compare->_opnds[0] = op_crx;
2925 n_compare->_opnds[1] = op_src;
2926 n_compare->_opnds[2] = new immL16Oper(0);
2927
2928 n_sub_base->add_req(n_region, n_src);
2929 n_sub_base->_opnds[0] = op_dst;
2930 n_sub_base->_opnds[1] = op_src;
2931 n_sub_base->_bottom_type = _bottom_type;
2932
2933 n_shift->add_req(n_region, n_sub_base);
2934 n_shift->_opnds[0] = op_dst;
2935 n_shift->_opnds[1] = op_dst;
2936 n_shift->_bottom_type = _bottom_type;
2937
2938 n_cond_set->add_req(n_region, n_compare, n_shift);
2939 n_cond_set->_opnds[0] = op_dst;
2940 n_cond_set->_opnds[1] = op_crx;
2941 n_cond_set->_opnds[2] = op_dst;
2942 n_cond_set->_bottom_type = _bottom_type;
2943
2944 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2945 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2946 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2947 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2948
2949 nodes->push(n_compare);
2950 nodes->push(n_sub_base);
2951 nodes->push(n_shift);
2952 nodes->push(n_cond_set);
2953
2954 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2955 %}
2956
2957 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
2958
2959 encodeP_subNode *n1 = new encodeP_subNode();
2960 n1->add_req(n_region, n_src);
2961 n1->_opnds[0] = op_dst;
2962 n1->_opnds[1] = op_src;
2963 n1->_bottom_type = _bottom_type;
2964
2965 encodeP_shiftNode *n2 = new encodeP_shiftNode();
2966 n2->add_req(n_region, n1);
2967 n2->_opnds[0] = op_dst;
2968 n2->_opnds[1] = op_dst;
2969 n2->_bottom_type = _bottom_type;
2970 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2971 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2972
2973 nodes->push(n1);
2974 nodes->push(n2);
2975 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2976 %}
2977
2978 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
2979 decodeN_shiftNode *n_shift = new decodeN_shiftNode();
2980 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
2981
2982 n_compare->add_req(n_region, n_src);
2983 n_compare->_opnds[0] = op_crx;
2984 n_compare->_opnds[1] = op_src;
2985 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
2986
2987 n_shift->add_req(n_region, n_src);
2988 n_shift->_opnds[0] = op_dst;
2989 n_shift->_opnds[1] = op_src;
2990 n_shift->_bottom_type = _bottom_type;
2991
2992 decodeN_addNode *n_add_base = new decodeN_addNode();
2993 n_add_base->add_req(n_region, n_shift);
2994 n_add_base->_opnds[0] = op_dst;
2995 n_add_base->_opnds[1] = op_dst;
2996 n_add_base->_bottom_type = _bottom_type;
2997
2998 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
2999 n_cond_set->add_req(n_region, n_compare, n_add_base);
3000 n_cond_set->_opnds[0] = op_dst;
3001 n_cond_set->_opnds[1] = op_crx;
3002 n_cond_set->_opnds[2] = op_dst;
3003 n_cond_set->_bottom_type = _bottom_type;
3004
3005 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3006 ra_->set_oop(n_cond_set, true);
3007
3008 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3009 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3010 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3011 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3012
3013 nodes->push(n_compare);
3014 nodes->push(n_shift);
3015 nodes->push(n_add_base);
3016 nodes->push(n_cond_set);
3017
3018 %}
3019
3020 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3021 decodeN_shiftNode *n1 = new decodeN_shiftNode();
3022 n1->add_req(n_region, n_src);
3023 n1->_opnds[0] = op_dst;
3024 n1->_opnds[1] = op_src;
3025 n1->_bottom_type = _bottom_type;
3026
3027 decodeN_addNode *n2 = new decodeN_addNode();
3028 n2->add_req(n_region, n1);
3029 n2->_opnds[0] = op_dst;
3030 n2->_opnds[1] = op_dst;
3031 n2->_bottom_type = _bottom_type;
3032 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3033 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3034
3035 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3036 ra_->set_oop(n2, true);
3037
3038 nodes->push(n1);
3039 nodes->push(n2);
3040 %}
3041
3042
3043 // This enc_class is needed so that scheduler gets proper
3044 // input mapping for latency computation.
3045 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
3046 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
3047 %}
3048
3049 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3050 Label done;
3051 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3052 __ li($dst$$Register, $zero$$constant);
3053 __ beq($crx$$CondRegister, done);
3054 __ li($dst$$Register, $notzero$$constant);
3055 __ bind(done);
3056 %}
3057
3058 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3059 Label done;
3060 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3061 __ li($dst$$Register, $zero$$constant);
3062 __ beq($crx$$CondRegister, done);
3063 __ li($dst$$Register, $notzero$$constant);
3064 __ bind(done);
3065 %}
3066
3067 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3068 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3069 Label done;
3070 __ bso($crx$$CondRegister, done);
3071 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3072 __ bind(done);
3073 %}
3074
3075 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
3076 Label done;
3077 __ bso($crx$$CondRegister, done);
3078 __ mffprd($dst$$Register, $src$$FloatRegister);
3079 __ bind(done);
3080 %}
3081
3082 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3083 Label d; // dummy
3084 __ bind(d);
3085 Label* p = ($lbl$$label);
3086 // `p' is `nullptr' when this encoding class is used only to
3087 // determine the size of the encoded instruction.
3088 Label& l = (nullptr == p)? d : *(p);
3089 int cc = $cmp$$cmpcode;
3090 int flags_reg = $crx$$reg;
3091 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3092 int bhint = Assembler::bhintNoHint;
3093
3094 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3095 if (_prob <= PROB_NEVER) {
3096 bhint = Assembler::bhintIsNotTaken;
3097 } else if (_prob >= PROB_ALWAYS) {
3098 bhint = Assembler::bhintIsTaken;
3099 }
3100 }
3101
3102 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3103 cc_to_biint(cc, flags_reg),
3104 l);
3105 %}
3106
3107 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3108 // The scheduler doesn't know about branch shortening, so we set the opcode
3109 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3110 Label d; // dummy
3111 __ bind(d);
3112 Label* p = ($lbl$$label);
3113 // `p' is `nullptr' when this encoding class is used only to
3114 // determine the size of the encoded instruction.
3115 Label& l = (nullptr == p)? d : *(p);
3116 int cc = $cmp$$cmpcode;
3117 int flags_reg = $crx$$reg;
3118 int bhint = Assembler::bhintNoHint;
3119
3120 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3121 if (_prob <= PROB_NEVER) {
3122 bhint = Assembler::bhintIsNotTaken;
3123 } else if (_prob >= PROB_ALWAYS) {
3124 bhint = Assembler::bhintIsTaken;
3125 }
3126 }
3127
3128 // Tell the conditional far branch to optimize itself when being relocated.
3129 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3130 cc_to_biint(cc, flags_reg),
3131 l,
3132 MacroAssembler::bc_far_optimize_on_relocate);
3133 %}
3134
3135 // Postalloc expand emitter for loading a replicatef float constant from
3136 // the method's TOC.
3137 // Enc_class needed as consttanttablebase is not supported by postalloc
3138 // expand.
3139 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3140 // Create new nodes.
3141
3142 // Make an operand with the bit pattern to load as float.
3143 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3144
3145 loadConLNodesTuple loadConLNodes =
3146 loadConLNodesTuple_create(ra_, n_toc, op_repl,
3147 ra_->get_reg_second(this), ra_->get_reg_first(this));
3148
3149 // Push new nodes.
3150 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3151 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3152
3153 assert(nodes->length() >= 1, "must have created at least 1 node");
3154 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3155 %}
3156
3157 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{
3158 // Create new nodes.
3159
3160 // Make an operand with the bit pattern to load as float.
3161 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3162 immI_0Oper *op_zero = new immI_0Oper(0);
3163
3164 loadConLReplicatedNodesTuple loadConLNodes =
3165 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero,
3166 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp),
3167 ra_->get_reg_second(this), ra_->get_reg_first(this));
3168
3169 // Push new nodes.
3170 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); }
3171 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); }
3172 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); }
3173 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); }
3174
3175 assert(nodes->length() >= 1, "must have created at least 1 node");
3176 %}
3177
3178 // This enc_class is needed so that scheduler gets proper
3179 // input mapping for latency computation.
3180 enc_class enc_poll(immI dst, iRegLdst poll) %{
3181 // Fake operand dst needed for PPC scheduler.
3182 assert($dst$$constant == 0x0, "dst must be 0x0");
3183
3184 // Mark the code position where the load from the safepoint
3185 // polling page was emitted as relocInfo::poll_type.
3186 __ relocate(relocInfo::poll_type);
3187 __ load_from_polling_page($poll$$Register);
3188 %}
3189
3190 // A Java static call or a runtime call.
3191 //
3192 // Branch-and-link relative to a trampoline.
3193 // The trampoline loads the target address and does a long branch to there.
3194 // In case we call java, the trampoline branches to a interpreter_stub
3195 // which loads the inline cache and the real call target from the constant pool.
3196 //
3197 // This basically looks like this:
3198 //
3199 // >>>> consts -+ -+
3200 // | |- offset1
3201 // [call target1] | <-+
3202 // [IC cache] |- offset2
3203 // [call target2] <--+
3204 //
3205 // <<<< consts
3206 // >>>> insts
3207 //
3208 // bl offset16 -+ -+ ??? // How many bits available?
3209 // | |
3210 // <<<< insts | |
3211 // >>>> stubs | |
3212 // | |- trampoline_stub_Reloc
3213 // trampoline stub: | <-+
3214 // r2 = toc |
3215 // r2 = [r2 + offset1] | // Load call target1 from const section
3216 // mtctr r2 |
3217 // bctr |- static_stub_Reloc
3218 // comp_to_interp_stub: <---+
3219 // r1 = toc
3220 // ICreg = [r1 + IC_offset] // Load IC from const section
3221 // r1 = [r1 + offset2] // Load call target2 from const section
3222 // mtctr r1
3223 // bctr
3224 //
3225 // <<<< stubs
3226 //
3227 // The call instruction in the code either
3228 // - Branches directly to a compiled method if the offset is encodable in instruction.
3229 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3230 // - Branches to the compiled_to_interp stub if the target is interpreted.
3231 //
3232 // Further there are three relocations from the loads to the constants in
3233 // the constant section.
3234 //
3235 // Usage of r1 and r2 in the stubs allows to distinguish them.
3236 enc_class enc_java_static_call(method meth) %{
3237 address entry_point = (address)$meth$$method;
3238 address call_pc;
3239
3240 if (!_method) {
3241 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3242 call_pc = __ trampoline_call(AddressLiteral(entry_point, relocInfo::runtime_call_type));
3243 if (call_pc == nullptr) {
3244 ciEnv::current()->record_failure("CodeCache is full");
3245 return;
3246 }
3247 } else {
3248 int method_index = resolved_method_index(masm);
3249 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3250 : static_call_Relocation::spec(method_index);
3251 call_pc = __ trampoline_call(AddressLiteral(entry_point, rspec));
3252 if (call_pc == nullptr) {
3253 ciEnv::current()->record_failure("CodeCache is full");
3254 return;
3255 }
3256
3257 // Emit stub for static call
3258 address stub = CompiledDirectCall::emit_to_interp_stub(masm, call_pc);
3259 if (stub == nullptr) {
3260 ciEnv::current()->record_failure("CodeCache is full");
3261 return;
3262 }
3263 }
3264 __ post_call_nop();
3265 %}
3266
3267 // Compound version of call dynamic
3268 // Toc is only passed so that it can be used in ins_encode statement.
3269 // In the code we have to use $constanttablebase.
3270 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
3271 int start_offset = __ offset();
3272 int method_index = resolved_method_index(masm);
3273 bool scratch_emit = ra_ == nullptr;
3274 Register Rtoc = scratch_emit ? R2_TOC : $constanttablebase;
3275 bool success = __ ic_call(Rtoc, (address)$meth$$method, method_index, scratch_emit, true /*fixed_size*/);
3276 if (!success) {
3277 ciEnv::current()->record_failure("CodeCache is full");
3278 return;
3279 }
3280 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3281 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3282 __ post_call_nop();
3283 %}
3284
3285 // a runtime call
3286 enc_class enc_java_to_runtime_call (method meth) %{
3287 const address start_pc = __ pc();
3288
3289 #if defined(ABI_ELFv2)
3290 address entry= !($meth$$method) ? nullptr : (address)$meth$$method;
3291 __ call_c(entry, relocInfo::runtime_call_type);
3292 __ post_call_nop();
3293 #else
3294 // The function we're going to call.
3295 FunctionDescriptor fdtemp;
3296 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3297
3298 Register Rtoc = R12_scratch2;
3299 // Calculate the method's TOC.
3300 __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3301 // Put entry, env, toc into the constant pool, this needs up to 3 constant
3302 // pool entries; call_c_using_toc will optimize the call.
3303 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3304 if (!success) {
3305 ciEnv::current()->record_out_of_memory_failure();
3306 return;
3307 }
3308 __ post_call_nop();
3309 #endif
3310
3311 // Check the ret_addr_offset.
3312 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3313 "Fix constant in ret_addr_offset()");
3314 %}
3315
3316 // Move to ctr for leaf call.
3317 // This enc_class is needed so that scheduler gets proper
3318 // input mapping for latency computation.
3319 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3320 __ mtctr($src$$Register);
3321 %}
3322
3323 // Postalloc expand emitter for runtime leaf calls.
3324 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3325 loadConLNodesTuple loadConLNodes_Entry;
3326 #if defined(ABI_ELFv2)
3327 jlong entry_address = (jlong) this->entry_point();
3328 assert(entry_address, "need address here");
3329 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3330 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3331 #else
3332 // Get the struct that describes the function we are about to call.
3333 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3334 assert(fd, "need fd here");
3335 jlong entry_address = (jlong) fd->entry();
3336 // new nodes
3337 loadConLNodesTuple loadConLNodes_Env;
3338 loadConLNodesTuple loadConLNodes_Toc;
3339
3340 // Create nodes and operands for loading the entry point.
3341 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3342 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3343
3344
3345 // Create nodes and operands for loading the env pointer.
3346 if (fd->env() != nullptr) {
3347 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3348 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3349 } else {
3350 loadConLNodes_Env._large_hi = nullptr;
3351 loadConLNodes_Env._large_lo = nullptr;
3352 loadConLNodes_Env._small = nullptr;
3353 loadConLNodes_Env._last = new loadConL16Node();
3354 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3355 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3356 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3357 }
3358
3359 // Create nodes and operands for loading the Toc point.
3360 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3361 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3362 #endif // ABI_ELFv2
3363 // mtctr node
3364 MachNode *mtctr = new CallLeafDirect_mtctrNode();
3365
3366 assert(loadConLNodes_Entry._last != nullptr, "entry must exist");
3367 mtctr->add_req(nullptr, loadConLNodes_Entry._last);
3368
3369 mtctr->_opnds[0] = new iRegLdstOper();
3370 mtctr->_opnds[1] = new iRegLdstOper();
3371
3372 // call node
3373 MachCallLeafNode *call = new CallLeafDirectNode();
3374
3375 call->_opnds[0] = _opnds[0];
3376 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3377
3378 // Make the new call node look like the old one.
3379 call->_name = _name;
3380 call->_tf = _tf;
3381 call->_entry_point = _entry_point;
3382 call->_cnt = _cnt;
3383 call->_guaranteed_safepoint = false;
3384 call->_oop_map = _oop_map;
3385 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3386 call->_jvms = nullptr;
3387 call->_jvmadj = _jvmadj;
3388 call->_in_rms = _in_rms;
3389 call->_nesting = _nesting;
3390
3391 // New call needs all inputs of old call.
3392 // Req...
3393 for (uint i = 0; i < req(); ++i) {
3394 if (i != mach_constant_base_node_input()) {
3395 call->add_req(in(i));
3396 }
3397 }
3398
3399 // These must be reqired edges, as the registers are live up to
3400 // the call. Else the constants are handled as kills.
3401 call->add_req(mtctr);
3402 #if !defined(ABI_ELFv2)
3403 call->add_req(loadConLNodes_Env._last);
3404 call->add_req(loadConLNodes_Toc._last);
3405 #endif
3406
3407 // ...as well as prec
3408 for (uint i = req(); i < len(); ++i) {
3409 call->add_prec(in(i));
3410 }
3411
3412 // registers
3413 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3414
3415 // Insert the new nodes.
3416 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3417 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last);
3418 #if !defined(ABI_ELFv2)
3419 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi);
3420 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last);
3421 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi);
3422 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last);
3423 #endif
3424 nodes->push(mtctr);
3425 nodes->push(call);
3426 %}
3427 %}
3428
3429 //----------FRAME--------------------------------------------------------------
3430 // Definition of frame structure and management information.
3431
3432 frame %{
3433 // These two registers define part of the calling convention between
3434 // compiled code and the interpreter.
3435
3436 // Inline Cache Register or method for I2C.
3437 inline_cache_reg(R19); // R19_method
3438
3439 // Optional: name the operand used by cisc-spilling to access
3440 // [stack_pointer + offset].
3441 cisc_spilling_operand_name(indOffset);
3442
3443 // Number of stack slots consumed by a Monitor enter.
3444 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size));
3445
3446 // Compiled code's Frame Pointer.
3447 frame_pointer(R1); // R1_SP
3448
3449 stack_alignment(frame::alignment_in_bytes);
3450
3451 // Number of outgoing stack slots killed above the
3452 // out_preserve_stack_slots for calls to C. Supports the var-args
3453 // backing area for register parms.
3454 //
3455 varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3456
3457 // The after-PROLOG location of the return address. Location of
3458 // return address specifies a type (REG or STACK) and a number
3459 // representing the register number (i.e. - use a register name) or
3460 // stack slot.
3461 //
3462 // A: Link register is stored in stack slot ...
3463 // M: ... but it's in the caller's frame according to PPC-64 ABI.
3464 // J: Therefore, we make sure that the link register is also in R11_scratch1
3465 // at the end of the prolog.
3466 // B: We use R20, now.
3467 //return_addr(REG R20);
3468
3469 // G: After reading the comments made by all the luminaries on their
3470 // failure to tell the compiler where the return address really is,
3471 // I hardly dare to try myself. However, I'm convinced it's in slot
3472 // 4 what apparently works and saves us some spills.
3473 return_addr(STACK 4);
3474
3475 // Location of native (C/C++) and interpreter return values. This
3476 // is specified to be the same as Java. In the 32-bit VM, long
3477 // values are actually returned from native calls in O0:O1 and
3478 // returned to the interpreter in I0:I1. The copying to and from
3479 // the register pairs is done by the appropriate call and epilog
3480 // opcodes. This simplifies the register allocator.
3481 c_return_value %{
3482 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3483 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3484 "only return normal values");
3485 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3486 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3487 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3488 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3489 %}
3490
3491 // Location of compiled Java return values. Same as C
3492 return_value %{
3493 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3494 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3495 "only return normal values");
3496 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3497 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3498 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3499 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3500 %}
3501 %}
3502
3503
3504 //----------ATTRIBUTES---------------------------------------------------------
3505
3506 //----------Operand Attributes-------------------------------------------------
3507 op_attrib op_cost(1); // Required cost attribute.
3508
3509 //----------Instruction Attributes---------------------------------------------
3510
3511 // Cost attribute. required.
3512 ins_attrib ins_cost(DEFAULT_COST);
3513
3514 // Is this instruction a non-matching short branch variant of some
3515 // long branch? Not required.
3516 ins_attrib ins_short_branch(0);
3517
3518 ins_attrib ins_is_TrapBasedCheckNode(true);
3519
3520 // Number of constants.
3521 // This instruction uses the given number of constants
3522 // (optional attribute).
3523 // This is needed to determine in time whether the constant pool will
3524 // exceed 4000 entries. Before postalloc_expand the overall number of constants
3525 // is determined. It's also used to compute the constant pool size
3526 // in Output().
3527 ins_attrib ins_num_consts(0);
3528
3529 // Required alignment attribute (must be a power of 2) specifies the
3530 // alignment that some part of the instruction (not necessarily the
3531 // start) requires. If > 1, a compute_padding() function must be
3532 // provided for the instruction.
3533 ins_attrib ins_alignment(1);
3534
3535 // Enforce/prohibit rematerializations.
3536 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3537 // then rematerialization of that instruction is prohibited and the
3538 // instruction's value will be spilled if necessary.
3539 // Causes that MachNode::rematerialize() returns false.
3540 // - If an instruction is attributed with 'ins_should_rematerialize(true)'
3541 // then rematerialization should be enforced and a copy of the instruction
3542 // should be inserted if possible; rematerialization is not guaranteed.
3543 // Note: this may result in rematerializations in front of every use.
3544 // Causes that MachNode::rematerialize() can return true.
3545 // (optional attribute)
3546 ins_attrib ins_cannot_rematerialize(false);
3547 ins_attrib ins_should_rematerialize(false);
3548
3549 // Instruction has variable size depending on alignment.
3550 ins_attrib ins_variable_size_depending_on_alignment(false);
3551
3552 // Instruction is a nop.
3553 ins_attrib ins_is_nop(false);
3554
3555 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock).
3556 ins_attrib ins_use_mach_if_fast_lock_node(false);
3557
3558 // Field for the toc offset of a constant.
3559 //
3560 // This is needed if the toc offset is not encodable as an immediate in
3561 // the PPC load instruction. If so, the upper (hi) bits of the offset are
3562 // added to the toc, and from this a load with immediate is performed.
3563 // With postalloc expand, we get two nodes that require the same offset
3564 // but which don't know about each other. The offset is only known
3565 // when the constant is added to the constant pool during emitting.
3566 // It is generated in the 'hi'-node adding the upper bits, and saved
3567 // in this node. The 'lo'-node has a link to the 'hi'-node and reads
3568 // the offset from there when it gets encoded.
3569 ins_attrib ins_field_const_toc_offset(0);
3570 ins_attrib ins_field_const_toc_offset_hi_node(0);
3571
3572 // A field that can hold the instructions offset in the code buffer.
3573 // Set in the nodes emitter.
3574 ins_attrib ins_field_cbuf_insts_offset(-1);
3575
3576 // Fields for referencing a call's load-IC-node.
3577 // If the toc offset can not be encoded as an immediate in a load, we
3578 // use two nodes.
3579 ins_attrib ins_field_load_ic_hi_node(0);
3580 ins_attrib ins_field_load_ic_node(0);
3581
3582 // Whether this node is expanded during code emission into a sequence of
3583 // instructions and the first instruction can perform an implicit null check.
3584 ins_attrib ins_is_late_expanded_null_check_candidate(false);
3585
3586 //----------OPERANDS-----------------------------------------------------------
3587 // Operand definitions must precede instruction definitions for correct
3588 // parsing in the ADLC because operands constitute user defined types
3589 // which are used in instruction definitions.
3590 //
3591 // Formats are generated automatically for constants and base registers.
3592
3593 operand vecX() %{
3594 constraint(ALLOC_IN_RC(v_reg));
3595 match(VecX);
3596
3597 format %{ %}
3598 interface(REG_INTER);
3599 %}
3600
3601 //----------Simple Operands----------------------------------------------------
3602 // Immediate Operands
3603
3604 // Integer Immediate: 32-bit
3605 operand immI() %{
3606 match(ConI);
3607 op_cost(40);
3608 format %{ %}
3609 interface(CONST_INTER);
3610 %}
3611
3612 operand immI8() %{
3613 predicate(Assembler::is_simm(n->get_int(), 8));
3614 op_cost(0);
3615 match(ConI);
3616 format %{ %}
3617 interface(CONST_INTER);
3618 %}
3619
3620 // Integer Immediate: 16-bit
3621 operand immI16() %{
3622 predicate(Assembler::is_simm(n->get_int(), 16));
3623 op_cost(0);
3624 match(ConI);
3625 format %{ %}
3626 interface(CONST_INTER);
3627 %}
3628
3629 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000.
3630 operand immIhi16() %{
3631 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0));
3632 match(ConI);
3633 op_cost(0);
3634 format %{ %}
3635 interface(CONST_INTER);
3636 %}
3637
3638 // Integer Immediate: 32-bit immediate for prefixed addi and load/store.
3639 operand immI32() %{
3640 predicate(PowerArchitecturePPC64 >= 10);
3641 op_cost(0);
3642 match(ConI);
3643 format %{ %}
3644 interface(CONST_INTER);
3645 %}
3646
3647 operand immInegpow2() %{
3648 predicate(is_power_of_2(-(juint)(n->get_int())));
3649 match(ConI);
3650 op_cost(0);
3651 format %{ %}
3652 interface(CONST_INTER);
3653 %}
3654
3655 operand immIpow2minus1() %{
3656 predicate(is_power_of_2((juint)(n->get_int()) + 1u));
3657 match(ConI);
3658 op_cost(0);
3659 format %{ %}
3660 interface(CONST_INTER);
3661 %}
3662
3663 operand immIpowerOf2() %{
3664 predicate(is_power_of_2((juint)(n->get_int())));
3665 match(ConI);
3666 op_cost(0);
3667 format %{ %}
3668 interface(CONST_INTER);
3669 %}
3670
3671 // Unsigned Integer Immediate: the values 0-31
3672 operand uimmI5() %{
3673 predicate(Assembler::is_uimm(n->get_int(), 5));
3674 match(ConI);
3675 op_cost(0);
3676 format %{ %}
3677 interface(CONST_INTER);
3678 %}
3679
3680 // Unsigned Integer Immediate: 6-bit
3681 operand uimmI6() %{
3682 predicate(Assembler::is_uimm(n->get_int(), 6));
3683 match(ConI);
3684 op_cost(0);
3685 format %{ %}
3686 interface(CONST_INTER);
3687 %}
3688
3689 // Unsigned Integer Immediate: 6-bit int, greater than 32
3690 operand uimmI6_ge32() %{
3691 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32);
3692 match(ConI);
3693 op_cost(0);
3694 format %{ %}
3695 interface(CONST_INTER);
3696 %}
3697
3698 // Unsigned Integer Immediate: 15-bit
3699 operand uimmI15() %{
3700 predicate(Assembler::is_uimm(n->get_int(), 15));
3701 match(ConI);
3702 op_cost(0);
3703 format %{ %}
3704 interface(CONST_INTER);
3705 %}
3706
3707 // Unsigned Integer Immediate: 16-bit
3708 operand uimmI16() %{
3709 predicate(Assembler::is_uimm(n->get_int(), 16));
3710 match(ConI);
3711 op_cost(0);
3712 format %{ %}
3713 interface(CONST_INTER);
3714 %}
3715
3716 // constant 'int 0'.
3717 operand immI_0() %{
3718 predicate(n->get_int() == 0);
3719 match(ConI);
3720 op_cost(0);
3721 format %{ %}
3722 interface(CONST_INTER);
3723 %}
3724
3725 // constant 'int 1'.
3726 operand immI_1() %{
3727 predicate(n->get_int() == 1);
3728 match(ConI);
3729 op_cost(0);
3730 format %{ %}
3731 interface(CONST_INTER);
3732 %}
3733
3734 // constant 'int -1'.
3735 operand immI_minus1() %{
3736 predicate(n->get_int() == -1);
3737 match(ConI);
3738 op_cost(0);
3739 format %{ %}
3740 interface(CONST_INTER);
3741 %}
3742
3743 // int value 16.
3744 operand immI_16() %{
3745 predicate(n->get_int() == 16);
3746 match(ConI);
3747 op_cost(0);
3748 format %{ %}
3749 interface(CONST_INTER);
3750 %}
3751
3752 // int value 24.
3753 operand immI_24() %{
3754 predicate(n->get_int() == 24);
3755 match(ConI);
3756 op_cost(0);
3757 format %{ %}
3758 interface(CONST_INTER);
3759 %}
3760
3761 // Compressed oops constants
3762 // Pointer Immediate
3763 operand immN() %{
3764 match(ConN);
3765
3766 op_cost(10);
3767 format %{ %}
3768 interface(CONST_INTER);
3769 %}
3770
3771 // nullptr Pointer Immediate
3772 operand immN_0() %{
3773 predicate(n->get_narrowcon() == 0);
3774 match(ConN);
3775
3776 op_cost(0);
3777 format %{ %}
3778 interface(CONST_INTER);
3779 %}
3780
3781 // Compressed klass constants
3782 operand immNKlass() %{
3783 match(ConNKlass);
3784
3785 op_cost(0);
3786 format %{ %}
3787 interface(CONST_INTER);
3788 %}
3789
3790 // This operand can be used to avoid matching of an instruct
3791 // with chain rule.
3792 operand immNKlass_NM() %{
3793 match(ConNKlass);
3794 predicate(false);
3795 op_cost(0);
3796 format %{ %}
3797 interface(CONST_INTER);
3798 %}
3799
3800 // Pointer Immediate: 64-bit
3801 operand immP() %{
3802 match(ConP);
3803 op_cost(0);
3804 format %{ %}
3805 interface(CONST_INTER);
3806 %}
3807
3808 // Operand to avoid match of loadConP.
3809 // This operand can be used to avoid matching of an instruct
3810 // with chain rule.
3811 operand immP_NM() %{
3812 match(ConP);
3813 predicate(false);
3814 op_cost(0);
3815 format %{ %}
3816 interface(CONST_INTER);
3817 %}
3818
3819 // constant 'pointer 0'.
3820 operand immP_0() %{
3821 predicate(n->get_ptr() == 0);
3822 match(ConP);
3823 op_cost(0);
3824 format %{ %}
3825 interface(CONST_INTER);
3826 %}
3827
3828 // pointer 0x0 or 0x1
3829 operand immP_0or1() %{
3830 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
3831 match(ConP);
3832 op_cost(0);
3833 format %{ %}
3834 interface(CONST_INTER);
3835 %}
3836
3837 operand immL() %{
3838 match(ConL);
3839 op_cost(40);
3840 format %{ %}
3841 interface(CONST_INTER);
3842 %}
3843
3844 operand immLmax30() %{
3845 predicate((n->get_long() <= 30));
3846 match(ConL);
3847 op_cost(0);
3848 format %{ %}
3849 interface(CONST_INTER);
3850 %}
3851
3852 // Long Immediate: 16-bit
3853 operand immL16() %{
3854 predicate(Assembler::is_simm(n->get_long(), 16));
3855 match(ConL);
3856 op_cost(0);
3857 format %{ %}
3858 interface(CONST_INTER);
3859 %}
3860
3861 // Long Immediate: 16-bit, 4-aligned
3862 operand immL16Alg4() %{
3863 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
3864 match(ConL);
3865 op_cost(0);
3866 format %{ %}
3867 interface(CONST_INTER);
3868 %}
3869
3870 // Long Immediate: 16-bit, 16-aligned
3871 operand immL16Alg16() %{
3872 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0xf) == 0));
3873 match(ConL);
3874 op_cost(0);
3875 format %{ %}
3876 interface(CONST_INTER);
3877 %}
3878
3879 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
3880 operand immL32hi16() %{
3881 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L));
3882 match(ConL);
3883 op_cost(0);
3884 format %{ %}
3885 interface(CONST_INTER);
3886 %}
3887
3888 // Long Immediate: 32-bit
3889 operand immL32() %{
3890 predicate(Assembler::is_simm(n->get_long(), 32));
3891 match(ConL);
3892 op_cost(0);
3893 format %{ %}
3894 interface(CONST_INTER);
3895 %}
3896
3897 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store.
3898 operand immL34() %{
3899 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34));
3900 match(ConL);
3901 op_cost(0);
3902 format %{ %}
3903 interface(CONST_INTER);
3904 %}
3905
3906 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000.
3907 operand immLhighest16() %{
3908 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L);
3909 match(ConL);
3910 op_cost(0);
3911 format %{ %}
3912 interface(CONST_INTER);
3913 %}
3914
3915 operand immLnegpow2() %{
3916 predicate(is_power_of_2(-(julong)(n->get_long())));
3917 match(ConL);
3918 op_cost(0);
3919 format %{ %}
3920 interface(CONST_INTER);
3921 %}
3922
3923 operand immLpow2minus1() %{
3924 predicate(is_power_of_2((julong)(n->get_long()) + 1ull));
3925 match(ConL);
3926 op_cost(0);
3927 format %{ %}
3928 interface(CONST_INTER);
3929 %}
3930
3931 // constant 'long 0'.
3932 operand immL_0() %{
3933 predicate(n->get_long() == 0L);
3934 match(ConL);
3935 op_cost(0);
3936 format %{ %}
3937 interface(CONST_INTER);
3938 %}
3939
3940 // constat ' long -1'.
3941 operand immL_minus1() %{
3942 predicate(n->get_long() == -1L);
3943 match(ConL);
3944 op_cost(0);
3945 format %{ %}
3946 interface(CONST_INTER);
3947 %}
3948
3949 // Long Immediate: low 32-bit mask
3950 operand immL_32bits() %{
3951 predicate(n->get_long() == 0xFFFFFFFFL);
3952 match(ConL);
3953 op_cost(0);
3954 format %{ %}
3955 interface(CONST_INTER);
3956 %}
3957
3958 // Unsigned Long Immediate: 16-bit
3959 operand uimmL16() %{
3960 predicate(Assembler::is_uimm(n->get_long(), 16));
3961 match(ConL);
3962 op_cost(0);
3963 format %{ %}
3964 interface(CONST_INTER);
3965 %}
3966
3967 // Float Immediate
3968 operand immF() %{
3969 match(ConF);
3970 op_cost(40);
3971 format %{ %}
3972 interface(CONST_INTER);
3973 %}
3974
3975 // Float Immediate: +0.0f.
3976 operand immF_0() %{
3977 predicate(jint_cast(n->getf()) == 0);
3978 match(ConF);
3979
3980 op_cost(0);
3981 format %{ %}
3982 interface(CONST_INTER);
3983 %}
3984
3985 // Double Immediate
3986 operand immD() %{
3987 match(ConD);
3988 op_cost(40);
3989 format %{ %}
3990 interface(CONST_INTER);
3991 %}
3992
3993 // Double Immediate: +0.0d.
3994 operand immD_0() %{
3995 predicate(jlong_cast(n->getd()) == 0);
3996 match(ConD);
3997
3998 op_cost(0);
3999 format %{ %}
4000 interface(CONST_INTER);
4001 %}
4002
4003 // Integer Register Operands
4004 // Integer Destination Register
4005 // See definition of reg_class bits32_reg_rw.
4006 operand iRegIdst() %{
4007 constraint(ALLOC_IN_RC(bits32_reg_rw));
4008 match(RegI);
4009 match(rscratch1RegI);
4010 match(rscratch2RegI);
4011 match(rarg1RegI);
4012 match(rarg2RegI);
4013 match(rarg3RegI);
4014 match(rarg4RegI);
4015 format %{ %}
4016 interface(REG_INTER);
4017 %}
4018
4019 // Integer Source Register
4020 // See definition of reg_class bits32_reg_ro.
4021 operand iRegIsrc() %{
4022 constraint(ALLOC_IN_RC(bits32_reg_ro));
4023 match(RegI);
4024 match(rscratch1RegI);
4025 match(rscratch2RegI);
4026 match(rarg1RegI);
4027 match(rarg2RegI);
4028 match(rarg3RegI);
4029 match(rarg4RegI);
4030 format %{ %}
4031 interface(REG_INTER);
4032 %}
4033
4034 operand rscratch1RegI() %{
4035 constraint(ALLOC_IN_RC(rscratch1_bits32_reg));
4036 match(iRegIdst);
4037 format %{ %}
4038 interface(REG_INTER);
4039 %}
4040
4041 operand rscratch2RegI() %{
4042 constraint(ALLOC_IN_RC(rscratch2_bits32_reg));
4043 match(iRegIdst);
4044 format %{ %}
4045 interface(REG_INTER);
4046 %}
4047
4048 operand rarg1RegI() %{
4049 constraint(ALLOC_IN_RC(rarg1_bits32_reg));
4050 match(iRegIdst);
4051 format %{ %}
4052 interface(REG_INTER);
4053 %}
4054
4055 operand rarg2RegI() %{
4056 constraint(ALLOC_IN_RC(rarg2_bits32_reg));
4057 match(iRegIdst);
4058 format %{ %}
4059 interface(REG_INTER);
4060 %}
4061
4062 operand rarg3RegI() %{
4063 constraint(ALLOC_IN_RC(rarg3_bits32_reg));
4064 match(iRegIdst);
4065 format %{ %}
4066 interface(REG_INTER);
4067 %}
4068
4069 operand rarg4RegI() %{
4070 constraint(ALLOC_IN_RC(rarg4_bits32_reg));
4071 match(iRegIdst);
4072 format %{ %}
4073 interface(REG_INTER);
4074 %}
4075
4076 operand rarg1RegL() %{
4077 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4078 match(iRegLdst);
4079 format %{ %}
4080 interface(REG_INTER);
4081 %}
4082
4083 // Pointer Destination Register
4084 // See definition of reg_class bits64_reg_rw.
4085 operand iRegPdst() %{
4086 constraint(ALLOC_IN_RC(bits64_reg_rw));
4087 match(RegP);
4088 match(rscratch1RegP);
4089 match(rscratch2RegP);
4090 match(rarg1RegP);
4091 match(rarg2RegP);
4092 match(rarg3RegP);
4093 match(rarg4RegP);
4094 format %{ %}
4095 interface(REG_INTER);
4096 %}
4097
4098 // Pointer Destination Register
4099 // Operand not using r11 and r12 (killed in epilog).
4100 operand iRegPdstNoScratch() %{
4101 constraint(ALLOC_IN_RC(bits64_reg_leaf_call));
4102 match(RegP);
4103 match(rarg1RegP);
4104 match(rarg2RegP);
4105 match(rarg3RegP);
4106 match(rarg4RegP);
4107 format %{ %}
4108 interface(REG_INTER);
4109 %}
4110
4111 // Pointer Source Register
4112 // See definition of reg_class bits64_reg_ro.
4113 operand iRegPsrc() %{
4114 constraint(ALLOC_IN_RC(bits64_reg_ro));
4115 match(RegP);
4116 match(iRegPdst);
4117 match(rscratch1RegP);
4118 match(rscratch2RegP);
4119 match(rarg1RegP);
4120 match(rarg2RegP);
4121 match(rarg3RegP);
4122 match(rarg4RegP);
4123 match(rarg5RegP);
4124 match(rarg6RegP);
4125 match(threadRegP);
4126 format %{ %}
4127 interface(REG_INTER);
4128 %}
4129
4130 // Thread operand.
4131 operand threadRegP() %{
4132 constraint(ALLOC_IN_RC(thread_bits64_reg));
4133 match(iRegPdst);
4134 format %{ "R16" %}
4135 interface(REG_INTER);
4136 %}
4137
4138 operand rscratch1RegP() %{
4139 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4140 match(iRegPdst);
4141 format %{ "R11" %}
4142 interface(REG_INTER);
4143 %}
4144
4145 operand rscratch2RegP() %{
4146 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4147 match(iRegPdst);
4148 format %{ %}
4149 interface(REG_INTER);
4150 %}
4151
4152 operand rarg1RegP() %{
4153 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4154 match(iRegPdst);
4155 format %{ %}
4156 interface(REG_INTER);
4157 %}
4158
4159 operand rarg2RegP() %{
4160 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4161 match(iRegPdst);
4162 format %{ %}
4163 interface(REG_INTER);
4164 %}
4165
4166 operand rarg3RegP() %{
4167 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4168 match(iRegPdst);
4169 format %{ %}
4170 interface(REG_INTER);
4171 %}
4172
4173 operand rarg4RegP() %{
4174 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4175 match(iRegPdst);
4176 format %{ %}
4177 interface(REG_INTER);
4178 %}
4179
4180 operand rarg5RegP() %{
4181 constraint(ALLOC_IN_RC(rarg5_bits64_reg));
4182 match(iRegPdst);
4183 format %{ %}
4184 interface(REG_INTER);
4185 %}
4186
4187 operand rarg6RegP() %{
4188 constraint(ALLOC_IN_RC(rarg6_bits64_reg));
4189 match(iRegPdst);
4190 format %{ %}
4191 interface(REG_INTER);
4192 %}
4193
4194 operand iRegNsrc() %{
4195 constraint(ALLOC_IN_RC(bits32_reg_ro));
4196 match(RegN);
4197 match(iRegNdst);
4198
4199 format %{ %}
4200 interface(REG_INTER);
4201 %}
4202
4203 operand iRegNdst() %{
4204 constraint(ALLOC_IN_RC(bits32_reg_rw));
4205 match(RegN);
4206
4207 format %{ %}
4208 interface(REG_INTER);
4209 %}
4210
4211 // Long Destination Register
4212 // See definition of reg_class bits64_reg_rw.
4213 operand iRegLdst() %{
4214 constraint(ALLOC_IN_RC(bits64_reg_rw));
4215 match(RegL);
4216 match(rscratch1RegL);
4217 match(rscratch2RegL);
4218 format %{ %}
4219 interface(REG_INTER);
4220 %}
4221
4222 // Long Source Register
4223 // See definition of reg_class bits64_reg_ro.
4224 operand iRegLsrc() %{
4225 constraint(ALLOC_IN_RC(bits64_reg_ro));
4226 match(RegL);
4227 match(iRegLdst);
4228 match(rscratch1RegL);
4229 match(rscratch2RegL);
4230 format %{ %}
4231 interface(REG_INTER);
4232 %}
4233
4234 // Special operand for ConvL2I.
4235 operand iRegL2Isrc(iRegLsrc reg) %{
4236 constraint(ALLOC_IN_RC(bits64_reg_ro));
4237 match(ConvL2I reg);
4238 format %{ "ConvL2I($reg)" %}
4239 interface(REG_INTER)
4240 %}
4241
4242 operand rscratch1RegL() %{
4243 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4244 match(RegL);
4245 format %{ %}
4246 interface(REG_INTER);
4247 %}
4248
4249 operand rscratch2RegL() %{
4250 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4251 match(RegL);
4252 format %{ %}
4253 interface(REG_INTER);
4254 %}
4255
4256 // Condition Code Flag Registers
4257 operand flagsReg() %{
4258 constraint(ALLOC_IN_RC(int_flags));
4259 match(RegFlags);
4260 format %{ %}
4261 interface(REG_INTER);
4262 %}
4263
4264 operand flagsRegSrc() %{
4265 constraint(ALLOC_IN_RC(int_flags_ro));
4266 match(RegFlags);
4267 match(flagsReg);
4268 match(flagsRegCR0);
4269 format %{ %}
4270 interface(REG_INTER);
4271 %}
4272
4273 // Condition Code Flag Register CR0
4274 operand flagsRegCR0() %{
4275 constraint(ALLOC_IN_RC(int_flags_CR0));
4276 match(RegFlags);
4277 format %{ "CR0" %}
4278 interface(REG_INTER);
4279 %}
4280
4281 operand flagsRegCR1() %{
4282 constraint(ALLOC_IN_RC(int_flags_CR1));
4283 match(RegFlags);
4284 format %{ "CR1" %}
4285 interface(REG_INTER);
4286 %}
4287
4288 operand flagsRegCR6() %{
4289 constraint(ALLOC_IN_RC(int_flags_CR6));
4290 match(RegFlags);
4291 format %{ "CR6" %}
4292 interface(REG_INTER);
4293 %}
4294
4295 operand regCTR() %{
4296 constraint(ALLOC_IN_RC(ctr_reg));
4297 // RegFlags should work. Introducing a RegSpecial type would cause a
4298 // lot of changes.
4299 match(RegFlags);
4300 format %{"SR_CTR" %}
4301 interface(REG_INTER);
4302 %}
4303
4304 operand regD() %{
4305 constraint(ALLOC_IN_RC(dbl_reg));
4306 match(RegD);
4307 format %{ %}
4308 interface(REG_INTER);
4309 %}
4310
4311 operand regF() %{
4312 constraint(ALLOC_IN_RC(flt_reg));
4313 match(RegF);
4314 format %{ %}
4315 interface(REG_INTER);
4316 %}
4317
4318 // Special Registers
4319
4320 // Method Register
4321 operand inline_cache_regP(iRegPdst reg) %{
4322 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg
4323 match(reg);
4324 format %{ %}
4325 interface(REG_INTER);
4326 %}
4327
4328 // Operands to remove register moves in unscaled mode.
4329 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4330 operand iRegP2N(iRegPsrc reg) %{
4331 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0);
4332 constraint(ALLOC_IN_RC(bits64_reg_ro));
4333 match(EncodeP reg);
4334 format %{ "$reg" %}
4335 interface(REG_INTER)
4336 %}
4337
4338 operand iRegN2P(iRegNsrc reg) %{
4339 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4340 constraint(ALLOC_IN_RC(bits32_reg_ro));
4341 match(DecodeN reg);
4342 format %{ "$reg" %}
4343 interface(REG_INTER)
4344 %}
4345
4346 operand iRegN2P_klass(iRegNsrc reg) %{
4347 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4348 constraint(ALLOC_IN_RC(bits32_reg_ro));
4349 match(DecodeNKlass reg);
4350 format %{ "$reg" %}
4351 interface(REG_INTER)
4352 %}
4353
4354 //----------Complex Operands---------------------------------------------------
4355 // Indirect Memory Reference
4356 operand indirect(iRegPsrc reg) %{
4357 constraint(ALLOC_IN_RC(bits64_reg_ro));
4358 match(reg);
4359 op_cost(100);
4360 format %{ "[$reg]" %}
4361 interface(MEMORY_INTER) %{
4362 base($reg);
4363 index(0x0);
4364 scale(0x0);
4365 disp(0x0);
4366 %}
4367 %}
4368
4369 // Indirect with Offset
4370 operand indOffset16(iRegPsrc reg, immL16 offset) %{
4371 constraint(ALLOC_IN_RC(bits64_reg_ro));
4372 match(AddP reg offset);
4373 op_cost(100);
4374 format %{ "[$reg + $offset]" %}
4375 interface(MEMORY_INTER) %{
4376 base($reg);
4377 index(0x0);
4378 scale(0x0);
4379 disp($offset);
4380 %}
4381 %}
4382
4383 // Indirect with 4-aligned Offset
4384 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{
4385 constraint(ALLOC_IN_RC(bits64_reg_ro));
4386 match(AddP reg offset);
4387 op_cost(100);
4388 format %{ "[$reg + $offset]" %}
4389 interface(MEMORY_INTER) %{
4390 base($reg);
4391 index(0x0);
4392 scale(0x0);
4393 disp($offset);
4394 %}
4395 %}
4396
4397 // Indirect with 16-aligned Offset
4398 operand indOffset16Alg16(iRegPsrc reg, immL16Alg16 offset) %{
4399 constraint(ALLOC_IN_RC(bits64_reg_ro));
4400 match(AddP reg offset);
4401 op_cost(100);
4402 format %{ "[$reg + $offset]" %}
4403 interface(MEMORY_INTER) %{
4404 base($reg);
4405 index(0x0);
4406 scale(0x0);
4407 disp($offset);
4408 %}
4409 %}
4410
4411 //----------Complex Operands for Compressed OOPs-------------------------------
4412 // Compressed OOPs with narrow_oop_shift == 0.
4413
4414 // Indirect Memory Reference, compressed OOP
4415 operand indirectNarrow(iRegNsrc reg) %{
4416 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4417 constraint(ALLOC_IN_RC(bits64_reg_ro));
4418 match(DecodeN reg);
4419 op_cost(100);
4420 format %{ "[$reg]" %}
4421 interface(MEMORY_INTER) %{
4422 base($reg);
4423 index(0x0);
4424 scale(0x0);
4425 disp(0x0);
4426 %}
4427 %}
4428
4429 operand indirectNarrow_klass(iRegNsrc reg) %{
4430 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4431 constraint(ALLOC_IN_RC(bits64_reg_ro));
4432 match(DecodeNKlass reg);
4433 op_cost(100);
4434 format %{ "[$reg]" %}
4435 interface(MEMORY_INTER) %{
4436 base($reg);
4437 index(0x0);
4438 scale(0x0);
4439 disp(0x0);
4440 %}
4441 %}
4442
4443 // Indirect with Offset, compressed OOP
4444 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4445 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4446 constraint(ALLOC_IN_RC(bits64_reg_ro));
4447 match(AddP (DecodeN reg) offset);
4448 op_cost(100);
4449 format %{ "[$reg + $offset]" %}
4450 interface(MEMORY_INTER) %{
4451 base($reg);
4452 index(0x0);
4453 scale(0x0);
4454 disp($offset);
4455 %}
4456 %}
4457
4458 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4459 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4460 constraint(ALLOC_IN_RC(bits64_reg_ro));
4461 match(AddP (DecodeNKlass reg) offset);
4462 op_cost(100);
4463 format %{ "[$reg + $offset]" %}
4464 interface(MEMORY_INTER) %{
4465 base($reg);
4466 index(0x0);
4467 scale(0x0);
4468 disp($offset);
4469 %}
4470 %}
4471
4472 // Indirect with 4-aligned Offset, compressed OOP
4473 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4474 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4475 constraint(ALLOC_IN_RC(bits64_reg_ro));
4476 match(AddP (DecodeN reg) offset);
4477 op_cost(100);
4478 format %{ "[$reg + $offset]" %}
4479 interface(MEMORY_INTER) %{
4480 base($reg);
4481 index(0x0);
4482 scale(0x0);
4483 disp($offset);
4484 %}
4485 %}
4486
4487 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4488 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4489 constraint(ALLOC_IN_RC(bits64_reg_ro));
4490 match(AddP (DecodeNKlass reg) offset);
4491 op_cost(100);
4492 format %{ "[$reg + $offset]" %}
4493 interface(MEMORY_INTER) %{
4494 base($reg);
4495 index(0x0);
4496 scale(0x0);
4497 disp($offset);
4498 %}
4499 %}
4500
4501 //----------Special Memory Operands--------------------------------------------
4502 // Stack Slot Operand
4503 //
4504 // This operand is used for loading and storing temporary values on
4505 // the stack where a match requires a value to flow through memory.
4506 operand stackSlotI(sRegI reg) %{
4507 constraint(ALLOC_IN_RC(stack_slots));
4508 op_cost(100);
4509 //match(RegI);
4510 format %{ "[sp+$reg]" %}
4511 interface(MEMORY_INTER) %{
4512 base(0x1); // R1_SP
4513 index(0x0);
4514 scale(0x0);
4515 disp($reg); // Stack Offset
4516 %}
4517 %}
4518
4519 operand stackSlotL(sRegL reg) %{
4520 constraint(ALLOC_IN_RC(stack_slots));
4521 op_cost(100);
4522 //match(RegL);
4523 format %{ "[sp+$reg]" %}
4524 interface(MEMORY_INTER) %{
4525 base(0x1); // R1_SP
4526 index(0x0);
4527 scale(0x0);
4528 disp($reg); // Stack Offset
4529 %}
4530 %}
4531
4532 operand stackSlotP(sRegP reg) %{
4533 constraint(ALLOC_IN_RC(stack_slots));
4534 op_cost(100);
4535 //match(RegP);
4536 format %{ "[sp+$reg]" %}
4537 interface(MEMORY_INTER) %{
4538 base(0x1); // R1_SP
4539 index(0x0);
4540 scale(0x0);
4541 disp($reg); // Stack Offset
4542 %}
4543 %}
4544
4545 operand stackSlotF(sRegF reg) %{
4546 constraint(ALLOC_IN_RC(stack_slots));
4547 op_cost(100);
4548 //match(RegF);
4549 format %{ "[sp+$reg]" %}
4550 interface(MEMORY_INTER) %{
4551 base(0x1); // R1_SP
4552 index(0x0);
4553 scale(0x0);
4554 disp($reg); // Stack Offset
4555 %}
4556 %}
4557
4558 operand stackSlotD(sRegD reg) %{
4559 constraint(ALLOC_IN_RC(stack_slots));
4560 op_cost(100);
4561 //match(RegD);
4562 format %{ "[sp+$reg]" %}
4563 interface(MEMORY_INTER) %{
4564 base(0x1); // R1_SP
4565 index(0x0);
4566 scale(0x0);
4567 disp($reg); // Stack Offset
4568 %}
4569 %}
4570
4571 // Operands for expressing Control Flow
4572 // NOTE: Label is a predefined operand which should not be redefined in
4573 // the AD file. It is generically handled within the ADLC.
4574
4575 //----------Conditional Branch Operands----------------------------------------
4576 // Comparison Op
4577 //
4578 // This is the operation of the comparison, and is limited to the
4579 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE
4580 // (!=).
4581 //
4582 // Other attributes of the comparison, such as unsignedness, are specified
4583 // by the comparison instruction that sets a condition code flags register.
4584 // That result is represented by a flags operand whose subtype is appropriate
4585 // to the unsignedness (etc.) of the comparison.
4586 //
4587 // Later, the instruction which matches both the Comparison Op (a Bool) and
4588 // the flags (produced by the Cmp) specifies the coding of the comparison op
4589 // by matching a specific subtype of Bool operand below.
4590
4591 // When used for floating point comparisons: unordered same as less.
4592 operand cmpOp() %{
4593 match(Bool);
4594 format %{ "" %}
4595 interface(COND_INTER) %{
4596 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'.
4597 // BO & BI
4598 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4599 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4600 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4601 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4602 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4603 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4604 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4605 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4606 %}
4607 %}
4608
4609 //----------OPERAND CLASSES----------------------------------------------------
4610 // Operand Classes are groups of operands that are used to simplify
4611 // instruction definitions by not requiring the AD writer to specify
4612 // separate instructions for every form of operand when the
4613 // instruction accepts multiple operand types with the same basic
4614 // encoding and format. The classic case of this is memory operands.
4615 // Indirect is not included since its use is limited to Compare & Swap.
4616
4617 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4618 // Memory operand where offsets are 4-aligned. Required for ld, std.
4619 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4620 opclass memoryAlg16(indirect, indOffset16Alg16);
4621 opclass indirectMemory(indirect, indirectNarrow);
4622
4623 // Special opclass for I and ConvL2I.
4624 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4625
4626 // Operand classes to match encode and decode. iRegN_P2N is only used
4627 // for storeN. I have never seen an encode node elsewhere.
4628 opclass iRegN_P2N(iRegNsrc, iRegP2N);
4629 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4630
4631 //----------PIPELINE-----------------------------------------------------------
4632
4633 pipeline %{
4634
4635 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4636 // J. Res. & Dev., No. 1, Jan. 2002.
4637
4638 //----------ATTRIBUTES---------------------------------------------------------
4639 attributes %{
4640
4641 // Power4 instructions are of fixed length.
4642 fixed_size_instructions;
4643
4644 // TODO: if `bundle' means number of instructions fetched
4645 // per cycle, this is 8. If `bundle' means Power4 `group', that is
4646 // max instructions issued per cycle, this is 5.
4647 max_instructions_per_bundle = 8;
4648
4649 // A Power4 instruction is 4 bytes long.
4650 instruction_unit_size = 4;
4651
4652 // The Power4 processor fetches 64 bytes...
4653 instruction_fetch_unit_size = 64;
4654
4655 // ...in one line
4656 instruction_fetch_units = 1
4657 %}
4658
4659 //----------RESOURCES----------------------------------------------------------
4660 // Resources are the functional units available to the machine
4661 resources(
4662 PPC_BR, // branch unit
4663 PPC_CR, // condition unit
4664 PPC_FX1, // integer arithmetic unit 1
4665 PPC_FX2, // integer arithmetic unit 2
4666 PPC_LDST1, // load/store unit 1
4667 PPC_LDST2, // load/store unit 2
4668 PPC_FP1, // float arithmetic unit 1
4669 PPC_FP2, // float arithmetic unit 2
4670 PPC_LDST = PPC_LDST1 | PPC_LDST2,
4671 PPC_FX = PPC_FX1 | PPC_FX2,
4672 PPC_FP = PPC_FP1 | PPC_FP2
4673 );
4674
4675 //----------PIPELINE DESCRIPTION-----------------------------------------------
4676 // Pipeline Description specifies the stages in the machine's pipeline
4677 pipe_desc(
4678 // Power4 longest pipeline path
4679 PPC_IF, // instruction fetch
4680 PPC_IC,
4681 //PPC_BP, // branch prediction
4682 PPC_D0, // decode
4683 PPC_D1, // decode
4684 PPC_D2, // decode
4685 PPC_D3, // decode
4686 PPC_Xfer1,
4687 PPC_GD, // group definition
4688 PPC_MP, // map
4689 PPC_ISS, // issue
4690 PPC_RF, // resource fetch
4691 PPC_EX1, // execute (all units)
4692 PPC_EX2, // execute (FP, LDST)
4693 PPC_EX3, // execute (FP, LDST)
4694 PPC_EX4, // execute (FP)
4695 PPC_EX5, // execute (FP)
4696 PPC_EX6, // execute (FP)
4697 PPC_WB, // write back
4698 PPC_Xfer2,
4699 PPC_CP
4700 );
4701
4702 //----------PIPELINE CLASSES---------------------------------------------------
4703 // Pipeline Classes describe the stages in which input and output are
4704 // referenced by the hardware pipeline.
4705
4706 // Simple pipeline classes.
4707
4708 // Default pipeline class.
4709 pipe_class pipe_class_default() %{
4710 single_instruction;
4711 fixed_latency(2);
4712 %}
4713
4714 // Pipeline class for empty instructions.
4715 pipe_class pipe_class_empty() %{
4716 single_instruction;
4717 fixed_latency(0);
4718 %}
4719
4720 // Pipeline class for compares.
4721 pipe_class pipe_class_compare() %{
4722 single_instruction;
4723 fixed_latency(16);
4724 %}
4725
4726 // Pipeline class for traps.
4727 pipe_class pipe_class_trap() %{
4728 single_instruction;
4729 fixed_latency(100);
4730 %}
4731
4732 // Pipeline class for memory operations.
4733 pipe_class pipe_class_memory() %{
4734 single_instruction;
4735 fixed_latency(16);
4736 %}
4737
4738 // Pipeline class for call.
4739 pipe_class pipe_class_call() %{
4740 single_instruction;
4741 fixed_latency(100);
4742 %}
4743
4744 // Define the class for the Nop node.
4745 define %{
4746 MachNop = pipe_class_default;
4747 %}
4748
4749 %}
4750
4751 //----------INSTRUCTIONS-------------------------------------------------------
4752
4753 // Naming of instructions:
4754 // opA_operB / opA_operB_operC:
4755 // Operation 'op' with one or two source operands 'oper'. Result
4756 // type is A, source operand types are B and C.
4757 // Iff A == B == C, B and C are left out.
4758 //
4759 // The instructions are ordered according to the following scheme:
4760 // - loads
4761 // - load constants
4762 // - prefetch
4763 // - store
4764 // - encode/decode
4765 // - membar
4766 // - conditional moves
4767 // - compare & swap
4768 // - arithmetic and logic operations
4769 // * int: Add, Sub, Mul, Div, Mod
4770 // * int: lShift, arShift, urShift, rot
4771 // * float: Add, Sub, Mul, Div
4772 // * and, or, xor ...
4773 // - register moves: float <-> int, reg <-> stack, repl
4774 // - cast (high level type cast, XtoP, castPP, castII, not_null etc.
4775 // - conv (low level type cast requiring bit changes (sign extend etc)
4776 // - compares, range & zero checks.
4777 // - branches
4778 // - complex operations, intrinsics, min, max, replicate
4779 // - lock
4780 // - Calls
4781 //
4782 // If there are similar instructions with different types they are sorted:
4783 // int before float
4784 // small before big
4785 // signed before unsigned
4786 // e.g., loadS before loadUS before loadI before loadF.
4787
4788
4789 //----------Load/Store Instructions--------------------------------------------
4790
4791 //----------Load Instructions--------------------------------------------------
4792
4793 // Converts byte to int.
4794 // As convB2I_reg, but without match rule. The match rule of convB2I_reg
4795 // reuses the 'amount' operand, but adlc expects that operand specification
4796 // and operands in match rule are equivalent.
4797 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
4798 effect(DEF dst, USE src);
4799 format %{ "EXTSB $dst, $src \t// byte->int" %}
4800 size(4);
4801 ins_encode %{
4802 __ extsb($dst$$Register, $src$$Register);
4803 %}
4804 ins_pipe(pipe_class_default);
4805 %}
4806
4807 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{
4808 // match-rule, false predicate
4809 match(Set dst (LoadB mem));
4810 predicate(false);
4811
4812 format %{ "LBZ $dst, $mem" %}
4813 size(4);
4814 ins_encode( enc_lbz(dst, mem) );
4815 ins_pipe(pipe_class_memory);
4816 %}
4817
4818 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{
4819 // match-rule, false predicate
4820 match(Set dst (LoadB mem));
4821 predicate(false);
4822
4823 format %{ "LBZ $dst, $mem\n\t"
4824 "TWI $dst\n\t"
4825 "ISYNC" %}
4826 size(12);
4827 ins_encode( enc_lbz_ac(dst, mem) );
4828 ins_pipe(pipe_class_memory);
4829 %}
4830
4831 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
4832 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{
4833 match(Set dst (LoadB mem));
4834 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4835 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4836 expand %{
4837 iRegIdst tmp;
4838 loadUB_indirect(tmp, mem);
4839 convB2I_reg_2(dst, tmp);
4840 %}
4841 %}
4842
4843 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{
4844 match(Set dst (LoadB mem));
4845 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
4846 expand %{
4847 iRegIdst tmp;
4848 loadUB_indirect_ac(tmp, mem);
4849 convB2I_reg_2(dst, tmp);
4850 %}
4851 %}
4852
4853 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{
4854 // match-rule, false predicate
4855 match(Set dst (LoadB mem));
4856 predicate(false);
4857
4858 format %{ "LBZ $dst, $mem" %}
4859 size(4);
4860 ins_encode( enc_lbz(dst, mem) );
4861 ins_pipe(pipe_class_memory);
4862 %}
4863
4864 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{
4865 // match-rule, false predicate
4866 match(Set dst (LoadB mem));
4867 predicate(false);
4868
4869 format %{ "LBZ $dst, $mem\n\t"
4870 "TWI $dst\n\t"
4871 "ISYNC" %}
4872 size(12);
4873 ins_encode( enc_lbz_ac(dst, mem) );
4874 ins_pipe(pipe_class_memory);
4875 %}
4876
4877 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
4878 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{
4879 match(Set dst (LoadB mem));
4880 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4881 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4882
4883 expand %{
4884 iRegIdst tmp;
4885 loadUB_indOffset16(tmp, mem);
4886 convB2I_reg_2(dst, tmp);
4887 %}
4888 %}
4889
4890 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{
4891 match(Set dst (LoadB mem));
4892 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
4893
4894 expand %{
4895 iRegIdst tmp;
4896 loadUB_indOffset16_ac(tmp, mem);
4897 convB2I_reg_2(dst, tmp);
4898 %}
4899 %}
4900
4901 // Load Unsigned Byte (8bit UNsigned) into an int reg.
4902 instruct loadUB(iRegIdst dst, memory mem) %{
4903 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4904 match(Set dst (LoadUB mem));
4905 ins_cost(MEMORY_REF_COST);
4906
4907 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %}
4908 size(4);
4909 ins_encode( enc_lbz(dst, mem) );
4910 ins_pipe(pipe_class_memory);
4911 %}
4912
4913 // Load Unsigned Byte (8bit UNsigned) acquire.
4914 instruct loadUB_ac(iRegIdst dst, memory mem) %{
4915 match(Set dst (LoadUB mem));
4916 ins_cost(3*MEMORY_REF_COST);
4917
4918 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t"
4919 "TWI $dst\n\t"
4920 "ISYNC" %}
4921 size(12);
4922 ins_encode( enc_lbz_ac(dst, mem) );
4923 ins_pipe(pipe_class_memory);
4924 %}
4925
4926 // Load Unsigned Byte (8bit UNsigned) into a Long Register.
4927 instruct loadUB2L(iRegLdst dst, memory mem) %{
4928 match(Set dst (ConvI2L (LoadUB mem)));
4929 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
4930 ins_cost(MEMORY_REF_COST);
4931
4932 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %}
4933 size(4);
4934 ins_encode( enc_lbz(dst, mem) );
4935 ins_pipe(pipe_class_memory);
4936 %}
4937
4938 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{
4939 match(Set dst (ConvI2L (LoadUB mem)));
4940 ins_cost(3*MEMORY_REF_COST);
4941
4942 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t"
4943 "TWI $dst\n\t"
4944 "ISYNC" %}
4945 size(12);
4946 ins_encode( enc_lbz_ac(dst, mem) );
4947 ins_pipe(pipe_class_memory);
4948 %}
4949
4950 // Load Short (16bit signed)
4951 instruct loadS(iRegIdst dst, memory mem) %{
4952 match(Set dst (LoadS mem));
4953 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4954 ins_cost(MEMORY_REF_COST);
4955
4956 format %{ "LHA $dst, $mem" %}
4957 size(4);
4958 ins_encode %{
4959 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
4960 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
4961 %}
4962 ins_pipe(pipe_class_memory);
4963 %}
4964
4965 // Load Short (16bit signed) acquire.
4966 instruct loadS_ac(iRegIdst dst, memory mem) %{
4967 match(Set dst (LoadS mem));
4968 ins_cost(3*MEMORY_REF_COST);
4969
4970 format %{ "LHA $dst, $mem\t acquire\n\t"
4971 "TWI $dst\n\t"
4972 "ISYNC" %}
4973 size(12);
4974 ins_encode %{
4975 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
4976 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
4977 __ twi_0($dst$$Register);
4978 __ isync();
4979 %}
4980 ins_pipe(pipe_class_memory);
4981 %}
4982
4983 // Load Char (16bit unsigned)
4984 instruct loadUS(iRegIdst dst, memory mem) %{
4985 match(Set dst (LoadUS mem));
4986 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4987 ins_cost(MEMORY_REF_COST);
4988
4989 format %{ "LHZ $dst, $mem" %}
4990 size(4);
4991 ins_encode( enc_lhz(dst, mem) );
4992 ins_pipe(pipe_class_memory);
4993 %}
4994
4995 // Load Char (16bit unsigned) acquire.
4996 instruct loadUS_ac(iRegIdst dst, memory mem) %{
4997 match(Set dst (LoadUS mem));
4998 ins_cost(3*MEMORY_REF_COST);
4999
5000 format %{ "LHZ $dst, $mem \t// acquire\n\t"
5001 "TWI $dst\n\t"
5002 "ISYNC" %}
5003 size(12);
5004 ins_encode( enc_lhz_ac(dst, mem) );
5005 ins_pipe(pipe_class_memory);
5006 %}
5007
5008 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register.
5009 instruct loadUS2L(iRegLdst dst, memory mem) %{
5010 match(Set dst (ConvI2L (LoadUS mem)));
5011 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5012 ins_cost(MEMORY_REF_COST);
5013
5014 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %}
5015 size(4);
5016 ins_encode( enc_lhz(dst, mem) );
5017 ins_pipe(pipe_class_memory);
5018 %}
5019
5020 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire.
5021 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{
5022 match(Set dst (ConvI2L (LoadUS mem)));
5023 ins_cost(3*MEMORY_REF_COST);
5024
5025 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t"
5026 "TWI $dst\n\t"
5027 "ISYNC" %}
5028 size(12);
5029 ins_encode( enc_lhz_ac(dst, mem) );
5030 ins_pipe(pipe_class_memory);
5031 %}
5032
5033 // Load Integer.
5034 instruct loadI(iRegIdst dst, memory mem) %{
5035 match(Set dst (LoadI mem));
5036 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5037 ins_cost(MEMORY_REF_COST);
5038
5039 format %{ "LWZ $dst, $mem" %}
5040 size(4);
5041 ins_encode( enc_lwz(dst, mem) );
5042 ins_pipe(pipe_class_memory);
5043 %}
5044
5045 // Load Integer acquire.
5046 instruct loadI_ac(iRegIdst dst, memory mem) %{
5047 match(Set dst (LoadI mem));
5048 ins_cost(3*MEMORY_REF_COST);
5049
5050 format %{ "LWZ $dst, $mem \t// load acquire\n\t"
5051 "TWI $dst\n\t"
5052 "ISYNC" %}
5053 size(12);
5054 ins_encode( enc_lwz_ac(dst, mem) );
5055 ins_pipe(pipe_class_memory);
5056 %}
5057
5058 // Match loading integer and casting it to unsigned int in
5059 // long register.
5060 // LoadI + ConvI2L + AndL 0xffffffff.
5061 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
5062 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5063 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered());
5064 ins_cost(MEMORY_REF_COST);
5065
5066 format %{ "LWZ $dst, $mem \t// zero-extend to long" %}
5067 size(4);
5068 ins_encode( enc_lwz(dst, mem) );
5069 ins_pipe(pipe_class_memory);
5070 %}
5071
5072 // Match loading integer and casting it to long.
5073 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
5074 match(Set dst (ConvI2L (LoadI mem)));
5075 predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5076 ins_cost(MEMORY_REF_COST);
5077
5078 format %{ "LWA $dst, $mem \t// loadI2L" %}
5079 size(4);
5080 ins_encode %{
5081 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5082 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5083 %}
5084 ins_pipe(pipe_class_memory);
5085 %}
5086
5087 // Match loading integer and casting it to long - acquire.
5088 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
5089 match(Set dst (ConvI2L (LoadI mem)));
5090 ins_cost(3*MEMORY_REF_COST);
5091
5092 format %{ "LWA $dst, $mem \t// loadI2L acquire"
5093 "TWI $dst\n\t"
5094 "ISYNC" %}
5095 size(12);
5096 ins_encode %{
5097 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5098 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5099 __ twi_0($dst$$Register);
5100 __ isync();
5101 %}
5102 ins_pipe(pipe_class_memory);
5103 %}
5104
5105 // Load Long - aligned
5106 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{
5107 match(Set dst (LoadL mem));
5108 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5109 ins_cost(MEMORY_REF_COST);
5110
5111 format %{ "LD $dst, $mem \t// long" %}
5112 size(4);
5113 ins_encode( enc_ld(dst, mem) );
5114 ins_pipe(pipe_class_memory);
5115 %}
5116
5117 // Load Long - aligned acquire.
5118 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{
5119 match(Set dst (LoadL mem));
5120 ins_cost(3*MEMORY_REF_COST);
5121
5122 format %{ "LD $dst, $mem \t// long acquire\n\t"
5123 "TWI $dst\n\t"
5124 "ISYNC" %}
5125 size(12);
5126 ins_encode( enc_ld_ac(dst, mem) );
5127 ins_pipe(pipe_class_memory);
5128 %}
5129
5130 // Load Long - UNaligned
5131 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{
5132 match(Set dst (LoadL_unaligned mem));
5133 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5134 ins_cost(MEMORY_REF_COST);
5135
5136 format %{ "LD $dst, $mem \t// unaligned long" %}
5137 size(4);
5138 ins_encode( enc_ld(dst, mem) );
5139 ins_pipe(pipe_class_memory);
5140 %}
5141
5142 // Load nodes for superwords
5143
5144 // Load Aligned Packed Byte
5145 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{
5146 predicate(n->as_LoadVector()->memory_size() == 8);
5147 match(Set dst (LoadVector mem));
5148 ins_cost(MEMORY_REF_COST);
5149
5150 format %{ "LD $dst, $mem \t// load 8-byte Vector" %}
5151 size(4);
5152 ins_encode( enc_ld(dst, mem) );
5153 ins_pipe(pipe_class_memory);
5154 %}
5155
5156
5157 instruct loadV16(vecX dst, memoryAlg16 mem) %{
5158 predicate(n->as_LoadVector()->memory_size() == 16);
5159 match(Set dst (LoadVector mem));
5160 ins_cost(MEMORY_REF_COST);
5161
5162 format %{ "LXV $dst, $mem \t// load 16-byte Vector" %}
5163 size(4);
5164 ins_encode %{
5165 __ lxv($dst$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
5166 %}
5167 ins_pipe(pipe_class_default);
5168 %}
5169
5170 // Load Range, range = array length (=jint)
5171 instruct loadRange(iRegIdst dst, memory mem) %{
5172 match(Set dst (LoadRange mem));
5173 ins_cost(MEMORY_REF_COST);
5174
5175 format %{ "LWZ $dst, $mem \t// range" %}
5176 size(4);
5177 ins_encode( enc_lwz(dst, mem) );
5178 ins_pipe(pipe_class_memory);
5179 %}
5180
5181 // Load Compressed Pointer
5182 instruct loadN(iRegNdst dst, memory mem) %{
5183 match(Set dst (LoadN mem));
5184 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5185 ins_cost(MEMORY_REF_COST);
5186
5187 format %{ "LWZ $dst, $mem \t// load compressed ptr" %}
5188 size(4);
5189 ins_encode( enc_lwz(dst, mem) );
5190 ins_pipe(pipe_class_memory);
5191 %}
5192
5193 // Load Compressed Pointer acquire.
5194 instruct loadN_ac(iRegNdst dst, memory mem) %{
5195 match(Set dst (LoadN mem));
5196 predicate(n->as_Load()->barrier_data() == 0);
5197 ins_cost(3*MEMORY_REF_COST);
5198
5199 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5200 "TWI $dst\n\t"
5201 "ISYNC" %}
5202 size(12);
5203 ins_encode( enc_lwz_ac(dst, mem) );
5204 ins_pipe(pipe_class_memory);
5205 %}
5206
5207 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5208 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5209 match(Set dst (DecodeN (LoadN mem)));
5210 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0 && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5211 ins_cost(MEMORY_REF_COST);
5212
5213 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5214 size(4);
5215 ins_encode( enc_lwz(dst, mem) );
5216 ins_pipe(pipe_class_memory);
5217 %}
5218
5219 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5220 match(Set dst (DecodeNKlass (LoadNKlass mem)));
5221 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0 &&
5222 _kids[0]->_leaf->as_Load()->is_unordered());
5223 ins_cost(MEMORY_REF_COST);
5224
5225 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5226 size(4);
5227 ins_encode( enc_lwz(dst, mem) );
5228 ins_pipe(pipe_class_memory);
5229 %}
5230
5231 // Load Pointer
5232 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5233 match(Set dst (LoadP mem));
5234 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5235 ins_cost(MEMORY_REF_COST);
5236
5237 format %{ "LD $dst, $mem \t// ptr" %}
5238 size(4);
5239 ins_encode( enc_ld(dst, mem) );
5240 ins_pipe(pipe_class_memory);
5241 %}
5242
5243 // Load Pointer acquire.
5244 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5245 match(Set dst (LoadP mem));
5246 ins_cost(3*MEMORY_REF_COST);
5247
5248 predicate(n->as_Load()->barrier_data() == 0);
5249
5250 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5251 "TWI $dst\n\t"
5252 "ISYNC" %}
5253 size(12);
5254 ins_encode( enc_ld_ac(dst, mem) );
5255 ins_pipe(pipe_class_memory);
5256 %}
5257
5258 // LoadP + CastP2L
5259 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
5260 match(Set dst (CastP2X (LoadP mem)));
5261 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5262 ins_cost(MEMORY_REF_COST);
5263
5264 format %{ "LD $dst, $mem \t// ptr + p2x" %}
5265 size(4);
5266 ins_encode( enc_ld(dst, mem) );
5267 ins_pipe(pipe_class_memory);
5268 %}
5269
5270 // Load compressed klass pointer.
5271 instruct loadNKlass(iRegNdst dst, memory mem) %{
5272 match(Set dst (LoadNKlass mem));
5273 predicate(!UseCompactObjectHeaders);
5274 ins_cost(MEMORY_REF_COST);
5275
5276 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %}
5277 size(4);
5278 ins_encode( enc_lwz(dst, mem) );
5279 ins_pipe(pipe_class_memory);
5280 %}
5281
5282 instruct loadNKlassCompactHeaders(iRegNdst dst, memory mem) %{
5283 match(Set dst (LoadNKlass mem));
5284 predicate(UseCompactObjectHeaders);
5285 ins_cost(MEMORY_REF_COST);
5286
5287 format %{ "load_narrow_klass_compact $dst, $mem \t// compressed class ptr" %}
5288 size(8);
5289 ins_encode %{
5290 assert($mem$$index$$Register == R0, "must not have indexed address: %s[%s]", $mem$$base$$Register.name(), $mem$$index$$Register.name());
5291 __ load_narrow_klass_compact_c2($dst$$Register, $mem$$base$$Register, $mem$$disp);
5292 %}
5293 ins_pipe(pipe_class_memory);
5294 %}
5295
5296 // Load Klass Pointer
5297 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
5298 match(Set dst (LoadKlass mem));
5299 ins_cost(MEMORY_REF_COST);
5300
5301 format %{ "LD $dst, $mem \t// klass ptr" %}
5302 size(4);
5303 ins_encode( enc_ld(dst, mem) );
5304 ins_pipe(pipe_class_memory);
5305 %}
5306
5307 // Load Float
5308 instruct loadF(regF dst, memory mem) %{
5309 match(Set dst (LoadF mem));
5310 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5311 ins_cost(MEMORY_REF_COST);
5312
5313 format %{ "LFS $dst, $mem" %}
5314 size(4);
5315 ins_encode %{
5316 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5317 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5318 %}
5319 ins_pipe(pipe_class_memory);
5320 %}
5321
5322 // Load Float acquire.
5323 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5324 match(Set dst (LoadF mem));
5325 effect(TEMP cr0);
5326 ins_cost(3*MEMORY_REF_COST);
5327
5328 format %{ "LFS $dst, $mem \t// acquire\n\t"
5329 "FCMPU cr0, $dst, $dst\n\t"
5330 "BNE cr0, next\n"
5331 "next:\n\t"
5332 "ISYNC" %}
5333 size(16);
5334 ins_encode %{
5335 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5336 Label next;
5337 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5338 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5339 __ bne(CR0, next);
5340 __ bind(next);
5341 __ isync();
5342 %}
5343 ins_pipe(pipe_class_memory);
5344 %}
5345
5346 // Load Double - aligned
5347 instruct loadD(regD dst, memory mem) %{
5348 match(Set dst (LoadD mem));
5349 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5350 ins_cost(MEMORY_REF_COST);
5351
5352 format %{ "LFD $dst, $mem" %}
5353 size(4);
5354 ins_encode( enc_lfd(dst, mem) );
5355 ins_pipe(pipe_class_memory);
5356 %}
5357
5358 // Load Double - aligned acquire.
5359 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5360 match(Set dst (LoadD mem));
5361 effect(TEMP cr0);
5362 ins_cost(3*MEMORY_REF_COST);
5363
5364 format %{ "LFD $dst, $mem \t// acquire\n\t"
5365 "FCMPU cr0, $dst, $dst\n\t"
5366 "BNE cr0, next\n"
5367 "next:\n\t"
5368 "ISYNC" %}
5369 size(16);
5370 ins_encode %{
5371 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5372 Label next;
5373 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5374 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5375 __ bne(CR0, next);
5376 __ bind(next);
5377 __ isync();
5378 %}
5379 ins_pipe(pipe_class_memory);
5380 %}
5381
5382 // Load Double - UNaligned
5383 instruct loadD_unaligned(regD dst, memory mem) %{
5384 match(Set dst (LoadD_unaligned mem));
5385 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5386 ins_cost(MEMORY_REF_COST);
5387
5388 format %{ "LFD $dst, $mem" %}
5389 size(4);
5390 ins_encode( enc_lfd(dst, mem) );
5391 ins_pipe(pipe_class_memory);
5392 %}
5393
5394 //----------Constants--------------------------------------------------------
5395
5396 // Load MachConstantTableBase: add hi offset to global toc.
5397 // TODO: Handle hidden register r29 in bundler!
5398 instruct loadToc_hi(iRegLdst dst) %{
5399 effect(DEF dst);
5400 ins_cost(DEFAULT_COST);
5401
5402 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %}
5403 size(4);
5404 ins_encode %{
5405 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
5406 %}
5407 ins_pipe(pipe_class_default);
5408 %}
5409
5410 // Load MachConstantTableBase: add lo offset to global toc.
5411 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
5412 effect(DEF dst, USE src);
5413 ins_cost(DEFAULT_COST);
5414
5415 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %}
5416 size(4);
5417 ins_encode %{
5418 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
5419 %}
5420 ins_pipe(pipe_class_default);
5421 %}
5422
5423 // Load 16-bit integer constant 0xssss????
5424 instruct loadConI16(iRegIdst dst, immI16 src) %{
5425 match(Set dst src);
5426
5427 format %{ "LI $dst, $src" %}
5428 size(4);
5429 ins_encode %{
5430 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5431 %}
5432 ins_pipe(pipe_class_default);
5433 %}
5434
5435 // Load integer constant 0x????0000
5436 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
5437 match(Set dst src);
5438 ins_cost(DEFAULT_COST);
5439
5440 format %{ "LIS $dst, $src.hi" %}
5441 size(4);
5442 ins_encode %{
5443 // Lis sign extends 16-bit src then shifts it 16 bit to the left.
5444 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5445 %}
5446 ins_pipe(pipe_class_default);
5447 %}
5448
5449 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted
5450 // and sign extended), this adds the low 16 bits.
5451 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
5452 // no match-rule, false predicate
5453 effect(DEF dst, USE src1, USE src2);
5454 predicate(false);
5455
5456 format %{ "ORI $dst, $src1.hi, $src2.lo" %}
5457 size(4);
5458 ins_encode %{
5459 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5460 %}
5461 ins_pipe(pipe_class_default);
5462 %}
5463
5464 instruct loadConI32(iRegIdst dst, immI32 src) %{
5465 match(Set dst src);
5466 // This macro is valid only in Power 10 and up, but adding the following predicate here
5467 // caused a build error, so we comment it out for now.
5468 // predicate(PowerArchitecturePPC64 >= 10);
5469 ins_cost(DEFAULT_COST+1);
5470
5471 format %{ "PLI $dst, $src" %}
5472 size(8);
5473 ins_encode %{
5474 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5475 __ pli($dst$$Register, $src$$constant);
5476 %}
5477 ins_pipe(pipe_class_default);
5478 ins_alignment(2);
5479 %}
5480
5481 instruct loadConI_Ex(iRegIdst dst, immI src) %{
5482 match(Set dst src);
5483 ins_cost(DEFAULT_COST*2);
5484
5485 expand %{
5486 // Would like to use $src$$constant.
5487 immI16 srcLo %{ _opnds[1]->constant() %}
5488 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5489 immIhi16 srcHi %{ _opnds[1]->constant() %}
5490 iRegIdst tmpI;
5491 loadConIhi16(tmpI, srcHi);
5492 loadConI32_lo16(dst, tmpI, srcLo);
5493 %}
5494 %}
5495
5496 // No constant pool entries required.
5497 instruct loadConL16(iRegLdst dst, immL16 src) %{
5498 match(Set dst src);
5499
5500 format %{ "LI $dst, $src \t// long" %}
5501 size(4);
5502 ins_encode %{
5503 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
5504 %}
5505 ins_pipe(pipe_class_default);
5506 %}
5507
5508 // Load long constant 0xssssssss????0000
5509 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
5510 match(Set dst src);
5511 ins_cost(DEFAULT_COST);
5512
5513 format %{ "LIS $dst, $src.hi \t// long" %}
5514 size(4);
5515 ins_encode %{
5516 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5517 %}
5518 ins_pipe(pipe_class_default);
5519 %}
5520
5521 // To load a 32 bit constant: merge lower 16 bits into already loaded
5522 // high 16 bits.
5523 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
5524 // no match-rule, false predicate
5525 effect(DEF dst, USE src1, USE src2);
5526 predicate(false);
5527
5528 format %{ "ORI $dst, $src1, $src2.lo" %}
5529 size(4);
5530 ins_encode %{
5531 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5532 %}
5533 ins_pipe(pipe_class_default);
5534 %}
5535
5536 // Load 32-bit long constant
5537 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{
5538 match(Set dst src);
5539 ins_cost(DEFAULT_COST*2);
5540
5541 expand %{
5542 // Would like to use $src$$constant.
5543 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%}
5544 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5545 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%}
5546 iRegLdst tmpL;
5547 loadConL32hi16(tmpL, srcHi);
5548 loadConL32_lo16(dst, tmpL, srcLo);
5549 %}
5550 %}
5551
5552 // Load 34-bit long constant using prefixed addi. No constant pool entries required.
5553 instruct loadConL34(iRegLdst dst, immL34 src) %{
5554 match(Set dst src);
5555 // This macro is valid only in Power 10 and up, but adding the following predicate here
5556 // caused a build error, so we comment it out for now.
5557 // predicate(PowerArchitecturePPC64 >= 10);
5558 ins_cost(DEFAULT_COST+1);
5559
5560 format %{ "PLI $dst, $src \t// long" %}
5561 size(8);
5562 ins_encode %{
5563 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5564 __ pli($dst$$Register, $src$$constant);
5565 %}
5566 ins_pipe(pipe_class_default);
5567 ins_alignment(2);
5568 %}
5569
5570 // Load long constant 0x????000000000000.
5571 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{
5572 match(Set dst src);
5573 ins_cost(DEFAULT_COST);
5574
5575 expand %{
5576 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%}
5577 immI shift32 %{ 32 %}
5578 iRegLdst tmpL;
5579 loadConL32hi16(tmpL, srcHi);
5580 lshiftL_regL_immI(dst, tmpL, shift32);
5581 %}
5582 %}
5583
5584 // Expand node for constant pool load: small offset.
5585 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{
5586 effect(DEF dst, USE src, USE toc);
5587 ins_cost(MEMORY_REF_COST);
5588
5589 ins_num_consts(1);
5590 // Needed so that CallDynamicJavaDirect can compute the address of this
5591 // instruction for relocation.
5592 ins_field_cbuf_insts_offset(int);
5593
5594 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %}
5595 size(4);
5596 ins_encode( enc_load_long_constL(dst, src, toc) );
5597 ins_pipe(pipe_class_memory);
5598 %}
5599
5600 // Expand node for constant pool load: large offset.
5601 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{
5602 effect(DEF dst, USE src, USE toc);
5603 predicate(false);
5604
5605 ins_num_consts(1);
5606 ins_field_const_toc_offset(int);
5607 // Needed so that CallDynamicJavaDirect can compute the address of this
5608 // instruction for relocation.
5609 ins_field_cbuf_insts_offset(int);
5610
5611 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %}
5612 size(4);
5613 ins_encode( enc_load_long_constL_hi(dst, toc, src) );
5614 ins_pipe(pipe_class_default);
5615 %}
5616
5617 // Expand node for constant pool load: large offset.
5618 // No constant pool entries required.
5619 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
5620 effect(DEF dst, USE src, USE base);
5621 predicate(false);
5622
5623 ins_field_const_toc_offset_hi_node(loadConL_hiNode*);
5624
5625 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %}
5626 size(4);
5627 ins_encode %{
5628 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5629 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5630 %}
5631 ins_pipe(pipe_class_memory);
5632 %}
5633
5634 // Load long constant from constant table. Expand in case of
5635 // offset > 16 bit is needed.
5636 // Adlc adds toc node MachConstantTableBase.
5637 instruct loadConL_Ex(iRegLdst dst, immL src) %{
5638 match(Set dst src);
5639 ins_cost(MEMORY_REF_COST);
5640
5641 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %}
5642 // We can not inline the enc_class for the expand as that does not support constanttablebase.
5643 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) );
5644 %}
5645
5646 // Load nullptr as compressed oop.
5647 instruct loadConN0(iRegNdst dst, immN_0 src) %{
5648 match(Set dst src);
5649 ins_cost(DEFAULT_COST);
5650
5651 format %{ "LI $dst, $src \t// compressed ptr" %}
5652 size(4);
5653 ins_encode %{
5654 __ li($dst$$Register, 0);
5655 %}
5656 ins_pipe(pipe_class_default);
5657 %}
5658
5659 // Load hi part of compressed oop constant.
5660 instruct loadConN_hi(iRegNdst dst, immN src) %{
5661 effect(DEF dst, USE src);
5662 ins_cost(DEFAULT_COST);
5663
5664 format %{ "LIS $dst, $src \t// narrow oop hi" %}
5665 size(4);
5666 ins_encode %{
5667 __ lis($dst$$Register, 0); // Will get patched.
5668 %}
5669 ins_pipe(pipe_class_default);
5670 %}
5671
5672 // Add lo part of compressed oop constant to already loaded hi part.
5673 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
5674 effect(DEF dst, USE src1, USE src2);
5675 ins_cost(DEFAULT_COST);
5676
5677 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %}
5678 size(4);
5679 ins_encode %{
5680 AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant);
5681 __ relocate(addrlit.rspec(), /*compressed format*/ 1);
5682 __ ori($dst$$Register, $src1$$Register, 0); // Will get patched.
5683 %}
5684 ins_pipe(pipe_class_default);
5685 %}
5686
5687 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
5688 effect(DEF dst, USE src, USE shift, USE mask_begin);
5689
5690 size(4);
5691 ins_encode %{
5692 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
5693 %}
5694 ins_pipe(pipe_class_default);
5695 %}
5696
5697 // Needed to postalloc expand loadConN: ConN is loaded as ConI
5698 // leaving the upper 32 bits with sign-extension bits.
5699 // This clears these bits: dst = src & 0xFFFFFFFF.
5700 // TODO: Eventually call this maskN_regN_FFFFFFFF.
5701 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
5702 effect(DEF dst, USE src);
5703 predicate(false);
5704
5705 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
5706 size(4);
5707 ins_encode %{
5708 __ clrldi($dst$$Register, $src$$Register, 0x20);
5709 %}
5710 ins_pipe(pipe_class_default);
5711 %}
5712
5713 // Optimize DecodeN for disjoint base.
5714 // Load base of compressed oops into a register
5715 instruct loadBase(iRegLdst dst) %{
5716 effect(DEF dst);
5717
5718 format %{ "LoadConst $dst, heapbase" %}
5719 ins_encode %{
5720 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0);
5721 %}
5722 ins_pipe(pipe_class_default);
5723 %}
5724
5725 // Loading ConN must be postalloc expanded so that edges between
5726 // the nodes are safe. They may not interfere with a safepoint.
5727 // GL TODO: This needs three instructions: better put this into the constant pool.
5728 instruct loadConN_Ex(iRegNdst dst, immN src) %{
5729 match(Set dst src);
5730 ins_cost(DEFAULT_COST*2);
5731
5732 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5733 postalloc_expand %{
5734 MachNode *m1 = new loadConN_hiNode();
5735 MachNode *m2 = new loadConN_loNode();
5736 MachNode *m3 = new clearMs32bNode();
5737 m1->_bottom_type = bottom_type();
5738 m2->_bottom_type = bottom_type();
5739 m3->_bottom_type = bottom_type();
5740 m1->add_req(nullptr);
5741 m2->add_req(nullptr, m1);
5742 m3->add_req(nullptr, m2);
5743 m1->_opnds[0] = op_dst;
5744 m1->_opnds[1] = op_src;
5745 m2->_opnds[0] = op_dst;
5746 m2->_opnds[1] = op_dst;
5747 m2->_opnds[2] = op_src;
5748 m3->_opnds[0] = op_dst;
5749 m3->_opnds[1] = op_dst;
5750 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5751 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5752 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5753 nodes->push(m1);
5754 nodes->push(m2);
5755 nodes->push(m3);
5756 %}
5757 %}
5758
5759 // We have seen a safepoint between the hi and lo parts, and this node was handled
5760 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is
5761 // not a narrow oop.
5762 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
5763 match(Set dst src);
5764 effect(DEF dst, USE src);
5765 ins_cost(DEFAULT_COST);
5766
5767 format %{ "LIS $dst, $src \t// narrow klass hi" %}
5768 size(4);
5769 ins_encode %{
5770 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant);
5771 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
5772 %}
5773 ins_pipe(pipe_class_default);
5774 %}
5775
5776 // As loadConNKlass_hi this must be recognized as narrow klass, not oop!
5777 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5778 match(Set dst src1);
5779 effect(TEMP src2);
5780 ins_cost(DEFAULT_COST);
5781
5782 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
5783 size(4);
5784 ins_encode %{
5785 __ clrldi($dst$$Register, $src2$$Register, 0x20);
5786 %}
5787 ins_pipe(pipe_class_default);
5788 %}
5789
5790 // This needs a match rule so that build_oop_map knows this is
5791 // not a narrow oop.
5792 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5793 match(Set dst src1);
5794 effect(TEMP src2);
5795 ins_cost(DEFAULT_COST);
5796
5797 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
5798 size(4);
5799 ins_encode %{
5800 // Notify OOP recorder (don't need the relocation)
5801 AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant);
5802 intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value());
5803 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
5804 %}
5805 ins_pipe(pipe_class_default);
5806 %}
5807
5808 // Loading ConNKlass must be postalloc expanded so that edges between
5809 // the nodes are safe. They may not interfere with a safepoint.
5810 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
5811 match(Set dst src);
5812 ins_cost(DEFAULT_COST*2);
5813
5814 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5815 postalloc_expand %{
5816 // Load high bits into register. Sign extended.
5817 MachNode *m1 = new loadConNKlass_hiNode();
5818 m1->_bottom_type = bottom_type();
5819 m1->add_req(nullptr);
5820 m1->_opnds[0] = op_dst;
5821 m1->_opnds[1] = op_src;
5822 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5823 nodes->push(m1);
5824
5825 MachNode *m2 = m1;
5826 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) {
5827 // Value might be 1-extended. Mask out these bits.
5828 m2 = new loadConNKlass_maskNode();
5829 m2->_bottom_type = bottom_type();
5830 m2->add_req(nullptr, m1);
5831 m2->_opnds[0] = op_dst;
5832 m2->_opnds[1] = op_src;
5833 m2->_opnds[2] = op_dst;
5834 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5835 nodes->push(m2);
5836 }
5837
5838 MachNode *m3 = new loadConNKlass_loNode();
5839 m3->_bottom_type = bottom_type();
5840 m3->add_req(nullptr, m2);
5841 m3->_opnds[0] = op_dst;
5842 m3->_opnds[1] = op_src;
5843 m3->_opnds[2] = op_dst;
5844 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5845 nodes->push(m3);
5846 %}
5847 %}
5848
5849 // 0x1 is used in object initialization (initial object header).
5850 // No constant pool entries required.
5851 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
5852 match(Set dst src);
5853
5854 format %{ "LI $dst, $src \t// ptr" %}
5855 size(4);
5856 ins_encode %{
5857 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5858 %}
5859 ins_pipe(pipe_class_default);
5860 %}
5861
5862 // Expand node for constant pool load: small offset.
5863 // The match rule is needed to generate the correct bottom_type(),
5864 // however this node should never match. The use of predicate is not
5865 // possible since ADLC forbids predicates for chain rules. The higher
5866 // costs do not prevent matching in this case. For that reason the
5867 // operand immP_NM with predicate(false) is used.
5868 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{
5869 match(Set dst src);
5870 effect(TEMP toc);
5871
5872 ins_num_consts(1);
5873
5874 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %}
5875 size(4);
5876 ins_encode( enc_load_long_constP(dst, src, toc) );
5877 ins_pipe(pipe_class_memory);
5878 %}
5879
5880 // Expand node for constant pool load: large offset.
5881 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{
5882 effect(DEF dst, USE src, USE toc);
5883 predicate(false);
5884
5885 ins_num_consts(1);
5886 ins_field_const_toc_offset(int);
5887
5888 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %}
5889 size(4);
5890 ins_encode( enc_load_long_constP_hi(dst, src, toc) );
5891 ins_pipe(pipe_class_default);
5892 %}
5893
5894 // Expand node for constant pool load: large offset.
5895 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
5896 match(Set dst src);
5897 effect(TEMP base);
5898
5899 ins_field_const_toc_offset_hi_node(loadConP_hiNode*);
5900
5901 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
5902 size(4);
5903 ins_encode %{
5904 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5905 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5906 %}
5907 ins_pipe(pipe_class_memory);
5908 %}
5909
5910 // Load pointer constant from constant table. Expand in case an
5911 // offset > 16 bit is needed.
5912 // Adlc adds toc node MachConstantTableBase.
5913 instruct loadConP_Ex(iRegPdst dst, immP src) %{
5914 match(Set dst src);
5915 ins_cost(MEMORY_REF_COST);
5916
5917 // This rule does not use "expand" because then
5918 // the result type is not known to be an Oop. An ADLC
5919 // enhancement will be needed to make that work - not worth it!
5920
5921 // If this instruction rematerializes, it prolongs the live range
5922 // of the toc node, causing illegal graphs.
5923 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule().
5924 ins_cannot_rematerialize(true);
5925
5926 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %}
5927 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) );
5928 %}
5929
5930 // Expand node for constant pool load: small offset.
5931 instruct loadConF(regF dst, immF src, iRegLdst toc) %{
5932 effect(DEF dst, USE src, USE toc);
5933 ins_cost(MEMORY_REF_COST);
5934
5935 ins_num_consts(1);
5936
5937 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %}
5938 size(4);
5939 ins_encode %{
5940 address float_address = __ float_constant($src$$constant);
5941 if (float_address == nullptr) {
5942 ciEnv::current()->record_out_of_memory_failure();
5943 return;
5944 }
5945 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register);
5946 %}
5947 ins_pipe(pipe_class_memory);
5948 %}
5949
5950 // Expand node for constant pool load: large offset.
5951 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
5952 effect(DEF dst, USE src, USE toc);
5953 ins_cost(MEMORY_REF_COST);
5954
5955 ins_num_consts(1);
5956
5957 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
5958 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t"
5959 "ADDIS $toc, $toc, -offset_hi"%}
5960 size(12);
5961 ins_encode %{
5962 FloatRegister Rdst = $dst$$FloatRegister;
5963 Register Rtoc = $toc$$Register;
5964 address float_address = __ float_constant($src$$constant);
5965 if (float_address == nullptr) {
5966 ciEnv::current()->record_out_of_memory_failure();
5967 return;
5968 }
5969 int offset = __ offset_to_method_toc(float_address);
5970 int hi = (offset + (1<<15))>>16;
5971 int lo = offset - hi * (1<<16);
5972
5973 __ addis(Rtoc, Rtoc, hi);
5974 __ lfs(Rdst, lo, Rtoc);
5975 __ addis(Rtoc, Rtoc, -hi);
5976 %}
5977 ins_pipe(pipe_class_memory);
5978 %}
5979
5980 // Adlc adds toc node MachConstantTableBase.
5981 instruct loadConF_Ex(regF dst, immF src) %{
5982 match(Set dst src);
5983 ins_cost(MEMORY_REF_COST);
5984
5985 // See loadConP.
5986 ins_cannot_rematerialize(true);
5987
5988 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
5989 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) );
5990 %}
5991
5992 // Expand node for constant pool load: small offset.
5993 instruct loadConD(regD dst, immD src, iRegLdst toc) %{
5994 effect(DEF dst, USE src, USE toc);
5995 ins_cost(MEMORY_REF_COST);
5996
5997 ins_num_consts(1);
5998
5999 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %}
6000 size(4);
6001 ins_encode %{
6002 address float_address = __ double_constant($src$$constant);
6003 if (float_address == nullptr) {
6004 ciEnv::current()->record_out_of_memory_failure();
6005 return;
6006 }
6007 int offset = __ offset_to_method_toc(float_address);
6008 __ lfd($dst$$FloatRegister, offset, $toc$$Register);
6009 %}
6010 ins_pipe(pipe_class_memory);
6011 %}
6012
6013 // Expand node for constant pool load: large offset.
6014 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
6015 effect(DEF dst, USE src, USE toc);
6016 ins_cost(MEMORY_REF_COST);
6017
6018 ins_num_consts(1);
6019
6020 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6021 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t"
6022 "ADDIS $toc, $toc, -offset_hi" %}
6023 size(12);
6024 ins_encode %{
6025 FloatRegister Rdst = $dst$$FloatRegister;
6026 Register Rtoc = $toc$$Register;
6027 address float_address = __ double_constant($src$$constant);
6028 if (float_address == nullptr) {
6029 ciEnv::current()->record_out_of_memory_failure();
6030 return;
6031 }
6032 int offset = __ offset_to_method_toc(float_address);
6033 int hi = (offset + (1<<15))>>16;
6034 int lo = offset - hi * (1<<16);
6035
6036 __ addis(Rtoc, Rtoc, hi);
6037 __ lfd(Rdst, lo, Rtoc);
6038 __ addis(Rtoc, Rtoc, -hi);
6039 %}
6040 ins_pipe(pipe_class_memory);
6041 %}
6042
6043 // Adlc adds toc node MachConstantTableBase.
6044 instruct loadConD_Ex(regD dst, immD src) %{
6045 match(Set dst src);
6046 ins_cost(MEMORY_REF_COST);
6047
6048 // See loadConP.
6049 ins_cannot_rematerialize(true);
6050
6051 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6052 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) );
6053 %}
6054
6055 // Prefetch instructions.
6056 // Must be safe to execute with invalid address (cannot fault).
6057
6058 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
6059 match(PrefetchAllocation (AddP mem src));
6060 ins_cost(MEMORY_REF_COST);
6061
6062 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
6063 size(4);
6064 ins_encode %{
6065 __ dcbtst($src$$Register, $mem$$base$$Register);
6066 %}
6067 ins_pipe(pipe_class_memory);
6068 %}
6069
6070 instruct prefetch_alloc_no_offset(indirectMemory mem) %{
6071 match(PrefetchAllocation mem);
6072 ins_cost(MEMORY_REF_COST);
6073
6074 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
6075 size(4);
6076 ins_encode %{
6077 __ dcbtst($mem$$base$$Register);
6078 %}
6079 ins_pipe(pipe_class_memory);
6080 %}
6081
6082 //----------Store Instructions-------------------------------------------------
6083
6084 // Store Byte
6085 instruct storeB(memory mem, iRegIsrc src) %{
6086 match(Set mem (StoreB mem src));
6087 ins_cost(MEMORY_REF_COST);
6088
6089 format %{ "STB $src, $mem \t// byte" %}
6090 size(4);
6091 ins_encode %{
6092 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6093 __ stb($src$$Register, Idisp, $mem$$base$$Register);
6094 %}
6095 ins_pipe(pipe_class_memory);
6096 %}
6097
6098 // Store Char/Short
6099 instruct storeC(memory mem, iRegIsrc src) %{
6100 match(Set mem (StoreC mem src));
6101 ins_cost(MEMORY_REF_COST);
6102
6103 format %{ "STH $src, $mem \t// short" %}
6104 size(4);
6105 ins_encode %{
6106 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6107 __ sth($src$$Register, Idisp, $mem$$base$$Register);
6108 %}
6109 ins_pipe(pipe_class_memory);
6110 %}
6111
6112 // Store Integer
6113 instruct storeI(memory mem, iRegIsrc src) %{
6114 match(Set mem (StoreI mem src));
6115 ins_cost(MEMORY_REF_COST);
6116
6117 format %{ "STW $src, $mem" %}
6118 size(4);
6119 ins_encode( enc_stw(src, mem) );
6120 ins_pipe(pipe_class_memory);
6121 %}
6122
6123 // ConvL2I + StoreI.
6124 instruct storeI_convL2I(memory mem, iRegLsrc src) %{
6125 match(Set mem (StoreI mem (ConvL2I src)));
6126 ins_cost(MEMORY_REF_COST);
6127
6128 format %{ "STW l2i($src), $mem" %}
6129 size(4);
6130 ins_encode( enc_stw(src, mem) );
6131 ins_pipe(pipe_class_memory);
6132 %}
6133
6134 // Store Long
6135 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{
6136 match(Set mem (StoreL mem src));
6137 ins_cost(MEMORY_REF_COST);
6138
6139 format %{ "STD $src, $mem \t// long" %}
6140 size(4);
6141 ins_encode( enc_std(src, mem) );
6142 ins_pipe(pipe_class_memory);
6143 %}
6144
6145 // Store super word nodes.
6146
6147 // Store Aligned Packed Byte long register to memory
6148 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{
6149 predicate(n->as_StoreVector()->memory_size() == 8);
6150 match(Set mem (StoreVector mem src));
6151 ins_cost(MEMORY_REF_COST);
6152
6153 format %{ "STD $mem, $src \t// packed8B" %}
6154 size(4);
6155 ins_encode( enc_std(src, mem) );
6156 ins_pipe(pipe_class_memory);
6157 %}
6158
6159
6160 instruct storeV16(memoryAlg16 mem, vecX src) %{
6161 predicate(n->as_StoreVector()->memory_size() == 16);
6162 match(Set mem (StoreVector mem src));
6163 ins_cost(MEMORY_REF_COST);
6164
6165 format %{ "STXV $mem, $src \t// store 16-byte Vector" %}
6166 size(4);
6167 ins_encode %{
6168 __ stxv($src$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
6169 %}
6170 ins_pipe(pipe_class_default);
6171 %}
6172
6173 // Reinterpret: only one vector size used: either L or X
6174 instruct reinterpretL(iRegLdst dst) %{
6175 match(Set dst (VectorReinterpret dst));
6176 ins_cost(0);
6177 format %{ "reinterpret $dst" %}
6178 size(0);
6179 ins_encode( /*empty*/ );
6180 ins_pipe(pipe_class_empty);
6181 %}
6182
6183 instruct reinterpretX(vecX dst) %{
6184 match(Set dst (VectorReinterpret dst));
6185 ins_cost(0);
6186 format %{ "reinterpret $dst" %}
6187 size(0);
6188 ins_encode( /*empty*/ );
6189 ins_pipe(pipe_class_empty);
6190 %}
6191
6192 // Store Compressed Oop
6193 instruct storeN(memory dst, iRegN_P2N src) %{
6194 match(Set dst (StoreN dst src));
6195 predicate(n->as_Store()->barrier_data() == 0);
6196 ins_cost(MEMORY_REF_COST);
6197
6198 format %{ "STW $src, $dst \t// compressed oop" %}
6199 size(4);
6200 ins_encode( enc_stw(src, dst) );
6201 ins_pipe(pipe_class_memory);
6202 %}
6203
6204 // Store Compressed KLass
6205 instruct storeNKlass(memory dst, iRegN_P2N src) %{
6206 match(Set dst (StoreNKlass dst src));
6207 ins_cost(MEMORY_REF_COST);
6208
6209 format %{ "STW $src, $dst \t// compressed klass" %}
6210 size(4);
6211 ins_encode( enc_stw(src, dst) );
6212 ins_pipe(pipe_class_memory);
6213 %}
6214
6215 // Store Pointer
6216 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{
6217 match(Set dst (StoreP dst src));
6218 predicate(n->as_Store()->barrier_data() == 0);
6219 ins_cost(MEMORY_REF_COST);
6220
6221 format %{ "STD $src, $dst \t// ptr" %}
6222 size(4);
6223 ins_encode( enc_std(src, dst) );
6224 ins_pipe(pipe_class_memory);
6225 %}
6226
6227 // Store Float
6228 instruct storeF(memory mem, regF src) %{
6229 match(Set mem (StoreF mem src));
6230 ins_cost(MEMORY_REF_COST);
6231
6232 format %{ "STFS $src, $mem" %}
6233 size(4);
6234 ins_encode( enc_stfs(src, mem) );
6235 ins_pipe(pipe_class_memory);
6236 %}
6237
6238 // Store Double
6239 instruct storeD(memory mem, regD src) %{
6240 match(Set mem (StoreD mem src));
6241 ins_cost(MEMORY_REF_COST);
6242
6243 format %{ "STFD $src, $mem" %}
6244 size(4);
6245 ins_encode( enc_stfd(src, mem) );
6246 ins_pipe(pipe_class_memory);
6247 %}
6248
6249 // Convert oop pointer into compressed form.
6250
6251 // Nodes for postalloc expand.
6252
6253 // Shift node for expand.
6254 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
6255 // The match rule is needed to make it a 'MachTypeNode'!
6256 match(Set dst (EncodeP src));
6257 predicate(false);
6258
6259 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6260 size(4);
6261 ins_encode %{
6262 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6263 %}
6264 ins_pipe(pipe_class_default);
6265 %}
6266
6267 // Add node for expand.
6268 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6269 // The match rule is needed to make it a 'MachTypeNode'!
6270 match(Set dst (EncodeP src));
6271 predicate(false);
6272
6273 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6274 ins_encode %{
6275 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6276 %}
6277 ins_pipe(pipe_class_default);
6278 %}
6279
6280 // Conditional sub base.
6281 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6282 // The match rule is needed to make it a 'MachTypeNode'!
6283 match(Set dst (EncodeP (Binary crx src1)));
6284 predicate(false);
6285
6286 format %{ "BEQ $crx, done\n\t"
6287 "SUB $dst, $src1, heapbase \t// encode: subtract base if != nullptr\n"
6288 "done:" %}
6289 ins_encode %{
6290 Label done;
6291 __ beq($crx$$CondRegister, done);
6292 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0);
6293 __ bind(done);
6294 %}
6295 ins_pipe(pipe_class_default);
6296 %}
6297
6298 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6299 // The match rule is needed to make it a 'MachTypeNode'!
6300 match(Set dst (EncodeP (Binary crx src1)));
6301 predicate(false);
6302
6303 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6304 size(4);
6305 ins_encode %{
6306 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6307 %}
6308 ins_pipe(pipe_class_default);
6309 %}
6310
6311 // Disjoint narrow oop base.
6312 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6313 match(Set dst (EncodeP src));
6314 predicate(CompressedOops::base_disjoint());
6315
6316 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6317 size(4);
6318 ins_encode %{
6319 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32);
6320 %}
6321 ins_pipe(pipe_class_default);
6322 %}
6323
6324 // shift != 0, base != 0
6325 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6326 match(Set dst (EncodeP src));
6327 effect(TEMP crx);
6328 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6329 CompressedOops::shift() != 0 &&
6330 CompressedOops::base_overlaps());
6331
6332 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6333 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6334 %}
6335
6336 // shift != 0, base != 0
6337 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6338 match(Set dst (EncodeP src));
6339 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6340 CompressedOops::shift() != 0 &&
6341 CompressedOops::base_overlaps());
6342
6343 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6344 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6345 %}
6346
6347 // shift != 0, base == 0
6348 // TODO: This is the same as encodeP_shift. Merge!
6349 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6350 match(Set dst (EncodeP src));
6351 predicate(CompressedOops::shift() != 0 &&
6352 CompressedOops::base() == nullptr);
6353
6354 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != nullptr" %}
6355 size(4);
6356 ins_encode %{
6357 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6358 %}
6359 ins_pipe(pipe_class_default);
6360 %}
6361
6362 // Compressed OOPs with narrow_oop_shift == 0.
6363 // shift == 0, base == 0
6364 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
6365 match(Set dst (EncodeP src));
6366 predicate(CompressedOops::shift() == 0);
6367
6368 format %{ "MR $dst, $src \t// Ptr->Narrow" %}
6369 // variable size, 0 or 4.
6370 ins_encode %{
6371 __ mr_if_needed($dst$$Register, $src$$Register);
6372 %}
6373 ins_pipe(pipe_class_default);
6374 %}
6375
6376 // Decode nodes.
6377
6378 // Shift node for expand.
6379 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6380 // The match rule is needed to make it a 'MachTypeNode'!
6381 match(Set dst (DecodeN src));
6382 predicate(false);
6383
6384 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6385 size(4);
6386 ins_encode %{
6387 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6388 %}
6389 ins_pipe(pipe_class_default);
6390 %}
6391
6392 // Add node for expand.
6393 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6394 // The match rule is needed to make it a 'MachTypeNode'!
6395 match(Set dst (DecodeN src));
6396 predicate(false);
6397
6398 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %}
6399 ins_encode %{
6400 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6401 %}
6402 ins_pipe(pipe_class_default);
6403 %}
6404
6405 // conditianal add base for expand
6406 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6407 // The match rule is needed to make it a 'MachTypeNode'!
6408 // NOTICE that the rule is nonsense - we just have to make sure that:
6409 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6410 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6411 match(Set dst (DecodeN (Binary crx src)));
6412 predicate(false);
6413
6414 format %{ "BEQ $crx, done\n\t"
6415 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != nullptr\n"
6416 "done:" %}
6417 ins_encode %{
6418 Label done;
6419 __ beq($crx$$CondRegister, done);
6420 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6421 __ bind(done);
6422 %}
6423 ins_pipe(pipe_class_default);
6424 %}
6425
6426 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6427 // The match rule is needed to make it a 'MachTypeNode'!
6428 // NOTICE that the rule is nonsense - we just have to make sure that:
6429 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6430 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6431 match(Set dst (DecodeN (Binary crx src1)));
6432 predicate(false);
6433
6434 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6435 size(4);
6436 ins_encode %{
6437 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6438 %}
6439 ins_pipe(pipe_class_default);
6440 %}
6441
6442 // shift != 0, base != 0
6443 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6444 match(Set dst (DecodeN src));
6445 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6446 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6447 CompressedOops::shift() != 0 &&
6448 CompressedOops::base() != nullptr);
6449 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6450 effect(TEMP crx);
6451
6452 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6453 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6454 %}
6455
6456 // shift != 0, base == 0
6457 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6458 match(Set dst (DecodeN src));
6459 predicate(CompressedOops::shift() != 0 &&
6460 CompressedOops::base() == nullptr);
6461
6462 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %}
6463 size(4);
6464 ins_encode %{
6465 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6466 %}
6467 ins_pipe(pipe_class_default);
6468 %}
6469
6470 // Optimize DecodeN for disjoint base.
6471 // Shift narrow oop and or it into register that already contains the heap base.
6472 // Base == dst must hold, and is assured by construction in postaloc_expand.
6473 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6474 match(Set dst (DecodeN src));
6475 effect(TEMP base);
6476 predicate(false);
6477
6478 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6479 size(4);
6480 ins_encode %{
6481 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift());
6482 %}
6483 ins_pipe(pipe_class_default);
6484 %}
6485
6486 // Optimize DecodeN for disjoint base.
6487 // This node requires only one cycle on the critical path.
6488 // We must postalloc_expand as we can not express use_def effects where
6489 // the used register is L and the def'ed register P.
6490 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6491 match(Set dst (DecodeN src));
6492 effect(TEMP_DEF dst);
6493 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6494 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6495 CompressedOops::base_disjoint());
6496 ins_cost(DEFAULT_COST);
6497
6498 format %{ "MOV $dst, heapbase \t\n"
6499 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6500 postalloc_expand %{
6501 loadBaseNode *n1 = new loadBaseNode();
6502 n1->add_req(nullptr);
6503 n1->_opnds[0] = op_dst;
6504
6505 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6506 n2->add_req(n_region, n_src, n1);
6507 n2->_opnds[0] = op_dst;
6508 n2->_opnds[1] = op_src;
6509 n2->_opnds[2] = op_dst;
6510 n2->_bottom_type = _bottom_type;
6511
6512 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6513 ra_->set_oop(n2, true);
6514
6515 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6516 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6517
6518 nodes->push(n1);
6519 nodes->push(n2);
6520 %}
6521 %}
6522
6523 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6524 match(Set dst (DecodeN src));
6525 effect(TEMP_DEF dst, TEMP crx);
6526 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6527 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6528 CompressedOops::base_disjoint());
6529 ins_cost(3 * DEFAULT_COST);
6530
6531 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %}
6532 postalloc_expand %{
6533 loadBaseNode *n1 = new loadBaseNode();
6534 n1->add_req(nullptr);
6535 n1->_opnds[0] = op_dst;
6536
6537 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
6538 n_compare->add_req(n_region, n_src);
6539 n_compare->_opnds[0] = op_crx;
6540 n_compare->_opnds[1] = op_src;
6541 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6542
6543 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6544 n2->add_req(n_region, n_src, n1);
6545 n2->_opnds[0] = op_dst;
6546 n2->_opnds[1] = op_src;
6547 n2->_opnds[2] = op_dst;
6548 n2->_bottom_type = _bottom_type;
6549
6550 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6551 n_cond_set->add_req(n_region, n_compare, n2);
6552 n_cond_set->_opnds[0] = op_dst;
6553 n_cond_set->_opnds[1] = op_crx;
6554 n_cond_set->_opnds[2] = op_dst;
6555 n_cond_set->_bottom_type = _bottom_type;
6556
6557 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6558 ra_->set_oop(n_cond_set, true);
6559
6560 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6561 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
6562 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6563 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6564
6565 nodes->push(n1);
6566 nodes->push(n_compare);
6567 nodes->push(n2);
6568 nodes->push(n_cond_set);
6569 %}
6570 %}
6571
6572 // src != 0, shift != 0, base != 0
6573 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6574 match(Set dst (DecodeN src));
6575 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6576 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6577 CompressedOops::shift() != 0 &&
6578 CompressedOops::base() != nullptr);
6579 ins_cost(2 * DEFAULT_COST);
6580
6581 format %{ "DecodeN $dst, $src \t// $src != nullptr, postalloc expanded" %}
6582 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6583 %}
6584
6585 // Compressed OOPs with narrow_oop_shift == 0.
6586 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6587 match(Set dst (DecodeN src));
6588 predicate(CompressedOops::shift() == 0);
6589 ins_cost(DEFAULT_COST);
6590
6591 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %}
6592 // variable size, 0 or 4.
6593 ins_encode %{
6594 __ mr_if_needed($dst$$Register, $src$$Register);
6595 %}
6596 ins_pipe(pipe_class_default);
6597 %}
6598
6599 // Convert compressed oop into int for vectors alignment masking.
6600 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
6601 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6602 predicate(CompressedOops::shift() == 0);
6603 ins_cost(DEFAULT_COST);
6604
6605 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %}
6606 // variable size, 0 or 4.
6607 ins_encode %{
6608 __ mr_if_needed($dst$$Register, $src$$Register);
6609 %}
6610 ins_pipe(pipe_class_default);
6611 %}
6612
6613 // Convert klass pointer into compressed form.
6614
6615 // Nodes for postalloc expand.
6616
6617 // Shift node for expand.
6618 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
6619 // The match rule is needed to make it a 'MachTypeNode'!
6620 match(Set dst (EncodePKlass src));
6621 predicate(false);
6622
6623 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6624 size(4);
6625 ins_encode %{
6626 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6627 %}
6628 ins_pipe(pipe_class_default);
6629 %}
6630
6631 // Add node for expand.
6632 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6633 // The match rule is needed to make it a 'MachTypeNode'!
6634 match(Set dst (EncodePKlass (Binary base src)));
6635 predicate(false);
6636
6637 format %{ "SUB $dst, $base, $src \t// encode" %}
6638 size(4);
6639 ins_encode %{
6640 __ subf($dst$$Register, $base$$Register, $src$$Register);
6641 %}
6642 ins_pipe(pipe_class_default);
6643 %}
6644
6645 // Disjoint narrow oop base.
6646 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
6647 match(Set dst (EncodePKlass src));
6648 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/);
6649
6650 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6651 size(4);
6652 ins_encode %{
6653 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
6654 %}
6655 ins_pipe(pipe_class_default);
6656 %}
6657
6658 // shift != 0, base != 0
6659 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6660 match(Set dst (EncodePKlass (Binary base src)));
6661 predicate(false);
6662
6663 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6664 postalloc_expand %{
6665 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
6666 n1->add_req(n_region, n_base, n_src);
6667 n1->_opnds[0] = op_dst;
6668 n1->_opnds[1] = op_base;
6669 n1->_opnds[2] = op_src;
6670 n1->_bottom_type = _bottom_type;
6671
6672 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode();
6673 n2->add_req(n_region, n1);
6674 n2->_opnds[0] = op_dst;
6675 n2->_opnds[1] = op_dst;
6676 n2->_bottom_type = _bottom_type;
6677 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6678 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6679
6680 nodes->push(n1);
6681 nodes->push(n2);
6682 %}
6683 %}
6684
6685 // shift != 0, base != 0
6686 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
6687 match(Set dst (EncodePKlass src));
6688 //predicate(CompressedKlassPointers::shift() != 0 &&
6689 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/);
6690
6691 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6692 ins_cost(DEFAULT_COST*2); // Don't count constant.
6693 expand %{
6694 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %}
6695 iRegLdst base;
6696 loadConL_Ex(base, baseImm);
6697 encodePKlass_not_null_Ex(dst, base, src);
6698 %}
6699 %}
6700
6701 // Decode nodes.
6702
6703 // Shift node for expand.
6704 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
6705 // The match rule is needed to make it a 'MachTypeNode'!
6706 match(Set dst (DecodeNKlass src));
6707 predicate(false);
6708
6709 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %}
6710 size(4);
6711 ins_encode %{
6712 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6713 %}
6714 ins_pipe(pipe_class_default);
6715 %}
6716
6717 // Add node for expand.
6718
6719 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6720 // The match rule is needed to make it a 'MachTypeNode'!
6721 match(Set dst (DecodeNKlass (Binary base src)));
6722 predicate(false);
6723
6724 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
6725 size(4);
6726 ins_encode %{
6727 __ add($dst$$Register, $base$$Register, $src$$Register);
6728 %}
6729 ins_pipe(pipe_class_default);
6730 %}
6731
6732 // src != 0, shift != 0, base != 0
6733 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
6734 match(Set dst (DecodeNKlass (Binary base src)));
6735 //effect(kill src); // We need a register for the immediate result after shifting.
6736 predicate(false);
6737
6738 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != nullptr, postalloc expanded" %}
6739 postalloc_expand %{
6740 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode();
6741 n1->add_req(n_region, n_base, n_src);
6742 n1->_opnds[0] = op_dst;
6743 n1->_opnds[1] = op_base;
6744 n1->_opnds[2] = op_src;
6745 n1->_bottom_type = _bottom_type;
6746
6747 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode();
6748 n2->add_req(n_region, n1);
6749 n2->_opnds[0] = op_dst;
6750 n2->_opnds[1] = op_dst;
6751 n2->_bottom_type = _bottom_type;
6752
6753 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6754 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6755
6756 nodes->push(n1);
6757 nodes->push(n2);
6758 %}
6759 %}
6760
6761 // src != 0, shift != 0, base != 0
6762 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
6763 match(Set dst (DecodeNKlass src));
6764 // predicate(CompressedKlassPointers::shift() != 0 &&
6765 // CompressedKlassPointers::base() != 0);
6766
6767 //format %{ "DecodeNKlass $dst, $src \t// $src != nullptr, expanded" %}
6768
6769 ins_cost(DEFAULT_COST*2); // Don't count constant.
6770 expand %{
6771 // We add first, then we shift. Like this, we can get along with one register less.
6772 // But we have to load the base pre-shifted.
6773 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %}
6774 iRegLdst base;
6775 loadConL_Ex(base, baseImm);
6776 decodeNKlass_notNull_addBase_Ex(dst, base, src);
6777 %}
6778 %}
6779
6780 //----------MemBar Instructions-----------------------------------------------
6781 // Memory barrier flavors
6782
6783 instruct membar_acquire() %{
6784 match(LoadFence);
6785 ins_cost(4*MEMORY_REF_COST);
6786
6787 format %{ "MEMBAR-acquire" %}
6788 size(4);
6789 ins_encode %{
6790 __ acquire();
6791 %}
6792 ins_pipe(pipe_class_default);
6793 %}
6794
6795 instruct unnecessary_membar_acquire() %{
6796 match(MemBarAcquire);
6797 ins_cost(0);
6798
6799 format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
6800 size(0);
6801 ins_encode( /*empty*/ );
6802 ins_pipe(pipe_class_default);
6803 %}
6804
6805 instruct membar_acquire_lock() %{
6806 match(MemBarAcquireLock);
6807 ins_cost(0);
6808
6809 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
6810 size(0);
6811 ins_encode( /*empty*/ );
6812 ins_pipe(pipe_class_default);
6813 %}
6814
6815 instruct membar_release() %{
6816 match(MemBarRelease);
6817 match(StoreFence);
6818 ins_cost(4*MEMORY_REF_COST);
6819
6820 format %{ "MEMBAR-release" %}
6821 size(4);
6822 ins_encode %{
6823 __ release();
6824 %}
6825 ins_pipe(pipe_class_default);
6826 %}
6827
6828 instruct membar_storestore() %{
6829 match(MemBarStoreStore);
6830 match(StoreStoreFence);
6831 ins_cost(4*MEMORY_REF_COST);
6832
6833 format %{ "MEMBAR-store-store" %}
6834 size(4);
6835 ins_encode %{
6836 __ membar(Assembler::StoreStore);
6837 %}
6838 ins_pipe(pipe_class_default);
6839 %}
6840
6841 instruct membar_release_lock() %{
6842 match(MemBarReleaseLock);
6843 ins_cost(0);
6844
6845 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
6846 size(0);
6847 ins_encode( /*empty*/ );
6848 ins_pipe(pipe_class_default);
6849 %}
6850
6851 instruct membar_storeload() %{
6852 match(MemBarStoreLoad);
6853 ins_cost(4*MEMORY_REF_COST);
6854
6855 format %{ "MEMBAR-store-load" %}
6856 size(4);
6857 ins_encode %{
6858 __ fence();
6859 %}
6860 ins_pipe(pipe_class_default);
6861 %}
6862
6863 instruct membar_volatile() %{
6864 match(MemBarVolatile);
6865 ins_cost(4*MEMORY_REF_COST);
6866
6867 format %{ "MEMBAR-volatile" %}
6868 size(4);
6869 ins_encode %{
6870 __ fence();
6871 %}
6872 ins_pipe(pipe_class_default);
6873 %}
6874
6875 // This optimization is wrong on PPC. The following pattern is not supported:
6876 // MemBarVolatile
6877 // ^ ^
6878 // | |
6879 // CtrlProj MemProj
6880 // ^ ^
6881 // | |
6882 // | Load
6883 // |
6884 // MemBarVolatile
6885 //
6886 // The first MemBarVolatile could get optimized out! According to
6887 // Vladimir, this pattern can not occur on Oracle platforms.
6888 // However, it does occur on PPC64 (because of membars in
6889 // inline_unsafe_load_store).
6890 //
6891 // Add this node again if we found a good solution for inline_unsafe_load_store().
6892 // Don't forget to look at the implementation of post_store_load_barrier again,
6893 // we did other fixes in that method.
6894 //instruct unnecessary_membar_volatile() %{
6895 // match(MemBarVolatile);
6896 // predicate(Matcher::post_store_load_barrier(n));
6897 // ins_cost(0);
6898 //
6899 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
6900 // size(0);
6901 // ins_encode( /*empty*/ );
6902 // ins_pipe(pipe_class_default);
6903 //%}
6904
6905 instruct membar_full() %{
6906 match(MemBarFull);
6907 ins_cost(4*MEMORY_REF_COST);
6908
6909 format %{ "MEMBAR-full" %}
6910 size(4);
6911 ins_encode %{
6912 __ fence();
6913 %}
6914 ins_pipe(pipe_class_default);
6915 %}
6916
6917 instruct membar_CPUOrder() %{
6918 match(MemBarCPUOrder);
6919 ins_cost(0);
6920
6921 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
6922 size(0);
6923 ins_encode( /*empty*/ );
6924 ins_pipe(pipe_class_default);
6925 %}
6926
6927 //----------Conditional Move---------------------------------------------------
6928
6929 // Cmove using isel.
6930 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
6931 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
6932 ins_cost(DEFAULT_COST);
6933
6934 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6935 size(4);
6936 ins_encode %{
6937 int cc = $cmp$$cmpcode;
6938 __ isel($dst$$Register, $crx$$CondRegister,
6939 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6940 %}
6941 ins_pipe(pipe_class_default);
6942 %}
6943
6944 // Cmove using isel.
6945 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
6946 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
6947 ins_cost(DEFAULT_COST);
6948
6949 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6950 size(4);
6951 ins_encode %{
6952 int cc = $cmp$$cmpcode;
6953 __ isel($dst$$Register, $crx$$CondRegister,
6954 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6955 %}
6956 ins_pipe(pipe_class_default);
6957 %}
6958
6959 // Cmove using isel.
6960 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
6961 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
6962 ins_cost(DEFAULT_COST);
6963
6964 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6965 size(4);
6966 ins_encode %{
6967 int cc = $cmp$$cmpcode;
6968 __ isel($dst$$Register, $crx$$CondRegister,
6969 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6970 %}
6971 ins_pipe(pipe_class_default);
6972 %}
6973
6974 // Cmove using isel.
6975 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
6976 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
6977 ins_cost(DEFAULT_COST);
6978
6979 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6980 size(4);
6981 ins_encode %{
6982 int cc = $cmp$$cmpcode;
6983 __ isel($dst$$Register, $crx$$CondRegister,
6984 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6985 %}
6986 ins_pipe(pipe_class_default);
6987 %}
6988
6989 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
6990 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
6991 ins_cost(DEFAULT_COST+BRANCH_COST);
6992
6993 ins_variable_size_depending_on_alignment(true);
6994
6995 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
6996 size(8);
6997 ins_encode %{
6998 Label done;
6999 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7000 // Branch if not (cmp crx).
7001 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7002 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7003 __ bind(done);
7004 %}
7005 ins_pipe(pipe_class_default);
7006 %}
7007
7008 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7009 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7010 ins_cost(DEFAULT_COST+BRANCH_COST);
7011
7012 ins_variable_size_depending_on_alignment(true);
7013
7014 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7015 size(8);
7016 ins_encode %{
7017 Label done;
7018 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7019 // Branch if not (cmp crx).
7020 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7021 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7022 __ bind(done);
7023 %}
7024 ins_pipe(pipe_class_default);
7025 %}
7026
7027 instruct cmovF_cmpF(cmpOp cop, regF op1, regF op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7028 match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7029 predicate(PowerArchitecturePPC64 >= 9);
7030 effect(TEMP tmp);
7031 ins_cost(2*DEFAULT_COST);
7032 format %{ "cmovF_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7033 size(8);
7034 ins_encode %{
7035 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7036 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7037 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7038 $tmp$$FloatRegister->to_vsr());
7039 %}
7040 ins_pipe(pipe_class_default);
7041 %}
7042
7043 instruct cmovF_cmpD(cmpOp cop, regD op1, regD op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7044 match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7045 predicate(PowerArchitecturePPC64 >= 9);
7046 effect(TEMP tmp);
7047 ins_cost(2*DEFAULT_COST);
7048 format %{ "cmovF_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7049 size(8);
7050 ins_encode %{
7051 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7052 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7053 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7054 $tmp$$FloatRegister->to_vsr());
7055 %}
7056 ins_pipe(pipe_class_default);
7057 %}
7058
7059 instruct cmovD_cmpD(cmpOp cop, regD op1, regD op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7060 match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7061 predicate(PowerArchitecturePPC64 >= 9);
7062 effect(TEMP tmp);
7063 ins_cost(2*DEFAULT_COST);
7064 format %{ "cmovD_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7065 size(8);
7066 ins_encode %{
7067 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7068 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7069 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7070 $tmp$$FloatRegister->to_vsr());
7071 %}
7072 ins_pipe(pipe_class_default);
7073 %}
7074
7075 instruct cmovD_cmpF(cmpOp cop, regF op1, regF op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7076 match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7077 predicate(PowerArchitecturePPC64 >= 9);
7078 effect(TEMP tmp);
7079 ins_cost(2*DEFAULT_COST);
7080 format %{ "cmovD_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7081 size(8);
7082 ins_encode %{
7083 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7084 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7085 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7086 $tmp$$FloatRegister->to_vsr());
7087 %}
7088 ins_pipe(pipe_class_default);
7089 %}
7090
7091 //----------Compare-And-Swap---------------------------------------------------
7092
7093 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7094 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7095 // matched.
7096
7097 // Strong versions:
7098
7099 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7100 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7101 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7102 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7103 ins_encode %{
7104 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7105 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7106 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7107 $res$$Register, nullptr, true);
7108 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7109 __ isync();
7110 } else {
7111 __ sync();
7112 }
7113 %}
7114 ins_pipe(pipe_class_default);
7115 %}
7116
7117 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7118 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7119 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7120 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7121 ins_encode %{
7122 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7123 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7124 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7125 $res$$Register, nullptr, true);
7126 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7127 __ isync();
7128 } else {
7129 __ sync();
7130 }
7131 %}
7132 ins_pipe(pipe_class_default);
7133 %}
7134
7135 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7136 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7137 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7138 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7139 ins_encode %{
7140 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7141 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7142 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7143 $res$$Register, nullptr, true);
7144 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7145 __ isync();
7146 } else {
7147 __ sync();
7148 }
7149 %}
7150 ins_pipe(pipe_class_default);
7151 %}
7152
7153 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7154 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7155 predicate(n->as_LoadStore()->barrier_data() == 0);
7156 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7157 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7158 ins_encode %{
7159 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7160 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7161 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7162 $res$$Register, nullptr, true);
7163 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7164 __ isync();
7165 } else {
7166 __ sync();
7167 }
7168 %}
7169 ins_pipe(pipe_class_default);
7170 %}
7171
7172 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7173 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7174 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7175 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7176 ins_encode %{
7177 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7178 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7179 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7180 $res$$Register, nullptr, true);
7181 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7182 __ isync();
7183 } else {
7184 __ sync();
7185 }
7186 %}
7187 ins_pipe(pipe_class_default);
7188 %}
7189
7190 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7191 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7192 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7193 predicate(n->as_LoadStore()->barrier_data() == 0);
7194 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7195 ins_encode %{
7196 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7197 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7198 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7199 $res$$Register, nullptr, true);
7200 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7201 __ isync();
7202 } else {
7203 __ sync();
7204 }
7205 %}
7206 ins_pipe(pipe_class_default);
7207 %}
7208
7209 // Weak versions:
7210
7211 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7212 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7213 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7214 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7215 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7216 ins_encode %{
7217 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7218 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7219 MacroAssembler::MemBarNone,
7220 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7221 %}
7222 ins_pipe(pipe_class_default);
7223 %}
7224
7225 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7226 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7227 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) );
7228 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7229 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7230 ins_encode %{
7231 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7232 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7233 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7234 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7235 %}
7236 ins_pipe(pipe_class_default);
7237 %}
7238
7239 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7240 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7241 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7242 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7243 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7244 ins_encode %{
7245 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7246 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7247 MacroAssembler::MemBarNone,
7248 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7249 %}
7250 ins_pipe(pipe_class_default);
7251 %}
7252
7253 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7254 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7255 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7256 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7257 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7258 ins_encode %{
7259 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7260 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7261 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7262 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7263 %}
7264 ins_pipe(pipe_class_default);
7265 %}
7266
7267 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7268 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7269 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7270 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7271 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7272 ins_encode %{
7273 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7274 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7275 MacroAssembler::MemBarNone,
7276 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7277 %}
7278 ins_pipe(pipe_class_default);
7279 %}
7280
7281 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7282 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7283 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7284 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7285 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7286 ins_encode %{
7287 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7288 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7289 // value is never passed to caller.
7290 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7291 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7292 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7293 %}
7294 ins_pipe(pipe_class_default);
7295 %}
7296
7297 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7298 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7299 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7300 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7301 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7302 ins_encode %{
7303 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7304 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7305 MacroAssembler::MemBarNone,
7306 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7307 %}
7308 ins_pipe(pipe_class_default);
7309 %}
7310
7311 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7312 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7313 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7314 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7315 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7316 ins_encode %{
7317 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7318 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7319 // value is never passed to caller.
7320 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7321 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7322 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7323 %}
7324 ins_pipe(pipe_class_default);
7325 %}
7326
7327 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7328 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7329 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7330 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7331 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7332 ins_encode %{
7333 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7334 // value is never passed to caller.
7335 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7336 MacroAssembler::MemBarNone,
7337 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7338 %}
7339 ins_pipe(pipe_class_default);
7340 %}
7341
7342 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7343 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7344 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7345 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7346 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7347 ins_encode %{
7348 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7349 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7350 // value is never passed to caller.
7351 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7352 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7353 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7354 %}
7355 ins_pipe(pipe_class_default);
7356 %}
7357
7358 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7359 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7360 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7361 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7362 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7363 ins_encode %{
7364 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7365 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7366 MacroAssembler::MemBarNone,
7367 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7368 %}
7369 ins_pipe(pipe_class_default);
7370 %}
7371
7372 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7373 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7374 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7375 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7376 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7377 ins_encode %{
7378 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7379 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7380 // value is never passed to caller.
7381 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7382 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7383 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7384 %}
7385 ins_pipe(pipe_class_default);
7386 %}
7387
7388 // CompareAndExchange
7389
7390 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7391 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7392 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7393 effect(TEMP_DEF res, TEMP cr0);
7394 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7395 ins_encode %{
7396 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7397 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7398 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7399 noreg, nullptr, true);
7400 %}
7401 ins_pipe(pipe_class_default);
7402 %}
7403
7404 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7405 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7406 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7407 effect(TEMP_DEF res, TEMP cr0);
7408 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7409 ins_encode %{
7410 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7411 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7412 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7413 noreg, nullptr, true);
7414 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7415 __ isync();
7416 } else {
7417 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7418 __ sync();
7419 }
7420 %}
7421 ins_pipe(pipe_class_default);
7422 %}
7423
7424
7425 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7426 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7427 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7428 effect(TEMP_DEF res, TEMP cr0);
7429 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7430 ins_encode %{
7431 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7432 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7433 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7434 noreg, nullptr, true);
7435 %}
7436 ins_pipe(pipe_class_default);
7437 %}
7438
7439 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7440 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7441 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7442 effect(TEMP_DEF res, TEMP cr0);
7443 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7444 ins_encode %{
7445 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7446 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7447 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7448 noreg, nullptr, true);
7449 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7450 __ isync();
7451 } else {
7452 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7453 __ sync();
7454 }
7455 %}
7456 ins_pipe(pipe_class_default);
7457 %}
7458
7459 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7460 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7461 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7462 effect(TEMP_DEF res, TEMP cr0);
7463 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
7464 ins_encode %{
7465 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7466 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7467 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7468 noreg, nullptr, true);
7469 %}
7470 ins_pipe(pipe_class_default);
7471 %}
7472
7473 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7474 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7475 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7476 effect(TEMP_DEF res, TEMP cr0);
7477 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
7478 ins_encode %{
7479 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7480 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7481 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7482 noreg, nullptr, true);
7483 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7484 __ isync();
7485 } else {
7486 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7487 __ sync();
7488 }
7489 %}
7490 ins_pipe(pipe_class_default);
7491 %}
7492
7493 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7494 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7495 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7496 effect(TEMP_DEF res, TEMP cr0);
7497 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7498 ins_encode %{
7499 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7500 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7501 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7502 noreg, nullptr, true);
7503 %}
7504 ins_pipe(pipe_class_default);
7505 %}
7506
7507 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7508 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7509 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7510 effect(TEMP_DEF res, TEMP cr0);
7511 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7512 ins_encode %{
7513 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7514 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7515 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7516 noreg, nullptr, true);
7517 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7518 __ isync();
7519 } else {
7520 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7521 __ sync();
7522 }
7523 %}
7524 ins_pipe(pipe_class_default);
7525 %}
7526
7527 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7528 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7529 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7530 effect(TEMP_DEF res, TEMP cr0);
7531 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
7532 ins_encode %{
7533 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7534 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7535 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7536 noreg, nullptr, true);
7537 %}
7538 ins_pipe(pipe_class_default);
7539 %}
7540
7541 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7542 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7543 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7544 effect(TEMP_DEF res, TEMP cr0);
7545 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
7546 ins_encode %{
7547 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7548 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7549 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7550 noreg, nullptr, true);
7551 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7552 __ isync();
7553 } else {
7554 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7555 __ sync();
7556 }
7557 %}
7558 ins_pipe(pipe_class_default);
7559 %}
7560
7561 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7562 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7563 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst)
7564 && n->as_LoadStore()->barrier_data() == 0);
7565 effect(TEMP_DEF res, TEMP cr0);
7566 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7567 ins_encode %{
7568 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7569 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7570 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7571 noreg, nullptr, true);
7572 %}
7573 ins_pipe(pipe_class_default);
7574 %}
7575
7576 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7577 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7578 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst)
7579 && n->as_LoadStore()->barrier_data() == 0);
7580 effect(TEMP_DEF res, TEMP cr0);
7581 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7582 ins_encode %{
7583 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7584 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7585 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7586 noreg, nullptr, true);
7587 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7588 __ isync();
7589 } else {
7590 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7591 __ sync();
7592 }
7593 %}
7594 ins_pipe(pipe_class_default);
7595 %}
7596
7597 // Special RMW
7598
7599 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7600 match(Set res (GetAndAddB mem_ptr src));
7601 effect(TEMP_DEF res, TEMP cr0);
7602 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
7603 ins_encode %{
7604 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
7605 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7606 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7607 __ isync();
7608 } else {
7609 __ sync();
7610 }
7611 %}
7612 ins_pipe(pipe_class_default);
7613 %}
7614
7615 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7616 match(Set res (GetAndAddS mem_ptr src));
7617 effect(TEMP_DEF res, TEMP cr0);
7618 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
7619 ins_encode %{
7620 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
7621 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7622 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7623 __ isync();
7624 } else {
7625 __ sync();
7626 }
7627 %}
7628 ins_pipe(pipe_class_default);
7629 %}
7630
7631
7632 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7633 match(Set res (GetAndAddI mem_ptr src));
7634 effect(TEMP_DEF res, TEMP cr0);
7635 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
7636 ins_encode %{
7637 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
7638 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7639 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7640 __ isync();
7641 } else {
7642 __ sync();
7643 }
7644 %}
7645 ins_pipe(pipe_class_default);
7646 %}
7647
7648 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7649 match(Set res (GetAndAddL mem_ptr src));
7650 effect(TEMP_DEF res, TEMP cr0);
7651 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
7652 ins_encode %{
7653 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
7654 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7655 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7656 __ isync();
7657 } else {
7658 __ sync();
7659 }
7660 %}
7661 ins_pipe(pipe_class_default);
7662 %}
7663
7664 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7665 match(Set res (GetAndSetB mem_ptr src));
7666 effect(TEMP_DEF res, TEMP cr0);
7667 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
7668 ins_encode %{
7669 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
7670 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7671 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7672 __ isync();
7673 } else {
7674 __ sync();
7675 }
7676 %}
7677 ins_pipe(pipe_class_default);
7678 %}
7679
7680 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7681 match(Set res (GetAndSetS mem_ptr src));
7682 effect(TEMP_DEF res, TEMP cr0);
7683 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
7684 ins_encode %{
7685 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
7686 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7687 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7688 __ isync();
7689 } else {
7690 __ sync();
7691 }
7692 %}
7693 ins_pipe(pipe_class_default);
7694 %}
7695
7696
7697 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7698 match(Set res (GetAndSetI mem_ptr src));
7699 effect(TEMP_DEF res, TEMP cr0);
7700 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
7701 ins_encode %{
7702 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7703 MacroAssembler::cmpxchgx_hint_atomic_update());
7704 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7705 __ isync();
7706 } else {
7707 __ sync();
7708 }
7709 %}
7710 ins_pipe(pipe_class_default);
7711 %}
7712
7713 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7714 match(Set res (GetAndSetL mem_ptr src));
7715 effect(TEMP_DEF res, TEMP cr0);
7716 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
7717 ins_encode %{
7718 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7719 MacroAssembler::cmpxchgx_hint_atomic_update());
7720 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7721 __ isync();
7722 } else {
7723 __ sync();
7724 }
7725 %}
7726 ins_pipe(pipe_class_default);
7727 %}
7728
7729 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
7730 match(Set res (GetAndSetP mem_ptr src));
7731 predicate(n->as_LoadStore()->barrier_data() == 0);
7732 effect(TEMP_DEF res, TEMP cr0);
7733 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
7734 ins_encode %{
7735 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7736 MacroAssembler::cmpxchgx_hint_atomic_update());
7737 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7738 __ isync();
7739 } else {
7740 __ sync();
7741 }
7742 %}
7743 ins_pipe(pipe_class_default);
7744 %}
7745
7746 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
7747 match(Set res (GetAndSetN mem_ptr src));
7748 predicate(n->as_LoadStore()->barrier_data() == 0);
7749 effect(TEMP_DEF res, TEMP cr0);
7750 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
7751 ins_encode %{
7752 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7753 MacroAssembler::cmpxchgx_hint_atomic_update());
7754 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7755 __ isync();
7756 } else {
7757 __ sync();
7758 }
7759 %}
7760 ins_pipe(pipe_class_default);
7761 %}
7762
7763 //----------Arithmetic Instructions--------------------------------------------
7764 // Addition Instructions
7765
7766 // Register Addition
7767 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
7768 match(Set dst (AddI src1 src2));
7769 format %{ "ADD $dst, $src1, $src2" %}
7770 size(4);
7771 ins_encode %{
7772 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7773 %}
7774 ins_pipe(pipe_class_default);
7775 %}
7776
7777 // Expand does not work with above instruct. (??)
7778 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7779 // no match-rule
7780 effect(DEF dst, USE src1, USE src2);
7781 format %{ "ADD $dst, $src1, $src2" %}
7782 size(4);
7783 ins_encode %{
7784 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7785 %}
7786 ins_pipe(pipe_class_default);
7787 %}
7788
7789 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
7790 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
7791 ins_cost(DEFAULT_COST*3);
7792
7793 expand %{
7794 // FIXME: we should do this in the ideal world.
7795 iRegIdst tmp1;
7796 iRegIdst tmp2;
7797 addI_reg_reg(tmp1, src1, src2);
7798 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
7799 addI_reg_reg(dst, tmp1, tmp2);
7800 %}
7801 %}
7802
7803 // Immediate Addition
7804 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
7805 match(Set dst (AddI src1 src2));
7806 format %{ "ADDI $dst, $src1, $src2" %}
7807 size(4);
7808 ins_encode %{
7809 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7810 %}
7811 ins_pipe(pipe_class_default);
7812 %}
7813
7814 // Immediate Addition with 16-bit shifted operand
7815 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
7816 match(Set dst (AddI src1 src2));
7817 format %{ "ADDIS $dst, $src1, $src2" %}
7818 size(4);
7819 ins_encode %{
7820 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7821 %}
7822 ins_pipe(pipe_class_default);
7823 %}
7824
7825 // Immediate Addition using prefixed addi
7826 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{
7827 match(Set dst (AddI src1 src2));
7828 predicate(PowerArchitecturePPC64 >= 10);
7829 ins_cost(DEFAULT_COST+1);
7830 format %{ "PADDI $dst, $src1, $src2" %}
7831 size(8);
7832 ins_encode %{
7833 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7834 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7835 %}
7836 ins_pipe(pipe_class_default);
7837 ins_alignment(2);
7838 %}
7839
7840 // Long Addition
7841 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7842 match(Set dst (AddL src1 src2));
7843 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7844 size(4);
7845 ins_encode %{
7846 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7847 %}
7848 ins_pipe(pipe_class_default);
7849 %}
7850
7851 // Expand does not work with above instruct. (??)
7852 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7853 // no match-rule
7854 effect(DEF dst, USE src1, USE src2);
7855 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7856 size(4);
7857 ins_encode %{
7858 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7859 %}
7860 ins_pipe(pipe_class_default);
7861 %}
7862
7863 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
7864 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
7865 ins_cost(DEFAULT_COST*3);
7866
7867 expand %{
7868 // FIXME: we should do this in the ideal world.
7869 iRegLdst tmp1;
7870 iRegLdst tmp2;
7871 addL_reg_reg(tmp1, src1, src2);
7872 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
7873 addL_reg_reg(dst, tmp1, tmp2);
7874 %}
7875 %}
7876
7877 // AddL + ConvL2I.
7878 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
7879 match(Set dst (ConvL2I (AddL src1 src2)));
7880
7881 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %}
7882 size(4);
7883 ins_encode %{
7884 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7885 %}
7886 ins_pipe(pipe_class_default);
7887 %}
7888
7889 // No constant pool entries required.
7890 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
7891 match(Set dst (AddL src1 src2));
7892
7893 format %{ "ADDI $dst, $src1, $src2" %}
7894 size(4);
7895 ins_encode %{
7896 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7897 %}
7898 ins_pipe(pipe_class_default);
7899 %}
7900
7901 // Long Immediate Addition with 16-bit shifted operand.
7902 // No constant pool entries required.
7903 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
7904 match(Set dst (AddL src1 src2));
7905
7906 format %{ "ADDIS $dst, $src1, $src2" %}
7907 size(4);
7908 ins_encode %{
7909 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7910 %}
7911 ins_pipe(pipe_class_default);
7912 %}
7913
7914 // Long Immediate Addition using prefixed addi
7915 // No constant pool entries required.
7916 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{
7917 match(Set dst (AddL src1 src2));
7918 predicate(PowerArchitecturePPC64 >= 10);
7919 ins_cost(DEFAULT_COST+1);
7920
7921 format %{ "PADDI $dst, $src1, $src2" %}
7922 size(8);
7923 ins_encode %{
7924 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7925 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7926 %}
7927 ins_pipe(pipe_class_default);
7928 ins_alignment(2);
7929 %}
7930
7931 // Pointer Register Addition
7932 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
7933 match(Set dst (AddP src1 src2));
7934 format %{ "ADD $dst, $src1, $src2" %}
7935 size(4);
7936 ins_encode %{
7937 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7938 %}
7939 ins_pipe(pipe_class_default);
7940 %}
7941
7942 // Pointer Immediate Addition
7943 // No constant pool entries required.
7944 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
7945 match(Set dst (AddP src1 src2));
7946
7947 format %{ "ADDI $dst, $src1, $src2" %}
7948 size(4);
7949 ins_encode %{
7950 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7951 %}
7952 ins_pipe(pipe_class_default);
7953 %}
7954
7955 // Pointer Immediate Addition with 16-bit shifted operand.
7956 // No constant pool entries required.
7957 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
7958 match(Set dst (AddP src1 src2));
7959
7960 format %{ "ADDIS $dst, $src1, $src2" %}
7961 size(4);
7962 ins_encode %{
7963 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7964 %}
7965 ins_pipe(pipe_class_default);
7966 %}
7967
7968 // Pointer Immediate Addition using prefixed addi
7969 // No constant pool entries required.
7970 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{
7971 match(Set dst (AddP src1 src2));
7972 predicate(PowerArchitecturePPC64 >= 10);
7973 ins_cost(DEFAULT_COST+1);
7974
7975 format %{ "PADDI $dst, $src1, $src2" %}
7976 size(8);
7977 ins_encode %{
7978 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7979 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7980 %}
7981 ins_pipe(pipe_class_default);
7982 ins_alignment(2);
7983 %}
7984
7985 //---------------------
7986 // Subtraction Instructions
7987
7988 // Register Subtraction
7989 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7990 match(Set dst (SubI src1 src2));
7991 format %{ "SUBF $dst, $src2, $src1" %}
7992 size(4);
7993 ins_encode %{
7994 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7995 %}
7996 ins_pipe(pipe_class_default);
7997 %}
7998
7999 // Immediate Subtraction
8000 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
8001 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
8002
8003 // SubI from constant (using subfic).
8004 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
8005 match(Set dst (SubI src1 src2));
8006 format %{ "SUBI $dst, $src1, $src2" %}
8007
8008 size(4);
8009 ins_encode %{
8010 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
8011 %}
8012 ins_pipe(pipe_class_default);
8013 %}
8014
8015 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
8016 // positive integers and 0xF...F for negative ones.
8017 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
8018 // no match-rule, false predicate
8019 effect(DEF dst, USE src);
8020 predicate(false);
8021
8022 format %{ "SRAWI $dst, $src, #31" %}
8023 size(4);
8024 ins_encode %{
8025 __ srawi($dst$$Register, $src$$Register, 0x1f);
8026 %}
8027 ins_pipe(pipe_class_default);
8028 %}
8029
8030 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
8031 match(Set dst (AbsI src));
8032 ins_cost(DEFAULT_COST*3);
8033
8034 expand %{
8035 iRegIdst tmp1;
8036 iRegIdst tmp2;
8037 signmask32I_regI(tmp1, src);
8038 xorI_reg_reg(tmp2, tmp1, src);
8039 subI_reg_reg(dst, tmp2, tmp1);
8040 %}
8041 %}
8042
8043 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
8044 match(Set dst (SubI zero src2));
8045 format %{ "NEG $dst, $src2" %}
8046 size(4);
8047 ins_encode %{
8048 __ neg($dst$$Register, $src2$$Register);
8049 %}
8050 ins_pipe(pipe_class_default);
8051 %}
8052
8053 // Long subtraction
8054 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8055 match(Set dst (SubL src1 src2));
8056 format %{ "SUBF $dst, $src2, $src1 \t// long" %}
8057 size(4);
8058 ins_encode %{
8059 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8060 %}
8061 ins_pipe(pipe_class_default);
8062 %}
8063
8064 // SubL + convL2I.
8065 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8066 match(Set dst (ConvL2I (SubL src1 src2)));
8067
8068 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
8069 size(4);
8070 ins_encode %{
8071 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8072 %}
8073 ins_pipe(pipe_class_default);
8074 %}
8075
8076 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8077 // positive longs and 0xF...F for negative ones.
8078 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8079 // no match-rule, false predicate
8080 effect(DEF dst, USE src);
8081 predicate(false);
8082
8083 format %{ "SRADI $dst, $src, #63" %}
8084 size(4);
8085 ins_encode %{
8086 __ sradi($dst$$Register, $src$$Register, 0x3f);
8087 %}
8088 ins_pipe(pipe_class_default);
8089 %}
8090
8091 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8092 // positive longs and 0xF...F for negative ones.
8093 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8094 // no match-rule, false predicate
8095 effect(DEF dst, USE src);
8096 predicate(false);
8097
8098 format %{ "SRADI $dst, $src, #63" %}
8099 size(4);
8100 ins_encode %{
8101 __ sradi($dst$$Register, $src$$Register, 0x3f);
8102 %}
8103 ins_pipe(pipe_class_default);
8104 %}
8105
8106 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{
8107 match(Set dst (AbsL src));
8108 ins_cost(DEFAULT_COST*3);
8109
8110 expand %{
8111 iRegLdst tmp1;
8112 iRegLdst tmp2;
8113 signmask64L_regL(tmp1, src);
8114 xorL_reg_reg(tmp2, tmp1, src);
8115 subL_reg_reg(dst, tmp2, tmp1);
8116 %}
8117 %}
8118
8119 // Long negation
8120 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8121 match(Set dst (SubL zero src2));
8122 format %{ "NEG $dst, $src2 \t// long" %}
8123 size(4);
8124 ins_encode %{
8125 __ neg($dst$$Register, $src2$$Register);
8126 %}
8127 ins_pipe(pipe_class_default);
8128 %}
8129
8130 // NegL + ConvL2I.
8131 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8132 match(Set dst (ConvL2I (SubL zero src2)));
8133
8134 format %{ "NEG $dst, $src2 \t// long + l2i" %}
8135 size(4);
8136 ins_encode %{
8137 __ neg($dst$$Register, $src2$$Register);
8138 %}
8139 ins_pipe(pipe_class_default);
8140 %}
8141
8142 // Multiplication Instructions
8143 // Integer Multiplication
8144
8145 // Register Multiplication
8146 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8147 match(Set dst (MulI src1 src2));
8148 ins_cost(DEFAULT_COST);
8149
8150 format %{ "MULLW $dst, $src1, $src2" %}
8151 size(4);
8152 ins_encode %{
8153 __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8154 %}
8155 ins_pipe(pipe_class_default);
8156 %}
8157
8158 // Immediate Multiplication
8159 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8160 match(Set dst (MulI src1 src2));
8161 ins_cost(DEFAULT_COST);
8162
8163 format %{ "MULLI $dst, $src1, $src2" %}
8164 size(4);
8165 ins_encode %{
8166 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8167 %}
8168 ins_pipe(pipe_class_default);
8169 %}
8170
8171 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8172 match(Set dst (MulL src1 src2));
8173 ins_cost(DEFAULT_COST);
8174
8175 format %{ "MULLD $dst $src1, $src2 \t// long" %}
8176 size(4);
8177 ins_encode %{
8178 __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8179 %}
8180 ins_pipe(pipe_class_default);
8181 %}
8182
8183 // Multiply high for optimized long division by constant.
8184 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8185 match(Set dst (MulHiL src1 src2));
8186 ins_cost(DEFAULT_COST);
8187
8188 format %{ "MULHD $dst $src1, $src2 \t// long" %}
8189 size(4);
8190 ins_encode %{
8191 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8192 %}
8193 ins_pipe(pipe_class_default);
8194 %}
8195
8196 instruct uMulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8197 match(Set dst (UMulHiL src1 src2));
8198 ins_cost(DEFAULT_COST);
8199
8200 format %{ "MULHDU $dst $src1, $src2 \t// unsigned long" %}
8201 size(4);
8202 ins_encode %{
8203 __ mulhdu($dst$$Register, $src1$$Register, $src2$$Register);
8204 %}
8205 ins_pipe(pipe_class_default);
8206 %}
8207
8208 // Immediate Multiplication
8209 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8210 match(Set dst (MulL src1 src2));
8211 ins_cost(DEFAULT_COST);
8212
8213 format %{ "MULLI $dst, $src1, $src2" %}
8214 size(4);
8215 ins_encode %{
8216 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8217 %}
8218 ins_pipe(pipe_class_default);
8219 %}
8220
8221 // Integer Division with Immediate -1: Negate.
8222 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8223 match(Set dst (DivI src1 src2));
8224 ins_cost(DEFAULT_COST);
8225
8226 format %{ "NEG $dst, $src1 \t// /-1" %}
8227 size(4);
8228 ins_encode %{
8229 __ neg($dst$$Register, $src1$$Register);
8230 %}
8231 ins_pipe(pipe_class_default);
8232 %}
8233
8234 // Integer Division with constant, but not -1.
8235 // We should be able to improve this by checking the type of src2.
8236 // It might well be that src2 is known to be positive.
8237 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8238 match(Set dst (DivI src1 src2));
8239 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8240 ins_cost(2*DEFAULT_COST);
8241
8242 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8243 size(4);
8244 ins_encode %{
8245 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8246 %}
8247 ins_pipe(pipe_class_default);
8248 %}
8249
8250 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8251 effect(USE_DEF dst, USE src1, USE crx);
8252 predicate(false);
8253
8254 ins_variable_size_depending_on_alignment(true);
8255
8256 format %{ "CMOVE $dst, neg($src1), $crx" %}
8257 size(8);
8258 ins_encode %{
8259 Label done;
8260 __ bne($crx$$CondRegister, done);
8261 __ neg($dst$$Register, $src1$$Register);
8262 __ bind(done);
8263 %}
8264 ins_pipe(pipe_class_default);
8265 %}
8266
8267 // Integer Division with Registers not containing constants.
8268 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8269 match(Set dst (DivI src1 src2));
8270 ins_cost(10*DEFAULT_COST);
8271
8272 expand %{
8273 immI16 imm %{ (int)-1 %}
8274 flagsReg tmp1;
8275 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8276 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8277 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8278 %}
8279 %}
8280
8281 // Long Division with Immediate -1: Negate.
8282 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8283 match(Set dst (DivL src1 src2));
8284 ins_cost(DEFAULT_COST);
8285
8286 format %{ "NEG $dst, $src1 \t// /-1, long" %}
8287 size(4);
8288 ins_encode %{
8289 __ neg($dst$$Register, $src1$$Register);
8290 %}
8291 ins_pipe(pipe_class_default);
8292 %}
8293
8294 // Long Division with constant, but not -1.
8295 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8296 match(Set dst (DivL src1 src2));
8297 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8298 ins_cost(2*DEFAULT_COST);
8299
8300 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8301 size(4);
8302 ins_encode %{
8303 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8304 %}
8305 ins_pipe(pipe_class_default);
8306 %}
8307
8308 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8309 effect(USE_DEF dst, USE src1, USE crx);
8310 predicate(false);
8311
8312 ins_variable_size_depending_on_alignment(true);
8313
8314 format %{ "CMOVE $dst, neg($src1), $crx" %}
8315 size(8);
8316 ins_encode %{
8317 Label done;
8318 __ bne($crx$$CondRegister, done);
8319 __ neg($dst$$Register, $src1$$Register);
8320 __ bind(done);
8321 %}
8322 ins_pipe(pipe_class_default);
8323 %}
8324
8325 // Long Division with Registers not containing constants.
8326 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8327 match(Set dst (DivL src1 src2));
8328 ins_cost(10*DEFAULT_COST);
8329
8330 expand %{
8331 immL16 imm %{ (int)-1 %}
8332 flagsReg tmp1;
8333 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8334 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8335 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8336 %}
8337 %}
8338
8339 // Integer Remainder with registers.
8340 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8341 match(Set dst (ModI src1 src2));
8342 ins_cost(10*DEFAULT_COST);
8343
8344 expand %{
8345 immI16 imm %{ (int)-1 %}
8346 flagsReg tmp1;
8347 iRegIdst tmp2;
8348 iRegIdst tmp3;
8349 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8350 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8351 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8352 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8353 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8354 %}
8355 %}
8356
8357 // Long Remainder with registers
8358 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8359 match(Set dst (ModL src1 src2));
8360 ins_cost(10*DEFAULT_COST);
8361
8362 expand %{
8363 immL16 imm %{ (int)-1 %}
8364 flagsReg tmp1;
8365 iRegLdst tmp2;
8366 iRegLdst tmp3;
8367 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8368 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8369 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8370 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8371 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8372 %}
8373 %}
8374
8375 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8376 match(Set dst (UDivI src1 src2));
8377 format %{ "DIVWU $dst, $src1, $src2" %}
8378 size(4);
8379 ins_encode %{
8380 __ divwu($dst$$Register, $src1$$Register, $src2$$Register);
8381 %}
8382 ins_pipe(pipe_class_default);
8383 %}
8384
8385 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8386 match(Set dst (UModI src1 src2));
8387 expand %{
8388 iRegIdst tmp1;
8389 iRegIdst tmp2;
8390 udivI_reg_reg(tmp1, src1, src2);
8391 // Compute lower 32 bit result using signed instructions as suggested by ISA.
8392 // Upper 32 bit will contain garbage.
8393 mulI_reg_reg(tmp2, src2, tmp1);
8394 subI_reg_reg(dst, src1, tmp2);
8395 %}
8396 %}
8397
8398 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8399 match(Set dst (UDivL src1 src2));
8400 format %{ "DIVDU $dst, $src1, $src2" %}
8401 size(4);
8402 ins_encode %{
8403 __ divdu($dst$$Register, $src1$$Register, $src2$$Register);
8404 %}
8405 ins_pipe(pipe_class_default);
8406 %}
8407
8408 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8409 match(Set dst (UModL src1 src2));
8410 expand %{
8411 iRegLdst tmp1;
8412 iRegLdst tmp2;
8413 udivL_reg_reg(tmp1, src1, src2);
8414 mulL_reg_reg(tmp2, src2, tmp1);
8415 subL_reg_reg(dst, src1, tmp2);
8416 %}
8417 %}
8418
8419 // Integer Shift Instructions
8420
8421 // Register Shift Left
8422
8423 // Clear all but the lowest #mask bits.
8424 // Used to normalize shift amounts in registers.
8425 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
8426 // no match-rule, false predicate
8427 effect(DEF dst, USE src, USE mask);
8428 predicate(false);
8429
8430 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %}
8431 size(4);
8432 ins_encode %{
8433 __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
8434 %}
8435 ins_pipe(pipe_class_default);
8436 %}
8437
8438 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8439 // no match-rule, false predicate
8440 effect(DEF dst, USE src1, USE src2);
8441 predicate(false);
8442
8443 format %{ "SLW $dst, $src1, $src2" %}
8444 size(4);
8445 ins_encode %{
8446 __ slw($dst$$Register, $src1$$Register, $src2$$Register);
8447 %}
8448 ins_pipe(pipe_class_default);
8449 %}
8450
8451 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8452 match(Set dst (LShiftI src1 src2));
8453 ins_cost(DEFAULT_COST*2);
8454 expand %{
8455 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8456 iRegIdst tmpI;
8457 maskI_reg_imm(tmpI, src2, mask);
8458 lShiftI_reg_reg(dst, src1, tmpI);
8459 %}
8460 %}
8461
8462 // Register Shift Left Immediate
8463 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8464 match(Set dst (LShiftI src1 src2));
8465
8466 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %}
8467 size(4);
8468 ins_encode %{
8469 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8470 %}
8471 ins_pipe(pipe_class_default);
8472 %}
8473
8474 // AndI with negpow2-constant + LShiftI
8475 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8476 match(Set dst (LShiftI (AndI src1 src2) src3));
8477 predicate(UseRotateAndMaskInstructionsPPC64);
8478
8479 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %}
8480 size(4);
8481 ins_encode %{
8482 long src3 = $src3$$constant;
8483 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8484 if (maskbits >= 32) {
8485 __ li($dst$$Register, 0); // addi
8486 } else {
8487 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
8488 }
8489 %}
8490 ins_pipe(pipe_class_default);
8491 %}
8492
8493 // RShiftI + AndI with negpow2-constant + LShiftI
8494 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8495 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
8496 predicate(UseRotateAndMaskInstructionsPPC64);
8497
8498 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
8499 size(4);
8500 ins_encode %{
8501 long src3 = $src3$$constant;
8502 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8503 if (maskbits >= 32) {
8504 __ li($dst$$Register, 0); // addi
8505 } else {
8506 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
8507 }
8508 %}
8509 ins_pipe(pipe_class_default);
8510 %}
8511
8512 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8513 // no match-rule, false predicate
8514 effect(DEF dst, USE src1, USE src2);
8515 predicate(false);
8516
8517 format %{ "SLD $dst, $src1, $src2" %}
8518 size(4);
8519 ins_encode %{
8520 __ sld($dst$$Register, $src1$$Register, $src2$$Register);
8521 %}
8522 ins_pipe(pipe_class_default);
8523 %}
8524
8525 // Register Shift Left
8526 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8527 match(Set dst (LShiftL src1 src2));
8528 ins_cost(DEFAULT_COST*2);
8529 expand %{
8530 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8531 iRegIdst tmpI;
8532 maskI_reg_imm(tmpI, src2, mask);
8533 lShiftL_regL_regI(dst, src1, tmpI);
8534 %}
8535 %}
8536
8537 // Register Shift Left Immediate
8538 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8539 match(Set dst (LShiftL src1 src2));
8540 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %}
8541 size(4);
8542 ins_encode %{
8543 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8544 %}
8545 ins_pipe(pipe_class_default);
8546 %}
8547
8548 // If we shift more than 32 bits, we need not convert I2L.
8549 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
8550 match(Set dst (LShiftL (ConvI2L src1) src2));
8551 ins_cost(DEFAULT_COST);
8552
8553 size(4);
8554 format %{ "SLDI $dst, i2l($src1), $src2" %}
8555 ins_encode %{
8556 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8557 %}
8558 ins_pipe(pipe_class_default);
8559 %}
8560
8561 // Shift a postivie int to the left.
8562 // Clrlsldi clears the upper 32 bits and shifts.
8563 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
8564 match(Set dst (LShiftL (ConvI2L src1) src2));
8565 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
8566
8567 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %}
8568 size(4);
8569 ins_encode %{
8570 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
8571 %}
8572 ins_pipe(pipe_class_default);
8573 %}
8574
8575 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8576 // no match-rule, false predicate
8577 effect(DEF dst, USE src1, USE src2);
8578 predicate(false);
8579
8580 format %{ "SRAW $dst, $src1, $src2" %}
8581 size(4);
8582 ins_encode %{
8583 __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
8584 %}
8585 ins_pipe(pipe_class_default);
8586 %}
8587
8588 // Register Arithmetic Shift Right
8589 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8590 match(Set dst (RShiftI src1 src2));
8591 ins_cost(DEFAULT_COST*2);
8592 expand %{
8593 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8594 iRegIdst tmpI;
8595 maskI_reg_imm(tmpI, src2, mask);
8596 arShiftI_reg_reg(dst, src1, tmpI);
8597 %}
8598 %}
8599
8600 // Register Arithmetic Shift Right Immediate
8601 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8602 match(Set dst (RShiftI src1 src2));
8603
8604 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %}
8605 size(4);
8606 ins_encode %{
8607 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8608 %}
8609 ins_pipe(pipe_class_default);
8610 %}
8611
8612 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8613 // no match-rule, false predicate
8614 effect(DEF dst, USE src1, USE src2);
8615 predicate(false);
8616
8617 format %{ "SRAD $dst, $src1, $src2" %}
8618 size(4);
8619 ins_encode %{
8620 __ srad($dst$$Register, $src1$$Register, $src2$$Register);
8621 %}
8622 ins_pipe(pipe_class_default);
8623 %}
8624
8625 // Register Shift Right Arithmetic Long
8626 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8627 match(Set dst (RShiftL src1 src2));
8628 ins_cost(DEFAULT_COST*2);
8629
8630 expand %{
8631 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8632 iRegIdst tmpI;
8633 maskI_reg_imm(tmpI, src2, mask);
8634 arShiftL_regL_regI(dst, src1, tmpI);
8635 %}
8636 %}
8637
8638 // Register Shift Right Immediate
8639 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8640 match(Set dst (RShiftL src1 src2));
8641
8642 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %}
8643 size(4);
8644 ins_encode %{
8645 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8646 %}
8647 ins_pipe(pipe_class_default);
8648 %}
8649
8650 // RShiftL + ConvL2I
8651 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8652 match(Set dst (ConvL2I (RShiftL src1 src2)));
8653
8654 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8655 size(4);
8656 ins_encode %{
8657 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8658 %}
8659 ins_pipe(pipe_class_default);
8660 %}
8661
8662 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8663 // no match-rule, false predicate
8664 effect(DEF dst, USE src1, USE src2);
8665 predicate(false);
8666
8667 format %{ "SRW $dst, $src1, $src2" %}
8668 size(4);
8669 ins_encode %{
8670 __ srw($dst$$Register, $src1$$Register, $src2$$Register);
8671 %}
8672 ins_pipe(pipe_class_default);
8673 %}
8674
8675 // Register Shift Right
8676 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8677 match(Set dst (URShiftI src1 src2));
8678 ins_cost(DEFAULT_COST*2);
8679
8680 expand %{
8681 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8682 iRegIdst tmpI;
8683 maskI_reg_imm(tmpI, src2, mask);
8684 urShiftI_reg_reg(dst, src1, tmpI);
8685 %}
8686 %}
8687
8688 // Register Shift Right Immediate
8689 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8690 match(Set dst (URShiftI src1 src2));
8691
8692 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %}
8693 size(4);
8694 ins_encode %{
8695 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8696 %}
8697 ins_pipe(pipe_class_default);
8698 %}
8699
8700 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8701 // no match-rule, false predicate
8702 effect(DEF dst, USE src1, USE src2);
8703 predicate(false);
8704
8705 format %{ "SRD $dst, $src1, $src2" %}
8706 size(4);
8707 ins_encode %{
8708 __ srd($dst$$Register, $src1$$Register, $src2$$Register);
8709 %}
8710 ins_pipe(pipe_class_default);
8711 %}
8712
8713 // Register Shift Right
8714 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8715 match(Set dst (URShiftL src1 src2));
8716 ins_cost(DEFAULT_COST*2);
8717
8718 expand %{
8719 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8720 iRegIdst tmpI;
8721 maskI_reg_imm(tmpI, src2, mask);
8722 urShiftL_regL_regI(dst, src1, tmpI);
8723 %}
8724 %}
8725
8726 // Register Shift Right Immediate
8727 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8728 match(Set dst (URShiftL src1 src2));
8729
8730 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %}
8731 size(4);
8732 ins_encode %{
8733 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8734 %}
8735 ins_pipe(pipe_class_default);
8736 %}
8737
8738 // URShiftL + ConvL2I.
8739 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8740 match(Set dst (ConvL2I (URShiftL src1 src2)));
8741
8742 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8743 size(4);
8744 ins_encode %{
8745 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8746 %}
8747 ins_pipe(pipe_class_default);
8748 %}
8749
8750 // Register Shift Right Immediate with a CastP2X
8751 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
8752 match(Set dst (URShiftL (CastP2X src1) src2));
8753
8754 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
8755 size(4);
8756 ins_encode %{
8757 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8758 %}
8759 ins_pipe(pipe_class_default);
8760 %}
8761
8762 // Bitfield Extract: URShiftI + AndI
8763 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
8764 match(Set dst (AndI (URShiftI src1 src2) src3));
8765
8766 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
8767 size(4);
8768 ins_encode %{
8769 int rshift = ($src2$$constant) & 0x1f;
8770 int length = log2i_exact((juint)$src3$$constant + 1u);
8771 if (rshift + length > 32) {
8772 // if necessary, adjust mask to omit rotated bits.
8773 length = 32 - rshift;
8774 }
8775 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8776 %}
8777 ins_pipe(pipe_class_default);
8778 %}
8779
8780 // Bitfield Extract: URShiftL + AndL
8781 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
8782 match(Set dst (AndL (URShiftL src1 src2) src3));
8783
8784 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
8785 size(4);
8786 ins_encode %{
8787 int rshift = ($src2$$constant) & 0x3f;
8788 int length = log2i_exact((julong)$src3$$constant + 1ull);
8789 if (rshift + length > 64) {
8790 // if necessary, adjust mask to omit rotated bits.
8791 length = 64 - rshift;
8792 }
8793 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8794 %}
8795 ins_pipe(pipe_class_default);
8796 %}
8797
8798 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
8799 match(Set dst (ConvL2I (ConvI2L src)));
8800
8801 format %{ "EXTSW $dst, $src \t// int->int" %}
8802 size(4);
8803 ins_encode %{
8804 __ extsw($dst$$Register, $src$$Register);
8805 %}
8806 ins_pipe(pipe_class_default);
8807 %}
8808
8809 //----------Rotate Instructions------------------------------------------------
8810
8811 // Rotate Left by 8-bit immediate
8812 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
8813 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
8814 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8815
8816 format %{ "ROTLWI $dst, $src, $lshift" %}
8817 size(4);
8818 ins_encode %{
8819 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
8820 %}
8821 ins_pipe(pipe_class_default);
8822 %}
8823
8824 // Rotate Right by 8-bit immediate
8825 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
8826 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
8827 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8828
8829 format %{ "ROTRWI $dst, $rshift" %}
8830 size(4);
8831 ins_encode %{
8832 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
8833 %}
8834 ins_pipe(pipe_class_default);
8835 %}
8836
8837 //----------Floating Point Arithmetic Instructions-----------------------------
8838
8839 // Add float single precision
8840 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
8841 match(Set dst (AddF src1 src2));
8842
8843 format %{ "FADDS $dst, $src1, $src2" %}
8844 size(4);
8845 ins_encode %{
8846 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8847 %}
8848 ins_pipe(pipe_class_default);
8849 %}
8850
8851 // Add float double precision
8852 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
8853 match(Set dst (AddD src1 src2));
8854
8855 format %{ "FADD $dst, $src1, $src2" %}
8856 size(4);
8857 ins_encode %{
8858 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8859 %}
8860 ins_pipe(pipe_class_default);
8861 %}
8862
8863 // Sub float single precision
8864 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
8865 match(Set dst (SubF src1 src2));
8866
8867 format %{ "FSUBS $dst, $src1, $src2" %}
8868 size(4);
8869 ins_encode %{
8870 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8871 %}
8872 ins_pipe(pipe_class_default);
8873 %}
8874
8875 // Sub float double precision
8876 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
8877 match(Set dst (SubD src1 src2));
8878 format %{ "FSUB $dst, $src1, $src2" %}
8879 size(4);
8880 ins_encode %{
8881 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8882 %}
8883 ins_pipe(pipe_class_default);
8884 %}
8885
8886 // Mul float single precision
8887 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
8888 match(Set dst (MulF src1 src2));
8889 format %{ "FMULS $dst, $src1, $src2" %}
8890 size(4);
8891 ins_encode %{
8892 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8893 %}
8894 ins_pipe(pipe_class_default);
8895 %}
8896
8897 // Mul float double precision
8898 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
8899 match(Set dst (MulD src1 src2));
8900 format %{ "FMUL $dst, $src1, $src2" %}
8901 size(4);
8902 ins_encode %{
8903 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8904 %}
8905 ins_pipe(pipe_class_default);
8906 %}
8907
8908 // Div float single precision
8909 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
8910 match(Set dst (DivF src1 src2));
8911 format %{ "FDIVS $dst, $src1, $src2" %}
8912 size(4);
8913 ins_encode %{
8914 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8915 %}
8916 ins_pipe(pipe_class_default);
8917 %}
8918
8919 // Div float double precision
8920 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
8921 match(Set dst (DivD src1 src2));
8922 format %{ "FDIV $dst, $src1, $src2" %}
8923 size(4);
8924 ins_encode %{
8925 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8926 %}
8927 ins_pipe(pipe_class_default);
8928 %}
8929
8930 // Absolute float single precision
8931 instruct absF_reg(regF dst, regF src) %{
8932 match(Set dst (AbsF src));
8933 format %{ "FABS $dst, $src \t// float" %}
8934 size(4);
8935 ins_encode %{
8936 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8937 %}
8938 ins_pipe(pipe_class_default);
8939 %}
8940
8941 // Absolute float double precision
8942 instruct absD_reg(regD dst, regD src) %{
8943 match(Set dst (AbsD src));
8944 format %{ "FABS $dst, $src \t// double" %}
8945 size(4);
8946 ins_encode %{
8947 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8948 %}
8949 ins_pipe(pipe_class_default);
8950 %}
8951
8952 instruct negF_reg(regF dst, regF src) %{
8953 match(Set dst (NegF src));
8954 format %{ "FNEG $dst, $src \t// float" %}
8955 size(4);
8956 ins_encode %{
8957 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8958 %}
8959 ins_pipe(pipe_class_default);
8960 %}
8961
8962 instruct negD_reg(regD dst, regD src) %{
8963 match(Set dst (NegD src));
8964 format %{ "FNEG $dst, $src \t// double" %}
8965 size(4);
8966 ins_encode %{
8967 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8968 %}
8969 ins_pipe(pipe_class_default);
8970 %}
8971
8972 // AbsF + NegF.
8973 instruct negF_absF_reg(regF dst, regF src) %{
8974 match(Set dst (NegF (AbsF src)));
8975 format %{ "FNABS $dst, $src \t// float" %}
8976 size(4);
8977 ins_encode %{
8978 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
8979 %}
8980 ins_pipe(pipe_class_default);
8981 %}
8982
8983 // AbsD + NegD.
8984 instruct negD_absD_reg(regD dst, regD src) %{
8985 match(Set dst (NegD (AbsD src)));
8986 format %{ "FNABS $dst, $src \t// double" %}
8987 size(4);
8988 ins_encode %{
8989 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
8990 %}
8991 ins_pipe(pipe_class_default);
8992 %}
8993
8994 // Sqrt float double precision
8995 instruct sqrtD_reg(regD dst, regD src) %{
8996 match(Set dst (SqrtD src));
8997 format %{ "FSQRT $dst, $src" %}
8998 size(4);
8999 ins_encode %{
9000 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
9001 %}
9002 ins_pipe(pipe_class_default);
9003 %}
9004
9005 // Single-precision sqrt.
9006 instruct sqrtF_reg(regF dst, regF src) %{
9007 match(Set dst (SqrtF src));
9008 ins_cost(DEFAULT_COST);
9009
9010 format %{ "FSQRTS $dst, $src" %}
9011 size(4);
9012 ins_encode %{
9013 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
9014 %}
9015 ins_pipe(pipe_class_default);
9016 %}
9017
9018
9019 // Multiply-Accumulate
9020 // src1 * src2 + src3
9021 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9022 match(Set dst (FmaF src3 (Binary src1 src2)));
9023
9024 format %{ "FMADDS $dst, $src1, $src2, $src3" %}
9025 size(4);
9026 ins_encode %{
9027 assert(UseFMA, "Needs FMA instructions support.");
9028 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9029 %}
9030 ins_pipe(pipe_class_default);
9031 %}
9032
9033 // src1 * src2 + src3
9034 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9035 match(Set dst (FmaD src3 (Binary src1 src2)));
9036
9037 format %{ "FMADD $dst, $src1, $src2, $src3" %}
9038 size(4);
9039 ins_encode %{
9040 assert(UseFMA, "Needs FMA instructions support.");
9041 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9042 %}
9043 ins_pipe(pipe_class_default);
9044 %}
9045
9046 // src1 * (-src2) + src3 = -(src1*src2-src3)
9047 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9048 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9049 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
9050
9051 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
9052 size(4);
9053 ins_encode %{
9054 assert(UseFMA, "Needs FMA instructions support.");
9055 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9056 %}
9057 ins_pipe(pipe_class_default);
9058 %}
9059
9060 // src1 * (-src2) + src3 = -(src1*src2-src3)
9061 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9062 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9063 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
9064
9065 format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
9066 size(4);
9067 ins_encode %{
9068 assert(UseFMA, "Needs FMA instructions support.");
9069 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9070 %}
9071 ins_pipe(pipe_class_default);
9072 %}
9073
9074 // src1 * (-src2) - src3 = -(src1*src2+src3)
9075 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9076 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9077 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
9078
9079 format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
9080 size(4);
9081 ins_encode %{
9082 assert(UseFMA, "Needs FMA instructions support.");
9083 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9084 %}
9085 ins_pipe(pipe_class_default);
9086 %}
9087
9088 // src1 * (-src2) - src3 = -(src1*src2+src3)
9089 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9090 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9091 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9092
9093 format %{ "FNMADD $dst, $src1, $src2, $src3" %}
9094 size(4);
9095 ins_encode %{
9096 assert(UseFMA, "Needs FMA instructions support.");
9097 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9098 %}
9099 ins_pipe(pipe_class_default);
9100 %}
9101
9102 // src1 * src2 - src3
9103 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9104 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9105
9106 format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
9107 size(4);
9108 ins_encode %{
9109 assert(UseFMA, "Needs FMA instructions support.");
9110 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9111 %}
9112 ins_pipe(pipe_class_default);
9113 %}
9114
9115 // src1 * src2 - src3
9116 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9117 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9118
9119 format %{ "FMSUB $dst, $src1, $src2, $src3" %}
9120 size(4);
9121 ins_encode %{
9122 assert(UseFMA, "Needs FMA instructions support.");
9123 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9124 %}
9125 ins_pipe(pipe_class_default);
9126 %}
9127
9128
9129 //----------Logical Instructions-----------------------------------------------
9130
9131 // And Instructions
9132
9133 // Register And
9134 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9135 match(Set dst (AndI src1 src2));
9136 format %{ "AND $dst, $src1, $src2" %}
9137 size(4);
9138 ins_encode %{
9139 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9140 %}
9141 ins_pipe(pipe_class_default);
9142 %}
9143
9144 // Left shifted Immediate And
9145 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{
9146 match(Set dst (AndI src1 src2));
9147 effect(KILL cr0);
9148 format %{ "ANDIS $dst, $src1, $src2.hi" %}
9149 size(4);
9150 ins_encode %{
9151 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16)));
9152 %}
9153 ins_pipe(pipe_class_default);
9154 %}
9155
9156 // Immediate And
9157 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{
9158 match(Set dst (AndI src1 src2));
9159 effect(KILL cr0);
9160
9161 format %{ "ANDI $dst, $src1, $src2" %}
9162 size(4);
9163 ins_encode %{
9164 // FIXME: avoid andi_ ?
9165 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9166 %}
9167 ins_pipe(pipe_class_default);
9168 %}
9169
9170 // Immediate And where the immediate is a negative power of 2.
9171 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{
9172 match(Set dst (AndI src1 src2));
9173 format %{ "ANDWI $dst, $src1, $src2" %}
9174 size(4);
9175 ins_encode %{
9176 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant));
9177 %}
9178 ins_pipe(pipe_class_default);
9179 %}
9180
9181 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{
9182 match(Set dst (AndI src1 src2));
9183 format %{ "ANDWI $dst, $src1, $src2" %}
9184 size(4);
9185 ins_encode %{
9186 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u));
9187 %}
9188 ins_pipe(pipe_class_default);
9189 %}
9190
9191 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{
9192 match(Set dst (AndI src1 src2));
9193 predicate(UseRotateAndMaskInstructionsPPC64);
9194 format %{ "ANDWI $dst, $src1, $src2" %}
9195 size(4);
9196 ins_encode %{
9197 int bitpos = 31 - log2i_exact((juint)$src2$$constant);
9198 __ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos);
9199 %}
9200 ins_pipe(pipe_class_default);
9201 %}
9202
9203 // Register And Long
9204 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9205 match(Set dst (AndL src1 src2));
9206 ins_cost(DEFAULT_COST);
9207
9208 format %{ "AND $dst, $src1, $src2 \t// long" %}
9209 size(4);
9210 ins_encode %{
9211 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9212 %}
9213 ins_pipe(pipe_class_default);
9214 %}
9215
9216 // Immediate And long
9217 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
9218 match(Set dst (AndL src1 src2));
9219 effect(KILL cr0);
9220
9221 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9222 size(4);
9223 ins_encode %{
9224 // FIXME: avoid andi_ ?
9225 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9226 %}
9227 ins_pipe(pipe_class_default);
9228 %}
9229
9230 // Immediate And Long where the immediate is a negative power of 2.
9231 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
9232 match(Set dst (AndL src1 src2));
9233 format %{ "ANDDI $dst, $src1, $src2" %}
9234 size(4);
9235 ins_encode %{
9236 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant));
9237 %}
9238 ins_pipe(pipe_class_default);
9239 %}
9240
9241 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9242 match(Set dst (AndL src1 src2));
9243 format %{ "ANDDI $dst, $src1, $src2" %}
9244 size(4);
9245 ins_encode %{
9246 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9247 %}
9248 ins_pipe(pipe_class_default);
9249 %}
9250
9251 // AndL + ConvL2I.
9252 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9253 match(Set dst (ConvL2I (AndL src1 src2)));
9254 ins_cost(DEFAULT_COST);
9255
9256 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %}
9257 size(4);
9258 ins_encode %{
9259 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9260 %}
9261 ins_pipe(pipe_class_default);
9262 %}
9263
9264 // Or Instructions
9265
9266 // Register Or
9267 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9268 match(Set dst (OrI src1 src2));
9269 format %{ "OR $dst, $src1, $src2" %}
9270 size(4);
9271 ins_encode %{
9272 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9273 %}
9274 ins_pipe(pipe_class_default);
9275 %}
9276
9277 // Expand does not work with above instruct. (??)
9278 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9279 // no match-rule
9280 effect(DEF dst, USE src1, USE src2);
9281 format %{ "OR $dst, $src1, $src2" %}
9282 size(4);
9283 ins_encode %{
9284 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9285 %}
9286 ins_pipe(pipe_class_default);
9287 %}
9288
9289 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9290 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9291 ins_cost(DEFAULT_COST*3);
9292
9293 expand %{
9294 // FIXME: we should do this in the ideal world.
9295 iRegIdst tmp1;
9296 iRegIdst tmp2;
9297 orI_reg_reg(tmp1, src1, src2);
9298 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9299 orI_reg_reg(dst, tmp1, tmp2);
9300 %}
9301 %}
9302
9303 // Immediate Or
9304 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9305 match(Set dst (OrI src1 src2));
9306 format %{ "ORI $dst, $src1, $src2" %}
9307 size(4);
9308 ins_encode %{
9309 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9310 %}
9311 ins_pipe(pipe_class_default);
9312 %}
9313
9314 // Register Or Long
9315 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9316 match(Set dst (OrL src1 src2));
9317 ins_cost(DEFAULT_COST);
9318
9319 size(4);
9320 format %{ "OR $dst, $src1, $src2 \t// long" %}
9321 ins_encode %{
9322 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9323 %}
9324 ins_pipe(pipe_class_default);
9325 %}
9326
9327 // OrL + ConvL2I.
9328 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9329 match(Set dst (ConvL2I (OrL src1 src2)));
9330 ins_cost(DEFAULT_COST);
9331
9332 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %}
9333 size(4);
9334 ins_encode %{
9335 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9336 %}
9337 ins_pipe(pipe_class_default);
9338 %}
9339
9340 // Immediate Or long
9341 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9342 match(Set dst (OrL src1 con));
9343 ins_cost(DEFAULT_COST);
9344
9345 format %{ "ORI $dst, $src1, $con \t// long" %}
9346 size(4);
9347 ins_encode %{
9348 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9349 %}
9350 ins_pipe(pipe_class_default);
9351 %}
9352
9353 // Xor Instructions
9354
9355 // Register Xor
9356 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9357 match(Set dst (XorI src1 src2));
9358 format %{ "XOR $dst, $src1, $src2" %}
9359 size(4);
9360 ins_encode %{
9361 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9362 %}
9363 ins_pipe(pipe_class_default);
9364 %}
9365
9366 // Expand does not work with above instruct. (??)
9367 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9368 // no match-rule
9369 effect(DEF dst, USE src1, USE src2);
9370 format %{ "XOR $dst, $src1, $src2" %}
9371 size(4);
9372 ins_encode %{
9373 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9374 %}
9375 ins_pipe(pipe_class_default);
9376 %}
9377
9378 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9379 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
9380 ins_cost(DEFAULT_COST*3);
9381
9382 expand %{
9383 // FIXME: we should do this in the ideal world.
9384 iRegIdst tmp1;
9385 iRegIdst tmp2;
9386 xorI_reg_reg(tmp1, src1, src2);
9387 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
9388 xorI_reg_reg(dst, tmp1, tmp2);
9389 %}
9390 %}
9391
9392 // Immediate Xor
9393 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9394 match(Set dst (XorI src1 src2));
9395 format %{ "XORI $dst, $src1, $src2" %}
9396 size(4);
9397 ins_encode %{
9398 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9399 %}
9400 ins_pipe(pipe_class_default);
9401 %}
9402
9403 // Register Xor Long
9404 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9405 match(Set dst (XorL src1 src2));
9406 ins_cost(DEFAULT_COST);
9407
9408 format %{ "XOR $dst, $src1, $src2 \t// long" %}
9409 size(4);
9410 ins_encode %{
9411 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9412 %}
9413 ins_pipe(pipe_class_default);
9414 %}
9415
9416 // XorL + ConvL2I.
9417 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9418 match(Set dst (ConvL2I (XorL src1 src2)));
9419 ins_cost(DEFAULT_COST);
9420
9421 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %}
9422 size(4);
9423 ins_encode %{
9424 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9425 %}
9426 ins_pipe(pipe_class_default);
9427 %}
9428
9429 // Immediate Xor Long
9430 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
9431 match(Set dst (XorL src1 src2));
9432 ins_cost(DEFAULT_COST);
9433
9434 format %{ "XORI $dst, $src1, $src2 \t// long" %}
9435 size(4);
9436 ins_encode %{
9437 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9438 %}
9439 ins_pipe(pipe_class_default);
9440 %}
9441
9442 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
9443 match(Set dst (XorI src1 src2));
9444 ins_cost(DEFAULT_COST);
9445
9446 format %{ "NOT $dst, $src1 ($src2)" %}
9447 size(4);
9448 ins_encode %{
9449 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9450 %}
9451 ins_pipe(pipe_class_default);
9452 %}
9453
9454 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
9455 match(Set dst (XorL src1 src2));
9456 ins_cost(DEFAULT_COST);
9457
9458 format %{ "NOT $dst, $src1 ($src2) \t// long" %}
9459 size(4);
9460 ins_encode %{
9461 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9462 %}
9463 ins_pipe(pipe_class_default);
9464 %}
9465
9466 // And-complement
9467 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
9468 match(Set dst (AndI (XorI src1 src2) src3));
9469 ins_cost(DEFAULT_COST);
9470
9471 format %{ "ANDW $dst, xori($src1, $src2), $src3" %}
9472 size(4);
9473 ins_encode( enc_andc(dst, src3, src1) );
9474 ins_pipe(pipe_class_default);
9475 %}
9476
9477 // And-complement
9478 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9479 // no match-rule, false predicate
9480 effect(DEF dst, USE src1, USE src2);
9481 predicate(false);
9482
9483 format %{ "ANDC $dst, $src1, $src2" %}
9484 size(4);
9485 ins_encode %{
9486 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
9487 %}
9488 ins_pipe(pipe_class_default);
9489 %}
9490
9491 //----------Moves between int/long and float/double----------------------------
9492 //
9493 // The following rules move values from int/long registers/stack-locations
9494 // to float/double registers/stack-locations and vice versa, without doing any
9495 // conversions. These rules are used to implement the bit-conversion methods
9496 // of java.lang.Float etc., e.g.
9497 // int floatToIntBits(float value)
9498 // float intBitsToFloat(int bits)
9499
9500 instruct moveL2D_reg(regD dst, iRegLsrc src) %{
9501 match(Set dst (MoveL2D src));
9502
9503 format %{ "MTFPRD $dst, $src" %}
9504 size(4);
9505 ins_encode %{
9506 __ mtfprd($dst$$FloatRegister, $src$$Register);
9507 %}
9508 ins_pipe(pipe_class_default);
9509 %}
9510
9511 instruct moveI2D_reg(regD dst, iRegIsrc src) %{
9512 // no match-rule, false predicate
9513 effect(DEF dst, USE src);
9514 predicate(false);
9515
9516 format %{ "MTFPRWA $dst, $src" %}
9517 size(4);
9518 ins_encode %{
9519 __ mtfprwa($dst$$FloatRegister, $src$$Register);
9520 %}
9521 ins_pipe(pipe_class_default);
9522 %}
9523
9524 //---------- Chain stack slots between similar types --------
9525
9526 // These are needed so that the rules below can match.
9527
9528 // Load integer from stack slot
9529 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
9530 match(Set dst src);
9531 ins_cost(MEMORY_REF_COST);
9532
9533 format %{ "LWZ $dst, $src" %}
9534 size(4);
9535 ins_encode( enc_lwz(dst, src) );
9536 ins_pipe(pipe_class_memory);
9537 %}
9538
9539 // Store integer to stack slot
9540 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
9541 match(Set dst src);
9542 ins_cost(MEMORY_REF_COST);
9543
9544 format %{ "STW $src, $dst \t// stk" %}
9545 size(4);
9546 ins_encode( enc_stw(src, dst) ); // rs=rt
9547 ins_pipe(pipe_class_memory);
9548 %}
9549
9550 // Load long from stack slot
9551 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
9552 match(Set dst src);
9553 ins_cost(MEMORY_REF_COST);
9554
9555 format %{ "LD $dst, $src \t// long" %}
9556 size(4);
9557 ins_encode( enc_ld(dst, src) );
9558 ins_pipe(pipe_class_memory);
9559 %}
9560
9561 // Store long to stack slot
9562 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
9563 match(Set dst src);
9564 ins_cost(MEMORY_REF_COST);
9565
9566 format %{ "STD $src, $dst \t// long" %}
9567 size(4);
9568 ins_encode( enc_std(src, dst) ); // rs=rt
9569 ins_pipe(pipe_class_memory);
9570 %}
9571
9572 //----------Moves between int and float
9573
9574 // Move float value from float stack-location to integer register.
9575 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
9576 match(Set dst (MoveF2I src));
9577 ins_cost(MEMORY_REF_COST);
9578
9579 format %{ "LWZ $dst, $src \t// MoveF2I" %}
9580 size(4);
9581 ins_encode( enc_lwz(dst, src) );
9582 ins_pipe(pipe_class_memory);
9583 %}
9584
9585 // Move float value from float register to integer stack-location.
9586 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
9587 match(Set dst (MoveF2I src));
9588 ins_cost(MEMORY_REF_COST);
9589
9590 format %{ "STFS $src, $dst \t// MoveF2I" %}
9591 size(4);
9592 ins_encode( enc_stfs(src, dst) );
9593 ins_pipe(pipe_class_memory);
9594 %}
9595
9596 // Move integer value from integer stack-location to float register.
9597 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
9598 match(Set dst (MoveI2F src));
9599 ins_cost(MEMORY_REF_COST);
9600
9601 format %{ "LFS $dst, $src \t// MoveI2F" %}
9602 size(4);
9603 ins_encode %{
9604 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
9605 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
9606 %}
9607 ins_pipe(pipe_class_memory);
9608 %}
9609
9610 // Move integer value from integer register to float stack-location.
9611 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
9612 match(Set dst (MoveI2F src));
9613 ins_cost(MEMORY_REF_COST);
9614
9615 format %{ "STW $src, $dst \t// MoveI2F" %}
9616 size(4);
9617 ins_encode( enc_stw(src, dst) );
9618 ins_pipe(pipe_class_memory);
9619 %}
9620
9621
9622 //----------Moves between long and double
9623
9624 // Move double value from double stack-location to long register.
9625 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
9626 match(Set dst (MoveD2L src));
9627 ins_cost(MEMORY_REF_COST);
9628 size(4);
9629 format %{ "LD $dst, $src \t// MoveD2L" %}
9630 ins_encode( enc_ld(dst, src) );
9631 ins_pipe(pipe_class_memory);
9632 %}
9633
9634 // Move double value from double register to long stack-location.
9635 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
9636 match(Set dst (MoveD2L src));
9637 effect(DEF dst, USE src);
9638 ins_cost(MEMORY_REF_COST);
9639
9640 format %{ "STFD $src, $dst \t// MoveD2L" %}
9641 size(4);
9642 ins_encode( enc_stfd(src, dst) );
9643 ins_pipe(pipe_class_memory);
9644 %}
9645
9646
9647 //----------Register Move Instructions-----------------------------------------
9648
9649 // Replicate for Superword
9650
9651 instruct moveReg(iRegLdst dst, iRegIsrc src) %{
9652 predicate(false);
9653 effect(DEF dst, USE src);
9654
9655 format %{ "MR $dst, $src \t// replicate " %}
9656 // variable size, 0 or 4.
9657 ins_encode %{
9658 __ mr_if_needed($dst$$Register, $src$$Register);
9659 %}
9660 ins_pipe(pipe_class_default);
9661 %}
9662
9663 //----------Cast instructions (Java-level type cast)---------------------------
9664
9665 // Cast Long to Pointer for unsafe natives.
9666 instruct castX2P(iRegPdst dst, iRegLsrc src) %{
9667 match(Set dst (CastX2P src));
9668
9669 format %{ "MR $dst, $src \t// Long->Ptr" %}
9670 // variable size, 0 or 4.
9671 ins_encode %{
9672 __ mr_if_needed($dst$$Register, $src$$Register);
9673 %}
9674 ins_pipe(pipe_class_default);
9675 %}
9676
9677 // Cast Pointer to Long for unsafe natives.
9678 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
9679 match(Set dst (CastP2X src));
9680
9681 format %{ "MR $dst, $src \t// Ptr->Long" %}
9682 // variable size, 0 or 4.
9683 ins_encode %{
9684 __ mr_if_needed($dst$$Register, $src$$Register);
9685 %}
9686 ins_pipe(pipe_class_default);
9687 %}
9688
9689 instruct castPP(iRegPdst dst) %{
9690 match(Set dst (CastPP dst));
9691 format %{ " -- \t// castPP of $dst" %}
9692 size(0);
9693 ins_encode( /*empty*/ );
9694 ins_pipe(pipe_class_default);
9695 %}
9696
9697 instruct castII(iRegIdst dst) %{
9698 match(Set dst (CastII dst));
9699 format %{ " -- \t// castII of $dst" %}
9700 size(0);
9701 ins_encode( /*empty*/ );
9702 ins_pipe(pipe_class_default);
9703 %}
9704
9705 instruct castLL(iRegLdst dst) %{
9706 match(Set dst (CastLL dst));
9707 format %{ " -- \t// castLL of $dst" %}
9708 size(0);
9709 ins_encode( /*empty*/ );
9710 ins_pipe(pipe_class_default);
9711 %}
9712
9713 instruct castFF(regF dst) %{
9714 match(Set dst (CastFF dst));
9715 format %{ " -- \t// castFF of $dst" %}
9716 size(0);
9717 ins_encode( /*empty*/ );
9718 ins_pipe(pipe_class_default);
9719 %}
9720
9721 instruct castDD(regD dst) %{
9722 match(Set dst (CastDD dst));
9723 format %{ " -- \t// castDD of $dst" %}
9724 size(0);
9725 ins_encode( /*empty*/ );
9726 ins_pipe(pipe_class_default);
9727 %}
9728
9729 instruct castVV8(iRegLdst dst) %{
9730 match(Set dst (CastVV dst));
9731 format %{ " -- \t// castVV of $dst" %}
9732 size(0);
9733 ins_encode( /*empty*/ );
9734 ins_pipe(pipe_class_default);
9735 %}
9736
9737 instruct castVV16(vecX dst) %{
9738 match(Set dst (CastVV dst));
9739 format %{ " -- \t// castVV of $dst" %}
9740 size(0);
9741 ins_encode( /*empty*/ );
9742 ins_pipe(pipe_class_default);
9743 %}
9744
9745 instruct checkCastPP(iRegPdst dst) %{
9746 match(Set dst (CheckCastPP dst));
9747 format %{ " -- \t// checkcastPP of $dst" %}
9748 size(0);
9749 ins_encode( /*empty*/ );
9750 ins_pipe(pipe_class_default);
9751 %}
9752
9753 //----------Convert instructions-----------------------------------------------
9754
9755 // Convert to boolean.
9756
9757 // int_to_bool(src) : { 1 if src != 0
9758 // { 0 else
9759 //
9760 // strategy:
9761 // 1) Count leading zeros of 32 bit-value src,
9762 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
9763 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9764 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9765
9766 // convI2Bool
9767 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
9768 match(Set dst (Conv2B src));
9769 predicate(UseCountLeadingZerosInstructionsPPC64);
9770 ins_cost(DEFAULT_COST);
9771
9772 expand %{
9773 immI shiftAmount %{ 0x5 %}
9774 uimmI16 mask %{ 0x1 %}
9775 iRegIdst tmp1;
9776 iRegIdst tmp2;
9777 countLeadingZerosI(tmp1, src);
9778 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9779 xorI_reg_uimm16(dst, tmp2, mask);
9780 %}
9781 %}
9782
9783 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
9784 match(Set dst (Conv2B src));
9785 effect(TEMP crx);
9786 predicate(!UseCountLeadingZerosInstructionsPPC64);
9787 ins_cost(DEFAULT_COST);
9788
9789 format %{ "CMPWI $crx, $src, #0 \t// convI2B"
9790 "LI $dst, #0\n\t"
9791 "BEQ $crx, done\n\t"
9792 "LI $dst, #1\n"
9793 "done:" %}
9794 size(16);
9795 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
9796 ins_pipe(pipe_class_compare);
9797 %}
9798
9799 // ConvI2B + XorI
9800 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
9801 match(Set dst (XorI (Conv2B src) mask));
9802 predicate(UseCountLeadingZerosInstructionsPPC64);
9803 ins_cost(DEFAULT_COST);
9804
9805 expand %{
9806 immI shiftAmount %{ 0x5 %}
9807 iRegIdst tmp1;
9808 countLeadingZerosI(tmp1, src);
9809 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9810 %}
9811 %}
9812
9813 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
9814 match(Set dst (XorI (Conv2B src) mask));
9815 effect(TEMP crx);
9816 predicate(!UseCountLeadingZerosInstructionsPPC64);
9817 ins_cost(DEFAULT_COST);
9818
9819 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
9820 "LI $dst, #1\n\t"
9821 "BEQ $crx, done\n\t"
9822 "LI $dst, #0\n"
9823 "done:" %}
9824 size(16);
9825 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
9826 ins_pipe(pipe_class_compare);
9827 %}
9828
9829 // AndI 0b0..010..0 + ConvI2B
9830 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
9831 match(Set dst (Conv2B (AndI src mask)));
9832 predicate(UseRotateAndMaskInstructionsPPC64);
9833 ins_cost(DEFAULT_COST);
9834
9835 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
9836 size(4);
9837 ins_encode %{
9838 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31);
9839 %}
9840 ins_pipe(pipe_class_default);
9841 %}
9842
9843 // Convert pointer to boolean.
9844 //
9845 // ptr_to_bool(src) : { 1 if src != 0
9846 // { 0 else
9847 //
9848 // strategy:
9849 // 1) Count leading zeros of 64 bit-value src,
9850 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
9851 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9852 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9853
9854 // ConvP2B
9855 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
9856 match(Set dst (Conv2B src));
9857 predicate(UseCountLeadingZerosInstructionsPPC64);
9858 ins_cost(DEFAULT_COST);
9859
9860 expand %{
9861 immI shiftAmount %{ 0x6 %}
9862 uimmI16 mask %{ 0x1 %}
9863 iRegIdst tmp1;
9864 iRegIdst tmp2;
9865 countLeadingZerosP(tmp1, src);
9866 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9867 xorI_reg_uimm16(dst, tmp2, mask);
9868 %}
9869 %}
9870
9871 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
9872 match(Set dst (Conv2B src));
9873 effect(TEMP crx);
9874 predicate(!UseCountLeadingZerosInstructionsPPC64);
9875 ins_cost(DEFAULT_COST);
9876
9877 format %{ "CMPDI $crx, $src, #0 \t// convP2B"
9878 "LI $dst, #0\n\t"
9879 "BEQ $crx, done\n\t"
9880 "LI $dst, #1\n"
9881 "done:" %}
9882 size(16);
9883 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
9884 ins_pipe(pipe_class_compare);
9885 %}
9886
9887 // ConvP2B + XorI
9888 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
9889 match(Set dst (XorI (Conv2B src) mask));
9890 predicate(UseCountLeadingZerosInstructionsPPC64);
9891 ins_cost(DEFAULT_COST);
9892
9893 expand %{
9894 immI shiftAmount %{ 0x6 %}
9895 iRegIdst tmp1;
9896 countLeadingZerosP(tmp1, src);
9897 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9898 %}
9899 %}
9900
9901 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
9902 match(Set dst (XorI (Conv2B src) mask));
9903 effect(TEMP crx);
9904 predicate(!UseCountLeadingZerosInstructionsPPC64);
9905 ins_cost(DEFAULT_COST);
9906
9907 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
9908 "LI $dst, #1\n\t"
9909 "BEQ $crx, done\n\t"
9910 "LI $dst, #0\n"
9911 "done:" %}
9912 size(16);
9913 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
9914 ins_pipe(pipe_class_compare);
9915 %}
9916
9917 // if src1 < src2, return -1 else return 0
9918 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9919 match(Set dst (CmpLTMask src1 src2));
9920 ins_cost(DEFAULT_COST*4);
9921
9922 expand %{
9923 iRegLdst src1s;
9924 iRegLdst src2s;
9925 iRegLdst diff;
9926 convI2L_reg(src1s, src1); // Ensure proper sign extension.
9927 convI2L_reg(src2s, src2); // Ensure proper sign extension.
9928 subL_reg_reg(diff, src1s, src2s);
9929 // Need to consider >=33 bit result, therefore we need signmaskL.
9930 signmask64I_regL(dst, diff);
9931 %}
9932 %}
9933
9934 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
9935 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
9936 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %}
9937 size(4);
9938 ins_encode %{
9939 __ srawi($dst$$Register, $src1$$Register, 0x1f);
9940 %}
9941 ins_pipe(pipe_class_default);
9942 %}
9943
9944 //----------Arithmetic Conversion Instructions---------------------------------
9945
9946 // Convert to Byte -- nop
9947 // Convert to Short -- nop
9948
9949 // Convert to Int
9950
9951 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
9952 match(Set dst (RShiftI (LShiftI src amount) amount));
9953 format %{ "EXTSB $dst, $src \t// byte->int" %}
9954 size(4);
9955 ins_encode %{
9956 __ extsb($dst$$Register, $src$$Register);
9957 %}
9958 ins_pipe(pipe_class_default);
9959 %}
9960
9961 instruct extsh(iRegIdst dst, iRegIsrc src) %{
9962 effect(DEF dst, USE src);
9963
9964 size(4);
9965 ins_encode %{
9966 __ extsh($dst$$Register, $src$$Register);
9967 %}
9968 ins_pipe(pipe_class_default);
9969 %}
9970
9971 // LShiftI 16 + RShiftI 16 converts short to int.
9972 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
9973 match(Set dst (RShiftI (LShiftI src amount) amount));
9974 format %{ "EXTSH $dst, $src \t// short->int" %}
9975 size(4);
9976 ins_encode %{
9977 __ extsh($dst$$Register, $src$$Register);
9978 %}
9979 ins_pipe(pipe_class_default);
9980 %}
9981
9982 // ConvL2I + ConvI2L: Sign extend int in long register.
9983 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
9984 match(Set dst (ConvI2L (ConvL2I src)));
9985
9986 format %{ "EXTSW $dst, $src \t// long->long" %}
9987 size(4);
9988 ins_encode %{
9989 __ extsw($dst$$Register, $src$$Register);
9990 %}
9991 ins_pipe(pipe_class_default);
9992 %}
9993
9994 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
9995 match(Set dst (ConvL2I src));
9996 format %{ "MR $dst, $src \t// long->int" %}
9997 // variable size, 0 or 4
9998 ins_encode %{
9999 __ mr_if_needed($dst$$Register, $src$$Register);
10000 %}
10001 ins_pipe(pipe_class_default);
10002 %}
10003
10004 instruct convD2IRaw_regD(regD dst, regD src) %{
10005 // no match-rule, false predicate
10006 effect(DEF dst, USE src);
10007 predicate(false);
10008
10009 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
10010 size(4);
10011 ins_encode %{
10012 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10013 %}
10014 ins_pipe(pipe_class_default);
10015 %}
10016
10017 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
10018 // no match-rule, false predicate
10019 effect(DEF dst, USE crx, USE src);
10020 predicate(false);
10021
10022 ins_variable_size_depending_on_alignment(true);
10023
10024 format %{ "CMOVI $crx, $dst, $src" %}
10025 size(8);
10026 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10027 ins_pipe(pipe_class_default);
10028 %}
10029
10030 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
10031 // no match-rule, false predicate
10032 effect(DEF dst, USE crx, USE src);
10033 predicate(false);
10034
10035 ins_variable_size_depending_on_alignment(true);
10036
10037 format %{ "CMOVI $crx, $dst, $src" %}
10038 size(8);
10039 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10040 ins_pipe(pipe_class_default);
10041 %}
10042
10043
10044 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{
10045 // no match-rule, false predicate
10046 effect(DEF dst, USE crx, USE src);
10047 predicate(false);
10048
10049 format %{ "CMOVI $dst, $crx, $src \t// postalloc expanded" %}
10050 postalloc_expand %{
10051 //
10052 // replaces
10053 //
10054 // region dst crx src
10055 // \ | | /
10056 // dst=cmovI_bso_reg_conLvalue0
10057 //
10058 // with
10059 //
10060 // region dst
10061 // \ /
10062 // dst=loadConI16(0)
10063 // |
10064 // ^ region dst crx src
10065 // | \ | | /
10066 // dst=cmovI_bso_reg
10067 //
10068
10069 // Create new nodes.
10070 MachNode *m1 = new loadConI16Node();
10071 MachNode *m2 = new cmovI_bso_regNode();
10072
10073 // inputs for new nodes
10074 m1->add_req(n_region);
10075 m2->add_req(n_region, n_crx, n_src);
10076
10077 // precedences for new nodes
10078 m2->add_prec(m1);
10079
10080 // operands for new nodes
10081 m1->_opnds[0] = op_dst;
10082 m1->_opnds[1] = new immI16Oper(0);
10083
10084 m2->_opnds[0] = op_dst;
10085 m2->_opnds[1] = op_crx;
10086 m2->_opnds[2] = op_src;
10087
10088 // registers for new nodes
10089 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10090 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10091
10092 // Insert new nodes.
10093 nodes->push(m1);
10094 nodes->push(m2);
10095 %}
10096 %}
10097
10098
10099 // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
10100 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
10101 match(Set dst (ConvD2I src));
10102 ins_cost(DEFAULT_COST);
10103
10104 expand %{
10105 regD tmpD;
10106 flagsReg crx;
10107 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10108 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
10109 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10110 %}
10111 %}
10112
10113 instruct convF2IRaw_regF(regF dst, regF src) %{
10114 // no match-rule, false predicate
10115 effect(DEF dst, USE src);
10116 predicate(false);
10117
10118 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
10119 size(4);
10120 ins_encode %{
10121 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10122 %}
10123 ins_pipe(pipe_class_default);
10124 %}
10125
10126
10127 // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
10128 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
10129 match(Set dst (ConvF2I src));
10130 ins_cost(DEFAULT_COST);
10131
10132 expand %{
10133 regF tmpF;
10134 flagsReg crx;
10135 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10136 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10137 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10138 %}
10139 %}
10140
10141 // Convert to Long
10142
10143 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
10144 match(Set dst (ConvI2L src));
10145 format %{ "EXTSW $dst, $src \t// int->long" %}
10146 size(4);
10147 ins_encode %{
10148 __ extsw($dst$$Register, $src$$Register);
10149 %}
10150 ins_pipe(pipe_class_default);
10151 %}
10152
10153 // Zero-extend: convert unsigned int to long (convUI2L).
10154 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
10155 match(Set dst (AndL (ConvI2L src) mask));
10156 ins_cost(DEFAULT_COST);
10157
10158 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10159 size(4);
10160 ins_encode %{
10161 __ clrldi($dst$$Register, $src$$Register, 32);
10162 %}
10163 ins_pipe(pipe_class_default);
10164 %}
10165
10166 // Zero-extend: convert unsigned int to long in long register.
10167 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
10168 match(Set dst (AndL src mask));
10169 ins_cost(DEFAULT_COST);
10170
10171 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10172 size(4);
10173 ins_encode %{
10174 __ clrldi($dst$$Register, $src$$Register, 32);
10175 %}
10176 ins_pipe(pipe_class_default);
10177 %}
10178
10179 instruct convF2LRaw_regF(regF dst, regF src) %{
10180 // no match-rule, false predicate
10181 effect(DEF dst, USE src);
10182 predicate(false);
10183
10184 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10185 size(4);
10186 ins_encode %{
10187 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10188 %}
10189 ins_pipe(pipe_class_default);
10190 %}
10191
10192 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
10193 // no match-rule, false predicate
10194 effect(DEF dst, USE crx, USE src);
10195 predicate(false);
10196
10197 ins_variable_size_depending_on_alignment(true);
10198
10199 format %{ "CMOVL $crx, $dst, $src" %}
10200 size(8);
10201 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10202 ins_pipe(pipe_class_default);
10203 %}
10204
10205 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
10206 // no match-rule, false predicate
10207 effect(DEF dst, USE crx, USE src);
10208 predicate(false);
10209
10210 ins_variable_size_depending_on_alignment(true);
10211
10212 format %{ "CMOVL $crx, $dst, $src" %}
10213 size(8);
10214 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10215 ins_pipe(pipe_class_default);
10216 %}
10217
10218
10219 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{
10220 // no match-rule, false predicate
10221 effect(DEF dst, USE crx, USE src);
10222 predicate(false);
10223
10224 format %{ "CMOVL $dst, $crx, $src \t// postalloc expanded" %}
10225 postalloc_expand %{
10226 //
10227 // replaces
10228 //
10229 // region dst crx src
10230 // \ | | /
10231 // dst=cmovL_bso_reg_conLvalue0
10232 //
10233 // with
10234 //
10235 // region dst
10236 // \ /
10237 // dst=loadConL16(0)
10238 // |
10239 // ^ region dst crx src
10240 // | \ | | /
10241 // dst=cmovL_bso_reg
10242 //
10243
10244 // Create new nodes.
10245 MachNode *m1 = new loadConL16Node();
10246 MachNode *m2 = new cmovL_bso_regNode();
10247
10248 // inputs for new nodes
10249 m1->add_req(n_region);
10250 m2->add_req(n_region, n_crx, n_src);
10251 m2->add_prec(m1);
10252
10253 // operands for new nodes
10254 m1->_opnds[0] = op_dst;
10255 m1->_opnds[1] = new immL16Oper(0);
10256 m2->_opnds[0] = op_dst;
10257 m2->_opnds[1] = op_crx;
10258 m2->_opnds[2] = op_src;
10259
10260 // registers for new nodes
10261 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10262 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10263
10264 // Insert new nodes.
10265 nodes->push(m1);
10266 nodes->push(m2);
10267 %}
10268 %}
10269
10270
10271 // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
10272 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
10273 match(Set dst (ConvF2L src));
10274 ins_cost(DEFAULT_COST);
10275
10276 expand %{
10277 regF tmpF;
10278 flagsReg crx;
10279 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10280 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
10281 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10282 %}
10283 %}
10284
10285 instruct convD2LRaw_regD(regD dst, regD src) %{
10286 // no match-rule, false predicate
10287 effect(DEF dst, USE src);
10288 predicate(false);
10289
10290 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
10291 size(4);
10292 ins_encode %{
10293 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10294 %}
10295 ins_pipe(pipe_class_default);
10296 %}
10297
10298
10299 // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
10300 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
10301 match(Set dst (ConvD2L src));
10302 ins_cost(DEFAULT_COST);
10303
10304 expand %{
10305 regD tmpD;
10306 flagsReg crx;
10307 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10308 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
10309 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10310 %}
10311 %}
10312
10313 // Convert to Float
10314
10315 // Placed here as needed in expand.
10316 instruct convL2DRaw_regD(regD dst, regD src) %{
10317 // no match-rule, false predicate
10318 effect(DEF dst, USE src);
10319 predicate(false);
10320
10321 format %{ "FCFID $dst, $src \t// convL2D" %}
10322 size(4);
10323 ins_encode %{
10324 __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
10325 %}
10326 ins_pipe(pipe_class_default);
10327 %}
10328
10329 // Placed here as needed in expand.
10330 instruct convD2F_reg(regF dst, regD src) %{
10331 match(Set dst (ConvD2F src));
10332 format %{ "FRSP $dst, $src \t// convD2F" %}
10333 size(4);
10334 ins_encode %{
10335 __ frsp($dst$$FloatRegister, $src$$FloatRegister);
10336 %}
10337 ins_pipe(pipe_class_default);
10338 %}
10339
10340 instruct convL2FRaw_regF(regF dst, regD src) %{
10341 // no match-rule, false predicate
10342 effect(DEF dst, USE src);
10343 predicate(false);
10344
10345 format %{ "FCFIDS $dst, $src \t// convL2F" %}
10346 size(4);
10347 ins_encode %{
10348 __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
10349 %}
10350 ins_pipe(pipe_class_default);
10351 %}
10352
10353
10354 // Integer to Float conversion. Special version for Power8.
10355 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
10356 match(Set dst (ConvI2F src));
10357 ins_cost(DEFAULT_COST);
10358
10359 expand %{
10360 regD tmpD;
10361 moveI2D_reg(tmpD, src);
10362 convL2FRaw_regF(dst, tmpD); // Convert to float.
10363 %}
10364 %}
10365
10366
10367 // L2F to avoid runtime call. Special version for Power8.
10368 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
10369 match(Set dst (ConvL2F src));
10370 ins_cost(DEFAULT_COST);
10371
10372 expand %{
10373 regD tmpD;
10374 moveL2D_reg(tmpD, src);
10375 convL2FRaw_regF(dst, tmpD); // Convert to float.
10376 %}
10377 %}
10378
10379 // Moved up as used in expand.
10380 //instruct convD2F_reg(regF dst, regD src) %{%}
10381
10382 // Convert to Double
10383
10384
10385 // Integer to Double conversion. Special version for Power8.
10386 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
10387 match(Set dst (ConvI2D src));
10388 ins_cost(DEFAULT_COST);
10389
10390 expand %{
10391 regD tmpD;
10392 moveI2D_reg(tmpD, src);
10393 convL2DRaw_regD(dst, tmpD); // Convert to double.
10394 %}
10395 %}
10396
10397
10398 // Long to Double conversion. Special version for Power8.
10399 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
10400 match(Set dst (ConvL2D src));
10401 ins_cost(DEFAULT_COST);
10402
10403 expand %{
10404 regD tmpD;
10405 moveL2D_reg(tmpD, src);
10406 convL2DRaw_regD(dst, tmpD); // Convert to double.
10407 %}
10408 %}
10409
10410 instruct convF2D_reg(regD dst, regF src) %{
10411 match(Set dst (ConvF2D src));
10412 format %{ "FMR $dst, $src \t// float->double" %}
10413 // variable size, 0 or 4
10414 ins_encode %{
10415 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
10416 %}
10417 ins_pipe(pipe_class_default);
10418 %}
10419
10420 instruct convF2HF_reg_reg(iRegIdst dst, regF src, regF tmp) %{
10421 match(Set dst (ConvF2HF src));
10422 effect(TEMP tmp);
10423 ins_cost(3 * DEFAULT_COST);
10424 size(12);
10425 format %{ "XSCVDPHP $tmp, $src\t# convert to half precision\n\t"
10426 "MFFPRD $dst, $tmp\t# move result from $tmp to $dst\n\t"
10427 "EXTSH $dst, $dst\t# make it a proper short"
10428 %}
10429 ins_encode %{
10430 __ f2hf($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
10431 %}
10432 ins_pipe(pipe_class_default);
10433 %}
10434
10435 instruct convHF2F_reg_reg(regF dst, iRegIsrc src) %{
10436 match(Set dst (ConvHF2F src));
10437 ins_cost(2 * DEFAULT_COST);
10438 size(8);
10439 format %{ "MTFPRD $dst, $src\t# move source from $src to $dst\n\t"
10440 "XSCVHPDP $dst, $dst\t# convert from half precision"
10441 %}
10442 ins_encode %{
10443 __ hf2f($dst$$FloatRegister, $src$$Register);
10444 %}
10445 ins_pipe(pipe_class_default);
10446 %}
10447
10448 //----------Control Flow Instructions------------------------------------------
10449 // Compare Instructions
10450
10451 // Compare Integers
10452 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10453 match(Set crx (CmpI src1 src2));
10454 size(4);
10455 format %{ "CMPW $crx, $src1, $src2" %}
10456 ins_encode %{
10457 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10458 %}
10459 ins_pipe(pipe_class_compare);
10460 %}
10461
10462 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
10463 match(Set crx (CmpI src1 src2));
10464 format %{ "CMPWI $crx, $src1, $src2" %}
10465 size(4);
10466 ins_encode %{
10467 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10468 %}
10469 ins_pipe(pipe_class_compare);
10470 %}
10471
10472 // (src1 & src2) == 0?
10473 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
10474 match(Set cr0 (CmpI (AndI src1 src2) zero));
10475 // r0 is killed
10476 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
10477 size(4);
10478 ins_encode %{
10479 __ andi_(R0, $src1$$Register, $src2$$constant);
10480 %}
10481 ins_pipe(pipe_class_compare);
10482 %}
10483
10484 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10485 match(Set crx (CmpL src1 src2));
10486 format %{ "CMPD $crx, $src1, $src2" %}
10487 size(4);
10488 ins_encode %{
10489 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
10490 %}
10491 ins_pipe(pipe_class_compare);
10492 %}
10493
10494 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
10495 match(Set crx (CmpL src1 src2));
10496 format %{ "CMPDI $crx, $src1, $src2" %}
10497 size(4);
10498 ins_encode %{
10499 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10500 %}
10501 ins_pipe(pipe_class_compare);
10502 %}
10503
10504 // Added CmpUL for LoopPredicate.
10505 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10506 match(Set crx (CmpUL src1 src2));
10507 format %{ "CMPLD $crx, $src1, $src2" %}
10508 size(4);
10509 ins_encode %{
10510 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10511 %}
10512 ins_pipe(pipe_class_compare);
10513 %}
10514
10515 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
10516 match(Set crx (CmpUL src1 src2));
10517 format %{ "CMPLDI $crx, $src1, $src2" %}
10518 size(4);
10519 ins_encode %{
10520 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10521 %}
10522 ins_pipe(pipe_class_compare);
10523 %}
10524
10525 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
10526 match(Set cr0 (CmpL (AndL src1 src2) zero));
10527 // r0 is killed
10528 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
10529 size(4);
10530 ins_encode %{
10531 __ and_(R0, $src1$$Register, $src2$$Register);
10532 %}
10533 ins_pipe(pipe_class_compare);
10534 %}
10535
10536 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
10537 match(Set cr0 (CmpL (AndL src1 src2) zero));
10538 // r0 is killed
10539 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
10540 size(4);
10541 ins_encode %{
10542 __ andi_(R0, $src1$$Register, $src2$$constant);
10543 %}
10544 ins_pipe(pipe_class_compare);
10545 %}
10546
10547 // Manifest a CmpL3 result in an integer register.
10548 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10549 match(Set dst (CmpL3 src1 src2));
10550 effect(KILL cr0);
10551 ins_cost(DEFAULT_COST * 5);
10552 size((VM_Version::has_brw() ? 16 : 20));
10553
10554 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %}
10555
10556 ins_encode %{
10557 __ cmpd(CR0, $src1$$Register, $src2$$Register);
10558 __ set_cmp3($dst$$Register);
10559 %}
10560 ins_pipe(pipe_class_default);
10561 %}
10562
10563 instruct cmpU3_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
10564 match(Set dst (CmpU3 src1 src2));
10565 effect(KILL cr0);
10566 ins_cost(DEFAULT_COST * 5);
10567 size((VM_Version::has_brw() ? 16 : 20));
10568
10569 format %{ "cmpU3_reg_reg $dst, $src1, $src2" %}
10570
10571 ins_encode %{
10572 __ cmplw(CR0, $src1$$Register, $src2$$Register);
10573 __ set_cmp3($dst$$Register);
10574 %}
10575 ins_pipe(pipe_class_default);
10576 %}
10577
10578 instruct cmpUL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10579 match(Set dst (CmpUL3 src1 src2));
10580 effect(KILL cr0);
10581 ins_cost(DEFAULT_COST * 5);
10582 size((VM_Version::has_brw() ? 16 : 20));
10583
10584 format %{ "cmpUL3_reg_reg $dst, $src1, $src2" %}
10585
10586 ins_encode %{
10587 __ cmpld(CR0, $src1$$Register, $src2$$Register);
10588 __ set_cmp3($dst$$Register);
10589 %}
10590 ins_pipe(pipe_class_default);
10591 %}
10592
10593 // Implicit range checks.
10594 // A range check in the ideal world has one of the following shapes:
10595 // - (If le (CmpU length index)), (IfTrue throw exception)
10596 // - (If lt (CmpU index length)), (IfFalse throw exception)
10597 //
10598 // Match range check 'If le (CmpU length index)'.
10599 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
10600 match(If cmp (CmpU src_length index));
10601 effect(USE labl);
10602 predicate(TrapBasedRangeChecks &&
10603 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
10604 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
10605 (Matcher::branches_to_uncommon_trap(_leaf)));
10606
10607 ins_is_TrapBasedCheckNode(true);
10608
10609 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %}
10610 size(4);
10611 ins_encode %{
10612 if ($cmp$$cmpcode == 0x1 /* less_equal */) {
10613 __ trap_range_check_le($src_length$$Register, $index$$constant);
10614 } else {
10615 // Both successors are uncommon traps, probability is 0.
10616 // Node got flipped during fixup flow.
10617 assert($cmp$$cmpcode == 0x9, "must be greater");
10618 __ trap_range_check_g($src_length$$Register, $index$$constant);
10619 }
10620 %}
10621 ins_pipe(pipe_class_trap);
10622 %}
10623
10624 // Match range check 'If lt (CmpU index length)'.
10625 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
10626 match(If cmp (CmpU src_index src_length));
10627 effect(USE labl);
10628 predicate(TrapBasedRangeChecks &&
10629 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10630 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10631 (Matcher::branches_to_uncommon_trap(_leaf)));
10632
10633 ins_is_TrapBasedCheckNode(true);
10634
10635 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
10636 size(4);
10637 ins_encode %{
10638 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10639 __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
10640 } else {
10641 // Both successors are uncommon traps, probability is 0.
10642 // Node got flipped during fixup flow.
10643 assert($cmp$$cmpcode == 0x8, "must be less");
10644 __ trap_range_check_l($src_index$$Register, $src_length$$Register);
10645 }
10646 %}
10647 ins_pipe(pipe_class_trap);
10648 %}
10649
10650 // Match range check 'If lt (CmpU index length)'.
10651 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
10652 match(If cmp (CmpU src_index length));
10653 effect(USE labl);
10654 predicate(TrapBasedRangeChecks &&
10655 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10656 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10657 (Matcher::branches_to_uncommon_trap(_leaf)));
10658
10659 ins_is_TrapBasedCheckNode(true);
10660
10661 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %}
10662 size(4);
10663 ins_encode %{
10664 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10665 __ trap_range_check_ge($src_index$$Register, $length$$constant);
10666 } else {
10667 // Both successors are uncommon traps, probability is 0.
10668 // Node got flipped during fixup flow.
10669 assert($cmp$$cmpcode == 0x8, "must be less");
10670 __ trap_range_check_l($src_index$$Register, $length$$constant);
10671 }
10672 %}
10673 ins_pipe(pipe_class_trap);
10674 %}
10675
10676 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10677 match(Set crx (CmpU src1 src2));
10678 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %}
10679 size(4);
10680 ins_encode %{
10681 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10682 %}
10683 ins_pipe(pipe_class_compare);
10684 %}
10685
10686 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
10687 match(Set crx (CmpU src1 src2));
10688 size(4);
10689 format %{ "CMPLWI $crx, $src1, $src2" %}
10690 ins_encode %{
10691 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10692 %}
10693 ins_pipe(pipe_class_compare);
10694 %}
10695
10696 // Implicit zero checks (more implicit null checks).
10697 // No constant pool entries required.
10698 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
10699 match(If cmp (CmpN value zero));
10700 effect(USE labl);
10701 predicate(TrapBasedNullChecks &&
10702 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10703 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10704 Matcher::branches_to_uncommon_trap(_leaf));
10705 ins_cost(1);
10706
10707 ins_is_TrapBasedCheckNode(true);
10708
10709 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
10710 size(4);
10711 ins_encode %{
10712 if ($cmp$$cmpcode == 0xA) {
10713 __ trap_null_check($value$$Register);
10714 } else {
10715 // Both successors are uncommon traps, probability is 0.
10716 // Node got flipped during fixup flow.
10717 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10718 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10719 }
10720 %}
10721 ins_pipe(pipe_class_trap);
10722 %}
10723
10724 // Compare narrow oops.
10725 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
10726 match(Set crx (CmpN src1 src2));
10727
10728 size(4);
10729 ins_cost(2);
10730 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %}
10731 ins_encode %{
10732 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10733 %}
10734 ins_pipe(pipe_class_compare);
10735 %}
10736
10737 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
10738 match(Set crx (CmpN src1 src2));
10739 // Make this more expensive than zeroCheckN_iReg_imm0.
10740 ins_cost(2);
10741
10742 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %}
10743 size(4);
10744 ins_encode %{
10745 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10746 %}
10747 ins_pipe(pipe_class_compare);
10748 %}
10749
10750 // Implicit zero checks (more implicit null checks).
10751 // No constant pool entries required.
10752 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
10753 match(If cmp (CmpP value zero));
10754 effect(USE labl);
10755 predicate(TrapBasedNullChecks &&
10756 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10757 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10758 Matcher::branches_to_uncommon_trap(_leaf));
10759 ins_cost(1); // Should not be cheaper than zeroCheckN.
10760
10761 ins_is_TrapBasedCheckNode(true);
10762
10763 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
10764 size(4);
10765 ins_encode %{
10766 if ($cmp$$cmpcode == 0xA) {
10767 __ trap_null_check($value$$Register);
10768 } else {
10769 // Both successors are uncommon traps, probability is 0.
10770 // Node got flipped during fixup flow.
10771 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10772 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10773 }
10774 %}
10775 ins_pipe(pipe_class_trap);
10776 %}
10777
10778 // Compare Pointers
10779 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
10780 match(Set crx (CmpP src1 src2));
10781 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %}
10782 size(4);
10783 ins_encode %{
10784 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10785 %}
10786 ins_pipe(pipe_class_compare);
10787 %}
10788
10789 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
10790 match(Set crx (CmpP src1 src2));
10791 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %}
10792 size(4);
10793 ins_encode %{
10794 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
10795 %}
10796 ins_pipe(pipe_class_compare);
10797 %}
10798
10799 // Used in postalloc expand.
10800 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
10801 // This match rule prevents reordering of node before a safepoint.
10802 // This only makes sense if this instructions is used exclusively
10803 // for the expansion of EncodeP!
10804 match(Set crx (CmpP src1 src2));
10805 predicate(false);
10806
10807 format %{ "CMPDI $crx, $src1, $src2" %}
10808 size(4);
10809 ins_encode %{
10810 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10811 %}
10812 ins_pipe(pipe_class_compare);
10813 %}
10814
10815 //----------Float Compares----------------------------------------------------
10816
10817 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
10818 // Needs matchrule, see cmpDUnordered.
10819 match(Set crx (CmpF src1 src2));
10820 // no match-rule, false predicate
10821 predicate(false);
10822
10823 format %{ "cmpFUrd $crx, $src1, $src2" %}
10824 size(4);
10825 ins_encode %{
10826 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10827 %}
10828 ins_pipe(pipe_class_default);
10829 %}
10830
10831 instruct cmov_bns_less(flagsReg crx) %{
10832 // no match-rule, false predicate
10833 effect(DEF crx);
10834 predicate(false);
10835
10836 ins_variable_size_depending_on_alignment(true);
10837
10838 format %{ "CMOV $crx" %}
10839 size(12);
10840 ins_encode %{
10841 Label done;
10842 __ bns($crx$$CondRegister, done); // not unordered -> keep crx
10843 __ li(R0, 0);
10844 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less'
10845 __ bind(done);
10846 %}
10847 ins_pipe(pipe_class_default);
10848 %}
10849
10850 // Compare floating, generate condition code.
10851 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{
10852 // FIXME: should we match 'If cmp (CmpF src1 src2))' ??
10853 //
10854 // The following code sequence occurs a lot in mpegaudio:
10855 //
10856 // block BXX:
10857 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0):
10858 // cmpFUrd CR6, F11, F9
10859 // 4: instruct cmov_bns_less (cmpF_reg_reg-1):
10860 // cmov CR6
10861 // 8: instruct branchConSched:
10862 // B_FARle CR6, B56 P=0.500000 C=-1.000000
10863 match(Set crx (CmpF src1 src2));
10864 ins_cost(DEFAULT_COST+BRANCH_COST);
10865
10866 format %{ "CMPF $crx, $src1, $src2 \t// postalloc expanded" %}
10867 postalloc_expand %{
10868 //
10869 // replaces
10870 //
10871 // region src1 src2
10872 // \ | |
10873 // crx=cmpF_reg_reg
10874 //
10875 // with
10876 //
10877 // region src1 src2
10878 // \ | |
10879 // crx=cmpFUnordered_reg_reg
10880 // |
10881 // ^ region
10882 // | \
10883 // crx=cmov_bns_less
10884 //
10885
10886 // Create new nodes.
10887 MachNode *m1 = new cmpFUnordered_reg_regNode();
10888 MachNode *m2 = new cmov_bns_lessNode();
10889
10890 // inputs for new nodes
10891 m1->add_req(n_region, n_src1, n_src2);
10892 m2->add_req(n_region);
10893 m2->add_prec(m1);
10894
10895 // operands for new nodes
10896 m1->_opnds[0] = op_crx;
10897 m1->_opnds[1] = op_src1;
10898 m1->_opnds[2] = op_src2;
10899 m2->_opnds[0] = op_crx;
10900
10901 // registers for new nodes
10902 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10903 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10904
10905 // Insert new nodes.
10906 nodes->push(m1);
10907 nodes->push(m2);
10908 %}
10909 %}
10910
10911 // Compare float, generate -1,0,1
10912 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{
10913 match(Set dst (CmpF3 src1 src2));
10914 effect(KILL cr0);
10915 ins_cost(DEFAULT_COST * 6);
10916 size((VM_Version::has_brw() ? 20 : 24));
10917
10918 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %}
10919
10920 ins_encode %{
10921 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
10922 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
10923 %}
10924 ins_pipe(pipe_class_default);
10925 %}
10926
10927 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
10928 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
10929 // node right before the conditional move using it.
10930 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
10931 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
10932 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
10933 // conditional move was supposed to be spilled.
10934 match(Set crx (CmpD src1 src2));
10935 // False predicate, shall not be matched.
10936 predicate(false);
10937
10938 format %{ "cmpFUrd $crx, $src1, $src2" %}
10939 size(4);
10940 ins_encode %{
10941 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10942 %}
10943 ins_pipe(pipe_class_default);
10944 %}
10945
10946 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{
10947 match(Set crx (CmpD src1 src2));
10948 ins_cost(DEFAULT_COST+BRANCH_COST);
10949
10950 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %}
10951 postalloc_expand %{
10952 //
10953 // replaces
10954 //
10955 // region src1 src2
10956 // \ | |
10957 // crx=cmpD_reg_reg
10958 //
10959 // with
10960 //
10961 // region src1 src2
10962 // \ | |
10963 // crx=cmpDUnordered_reg_reg
10964 // |
10965 // ^ region
10966 // | \
10967 // crx=cmov_bns_less
10968 //
10969
10970 // create new nodes
10971 MachNode *m1 = new cmpDUnordered_reg_regNode();
10972 MachNode *m2 = new cmov_bns_lessNode();
10973
10974 // inputs for new nodes
10975 m1->add_req(n_region, n_src1, n_src2);
10976 m2->add_req(n_region);
10977 m2->add_prec(m1);
10978
10979 // operands for new nodes
10980 m1->_opnds[0] = op_crx;
10981 m1->_opnds[1] = op_src1;
10982 m1->_opnds[2] = op_src2;
10983 m2->_opnds[0] = op_crx;
10984
10985 // registers for new nodes
10986 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10987 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
10988
10989 // Insert new nodes.
10990 nodes->push(m1);
10991 nodes->push(m2);
10992 %}
10993 %}
10994
10995 // Compare double, generate -1,0,1
10996 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{
10997 match(Set dst (CmpD3 src1 src2));
10998 effect(KILL cr0);
10999 ins_cost(DEFAULT_COST * 6);
11000 size((VM_Version::has_brw() ? 20 : 24));
11001
11002 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %}
11003
11004 ins_encode %{
11005 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
11006 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11007 %}
11008 ins_pipe(pipe_class_default);
11009 %}
11010
11011 // Compare char
11012 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11013 match(Set dst (Digit src1));
11014 effect(TEMP src2, TEMP crx);
11015 ins_cost(3 * DEFAULT_COST);
11016
11017 format %{ "LI $src2, 0x3930\n\t"
11018 "CMPRB $crx, 0, $src1, $src2\n\t"
11019 "SETB $dst, $crx" %}
11020 size(12);
11021 ins_encode %{
11022 // 0x30: 0, 0x39: 9
11023 __ li($src2$$Register, 0x3930);
11024 // compare src1 with ranges 0x30 to 0x39
11025 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11026 __ setb($dst$$Register, $crx$$CondRegister);
11027 %}
11028 ins_pipe(pipe_class_default);
11029 %}
11030
11031 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11032 match(Set dst (LowerCase src1));
11033 effect(TEMP src2, TEMP crx);
11034 ins_cost(12 * DEFAULT_COST);
11035
11036 format %{ "LI $src2, 0x7A61\n\t"
11037 "CMPRB $crx, 0, $src1, $src2\n\t"
11038 "BGT $crx, done\n\t"
11039 "LIS $src2, (signed short)0xF6DF\n\t"
11040 "ORI $src2, $src2, 0xFFF8\n\t"
11041 "CMPRB $crx, 1, $src1, $src2\n\t"
11042 "BGT $crx, done\n\t"
11043 "LIS $src2, (signed short)0xAAB5\n\t"
11044 "ORI $src2, $src2, 0xBABA\n\t"
11045 "INSRDI $src2, $src2, 32, 0\n\t"
11046 "CMPEQB $crx, 1, $src1, $src2\n"
11047 "done:\n\t"
11048 "SETB $dst, $crx" %}
11049
11050 size(48);
11051 ins_encode %{
11052 Label done;
11053 // 0x61: a, 0x7A: z
11054 __ li($src2$$Register, 0x7A61);
11055 // compare src1 with ranges 0x61 to 0x7A
11056 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11057 __ bgt($crx$$CondRegister, done);
11058
11059 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
11060 __ lis($src2$$Register, (signed short)0xF6DF);
11061 __ ori($src2$$Register, $src2$$Register, 0xFFF8);
11062 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
11063 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11064 __ bgt($crx$$CondRegister, done);
11065
11066 // 0xAA: feminine ordinal indicator
11067 // 0xB5: micro sign
11068 // 0xBA: masculine ordinal indicator
11069 __ lis($src2$$Register, (signed short)0xAAB5);
11070 __ ori($src2$$Register, $src2$$Register, 0xBABA);
11071 __ insrdi($src2$$Register, $src2$$Register, 32, 0);
11072 // compare src1 with 0xAA, 0xB5, and 0xBA
11073 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
11074
11075 __ bind(done);
11076 __ setb($dst$$Register, $crx$$CondRegister);
11077 %}
11078 ins_pipe(pipe_class_default);
11079 %}
11080
11081 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11082 match(Set dst (UpperCase src1));
11083 effect(TEMP src2, TEMP crx);
11084 ins_cost(7 * DEFAULT_COST);
11085
11086 format %{ "LI $src2, 0x5A41\n\t"
11087 "CMPRB $crx, 0, $src1, $src2\n\t"
11088 "BGT $crx, done\n\t"
11089 "LIS $src2, (signed short)0xD6C0\n\t"
11090 "ORI $src2, $src2, 0xDED8\n\t"
11091 "CMPRB $crx, 1, $src1, $src2\n"
11092 "done:\n\t"
11093 "SETB $dst, $crx" %}
11094
11095 size(28);
11096 ins_encode %{
11097 Label done;
11098 // 0x41: A, 0x5A: Z
11099 __ li($src2$$Register, 0x5A41);
11100 // compare src1 with a range 0x41 to 0x5A
11101 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11102 __ bgt($crx$$CondRegister, done);
11103
11104 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
11105 __ lis($src2$$Register, (signed short)0xD6C0);
11106 __ ori($src2$$Register, $src2$$Register, 0xDED8);
11107 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
11108 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11109
11110 __ bind(done);
11111 __ setb($dst$$Register, $crx$$CondRegister);
11112 %}
11113 ins_pipe(pipe_class_default);
11114 %}
11115
11116 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11117 match(Set dst (Whitespace src1));
11118 predicate(PowerArchitecturePPC64 <= 9);
11119 effect(TEMP src2, TEMP crx);
11120 ins_cost(4 * DEFAULT_COST);
11121
11122 format %{ "LI $src2, 0x0D09\n\t"
11123 "ADDIS $src2, 0x201C\n\t"
11124 "CMPRB $crx, 1, $src1, $src2\n\t"
11125 "SETB $dst, $crx" %}
11126 size(16);
11127 ins_encode %{
11128 // 0x09 to 0x0D, 0x1C to 0x20
11129 __ li($src2$$Register, 0x0D09);
11130 __ addis($src2$$Register, $src2$$Register, 0x0201C);
11131 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11132 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11133 __ setb($dst$$Register, $crx$$CondRegister);
11134 %}
11135 ins_pipe(pipe_class_default);
11136 %}
11137
11138 // Power 10 version, using prefixed addi to load 32-bit constant
11139 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11140 match(Set dst (Whitespace src1));
11141 predicate(PowerArchitecturePPC64 >= 10);
11142 effect(TEMP src2, TEMP crx);
11143 ins_cost(3 * DEFAULT_COST);
11144
11145 format %{ "PLI $src2, 0x201C0D09\n\t"
11146 "CMPRB $crx, 1, $src1, $src2\n\t"
11147 "SETB $dst, $crx" %}
11148 size(16);
11149 ins_encode %{
11150 // 0x09 to 0x0D, 0x1C to 0x20
11151 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
11152 __ pli($src2$$Register, 0x201C0D09);
11153 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11154 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11155 __ setb($dst$$Register, $crx$$CondRegister);
11156 %}
11157 ins_pipe(pipe_class_default);
11158 ins_alignment(2);
11159 %}
11160
11161 //----------Branches---------------------------------------------------------
11162 // Jump
11163
11164 // Direct Branch.
11165 instruct branch(label labl) %{
11166 match(Goto);
11167 effect(USE labl);
11168 ins_cost(BRANCH_COST);
11169
11170 format %{ "B $labl" %}
11171 size(4);
11172 ins_encode %{
11173 Label d; // dummy
11174 __ bind(d);
11175 Label* p = $labl$$label;
11176 // `p' is `nullptr' when this encoding class is used only to
11177 // determine the size of the encoded instruction.
11178 Label& l = (nullptr == p)? d : *(p);
11179 __ b(l);
11180 %}
11181 ins_pipe(pipe_class_default);
11182 %}
11183
11184 // Conditional Near Branch
11185 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11186 // Same match rule as `branchConFar'.
11187 match(If cmp crx);
11188 effect(USE lbl);
11189 ins_cost(BRANCH_COST);
11190
11191 // If set to 1 this indicates that the current instruction is a
11192 // short variant of a long branch. This avoids using this
11193 // instruction in first-pass matching. It will then only be used in
11194 // the `Shorten_branches' pass.
11195 ins_short_branch(1);
11196
11197 format %{ "B$cmp $crx, $lbl" %}
11198 size(4);
11199 ins_encode( enc_bc(crx, cmp, lbl) );
11200 ins_pipe(pipe_class_default);
11201 %}
11202
11203 // This is for cases when the ppc64 `bc' instruction does not
11204 // reach far enough. So we emit a far branch here, which is more
11205 // expensive.
11206 //
11207 // Conditional Far Branch
11208 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11209 // Same match rule as `branchCon'.
11210 match(If cmp crx);
11211 effect(USE crx, USE lbl);
11212 // Higher cost than `branchCon'.
11213 ins_cost(5*BRANCH_COST);
11214
11215 // This is not a short variant of a branch, but the long variant.
11216 ins_short_branch(0);
11217
11218 format %{ "B_FAR$cmp $crx, $lbl" %}
11219 size(8);
11220 ins_encode( enc_bc_far(crx, cmp, lbl) );
11221 ins_pipe(pipe_class_default);
11222 %}
11223
11224 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
11225 match(CountedLoopEnd cmp crx);
11226 effect(USE labl);
11227 ins_cost(BRANCH_COST);
11228
11229 // short variant.
11230 ins_short_branch(1);
11231
11232 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
11233 size(4);
11234 ins_encode( enc_bc(crx, cmp, labl) );
11235 ins_pipe(pipe_class_default);
11236 %}
11237
11238 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
11239 match(CountedLoopEnd cmp crx);
11240 effect(USE labl);
11241 ins_cost(BRANCH_COST);
11242
11243 // Long variant.
11244 ins_short_branch(0);
11245
11246 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
11247 size(8);
11248 ins_encode( enc_bc_far(crx, cmp, labl) );
11249 ins_pipe(pipe_class_default);
11250 %}
11251
11252 // ============================================================================
11253 // Java runtime operations, intrinsics and other complex operations.
11254
11255 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
11256 // array for an instance of the superklass. Set a hidden internal cache on a
11257 // hit (cache is checked with exposed code in gen_subtype_check()). Return
11258 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
11259 //
11260 // GL TODO: Improve this.
11261 // - result should not be a TEMP
11262 // - Add match rule as on sparc avoiding additional Cmp.
11263 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
11264 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
11265 match(Set result (PartialSubtypeCheck subklass superklass));
11266 predicate(!UseSecondarySupersTable);
11267 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
11268 ins_cost(DEFAULT_COST*10);
11269
11270 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
11271 ins_encode %{
11272 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
11273 $tmp_klass$$Register, nullptr, $result$$Register);
11274 %}
11275 ins_pipe(pipe_class_default);
11276 %}
11277
11278 // Two versions of partialSubtypeCheck, both used when we need to
11279 // search for a super class in the secondary supers array. The first
11280 // is used when we don't know _a priori_ the class being searched
11281 // for. The second, far more common, is used when we do know: this is
11282 // used for instanceof, checkcast, and any case where C2 can determine
11283 // it by constant propagation.
11284 instruct partialSubtypeCheckVarSuper(iRegPsrc sub, iRegPsrc super, iRegPdst result,
11285 iRegPdst tempR1, iRegPdst tempR2, iRegPdst tempR3, iRegPdst tempR4,
11286 flagsRegCR0 cr0, regCTR ctr)
11287 %{
11288 match(Set result (PartialSubtypeCheck sub super));
11289 predicate(UseSecondarySupersTable);
11290 effect(KILL cr0, KILL ctr, TEMP_DEF result, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11291
11292 ins_cost(DEFAULT_COST * 10); // slightly larger than the next version
11293 format %{ "partialSubtypeCheck $result, $sub, $super" %}
11294 ins_encode %{
11295 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register,
11296 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11297 $result$$Register);
11298 %}
11299 ins_pipe(pipe_class_memory);
11300 %}
11301
11302 instruct partialSubtypeCheckConstSuper(rarg3RegP sub, rarg2RegP super_reg, immP super_con, rarg6RegP result,
11303 rarg1RegP tempR1, rarg5RegP tempR2, rarg4RegP tempR3, rscratch1RegP tempR4,
11304 flagsRegCR0 cr0, regCTR ctr)
11305 %{
11306 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
11307 predicate(UseSecondarySupersTable);
11308 effect(KILL cr0, KILL ctr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11309
11310 ins_cost(DEFAULT_COST*8); // smaller than the other version
11311 format %{ "partialSubtypeCheck $result, $sub, $super_reg" %}
11312
11313 ins_encode %{
11314 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
11315 if (InlineSecondarySupersTest) {
11316 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register,
11317 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11318 $result$$Register, super_klass_slot);
11319 } else {
11320 address stub = StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot);
11321 Register r_stub_addr = $tempR1$$Register;
11322 __ add_const_optimized(r_stub_addr, R29_TOC, MacroAssembler::offset_to_global_toc(stub), R0);
11323 __ mtctr(r_stub_addr);
11324 __ bctrl();
11325 }
11326 %}
11327
11328 ins_pipe(pipe_class_memory);
11329 %}
11330
11331 // inlined locking and unlocking
11332
11333 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
11334 predicate(!UseObjectMonitorTable);
11335 match(Set crx (FastLock oop box));
11336 effect(TEMP tmp1, TEMP tmp2);
11337
11338 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %}
11339 ins_encode %{
11340 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11341 $tmp1$$Register, $tmp2$$Register, noreg /*tmp3*/);
11342 // If locking was successful, crx should indicate 'EQ'.
11343 // The compiler generates a branch to the runtime call to
11344 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11345 %}
11346 ins_pipe(pipe_class_compare);
11347 %}
11348
11349 instruct cmpFastLockMonitorTable(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, flagsRegCR1 cr1) %{
11350 predicate(UseObjectMonitorTable);
11351 match(Set crx (FastLock oop box));
11352 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr1);
11353
11354 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3" %}
11355 ins_encode %{
11356 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11357 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11358 // If locking was successful, crx should indicate 'EQ'.
11359 // The compiler generates a branch to the runtime call to
11360 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11361 %}
11362 ins_pipe(pipe_class_compare);
11363 %}
11364
11365 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11366 match(Set crx (FastUnlock oop box));
11367 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11368
11369 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
11370 ins_encode %{
11371 __ fast_unlock($crx$$CondRegister, $oop$$Register, $box$$Register,
11372 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11373 // If unlocking was successful, crx should indicate 'EQ'.
11374 // The compiler generates a branch to the runtime call to
11375 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11376 %}
11377 ins_pipe(pipe_class_compare);
11378 %}
11379
11380 // Align address.
11381 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11382 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11383
11384 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
11385 size(4);
11386 ins_encode %{
11387 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant));
11388 %}
11389 ins_pipe(pipe_class_default);
11390 %}
11391
11392 // Array size computation.
11393 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11394 match(Set dst (SubL (CastP2X end) (CastP2X start)));
11395
11396 format %{ "SUB $dst, $end, $start \t// array size in bytes" %}
11397 size(4);
11398 ins_encode %{
11399 __ subf($dst$$Register, $start$$Register, $end$$Register);
11400 %}
11401 ins_pipe(pipe_class_default);
11402 %}
11403
11404 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
11405 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11406 match(Set dummy (ClearArray cnt base));
11407 effect(USE_KILL base, KILL ctr);
11408 ins_cost(2 * MEMORY_REF_COST);
11409
11410 format %{ "ClearArray $cnt, $base" %}
11411 ins_encode %{
11412 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
11413 %}
11414 ins_pipe(pipe_class_default);
11415 %}
11416
11417 // Clear-array with constant large array length.
11418 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{
11419 match(Set dummy (ClearArray cnt base));
11420 effect(USE_KILL base, TEMP tmp, KILL ctr);
11421 ins_cost(3 * MEMORY_REF_COST);
11422
11423 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
11424 ins_encode %{
11425 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
11426 %}
11427 ins_pipe(pipe_class_default);
11428 %}
11429
11430 // Clear-array with dynamic array length.
11431 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11432 match(Set dummy (ClearArray cnt base));
11433 effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11434 ins_cost(4 * MEMORY_REF_COST);
11435
11436 format %{ "ClearArray $cnt, $base" %}
11437 ins_encode %{
11438 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
11439 %}
11440 ins_pipe(pipe_class_default);
11441 %}
11442
11443 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11444 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11445 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11446 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11447 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11448 ins_cost(300);
11449 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11450 ins_encode %{
11451 __ string_compare($str1$$Register, $str2$$Register,
11452 $cnt1$$Register, $cnt2$$Register,
11453 $tmp$$Register,
11454 $result$$Register, StrIntrinsicNode::LL);
11455 %}
11456 ins_pipe(pipe_class_default);
11457 %}
11458
11459 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11460 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11461 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11462 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11463 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11464 ins_cost(300);
11465 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11466 ins_encode %{
11467 __ string_compare($str1$$Register, $str2$$Register,
11468 $cnt1$$Register, $cnt2$$Register,
11469 $tmp$$Register,
11470 $result$$Register, StrIntrinsicNode::UU);
11471 %}
11472 ins_pipe(pipe_class_default);
11473 %}
11474
11475 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11476 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11477 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11478 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11479 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11480 ins_cost(300);
11481 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11482 ins_encode %{
11483 __ string_compare($str1$$Register, $str2$$Register,
11484 $cnt1$$Register, $cnt2$$Register,
11485 $tmp$$Register,
11486 $result$$Register, StrIntrinsicNode::LU);
11487 %}
11488 ins_pipe(pipe_class_default);
11489 %}
11490
11491 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11492 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11493 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11494 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11495 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11496 ins_cost(300);
11497 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11498 ins_encode %{
11499 __ string_compare($str2$$Register, $str1$$Register,
11500 $cnt2$$Register, $cnt1$$Register,
11501 $tmp$$Register,
11502 $result$$Register, StrIntrinsicNode::UL);
11503 %}
11504 ins_pipe(pipe_class_default);
11505 %}
11506
11507 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11508 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11509 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11510 match(Set result (StrEquals (Binary str1 str2) cnt));
11511 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11512 ins_cost(300);
11513 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11514 ins_encode %{
11515 __ array_equals(false, $str1$$Register, $str2$$Register,
11516 $cnt$$Register, $tmp$$Register,
11517 $result$$Register, true /* byte */);
11518 %}
11519 ins_pipe(pipe_class_default);
11520 %}
11521
11522 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11523 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11524 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11525 match(Set result (AryEq ary1 ary2));
11526 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11527 ins_cost(300);
11528 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11529 ins_encode %{
11530 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11531 $tmp1$$Register, $tmp2$$Register,
11532 $result$$Register, true /* byte */);
11533 %}
11534 ins_pipe(pipe_class_default);
11535 %}
11536
11537 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11538 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11539 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11540 match(Set result (AryEq ary1 ary2));
11541 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11542 ins_cost(300);
11543 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11544 ins_encode %{
11545 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11546 $tmp1$$Register, $tmp2$$Register,
11547 $result$$Register, false /* byte */);
11548 %}
11549 ins_pipe(pipe_class_default);
11550 %}
11551
11552 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11553 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11554 iRegIdst tmp1, iRegIdst tmp2,
11555 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11556 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11557 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11558 // Required for EA: check if it is still a type_array.
11559 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11560 ins_cost(150);
11561
11562 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11563 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11564
11565 ins_encode %{
11566 immPOper *needleOper = (immPOper *)$needleImm;
11567 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11568 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11569 jchar chr;
11570 #ifdef VM_LITTLE_ENDIAN
11571 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11572 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11573 #else
11574 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11575 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11576 #endif
11577 __ string_indexof_char($result$$Register,
11578 $haystack$$Register, $haycnt$$Register,
11579 R0, chr,
11580 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11581 %}
11582 ins_pipe(pipe_class_compare);
11583 %}
11584
11585 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11586 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11587 iRegIdst tmp1, iRegIdst tmp2,
11588 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11589 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11590 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11591 // Required for EA: check if it is still a type_array.
11592 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11593 ins_cost(150);
11594
11595 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11596 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11597
11598 ins_encode %{
11599 immPOper *needleOper = (immPOper *)$needleImm;
11600 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11601 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11602 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11603 __ string_indexof_char($result$$Register,
11604 $haystack$$Register, $haycnt$$Register,
11605 R0, chr,
11606 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11607 %}
11608 ins_pipe(pipe_class_compare);
11609 %}
11610
11611 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11612 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11613 iRegIdst tmp1, iRegIdst tmp2,
11614 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11615 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11616 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11617 // Required for EA: check if it is still a type_array.
11618 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11619 ins_cost(150);
11620
11621 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11622 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11623
11624 ins_encode %{
11625 immPOper *needleOper = (immPOper *)$needleImm;
11626 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11627 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11628 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11629 __ string_indexof_char($result$$Register,
11630 $haystack$$Register, $haycnt$$Register,
11631 R0, chr,
11632 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11633 %}
11634 ins_pipe(pipe_class_compare);
11635 %}
11636
11637 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11638 rscratch2RegP needle, immI_1 needlecntImm,
11639 iRegIdst tmp1, iRegIdst tmp2,
11640 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11641 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11642 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11643 // Required for EA: check if it is still a type_array.
11644 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11645 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11646 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11647 ins_cost(180);
11648
11649 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11650 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11651 ins_encode %{
11652 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11653 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11654 guarantee(needle_values, "sanity");
11655 jchar chr;
11656 #ifdef VM_LITTLE_ENDIAN
11657 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11658 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11659 #else
11660 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11661 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11662 #endif
11663 __ string_indexof_char($result$$Register,
11664 $haystack$$Register, $haycnt$$Register,
11665 R0, chr,
11666 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11667 %}
11668 ins_pipe(pipe_class_compare);
11669 %}
11670
11671 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11672 rscratch2RegP needle, immI_1 needlecntImm,
11673 iRegIdst tmp1, iRegIdst tmp2,
11674 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11675 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11676 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11677 // Required for EA: check if it is still a type_array.
11678 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11679 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11680 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11681 ins_cost(180);
11682
11683 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11684 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11685 ins_encode %{
11686 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11687 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11688 guarantee(needle_values, "sanity");
11689 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11690 __ string_indexof_char($result$$Register,
11691 $haystack$$Register, $haycnt$$Register,
11692 R0, chr,
11693 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11694 %}
11695 ins_pipe(pipe_class_compare);
11696 %}
11697
11698 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11699 rscratch2RegP needle, immI_1 needlecntImm,
11700 iRegIdst tmp1, iRegIdst tmp2,
11701 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11702 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11703 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11704 // Required for EA: check if it is still a type_array.
11705 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11706 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11707 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11708 ins_cost(180);
11709
11710 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11711 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11712 ins_encode %{
11713 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11714 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11715 guarantee(needle_values, "sanity");
11716 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11717 __ string_indexof_char($result$$Register,
11718 $haystack$$Register, $haycnt$$Register,
11719 R0, chr,
11720 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11721 %}
11722 ins_pipe(pipe_class_compare);
11723 %}
11724
11725 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11726 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11727 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11728 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11729 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11730 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
11731 ins_cost(180);
11732
11733 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch"
11734 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11735 ins_encode %{
11736 __ string_indexof_char($result$$Register,
11737 $haystack$$Register, $haycnt$$Register,
11738 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11739 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11740 %}
11741 ins_pipe(pipe_class_compare);
11742 %}
11743
11744 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11745 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11746 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11747 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11748 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11749 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
11750 ins_cost(180);
11751
11752 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch"
11753 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11754 ins_encode %{
11755 __ string_indexof_char($result$$Register,
11756 $haystack$$Register, $haycnt$$Register,
11757 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11758 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11759 %}
11760 ins_pipe(pipe_class_compare);
11761 %}
11762
11763 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11764 iRegPsrc needle, uimmI15 needlecntImm,
11765 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11766 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11767 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11768 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11769 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11770 // Required for EA: check if it is still a type_array.
11771 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11772 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11773 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11774 ins_cost(250);
11775
11776 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11777 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11778 ins_encode %{
11779 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11780 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11781
11782 __ string_indexof($result$$Register,
11783 $haystack$$Register, $haycnt$$Register,
11784 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11785 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11786 %}
11787 ins_pipe(pipe_class_compare);
11788 %}
11789
11790 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11791 iRegPsrc needle, uimmI15 needlecntImm,
11792 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11793 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11794 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11795 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11796 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11797 // Required for EA: check if it is still a type_array.
11798 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11799 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11800 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11801 ins_cost(250);
11802
11803 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11804 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11805 ins_encode %{
11806 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11807 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11808
11809 __ string_indexof($result$$Register,
11810 $haystack$$Register, $haycnt$$Register,
11811 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11812 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11813 %}
11814 ins_pipe(pipe_class_compare);
11815 %}
11816
11817 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11818 iRegPsrc needle, uimmI15 needlecntImm,
11819 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11820 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11821 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11822 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11823 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11824 // Required for EA: check if it is still a type_array.
11825 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11826 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11827 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11828 ins_cost(250);
11829
11830 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11831 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11832 ins_encode %{
11833 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11834 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11835
11836 __ string_indexof($result$$Register,
11837 $haystack$$Register, $haycnt$$Register,
11838 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11839 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11840 %}
11841 ins_pipe(pipe_class_compare);
11842 %}
11843
11844 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11845 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11846 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11847 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11848 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11849 TEMP_DEF result,
11850 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11851 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11852 ins_cost(300);
11853
11854 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11855 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11856 ins_encode %{
11857 __ string_indexof($result$$Register,
11858 $haystack$$Register, $haycnt$$Register,
11859 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11860 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11861 %}
11862 ins_pipe(pipe_class_compare);
11863 %}
11864
11865 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11866 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11867 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11868 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11869 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11870 TEMP_DEF result,
11871 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11872 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11873 ins_cost(300);
11874
11875 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11876 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11877 ins_encode %{
11878 __ string_indexof($result$$Register,
11879 $haystack$$Register, $haycnt$$Register,
11880 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11881 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11882 %}
11883 ins_pipe(pipe_class_compare);
11884 %}
11885
11886 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11887 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11888 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11889 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11890 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11891 TEMP_DEF result,
11892 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11893 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11894 ins_cost(300);
11895
11896 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11897 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11898 ins_encode %{
11899 __ string_indexof($result$$Register,
11900 $haystack$$Register, $haycnt$$Register,
11901 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11902 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11903 %}
11904 ins_pipe(pipe_class_compare);
11905 %}
11906
11907 // char[] to byte[] compression
11908 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11909 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11910 match(Set result (StrCompressedCopy src (Binary dst len)));
11911 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11912 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11913 ins_cost(300);
11914 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11915 ins_encode %{
11916 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11917 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11918 %}
11919 ins_pipe(pipe_class_default);
11920 %}
11921
11922 // byte[] to char[] inflation
11923 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
11924 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11925 match(Set dummy (StrInflatedCopy src (Binary dst len)));
11926 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11927 ins_cost(300);
11928 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11929 ins_encode %{
11930 Label Ldone;
11931 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
11932 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11933 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
11934 __ beq(CR0, Ldone);
11935 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
11936 __ bind(Ldone);
11937 %}
11938 ins_pipe(pipe_class_default);
11939 %}
11940
11941 // StringCoding.java intrinsics
11942 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
11943 regCTR ctr, flagsRegCR0 cr0)
11944 %{
11945 match(Set result (CountPositives ary1 len));
11946 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
11947 ins_cost(300);
11948 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
11949 ins_encode %{
11950 __ count_positives($ary1$$Register, $len$$Register, $result$$Register,
11951 $tmp1$$Register, $tmp2$$Register);
11952 %}
11953 ins_pipe(pipe_class_default);
11954 %}
11955
11956 // encode char[] to byte[] in ISO_8859_1
11957 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11958 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11959 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
11960 match(Set result (EncodeISOArray src (Binary dst len)));
11961 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11962 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11963 ins_cost(300);
11964 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11965 ins_encode %{
11966 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11967 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11968 %}
11969 ins_pipe(pipe_class_default);
11970 %}
11971
11972 // encode char[] to byte[] in ASCII
11973 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11974 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11975 predicate(((EncodeISOArrayNode*)n)->is_ascii());
11976 match(Set result (EncodeISOArray src (Binary dst len)));
11977 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11978 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11979 ins_cost(300);
11980 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11981 ins_encode %{
11982 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11983 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
11984 %}
11985 ins_pipe(pipe_class_default);
11986 %}
11987
11988
11989 //---------- Min/Max Instructions ---------------------------------------------
11990
11991
11992 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
11993 match(Set dst (MinI src1 src2));
11994 effect(KILL cr0);
11995 ins_cost(DEFAULT_COST*2);
11996
11997 size(8);
11998 ins_encode %{
11999 __ cmpw(CR0, $src1$$Register, $src2$$Register);
12000 __ isel($dst$$Register, CR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
12001 %}
12002 ins_pipe(pipe_class_default);
12003 %}
12004
12005
12006 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12007 match(Set dst (MaxI src1 src2));
12008 effect(KILL cr0);
12009 ins_cost(DEFAULT_COST*2);
12010
12011 size(8);
12012 ins_encode %{
12013 __ cmpw(CR0, $src1$$Register, $src2$$Register);
12014 __ isel($dst$$Register, CR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
12015 %}
12016 ins_pipe(pipe_class_default);
12017 %}
12018
12019 instruct minF(regF dst, regF src1, regF src2) %{
12020 match(Set dst (MinF src1 src2));
12021 predicate(PowerArchitecturePPC64 >= 9);
12022 ins_cost(DEFAULT_COST);
12023
12024 format %{ "XSMINJDP $dst, $src1, $src2\t// MinF" %}
12025 size(4);
12026 ins_encode %{
12027 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12028 %}
12029 ins_pipe(pipe_class_default);
12030 %}
12031
12032 instruct minD(regD dst, regD src1, regD src2) %{
12033 match(Set dst (MinD src1 src2));
12034 predicate(PowerArchitecturePPC64 >= 9);
12035 ins_cost(DEFAULT_COST);
12036
12037 format %{ "XSMINJDP $dst, $src1, $src2\t// MinD" %}
12038 size(4);
12039 ins_encode %{
12040 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12041 %}
12042 ins_pipe(pipe_class_default);
12043 %}
12044
12045 instruct maxF(regF dst, regF src1, regF src2) %{
12046 match(Set dst (MaxF src1 src2));
12047 predicate(PowerArchitecturePPC64 >= 9);
12048 ins_cost(DEFAULT_COST);
12049
12050 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxF" %}
12051 size(4);
12052 ins_encode %{
12053 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12054 %}
12055 ins_pipe(pipe_class_default);
12056 %}
12057
12058 instruct maxD(regD dst, regD src1, regD src2) %{
12059 match(Set dst (MaxD src1 src2));
12060 predicate(PowerArchitecturePPC64 >= 9);
12061 ins_cost(DEFAULT_COST);
12062
12063 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxD" %}
12064 size(4);
12065 ins_encode %{
12066 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12067 %}
12068 ins_pipe(pipe_class_default);
12069 %}
12070
12071 //---------- Population Count Instructions ------------------------------------
12072
12073 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
12074 match(Set dst (PopCountI src));
12075 predicate(UsePopCountInstruction);
12076 ins_cost(DEFAULT_COST);
12077
12078 format %{ "POPCNTW $dst, $src" %}
12079 size(4);
12080 ins_encode %{
12081 __ popcntw($dst$$Register, $src$$Register);
12082 %}
12083 ins_pipe(pipe_class_default);
12084 %}
12085
12086 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
12087 predicate(UsePopCountInstruction);
12088 match(Set dst (PopCountL src));
12089 ins_cost(DEFAULT_COST);
12090
12091 format %{ "POPCNTD $dst, $src" %}
12092 size(4);
12093 ins_encode %{
12094 __ popcntd($dst$$Register, $src$$Register);
12095 %}
12096 ins_pipe(pipe_class_default);
12097 %}
12098
12099 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
12100 match(Set dst (CountLeadingZerosI src));
12101 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12102 ins_cost(DEFAULT_COST);
12103
12104 format %{ "CNTLZW $dst, $src" %}
12105 size(4);
12106 ins_encode %{
12107 __ cntlzw($dst$$Register, $src$$Register);
12108 %}
12109 ins_pipe(pipe_class_default);
12110 %}
12111
12112 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
12113 match(Set dst (CountLeadingZerosL src));
12114 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12115 ins_cost(DEFAULT_COST);
12116
12117 format %{ "CNTLZD $dst, $src" %}
12118 size(4);
12119 ins_encode %{
12120 __ cntlzd($dst$$Register, $src$$Register);
12121 %}
12122 ins_pipe(pipe_class_default);
12123 %}
12124
12125 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
12126 // no match-rule, false predicate
12127 effect(DEF dst, USE src);
12128 predicate(false);
12129
12130 format %{ "CNTLZD $dst, $src" %}
12131 size(4);
12132 ins_encode %{
12133 __ cntlzd($dst$$Register, $src$$Register);
12134 %}
12135 ins_pipe(pipe_class_default);
12136 %}
12137
12138 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
12139 match(Set dst (CountTrailingZerosI src));
12140 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12141 ins_cost(DEFAULT_COST);
12142
12143 expand %{
12144 immI16 imm1 %{ (int)-1 %}
12145 immI16 imm2 %{ (int)32 %}
12146 immI_minus1 m1 %{ -1 %}
12147 iRegIdst tmpI1;
12148 iRegIdst tmpI2;
12149 iRegIdst tmpI3;
12150 addI_reg_imm16(tmpI1, src, imm1);
12151 andcI_reg_reg(tmpI2, src, m1, tmpI1);
12152 countLeadingZerosI(tmpI3, tmpI2);
12153 subI_imm16_reg(dst, imm2, tmpI3);
12154 %}
12155 %}
12156
12157 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{
12158 match(Set dst (CountTrailingZerosI src));
12159 predicate(UseCountTrailingZerosInstructionsPPC64);
12160 ins_cost(DEFAULT_COST);
12161
12162 format %{ "CNTTZW $dst, $src" %}
12163 size(4);
12164 ins_encode %{
12165 __ cnttzw($dst$$Register, $src$$Register);
12166 %}
12167 ins_pipe(pipe_class_default);
12168 %}
12169
12170 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
12171 match(Set dst (CountTrailingZerosL src));
12172 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12173 ins_cost(DEFAULT_COST);
12174
12175 expand %{
12176 immL16 imm1 %{ (long)-1 %}
12177 immI16 imm2 %{ (int)64 %}
12178 iRegLdst tmpL1;
12179 iRegLdst tmpL2;
12180 iRegIdst tmpL3;
12181 addL_reg_imm16(tmpL1, src, imm1);
12182 andcL_reg_reg(tmpL2, tmpL1, src);
12183 countLeadingZerosL(tmpL3, tmpL2);
12184 subI_imm16_reg(dst, imm2, tmpL3);
12185 %}
12186 %}
12187
12188 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{
12189 match(Set dst (CountTrailingZerosL src));
12190 predicate(UseCountTrailingZerosInstructionsPPC64);
12191 ins_cost(DEFAULT_COST);
12192
12193 format %{ "CNTTZD $dst, $src" %}
12194 size(4);
12195 ins_encode %{
12196 __ cnttzd($dst$$Register, $src$$Register);
12197 %}
12198 ins_pipe(pipe_class_default);
12199 %}
12200
12201 // Expand nodes for byte_reverse_int/ushort/short.
12202 instruct rlwinm(iRegIdst dst, iRegIsrc src, immI16 shift, immI16 mb, immI16 me) %{
12203 effect(DEF dst, USE src, USE shift, USE mb, USE me);
12204 predicate(false);
12205
12206 format %{ "RLWINM $dst, $src, $shift, $mb, $me" %}
12207 size(4);
12208 ins_encode %{
12209 __ rlwinm($dst$$Register, $src$$Register, $shift$$constant, $mb$$constant, $me$$constant);
12210 %}
12211 ins_pipe(pipe_class_default);
12212 %}
12213
12214 // Expand nodes for byte_reverse_int.
12215 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
12216 effect(DEF dst, USE src, USE n, USE b);
12217 predicate(false);
12218
12219 format %{ "INSRWI $dst, $src, $n, $b" %}
12220 size(4);
12221 ins_encode %{
12222 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
12223 %}
12224 ins_pipe(pipe_class_default);
12225 %}
12226
12227 // As insrwi_a, but with USE_DEF.
12228 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
12229 effect(USE_DEF dst, USE src, USE n, USE b);
12230 predicate(false);
12231
12232 format %{ "INSRWI $dst, $src, $n, $b" %}
12233 size(4);
12234 ins_encode %{
12235 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
12236 %}
12237 ins_pipe(pipe_class_default);
12238 %}
12239
12240 // Just slightly faster than java implementation.
12241 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
12242 match(Set dst (ReverseBytesI src));
12243 predicate(!UseByteReverseInstructions);
12244 ins_cost(7*DEFAULT_COST);
12245
12246 expand %{
12247 immI16 imm24 %{ (int) 24 %}
12248 immI16 imm16 %{ (int) 16 %}
12249 immI16 imm8 %{ (int) 8 %}
12250 immI16 imm4 %{ (int) 4 %}
12251 immI16 imm0 %{ (int) 0 %}
12252 iRegLdst tmpI1;
12253 iRegLdst tmpI2;
12254 iRegLdst tmpI3;
12255
12256 urShiftI_reg_imm(tmpI1, src, imm24);
12257 insrwi_a(dst, tmpI1, imm8, imm24);
12258 urShiftI_reg_imm(tmpI2, src, imm16);
12259 insrwi(dst, tmpI2, imm16, imm8);
12260 urShiftI_reg_imm(tmpI3, src, imm8);
12261 insrwi(dst, tmpI3, imm8, imm8);
12262 insrwi(dst, src, imm8, imm0);
12263 %}
12264 %}
12265
12266 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{
12267 match(Set dst (ReverseBytesI src));
12268 predicate(UseVectorByteReverseInstructionsPPC64);
12269 effect(TEMP tmpV);
12270 ins_cost(DEFAULT_COST*3);
12271 size(12);
12272 format %{ "MTVSRWZ $tmpV, $src\n"
12273 "\tXXBRW $tmpV, $tmpV\n"
12274 "\tMFVSRWZ $dst, $tmpV" %}
12275
12276 ins_encode %{
12277 __ mtvsrwz($tmpV$$VectorRegister.to_vsr(), $src$$Register);
12278 __ xxbrw($tmpV$$VectorRegister.to_vsr(), $tmpV$$VectorRegister->to_vsr());
12279 __ mfvsrwz($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12280 %}
12281 ins_pipe(pipe_class_default);
12282 %}
12283
12284 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{
12285 match(Set dst (ReverseBytesI src));
12286 predicate(UseByteReverseInstructions);
12287 ins_cost(DEFAULT_COST);
12288 size(4);
12289
12290 format %{ "BRW $dst, $src" %}
12291
12292 ins_encode %{
12293 __ brw($dst$$Register, $src$$Register);
12294 %}
12295 ins_pipe(pipe_class_default);
12296 %}
12297
12298 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
12299 match(Set dst (ReverseBytesL src));
12300 predicate(!UseByteReverseInstructions);
12301 ins_cost(15*DEFAULT_COST);
12302
12303 expand %{
12304 immI16 imm56 %{ (int) 56 %}
12305 immI16 imm48 %{ (int) 48 %}
12306 immI16 imm40 %{ (int) 40 %}
12307 immI16 imm32 %{ (int) 32 %}
12308 immI16 imm24 %{ (int) 24 %}
12309 immI16 imm16 %{ (int) 16 %}
12310 immI16 imm8 %{ (int) 8 %}
12311 immI16 imm0 %{ (int) 0 %}
12312 iRegLdst tmpL1;
12313 iRegLdst tmpL2;
12314 iRegLdst tmpL3;
12315 iRegLdst tmpL4;
12316 iRegLdst tmpL5;
12317 iRegLdst tmpL6;
12318
12319 // src : |a|b|c|d|e|f|g|h|
12320 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
12321 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
12322 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
12323 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
12324 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
12325 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
12326 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
12327 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
12328 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
12329 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
12330 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
12331 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
12332 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
12333 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
12334 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
12335 %}
12336 %}
12337
12338 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{
12339 match(Set dst (ReverseBytesL src));
12340 predicate(UseVectorByteReverseInstructionsPPC64);
12341 effect(TEMP tmpV);
12342 ins_cost(DEFAULT_COST*3);
12343 size(12);
12344 format %{ "MTVSRD $tmpV, $src\n"
12345 "\tXXBRD $tmpV, $tmpV\n"
12346 "\tMFVSRD $dst, $tmpV" %}
12347
12348 ins_encode %{
12349 __ mtvsrd($tmpV$$VectorRegister->to_vsr(), $src$$Register);
12350 __ xxbrd($tmpV$$VectorRegister->to_vsr(), $tmpV$$VectorRegister->to_vsr());
12351 __ mfvsrd($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12352 %}
12353 ins_pipe(pipe_class_default);
12354 %}
12355
12356 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{
12357 match(Set dst (ReverseBytesL src));
12358 predicate(UseByteReverseInstructions);
12359 ins_cost(DEFAULT_COST);
12360 size(4);
12361
12362 format %{ "BRD $dst, $src" %}
12363
12364 ins_encode %{
12365 __ brd($dst$$Register, $src$$Register);
12366 %}
12367 ins_pipe(pipe_class_default);
12368 %}
12369
12370 // Need zero extend. Must not use brh only.
12371 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
12372 match(Set dst (ReverseBytesUS src));
12373 ins_cost(2*DEFAULT_COST);
12374
12375 expand %{
12376 immI16 imm31 %{ (int) 31 %}
12377 immI16 imm24 %{ (int) 24 %}
12378 immI16 imm16 %{ (int) 16 %}
12379 immI16 imm8 %{ (int) 8 %}
12380
12381 rlwinm(dst, src, imm24, imm24, imm31);
12382 insrwi(dst, src, imm8, imm16);
12383 %}
12384 %}
12385
12386 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
12387 match(Set dst (ReverseBytesS src));
12388 predicate(!UseByteReverseInstructions);
12389 ins_cost(3*DEFAULT_COST);
12390
12391 expand %{
12392 immI16 imm16 %{ (int) 16 %}
12393 immI16 imm8 %{ (int) 8 %}
12394 iRegLdst tmpI1;
12395
12396 urShiftI_reg_imm(tmpI1, src, imm8);
12397 insrwi(tmpI1, src, imm8, imm16);
12398 extsh(dst, tmpI1);
12399 %}
12400 %}
12401
12402 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{
12403 match(Set dst (ReverseBytesS src));
12404 predicate(UseByteReverseInstructions);
12405 ins_cost(DEFAULT_COST);
12406 size(8);
12407
12408 format %{ "BRH $dst, $src\n\t"
12409 "EXTSH $dst, $dst" %}
12410
12411 ins_encode %{
12412 __ brh($dst$$Register, $src$$Register);
12413 __ extsh($dst$$Register, $dst$$Register);
12414 %}
12415 ins_pipe(pipe_class_default);
12416 %}
12417
12418 // Load Integer reversed byte order
12419 instruct loadI_reversed(iRegIdst dst, indirect mem) %{
12420 match(Set dst (ReverseBytesI (LoadI mem)));
12421 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12422 ins_cost(MEMORY_REF_COST);
12423
12424 size(4);
12425 ins_encode %{
12426 __ lwbrx($dst$$Register, $mem$$Register);
12427 %}
12428 ins_pipe(pipe_class_default);
12429 %}
12430
12431 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{
12432 match(Set dst (ReverseBytesI (LoadI mem)));
12433 ins_cost(2 * MEMORY_REF_COST);
12434
12435 size(12);
12436 ins_encode %{
12437 __ lwbrx($dst$$Register, $mem$$Register);
12438 __ twi_0($dst$$Register);
12439 __ isync();
12440 %}
12441 ins_pipe(pipe_class_default);
12442 %}
12443
12444 // Load Long - aligned and reversed
12445 instruct loadL_reversed(iRegLdst dst, indirect mem) %{
12446 match(Set dst (ReverseBytesL (LoadL mem)));
12447 predicate((n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))));
12448 ins_cost(MEMORY_REF_COST);
12449
12450 size(4);
12451 ins_encode %{
12452 __ ldbrx($dst$$Register, $mem$$Register);
12453 %}
12454 ins_pipe(pipe_class_default);
12455 %}
12456
12457 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{
12458 match(Set dst (ReverseBytesL (LoadL mem)));
12459 ins_cost(2 * MEMORY_REF_COST);
12460
12461 size(12);
12462 ins_encode %{
12463 __ ldbrx($dst$$Register, $mem$$Register);
12464 __ twi_0($dst$$Register);
12465 __ isync();
12466 %}
12467 ins_pipe(pipe_class_default);
12468 %}
12469
12470 // Load unsigned short / char reversed byte order
12471 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
12472 match(Set dst (ReverseBytesUS (LoadUS mem)));
12473 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12474 ins_cost(MEMORY_REF_COST);
12475
12476 size(4);
12477 ins_encode %{
12478 __ lhbrx($dst$$Register, $mem$$Register);
12479 %}
12480 ins_pipe(pipe_class_default);
12481 %}
12482
12483 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{
12484 match(Set dst (ReverseBytesUS (LoadUS mem)));
12485 ins_cost(2 * MEMORY_REF_COST);
12486
12487 size(12);
12488 ins_encode %{
12489 __ lhbrx($dst$$Register, $mem$$Register);
12490 __ twi_0($dst$$Register);
12491 __ isync();
12492 %}
12493 ins_pipe(pipe_class_default);
12494 %}
12495
12496 // Load short reversed byte order
12497 instruct loadS_reversed(iRegIdst dst, indirect mem) %{
12498 match(Set dst (ReverseBytesS (LoadS mem)));
12499 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12500 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
12501
12502 size(8);
12503 ins_encode %{
12504 __ lhbrx($dst$$Register, $mem$$Register);
12505 __ extsh($dst$$Register, $dst$$Register);
12506 %}
12507 ins_pipe(pipe_class_default);
12508 %}
12509
12510 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{
12511 match(Set dst (ReverseBytesS (LoadS mem)));
12512 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12513
12514 size(16);
12515 ins_encode %{
12516 __ lhbrx($dst$$Register, $mem$$Register);
12517 __ twi_0($dst$$Register);
12518 __ extsh($dst$$Register, $dst$$Register);
12519 __ isync();
12520 %}
12521 ins_pipe(pipe_class_default);
12522 %}
12523
12524 // Store Integer reversed byte order
12525 instruct storeI_reversed(iRegIsrc src, indirect mem) %{
12526 match(Set mem (StoreI mem (ReverseBytesI src)));
12527 ins_cost(MEMORY_REF_COST);
12528
12529 size(4);
12530 ins_encode %{
12531 __ stwbrx($src$$Register, $mem$$Register);
12532 %}
12533 ins_pipe(pipe_class_default);
12534 %}
12535
12536 // Store Long reversed byte order
12537 instruct storeL_reversed(iRegLsrc src, indirect mem) %{
12538 match(Set mem (StoreL mem (ReverseBytesL src)));
12539 ins_cost(MEMORY_REF_COST);
12540
12541 size(4);
12542 ins_encode %{
12543 __ stdbrx($src$$Register, $mem$$Register);
12544 %}
12545 ins_pipe(pipe_class_default);
12546 %}
12547
12548 // Store unsigned short / char reversed byte order
12549 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
12550 match(Set mem (StoreC mem (ReverseBytesUS src)));
12551 ins_cost(MEMORY_REF_COST);
12552
12553 size(4);
12554 ins_encode %{
12555 __ sthbrx($src$$Register, $mem$$Register);
12556 %}
12557 ins_pipe(pipe_class_default);
12558 %}
12559
12560 // Store short reversed byte order
12561 instruct storeS_reversed(iRegIsrc src, indirect mem) %{
12562 match(Set mem (StoreC mem (ReverseBytesS src)));
12563 ins_cost(MEMORY_REF_COST);
12564
12565 size(4);
12566 ins_encode %{
12567 __ sthbrx($src$$Register, $mem$$Register);
12568 %}
12569 ins_pipe(pipe_class_default);
12570 %}
12571
12572 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
12573 effect(DEF temp1, USE src);
12574
12575 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %}
12576 size(4);
12577 ins_encode %{
12578 __ mtvsrwz($temp1$$VectorRegister->to_vsr(), $src$$Register);
12579 %}
12580 ins_pipe(pipe_class_default);
12581 %}
12582
12583 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{
12584 effect(DEF dst, USE src, USE imm1);
12585
12586 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %}
12587 size(4);
12588 ins_encode %{
12589 __ xxspltw($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $imm1$$constant);
12590 %}
12591 ins_pipe(pipe_class_default);
12592 %}
12593
12594 instruct xscvdpspn_regF(vecX dst, regF src) %{
12595 effect(DEF dst, USE src);
12596
12597 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %}
12598 size(4);
12599 ins_encode %{
12600 __ xscvdpspn($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr());
12601 %}
12602 ins_pipe(pipe_class_default);
12603 %}
12604
12605 //---------- Replicate Vector Instructions ------------------------------------
12606
12607 // Insrdi does replicate if src == dst.
12608 instruct repl32(iRegLdst dst) %{
12609 predicate(false);
12610 effect(USE_DEF dst);
12611
12612 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %}
12613 size(4);
12614 ins_encode %{
12615 __ insrdi($dst$$Register, $dst$$Register, 32, 0);
12616 %}
12617 ins_pipe(pipe_class_default);
12618 %}
12619
12620 // Insrdi does replicate if src == dst.
12621 instruct repl48(iRegLdst dst) %{
12622 predicate(false);
12623 effect(USE_DEF dst);
12624
12625 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %}
12626 size(4);
12627 ins_encode %{
12628 __ insrdi($dst$$Register, $dst$$Register, 48, 0);
12629 %}
12630 ins_pipe(pipe_class_default);
12631 %}
12632
12633 // Insrdi does replicate if src == dst.
12634 instruct repl56(iRegLdst dst) %{
12635 predicate(false);
12636 effect(USE_DEF dst);
12637
12638 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %}
12639 size(4);
12640 ins_encode %{
12641 __ insrdi($dst$$Register, $dst$$Register, 56, 0);
12642 %}
12643 ins_pipe(pipe_class_default);
12644 %}
12645
12646 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12647 match(Set dst (Replicate src));
12648 predicate(n->as_Vector()->length() == 8 &&
12649 Matcher::vector_element_basic_type(n) == T_BYTE);
12650 expand %{
12651 moveReg(dst, src);
12652 repl56(dst);
12653 repl48(dst);
12654 repl32(dst);
12655 %}
12656 %}
12657
12658 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
12659 match(Set dst (Replicate zero));
12660 predicate(n->as_Vector()->length() == 8 &&
12661 Matcher::vector_element_basic_type(n) == T_BYTE);
12662 format %{ "LI $dst, #0 \t// replicate8B" %}
12663 size(4);
12664 ins_encode %{
12665 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12666 %}
12667 ins_pipe(pipe_class_default);
12668 %}
12669
12670 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
12671 match(Set dst (Replicate src));
12672 predicate(n->as_Vector()->length() == 8 &&
12673 Matcher::vector_element_basic_type(n) == T_BYTE);
12674 format %{ "LI $dst, #-1 \t// replicate8B" %}
12675 size(4);
12676 ins_encode %{
12677 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12678 %}
12679 ins_pipe(pipe_class_default);
12680 %}
12681
12682 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{
12683 match(Set dst (Replicate src));
12684 predicate(n->as_Vector()->length() == 16 &&
12685 Matcher::vector_element_basic_type(n) == T_BYTE);
12686
12687 expand %{
12688 iRegLdst tmpL;
12689 vecX tmpV;
12690 immI8 imm1 %{ (int) 1 %}
12691 moveReg(tmpL, src);
12692 repl56(tmpL);
12693 repl48(tmpL);
12694 mtvsrwz(tmpV, tmpL);
12695 xxspltw(dst, tmpV, imm1);
12696 %}
12697 %}
12698
12699 instruct repl16B_immI0(vecX dst, immI_0 zero) %{
12700 match(Set dst (Replicate zero));
12701 predicate(n->as_Vector()->length() == 16 &&
12702 Matcher::vector_element_basic_type(n) == T_BYTE);
12703
12704 format %{ "XXLXOR $dst, $zero \t// replicate16B" %}
12705 size(4);
12706 ins_encode %{
12707 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12708 %}
12709 ins_pipe(pipe_class_default);
12710 %}
12711
12712 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{
12713 match(Set dst (Replicate src));
12714 predicate(n->as_Vector()->length() == 16 &&
12715 Matcher::vector_element_basic_type(n) == T_BYTE);
12716
12717 format %{ "XXLEQV $dst, $src \t// replicate16B" %}
12718 size(4);
12719 ins_encode %{
12720 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12721 %}
12722 ins_pipe(pipe_class_default);
12723 %}
12724
12725 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12726 match(Set dst (Replicate src));
12727 predicate(n->as_Vector()->length() == 4 &&
12728 Matcher::vector_element_basic_type(n) == T_SHORT);
12729 expand %{
12730 moveReg(dst, src);
12731 repl48(dst);
12732 repl32(dst);
12733 %}
12734 %}
12735
12736 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
12737 match(Set dst (Replicate zero));
12738 predicate(n->as_Vector()->length() == 4 &&
12739 Matcher::vector_element_basic_type(n) == T_SHORT);
12740 format %{ "LI $dst, #0 \t// replicate4S" %}
12741 size(4);
12742 ins_encode %{
12743 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12744 %}
12745 ins_pipe(pipe_class_default);
12746 %}
12747
12748 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
12749 match(Set dst (Replicate src));
12750 predicate(n->as_Vector()->length() == 4 &&
12751 Matcher::vector_element_basic_type(n) == T_SHORT);
12752 format %{ "LI $dst, -1 \t// replicate4S" %}
12753 size(4);
12754 ins_encode %{
12755 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12756 %}
12757 ins_pipe(pipe_class_default);
12758 %}
12759
12760 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{
12761 match(Set dst (Replicate src));
12762 predicate(n->as_Vector()->length() == 8 &&
12763 Matcher::vector_element_basic_type(n) == T_SHORT);
12764
12765 expand %{
12766 iRegLdst tmpL;
12767 vecX tmpV;
12768 immI8 zero %{ (int) 0 %}
12769 moveReg(tmpL, src);
12770 repl48(tmpL);
12771 repl32(tmpL);
12772 mtvsrd(tmpV, tmpL);
12773 xxpermdi(dst, tmpV, tmpV, zero);
12774 %}
12775 %}
12776
12777 instruct repl8S_immI0(vecX dst, immI_0 zero) %{
12778 match(Set dst (Replicate zero));
12779 predicate(n->as_Vector()->length() == 8 &&
12780 Matcher::vector_element_basic_type(n) == T_SHORT);
12781
12782 format %{ "XXLXOR $dst, $zero \t// replicate8S" %}
12783 size(4);
12784 ins_encode %{
12785 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12786 %}
12787 ins_pipe(pipe_class_default);
12788 %}
12789
12790 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{
12791 match(Set dst (Replicate src));
12792 predicate(n->as_Vector()->length() == 8 &&
12793 Matcher::vector_element_basic_type(n) == T_SHORT);
12794
12795 format %{ "XXLEQV $dst, $src \t// replicate8S" %}
12796 size(4);
12797 ins_encode %{
12798 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12799 %}
12800 ins_pipe(pipe_class_default);
12801 %}
12802
12803 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12804 match(Set dst (Replicate src));
12805 predicate(n->as_Vector()->length() == 2 &&
12806 Matcher::vector_element_basic_type(n) == T_INT);
12807 ins_cost(2 * DEFAULT_COST);
12808 expand %{
12809 moveReg(dst, src);
12810 repl32(dst);
12811 %}
12812 %}
12813
12814 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
12815 match(Set dst (Replicate zero));
12816 predicate(n->as_Vector()->length() == 2 &&
12817 Matcher::vector_element_basic_type(n) == T_INT);
12818 format %{ "LI $dst, #0 \t// replicate2I" %}
12819 size(4);
12820 ins_encode %{
12821 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12822 %}
12823 ins_pipe(pipe_class_default);
12824 %}
12825
12826 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
12827 match(Set dst (Replicate src));
12828 predicate(n->as_Vector()->length() == 2 &&
12829 Matcher::vector_element_basic_type(n) == T_INT);
12830 format %{ "LI $dst, -1 \t// replicate2I" %}
12831 size(4);
12832 ins_encode %{
12833 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12834 %}
12835 ins_pipe(pipe_class_default);
12836 %}
12837
12838 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{
12839 match(Set dst (Replicate src));
12840 predicate(n->as_Vector()->length() == 4 &&
12841 Matcher::vector_element_basic_type(n) == T_INT);
12842 ins_cost(2 * DEFAULT_COST);
12843
12844 expand %{
12845 iRegLdst tmpL;
12846 vecX tmpV;
12847 immI8 zero %{ (int) 0 %}
12848 moveReg(tmpL, src);
12849 repl32(tmpL);
12850 mtvsrd(tmpV, tmpL);
12851 xxpermdi(dst, tmpV, tmpV, zero);
12852 %}
12853 %}
12854
12855 instruct repl4I_immI0(vecX dst, immI_0 zero) %{
12856 match(Set dst (Replicate zero));
12857 predicate(n->as_Vector()->length() == 4 &&
12858 Matcher::vector_element_basic_type(n) == T_INT);
12859
12860 format %{ "XXLXOR $dst, $zero \t// replicate4I" %}
12861 size(4);
12862 ins_encode %{
12863 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12864 %}
12865 ins_pipe(pipe_class_default);
12866 %}
12867
12868 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{
12869 match(Set dst (Replicate src));
12870 predicate(n->as_Vector()->length() == 4 &&
12871 Matcher::vector_element_basic_type(n) == T_INT);
12872
12873 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %}
12874 size(4);
12875 ins_encode %{
12876 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12877 %}
12878 ins_pipe(pipe_class_default);
12879 %}
12880
12881 // Move float to int register via stack, replicate.
12882 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
12883 match(Set dst (Replicate src));
12884 predicate(n->as_Vector()->length() == 2 &&
12885 Matcher::vector_element_basic_type(n) == T_FLOAT);
12886 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12887 expand %{
12888 stackSlotL tmpS;
12889 iRegIdst tmpI;
12890 moveF2I_reg_stack(tmpS, src); // Move float to stack.
12891 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
12892 moveReg(dst, tmpI); // Move int to long reg.
12893 repl32(dst); // Replicate bitpattern.
12894 %}
12895 %}
12896
12897 // Replicate scalar constant to packed float values in Double register
12898 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
12899 match(Set dst (Replicate src));
12900 predicate(n->as_Vector()->length() == 2 &&
12901 Matcher::vector_element_basic_type(n) == T_FLOAT);
12902 ins_cost(5 * DEFAULT_COST);
12903
12904 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
12905 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
12906 %}
12907
12908 // Replicate scalar zero constant to packed float values in Double register
12909 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
12910 match(Set dst (Replicate zero));
12911 predicate(n->as_Vector()->length() == 2 &&
12912 Matcher::vector_element_basic_type(n) == T_FLOAT);
12913
12914 format %{ "LI $dst, #0 \t// replicate2F" %}
12915 size(4);
12916 ins_encode %{
12917 __ li($dst$$Register, 0x0);
12918 %}
12919 ins_pipe(pipe_class_default);
12920 %}
12921
12922
12923 //----------Vector Arithmetic Instructions--------------------------------------
12924
12925 // Vector Addition Instructions
12926
12927 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
12928 match(Set dst (AddVB src1 src2));
12929 predicate(n->as_Vector()->length() == 16);
12930 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %}
12931 size(4);
12932 ins_encode %{
12933 __ vaddubm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12934 %}
12935 ins_pipe(pipe_class_default);
12936 %}
12937
12938 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
12939 match(Set dst (AddVS src1 src2));
12940 predicate(n->as_Vector()->length() == 8);
12941 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %}
12942 size(4);
12943 ins_encode %{
12944 __ vadduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12945 %}
12946 ins_pipe(pipe_class_default);
12947 %}
12948
12949 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
12950 match(Set dst (AddVI src1 src2));
12951 predicate(n->as_Vector()->length() == 4);
12952 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %}
12953 size(4);
12954 ins_encode %{
12955 __ vadduwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12956 %}
12957 ins_pipe(pipe_class_default);
12958 %}
12959
12960 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
12961 match(Set dst (AddVF src1 src2));
12962 predicate(n->as_Vector()->length() == 4);
12963 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %}
12964 size(4);
12965 ins_encode %{
12966 __ vaddfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12967 %}
12968 ins_pipe(pipe_class_default);
12969 %}
12970
12971 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
12972 match(Set dst (AddVL src1 src2));
12973 predicate(n->as_Vector()->length() == 2);
12974 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %}
12975 size(4);
12976 ins_encode %{
12977 __ vaddudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12978 %}
12979 ins_pipe(pipe_class_default);
12980 %}
12981
12982 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
12983 match(Set dst (AddVD src1 src2));
12984 predicate(n->as_Vector()->length() == 2);
12985 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %}
12986 size(4);
12987 ins_encode %{
12988 __ xvadddp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12989 %}
12990 ins_pipe(pipe_class_default);
12991 %}
12992
12993 // Vector Subtraction Instructions
12994
12995 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
12996 match(Set dst (SubVB src1 src2));
12997 predicate(n->as_Vector()->length() == 16);
12998 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %}
12999 size(4);
13000 ins_encode %{
13001 __ vsububm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13002 %}
13003 ins_pipe(pipe_class_default);
13004 %}
13005
13006 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
13007 match(Set dst (SubVS src1 src2));
13008 predicate(n->as_Vector()->length() == 8);
13009 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %}
13010 size(4);
13011 ins_encode %{
13012 __ vsubuhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13013 %}
13014 ins_pipe(pipe_class_default);
13015 %}
13016
13017 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
13018 match(Set dst (SubVI src1 src2));
13019 predicate(n->as_Vector()->length() == 4);
13020 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %}
13021 size(4);
13022 ins_encode %{
13023 __ vsubuwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13024 %}
13025 ins_pipe(pipe_class_default);
13026 %}
13027
13028 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
13029 match(Set dst (SubVF src1 src2));
13030 predicate(n->as_Vector()->length() == 4);
13031 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %}
13032 size(4);
13033 ins_encode %{
13034 __ vsubfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13035 %}
13036 ins_pipe(pipe_class_default);
13037 %}
13038
13039 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
13040 match(Set dst (SubVL src1 src2));
13041 predicate(n->as_Vector()->length() == 2);
13042 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %}
13043 size(4);
13044 ins_encode %{
13045 __ vsubudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13046 %}
13047 ins_pipe(pipe_class_default);
13048 %}
13049
13050 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
13051 match(Set dst (SubVD src1 src2));
13052 predicate(n->as_Vector()->length() == 2);
13053 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %}
13054 size(4);
13055 ins_encode %{
13056 __ xvsubdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13057 %}
13058 ins_pipe(pipe_class_default);
13059 %}
13060
13061 // Vector Multiplication Instructions
13062
13063 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
13064 match(Set dst (MulVS src1 src2));
13065 predicate(n->as_Vector()->length() == 8);
13066 effect(TEMP tmp);
13067 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %}
13068 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %}
13069 size(8);
13070 ins_encode %{
13071 __ vspltish($tmp$$VectorRegister, 0);
13072 __ vmladduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister, $tmp$$VectorRegister);
13073 %}
13074 ins_pipe(pipe_class_default);
13075 %}
13076
13077 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
13078 match(Set dst (MulVI src1 src2));
13079 predicate(n->as_Vector()->length() == 4);
13080 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %}
13081 size(4);
13082 ins_encode %{
13083 __ vmuluwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13084 %}
13085 ins_pipe(pipe_class_default);
13086 %}
13087
13088 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
13089 match(Set dst (MulVF src1 src2));
13090 predicate(n->as_Vector()->length() == 4);
13091 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %}
13092 size(4);
13093 ins_encode %{
13094 __ xvmulsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13095 %}
13096 ins_pipe(pipe_class_default);
13097 %}
13098
13099 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
13100 match(Set dst (MulVD src1 src2));
13101 predicate(n->as_Vector()->length() == 2);
13102 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %}
13103 size(4);
13104 ins_encode %{
13105 __ xvmuldp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13106 %}
13107 ins_pipe(pipe_class_default);
13108 %}
13109
13110 // Vector Division Instructions
13111
13112 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
13113 match(Set dst (DivVF src1 src2));
13114 predicate(n->as_Vector()->length() == 4);
13115 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %}
13116 size(4);
13117 ins_encode %{
13118 __ xvdivsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13119 %}
13120 ins_pipe(pipe_class_default);
13121 %}
13122
13123 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
13124 match(Set dst (DivVD src1 src2));
13125 predicate(n->as_Vector()->length() == 2);
13126 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %}
13127 size(4);
13128 ins_encode %{
13129 __ xvdivdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13130 %}
13131 ins_pipe(pipe_class_default);
13132 %}
13133
13134 // Vector Min / Max Instructions
13135
13136 instruct vmin_reg(vecX dst, vecX src1, vecX src2) %{
13137 match(Set dst (MinV src1 src2));
13138 format %{ "VMIN $dst,$src1,$src2\t// vector min" %}
13139 size(4);
13140 ins_encode %{
13141 BasicType bt = Matcher::vector_element_basic_type(this);
13142 switch (bt) {
13143 case T_INT:
13144 __ vminsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13145 break;
13146 case T_LONG:
13147 __ vminsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13148 break;
13149 default:
13150 ShouldNotReachHere();
13151 }
13152 %}
13153 ins_pipe(pipe_class_default);
13154 %}
13155
13156 instruct vmax_reg(vecX dst, vecX src1, vecX src2) %{
13157 match(Set dst (MaxV src1 src2));
13158 format %{ "VMAX $dst,$src1,$src2\t// vector max" %}
13159 size(4);
13160 ins_encode %{
13161 BasicType bt = Matcher::vector_element_basic_type(this);
13162 switch (bt) {
13163 case T_INT:
13164 __ vmaxsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13165 break;
13166 case T_LONG:
13167 __ vmaxsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13168 break;
13169 default:
13170 ShouldNotReachHere();
13171 }
13172 %}
13173 ins_pipe(pipe_class_default);
13174 %}
13175
13176 instruct vminu_reg(vecX dst, vecX src1, vecX src2) %{
13177 match(Set dst (UMinV src1 src2));
13178 format %{ "VMINU $dst,$src1,$src2\t// vector unsigned min" %}
13179 size(4);
13180 ins_encode %{
13181 BasicType bt = Matcher::vector_element_basic_type(this);
13182 switch (bt) {
13183 case T_INT:
13184 __ vminuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13185 break;
13186 case T_LONG:
13187 __ vminud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13188 break;
13189 default:
13190 ShouldNotReachHere();
13191 }
13192 %}
13193 ins_pipe(pipe_class_default);
13194 %}
13195
13196 instruct vmaxu_reg(vecX dst, vecX src1, vecX src2) %{
13197 match(Set dst (UMaxV src1 src2));
13198 format %{ "VMAXU $dst,$src1,$src2\t// vector unsigned max" %}
13199 size(4);
13200 ins_encode %{
13201 BasicType bt = Matcher::vector_element_basic_type(this);
13202 switch (bt) {
13203 case T_INT:
13204 __ vmaxuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13205 break;
13206 case T_LONG:
13207 __ vmaxud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13208 break;
13209 default:
13210 ShouldNotReachHere();
13211 }
13212 %}
13213 ins_pipe(pipe_class_default);
13214 %}
13215
13216 instruct vand(vecX dst, vecX src1, vecX src2) %{
13217 match(Set dst (AndV src1 src2));
13218 size(4);
13219 format %{ "VAND $dst,$src1,$src2\t// and vectors" %}
13220 ins_encode %{
13221 __ vand($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13222 %}
13223 ins_pipe(pipe_class_default);
13224 %}
13225
13226 instruct vor(vecX dst, vecX src1, vecX src2) %{
13227 match(Set dst (OrV src1 src2));
13228 size(4);
13229 format %{ "VOR $dst,$src1,$src2\t// or vectors" %}
13230 ins_encode %{
13231 __ vor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13232 %}
13233 ins_pipe(pipe_class_default);
13234 %}
13235
13236 instruct vxor(vecX dst, vecX src1, vecX src2) %{
13237 match(Set dst (XorV src1 src2));
13238 size(4);
13239 format %{ "VXOR $dst,$src1,$src2\t// xor vectors" %}
13240 ins_encode %{
13241 __ vxor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13242 %}
13243 ins_pipe(pipe_class_default);
13244 %}
13245
13246 instruct reductionI_arith_logic(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2) %{
13247 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13248 match(Set dst (AddReductionVI srcInt srcVec));
13249 match(Set dst (MulReductionVI srcInt srcVec));
13250 match(Set dst (AndReductionV srcInt srcVec));
13251 match(Set dst ( OrReductionV srcInt srcVec));
13252 match(Set dst (XorReductionV srcInt srcVec));
13253 effect(TEMP tmp1, TEMP tmp2);
13254 ins_cost(DEFAULT_COST * 6);
13255 format %{ "REDUCEI_ARITH_LOGIC // $dst,$srcInt,$srcVec,$tmp1,$tmp2\t// reduce vector int add/mul/and/or/xor" %}
13256 size(24);
13257 ins_encode %{
13258 int opcode = this->ideal_Opcode();
13259 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13260 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13261 %}
13262 ins_pipe(pipe_class_default);
13263 %}
13264
13265 instruct reductionI_min_max(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2, flagsRegCR0 cr0) %{
13266 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13267 match(Set dst (MinReductionV srcInt srcVec));
13268 match(Set dst (MaxReductionV srcInt srcVec));
13269 effect(TEMP tmp1, TEMP tmp2, KILL cr0);
13270 ins_cost(DEFAULT_COST * 7);
13271 format %{ "REDUCEI_MINMAX // $dst,$srcInt,$srcVec,$tmp1,$tmp2,cr0\t// reduce vector int min/max" %}
13272 size(28);
13273 ins_encode %{
13274 int opcode = this->ideal_Opcode();
13275 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13276 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13277 %}
13278 ins_pipe(pipe_class_default);
13279 %}
13280
13281 // Vector Absolute Instructions
13282
13283 instruct vabs4F_reg(vecX dst, vecX src) %{
13284 match(Set dst (AbsVF src));
13285 predicate(n->as_Vector()->length() == 4);
13286 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
13287 size(4);
13288 ins_encode %{
13289 __ xvabssp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13290 %}
13291 ins_pipe(pipe_class_default);
13292 %}
13293
13294 instruct vabs2D_reg(vecX dst, vecX src) %{
13295 match(Set dst (AbsVD src));
13296 predicate(n->as_Vector()->length() == 2);
13297 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
13298 size(4);
13299 ins_encode %{
13300 __ xvabsdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13301 %}
13302 ins_pipe(pipe_class_default);
13303 %}
13304
13305 // Round Instructions
13306 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{
13307 match(Set dst (RoundDoubleMode src rmode));
13308 format %{ "RoundDoubleMode $src,$rmode" %}
13309 size(4);
13310 ins_encode %{
13311 switch ($rmode$$constant) {
13312 case RoundDoubleModeNode::rmode_rint:
13313 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr());
13314 break;
13315 case RoundDoubleModeNode::rmode_floor:
13316 __ frim($dst$$FloatRegister, $src$$FloatRegister);
13317 break;
13318 case RoundDoubleModeNode::rmode_ceil:
13319 __ frip($dst$$FloatRegister, $src$$FloatRegister);
13320 break;
13321 default:
13322 ShouldNotReachHere();
13323 }
13324 %}
13325 ins_pipe(pipe_class_default);
13326 %}
13327
13328 // Vector Round Instructions
13329 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
13330 match(Set dst (RoundDoubleModeV src rmode));
13331 predicate(n->as_Vector()->length() == 2);
13332 format %{ "RoundDoubleModeV $src,$rmode" %}
13333 size(4);
13334 ins_encode %{
13335 switch ($rmode$$constant) {
13336 case RoundDoubleModeNode::rmode_rint:
13337 __ xvrdpic($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13338 break;
13339 case RoundDoubleModeNode::rmode_floor:
13340 __ xvrdpim($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13341 break;
13342 case RoundDoubleModeNode::rmode_ceil:
13343 __ xvrdpip($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13344 break;
13345 default:
13346 ShouldNotReachHere();
13347 }
13348 %}
13349 ins_pipe(pipe_class_default);
13350 %}
13351
13352 // Vector Negate Instructions
13353
13354 instruct vneg4F_reg(vecX dst, vecX src) %{
13355 match(Set dst (NegVF src));
13356 predicate(n->as_Vector()->length() == 4);
13357 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
13358 size(4);
13359 ins_encode %{
13360 __ xvnegsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13361 %}
13362 ins_pipe(pipe_class_default);
13363 %}
13364
13365 instruct vneg2D_reg(vecX dst, vecX src) %{
13366 match(Set dst (NegVD src));
13367 predicate(n->as_Vector()->length() == 2);
13368 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
13369 size(4);
13370 ins_encode %{
13371 __ xvnegdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13372 %}
13373 ins_pipe(pipe_class_default);
13374 %}
13375
13376 instruct vneg4I_reg(vecX dst, vecX src) %{
13377 match(Set dst (NegVI src));
13378 predicate(Matcher::vector_element_basic_type(n) == T_INT);
13379 format %{ "VNEGW $dst,$src\t// negate int vector" %}
13380 size(4);
13381 ins_encode %{
13382 __ vnegw($dst$$VectorRegister, $src$$VectorRegister);
13383 %}
13384 ins_pipe(pipe_class_default);
13385 %}
13386
13387 // Vector Square Root Instructions
13388
13389 instruct vsqrt4F_reg(vecX dst, vecX src) %{
13390 match(Set dst (SqrtVF src));
13391 predicate(n->as_Vector()->length() == 4);
13392 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
13393 size(4);
13394 ins_encode %{
13395 __ xvsqrtsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13396 %}
13397 ins_pipe(pipe_class_default);
13398 %}
13399
13400 instruct vsqrt2D_reg(vecX dst, vecX src) %{
13401 match(Set dst (SqrtVD src));
13402 predicate(n->as_Vector()->length() == 2);
13403 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %}
13404 size(4);
13405 ins_encode %{
13406 __ xvsqrtdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13407 %}
13408 ins_pipe(pipe_class_default);
13409 %}
13410
13411 // Vector Population Count and Zeros Count Instructions
13412
13413 instruct vpopcnt_reg(vecX dst, vecX src) %{
13414 match(Set dst (PopCountVI src));
13415 match(Set dst (PopCountVL src));
13416 format %{ "VPOPCNT $dst,$src\t// pop count packed" %}
13417 size(4);
13418 ins_encode %{
13419 BasicType bt = Matcher::vector_element_basic_type(this);
13420 switch (bt) {
13421 case T_BYTE:
13422 __ vpopcntb($dst$$VectorRegister, $src$$VectorRegister);
13423 break;
13424 case T_SHORT:
13425 __ vpopcnth($dst$$VectorRegister, $src$$VectorRegister);
13426 break;
13427 case T_INT:
13428 __ vpopcntw($dst$$VectorRegister, $src$$VectorRegister);
13429 break;
13430 case T_LONG:
13431 __ vpopcntd($dst$$VectorRegister, $src$$VectorRegister);
13432 break;
13433 default:
13434 ShouldNotReachHere();
13435 }
13436 %}
13437 ins_pipe(pipe_class_default);
13438 %}
13439
13440 instruct vcount_leading_zeros_reg(vecX dst, vecX src) %{
13441 match(Set dst (CountLeadingZerosV src));
13442 format %{ "VCLZ $dst,$src\t// leading zeros count packed" %}
13443 size(4);
13444 ins_encode %{
13445 BasicType bt = Matcher::vector_element_basic_type(this);
13446 switch (bt) {
13447 case T_BYTE:
13448 __ vclzb($dst$$VectorRegister, $src$$VectorRegister);
13449 break;
13450 case T_SHORT:
13451 __ vclzh($dst$$VectorRegister, $src$$VectorRegister);
13452 break;
13453 case T_INT:
13454 __ vclzw($dst$$VectorRegister, $src$$VectorRegister);
13455 break;
13456 case T_LONG:
13457 __ vclzd($dst$$VectorRegister, $src$$VectorRegister);
13458 break;
13459 default:
13460 ShouldNotReachHere();
13461 }
13462 %}
13463 ins_pipe(pipe_class_default);
13464 %}
13465
13466 instruct vcount_trailing_zeros_reg(vecX dst, vecX src) %{
13467 match(Set dst (CountTrailingZerosV src));
13468 format %{ "VCTZ $dst,$src\t// trailing zeros count packed" %}
13469 size(4);
13470 ins_encode %{
13471 BasicType bt = Matcher::vector_element_basic_type(this);
13472 switch (bt) {
13473 case T_BYTE:
13474 __ vctzb($dst$$VectorRegister, $src$$VectorRegister);
13475 break;
13476 case T_SHORT:
13477 __ vctzh($dst$$VectorRegister, $src$$VectorRegister);
13478 break;
13479 case T_INT:
13480 __ vctzw($dst$$VectorRegister, $src$$VectorRegister);
13481 break;
13482 case T_LONG:
13483 __ vctzd($dst$$VectorRegister, $src$$VectorRegister);
13484 break;
13485 default:
13486 ShouldNotReachHere();
13487 }
13488 %}
13489 ins_pipe(pipe_class_default);
13490 %}
13491
13492 // --------------------------------- FMA --------------------------------------
13493 // src1 * src2 + dst
13494 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{
13495 match(Set dst (FmaVF dst (Binary src1 src2)));
13496 predicate(n->as_Vector()->length() == 4);
13497
13498 format %{ "XVMADDASP $dst, $src1, $src2" %}
13499
13500 size(4);
13501 ins_encode %{
13502 assert(UseFMA, "Needs FMA instructions support.");
13503 __ xvmaddasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13504 %}
13505 ins_pipe(pipe_class_default);
13506 %}
13507
13508 // src1 * (-src2) + dst
13509 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13510 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{
13511 match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
13512 predicate(n->as_Vector()->length() == 4);
13513
13514 format %{ "XVNMSUBASP $dst, $src1, $src2" %}
13515
13516 size(4);
13517 ins_encode %{
13518 assert(UseFMA, "Needs FMA instructions support.");
13519 __ xvnmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13520 %}
13521 ins_pipe(pipe_class_default);
13522 %}
13523
13524 // src1 * src2 - dst
13525 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{
13526 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2)));
13527 predicate(n->as_Vector()->length() == 4);
13528
13529 format %{ "XVMSUBASP $dst, $src1, $src2" %}
13530
13531 size(4);
13532 ins_encode %{
13533 assert(UseFMA, "Needs FMA instructions support.");
13534 __ xvmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13535 %}
13536 ins_pipe(pipe_class_default);
13537 %}
13538
13539 // src1 * src2 + dst
13540 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{
13541 match(Set dst (FmaVD dst (Binary src1 src2)));
13542 predicate(n->as_Vector()->length() == 2);
13543
13544 format %{ "XVMADDADP $dst, $src1, $src2" %}
13545
13546 size(4);
13547 ins_encode %{
13548 assert(UseFMA, "Needs FMA instructions support.");
13549 __ xvmaddadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13550 %}
13551 ins_pipe(pipe_class_default);
13552 %}
13553
13554 // src1 * (-src2) + dst
13555 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13556 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{
13557 match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
13558 predicate(n->as_Vector()->length() == 2);
13559
13560 format %{ "XVNMSUBADP $dst, $src1, $src2" %}
13561
13562 size(4);
13563 ins_encode %{
13564 assert(UseFMA, "Needs FMA instructions support.");
13565 __ xvnmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13566 %}
13567 ins_pipe(pipe_class_default);
13568 %}
13569
13570 // src1 * src2 - dst
13571 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
13572 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2)));
13573 predicate(n->as_Vector()->length() == 2);
13574
13575 format %{ "XVMSUBADP $dst, $src1, $src2" %}
13576
13577 size(4);
13578 ins_encode %{
13579 assert(UseFMA, "Needs FMA instructions support.");
13580 __ xvmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13581 %}
13582 ins_pipe(pipe_class_default);
13583 %}
13584
13585 //----------Overflow Math Instructions-----------------------------------------
13586
13587 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
13588 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
13589 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
13590
13591 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13592 match(Set cr0 (OverflowAddL op1 op2));
13593
13594 format %{ "ADD_ $op1, $op2\t# overflow check long" %}
13595 size(12);
13596 ins_encode %{
13597 __ li(R0, 0);
13598 __ mtxer(R0); // clear XER.SO
13599 __ addo_(R0, $op1$$Register, $op2$$Register);
13600 %}
13601 ins_pipe(pipe_class_default);
13602 %}
13603
13604 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13605 match(Set cr0 (OverflowSubL op1 op2));
13606
13607 format %{ "SUBFO_ R0, $op2, $op1\t# overflow check long" %}
13608 size(12);
13609 ins_encode %{
13610 __ li(R0, 0);
13611 __ mtxer(R0); // clear XER.SO
13612 __ subfo_(R0, $op2$$Register, $op1$$Register);
13613 %}
13614 ins_pipe(pipe_class_default);
13615 %}
13616
13617 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
13618 match(Set cr0 (OverflowSubL zero op2));
13619
13620 format %{ "NEGO_ R0, $op2\t# overflow check long" %}
13621 size(12);
13622 ins_encode %{
13623 __ li(R0, 0);
13624 __ mtxer(R0); // clear XER.SO
13625 __ nego_(R0, $op2$$Register);
13626 %}
13627 ins_pipe(pipe_class_default);
13628 %}
13629
13630 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13631 match(Set cr0 (OverflowMulL op1 op2));
13632
13633 format %{ "MULLDO_ R0, $op1, $op2\t# overflow check long" %}
13634 size(12);
13635 ins_encode %{
13636 __ li(R0, 0);
13637 __ mtxer(R0); // clear XER.SO
13638 __ mulldo_(R0, $op1$$Register, $op2$$Register);
13639 %}
13640 ins_pipe(pipe_class_default);
13641 %}
13642
13643 instruct repl4F_reg_Ex(vecX dst, regF src) %{
13644 match(Set dst (Replicate src));
13645 predicate(n->as_Vector()->length() == 4 &&
13646 Matcher::vector_element_basic_type(n) == T_FLOAT);
13647 ins_cost(DEFAULT_COST);
13648 expand %{
13649 vecX tmpV;
13650 immI8 zero %{ (int) 0 %}
13651
13652 xscvdpspn_regF(tmpV, src);
13653 xxspltw(dst, tmpV, zero);
13654 %}
13655 %}
13656
13657 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{
13658 match(Set dst (Replicate src));
13659 predicate(n->as_Vector()->length() == 4 &&
13660 Matcher::vector_element_basic_type(n) == T_FLOAT);
13661 effect(TEMP tmp);
13662 ins_cost(10 * DEFAULT_COST);
13663
13664 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) );
13665 %}
13666
13667 instruct repl4F_immF0(vecX dst, immF_0 zero) %{
13668 match(Set dst (Replicate zero));
13669 predicate(n->as_Vector()->length() == 4 &&
13670 Matcher::vector_element_basic_type(n) == T_FLOAT);
13671
13672 format %{ "XXLXOR $dst, $zero \t// replicate4F" %}
13673 size(4);
13674 ins_encode %{
13675 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13676 %}
13677 ins_pipe(pipe_class_default);
13678 %}
13679
13680 instruct repl2D_reg_Ex(vecX dst, regD src) %{
13681 match(Set dst (Replicate src));
13682 predicate(n->as_Vector()->length() == 2 &&
13683 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13684
13685 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %}
13686 size(4);
13687 ins_encode %{
13688 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0);
13689 %}
13690 ins_pipe(pipe_class_default);
13691 %}
13692
13693 instruct repl2D_immD0(vecX dst, immD_0 zero) %{
13694 match(Set dst (Replicate zero));
13695 predicate(n->as_Vector()->length() == 2 &&
13696 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13697
13698 format %{ "XXLXOR $dst, $zero \t// replicate2D" %}
13699 size(4);
13700 ins_encode %{
13701 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13702 %}
13703 ins_pipe(pipe_class_default);
13704 %}
13705
13706 instruct mtvsrd(vecX dst, iRegLsrc src) %{
13707 predicate(false);
13708 effect(DEF dst, USE src);
13709
13710 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %}
13711 size(4);
13712 ins_encode %{
13713 __ mtvsrd($dst$$VectorRegister->to_vsr(), $src$$Register);
13714 %}
13715 ins_pipe(pipe_class_default);
13716 %}
13717
13718 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{
13719 effect(DEF dst, USE src, USE zero);
13720
13721 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %}
13722 size(4);
13723 ins_encode %{
13724 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $zero$$constant);
13725 %}
13726 ins_pipe(pipe_class_default);
13727 %}
13728
13729 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{
13730 effect(DEF dst, USE src1, USE src2, USE zero);
13731
13732 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %}
13733 size(4);
13734 ins_encode %{
13735 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr(), $zero$$constant);
13736 %}
13737 ins_pipe(pipe_class_default);
13738 %}
13739
13740 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{
13741 predicate(Matcher::vector_element_basic_type(n) == T_LONG);
13742 match(Set dst (Replicate src));
13743 predicate(n->as_Vector()->length() == 2);
13744 expand %{
13745 vecX tmpV;
13746 immI8 zero %{ (int) 0 %}
13747 mtvsrd(tmpV, src);
13748 xxpermdi(dst, tmpV, tmpV, zero);
13749 %}
13750 %}
13751
13752 instruct repl2L_immI0(vecX dst, immI_0 zero) %{
13753 match(Set dst (Replicate zero));
13754 predicate(n->as_Vector()->length() == 2 &&
13755 Matcher::vector_element_basic_type(n) == T_LONG);
13756
13757 format %{ "XXLXOR $dst, $zero \t// replicate2L" %}
13758 size(4);
13759 ins_encode %{
13760 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13761 %}
13762 ins_pipe(pipe_class_default);
13763 %}
13764
13765 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{
13766 match(Set dst (Replicate src));
13767 predicate(n->as_Vector()->length() == 2 &&
13768 Matcher::vector_element_basic_type(n) == T_LONG);
13769
13770 format %{ "XXLEQV $dst, $src \t// replicate2L" %}
13771 size(4);
13772 ins_encode %{
13773 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13774 %}
13775 ins_pipe(pipe_class_default);
13776 %}
13777
13778 // ============================================================================
13779 // Safepoint Instruction
13780
13781 instruct safePoint_poll(iRegPdst poll) %{
13782 match(SafePoint poll);
13783
13784 // It caused problems to add the effect that r0 is killed, but this
13785 // effect no longer needs to be mentioned, since r0 is not contained
13786 // in a reg_class.
13787
13788 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
13789 size(4);
13790 ins_encode( enc_poll(0x0, poll) );
13791 ins_pipe(pipe_class_default);
13792 %}
13793
13794 // ============================================================================
13795 // Call Instructions
13796
13797 source %{
13798
13799 #include "runtime/continuation.hpp"
13800
13801 %}
13802
13803 // Call Java Static Instruction
13804
13805 instruct CallStaticJavaDirect(method meth) %{
13806 match(CallStaticJava);
13807 effect(USE meth);
13808 ins_cost(CALL_COST);
13809
13810 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
13811
13812 format %{ "CALL,static $meth \t// ==> " %}
13813 size((Continuations::enabled() ? 8 : 4));
13814 ins_encode( enc_java_static_call(meth) );
13815 ins_pipe(pipe_class_call);
13816 %}
13817
13818 // Call Java Dynamic Instruction
13819
13820 instruct CallDynamicJavaDirect(method meth) %{
13821 match(CallDynamicJava);
13822 effect(USE meth);
13823 ins_cost(CALL_COST);
13824
13825 // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
13826 ins_num_consts(4);
13827
13828 format %{ "CALL,dynamic $meth \t// ==> " %}
13829 ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
13830 ins_pipe(pipe_class_call);
13831 %}
13832
13833 // Call Runtime Instruction
13834
13835 instruct CallRuntimeDirect(method meth) %{
13836 match(CallRuntime);
13837 effect(USE meth);
13838 ins_cost(CALL_COST);
13839
13840 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13841 // env for callee, C-toc.
13842 ins_num_consts(3);
13843
13844 format %{ "CALL,runtime" %}
13845 ins_encode( enc_java_to_runtime_call(meth) );
13846 ins_pipe(pipe_class_call);
13847 %}
13848
13849 // Call Leaf
13850
13851 // Used by postalloc expand of CallLeafDirect_Ex (mtctr).
13852 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
13853 effect(DEF dst, USE src);
13854
13855 ins_num_consts(1);
13856
13857 format %{ "MTCTR $src" %}
13858 size(4);
13859 ins_encode( enc_leaf_call_mtctr(src) );
13860 ins_pipe(pipe_class_default);
13861 %}
13862
13863 // Used by postalloc expand of CallLeafDirect_Ex (actual call).
13864 instruct CallLeafDirect(method meth) %{
13865 match(CallLeaf); // To get the data all the data fields we need ...
13866 effect(USE meth);
13867 predicate(false); // but never match.
13868
13869 format %{ "BCTRL \t// leaf call $meth ==> " %}
13870 size((Continuations::enabled() ? 8 : 4));
13871 ins_encode %{
13872 __ bctrl();
13873 __ post_call_nop();
13874 %}
13875 ins_pipe(pipe_class_call);
13876 %}
13877
13878 // postalloc expand of CallLeafDirect.
13879 // Load address to call from TOC, then bl to it.
13880 instruct CallLeafDirect_Ex(method meth) %{
13881 match(CallLeaf);
13882 effect(USE meth);
13883 ins_cost(CALL_COST);
13884
13885 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
13886 // env for callee, C-toc.
13887 ins_num_consts(3);
13888
13889 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
13890 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13891 %}
13892
13893 // Call runtime without safepoint - same as CallLeaf.
13894 // postalloc expand of CallLeafNoFPDirect.
13895 // Load address to call from TOC, then bl to it.
13896 instruct CallLeafNoFPDirect_Ex(method meth) %{
13897 match(CallLeafNoFP);
13898 effect(USE meth);
13899 ins_cost(CALL_COST);
13900
13901 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13902 // env for callee, C-toc.
13903 ins_num_consts(3);
13904
13905 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
13906 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13907 %}
13908
13909 // Tail Call; Jump from runtime stub to Java code.
13910 // Also known as an 'interprocedural jump'.
13911 // Target of jump will eventually return to caller.
13912 // TailJump below removes the return address.
13913 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{
13914 match(TailCall jump_target method_ptr);
13915 ins_cost(CALL_COST);
13916
13917 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t"
13918 "BCTR \t// tail call" %}
13919 size(8);
13920 ins_encode %{
13921 __ mtctr($jump_target$$Register);
13922 __ bctr();
13923 %}
13924 ins_pipe(pipe_class_call);
13925 %}
13926
13927 // Return Instruction
13928 instruct Ret() %{
13929 match(Return);
13930 format %{ "BLR \t// branch to link register" %}
13931 size(4);
13932 ins_encode %{
13933 // LR is restored in MachEpilogNode. Just do the RET here.
13934 __ blr();
13935 %}
13936 ins_pipe(pipe_class_default);
13937 %}
13938
13939 // Tail Jump; remove the return address; jump to target.
13940 // TailCall above leaves the return address around.
13941 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13942 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13943 // "restore" before this instruction (in Epilogue), we need to materialize it
13944 // in %i0.
13945 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
13946 match(TailJump jump_target ex_oop);
13947 ins_cost(CALL_COST);
13948
13949 format %{ "LD R4_ARG2 = LR\n\t"
13950 "MTCTR $jump_target\n\t"
13951 "BCTR \t// TailJump, exception oop: $ex_oop" %}
13952 size(12);
13953 ins_encode %{
13954 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP);
13955 __ mtctr($jump_target$$Register);
13956 __ bctr();
13957 %}
13958 ins_pipe(pipe_class_call);
13959 %}
13960
13961 // Forward exception.
13962 instruct ForwardExceptionjmp()
13963 %{
13964 match(ForwardException);
13965 ins_cost(CALL_COST);
13966
13967 format %{ "JMP forward_exception_stub" %}
13968 ins_encode %{
13969 __ set_inst_mark();
13970 __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
13971 __ clear_inst_mark();
13972 %}
13973 ins_pipe(pipe_class_call);
13974 %}
13975
13976 // Create exception oop: created by stack-crawling runtime code.
13977 // Created exception is now available to this handler, and is setup
13978 // just prior to jumping to this handler. No code emitted.
13979 instruct CreateException(rarg1RegP ex_oop) %{
13980 match(Set ex_oop (CreateEx));
13981 ins_cost(0);
13982
13983 format %{ " -- \t// exception oop; no code emitted" %}
13984 size(0);
13985 ins_encode( /*empty*/ );
13986 ins_pipe(pipe_class_default);
13987 %}
13988
13989 // Rethrow exception: The exception oop will come in the first
13990 // argument position. Then JUMP (not call) to the rethrow stub code.
13991 instruct RethrowException() %{
13992 match(Rethrow);
13993 ins_cost(CALL_COST);
13994
13995 format %{ "JMP rethrow_stub" %}
13996 ins_encode %{
13997 __ set_inst_mark();
13998 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
13999 __ clear_inst_mark();
14000 %}
14001 ins_pipe(pipe_class_call);
14002 %}
14003
14004 // Die now.
14005 instruct ShouldNotReachHere() %{
14006 match(Halt);
14007 ins_cost(CALL_COST);
14008
14009 format %{ "ShouldNotReachHere" %}
14010 ins_encode %{
14011 if (is_reachable()) {
14012 const char* str = __ code_string(_halt_reason);
14013 __ stop(str);
14014 }
14015 %}
14016 ins_pipe(pipe_class_default);
14017 %}
14018
14019 // This name is KNOWN by the ADLC and cannot be changed. The ADLC
14020 // forces a 'TypeRawPtr::BOTTOM' output type for this guy.
14021 // Get a DEF on threadRegP, no costs, no encoding, use
14022 // 'ins_should_rematerialize(true)' to avoid spilling.
14023 instruct tlsLoadP(threadRegP dst) %{
14024 match(Set dst (ThreadLocal));
14025 ins_cost(0);
14026
14027 ins_should_rematerialize(true);
14028
14029 format %{ " -- \t// $dst=Thread::current(), empty" %}
14030 size(0);
14031 ins_encode( /*empty*/ );
14032 ins_pipe(pipe_class_empty);
14033 %}
14034
14035 //---Some PPC specific nodes---------------------------------------------------
14036
14037 // Nop instructions
14038
14039 instruct fxNop() %{
14040 ins_cost(0);
14041
14042 ins_is_nop(true);
14043
14044 format %{ "fxNop" %}
14045 size(4);
14046 ins_encode %{
14047 __ nop();
14048 %}
14049 ins_pipe(pipe_class_default);
14050 %}
14051
14052 instruct fpNop0() %{
14053 ins_cost(0);
14054
14055 ins_is_nop(true);
14056
14057 format %{ "fpNop0" %}
14058 size(4);
14059 ins_encode %{
14060 __ fpnop0();
14061 %}
14062 ins_pipe(pipe_class_default);
14063 %}
14064
14065 instruct fpNop1() %{
14066 ins_cost(0);
14067
14068 ins_is_nop(true);
14069
14070 format %{ "fpNop1" %}
14071 size(4);
14072 ins_encode %{
14073 __ fpnop1();
14074 %}
14075 ins_pipe(pipe_class_default);
14076 %}
14077
14078 instruct brNop0() %{
14079 ins_cost(0);
14080 size(4);
14081 format %{ "brNop0" %}
14082 ins_encode %{
14083 __ brnop0();
14084 %}
14085 ins_is_nop(true);
14086 ins_pipe(pipe_class_default);
14087 %}
14088
14089 instruct brNop1() %{
14090 ins_cost(0);
14091
14092 ins_is_nop(true);
14093
14094 format %{ "brNop1" %}
14095 size(4);
14096 ins_encode %{
14097 __ brnop1();
14098 %}
14099 ins_pipe(pipe_class_default);
14100 %}
14101
14102 instruct brNop2() %{
14103 ins_cost(0);
14104
14105 ins_is_nop(true);
14106
14107 format %{ "brNop2" %}
14108 size(4);
14109 ins_encode %{
14110 __ brnop2();
14111 %}
14112 ins_pipe(pipe_class_default);
14113 %}
14114
14115 instruct cacheWB(indirect addr)
14116 %{
14117 match(CacheWB addr);
14118
14119 ins_cost(100);
14120 format %{ "cache writeback, address = $addr" %}
14121 ins_encode %{
14122 assert($addr->index_position() < 0, "should be");
14123 assert($addr$$disp == 0, "should be");
14124 __ cache_wb(Address($addr$$base$$Register));
14125 %}
14126 ins_pipe(pipe_class_default);
14127 %}
14128
14129 instruct cacheWBPreSync()
14130 %{
14131 match(CacheWBPreSync);
14132
14133 ins_cost(0);
14134 format %{ "cache writeback presync" %}
14135 ins_encode %{
14136 __ cache_wbsync(true);
14137 %}
14138 ins_pipe(pipe_class_default);
14139 %}
14140
14141 instruct cacheWBPostSync()
14142 %{
14143 match(CacheWBPostSync);
14144
14145 ins_cost(100);
14146 format %{ "cache writeback postsync" %}
14147 ins_encode %{
14148 __ cache_wbsync(false);
14149 %}
14150 ins_pipe(pipe_class_default);
14151 %}
14152
14153 //----------PEEPHOLE RULES-----------------------------------------------------
14154 // These must follow all instruction definitions as they use the names
14155 // defined in the instructions definitions.
14156 //
14157 // peepmatch ( root_instr_name [preceeding_instruction]* );
14158 //
14159 // peepconstraint %{
14160 // (instruction_number.operand_name relational_op instruction_number.operand_name
14161 // [, ...] );
14162 // // instruction numbers are zero-based using left to right order in peepmatch
14163 //
14164 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14165 // // provide an instruction_number.operand_name for each operand that appears
14166 // // in the replacement instruction's match rule
14167 //
14168 // ---------VM FLAGS---------------------------------------------------------
14169 //
14170 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14171 //
14172 // Each peephole rule is given an identifying number starting with zero and
14173 // increasing by one in the order seen by the parser. An individual peephole
14174 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14175 // on the command-line.
14176 //
14177 // ---------CURRENT LIMITATIONS----------------------------------------------
14178 //
14179 // Only match adjacent instructions in same basic block
14180 // Only equality constraints
14181 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14182 // Only one replacement instruction
14183 //
14184 // ---------EXAMPLE----------------------------------------------------------
14185 //
14186 // // pertinent parts of existing instructions in architecture description
14187 // instruct movI(eRegI dst, eRegI src) %{
14188 // match(Set dst (CopyI src));
14189 // %}
14190 //
14191 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14192 // match(Set dst (AddI dst src));
14193 // effect(KILL cr);
14194 // %}
14195 //
14196 // // Change (inc mov) to lea
14197 // peephole %{
14198 // // increment preceded by register-register move
14199 // peepmatch ( incI_eReg movI );
14200 // // require that the destination register of the increment
14201 // // match the destination register of the move
14202 // peepconstraint ( 0.dst == 1.dst );
14203 // // construct a replacement instruction that sets
14204 // // the destination to ( move's source register + one )
14205 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14206 // %}
14207 //
14208 // Implementation no longer uses movX instructions since
14209 // machine-independent system no longer uses CopyX nodes.
14210 //
14211 // peephole %{
14212 // peepmatch ( incI_eReg movI );
14213 // peepconstraint ( 0.dst == 1.dst );
14214 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14215 // %}
14216 //
14217 // peephole %{
14218 // peepmatch ( decI_eReg movI );
14219 // peepconstraint ( 0.dst == 1.dst );
14220 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14221 // %}
14222 //
14223 // peephole %{
14224 // peepmatch ( addI_eReg_imm movI );
14225 // peepconstraint ( 0.dst == 1.dst );
14226 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14227 // %}
14228 //
14229 // peephole %{
14230 // peepmatch ( addP_eReg_imm movP );
14231 // peepconstraint ( 0.dst == 1.dst );
14232 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
14233 // %}
14234
14235 // // Change load of spilled value to only a spill
14236 // instruct storeI(memory mem, eRegI src) %{
14237 // match(Set mem (StoreI mem src));
14238 // %}
14239 //
14240 // instruct loadI(eRegI dst, memory mem) %{
14241 // match(Set dst (LoadI mem));
14242 // %}
14243 //
14244 peephole %{
14245 peepmatch ( loadI storeI );
14246 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14247 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14248 %}
14249
14250 peephole %{
14251 peepmatch ( loadL storeL );
14252 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14253 peepreplace ( storeL( 1.mem 1.mem 1.src ) );
14254 %}
14255
14256 peephole %{
14257 peepmatch ( loadP storeP );
14258 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
14259 peepreplace ( storeP( 1.dst 1.dst 1.src ) );
14260 %}
14261
14262 //----------SMARTSPILL RULES---------------------------------------------------
14263 // These must follow all instruction definitions as they use the names
14264 // defined in the instructions definitions.