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() const {
1175 // It's only a single branch-and-link instruction.
1176 return 4;
1177 }
1178
1179 int MachCallDynamicJavaNode::ret_addr_offset() const {
1180 return 12;
1181 }
1182
1183 int MachCallRuntimeNode::ret_addr_offset() const {
1184 if (rule() == CallRuntimeDirect_rule) {
1185 // CallRuntimeDirectNode uses call_c.
1186 #if defined(ABI_ELFv2)
1187 return 28;
1188 #else
1189 return 40;
1190 #endif
1191 }
1192 assert(rule() == CallLeafDirect_rule, "unexpected node with rule %u", rule());
1193 // CallLeafDirectNode uses bl.
1194 return 4;
1195 }
1196
1197 //=============================================================================
1198
1199 // condition code conversions
1200
1201 static int cc_to_boint(int cc) {
1202 return Assembler::bcondCRbiIs0 | (cc & 8);
1203 }
1204
1205 static int cc_to_inverse_boint(int cc) {
1206 return Assembler::bcondCRbiIs0 | (8-(cc & 8));
1207 }
1208
1209 static int cc_to_biint(int cc, int flags_reg) {
1210 return (flags_reg << 2) | (cc & 3);
1211 }
1212
1213 //=============================================================================
1214
1215 // Compute padding required for nodes which need alignment. The padding
1216 // is the number of bytes (not instructions) which will be inserted before
1217 // the instruction. The padding must match the size of a NOP instruction.
1218
1219 // Add nop if a prefixed (two-word) instruction is going to cross a 64-byte boundary.
1220 // (See Section 1.6 of Power ISA Version 3.1)
1221 static int compute_prefix_padding(int current_offset) {
1222 assert(PowerArchitecturePPC64 >= 10 && (CodeEntryAlignment & 63) == 0,
1223 "Code buffer must be aligned to a multiple of 64 bytes");
1224 if (is_aligned(current_offset + BytesPerInstWord, 64)) {
1225 return BytesPerInstWord;
1226 }
1227 return 0;
1228 }
1229
1230 int loadConI32Node::compute_padding(int current_offset) const {
1231 return compute_prefix_padding(current_offset);
1232 }
1233
1234 int loadConL34Node::compute_padding(int current_offset) const {
1235 return compute_prefix_padding(current_offset);
1236 }
1237
1238 int addI_reg_imm32Node::compute_padding(int current_offset) const {
1239 return compute_prefix_padding(current_offset);
1240 }
1241
1242 int addL_reg_imm34Node::compute_padding(int current_offset) const {
1243 return compute_prefix_padding(current_offset);
1244 }
1245
1246 int addP_reg_imm34Node::compute_padding(int current_offset) const {
1247 return compute_prefix_padding(current_offset);
1248 }
1249
1250 int cmprb_Whitespace_reg_reg_prefixedNode::compute_padding(int current_offset) const {
1251 return compute_prefix_padding(current_offset);
1252 }
1253
1254
1255 //=============================================================================
1256
1257 // Emit an interrupt that is caught by the debugger (for debugging compiler).
1258 void emit_break(C2_MacroAssembler *masm) {
1259 __ illtrap();
1260 }
1261
1262 #ifndef PRODUCT
1263 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1264 st->print("BREAKPOINT");
1265 }
1266 #endif
1267
1268 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1269 emit_break(masm);
1270 }
1271
1272 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1273 return MachNode::size(ra_);
1274 }
1275
1276 //=============================================================================
1277
1278 void emit_nop(C2_MacroAssembler *masm) {
1279 __ nop();
1280 }
1281
1282 static inline void emit_long(C2_MacroAssembler *masm, int value) {
1283 *((int*)(__ pc())) = value;
1284 __ set_inst_end(__ pc() + BytesPerInstWord);
1285 }
1286
1287 //=============================================================================
1288
1289 %} // interrupt source
1290
1291 source_hpp %{ // Header information of the source block.
1292
1293 //--------------------------------------------------------------
1294 //---< Used for optimization in Compile::Shorten_branches >---
1295 //--------------------------------------------------------------
1296
1297 class C2_MacroAssembler;
1298
1299 class CallStubImpl {
1300
1301 public:
1302
1303 // Size of call trampoline stub.
1304 // This doesn't need to be accurate to the byte, but it
1305 // must be larger than or equal to the real size of the stub.
1306 static uint size_call_trampoline() {
1307 return MacroAssembler::trampoline_stub_size;
1308 }
1309
1310 // number of relocations needed by a call trampoline stub
1311 static uint reloc_call_trampoline() {
1312 return 5;
1313 }
1314
1315 };
1316
1317 %} // end source_hpp
1318
1319 source %{
1320
1321 // Factory for creating loadConL* nodes for large/small constant pool.
1322
1323 static inline jlong replicate_immF(float con) {
1324 // Replicate float con 2 times and pack into vector.
1325 int val = *((int*)&con);
1326 jlong lval = val;
1327 lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1328 return lval;
1329 }
1330
1331 //=============================================================================
1332
1333 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1334 int ConstantTable::calculate_table_base_offset() const {
1335 return 0; // absolute addressing, no offset
1336 }
1337
1338 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1339 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1340 iRegLdstOper *op_dst = new iRegLdstOper();
1341 MachNode *m1 = new loadToc_hiNode();
1342 MachNode *m2 = new loadToc_loNode();
1343
1344 m1->add_req(nullptr);
1345 m2->add_req(nullptr, m1);
1346 m1->_opnds[0] = op_dst;
1347 m2->_opnds[0] = op_dst;
1348 m2->_opnds[1] = op_dst;
1349 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1350 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1351 nodes->push(m1);
1352 nodes->push(m2);
1353 }
1354
1355 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const {
1356 // Is postalloc expanded.
1357 ShouldNotReachHere();
1358 }
1359
1360 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1361 return 0;
1362 }
1363
1364 #ifndef PRODUCT
1365 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1366 st->print("-- \t// MachConstantBaseNode (empty encoding)");
1367 }
1368 #endif
1369
1370 //=============================================================================
1371
1372 #ifndef PRODUCT
1373 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1374 Compile* C = ra_->C;
1375 const long framesize = C->output()->frame_slots() << LogBytesPerInt;
1376
1377 st->print("PROLOG\n\t");
1378 if (C->output()->need_stack_bang(framesize)) {
1379 st->print("stack_overflow_check\n\t");
1380 }
1381
1382 if (!false /* TODO: PPC port C->is_frameless_method()*/) {
1383 st->print("save return pc\n\t");
1384 st->print("push frame %ld\n\t", -framesize);
1385 }
1386
1387 if (C->stub_function() == nullptr) {
1388 st->print("nmethod entry barrier\n\t");
1389 }
1390 }
1391 #endif
1392
1393 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1394 Compile* C = ra_->C;
1395
1396 const long framesize = C->output()->frame_size_in_bytes();
1397 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment");
1398
1399 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1400
1401 const Register return_pc = R20; // Must match return_addr() in frame section.
1402 const Register callers_sp = R21;
1403 const Register push_frame_temp = R22;
1404 const Register toc_temp = R23;
1405 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp);
1406
1407 if (!method_is_frameless) {
1408 // Get return pc.
1409 __ mflr(return_pc);
1410 }
1411
1412 if (C->clinit_barrier_on_entry()) {
1413 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
1414
1415 Label L_skip_barrier;
1416 Register klass = toc_temp;
1417
1418 // Notify OOP recorder (don't need the relocation)
1419 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding());
1420 __ load_const_optimized(klass, md.value(), R0);
1421 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/);
1422
1423 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0);
1424 __ mtctr(klass);
1425 __ bctr();
1426
1427 __ bind(L_skip_barrier);
1428 }
1429
1430 // Calls to C2R adapters often do not accept exceptional returns.
1431 // We require that their callers must bang for them. But be
1432 // careful, because some VM calls (such as call site linkage) can
1433 // use several kilobytes of stack. But the stack safety zone should
1434 // account for that. See bugs 4446381, 4468289, 4497237.
1435
1436 int bangsize = C->output()->bang_size_in_bytes();
1437 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect");
1438 if (C->output()->need_stack_bang(bangsize)) {
1439 // Unfortunately we cannot use the function provided in
1440 // assembler.cpp as we have to emulate the pipes. So I had to
1441 // insert the code of generate_stack_overflow_check(), see
1442 // assembler.cpp for some illuminative comments.
1443 const int page_size = os::vm_page_size();
1444 int bang_end = StackOverflow::stack_shadow_zone_size();
1445
1446 // This is how far the previous frame's stack banging extended.
1447 const int bang_end_safe = bang_end;
1448
1449 if (bangsize > page_size) {
1450 bang_end += bangsize;
1451 }
1452
1453 int bang_offset = bang_end_safe;
1454
1455 while (bang_offset <= bang_end) {
1456 // Need at least one stack bang at end of shadow zone.
1457
1458 // Again I had to copy code, this time from assembler_ppc.cpp,
1459 // bang_stack_with_offset - see there for comments.
1460
1461 // Stack grows down, caller passes positive offset.
1462 assert(bang_offset > 0, "must bang with positive offset");
1463
1464 long stdoffset = -bang_offset;
1465
1466 if (Assembler::is_simm(stdoffset, 16)) {
1467 // Signed 16 bit offset, a simple std is ok.
1468 if (UseLoadInstructionsForStackBangingPPC64) {
1469 __ ld(R0, (int)(signed short)stdoffset, R1_SP);
1470 } else {
1471 __ std(R0, (int)(signed short)stdoffset, R1_SP);
1472 }
1473 } else if (Assembler::is_simm(stdoffset, 31)) {
1474 // Use largeoffset calculations for addis & ld/std.
1475 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset);
1476 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset);
1477
1478 Register tmp = R11;
1479 __ addis(tmp, R1_SP, hi);
1480 if (UseLoadInstructionsForStackBangingPPC64) {
1481 __ ld(R0, lo, tmp);
1482 } else {
1483 __ std(R0, lo, tmp);
1484 }
1485 } else {
1486 ShouldNotReachHere();
1487 }
1488
1489 bang_offset += page_size;
1490 }
1491 // R11 trashed
1492 } // C->output()->need_stack_bang(framesize)
1493
1494 unsigned int bytes = (unsigned int)framesize;
1495 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
1496 ciMethod *currMethod = C->method();
1497
1498 if (!method_is_frameless) {
1499 // Get callers sp.
1500 __ mr(callers_sp, R1_SP);
1501
1502 // Push method's frame, modifies SP.
1503 assert(Assembler::is_uimm(framesize, 32U), "wrong type");
1504 // The ABI is already accounted for in 'framesize' via the
1505 // 'out_preserve' area.
1506 Register tmp = push_frame_temp;
1507 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp).
1508 if (Assembler::is_simm(-offset, 16)) {
1509 __ stdu(R1_SP, -offset, R1_SP);
1510 } else {
1511 long x = -offset;
1512 // Had to insert load_const(tmp, -offset).
1513 __ lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16)));
1514 __ ori( tmp, tmp, ((x >> 32) & 0x0000ffff));
1515 __ sldi(tmp, tmp, 32);
1516 __ oris(tmp, tmp, (x & 0xffff0000) >> 16);
1517 __ ori( tmp, tmp, (x & 0x0000ffff));
1518
1519 __ stdux(R1_SP, R1_SP, tmp);
1520 }
1521 }
1522 #if 0 // TODO: PPC port
1523 // For testing large constant pools, emit a lot of constants to constant pool.
1524 // "Randomize" const_size.
1525 if (ConstantsALot) {
1526 const int num_consts = const_size();
1527 for (int i = 0; i < num_consts; i++) {
1528 __ long_constant(0xB0B5B00BBABE);
1529 }
1530 }
1531 #endif
1532 if (!method_is_frameless) {
1533 // Save return pc.
1534 __ std(return_pc, _abi0(lr), callers_sp);
1535 }
1536
1537 if (C->stub_function() == nullptr) {
1538 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
1539 bs->nmethod_entry_barrier(masm, push_frame_temp);
1540 }
1541
1542 C->output()->set_frame_complete(__ offset());
1543 }
1544
1545 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1546 // Variable size. determine dynamically.
1547 return MachNode::size(ra_);
1548 }
1549
1550 int MachPrologNode::reloc() const {
1551 // Return number of relocatable values contained in this instruction.
1552 return 1; // 1 reloc entry for load_const(toc).
1553 }
1554
1555 //=============================================================================
1556
1557 #ifndef PRODUCT
1558 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1559 Compile* C = ra_->C;
1560
1561 st->print("EPILOG\n\t");
1562 st->print("restore return pc\n\t");
1563 st->print("pop frame\n\t");
1564
1565 if (do_polling() && C->is_method_compilation()) {
1566 st->print("safepoint poll\n\t");
1567 }
1568 }
1569 #endif
1570
1571 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1572 Compile* C = ra_->C;
1573
1574 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt;
1575 assert(framesize >= 0, "negative frame-size?");
1576
1577 const bool method_needs_polling = do_polling() && C->is_method_compilation();
1578 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1579 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
1580 const Register temp = R12;
1581
1582 if (!method_is_frameless) {
1583 // Restore return pc relative to callers' sp.
1584 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP);
1585 // Move return pc to LR.
1586 __ mtlr(return_pc);
1587 // Pop frame (fixed frame-size).
1588 __ addi(R1_SP, R1_SP, (int)framesize);
1589 }
1590
1591 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1592 __ reserved_stack_check(return_pc);
1593 }
1594
1595 if (method_needs_polling) {
1596 Label dummy_label;
1597 Label* code_stub = &dummy_label;
1598 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) {
1599 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1600 C->output()->add_stub(stub);
1601 code_stub = &stub->entry();
1602 __ relocate(relocInfo::poll_return_type);
1603 }
1604 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */);
1605 }
1606 }
1607
1608 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1609 // Variable size. Determine dynamically.
1610 return MachNode::size(ra_);
1611 }
1612
1613 int MachEpilogNode::reloc() const {
1614 // Return number of relocatable values contained in this instruction.
1615 return 1; // 1 for load_from_polling_page.
1616 }
1617
1618 const Pipeline * MachEpilogNode::pipeline() const {
1619 return MachNode::pipeline_class();
1620 }
1621
1622 // =============================================================================
1623
1624 // Figure out which register class each belongs in: rc_int, rc_float, rc_vec or
1625 // rc_stack.
1626 enum RC { rc_bad, rc_int, rc_float, rc_vec, rc_stack };
1627
1628 static enum RC rc_class(OptoReg::Name reg) {
1629 // Return the register class for the given register. The given register
1630 // reg is a <register>_num value, which is an index into the MachRegisterNumbers
1631 // enumeration in adGlobals_ppc.hpp.
1632
1633 if (reg == OptoReg::Bad) return rc_bad;
1634
1635 // We have 64 integer register halves, starting at index 0.
1636 STATIC_ASSERT((int)ConcreteRegisterImpl::max_gpr == (int)MachRegisterNumbers::F0_num);
1637 if (reg < ConcreteRegisterImpl::max_gpr) return rc_int;
1638
1639 // We have 64 floating-point register halves, starting at index 64.
1640 STATIC_ASSERT((int)ConcreteRegisterImpl::max_fpr == (int)MachRegisterNumbers::VR0_num);
1641 if (reg < ConcreteRegisterImpl::max_fpr) return rc_float;
1642
1643 // We have 64 vector-scalar registers, starting at index 128.
1644 STATIC_ASSERT((int)ConcreteRegisterImpl::max_vr == (int)MachRegisterNumbers::CR0_num);
1645 if (reg < ConcreteRegisterImpl::max_vr) return rc_vec;
1646
1647 // Condition and special purpose registers are not allocated. We only accept stack from here.
1648 assert(OptoReg::is_stack(reg), "what else is it?");
1649 return rc_stack;
1650 }
1651
1652 static int ld_st_helper(C2_MacroAssembler *masm, const char *op_str, uint opcode, int reg, int offset,
1653 bool do_print, Compile* C, outputStream *st) {
1654
1655 assert(opcode == Assembler::LD_OPCODE ||
1656 opcode == Assembler::STD_OPCODE ||
1657 opcode == Assembler::LWZ_OPCODE ||
1658 opcode == Assembler::STW_OPCODE ||
1659 opcode == Assembler::LFD_OPCODE ||
1660 opcode == Assembler::STFD_OPCODE ||
1661 opcode == Assembler::LFS_OPCODE ||
1662 opcode == Assembler::STFS_OPCODE,
1663 "opcode not supported");
1664
1665 if (masm) {
1666 int d =
1667 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ?
1668 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/)
1669 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build.
1670 emit_long(masm, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP));
1671 }
1672 #ifndef PRODUCT
1673 else if (do_print) {
1674 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy",
1675 op_str,
1676 Matcher::regName[reg],
1677 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/);
1678 }
1679 #endif
1680 return 4; // size
1681 }
1682
1683 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1684 Compile* C = ra_->C;
1685
1686 // Get registers to move.
1687 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1688 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1689 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1690 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1691
1692 enum RC src_hi_rc = rc_class(src_hi);
1693 enum RC src_lo_rc = rc_class(src_lo);
1694 enum RC dst_hi_rc = rc_class(dst_hi);
1695 enum RC dst_lo_rc = rc_class(dst_lo);
1696
1697 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1698 if (src_hi != OptoReg::Bad)
1699 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1700 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1701 "expected aligned-adjacent pairs");
1702 // Generate spill code!
1703 int size = 0;
1704
1705 if (src_lo == dst_lo && src_hi == dst_hi)
1706 return size; // Self copy, no move.
1707
1708 if (bottom_type()->isa_vect() != nullptr && ideal_reg() == Op_VecX) {
1709 int src_offset = ra_->reg2offset(src_lo);
1710 int dst_offset = ra_->reg2offset(dst_lo);
1711 DEBUG_ONLY(int algm = MIN2(RegMask::num_registers(ideal_reg()), (int)Matcher::stack_alignment_in_slots()) * VMRegImpl::stack_slot_size);
1712 assert((src_lo_rc != rc_stack) || is_aligned(src_offset, algm), "unaligned vector spill sp offset %d (src)", src_offset);
1713 assert((dst_lo_rc != rc_stack) || is_aligned(dst_offset, algm), "unaligned vector spill sp offset %d (dst)", dst_offset);
1714 // Memory->Memory Spill.
1715 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1716 if (masm) {
1717 __ ld(R0, src_offset, R1_SP);
1718 __ std(R0, dst_offset, R1_SP);
1719 __ ld(R0, src_offset+8, R1_SP);
1720 __ std(R0, dst_offset+8, R1_SP);
1721 }
1722 size += 16;
1723 #ifndef PRODUCT
1724 if (st != nullptr) {
1725 st->print("%-7s [R1_SP + #%d] -> [R1_SP + #%d] \t// vector spill copy", "SPILL", src_offset, dst_offset);
1726 }
1727 #endif // !PRODUCT
1728 }
1729 // VectorRegister->Memory Spill.
1730 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_stack) {
1731 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1732 if (masm) {
1733 __ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16
1734 }
1735 size += 4;
1736 #ifndef PRODUCT
1737 if (st != nullptr) {
1738 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "STXV", Matcher::regName[src_lo], dst_offset);
1739 }
1740 #endif // !PRODUCT
1741 }
1742 // Memory->VectorRegister Spill.
1743 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vec) {
1744 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1745 if (masm) {
1746 __ lxv(Rdst, src_offset, R1_SP);
1747 }
1748 size += 4;
1749 #ifndef PRODUCT
1750 if (st != nullptr) {
1751 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "LXV", Matcher::regName[dst_lo], src_offset);
1752 }
1753 #endif // !PRODUCT
1754 }
1755 // VectorRegister->VectorRegister.
1756 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_vec) {
1757 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1758 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1759 if (masm) {
1760 __ xxlor(Rdst, Rsrc, Rsrc);
1761 }
1762 size += 4;
1763 #ifndef PRODUCT
1764 if (st != nullptr) {
1765 st->print("%-7s %s, %s, %s\t// vector spill copy",
1766 "XXLOR", Matcher::regName[dst_lo], Matcher::regName[src_lo], Matcher::regName[src_lo]);
1767 }
1768 #endif // !PRODUCT
1769 }
1770 else {
1771 ShouldNotReachHere(); // No VR spill.
1772 }
1773 return size;
1774 }
1775
1776 // --------------------------------------
1777 // Memory->Memory Spill. Use R0 to hold the value.
1778 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1779 int src_offset = ra_->reg2offset(src_lo);
1780 int dst_offset = ra_->reg2offset(dst_lo);
1781 if (src_hi != OptoReg::Bad) {
1782 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack,
1783 "expected same type of move for high parts");
1784 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st);
1785 if (!masm && !do_size) st->print("\n\t");
1786 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st);
1787 } else {
1788 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st);
1789 if (!masm && !do_size) st->print("\n\t");
1790 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st);
1791 }
1792 return size;
1793 }
1794
1795 // --------------------------------------
1796 // Check for float->int copy; requires a trip through memory.
1797 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1798 Unimplemented();
1799 }
1800
1801 // --------------------------------------
1802 // Check for integer reg-reg copy.
1803 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1804 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1805 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1806 size = (Rsrc != Rdst) ? 4 : 0;
1807
1808 if (masm) {
1809 if (size) {
1810 __ mr(Rdst, Rsrc);
1811 }
1812 }
1813 #ifndef PRODUCT
1814 else if (!do_size) {
1815 if (size) {
1816 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1817 } else {
1818 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1819 }
1820 }
1821 #endif
1822 return size;
1823 }
1824
1825 // Check for integer store.
1826 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1827 int dst_offset = ra_->reg2offset(dst_lo);
1828 if (src_hi != OptoReg::Bad) {
1829 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack,
1830 "expected same type of move for high parts");
1831 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1832 } else {
1833 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st);
1834 }
1835 return size;
1836 }
1837
1838 // Check for integer load.
1839 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1840 int src_offset = ra_->reg2offset(src_lo);
1841 if (src_hi != OptoReg::Bad) {
1842 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack,
1843 "expected same type of move for high parts");
1844 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1845 } else {
1846 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st);
1847 }
1848 return size;
1849 }
1850
1851 // Check for float reg-reg copy.
1852 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1853 if (masm) {
1854 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]);
1855 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]);
1856 __ fmr(Rdst, Rsrc);
1857 }
1858 #ifndef PRODUCT
1859 else if (!do_size) {
1860 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1861 }
1862 #endif
1863 return 4;
1864 }
1865
1866 // Check for float store.
1867 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1868 int dst_offset = ra_->reg2offset(dst_lo);
1869 if (src_hi != OptoReg::Bad) {
1870 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack,
1871 "expected same type of move for high parts");
1872 size += ld_st_helper(masm, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1873 } else {
1874 size += ld_st_helper(masm, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st);
1875 }
1876 return size;
1877 }
1878
1879 // Check for float load.
1880 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1881 int src_offset = ra_->reg2offset(src_lo);
1882 if (src_hi != OptoReg::Bad) {
1883 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack,
1884 "expected same type of move for high parts");
1885 size += ld_st_helper(masm, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1886 } else {
1887 size += ld_st_helper(masm, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st);
1888 }
1889 return size;
1890 }
1891
1892 // --------------------------------------------------------------------
1893 // Check for hi bits still needing moving. Only happens for misaligned
1894 // arguments to native calls.
1895 if (src_hi == dst_hi)
1896 return size; // Self copy; no move.
1897
1898 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad");
1899 ShouldNotReachHere(); // Unimplemented
1900 return 0;
1901 }
1902
1903 #ifndef PRODUCT
1904 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1905 if (!ra_)
1906 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1907 else
1908 implementation(nullptr, ra_, false, st);
1909 }
1910 #endif
1911
1912 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1913 implementation(masm, ra_, false, nullptr);
1914 }
1915
1916 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1917 return implementation(nullptr, ra_, true, nullptr);
1918 }
1919
1920 #ifndef PRODUCT
1921 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1922 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count);
1923 }
1924 #endif
1925
1926 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *) const {
1927 // _count contains the number of nops needed for padding.
1928 for (int i = 0; i < _count; i++) {
1929 __ nop();
1930 }
1931 }
1932
1933 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
1934 return _count * 4;
1935 }
1936
1937 #ifndef PRODUCT
1938 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1939 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1940 char reg_str[128];
1941 ra_->dump_register(this, reg_str, sizeof(reg_str));
1942 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset);
1943 }
1944 #endif
1945
1946 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1947 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1948 int reg = ra_->get_encode(this);
1949
1950 if (Assembler::is_simm(offset, 16)) {
1951 __ addi(as_Register(reg), R1, offset);
1952 } else {
1953 ShouldNotReachHere();
1954 }
1955 }
1956
1957 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1958 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1959 return 4;
1960 }
1961
1962 #ifndef PRODUCT
1963 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1964 st->print_cr("---- MachUEPNode ----");
1965 st->print_cr("...");
1966 }
1967 #endif
1968
1969 void MachUEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1970 // This is the unverified entry point.
1971 __ ic_check(CodeEntryAlignment);
1972 // Argument is valid and klass is as expected, continue.
1973 }
1974
1975 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1976 // Variable size. Determine dynamically.
1977 return MachNode::size(ra_);
1978 }
1979
1980 //=============================================================================
1981
1982 %} // interrupt source
1983
1984 source_hpp %{ // Header information of the source block.
1985
1986 class HandlerImpl {
1987
1988 public:
1989
1990 static int emit_deopt_handler(C2_MacroAssembler* masm);
1991
1992 static uint size_deopt_handler() {
1993 // The deopt_handler is a bl64_patchable.
1994 return MacroAssembler::bl64_patchable_size + BytesPerInstWord;
1995 }
1996
1997 };
1998
1999 class Node::PD {
2000 public:
2001 enum NodeFlags {
2002 _last_flag = Node::_last_flag
2003 };
2004 };
2005
2006 %} // end source_hpp
2007
2008 source %{
2009
2010 // The deopt_handler is like the exception handler, but it calls to
2011 // the deoptimization blob instead of jumping to the exception blob.
2012 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
2013 address base = __ start_a_stub(size_deopt_handler());
2014 if (base == nullptr) {
2015 ciEnv::current()->record_failure("CodeCache is full");
2016 return 0; // CodeBuffer::expand failed
2017 }
2018
2019 int offset = __ offset();
2020
2021 Label start;
2022 __ bind(start);
2023
2024 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
2025 relocInfo::runtime_call_type);
2026
2027 int entry_offset = __ offset();
2028
2029 __ b(start);
2030
2031 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
2032 assert(__ offset() - entry_offset >= NativePostCallNop::first_check_size,
2033 "out of bounds read in post-call NOP check");
2034 __ end_a_stub();
2035
2036 return entry_offset;
2037 }
2038
2039 //=============================================================================
2040
2041 // Use a frame slots bias for frameless methods if accessing the stack.
2042 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) {
2043 if (as_Register(reg_enc) == R1_SP) {
2044 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes();
2045 }
2046 return 0;
2047 }
2048
2049 bool Matcher::match_rule_supported(int opcode) {
2050 if (!has_match_rule(opcode)) {
2051 return false; // no match rule present
2052 }
2053
2054 switch (opcode) {
2055 case Op_CountLeadingZerosI:
2056 case Op_CountLeadingZerosL:
2057 return UseCountLeadingZerosInstructionsPPC64;
2058 case Op_CountTrailingZerosI:
2059 case Op_CountTrailingZerosL:
2060 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64);
2061 case Op_PopCountI:
2062 case Op_PopCountL:
2063 return UsePopCountInstruction;
2064 case Op_ConvF2HF:
2065 case Op_ConvHF2F:
2066 return VM_Version::supports_float16();
2067 case Op_AddVB:
2068 case Op_AddVS:
2069 case Op_AddVI:
2070 case Op_AddVF:
2071 case Op_AddVD:
2072 case Op_SubVB:
2073 case Op_SubVS:
2074 case Op_SubVI:
2075 case Op_SubVF:
2076 case Op_SubVD:
2077 case Op_MulVS:
2078 case Op_MulVF:
2079 case Op_MulVD:
2080 case Op_DivVF:
2081 case Op_DivVD:
2082 case Op_AbsVF:
2083 case Op_AbsVD:
2084 case Op_NegVI:
2085 case Op_NegVF:
2086 case Op_NegVD:
2087 case Op_SqrtVF:
2088 case Op_SqrtVD:
2089 case Op_AddVL:
2090 case Op_SubVL:
2091 case Op_MulVI:
2092 case Op_RoundDoubleModeV:
2093 case Op_MinV:
2094 case Op_MaxV:
2095 case Op_UMinV:
2096 case Op_UMaxV:
2097 case Op_AndV:
2098 case Op_OrV:
2099 case Op_XorV:
2100 case Op_AddReductionVI:
2101 case Op_MulReductionVI:
2102 case Op_AndReductionV:
2103 case Op_OrReductionV:
2104 case Op_XorReductionV:
2105 case Op_MinReductionV:
2106 case Op_MaxReductionV:
2107 return SuperwordUseVSX;
2108 case Op_PopCountVI:
2109 case Op_PopCountVL:
2110 return (SuperwordUseVSX && UsePopCountInstruction);
2111 case Op_CountLeadingZerosV:
2112 return SuperwordUseVSX && UseCountLeadingZerosInstructionsPPC64;
2113 case Op_CountTrailingZerosV:
2114 return SuperwordUseVSX && UseCountTrailingZerosInstructionsPPC64;
2115 case Op_FmaF:
2116 case Op_FmaD:
2117 return UseFMA;
2118 case Op_FmaVF:
2119 case Op_FmaVD:
2120 return (SuperwordUseVSX && UseFMA);
2121
2122 case Op_MinF:
2123 case Op_MaxF:
2124 case Op_MinD:
2125 case Op_MaxD:
2126 return (PowerArchitecturePPC64 >= 9);
2127
2128 case Op_Digit:
2129 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit);
2130 case Op_LowerCase:
2131 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase);
2132 case Op_UpperCase:
2133 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase);
2134 case Op_Whitespace:
2135 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace);
2136
2137 case Op_CacheWB:
2138 case Op_CacheWBPreSync:
2139 case Op_CacheWBPostSync:
2140 return VM_Version::supports_data_cache_line_flush();
2141
2142 case Op_OnSpinWait:
2143 return VM_Version::supports_on_spin_wait();
2144 }
2145
2146 return true; // Per default match rules are supported.
2147 }
2148
2149 bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
2150 return match_rule_supported_vector(opcode, vlen, bt);
2151 }
2152
2153 bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
2154 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
2155 return false;
2156 }
2157 // Special cases
2158 switch (opcode) {
2159 // Reductions only support INT at the moment.
2160 case Op_AddReductionVI:
2161 case Op_MulReductionVI:
2162 case Op_AndReductionV:
2163 case Op_OrReductionV:
2164 case Op_XorReductionV:
2165 case Op_MinReductionV:
2166 case Op_MaxReductionV:
2167 return bt == T_INT;
2168 // MaxV, MinV need types == INT || LONG.
2169 case Op_MaxV:
2170 case Op_MinV:
2171 case Op_UMinV:
2172 case Op_UMaxV:
2173 return bt == T_INT || bt == T_LONG;
2174 case Op_NegVI:
2175 return bt == T_INT;
2176 }
2177 return true; // Per default match rules are supported.
2178 }
2179
2180 bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
2181 return false;
2182 }
2183
2184 bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
2185 return false;
2186 }
2187
2188 bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
2189 return false;
2190 }
2191
2192 bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
2193 return false;
2194 }
2195
2196 const RegMask* Matcher::predicate_reg_mask(void) {
2197 return nullptr;
2198 }
2199
2200 // Vector calling convention not yet implemented.
2201 bool Matcher::supports_vector_calling_convention(void) {
2202 return false;
2203 }
2204
2205 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2206 Unimplemented();
2207 return OptoRegPair(0, 0);
2208 }
2209
2210 // Vector width in bytes.
2211 int Matcher::vector_width_in_bytes(BasicType bt) {
2212 if (SuperwordUseVSX) {
2213 assert(MaxVectorSize == 16,
2214 "SuperwordUseVSX requires MaxVectorSize 16, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2215 return 16;
2216 } else {
2217 assert(MaxVectorSize == 8,
2218 "expected MaxVectorSize 8, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2219 return 8;
2220 }
2221 }
2222
2223 // Vector ideal reg.
2224 uint Matcher::vector_ideal_reg(int size) {
2225 if (SuperwordUseVSX) {
2226 assert(MaxVectorSize == 16 && size == 16,
2227 "SuperwordUseVSX requires MaxVectorSize 16 and size 16, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2228 (int64_t)MaxVectorSize, size);
2229 return Op_VecX;
2230 } else {
2231 assert(MaxVectorSize == 8 && size == 8,
2232 "expected MaxVectorSize 8 and size 8, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2233 (int64_t)MaxVectorSize, size);
2234 return Op_RegL;
2235 }
2236 }
2237
2238 // Limits on vector size (number of elements) loaded into vector.
2239 int Matcher::max_vector_size(const BasicType bt) {
2240 assert(is_java_primitive(bt), "only primitive type vectors");
2241 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2242 }
2243
2244 int Matcher::min_vector_size(const BasicType bt) {
2245 return max_vector_size(bt); // Same as max.
2246 }
2247
2248 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
2249 return Matcher::max_vector_size(bt);
2250 }
2251
2252 int Matcher::scalable_vector_reg_size(const BasicType bt) {
2253 return -1;
2254 }
2255
2256 // RETURNS: whether this branch offset is short enough that a short
2257 // branch can be used.
2258 //
2259 // If the platform does not provide any short branch variants, then
2260 // this method should return `false' for offset 0.
2261 //
2262 // `Compile::Fill_buffer' will decide on basis of this information
2263 // whether to do the pass `Compile::Shorten_branches' at all.
2264 //
2265 // And `Compile::Shorten_branches' will decide on basis of this
2266 // information whether to replace particular branch sites by short
2267 // ones.
2268 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2269 // Is the offset within the range of a ppc64 pc relative branch?
2270 bool b;
2271
2272 const int safety_zone = 3 * BytesPerInstWord;
2273 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2274 29 - 16 + 1 + 2);
2275 return b;
2276 }
2277
2278 /* TODO: PPC port
2279 // Make a new machine dependent decode node (with its operands).
2280 MachTypeNode *Matcher::make_decode_node() {
2281 assert(CompressedOops::base() == nullptr && CompressedOops::shift() == 0,
2282 "This method is only implemented for unscaled cOops mode so far");
2283 MachTypeNode *decode = new decodeN_unscaledNode();
2284 decode->set_opnd_array(0, new iRegPdstOper());
2285 decode->set_opnd_array(1, new iRegNsrcOper());
2286 return decode;
2287 }
2288 */
2289
2290 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
2291 ShouldNotReachHere(); // generic vector operands not supported
2292 return nullptr;
2293 }
2294
2295 bool Matcher::is_reg2reg_move(MachNode* m) {
2296 ShouldNotReachHere(); // generic vector operands not supported
2297 return false;
2298 }
2299
2300 bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
2301 return false;
2302 }
2303
2304 bool Matcher::is_generic_vector(MachOper* opnd) {
2305 ShouldNotReachHere(); // generic vector operands not supported
2306 return false;
2307 }
2308
2309 #ifdef ASSERT
2310 // Return whether or not this register is ever used as an argument.
2311 bool Matcher::can_be_java_arg(int reg) {
2312 // We must include the virtual halves in order to get STDs and LDs
2313 // instead of STWs and LWs in the trampoline stubs.
2314
2315 if ( reg == R3_num || reg == R3_H_num
2316 || reg == R4_num || reg == R4_H_num
2317 || reg == R5_num || reg == R5_H_num
2318 || reg == R6_num || reg == R6_H_num
2319 || reg == R7_num || reg == R7_H_num
2320 || reg == R8_num || reg == R8_H_num
2321 || reg == R9_num || reg == R9_H_num
2322 || reg == R10_num || reg == R10_H_num)
2323 return true;
2324
2325 if ( reg == F1_num || reg == F1_H_num
2326 || reg == F2_num || reg == F2_H_num
2327 || reg == F3_num || reg == F3_H_num
2328 || reg == F4_num || reg == F4_H_num
2329 || reg == F5_num || reg == F5_H_num
2330 || reg == F6_num || reg == F6_H_num
2331 || reg == F7_num || reg == F7_H_num
2332 || reg == F8_num || reg == F8_H_num
2333 || reg == F9_num || reg == F9_H_num
2334 || reg == F10_num || reg == F10_H_num
2335 || reg == F11_num || reg == F11_H_num
2336 || reg == F12_num || reg == F12_H_num
2337 || reg == F13_num || reg == F13_H_num)
2338 return true;
2339
2340 return false;
2341 }
2342 #endif
2343
2344 uint Matcher::int_pressure_limit()
2345 {
2346 return (INTPRESSURE == -1) ? 26 : INTPRESSURE;
2347 }
2348
2349 uint Matcher::float_pressure_limit()
2350 {
2351 return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE;
2352 }
2353
2354 // Register for the first projection of an int pair
2355 const RegMask& Matcher::firstI_proj_mask() {
2356 ShouldNotReachHere();
2357 return RegMask::EMPTY;
2358 }
2359
2360 // Register for the second projection of an int pair
2361 const RegMask& Matcher::secondI_proj_mask() {
2362 ShouldNotReachHere();
2363 return RegMask::EMPTY;
2364 }
2365
2366 // Register for the first projection of a long pair
2367 const RegMask& Matcher::firstL_proj_mask() {
2368 ShouldNotReachHere();
2369 return RegMask::EMPTY;
2370 }
2371
2372 // Register for the second projection of a long pair
2373 const RegMask& Matcher::secondL_proj_mask() {
2374 ShouldNotReachHere();
2375 return RegMask::EMPTY;
2376 }
2377
2378 %}
2379
2380 //----------ENCODING BLOCK-----------------------------------------------------
2381 // This block specifies the encoding classes used by the compiler to output
2382 // byte streams. Encoding classes are parameterized macros used by
2383 // Machine Instruction Nodes in order to generate the bit encoding of the
2384 // instruction. Operands specify their base encoding interface with the
2385 // interface keyword. There are currently supported four interfaces,
2386 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
2387 // operand to generate a function which returns its register number when
2388 // queried. CONST_INTER causes an operand to generate a function which
2389 // returns the value of the constant when queried. MEMORY_INTER causes an
2390 // operand to generate four functions which return the Base Register, the
2391 // Index Register, the Scale Value, and the Offset Value of the operand when
2392 // queried. COND_INTER causes an operand to generate six functions which
2393 // return the encoding code (ie - encoding bits for the instruction)
2394 // associated with each basic boolean condition for a conditional instruction.
2395 //
2396 // Instructions specify two basic values for encoding. Again, a function
2397 // is available to check if the constant displacement is an oop. They use the
2398 // ins_encode keyword to specify their encoding classes (which must be
2399 // a sequence of enc_class names, and their parameters, specified in
2400 // the encoding block), and they use the
2401 // opcode keyword to specify, in order, their primary, secondary, and
2402 // tertiary opcode. Only the opcode sections which a particular instruction
2403 // needs for encoding need to be specified.
2404 encode %{
2405 enc_class enc_unimplemented %{
2406 __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
2407 %}
2408
2409 enc_class enc_untested %{
2410 #ifdef ASSERT
2411 __ untested("Untested mach node encoding in AD file.");
2412 #else
2413 #endif
2414 %}
2415
2416 enc_class enc_lbz(iRegIdst dst, memory mem) %{
2417 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2418 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2419 %}
2420
2421 // Load acquire.
2422 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
2423 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2424 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2425 __ twi_0($dst$$Register);
2426 __ isync();
2427 %}
2428
2429 enc_class enc_lhz(iRegIdst dst, memory mem) %{
2430 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2431 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2432 %}
2433
2434 // Load acquire.
2435 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
2436 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2437 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2438 __ twi_0($dst$$Register);
2439 __ isync();
2440 %}
2441
2442 enc_class enc_lwz(iRegIdst dst, memory mem) %{
2443 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2444 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2445 %}
2446
2447 // Load acquire.
2448 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
2449 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2450 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2451 __ twi_0($dst$$Register);
2452 __ isync();
2453 %}
2454
2455 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
2456 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2457 // Operand 'ds' requires 4-alignment.
2458 assert((Idisp & 0x3) == 0, "unaligned offset");
2459 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2460 %}
2461
2462 // Load acquire.
2463 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
2464 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2465 // Operand 'ds' requires 4-alignment.
2466 assert((Idisp & 0x3) == 0, "unaligned offset");
2467 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2468 __ twi_0($dst$$Register);
2469 __ isync();
2470 %}
2471
2472 enc_class enc_lfd(RegF dst, memory mem) %{
2473 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2474 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2475 %}
2476
2477 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2478 int toc_offset = 0;
2479
2480 address const_toc_addr;
2481 // Create a non-oop constant, no relocation needed.
2482 // If it is an IC, it has a virtual_call_Relocation.
2483 const_toc_addr = __ long_constant((jlong)$src$$constant);
2484 if (const_toc_addr == nullptr) {
2485 ciEnv::current()->record_out_of_memory_failure();
2486 return;
2487 }
2488
2489 // Get the constant's TOC offset.
2490 toc_offset = __ offset_to_method_toc(const_toc_addr);
2491
2492 // Keep the current instruction offset in mind.
2493 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2494
2495 __ ld($dst$$Register, toc_offset, $toc$$Register);
2496 %}
2497
2498 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2499 if (!ra_->C->output()->in_scratch_emit_size()) {
2500 address const_toc_addr;
2501 // Create a non-oop constant, no relocation needed.
2502 // If it is an IC, it has a virtual_call_Relocation.
2503 const_toc_addr = __ long_constant((jlong)$src$$constant);
2504 if (const_toc_addr == nullptr) {
2505 ciEnv::current()->record_out_of_memory_failure();
2506 return;
2507 }
2508
2509 // Get the constant's TOC offset.
2510 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2511 // Store the toc offset of the constant.
2512 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2513
2514 // Also keep the current instruction offset in mind.
2515 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2516 }
2517
2518 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2519 %}
2520
2521 %} // encode
2522
2523 source %{
2524
2525 typedef struct {
2526 loadConL_hiNode *_large_hi;
2527 loadConL_loNode *_large_lo;
2528 loadConLNode *_small;
2529 MachNode *_last;
2530 } loadConLNodesTuple;
2531
2532 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2533 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2534 loadConLNodesTuple nodes;
2535
2536 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2537 if (large_constant_pool) {
2538 // Create new nodes.
2539 loadConL_hiNode *m1 = new loadConL_hiNode();
2540 loadConL_loNode *m2 = new loadConL_loNode();
2541
2542 // inputs for new nodes
2543 m1->add_req(nullptr, toc);
2544 m2->add_req(nullptr, m1);
2545
2546 // operands for new nodes
2547 m1->_opnds[0] = new iRegLdstOper(); // dst
2548 m1->_opnds[1] = immSrc; // src
2549 m1->_opnds[2] = new iRegLdstOper(); // toc
2550 m2->_opnds[0] = new iRegLdstOper(); // dst
2551 m2->_opnds[1] = immSrc; // src
2552 m2->_opnds[2] = new iRegLdstOper(); // base
2553
2554 // Initialize ins_attrib TOC fields.
2555 m1->_const_toc_offset = -1;
2556 m2->_const_toc_offset_hi_node = m1;
2557
2558 // Initialize ins_attrib instruction offset.
2559 m1->_cbuf_insts_offset = -1;
2560
2561 // register allocation for new nodes
2562 ra_->set_pair(m1->_idx, reg_second, reg_first);
2563 ra_->set_pair(m2->_idx, reg_second, reg_first);
2564
2565 // Create result.
2566 nodes._large_hi = m1;
2567 nodes._large_lo = m2;
2568 nodes._small = nullptr;
2569 nodes._last = nodes._large_lo;
2570 assert(m2->bottom_type()->isa_long(), "must be long");
2571 } else {
2572 loadConLNode *m2 = new loadConLNode();
2573
2574 // inputs for new nodes
2575 m2->add_req(nullptr, toc);
2576
2577 // operands for new nodes
2578 m2->_opnds[0] = new iRegLdstOper(); // dst
2579 m2->_opnds[1] = immSrc; // src
2580 m2->_opnds[2] = new iRegLdstOper(); // toc
2581
2582 // Initialize ins_attrib instruction offset.
2583 m2->_cbuf_insts_offset = -1;
2584
2585 // register allocation for new nodes
2586 ra_->set_pair(m2->_idx, reg_second, reg_first);
2587
2588 // Create result.
2589 nodes._large_hi = nullptr;
2590 nodes._large_lo = nullptr;
2591 nodes._small = m2;
2592 nodes._last = nodes._small;
2593 assert(m2->bottom_type()->isa_long(), "must be long");
2594 }
2595
2596 return nodes;
2597 }
2598
2599 typedef struct {
2600 loadConL_hiNode *_large_hi;
2601 loadConL_loNode *_large_lo;
2602 mtvsrdNode *_moved;
2603 xxspltdNode *_replicated;
2604 loadConLNode *_small;
2605 MachNode *_last;
2606 } loadConLReplicatedNodesTuple;
2607
2608 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2609 vecXOper *dst, immI_0Oper *zero,
2610 OptoReg::Name reg_second, OptoReg::Name reg_first,
2611 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) {
2612 loadConLReplicatedNodesTuple nodes;
2613
2614 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2615 if (large_constant_pool) {
2616 // Create new nodes.
2617 loadConL_hiNode *m1 = new loadConL_hiNode();
2618 loadConL_loNode *m2 = new loadConL_loNode();
2619 mtvsrdNode *m3 = new mtvsrdNode();
2620 xxspltdNode *m4 = new xxspltdNode();
2621
2622 // inputs for new nodes
2623 m1->add_req(nullptr, toc);
2624 m2->add_req(nullptr, m1);
2625 m3->add_req(nullptr, m2);
2626 m4->add_req(nullptr, m3);
2627
2628 // operands for new nodes
2629 m1->_opnds[0] = new iRegLdstOper(); // dst
2630 m1->_opnds[1] = immSrc; // src
2631 m1->_opnds[2] = new iRegLdstOper(); // toc
2632
2633 m2->_opnds[0] = new iRegLdstOper(); // dst
2634 m2->_opnds[1] = immSrc; // src
2635 m2->_opnds[2] = new iRegLdstOper(); // base
2636
2637 m3->_opnds[0] = new vecXOper(); // dst
2638 m3->_opnds[1] = new iRegLdstOper(); // src
2639
2640 m4->_opnds[0] = new vecXOper(); // dst
2641 m4->_opnds[1] = new vecXOper(); // src
2642 m4->_opnds[2] = zero;
2643
2644 // Initialize ins_attrib TOC fields.
2645 m1->_const_toc_offset = -1;
2646 m2->_const_toc_offset_hi_node = m1;
2647
2648 // Initialize ins_attrib instruction offset.
2649 m1->_cbuf_insts_offset = -1;
2650
2651 // register allocation for new nodes
2652 ra_->set_pair(m1->_idx, reg_second, reg_first);
2653 ra_->set_pair(m2->_idx, reg_second, reg_first);
2654 ra_->set1(m3->_idx, reg_second);
2655 ra_->set2(m3->_idx, reg_vec_first);
2656 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2657
2658 // Create result.
2659 nodes._large_hi = m1;
2660 nodes._large_lo = m2;
2661 nodes._moved = m3;
2662 nodes._replicated = m4;
2663 nodes._small = nullptr;
2664 nodes._last = nodes._replicated;
2665 assert(m2->bottom_type()->isa_long(), "must be long");
2666 } else {
2667 loadConLNode *m2 = new loadConLNode();
2668 mtvsrdNode *m3 = new mtvsrdNode();
2669 xxspltdNode *m4 = new xxspltdNode();
2670
2671 // inputs for new nodes
2672 m2->add_req(nullptr, toc);
2673
2674 // operands for new nodes
2675 m2->_opnds[0] = new iRegLdstOper(); // dst
2676 m2->_opnds[1] = immSrc; // src
2677 m2->_opnds[2] = new iRegLdstOper(); // toc
2678
2679 m3->_opnds[0] = new vecXOper(); // dst
2680 m3->_opnds[1] = new iRegLdstOper(); // src
2681
2682 m4->_opnds[0] = new vecXOper(); // dst
2683 m4->_opnds[1] = new vecXOper(); // src
2684 m4->_opnds[2] = zero;
2685
2686 // Initialize ins_attrib instruction offset.
2687 m2->_cbuf_insts_offset = -1;
2688 ra_->set1(m3->_idx, reg_second);
2689 ra_->set2(m3->_idx, reg_vec_first);
2690 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2691
2692 // register allocation for new nodes
2693 ra_->set_pair(m2->_idx, reg_second, reg_first);
2694
2695 // Create result.
2696 nodes._large_hi = nullptr;
2697 nodes._large_lo = nullptr;
2698 nodes._small = m2;
2699 nodes._moved = m3;
2700 nodes._replicated = m4;
2701 nodes._last = nodes._replicated;
2702 assert(m2->bottom_type()->isa_long(), "must be long");
2703 }
2704
2705 return nodes;
2706 }
2707
2708 %} // source
2709
2710 encode %{
2711 // Postalloc expand emitter for loading a long constant from the method's TOC.
2712 // Enc_class needed as consttanttablebase is not supported by postalloc
2713 // expand.
2714 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2715 // Create new nodes.
2716 loadConLNodesTuple loadConLNodes =
2717 loadConLNodesTuple_create(ra_, n_toc, op_src,
2718 ra_->get_reg_second(this), ra_->get_reg_first(this));
2719
2720 // Push new nodes.
2721 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2722 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2723
2724 // some asserts
2725 assert(nodes->length() >= 1, "must have created at least 1 node");
2726 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2727 %}
2728
2729 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2730 int toc_offset = 0;
2731
2732 intptr_t val = $src$$constant;
2733 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2734 address const_toc_addr;
2735 RelocationHolder r; // Initializes type to none.
2736 if (constant_reloc == relocInfo::oop_type) {
2737 // Create an oop constant and a corresponding relocation.
2738 AddressLiteral a = __ constant_oop_address((jobject)val);
2739 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2740 r = a.rspec();
2741 } else if (constant_reloc == relocInfo::metadata_type) {
2742 // Notify OOP recorder (don't need the relocation)
2743 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2744 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2745 } else {
2746 // Create a non-oop constant, no relocation needed.
2747 const_toc_addr = __ long_constant((jlong)$src$$constant);
2748 }
2749
2750 if (const_toc_addr == nullptr) {
2751 ciEnv::current()->record_out_of_memory_failure();
2752 return;
2753 }
2754 __ relocate(r); // If set above.
2755 // Get the constant's TOC offset.
2756 toc_offset = __ offset_to_method_toc(const_toc_addr);
2757
2758 __ ld($dst$$Register, toc_offset, $toc$$Register);
2759 %}
2760
2761 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2762 if (!ra_->C->output()->in_scratch_emit_size()) {
2763 intptr_t val = $src$$constant;
2764 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2765 address const_toc_addr;
2766 RelocationHolder r; // Initializes type to none.
2767 if (constant_reloc == relocInfo::oop_type) {
2768 // Create an oop constant and a corresponding relocation.
2769 AddressLiteral a = __ constant_oop_address((jobject)val);
2770 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2771 r = a.rspec();
2772 } else if (constant_reloc == relocInfo::metadata_type) {
2773 // Notify OOP recorder (don't need the relocation)
2774 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2775 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2776 } else { // non-oop pointers, e.g. card mark base, heap top
2777 // Create a non-oop constant, no relocation needed.
2778 const_toc_addr = __ long_constant((jlong)$src$$constant);
2779 }
2780
2781 if (const_toc_addr == nullptr) {
2782 ciEnv::current()->record_out_of_memory_failure();
2783 return;
2784 }
2785 __ relocate(r); // If set above.
2786 // Get the constant's TOC offset.
2787 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2788 // Store the toc offset of the constant.
2789 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2790 }
2791
2792 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2793 %}
2794
2795 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2796 // Enc_class needed as consttanttablebase is not supported by postalloc
2797 // expand.
2798 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2799 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2800 if (large_constant_pool) {
2801 // Create new nodes.
2802 loadConP_hiNode *m1 = new loadConP_hiNode();
2803 loadConP_loNode *m2 = new loadConP_loNode();
2804
2805 // If this is an oop, both m1 and m2 must be consider oops so postalloc scheduling does not
2806 // put a safepoint between them
2807 m1->_bottom_type = bottom_type();
2808 m2->_bottom_type = bottom_type();
2809
2810 // inputs for new nodes
2811 m1->add_req(nullptr, n_toc);
2812 m2->add_req(nullptr, m1);
2813
2814 // operands for new nodes
2815 m1->_opnds[0] = new iRegPdstOper(); // dst
2816 m1->_opnds[1] = op_src; // src
2817 m1->_opnds[2] = new iRegLdstOper(); // toc
2818
2819 m2->_opnds[0] = new iRegPdstOper(); // dst
2820 m2->_opnds[1] = op_src; // src
2821 m2->_opnds[2] = new iRegLdstOper(); // base
2822
2823 // Initialize ins_attrib TOC fields.
2824 m1->_const_toc_offset = -1;
2825 m2->_const_toc_offset_hi_node = m1;
2826
2827 // Register allocation for new nodes.
2828 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2829 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2830
2831 nodes->push(m1);
2832 nodes->push(m2);
2833 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2834 } else {
2835 loadConPNode *m2 = new loadConPNode();
2836
2837 // inputs for new nodes
2838 m2->add_req(nullptr, n_toc);
2839
2840 // operands for new nodes
2841 m2->_opnds[0] = new iRegPdstOper(); // dst
2842 m2->_opnds[1] = op_src; // src
2843 m2->_opnds[2] = new iRegLdstOper(); // toc
2844
2845 // Register allocation for new nodes.
2846 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2847
2848 nodes->push(m2);
2849 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2850 }
2851 %}
2852
2853 // Enc_class needed as consttanttablebase is not supported by postalloc
2854 // expand.
2855 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2856 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2857
2858 MachNode *m2;
2859 if (large_constant_pool) {
2860 m2 = new loadConFCompNode();
2861 } else {
2862 m2 = new loadConFNode();
2863 }
2864 // inputs for new nodes
2865 m2->add_req(nullptr, n_toc);
2866
2867 // operands for new nodes
2868 m2->_opnds[0] = op_dst;
2869 m2->_opnds[1] = op_src;
2870 m2->_opnds[2] = new iRegLdstOper(); // constanttablebase
2871
2872 // register allocation for new nodes
2873 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2874 nodes->push(m2);
2875 %}
2876
2877 // Enc_class needed as consttanttablebase is not supported by postalloc
2878 // expand.
2879 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2880 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2881
2882 MachNode *m2;
2883 if (large_constant_pool) {
2884 m2 = new loadConDCompNode();
2885 } else {
2886 m2 = new loadConDNode();
2887 }
2888 // inputs for new nodes
2889 m2->add_req(nullptr, n_toc);
2890
2891 // operands for new nodes
2892 m2->_opnds[0] = op_dst;
2893 m2->_opnds[1] = op_src;
2894 m2->_opnds[2] = new iRegLdstOper(); // constanttablebase
2895
2896 // register allocation for new nodes
2897 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2898 nodes->push(m2);
2899 %}
2900
2901 enc_class enc_stw(iRegIsrc src, memory mem) %{
2902 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2903 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2904 %}
2905
2906 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2907 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2908 // Operand 'ds' requires 4-alignment.
2909 assert((Idisp & 0x3) == 0, "unaligned offset");
2910 __ std($src$$Register, Idisp, $mem$$base$$Register);
2911 %}
2912
2913 enc_class enc_stfs(RegF src, memory mem) %{
2914 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2915 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2916 %}
2917
2918 enc_class enc_stfd(RegF src, memory mem) %{
2919 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2920 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2921 %}
2922
2923 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2924 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
2925 encodeP_subNode *n_sub_base = new encodeP_subNode();
2926 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
2927 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode();
2928
2929 n_compare->add_req(n_region, n_src);
2930 n_compare->_opnds[0] = op_crx;
2931 n_compare->_opnds[1] = op_src;
2932 n_compare->_opnds[2] = new immL16Oper(0);
2933
2934 n_sub_base->add_req(n_region, n_src);
2935 n_sub_base->_opnds[0] = op_dst;
2936 n_sub_base->_opnds[1] = op_src;
2937 n_sub_base->_bottom_type = _bottom_type;
2938
2939 n_shift->add_req(n_region, n_sub_base);
2940 n_shift->_opnds[0] = op_dst;
2941 n_shift->_opnds[1] = op_dst;
2942 n_shift->_bottom_type = _bottom_type;
2943
2944 n_cond_set->add_req(n_region, n_compare, n_shift);
2945 n_cond_set->_opnds[0] = op_dst;
2946 n_cond_set->_opnds[1] = op_crx;
2947 n_cond_set->_opnds[2] = op_dst;
2948 n_cond_set->_bottom_type = _bottom_type;
2949
2950 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2951 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2952 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2953 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2954
2955 nodes->push(n_compare);
2956 nodes->push(n_sub_base);
2957 nodes->push(n_shift);
2958 nodes->push(n_cond_set);
2959
2960 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2961 %}
2962
2963 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
2964
2965 encodeP_subNode *n1 = new encodeP_subNode();
2966 n1->add_req(n_region, n_src);
2967 n1->_opnds[0] = op_dst;
2968 n1->_opnds[1] = op_src;
2969 n1->_bottom_type = _bottom_type;
2970
2971 encodeP_shiftNode *n2 = new encodeP_shiftNode();
2972 n2->add_req(n_region, n1);
2973 n2->_opnds[0] = op_dst;
2974 n2->_opnds[1] = op_dst;
2975 n2->_bottom_type = _bottom_type;
2976 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2977 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2978
2979 nodes->push(n1);
2980 nodes->push(n2);
2981 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2982 %}
2983
2984 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
2985 decodeN_shiftNode *n_shift = new decodeN_shiftNode();
2986 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
2987
2988 n_compare->add_req(n_region, n_src);
2989 n_compare->_opnds[0] = op_crx;
2990 n_compare->_opnds[1] = op_src;
2991 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
2992
2993 n_shift->add_req(n_region, n_src);
2994 n_shift->_opnds[0] = op_dst;
2995 n_shift->_opnds[1] = op_src;
2996 n_shift->_bottom_type = _bottom_type;
2997
2998 decodeN_addNode *n_add_base = new decodeN_addNode();
2999 n_add_base->add_req(n_region, n_shift);
3000 n_add_base->_opnds[0] = op_dst;
3001 n_add_base->_opnds[1] = op_dst;
3002 n_add_base->_bottom_type = _bottom_type;
3003
3004 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
3005 n_cond_set->add_req(n_region, n_compare, n_add_base);
3006 n_cond_set->_opnds[0] = op_dst;
3007 n_cond_set->_opnds[1] = op_crx;
3008 n_cond_set->_opnds[2] = op_dst;
3009 n_cond_set->_bottom_type = _bottom_type;
3010
3011 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3012 ra_->set_oop(n_cond_set, true);
3013
3014 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3015 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3016 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3017 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3018
3019 nodes->push(n_compare);
3020 nodes->push(n_shift);
3021 nodes->push(n_add_base);
3022 nodes->push(n_cond_set);
3023
3024 %}
3025
3026 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3027 decodeN_shiftNode *n1 = new decodeN_shiftNode();
3028 n1->add_req(n_region, n_src);
3029 n1->_opnds[0] = op_dst;
3030 n1->_opnds[1] = op_src;
3031 n1->_bottom_type = _bottom_type;
3032
3033 decodeN_addNode *n2 = new decodeN_addNode();
3034 n2->add_req(n_region, n1);
3035 n2->_opnds[0] = op_dst;
3036 n2->_opnds[1] = op_dst;
3037 n2->_bottom_type = _bottom_type;
3038 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3039 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3040
3041 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3042 ra_->set_oop(n2, true);
3043
3044 nodes->push(n1);
3045 nodes->push(n2);
3046 %}
3047
3048
3049 // This enc_class is needed so that scheduler gets proper
3050 // input mapping for latency computation.
3051 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
3052 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
3053 %}
3054
3055 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3056 Label done;
3057 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3058 __ li($dst$$Register, $zero$$constant);
3059 __ beq($crx$$CondRegister, done);
3060 __ li($dst$$Register, $notzero$$constant);
3061 __ bind(done);
3062 %}
3063
3064 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3065 Label done;
3066 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3067 __ li($dst$$Register, $zero$$constant);
3068 __ beq($crx$$CondRegister, done);
3069 __ li($dst$$Register, $notzero$$constant);
3070 __ bind(done);
3071 %}
3072
3073 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3074 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3075 Label done;
3076 __ bso($crx$$CondRegister, done);
3077 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3078 __ bind(done);
3079 %}
3080
3081 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3082 Label d; // dummy
3083 __ bind(d);
3084 Label* p = ($lbl$$label);
3085 // `p' is `nullptr' when this encoding class is used only to
3086 // determine the size of the encoded instruction.
3087 Label& l = (nullptr == p)? d : *(p);
3088 int cc = $cmp$$cmpcode;
3089 int flags_reg = $crx$$reg;
3090 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3091 int bhint = Assembler::bhintNoHint;
3092
3093 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3094 if (_prob <= PROB_NEVER) {
3095 bhint = Assembler::bhintIsNotTaken;
3096 } else if (_prob >= PROB_ALWAYS) {
3097 bhint = Assembler::bhintIsTaken;
3098 }
3099 }
3100
3101 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3102 cc_to_biint(cc, flags_reg),
3103 l);
3104 %}
3105
3106 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3107 // The scheduler doesn't know about branch shortening, so we set the opcode
3108 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3109 Label d; // dummy
3110 __ bind(d);
3111 Label* p = ($lbl$$label);
3112 // `p' is `nullptr' when this encoding class is used only to
3113 // determine the size of the encoded instruction.
3114 Label& l = (nullptr == p)? d : *(p);
3115 int cc = $cmp$$cmpcode;
3116 int flags_reg = $crx$$reg;
3117 int bhint = Assembler::bhintNoHint;
3118
3119 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3120 if (_prob <= PROB_NEVER) {
3121 bhint = Assembler::bhintIsNotTaken;
3122 } else if (_prob >= PROB_ALWAYS) {
3123 bhint = Assembler::bhintIsTaken;
3124 }
3125 }
3126
3127 // Tell the conditional far branch to optimize itself when being relocated.
3128 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3129 cc_to_biint(cc, flags_reg),
3130 l,
3131 MacroAssembler::bc_far_optimize_on_relocate);
3132 %}
3133
3134 // Postalloc expand emitter for loading a replicatef float constant from
3135 // the method's TOC.
3136 // Enc_class needed as consttanttablebase is not supported by postalloc
3137 // expand.
3138 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3139 // Create new nodes.
3140
3141 // Make an operand with the bit pattern to load as float.
3142 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3143
3144 loadConLNodesTuple loadConLNodes =
3145 loadConLNodesTuple_create(ra_, n_toc, op_repl,
3146 ra_->get_reg_second(this), ra_->get_reg_first(this));
3147
3148 // Push new nodes.
3149 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3150 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3151
3152 assert(nodes->length() >= 1, "must have created at least 1 node");
3153 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3154 %}
3155
3156 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{
3157 // Create new nodes.
3158
3159 // Make an operand with the bit pattern to load as float.
3160 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3161 immI_0Oper *op_zero = new immI_0Oper(0);
3162
3163 loadConLReplicatedNodesTuple loadConLNodes =
3164 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero,
3165 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp),
3166 ra_->get_reg_second(this), ra_->get_reg_first(this));
3167
3168 // Push new nodes.
3169 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); }
3170 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); }
3171 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); }
3172 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); }
3173
3174 assert(nodes->length() >= 1, "must have created at least 1 node");
3175 %}
3176
3177 // This enc_class is needed so that scheduler gets proper
3178 // input mapping for latency computation.
3179 enc_class enc_poll(immI dst, iRegLdst poll) %{
3180 // Fake operand dst needed for PPC scheduler.
3181 assert($dst$$constant == 0x0, "dst must be 0x0");
3182
3183 // Mark the code position where the load from the safepoint
3184 // polling page was emitted as relocInfo::poll_type.
3185 __ relocate(relocInfo::poll_type);
3186 __ load_from_polling_page($poll$$Register);
3187 %}
3188
3189 // A Java static call or a runtime call.
3190 //
3191 // Branch-and-link relative to a trampoline.
3192 // The trampoline loads the target address and does a long branch to there.
3193 // In case we call java, the trampoline branches to a interpreter_stub
3194 // which loads the inline cache and the real call target from the constant pool.
3195 //
3196 // This basically looks like this:
3197 //
3198 // >>>> consts -+ -+
3199 // | |- offset1
3200 // [call target1] | <-+
3201 // [IC cache] |- offset2
3202 // [call target2] <--+
3203 //
3204 // <<<< consts
3205 // >>>> insts
3206 //
3207 // bl offset16 -+ -+ ??? // How many bits available?
3208 // | |
3209 // <<<< insts | |
3210 // >>>> stubs | |
3211 // | |- trampoline_stub_Reloc
3212 // trampoline stub: | <-+
3213 // r2 = toc |
3214 // r2 = [r2 + offset1] | // Load call target1 from const section
3215 // mtctr r2 |
3216 // bctr |- static_stub_Reloc
3217 // comp_to_interp_stub: <---+
3218 // r1 = toc
3219 // ICreg = [r1 + IC_offset] // Load IC from const section
3220 // r1 = [r1 + offset2] // Load call target2 from const section
3221 // mtctr r1
3222 // bctr
3223 //
3224 // <<<< stubs
3225 //
3226 // The call instruction in the code either
3227 // - Branches directly to a compiled method if the offset is encodable in instruction.
3228 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3229 // - Branches to the compiled_to_interp stub if the target is interpreted.
3230 //
3231 // Further there are three relocations from the loads to the constants in
3232 // the constant section.
3233 //
3234 // Usage of r1 and r2 in the stubs allows to distinguish them.
3235 enc_class enc_java_static_call(method meth) %{
3236 address entry_point = (address)$meth$$method;
3237 address call_pc;
3238
3239 if (!_method) {
3240 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3241 call_pc = __ trampoline_call(AddressLiteral(entry_point, relocInfo::runtime_call_type));
3242 if (call_pc == nullptr) {
3243 ciEnv::current()->record_failure("CodeCache is full");
3244 return;
3245 }
3246 } else {
3247 int method_index = resolved_method_index(masm);
3248 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3249 : static_call_Relocation::spec(method_index);
3250 call_pc = __ trampoline_call(AddressLiteral(entry_point, rspec));
3251 if (call_pc == nullptr) {
3252 ciEnv::current()->record_failure("CodeCache is full");
3253 return;
3254 }
3255
3256 // Emit stub for static call
3257 address stub = CompiledDirectCall::emit_to_interp_stub(masm, call_pc);
3258 if (stub == nullptr) {
3259 ciEnv::current()->record_failure("CodeCache is full");
3260 return;
3261 }
3262 }
3263 __ post_call_nop();
3264 %}
3265
3266 // Compound version of call dynamic
3267 // Toc is only passed so that it can be used in ins_encode statement.
3268 // In the code we have to use $constanttablebase.
3269 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
3270 int start_offset = __ offset();
3271 int method_index = resolved_method_index(masm);
3272 bool scratch_emit = ra_ == nullptr;
3273 Register Rtoc = scratch_emit ? R2_TOC : $constanttablebase;
3274 bool success = __ ic_call(Rtoc, (address)$meth$$method, method_index, scratch_emit, true /*fixed_size*/);
3275 if (!success) {
3276 ciEnv::current()->record_failure("CodeCache is full");
3277 return;
3278 }
3279 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3280 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3281 __ post_call_nop();
3282 %}
3283
3284 // a runtime call
3285 enc_class enc_java_to_runtime_call (method meth) %{
3286 const address start_pc = __ pc();
3287
3288 #if defined(ABI_ELFv2)
3289 address entry= !($meth$$method) ? nullptr : (address)$meth$$method;
3290 __ call_c(entry, relocInfo::runtime_call_type);
3291 __ post_call_nop();
3292 #else
3293 // The function we're going to call.
3294 FunctionDescriptor fdtemp;
3295 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3296
3297 Register Rtoc = R12_scratch2;
3298 // Calculate the method's TOC.
3299 __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3300 // Put entry, env, toc into the constant pool, this needs up to 3 constant
3301 // pool entries; call_c_using_toc will optimize the call.
3302 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3303 if (!success) {
3304 ciEnv::current()->record_out_of_memory_failure();
3305 return;
3306 }
3307 __ post_call_nop();
3308 #endif
3309
3310 // Check the ret_addr_offset.
3311 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3312 "Fix constant in ret_addr_offset()");
3313 %}
3314
3315 // Move to ctr for leaf call.
3316 // This enc_class is needed so that scheduler gets proper
3317 // input mapping for latency computation.
3318 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3319 __ mtctr($src$$Register);
3320 %}
3321
3322 // Postalloc expand emitter for runtime leaf calls.
3323 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3324 loadConLNodesTuple loadConLNodes_Entry;
3325 #if defined(ABI_ELFv2)
3326 jlong entry_address = (jlong) this->entry_point();
3327 assert(entry_address, "need address here");
3328 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3329 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3330 #else
3331 // Get the struct that describes the function we are about to call.
3332 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3333 assert(fd, "need fd here");
3334 jlong entry_address = (jlong) fd->entry();
3335 // new nodes
3336 loadConLNodesTuple loadConLNodes_Env;
3337 loadConLNodesTuple loadConLNodes_Toc;
3338
3339 // Create nodes and operands for loading the entry point.
3340 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3341 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3342
3343
3344 // Create nodes and operands for loading the env pointer.
3345 if (fd->env() != nullptr) {
3346 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3347 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3348 } else {
3349 loadConLNodes_Env._large_hi = nullptr;
3350 loadConLNodes_Env._large_lo = nullptr;
3351 loadConLNodes_Env._small = nullptr;
3352 loadConLNodes_Env._last = new loadConL16Node();
3353 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3354 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3355 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3356 }
3357
3358 // Create nodes and operands for loading the Toc point.
3359 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3360 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3361 #endif // ABI_ELFv2
3362 // mtctr node
3363 MachNode *mtctr = new CallLeafDirect_mtctrNode();
3364
3365 assert(loadConLNodes_Entry._last != nullptr, "entry must exist");
3366 mtctr->add_req(nullptr, loadConLNodes_Entry._last);
3367
3368 mtctr->_opnds[0] = new iRegLdstOper();
3369 mtctr->_opnds[1] = new iRegLdstOper();
3370
3371 // call node
3372 MachCallLeafNode *call = new CallLeafDirectNode();
3373
3374 call->_opnds[0] = _opnds[0];
3375 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3376
3377 // Make the new call node look like the old one.
3378 call->_name = _name;
3379 call->_tf = _tf;
3380 call->_entry_point = _entry_point;
3381 call->_cnt = _cnt;
3382 call->_guaranteed_safepoint = false;
3383 call->_oop_map = _oop_map;
3384 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3385 call->_jvms = nullptr;
3386 call->_jvmadj = _jvmadj;
3387 call->_in_rms = _in_rms;
3388 call->_nesting = _nesting;
3389
3390 // New call needs all inputs of old call.
3391 // Req...
3392 for (uint i = 0; i < req(); ++i) {
3393 if (i != mach_constant_base_node_input()) {
3394 call->add_req(in(i));
3395 }
3396 }
3397
3398 // These must be reqired edges, as the registers are live up to
3399 // the call. Else the constants are handled as kills.
3400 call->add_req(mtctr);
3401 #if !defined(ABI_ELFv2)
3402 call->add_req(loadConLNodes_Env._last);
3403 call->add_req(loadConLNodes_Toc._last);
3404 #endif
3405
3406 // ...as well as prec
3407 for (uint i = req(); i < len(); ++i) {
3408 call->add_prec(in(i));
3409 }
3410
3411 // registers
3412 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3413
3414 // Insert the new nodes.
3415 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3416 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last);
3417 #if !defined(ABI_ELFv2)
3418 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi);
3419 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last);
3420 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi);
3421 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last);
3422 #endif
3423 nodes->push(mtctr);
3424 nodes->push(call);
3425 %}
3426 %}
3427
3428 //----------FRAME--------------------------------------------------------------
3429 // Definition of frame structure and management information.
3430
3431 frame %{
3432 // These two registers define part of the calling convention between
3433 // compiled code and the interpreter.
3434
3435 // Inline Cache Register or method for I2C.
3436 inline_cache_reg(R19); // R19_method
3437
3438 // Optional: name the operand used by cisc-spilling to access
3439 // [stack_pointer + offset].
3440 cisc_spilling_operand_name(indOffset);
3441
3442 // Number of stack slots consumed by a Monitor enter.
3443 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size));
3444
3445 // Compiled code's Frame Pointer.
3446 frame_pointer(R1); // R1_SP
3447
3448 stack_alignment(frame::alignment_in_bytes);
3449
3450 // Number of outgoing stack slots killed above the
3451 // out_preserve_stack_slots for calls to C. Supports the var-args
3452 // backing area for register parms.
3453 //
3454 varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3455
3456 // The after-PROLOG location of the return address. Location of
3457 // return address specifies a type (REG or STACK) and a number
3458 // representing the register number (i.e. - use a register name) or
3459 // stack slot.
3460 //
3461 // A: Link register is stored in stack slot ...
3462 // M: ... but it's in the caller's frame according to PPC-64 ABI.
3463 // J: Therefore, we make sure that the link register is also in R11_scratch1
3464 // at the end of the prolog.
3465 // B: We use R20, now.
3466 //return_addr(REG R20);
3467
3468 // G: After reading the comments made by all the luminaries on their
3469 // failure to tell the compiler where the return address really is,
3470 // I hardly dare to try myself. However, I'm convinced it's in slot
3471 // 4 what apparently works and saves us some spills.
3472 return_addr(STACK 4);
3473
3474 // Location of compiled Java return values. Same as C
3475 return_value %{
3476 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3477 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3478 "only return normal values");
3479 // enum names from opcodes.hpp
3480 static int typeToRegLo[Op_RegL+1] = {
3481 0, // Op_Node
3482 0, // Op_Set
3483 R3_num, // Op_RegN
3484 R3_num, // Op_RegI
3485 R3_num, // Op_RegP
3486 F1_num, // Op_RegF
3487 F1_num, // Op_RegD
3488 R3_num, // Op_RegL
3489 };
3490
3491 static int typeToRegHi[Op_RegL+1] = {
3492 0, // Op_Node
3493 0, // Op_Set
3494 OptoReg::Bad, // Op_RegN
3495 OptoReg::Bad, // Op_RegI
3496 R3_H_num, // Op_RegP
3497 OptoReg::Bad, // Op_RegF
3498 F1_H_num, // Op_RegD
3499 R3_H_num // Op_RegL
3500 };
3501
3502 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3503 %}
3504 %}
3505
3506
3507 //----------ATTRIBUTES---------------------------------------------------------
3508
3509 //----------Operand Attributes-------------------------------------------------
3510 op_attrib op_cost(1); // Required cost attribute.
3511
3512 //----------Instruction Attributes---------------------------------------------
3513
3514 // Cost attribute. required.
3515 ins_attrib ins_cost(DEFAULT_COST);
3516
3517 // Is this instruction a non-matching short branch variant of some
3518 // long branch? Not required.
3519 ins_attrib ins_short_branch(0);
3520
3521 ins_attrib ins_is_TrapBasedCheckNode(true);
3522
3523 // Number of constants.
3524 // This instruction uses the given number of constants
3525 // (optional attribute).
3526 // This is needed to determine in time whether the constant pool will
3527 // exceed 4000 entries. Before postalloc_expand the overall number of constants
3528 // is determined. It's also used to compute the constant pool size
3529 // in Output().
3530 ins_attrib ins_num_consts(0);
3531
3532 // Required alignment attribute (must be a power of 2) specifies the
3533 // alignment that some part of the instruction (not necessarily the
3534 // start) requires. If > 1, a compute_padding() function must be
3535 // provided for the instruction.
3536 ins_attrib ins_alignment(1);
3537
3538 // Enforce/prohibit rematerializations.
3539 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3540 // then rematerialization of that instruction is prohibited and the
3541 // instruction's value will be spilled if necessary.
3542 // Causes that MachNode::rematerialize() returns false.
3543 // - If an instruction is attributed with 'ins_should_rematerialize(true)'
3544 // then rematerialization should be enforced and a copy of the instruction
3545 // should be inserted if possible; rematerialization is not guaranteed.
3546 // Note: this may result in rematerializations in front of every use.
3547 // Causes that MachNode::rematerialize() can return true.
3548 // (optional attribute)
3549 ins_attrib ins_cannot_rematerialize(false);
3550 ins_attrib ins_should_rematerialize(false);
3551
3552 // Instruction 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 // Disjoint narrow oop base.
6616 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
6617 match(Set dst (EncodePKlass src));
6618 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/);
6619
6620 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6621 size(4);
6622 ins_encode %{
6623 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
6624 %}
6625 ins_pipe(pipe_class_default);
6626 %}
6627
6628 // shift != 0, base != 0
6629 instruct encodePKlass_not_null(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6630 match(Set dst (EncodePKlass (Binary base src)));
6631 predicate(false);
6632
6633 format %{ "EncodePKlass $dst = ($src - $base) >> 3\t// $src != nullptr" %}
6634 size(8);
6635 ins_encode %{
6636 __ subf($dst$$Register, $base$$Register, $src$$Register);
6637 __ srdi($dst$$Register, $dst$$Register, CompressedKlassPointers::shift());
6638 %}
6639 ins_pipe(pipe_class_default);
6640 %}
6641
6642 // shift != 0, base != 0
6643 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6644 match(Set dst (EncodePKlass src));
6645 //predicate(CompressedKlassPointers::shift() != 0 &&
6646 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/);
6647
6648 ins_cost(DEFAULT_COST*2); // Don't count constant.
6649 expand %{
6650 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %}
6651 iRegLdst base;
6652 loadConL_Ex(base, baseImm);
6653 encodePKlass_not_null(dst, base, src);
6654 %}
6655 %}
6656
6657 // Decode nodes.
6658
6659 // src != 0, shift != 0, base != 0
6660 instruct decodeNKlass_notNull(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
6661 match(Set dst (DecodeNKlass (Binary base src)));
6662 predicate(false);
6663
6664 format %{ "DecodeNKlass $dst = ($base + $src) << 3\t// $src != nullptr, base pre-shifted" %}
6665 size(8);
6666 ins_encode %{
6667 __ add($dst$$Register, $base$$Register, $src$$Register);
6668 __ sldi($dst$$Register, $dst$$Register, CompressedKlassPointers::shift());
6669 %}
6670 ins_pipe(pipe_class_default);
6671 %}
6672
6673 // src != 0, shift != 0, base != 0
6674 instruct decodeNKlass_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6675 match(Set dst (DecodeNKlass src));
6676 // predicate(CompressedKlassPointers::shift() != 0 &&
6677 // CompressedKlassPointers::base() != 0);
6678
6679 ins_cost(DEFAULT_COST*2); // Don't count constant.
6680 expand %{
6681 // We add first, then we shift. Like this, we can get along with one register less.
6682 // But we have to load the base pre-shifted.
6683 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %}
6684 iRegLdst base;
6685 loadConL_Ex(base, baseImm);
6686 decodeNKlass_notNull(dst, base, src);
6687 %}
6688 %}
6689
6690 //----------MemBar Instructions-----------------------------------------------
6691 // Memory barrier flavors
6692
6693 instruct membar_acquire() %{
6694 match(LoadFence);
6695 ins_cost(4*MEMORY_REF_COST);
6696
6697 format %{ "MEMBAR-acquire" %}
6698 size(4);
6699 ins_encode %{
6700 __ acquire();
6701 %}
6702 ins_pipe(pipe_class_default);
6703 %}
6704
6705 instruct unnecessary_membar_acquire() %{
6706 match(MemBarAcquire);
6707 ins_cost(0);
6708
6709 format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
6710 size(0);
6711 ins_encode( /*empty*/ );
6712 ins_pipe(pipe_class_default);
6713 %}
6714
6715 instruct membar_acquire_lock() %{
6716 match(MemBarAcquireLock);
6717 ins_cost(0);
6718
6719 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
6720 size(0);
6721 ins_encode( /*empty*/ );
6722 ins_pipe(pipe_class_default);
6723 %}
6724
6725 instruct membar_release() %{
6726 match(MemBarRelease);
6727 match(StoreFence);
6728 ins_cost(4*MEMORY_REF_COST);
6729
6730 format %{ "MEMBAR-release" %}
6731 size(4);
6732 ins_encode %{
6733 __ release();
6734 %}
6735 ins_pipe(pipe_class_default);
6736 %}
6737
6738 instruct membar_storestore() %{
6739 match(MemBarStoreStore);
6740 match(StoreStoreFence);
6741 ins_cost(4*MEMORY_REF_COST);
6742
6743 format %{ "MEMBAR-store-store" %}
6744 size(4);
6745 ins_encode %{
6746 __ membar(Assembler::StoreStore);
6747 %}
6748 ins_pipe(pipe_class_default);
6749 %}
6750
6751 instruct membar_release_lock() %{
6752 match(MemBarReleaseLock);
6753 ins_cost(0);
6754
6755 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
6756 size(0);
6757 ins_encode( /*empty*/ );
6758 ins_pipe(pipe_class_default);
6759 %}
6760
6761 instruct membar_storeload() %{
6762 match(MemBarStoreLoad);
6763 ins_cost(4*MEMORY_REF_COST);
6764
6765 format %{ "MEMBAR-store-load" %}
6766 size(4);
6767 ins_encode %{
6768 __ fence();
6769 %}
6770 ins_pipe(pipe_class_default);
6771 %}
6772
6773 instruct membar_volatile() %{
6774 match(MemBarVolatile);
6775 ins_cost(4*MEMORY_REF_COST);
6776
6777 format %{ "MEMBAR-volatile" %}
6778 size(4);
6779 ins_encode %{
6780 __ fence();
6781 %}
6782 ins_pipe(pipe_class_default);
6783 %}
6784
6785 // This optimization is wrong on PPC. The following pattern is not supported:
6786 // MemBarVolatile
6787 // ^ ^
6788 // | |
6789 // CtrlProj MemProj
6790 // ^ ^
6791 // | |
6792 // | Load
6793 // |
6794 // MemBarVolatile
6795 //
6796 // The first MemBarVolatile could get optimized out! According to
6797 // Vladimir, this pattern can not occur on Oracle platforms.
6798 // However, it does occur on PPC64 (because of membars in
6799 // inline_unsafe_load_store).
6800 //
6801 // Add this node again if we found a good solution for inline_unsafe_load_store().
6802 // Don't forget to look at the implementation of post_store_load_barrier again,
6803 // we did other fixes in that method.
6804 //instruct unnecessary_membar_volatile() %{
6805 // match(MemBarVolatile);
6806 // predicate(Matcher::post_store_load_barrier(n));
6807 // ins_cost(0);
6808 //
6809 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
6810 // size(0);
6811 // ins_encode( /*empty*/ );
6812 // ins_pipe(pipe_class_default);
6813 //%}
6814
6815 instruct membar_full() %{
6816 match(MemBarFull);
6817 ins_cost(4*MEMORY_REF_COST);
6818
6819 format %{ "MEMBAR-full" %}
6820 size(4);
6821 ins_encode %{
6822 __ fence();
6823 %}
6824 ins_pipe(pipe_class_default);
6825 %}
6826
6827 instruct membar_CPUOrder() %{
6828 match(MemBarCPUOrder);
6829 ins_cost(0);
6830
6831 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
6832 size(0);
6833 ins_encode( /*empty*/ );
6834 ins_pipe(pipe_class_default);
6835 %}
6836
6837 instruct onspinwait() %{
6838 match(OnSpinWait);
6839 ins_cost(DEFAULT_COST);
6840
6841 format %{ "OnSpinWait (smt_prio_low ; smt_prio_medium)" %}
6842 size(8);
6843 ins_encode %{
6844 __ block_comment("spin_wait {");
6845 __ smt_prio_low();
6846 __ smt_prio_medium();
6847 __ block_comment("}");
6848 %}
6849 ins_pipe(pipe_class_default);
6850 %}
6851
6852 //----------Conditional Move---------------------------------------------------
6853
6854 // Cmove using isel.
6855 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
6856 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
6857 ins_cost(DEFAULT_COST);
6858
6859 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6860 size(4);
6861 ins_encode %{
6862 int cc = $cmp$$cmpcode;
6863 __ isel($dst$$Register, $crx$$CondRegister,
6864 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6865 %}
6866 ins_pipe(pipe_class_default);
6867 %}
6868
6869 // Cmove using isel.
6870 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
6871 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
6872 ins_cost(DEFAULT_COST);
6873
6874 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6875 size(4);
6876 ins_encode %{
6877 int cc = $cmp$$cmpcode;
6878 __ isel($dst$$Register, $crx$$CondRegister,
6879 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6880 %}
6881 ins_pipe(pipe_class_default);
6882 %}
6883
6884 // Cmove using isel.
6885 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
6886 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
6887 ins_cost(DEFAULT_COST);
6888
6889 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6890 size(4);
6891 ins_encode %{
6892 int cc = $cmp$$cmpcode;
6893 __ isel($dst$$Register, $crx$$CondRegister,
6894 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6895 %}
6896 ins_pipe(pipe_class_default);
6897 %}
6898
6899 // Cmove using isel.
6900 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
6901 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
6902 ins_cost(DEFAULT_COST);
6903
6904 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6905 size(4);
6906 ins_encode %{
6907 int cc = $cmp$$cmpcode;
6908 __ isel($dst$$Register, $crx$$CondRegister,
6909 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6910 %}
6911 ins_pipe(pipe_class_default);
6912 %}
6913
6914 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
6915 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
6916 ins_cost(DEFAULT_COST+BRANCH_COST);
6917
6918 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
6919 size(8);
6920 ins_encode %{
6921 Label done;
6922 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
6923 // Branch if not (cmp crx).
6924 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
6925 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
6926 __ bind(done);
6927 %}
6928 ins_pipe(pipe_class_default);
6929 %}
6930
6931 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
6932 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
6933 ins_cost(DEFAULT_COST+BRANCH_COST);
6934
6935 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
6936 size(8);
6937 ins_encode %{
6938 Label done;
6939 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
6940 // Branch if not (cmp crx).
6941 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
6942 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
6943 __ bind(done);
6944 %}
6945 ins_pipe(pipe_class_default);
6946 %}
6947
6948 instruct cmovF_cmpF(cmpOp cop, regF op1, regF op2, regF dst, regF false_result, regF true_result, regD tmp) %{
6949 match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
6950 predicate(PowerArchitecturePPC64 >= 9);
6951 effect(TEMP tmp);
6952 ins_cost(2*DEFAULT_COST);
6953 format %{ "cmovF_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
6954 size(8);
6955 ins_encode %{
6956 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
6957 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
6958 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
6959 $tmp$$FloatRegister->to_vsr());
6960 %}
6961 ins_pipe(pipe_class_default);
6962 %}
6963
6964 instruct cmovF_cmpD(cmpOp cop, regD op1, regD op2, regF dst, regF false_result, regF true_result, regD tmp) %{
6965 match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
6966 predicate(PowerArchitecturePPC64 >= 9);
6967 effect(TEMP tmp);
6968 ins_cost(2*DEFAULT_COST);
6969 format %{ "cmovF_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
6970 size(8);
6971 ins_encode %{
6972 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
6973 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
6974 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
6975 $tmp$$FloatRegister->to_vsr());
6976 %}
6977 ins_pipe(pipe_class_default);
6978 %}
6979
6980 instruct cmovD_cmpD(cmpOp cop, regD op1, regD op2, regD dst, regD false_result, regD true_result, regD tmp) %{
6981 match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
6982 predicate(PowerArchitecturePPC64 >= 9);
6983 effect(TEMP tmp);
6984 ins_cost(2*DEFAULT_COST);
6985 format %{ "cmovD_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
6986 size(8);
6987 ins_encode %{
6988 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
6989 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
6990 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
6991 $tmp$$FloatRegister->to_vsr());
6992 %}
6993 ins_pipe(pipe_class_default);
6994 %}
6995
6996 instruct cmovD_cmpF(cmpOp cop, regF op1, regF op2, regD dst, regD false_result, regD true_result, regD tmp) %{
6997 match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
6998 predicate(PowerArchitecturePPC64 >= 9);
6999 effect(TEMP tmp);
7000 ins_cost(2*DEFAULT_COST);
7001 format %{ "cmovD_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7002 size(8);
7003 ins_encode %{
7004 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7005 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7006 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7007 $tmp$$FloatRegister->to_vsr());
7008 %}
7009 ins_pipe(pipe_class_default);
7010 %}
7011
7012 //----------Compare-And-Swap---------------------------------------------------
7013
7014 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7015 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7016 // matched.
7017
7018 // Strong versions:
7019
7020 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7021 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7022 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7023 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7024 ins_encode %{
7025 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7026 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7027 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7028 $res$$Register, nullptr, true);
7029 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7030 __ isync();
7031 } else {
7032 __ sync();
7033 }
7034 %}
7035 ins_pipe(pipe_class_default);
7036 %}
7037
7038 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7039 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7040 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7041 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7042 ins_encode %{
7043 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7044 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7045 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7046 $res$$Register, nullptr, true);
7047 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7048 __ isync();
7049 } else {
7050 __ sync();
7051 }
7052 %}
7053 ins_pipe(pipe_class_default);
7054 %}
7055
7056 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7057 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7058 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7059 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7060 ins_encode %{
7061 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7062 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7063 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7064 $res$$Register, nullptr, true);
7065 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7066 __ isync();
7067 } else {
7068 __ sync();
7069 }
7070 %}
7071 ins_pipe(pipe_class_default);
7072 %}
7073
7074 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7075 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7076 predicate(n->as_LoadStore()->barrier_data() == 0);
7077 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7078 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7079 ins_encode %{
7080 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7081 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7082 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7083 $res$$Register, nullptr, true);
7084 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7085 __ isync();
7086 } else {
7087 __ sync();
7088 }
7089 %}
7090 ins_pipe(pipe_class_default);
7091 %}
7092
7093 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7094 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7095 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7096 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7097 ins_encode %{
7098 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7099 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7100 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7101 $res$$Register, nullptr, true);
7102 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7103 __ isync();
7104 } else {
7105 __ sync();
7106 }
7107 %}
7108 ins_pipe(pipe_class_default);
7109 %}
7110
7111 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7112 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7113 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7114 predicate(n->as_LoadStore()->barrier_data() == 0);
7115 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7116 ins_encode %{
7117 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7118 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7119 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7120 $res$$Register, nullptr, true);
7121 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7122 __ isync();
7123 } else {
7124 __ sync();
7125 }
7126 %}
7127 ins_pipe(pipe_class_default);
7128 %}
7129
7130 // Weak versions:
7131
7132 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7133 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7134 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7135 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7136 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7137 ins_encode %{
7138 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7139 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7140 MacroAssembler::MemBarNone,
7141 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7142 %}
7143 ins_pipe(pipe_class_default);
7144 %}
7145
7146 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7147 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7148 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) );
7149 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7150 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7151 ins_encode %{
7152 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7153 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7154 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7155 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7156 %}
7157 ins_pipe(pipe_class_default);
7158 %}
7159
7160 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7161 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7162 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7163 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7164 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7165 ins_encode %{
7166 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7167 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7168 MacroAssembler::MemBarNone,
7169 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7170 %}
7171 ins_pipe(pipe_class_default);
7172 %}
7173
7174 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7175 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7176 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7177 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7178 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7179 ins_encode %{
7180 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7181 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7182 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7183 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7184 %}
7185 ins_pipe(pipe_class_default);
7186 %}
7187
7188 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7189 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7190 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7191 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7192 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7193 ins_encode %{
7194 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7195 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7196 MacroAssembler::MemBarNone,
7197 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7198 %}
7199 ins_pipe(pipe_class_default);
7200 %}
7201
7202 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7203 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7204 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7205 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7206 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7207 ins_encode %{
7208 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7209 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7210 // value is never passed to caller.
7211 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7212 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7213 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7214 %}
7215 ins_pipe(pipe_class_default);
7216 %}
7217
7218 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7219 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7220 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7221 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7222 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7223 ins_encode %{
7224 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7225 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7226 MacroAssembler::MemBarNone,
7227 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7228 %}
7229 ins_pipe(pipe_class_default);
7230 %}
7231
7232 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7233 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7234 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7235 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7236 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7237 ins_encode %{
7238 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7239 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7240 // value is never passed to caller.
7241 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7242 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7243 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7244 %}
7245 ins_pipe(pipe_class_default);
7246 %}
7247
7248 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7249 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7250 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7251 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7252 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7253 ins_encode %{
7254 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7255 // value is never passed to caller.
7256 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7257 MacroAssembler::MemBarNone,
7258 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7259 %}
7260 ins_pipe(pipe_class_default);
7261 %}
7262
7263 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7264 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7265 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7266 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7267 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7268 ins_encode %{
7269 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7270 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7271 // value is never passed to caller.
7272 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7273 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7274 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7275 %}
7276 ins_pipe(pipe_class_default);
7277 %}
7278
7279 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7280 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7281 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7282 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7283 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7284 ins_encode %{
7285 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7286 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7287 MacroAssembler::MemBarNone,
7288 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7289 %}
7290 ins_pipe(pipe_class_default);
7291 %}
7292
7293 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7294 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7295 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7296 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7297 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7298 ins_encode %{
7299 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7300 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7301 // value is never passed to caller.
7302 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7303 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7304 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7305 %}
7306 ins_pipe(pipe_class_default);
7307 %}
7308
7309 // CompareAndExchange
7310
7311 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7312 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7313 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7314 effect(TEMP_DEF res, TEMP cr0);
7315 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7316 ins_encode %{
7317 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7318 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7319 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7320 noreg, nullptr, true);
7321 %}
7322 ins_pipe(pipe_class_default);
7323 %}
7324
7325 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7326 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7327 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7328 effect(TEMP_DEF res, TEMP cr0);
7329 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7330 ins_encode %{
7331 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7332 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7333 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7334 noreg, nullptr, true);
7335 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7336 __ isync();
7337 } else {
7338 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7339 __ sync();
7340 }
7341 %}
7342 ins_pipe(pipe_class_default);
7343 %}
7344
7345
7346 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7347 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7348 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7349 effect(TEMP_DEF res, TEMP cr0);
7350 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7351 ins_encode %{
7352 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7353 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7354 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7355 noreg, nullptr, true);
7356 %}
7357 ins_pipe(pipe_class_default);
7358 %}
7359
7360 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7361 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7362 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7363 effect(TEMP_DEF res, TEMP cr0);
7364 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7365 ins_encode %{
7366 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7367 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7368 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7369 noreg, nullptr, true);
7370 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7371 __ isync();
7372 } else {
7373 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7374 __ sync();
7375 }
7376 %}
7377 ins_pipe(pipe_class_default);
7378 %}
7379
7380 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7381 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7382 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7383 effect(TEMP_DEF res, TEMP cr0);
7384 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
7385 ins_encode %{
7386 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7387 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7388 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7389 noreg, nullptr, true);
7390 %}
7391 ins_pipe(pipe_class_default);
7392 %}
7393
7394 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7395 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7396 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7397 effect(TEMP_DEF res, TEMP cr0);
7398 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
7399 ins_encode %{
7400 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7401 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7402 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7403 noreg, nullptr, true);
7404 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7405 __ isync();
7406 } else {
7407 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7408 __ sync();
7409 }
7410 %}
7411 ins_pipe(pipe_class_default);
7412 %}
7413
7414 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7415 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7416 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7417 effect(TEMP_DEF res, TEMP cr0);
7418 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7419 ins_encode %{
7420 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7421 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7422 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7423 noreg, nullptr, true);
7424 %}
7425 ins_pipe(pipe_class_default);
7426 %}
7427
7428 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7429 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7430 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7431 effect(TEMP_DEF res, TEMP cr0);
7432 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7433 ins_encode %{
7434 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7435 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7436 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7437 noreg, nullptr, true);
7438 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7439 __ isync();
7440 } else {
7441 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7442 __ sync();
7443 }
7444 %}
7445 ins_pipe(pipe_class_default);
7446 %}
7447
7448 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7449 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7450 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7451 effect(TEMP_DEF res, TEMP cr0);
7452 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
7453 ins_encode %{
7454 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7455 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7456 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7457 noreg, nullptr, true);
7458 %}
7459 ins_pipe(pipe_class_default);
7460 %}
7461
7462 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7463 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7464 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7465 effect(TEMP_DEF res, TEMP cr0);
7466 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
7467 ins_encode %{
7468 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7469 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7470 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7471 noreg, nullptr, true);
7472 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7473 __ isync();
7474 } else {
7475 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7476 __ sync();
7477 }
7478 %}
7479 ins_pipe(pipe_class_default);
7480 %}
7481
7482 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7483 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7484 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst)
7485 && n->as_LoadStore()->barrier_data() == 0);
7486 effect(TEMP_DEF res, TEMP cr0);
7487 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7488 ins_encode %{
7489 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7490 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7491 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7492 noreg, nullptr, true);
7493 %}
7494 ins_pipe(pipe_class_default);
7495 %}
7496
7497 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7498 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7499 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst)
7500 && n->as_LoadStore()->barrier_data() == 0);
7501 effect(TEMP_DEF res, TEMP cr0);
7502 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7503 ins_encode %{
7504 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7505 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7506 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7507 noreg, nullptr, true);
7508 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7509 __ isync();
7510 } else {
7511 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7512 __ sync();
7513 }
7514 %}
7515 ins_pipe(pipe_class_default);
7516 %}
7517
7518 // Special RMW
7519
7520 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7521 match(Set res (GetAndAddB mem_ptr src));
7522 effect(TEMP_DEF res, TEMP cr0);
7523 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
7524 ins_encode %{
7525 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
7526 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7527 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7528 __ isync();
7529 } else {
7530 __ sync();
7531 }
7532 %}
7533 ins_pipe(pipe_class_default);
7534 %}
7535
7536 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7537 match(Set res (GetAndAddS mem_ptr src));
7538 effect(TEMP_DEF res, TEMP cr0);
7539 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
7540 ins_encode %{
7541 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
7542 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7543 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7544 __ isync();
7545 } else {
7546 __ sync();
7547 }
7548 %}
7549 ins_pipe(pipe_class_default);
7550 %}
7551
7552
7553 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7554 match(Set res (GetAndAddI mem_ptr src));
7555 effect(TEMP_DEF res, TEMP cr0);
7556 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
7557 ins_encode %{
7558 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
7559 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7560 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7561 __ isync();
7562 } else {
7563 __ sync();
7564 }
7565 %}
7566 ins_pipe(pipe_class_default);
7567 %}
7568
7569 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7570 match(Set res (GetAndAddL mem_ptr src));
7571 effect(TEMP_DEF res, TEMP cr0);
7572 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
7573 ins_encode %{
7574 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
7575 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7576 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7577 __ isync();
7578 } else {
7579 __ sync();
7580 }
7581 %}
7582 ins_pipe(pipe_class_default);
7583 %}
7584
7585 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7586 match(Set res (GetAndSetB mem_ptr src));
7587 effect(TEMP_DEF res, TEMP cr0);
7588 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
7589 ins_encode %{
7590 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
7591 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7592 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7593 __ isync();
7594 } else {
7595 __ sync();
7596 }
7597 %}
7598 ins_pipe(pipe_class_default);
7599 %}
7600
7601 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7602 match(Set res (GetAndSetS mem_ptr src));
7603 effect(TEMP_DEF res, TEMP cr0);
7604 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
7605 ins_encode %{
7606 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
7607 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7608 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7609 __ isync();
7610 } else {
7611 __ sync();
7612 }
7613 %}
7614 ins_pipe(pipe_class_default);
7615 %}
7616
7617
7618 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7619 match(Set res (GetAndSetI mem_ptr src));
7620 effect(TEMP_DEF res, TEMP cr0);
7621 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
7622 ins_encode %{
7623 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7624 MacroAssembler::cmpxchgx_hint_atomic_update());
7625 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7626 __ isync();
7627 } else {
7628 __ sync();
7629 }
7630 %}
7631 ins_pipe(pipe_class_default);
7632 %}
7633
7634 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7635 match(Set res (GetAndSetL mem_ptr src));
7636 effect(TEMP_DEF res, TEMP cr0);
7637 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
7638 ins_encode %{
7639 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7640 MacroAssembler::cmpxchgx_hint_atomic_update());
7641 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7642 __ isync();
7643 } else {
7644 __ sync();
7645 }
7646 %}
7647 ins_pipe(pipe_class_default);
7648 %}
7649
7650 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
7651 match(Set res (GetAndSetP mem_ptr src));
7652 predicate(n->as_LoadStore()->barrier_data() == 0);
7653 effect(TEMP_DEF res, TEMP cr0);
7654 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
7655 ins_encode %{
7656 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7657 MacroAssembler::cmpxchgx_hint_atomic_update());
7658 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7659 __ isync();
7660 } else {
7661 __ sync();
7662 }
7663 %}
7664 ins_pipe(pipe_class_default);
7665 %}
7666
7667 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
7668 match(Set res (GetAndSetN mem_ptr src));
7669 predicate(n->as_LoadStore()->barrier_data() == 0);
7670 effect(TEMP_DEF res, TEMP cr0);
7671 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
7672 ins_encode %{
7673 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7674 MacroAssembler::cmpxchgx_hint_atomic_update());
7675 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7676 __ isync();
7677 } else {
7678 __ sync();
7679 }
7680 %}
7681 ins_pipe(pipe_class_default);
7682 %}
7683
7684 //----------Arithmetic Instructions--------------------------------------------
7685 // Addition Instructions
7686
7687 // Register Addition
7688 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
7689 match(Set dst (AddI src1 src2));
7690 format %{ "ADD $dst, $src1, $src2" %}
7691 size(4);
7692 ins_encode %{
7693 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7694 %}
7695 ins_pipe(pipe_class_default);
7696 %}
7697
7698 // Expand does not work with above instruct. (??)
7699 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7700 // no match-rule
7701 effect(DEF dst, USE src1, USE src2);
7702 format %{ "ADD $dst, $src1, $src2" %}
7703 size(4);
7704 ins_encode %{
7705 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7706 %}
7707 ins_pipe(pipe_class_default);
7708 %}
7709
7710 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
7711 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
7712 ins_cost(DEFAULT_COST*3);
7713
7714 expand %{
7715 // FIXME: we should do this in the ideal world.
7716 iRegIdst tmp1;
7717 iRegIdst tmp2;
7718 addI_reg_reg(tmp1, src1, src2);
7719 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
7720 addI_reg_reg(dst, tmp1, tmp2);
7721 %}
7722 %}
7723
7724 // Immediate Addition
7725 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
7726 match(Set dst (AddI src1 src2));
7727 format %{ "ADDI $dst, $src1, $src2" %}
7728 size(4);
7729 ins_encode %{
7730 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7731 %}
7732 ins_pipe(pipe_class_default);
7733 %}
7734
7735 // Immediate Addition with 16-bit shifted operand
7736 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
7737 match(Set dst (AddI src1 src2));
7738 format %{ "ADDIS $dst, $src1, $src2" %}
7739 size(4);
7740 ins_encode %{
7741 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7742 %}
7743 ins_pipe(pipe_class_default);
7744 %}
7745
7746 // Immediate Addition using prefixed addi
7747 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{
7748 match(Set dst (AddI src1 src2));
7749 predicate(PowerArchitecturePPC64 >= 10);
7750 ins_cost(DEFAULT_COST+1);
7751 format %{ "PADDI $dst, $src1, $src2" %}
7752 size(8);
7753 ins_encode %{
7754 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7755 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7756 %}
7757 ins_pipe(pipe_class_default);
7758 ins_alignment(2);
7759 %}
7760
7761 // Long Addition
7762 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7763 match(Set dst (AddL src1 src2));
7764 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7765 size(4);
7766 ins_encode %{
7767 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7768 %}
7769 ins_pipe(pipe_class_default);
7770 %}
7771
7772 // Expand does not work with above instruct. (??)
7773 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7774 // no match-rule
7775 effect(DEF dst, USE src1, USE src2);
7776 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7777 size(4);
7778 ins_encode %{
7779 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7780 %}
7781 ins_pipe(pipe_class_default);
7782 %}
7783
7784 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
7785 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
7786 ins_cost(DEFAULT_COST*3);
7787
7788 expand %{
7789 // FIXME: we should do this in the ideal world.
7790 iRegLdst tmp1;
7791 iRegLdst tmp2;
7792 addL_reg_reg(tmp1, src1, src2);
7793 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
7794 addL_reg_reg(dst, tmp1, tmp2);
7795 %}
7796 %}
7797
7798 // AddL + ConvL2I.
7799 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
7800 match(Set dst (ConvL2I (AddL src1 src2)));
7801
7802 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %}
7803 size(4);
7804 ins_encode %{
7805 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7806 %}
7807 ins_pipe(pipe_class_default);
7808 %}
7809
7810 // No constant pool entries required.
7811 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
7812 match(Set dst (AddL src1 src2));
7813
7814 format %{ "ADDI $dst, $src1, $src2" %}
7815 size(4);
7816 ins_encode %{
7817 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7818 %}
7819 ins_pipe(pipe_class_default);
7820 %}
7821
7822 // Long Immediate Addition with 16-bit shifted operand.
7823 // No constant pool entries required.
7824 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
7825 match(Set dst (AddL src1 src2));
7826
7827 format %{ "ADDIS $dst, $src1, $src2" %}
7828 size(4);
7829 ins_encode %{
7830 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7831 %}
7832 ins_pipe(pipe_class_default);
7833 %}
7834
7835 // Long Immediate Addition using prefixed addi
7836 // No constant pool entries required.
7837 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{
7838 match(Set dst (AddL src1 src2));
7839 predicate(PowerArchitecturePPC64 >= 10);
7840 ins_cost(DEFAULT_COST+1);
7841
7842 format %{ "PADDI $dst, $src1, $src2" %}
7843 size(8);
7844 ins_encode %{
7845 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7846 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7847 %}
7848 ins_pipe(pipe_class_default);
7849 ins_alignment(2);
7850 %}
7851
7852 // Pointer Register Addition
7853 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
7854 match(Set dst (AddP src1 src2));
7855 format %{ "ADD $dst, $src1, $src2" %}
7856 size(4);
7857 ins_encode %{
7858 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7859 %}
7860 ins_pipe(pipe_class_default);
7861 %}
7862
7863 // Pointer Immediate Addition
7864 // No constant pool entries required.
7865 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
7866 match(Set dst (AddP src1 src2));
7867
7868 format %{ "ADDI $dst, $src1, $src2" %}
7869 size(4);
7870 ins_encode %{
7871 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7872 %}
7873 ins_pipe(pipe_class_default);
7874 %}
7875
7876 // Pointer Immediate Addition with 16-bit shifted operand.
7877 // No constant pool entries required.
7878 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
7879 match(Set dst (AddP src1 src2));
7880
7881 format %{ "ADDIS $dst, $src1, $src2" %}
7882 size(4);
7883 ins_encode %{
7884 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7885 %}
7886 ins_pipe(pipe_class_default);
7887 %}
7888
7889 // Pointer Immediate Addition using prefixed addi
7890 // No constant pool entries required.
7891 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{
7892 match(Set dst (AddP src1 src2));
7893 predicate(PowerArchitecturePPC64 >= 10);
7894 ins_cost(DEFAULT_COST+1);
7895
7896 format %{ "PADDI $dst, $src1, $src2" %}
7897 size(8);
7898 ins_encode %{
7899 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7900 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7901 %}
7902 ins_pipe(pipe_class_default);
7903 ins_alignment(2);
7904 %}
7905
7906 //---------------------
7907 // Subtraction Instructions
7908
7909 // Register Subtraction
7910 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7911 match(Set dst (SubI src1 src2));
7912 format %{ "SUBF $dst, $src2, $src1" %}
7913 size(4);
7914 ins_encode %{
7915 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7916 %}
7917 ins_pipe(pipe_class_default);
7918 %}
7919
7920 // Immediate Subtraction
7921 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
7922 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
7923
7924 // SubI from constant (using subfic).
7925 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
7926 match(Set dst (SubI src1 src2));
7927 format %{ "SUBI $dst, $src1, $src2" %}
7928
7929 size(4);
7930 ins_encode %{
7931 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
7932 %}
7933 ins_pipe(pipe_class_default);
7934 %}
7935
7936 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
7937 // positive integers and 0xF...F for negative ones.
7938 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
7939 // no match-rule, false predicate
7940 effect(DEF dst, USE src);
7941 predicate(false);
7942
7943 format %{ "SRAWI $dst, $src, #31" %}
7944 size(4);
7945 ins_encode %{
7946 __ srawi($dst$$Register, $src$$Register, 0x1f);
7947 %}
7948 ins_pipe(pipe_class_default);
7949 %}
7950
7951 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
7952 match(Set dst (AbsI src));
7953 ins_cost(DEFAULT_COST*3);
7954
7955 expand %{
7956 iRegIdst tmp1;
7957 iRegIdst tmp2;
7958 signmask32I_regI(tmp1, src);
7959 xorI_reg_reg(tmp2, tmp1, src);
7960 subI_reg_reg(dst, tmp2, tmp1);
7961 %}
7962 %}
7963
7964 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
7965 match(Set dst (SubI zero src2));
7966 format %{ "NEG $dst, $src2" %}
7967 size(4);
7968 ins_encode %{
7969 __ neg($dst$$Register, $src2$$Register);
7970 %}
7971 ins_pipe(pipe_class_default);
7972 %}
7973
7974 // Long subtraction
7975 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7976 match(Set dst (SubL src1 src2));
7977 format %{ "SUBF $dst, $src2, $src1 \t// long" %}
7978 size(4);
7979 ins_encode %{
7980 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7981 %}
7982 ins_pipe(pipe_class_default);
7983 %}
7984
7985 // SubL + convL2I.
7986 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
7987 match(Set dst (ConvL2I (SubL src1 src2)));
7988
7989 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
7990 size(4);
7991 ins_encode %{
7992 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7993 %}
7994 ins_pipe(pipe_class_default);
7995 %}
7996
7997 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
7998 // positive longs and 0xF...F for negative ones.
7999 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8000 // no match-rule, false predicate
8001 effect(DEF dst, USE src);
8002 predicate(false);
8003
8004 format %{ "SRADI $dst, $src, #63" %}
8005 size(4);
8006 ins_encode %{
8007 __ sradi($dst$$Register, $src$$Register, 0x3f);
8008 %}
8009 ins_pipe(pipe_class_default);
8010 %}
8011
8012 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8013 // positive longs and 0xF...F for negative ones.
8014 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8015 // no match-rule, false predicate
8016 effect(DEF dst, USE src);
8017 predicate(false);
8018
8019 format %{ "SRADI $dst, $src, #63" %}
8020 size(4);
8021 ins_encode %{
8022 __ sradi($dst$$Register, $src$$Register, 0x3f);
8023 %}
8024 ins_pipe(pipe_class_default);
8025 %}
8026
8027 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{
8028 match(Set dst (AbsL src));
8029 ins_cost(DEFAULT_COST*3);
8030
8031 expand %{
8032 iRegLdst tmp1;
8033 iRegLdst tmp2;
8034 signmask64L_regL(tmp1, src);
8035 xorL_reg_reg(tmp2, tmp1, src);
8036 subL_reg_reg(dst, tmp2, tmp1);
8037 %}
8038 %}
8039
8040 // Long negation
8041 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8042 match(Set dst (SubL zero src2));
8043 format %{ "NEG $dst, $src2 \t// long" %}
8044 size(4);
8045 ins_encode %{
8046 __ neg($dst$$Register, $src2$$Register);
8047 %}
8048 ins_pipe(pipe_class_default);
8049 %}
8050
8051 // NegL + ConvL2I.
8052 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8053 match(Set dst (ConvL2I (SubL zero src2)));
8054
8055 format %{ "NEG $dst, $src2 \t// long + l2i" %}
8056 size(4);
8057 ins_encode %{
8058 __ neg($dst$$Register, $src2$$Register);
8059 %}
8060 ins_pipe(pipe_class_default);
8061 %}
8062
8063 // Multiplication Instructions
8064 // Integer Multiplication
8065
8066 // Register Multiplication
8067 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8068 match(Set dst (MulI src1 src2));
8069 ins_cost(DEFAULT_COST);
8070
8071 format %{ "MULLW $dst, $src1, $src2" %}
8072 size(4);
8073 ins_encode %{
8074 __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8075 %}
8076 ins_pipe(pipe_class_default);
8077 %}
8078
8079 // Immediate Multiplication
8080 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8081 match(Set dst (MulI src1 src2));
8082 ins_cost(DEFAULT_COST);
8083
8084 format %{ "MULLI $dst, $src1, $src2" %}
8085 size(4);
8086 ins_encode %{
8087 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8088 %}
8089 ins_pipe(pipe_class_default);
8090 %}
8091
8092 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8093 match(Set dst (MulL src1 src2));
8094 ins_cost(DEFAULT_COST);
8095
8096 format %{ "MULLD $dst $src1, $src2 \t// long" %}
8097 size(4);
8098 ins_encode %{
8099 __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8100 %}
8101 ins_pipe(pipe_class_default);
8102 %}
8103
8104 // Multiply high for optimized long division by constant.
8105 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8106 match(Set dst (MulHiL src1 src2));
8107 ins_cost(DEFAULT_COST);
8108
8109 format %{ "MULHD $dst $src1, $src2 \t// long" %}
8110 size(4);
8111 ins_encode %{
8112 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8113 %}
8114 ins_pipe(pipe_class_default);
8115 %}
8116
8117 instruct uMulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8118 match(Set dst (UMulHiL src1 src2));
8119 ins_cost(DEFAULT_COST);
8120
8121 format %{ "MULHDU $dst $src1, $src2 \t// unsigned long" %}
8122 size(4);
8123 ins_encode %{
8124 __ mulhdu($dst$$Register, $src1$$Register, $src2$$Register);
8125 %}
8126 ins_pipe(pipe_class_default);
8127 %}
8128
8129 // Immediate Multiplication
8130 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8131 match(Set dst (MulL src1 src2));
8132 ins_cost(DEFAULT_COST);
8133
8134 format %{ "MULLI $dst, $src1, $src2" %}
8135 size(4);
8136 ins_encode %{
8137 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8138 %}
8139 ins_pipe(pipe_class_default);
8140 %}
8141
8142 // Integer Division with Immediate -1: Negate.
8143 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8144 match(Set dst (DivI src1 src2));
8145 ins_cost(DEFAULT_COST);
8146
8147 format %{ "NEG $dst, $src1 \t// /-1" %}
8148 size(4);
8149 ins_encode %{
8150 __ neg($dst$$Register, $src1$$Register);
8151 %}
8152 ins_pipe(pipe_class_default);
8153 %}
8154
8155 // Integer Division with constant, but not -1.
8156 // We should be able to improve this by checking the type of src2.
8157 // It might well be that src2 is known to be positive.
8158 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8159 match(Set dst (DivI src1 src2));
8160 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8161 ins_cost(2*DEFAULT_COST);
8162
8163 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8164 size(4);
8165 ins_encode %{
8166 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8167 %}
8168 ins_pipe(pipe_class_default);
8169 %}
8170
8171 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8172 effect(USE_DEF dst, USE src1, USE crx);
8173 predicate(false);
8174
8175 format %{ "CMOVE $dst, neg($src1), $crx" %}
8176 size(8);
8177 ins_encode %{
8178 Label done;
8179 __ bne($crx$$CondRegister, done);
8180 __ neg($dst$$Register, $src1$$Register);
8181 __ bind(done);
8182 %}
8183 ins_pipe(pipe_class_default);
8184 %}
8185
8186 // Integer Division with Registers not containing constants.
8187 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8188 match(Set dst (DivI src1 src2));
8189 ins_cost(10*DEFAULT_COST);
8190
8191 expand %{
8192 immI16 imm %{ (int)-1 %}
8193 flagsReg tmp1;
8194 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8195 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8196 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8197 %}
8198 %}
8199
8200 // Long Division with Immediate -1: Negate.
8201 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8202 match(Set dst (DivL src1 src2));
8203 ins_cost(DEFAULT_COST);
8204
8205 format %{ "NEG $dst, $src1 \t// /-1, long" %}
8206 size(4);
8207 ins_encode %{
8208 __ neg($dst$$Register, $src1$$Register);
8209 %}
8210 ins_pipe(pipe_class_default);
8211 %}
8212
8213 // Long Division with constant, but not -1.
8214 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8215 match(Set dst (DivL src1 src2));
8216 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8217 ins_cost(2*DEFAULT_COST);
8218
8219 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8220 size(4);
8221 ins_encode %{
8222 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8223 %}
8224 ins_pipe(pipe_class_default);
8225 %}
8226
8227 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8228 effect(USE_DEF dst, USE src1, USE crx);
8229 predicate(false);
8230
8231 format %{ "CMOVE $dst, neg($src1), $crx" %}
8232 size(8);
8233 ins_encode %{
8234 Label done;
8235 __ bne($crx$$CondRegister, done);
8236 __ neg($dst$$Register, $src1$$Register);
8237 __ bind(done);
8238 %}
8239 ins_pipe(pipe_class_default);
8240 %}
8241
8242 // Long Division with Registers not containing constants.
8243 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8244 match(Set dst (DivL src1 src2));
8245 ins_cost(10*DEFAULT_COST);
8246
8247 expand %{
8248 immL16 imm %{ (int)-1 %}
8249 flagsReg tmp1;
8250 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8251 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8252 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8253 %}
8254 %}
8255
8256 // Integer Remainder with registers.
8257 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8258 match(Set dst (ModI src1 src2));
8259 ins_cost(10*DEFAULT_COST);
8260
8261 expand %{
8262 immI16 imm %{ (int)-1 %}
8263 flagsReg tmp1;
8264 iRegIdst tmp2;
8265 iRegIdst tmp3;
8266 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8267 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8268 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8269 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8270 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8271 %}
8272 %}
8273
8274 // Long Remainder with registers
8275 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8276 match(Set dst (ModL src1 src2));
8277 ins_cost(10*DEFAULT_COST);
8278
8279 expand %{
8280 immL16 imm %{ (int)-1 %}
8281 flagsReg tmp1;
8282 iRegLdst tmp2;
8283 iRegLdst tmp3;
8284 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8285 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8286 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8287 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8288 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8289 %}
8290 %}
8291
8292 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8293 match(Set dst (UDivI src1 src2));
8294 format %{ "DIVWU $dst, $src1, $src2" %}
8295 size(4);
8296 ins_encode %{
8297 __ divwu($dst$$Register, $src1$$Register, $src2$$Register);
8298 %}
8299 ins_pipe(pipe_class_default);
8300 %}
8301
8302 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8303 match(Set dst (UModI src1 src2));
8304 expand %{
8305 iRegIdst tmp1;
8306 iRegIdst tmp2;
8307 udivI_reg_reg(tmp1, src1, src2);
8308 // Compute lower 32 bit result using signed instructions as suggested by ISA.
8309 // Upper 32 bit will contain garbage.
8310 mulI_reg_reg(tmp2, src2, tmp1);
8311 subI_reg_reg(dst, src1, tmp2);
8312 %}
8313 %}
8314
8315 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8316 match(Set dst (UDivL src1 src2));
8317 format %{ "DIVDU $dst, $src1, $src2" %}
8318 size(4);
8319 ins_encode %{
8320 __ divdu($dst$$Register, $src1$$Register, $src2$$Register);
8321 %}
8322 ins_pipe(pipe_class_default);
8323 %}
8324
8325 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8326 match(Set dst (UModL src1 src2));
8327 expand %{
8328 iRegLdst tmp1;
8329 iRegLdst tmp2;
8330 udivL_reg_reg(tmp1, src1, src2);
8331 mulL_reg_reg(tmp2, src2, tmp1);
8332 subL_reg_reg(dst, src1, tmp2);
8333 %}
8334 %}
8335
8336 // Integer Shift Instructions
8337
8338 // Register Shift Left
8339
8340 // Clear all but the lowest #mask bits.
8341 // Used to normalize shift amounts in registers.
8342 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
8343 // no match-rule, false predicate
8344 effect(DEF dst, USE src, USE mask);
8345 predicate(false);
8346
8347 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %}
8348 size(4);
8349 ins_encode %{
8350 __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
8351 %}
8352 ins_pipe(pipe_class_default);
8353 %}
8354
8355 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8356 // no match-rule, false predicate
8357 effect(DEF dst, USE src1, USE src2);
8358 predicate(false);
8359
8360 format %{ "SLW $dst, $src1, $src2" %}
8361 size(4);
8362 ins_encode %{
8363 __ slw($dst$$Register, $src1$$Register, $src2$$Register);
8364 %}
8365 ins_pipe(pipe_class_default);
8366 %}
8367
8368 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8369 match(Set dst (LShiftI src1 src2));
8370 ins_cost(DEFAULT_COST*2);
8371 expand %{
8372 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8373 iRegIdst tmpI;
8374 maskI_reg_imm(tmpI, src2, mask);
8375 lShiftI_reg_reg(dst, src1, tmpI);
8376 %}
8377 %}
8378
8379 // Register Shift Left Immediate
8380 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8381 match(Set dst (LShiftI src1 src2));
8382
8383 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %}
8384 size(4);
8385 ins_encode %{
8386 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8387 %}
8388 ins_pipe(pipe_class_default);
8389 %}
8390
8391 // AndI with negpow2-constant + LShiftI
8392 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8393 match(Set dst (LShiftI (AndI src1 src2) src3));
8394 predicate(UseRotateAndMaskInstructionsPPC64);
8395
8396 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %}
8397 size(4);
8398 ins_encode %{
8399 long src3 = $src3$$constant;
8400 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8401 if (maskbits >= 32) {
8402 __ li($dst$$Register, 0); // addi
8403 } else {
8404 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
8405 }
8406 %}
8407 ins_pipe(pipe_class_default);
8408 %}
8409
8410 // RShiftI + AndI with negpow2-constant + LShiftI
8411 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8412 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
8413 predicate(UseRotateAndMaskInstructionsPPC64);
8414
8415 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
8416 size(4);
8417 ins_encode %{
8418 long src3 = $src3$$constant;
8419 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8420 if (maskbits >= 32) {
8421 __ li($dst$$Register, 0); // addi
8422 } else {
8423 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
8424 }
8425 %}
8426 ins_pipe(pipe_class_default);
8427 %}
8428
8429 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8430 // no match-rule, false predicate
8431 effect(DEF dst, USE src1, USE src2);
8432 predicate(false);
8433
8434 format %{ "SLD $dst, $src1, $src2" %}
8435 size(4);
8436 ins_encode %{
8437 __ sld($dst$$Register, $src1$$Register, $src2$$Register);
8438 %}
8439 ins_pipe(pipe_class_default);
8440 %}
8441
8442 // Register Shift Left
8443 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8444 match(Set dst (LShiftL src1 src2));
8445 ins_cost(DEFAULT_COST*2);
8446 expand %{
8447 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8448 iRegIdst tmpI;
8449 maskI_reg_imm(tmpI, src2, mask);
8450 lShiftL_regL_regI(dst, src1, tmpI);
8451 %}
8452 %}
8453
8454 // Register Shift Left Immediate
8455 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8456 match(Set dst (LShiftL src1 src2));
8457 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %}
8458 size(4);
8459 ins_encode %{
8460 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8461 %}
8462 ins_pipe(pipe_class_default);
8463 %}
8464
8465 // If we shift more than 32 bits, we need not convert I2L.
8466 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
8467 match(Set dst (LShiftL (ConvI2L src1) src2));
8468 ins_cost(DEFAULT_COST);
8469
8470 size(4);
8471 format %{ "SLDI $dst, i2l($src1), $src2" %}
8472 ins_encode %{
8473 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8474 %}
8475 ins_pipe(pipe_class_default);
8476 %}
8477
8478 // Shift a postivie int to the left.
8479 // Clrlsldi clears the upper 32 bits and shifts.
8480 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
8481 match(Set dst (LShiftL (ConvI2L src1) src2));
8482 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
8483
8484 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %}
8485 size(4);
8486 ins_encode %{
8487 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
8488 %}
8489 ins_pipe(pipe_class_default);
8490 %}
8491
8492 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8493 // no match-rule, false predicate
8494 effect(DEF dst, USE src1, USE src2);
8495 predicate(false);
8496
8497 format %{ "SRAW $dst, $src1, $src2" %}
8498 size(4);
8499 ins_encode %{
8500 __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
8501 %}
8502 ins_pipe(pipe_class_default);
8503 %}
8504
8505 // Register Arithmetic Shift Right
8506 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8507 match(Set dst (RShiftI src1 src2));
8508 ins_cost(DEFAULT_COST*2);
8509 expand %{
8510 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8511 iRegIdst tmpI;
8512 maskI_reg_imm(tmpI, src2, mask);
8513 arShiftI_reg_reg(dst, src1, tmpI);
8514 %}
8515 %}
8516
8517 // Register Arithmetic Shift Right Immediate
8518 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8519 match(Set dst (RShiftI src1 src2));
8520
8521 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %}
8522 size(4);
8523 ins_encode %{
8524 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8525 %}
8526 ins_pipe(pipe_class_default);
8527 %}
8528
8529 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8530 // no match-rule, false predicate
8531 effect(DEF dst, USE src1, USE src2);
8532 predicate(false);
8533
8534 format %{ "SRAD $dst, $src1, $src2" %}
8535 size(4);
8536 ins_encode %{
8537 __ srad($dst$$Register, $src1$$Register, $src2$$Register);
8538 %}
8539 ins_pipe(pipe_class_default);
8540 %}
8541
8542 // Register Shift Right Arithmetic Long
8543 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8544 match(Set dst (RShiftL src1 src2));
8545 ins_cost(DEFAULT_COST*2);
8546
8547 expand %{
8548 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8549 iRegIdst tmpI;
8550 maskI_reg_imm(tmpI, src2, mask);
8551 arShiftL_regL_regI(dst, src1, tmpI);
8552 %}
8553 %}
8554
8555 // Register Shift Right Immediate
8556 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8557 match(Set dst (RShiftL src1 src2));
8558
8559 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %}
8560 size(4);
8561 ins_encode %{
8562 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8563 %}
8564 ins_pipe(pipe_class_default);
8565 %}
8566
8567 // RShiftL + ConvL2I
8568 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8569 match(Set dst (ConvL2I (RShiftL src1 src2)));
8570
8571 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8572 size(4);
8573 ins_encode %{
8574 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8575 %}
8576 ins_pipe(pipe_class_default);
8577 %}
8578
8579 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8580 // no match-rule, false predicate
8581 effect(DEF dst, USE src1, USE src2);
8582 predicate(false);
8583
8584 format %{ "SRW $dst, $src1, $src2" %}
8585 size(4);
8586 ins_encode %{
8587 __ srw($dst$$Register, $src1$$Register, $src2$$Register);
8588 %}
8589 ins_pipe(pipe_class_default);
8590 %}
8591
8592 // Register Shift Right
8593 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8594 match(Set dst (URShiftI src1 src2));
8595 ins_cost(DEFAULT_COST*2);
8596
8597 expand %{
8598 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8599 iRegIdst tmpI;
8600 maskI_reg_imm(tmpI, src2, mask);
8601 urShiftI_reg_reg(dst, src1, tmpI);
8602 %}
8603 %}
8604
8605 // Register Shift Right Immediate
8606 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8607 match(Set dst (URShiftI src1 src2));
8608
8609 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %}
8610 size(4);
8611 ins_encode %{
8612 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8613 %}
8614 ins_pipe(pipe_class_default);
8615 %}
8616
8617 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8618 // no match-rule, false predicate
8619 effect(DEF dst, USE src1, USE src2);
8620 predicate(false);
8621
8622 format %{ "SRD $dst, $src1, $src2" %}
8623 size(4);
8624 ins_encode %{
8625 __ srd($dst$$Register, $src1$$Register, $src2$$Register);
8626 %}
8627 ins_pipe(pipe_class_default);
8628 %}
8629
8630 // Register Shift Right
8631 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8632 match(Set dst (URShiftL src1 src2));
8633 ins_cost(DEFAULT_COST*2);
8634
8635 expand %{
8636 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8637 iRegIdst tmpI;
8638 maskI_reg_imm(tmpI, src2, mask);
8639 urShiftL_regL_regI(dst, src1, tmpI);
8640 %}
8641 %}
8642
8643 // Register Shift Right Immediate
8644 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8645 match(Set dst (URShiftL src1 src2));
8646
8647 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %}
8648 size(4);
8649 ins_encode %{
8650 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8651 %}
8652 ins_pipe(pipe_class_default);
8653 %}
8654
8655 // URShiftL + ConvL2I.
8656 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8657 match(Set dst (ConvL2I (URShiftL src1 src2)));
8658
8659 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8660 size(4);
8661 ins_encode %{
8662 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8663 %}
8664 ins_pipe(pipe_class_default);
8665 %}
8666
8667 // Register Shift Right Immediate with a CastP2X
8668 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
8669 match(Set dst (URShiftL (CastP2X src1) src2));
8670
8671 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
8672 size(4);
8673 ins_encode %{
8674 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8675 %}
8676 ins_pipe(pipe_class_default);
8677 %}
8678
8679 // Bitfield Extract: URShiftI + AndI
8680 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
8681 match(Set dst (AndI (URShiftI src1 src2) src3));
8682
8683 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
8684 size(4);
8685 ins_encode %{
8686 int rshift = ($src2$$constant) & 0x1f;
8687 int length = log2i_exact((juint)$src3$$constant + 1u);
8688 if (rshift + length > 32) {
8689 // if necessary, adjust mask to omit rotated bits.
8690 length = 32 - rshift;
8691 }
8692 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8693 %}
8694 ins_pipe(pipe_class_default);
8695 %}
8696
8697 // Bitfield Extract: URShiftL + AndL
8698 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
8699 match(Set dst (AndL (URShiftL src1 src2) src3));
8700
8701 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
8702 size(4);
8703 ins_encode %{
8704 int rshift = ($src2$$constant) & 0x3f;
8705 int length = log2i_exact((julong)$src3$$constant + 1ull);
8706 if (rshift + length > 64) {
8707 // if necessary, adjust mask to omit rotated bits.
8708 length = 64 - rshift;
8709 }
8710 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8711 %}
8712 ins_pipe(pipe_class_default);
8713 %}
8714
8715 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
8716 match(Set dst (ConvL2I (ConvI2L src)));
8717
8718 format %{ "EXTSW $dst, $src \t// int->int" %}
8719 size(4);
8720 ins_encode %{
8721 __ extsw($dst$$Register, $src$$Register);
8722 %}
8723 ins_pipe(pipe_class_default);
8724 %}
8725
8726 //----------Rotate Instructions------------------------------------------------
8727
8728 // Rotate Left by 8-bit immediate
8729 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
8730 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
8731 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8732
8733 format %{ "ROTLWI $dst, $src, $lshift" %}
8734 size(4);
8735 ins_encode %{
8736 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
8737 %}
8738 ins_pipe(pipe_class_default);
8739 %}
8740
8741 // Rotate Right by 8-bit immediate
8742 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
8743 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
8744 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8745
8746 format %{ "ROTRWI $dst, $rshift" %}
8747 size(4);
8748 ins_encode %{
8749 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
8750 %}
8751 ins_pipe(pipe_class_default);
8752 %}
8753
8754 //----------Floating Point Arithmetic Instructions-----------------------------
8755
8756 // Add float single precision
8757 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
8758 match(Set dst (AddF src1 src2));
8759
8760 format %{ "FADDS $dst, $src1, $src2" %}
8761 size(4);
8762 ins_encode %{
8763 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8764 %}
8765 ins_pipe(pipe_class_default);
8766 %}
8767
8768 // Add float double precision
8769 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
8770 match(Set dst (AddD src1 src2));
8771
8772 format %{ "FADD $dst, $src1, $src2" %}
8773 size(4);
8774 ins_encode %{
8775 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8776 %}
8777 ins_pipe(pipe_class_default);
8778 %}
8779
8780 // Sub float single precision
8781 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
8782 match(Set dst (SubF src1 src2));
8783
8784 format %{ "FSUBS $dst, $src1, $src2" %}
8785 size(4);
8786 ins_encode %{
8787 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8788 %}
8789 ins_pipe(pipe_class_default);
8790 %}
8791
8792 // Sub float double precision
8793 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
8794 match(Set dst (SubD src1 src2));
8795 format %{ "FSUB $dst, $src1, $src2" %}
8796 size(4);
8797 ins_encode %{
8798 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8799 %}
8800 ins_pipe(pipe_class_default);
8801 %}
8802
8803 // Mul float single precision
8804 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
8805 match(Set dst (MulF src1 src2));
8806 format %{ "FMULS $dst, $src1, $src2" %}
8807 size(4);
8808 ins_encode %{
8809 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8810 %}
8811 ins_pipe(pipe_class_default);
8812 %}
8813
8814 // Mul float double precision
8815 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
8816 match(Set dst (MulD src1 src2));
8817 format %{ "FMUL $dst, $src1, $src2" %}
8818 size(4);
8819 ins_encode %{
8820 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8821 %}
8822 ins_pipe(pipe_class_default);
8823 %}
8824
8825 // Div float single precision
8826 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
8827 match(Set dst (DivF src1 src2));
8828 format %{ "FDIVS $dst, $src1, $src2" %}
8829 size(4);
8830 ins_encode %{
8831 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8832 %}
8833 ins_pipe(pipe_class_default);
8834 %}
8835
8836 // Div float double precision
8837 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
8838 match(Set dst (DivD src1 src2));
8839 format %{ "FDIV $dst, $src1, $src2" %}
8840 size(4);
8841 ins_encode %{
8842 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8843 %}
8844 ins_pipe(pipe_class_default);
8845 %}
8846
8847 // Absolute float single precision
8848 instruct absF_reg(regF dst, regF src) %{
8849 match(Set dst (AbsF src));
8850 format %{ "FABS $dst, $src \t// float" %}
8851 size(4);
8852 ins_encode %{
8853 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8854 %}
8855 ins_pipe(pipe_class_default);
8856 %}
8857
8858 // Absolute float double precision
8859 instruct absD_reg(regD dst, regD src) %{
8860 match(Set dst (AbsD src));
8861 format %{ "FABS $dst, $src \t// double" %}
8862 size(4);
8863 ins_encode %{
8864 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8865 %}
8866 ins_pipe(pipe_class_default);
8867 %}
8868
8869 instruct negF_reg(regF dst, regF src) %{
8870 match(Set dst (NegF src));
8871 format %{ "FNEG $dst, $src \t// float" %}
8872 size(4);
8873 ins_encode %{
8874 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8875 %}
8876 ins_pipe(pipe_class_default);
8877 %}
8878
8879 instruct negD_reg(regD dst, regD src) %{
8880 match(Set dst (NegD src));
8881 format %{ "FNEG $dst, $src \t// double" %}
8882 size(4);
8883 ins_encode %{
8884 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8885 %}
8886 ins_pipe(pipe_class_default);
8887 %}
8888
8889 // AbsF + NegF.
8890 instruct negF_absF_reg(regF dst, regF src) %{
8891 match(Set dst (NegF (AbsF src)));
8892 format %{ "FNABS $dst, $src \t// float" %}
8893 size(4);
8894 ins_encode %{
8895 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
8896 %}
8897 ins_pipe(pipe_class_default);
8898 %}
8899
8900 // AbsD + NegD.
8901 instruct negD_absD_reg(regD dst, regD src) %{
8902 match(Set dst (NegD (AbsD src)));
8903 format %{ "FNABS $dst, $src \t// double" %}
8904 size(4);
8905 ins_encode %{
8906 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
8907 %}
8908 ins_pipe(pipe_class_default);
8909 %}
8910
8911 // Sqrt float double precision
8912 instruct sqrtD_reg(regD dst, regD src) %{
8913 match(Set dst (SqrtD src));
8914 format %{ "FSQRT $dst, $src" %}
8915 size(4);
8916 ins_encode %{
8917 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
8918 %}
8919 ins_pipe(pipe_class_default);
8920 %}
8921
8922 // Single-precision sqrt.
8923 instruct sqrtF_reg(regF dst, regF src) %{
8924 match(Set dst (SqrtF src));
8925 ins_cost(DEFAULT_COST);
8926
8927 format %{ "FSQRTS $dst, $src" %}
8928 size(4);
8929 ins_encode %{
8930 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
8931 %}
8932 ins_pipe(pipe_class_default);
8933 %}
8934
8935
8936 // Multiply-Accumulate
8937 // src1 * src2 + src3
8938 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
8939 match(Set dst (FmaF src3 (Binary src1 src2)));
8940
8941 format %{ "FMADDS $dst, $src1, $src2, $src3" %}
8942 size(4);
8943 ins_encode %{
8944 assert(UseFMA, "Needs FMA instructions support.");
8945 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
8946 %}
8947 ins_pipe(pipe_class_default);
8948 %}
8949
8950 // src1 * src2 + src3
8951 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
8952 match(Set dst (FmaD src3 (Binary src1 src2)));
8953
8954 format %{ "FMADD $dst, $src1, $src2, $src3" %}
8955 size(4);
8956 ins_encode %{
8957 assert(UseFMA, "Needs FMA instructions support.");
8958 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
8959 %}
8960 ins_pipe(pipe_class_default);
8961 %}
8962
8963 // src1 * (-src2) + src3 = -(src1*src2-src3)
8964 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
8965 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
8966 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
8967
8968 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
8969 size(4);
8970 ins_encode %{
8971 assert(UseFMA, "Needs FMA instructions support.");
8972 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
8973 %}
8974 ins_pipe(pipe_class_default);
8975 %}
8976
8977 // src1 * (-src2) + src3 = -(src1*src2-src3)
8978 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
8979 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
8980 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
8981
8982 format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
8983 size(4);
8984 ins_encode %{
8985 assert(UseFMA, "Needs FMA instructions support.");
8986 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
8987 %}
8988 ins_pipe(pipe_class_default);
8989 %}
8990
8991 // src1 * (-src2) - src3 = -(src1*src2+src3)
8992 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
8993 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
8994 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
8995
8996 format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
8997 size(4);
8998 ins_encode %{
8999 assert(UseFMA, "Needs FMA instructions support.");
9000 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9001 %}
9002 ins_pipe(pipe_class_default);
9003 %}
9004
9005 // src1 * (-src2) - src3 = -(src1*src2+src3)
9006 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9007 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9008 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9009
9010 format %{ "FNMADD $dst, $src1, $src2, $src3" %}
9011 size(4);
9012 ins_encode %{
9013 assert(UseFMA, "Needs FMA instructions support.");
9014 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9015 %}
9016 ins_pipe(pipe_class_default);
9017 %}
9018
9019 // src1 * src2 - src3
9020 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9021 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9022
9023 format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
9024 size(4);
9025 ins_encode %{
9026 assert(UseFMA, "Needs FMA instructions support.");
9027 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9028 %}
9029 ins_pipe(pipe_class_default);
9030 %}
9031
9032 // src1 * src2 - src3
9033 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9034 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9035
9036 format %{ "FMSUB $dst, $src1, $src2, $src3" %}
9037 size(4);
9038 ins_encode %{
9039 assert(UseFMA, "Needs FMA instructions support.");
9040 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9041 %}
9042 ins_pipe(pipe_class_default);
9043 %}
9044
9045
9046 //----------Logical Instructions-----------------------------------------------
9047
9048 // And Instructions
9049
9050 // Register And
9051 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9052 match(Set dst (AndI src1 src2));
9053 format %{ "AND $dst, $src1, $src2" %}
9054 size(4);
9055 ins_encode %{
9056 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9057 %}
9058 ins_pipe(pipe_class_default);
9059 %}
9060
9061 instruct andI_reg_immI(iRegIdst dst, iRegIsrc src1, immI src2, flagsRegCR0 cr0) %{
9062 match(Set dst (AndI src1 src2));
9063 predicate(Assembler::andi_supports((juint)(n->in(2)->get_int())));
9064 effect(KILL cr0);
9065 format %{ "ANDI $dst, $src1, $src2" %}
9066 size(4);
9067 ins_encode %{
9068 __ andi($dst$$Register, $src1$$Register, (juint)$src2$$constant); // optimized version
9069 %}
9070 ins_pipe(pipe_class_default);
9071 %}
9072
9073 // Register And Long
9074 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9075 match(Set dst (AndL src1 src2));
9076 ins_cost(DEFAULT_COST);
9077
9078 format %{ "AND $dst, $src1, $src2 \t// long" %}
9079 size(4);
9080 ins_encode %{
9081 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9082 %}
9083 ins_pipe(pipe_class_default);
9084 %}
9085
9086 instruct andL_reg_immL(iRegLdst dst, iRegLsrc src1, immL src2, flagsRegCR0 cr0) %{
9087 match(Set dst (AndL src1 src2));
9088 predicate(Assembler::andi_supports(n->in(2)->get_long()));
9089 effect(KILL cr0);
9090 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9091 size(4);
9092 ins_encode %{
9093 __ andi($dst$$Register, $src1$$Register, $src2$$constant); // optimized version
9094 %}
9095 ins_pipe(pipe_class_default);
9096 %}
9097
9098 // AndL + ConvL2I.
9099 instruct convL2I_andL_reg_immL(iRegIdst dst, iRegLsrc src1, immL src2, flagsRegCR0 cr0) %{
9100 match(Set dst (ConvL2I (AndL src1 src2)));
9101 predicate(Assembler::andi_supports(n->in(1)->in(2)->get_long()));
9102 effect(KILL cr0);
9103 format %{ "ANDI $dst, $src1, $src2 \t// long + l2i" %}
9104 size(4);
9105 ins_encode %{
9106 __ andi($dst$$Register, $src1$$Register, $src2$$constant); // optimized version
9107 %}
9108 ins_pipe(pipe_class_default);
9109 %}
9110
9111 // Or Instructions
9112
9113 // Register Or
9114 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9115 match(Set dst (OrI src1 src2));
9116 format %{ "OR $dst, $src1, $src2" %}
9117 size(4);
9118 ins_encode %{
9119 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9120 %}
9121 ins_pipe(pipe_class_default);
9122 %}
9123
9124 // Expand does not work with above instruct. (??)
9125 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9126 // no match-rule
9127 effect(DEF dst, USE src1, USE src2);
9128 format %{ "OR $dst, $src1, $src2" %}
9129 size(4);
9130 ins_encode %{
9131 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9132 %}
9133 ins_pipe(pipe_class_default);
9134 %}
9135
9136 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9137 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9138 ins_cost(DEFAULT_COST*3);
9139
9140 expand %{
9141 // FIXME: we should do this in the ideal world.
9142 iRegIdst tmp1;
9143 iRegIdst tmp2;
9144 orI_reg_reg(tmp1, src1, src2);
9145 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9146 orI_reg_reg(dst, tmp1, tmp2);
9147 %}
9148 %}
9149
9150 // Immediate Or
9151 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9152 match(Set dst (OrI src1 src2));
9153 format %{ "ORI $dst, $src1, $src2" %}
9154 size(4);
9155 ins_encode %{
9156 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9157 %}
9158 ins_pipe(pipe_class_default);
9159 %}
9160
9161 // Register Or Long
9162 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9163 match(Set dst (OrL src1 src2));
9164 ins_cost(DEFAULT_COST);
9165
9166 size(4);
9167 format %{ "OR $dst, $src1, $src2 \t// long" %}
9168 ins_encode %{
9169 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9170 %}
9171 ins_pipe(pipe_class_default);
9172 %}
9173
9174 // OrL + ConvL2I.
9175 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9176 match(Set dst (ConvL2I (OrL src1 src2)));
9177 ins_cost(DEFAULT_COST);
9178
9179 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %}
9180 size(4);
9181 ins_encode %{
9182 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9183 %}
9184 ins_pipe(pipe_class_default);
9185 %}
9186
9187 // Immediate Or long
9188 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9189 match(Set dst (OrL src1 con));
9190 ins_cost(DEFAULT_COST);
9191
9192 format %{ "ORI $dst, $src1, $con \t// long" %}
9193 size(4);
9194 ins_encode %{
9195 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9196 %}
9197 ins_pipe(pipe_class_default);
9198 %}
9199
9200 // Xor Instructions
9201
9202 // Register Xor
9203 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9204 match(Set dst (XorI src1 src2));
9205 format %{ "XOR $dst, $src1, $src2" %}
9206 size(4);
9207 ins_encode %{
9208 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9209 %}
9210 ins_pipe(pipe_class_default);
9211 %}
9212
9213 // Expand does not work with above instruct. (??)
9214 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9215 // no match-rule
9216 effect(DEF dst, USE src1, USE src2);
9217 format %{ "XOR $dst, $src1, $src2" %}
9218 size(4);
9219 ins_encode %{
9220 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9221 %}
9222 ins_pipe(pipe_class_default);
9223 %}
9224
9225 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9226 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
9227 ins_cost(DEFAULT_COST*3);
9228
9229 expand %{
9230 // FIXME: we should do this in the ideal world.
9231 iRegIdst tmp1;
9232 iRegIdst tmp2;
9233 xorI_reg_reg(tmp1, src1, src2);
9234 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
9235 xorI_reg_reg(dst, tmp1, tmp2);
9236 %}
9237 %}
9238
9239 // Immediate Xor
9240 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9241 match(Set dst (XorI src1 src2));
9242 format %{ "XORI $dst, $src1, $src2" %}
9243 size(4);
9244 ins_encode %{
9245 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9246 %}
9247 ins_pipe(pipe_class_default);
9248 %}
9249
9250 // Register Xor Long
9251 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9252 match(Set dst (XorL src1 src2));
9253 ins_cost(DEFAULT_COST);
9254
9255 format %{ "XOR $dst, $src1, $src2 \t// long" %}
9256 size(4);
9257 ins_encode %{
9258 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9259 %}
9260 ins_pipe(pipe_class_default);
9261 %}
9262
9263 // XorL + ConvL2I.
9264 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9265 match(Set dst (ConvL2I (XorL src1 src2)));
9266 ins_cost(DEFAULT_COST);
9267
9268 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %}
9269 size(4);
9270 ins_encode %{
9271 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9272 %}
9273 ins_pipe(pipe_class_default);
9274 %}
9275
9276 // Immediate Xor Long
9277 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
9278 match(Set dst (XorL src1 src2));
9279 ins_cost(DEFAULT_COST);
9280
9281 format %{ "XORI $dst, $src1, $src2 \t// long" %}
9282 size(4);
9283 ins_encode %{
9284 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9285 %}
9286 ins_pipe(pipe_class_default);
9287 %}
9288
9289 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
9290 match(Set dst (XorI src1 src2));
9291 ins_cost(DEFAULT_COST);
9292
9293 format %{ "NOT $dst, $src1 ($src2)" %}
9294 size(4);
9295 ins_encode %{
9296 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9297 %}
9298 ins_pipe(pipe_class_default);
9299 %}
9300
9301 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
9302 match(Set dst (XorL src1 src2));
9303 ins_cost(DEFAULT_COST);
9304
9305 format %{ "NOT $dst, $src1 ($src2) \t// long" %}
9306 size(4);
9307 ins_encode %{
9308 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9309 %}
9310 ins_pipe(pipe_class_default);
9311 %}
9312
9313 // And-complement
9314 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
9315 match(Set dst (AndI (XorI src1 src2) src3));
9316 ins_cost(DEFAULT_COST);
9317
9318 format %{ "ANDW $dst, xori($src1, $src2), $src3" %}
9319 size(4);
9320 ins_encode( enc_andc(dst, src3, src1) );
9321 ins_pipe(pipe_class_default);
9322 %}
9323
9324 // And-complement
9325 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9326 // no match-rule, false predicate
9327 effect(DEF dst, USE src1, USE src2);
9328 predicate(false);
9329
9330 format %{ "ANDC $dst, $src1, $src2" %}
9331 size(4);
9332 ins_encode %{
9333 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
9334 %}
9335 ins_pipe(pipe_class_default);
9336 %}
9337
9338 //----------Moves between int/long and float/double----------------------------
9339 //
9340 // The following rules move values from int/long registers/stack-locations
9341 // to float/double registers/stack-locations and vice versa, without doing any
9342 // conversions. These rules are used to implement the bit-conversion methods
9343 // of java.lang.Float etc., e.g.
9344 // int floatToIntBits(float value)
9345 // float intBitsToFloat(int bits)
9346
9347 instruct moveL2D_reg(regD dst, iRegLsrc src) %{
9348 match(Set dst (MoveL2D src));
9349
9350 format %{ "MTFPRD $dst, $src" %}
9351 size(4);
9352 ins_encode %{
9353 __ mtfprd($dst$$FloatRegister, $src$$Register);
9354 %}
9355 ins_pipe(pipe_class_default);
9356 %}
9357
9358 instruct moveI2D_reg(regD dst, iRegIsrc src) %{
9359 // no match-rule, false predicate
9360 effect(DEF dst, USE src);
9361 predicate(false);
9362
9363 format %{ "MTFPRWA $dst, $src" %}
9364 size(4);
9365 ins_encode %{
9366 __ mtfprwa($dst$$FloatRegister, $src$$Register);
9367 %}
9368 ins_pipe(pipe_class_default);
9369 %}
9370
9371 //---------- Chain stack slots between similar types --------
9372
9373 // These are needed so that the rules below can match.
9374
9375 // Load integer from stack slot
9376 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
9377 match(Set dst src);
9378 ins_cost(MEMORY_REF_COST);
9379
9380 format %{ "LWZ $dst, $src" %}
9381 size(4);
9382 ins_encode( enc_lwz(dst, src) );
9383 ins_pipe(pipe_class_memory);
9384 %}
9385
9386 // Store integer to stack slot
9387 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
9388 match(Set dst src);
9389 ins_cost(MEMORY_REF_COST);
9390
9391 format %{ "STW $src, $dst \t// stk" %}
9392 size(4);
9393 ins_encode( enc_stw(src, dst) ); // rs=rt
9394 ins_pipe(pipe_class_memory);
9395 %}
9396
9397 // Load long from stack slot
9398 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
9399 match(Set dst src);
9400 ins_cost(MEMORY_REF_COST);
9401
9402 format %{ "LD $dst, $src \t// long" %}
9403 size(4);
9404 ins_encode( enc_ld(dst, src) );
9405 ins_pipe(pipe_class_memory);
9406 %}
9407
9408 // Store long to stack slot
9409 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
9410 match(Set dst src);
9411 ins_cost(MEMORY_REF_COST);
9412
9413 format %{ "STD $src, $dst \t// long" %}
9414 size(4);
9415 ins_encode( enc_std(src, dst) ); // rs=rt
9416 ins_pipe(pipe_class_memory);
9417 %}
9418
9419 //----------Moves between int and float
9420
9421 // Move float value from float stack-location to integer register.
9422 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
9423 match(Set dst (MoveF2I src));
9424 ins_cost(MEMORY_REF_COST);
9425
9426 format %{ "LWZ $dst, $src \t// MoveF2I" %}
9427 size(4);
9428 ins_encode( enc_lwz(dst, src) );
9429 ins_pipe(pipe_class_memory);
9430 %}
9431
9432 // Move float value from float register to integer stack-location.
9433 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
9434 match(Set dst (MoveF2I src));
9435 ins_cost(MEMORY_REF_COST);
9436
9437 format %{ "STFS $src, $dst \t// MoveF2I" %}
9438 size(4);
9439 ins_encode( enc_stfs(src, dst) );
9440 ins_pipe(pipe_class_memory);
9441 %}
9442
9443 // Move integer value from integer stack-location to float register.
9444 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
9445 match(Set dst (MoveI2F src));
9446 ins_cost(MEMORY_REF_COST);
9447
9448 format %{ "LFS $dst, $src \t// MoveI2F" %}
9449 size(4);
9450 ins_encode %{
9451 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
9452 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
9453 %}
9454 ins_pipe(pipe_class_memory);
9455 %}
9456
9457 // Move integer value from integer register to float stack-location.
9458 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
9459 match(Set dst (MoveI2F src));
9460 ins_cost(MEMORY_REF_COST);
9461
9462 format %{ "STW $src, $dst \t// MoveI2F" %}
9463 size(4);
9464 ins_encode( enc_stw(src, dst) );
9465 ins_pipe(pipe_class_memory);
9466 %}
9467
9468
9469 //----------Moves between long and double
9470
9471 // Move double value from double stack-location to long register.
9472 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
9473 match(Set dst (MoveD2L src));
9474 ins_cost(MEMORY_REF_COST);
9475 size(4);
9476 format %{ "LD $dst, $src \t// MoveD2L" %}
9477 ins_encode( enc_ld(dst, src) );
9478 ins_pipe(pipe_class_memory);
9479 %}
9480
9481 // Move double value from double register to long stack-location.
9482 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
9483 match(Set dst (MoveD2L src));
9484 effect(DEF dst, USE src);
9485 ins_cost(MEMORY_REF_COST);
9486
9487 format %{ "STFD $src, $dst \t// MoveD2L" %}
9488 size(4);
9489 ins_encode( enc_stfd(src, dst) );
9490 ins_pipe(pipe_class_memory);
9491 %}
9492
9493
9494 //----------Register Move Instructions-----------------------------------------
9495
9496 // Replicate for Superword
9497
9498 instruct moveReg(iRegLdst dst, iRegIsrc src) %{
9499 predicate(false);
9500 effect(DEF dst, USE src);
9501
9502 format %{ "MR $dst, $src \t// replicate " %}
9503 // variable size, 0 or 4.
9504 ins_encode %{
9505 __ mr_if_needed($dst$$Register, $src$$Register);
9506 %}
9507 ins_pipe(pipe_class_default);
9508 %}
9509
9510 //----------Cast instructions (Java-level type cast)---------------------------
9511
9512 // Cast Long to Pointer for unsafe natives.
9513 instruct castX2P(iRegPdst dst, iRegLsrc src) %{
9514 match(Set dst (CastX2P src));
9515
9516 format %{ "MR $dst, $src \t// Long->Ptr" %}
9517 // variable size, 0 or 4.
9518 ins_encode %{
9519 __ mr_if_needed($dst$$Register, $src$$Register);
9520 %}
9521 ins_pipe(pipe_class_default);
9522 %}
9523
9524 // Cast Pointer to Long for unsafe natives.
9525 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
9526 match(Set dst (CastP2X src));
9527
9528 format %{ "MR $dst, $src \t// Ptr->Long" %}
9529 // variable size, 0 or 4.
9530 ins_encode %{
9531 __ mr_if_needed($dst$$Register, $src$$Register);
9532 %}
9533 ins_pipe(pipe_class_default);
9534 %}
9535
9536 instruct castPP(iRegPdst dst) %{
9537 match(Set dst (CastPP dst));
9538 format %{ " -- \t// castPP of $dst" %}
9539 size(0);
9540 ins_encode( /*empty*/ );
9541 ins_pipe(pipe_class_default);
9542 %}
9543
9544 instruct castII(iRegIdst dst) %{
9545 match(Set dst (CastII dst));
9546 format %{ " -- \t// castII of $dst" %}
9547 size(0);
9548 ins_encode( /*empty*/ );
9549 ins_pipe(pipe_class_default);
9550 %}
9551
9552 instruct castLL(iRegLdst dst) %{
9553 match(Set dst (CastLL dst));
9554 format %{ " -- \t// castLL of $dst" %}
9555 size(0);
9556 ins_encode( /*empty*/ );
9557 ins_pipe(pipe_class_default);
9558 %}
9559
9560 instruct castFF(regF dst) %{
9561 match(Set dst (CastFF dst));
9562 format %{ " -- \t// castFF of $dst" %}
9563 size(0);
9564 ins_encode( /*empty*/ );
9565 ins_pipe(pipe_class_default);
9566 %}
9567
9568 instruct castDD(regD dst) %{
9569 match(Set dst (CastDD dst));
9570 format %{ " -- \t// castDD of $dst" %}
9571 size(0);
9572 ins_encode( /*empty*/ );
9573 ins_pipe(pipe_class_default);
9574 %}
9575
9576 instruct castVV8(iRegLdst dst) %{
9577 match(Set dst (CastVV dst));
9578 format %{ " -- \t// castVV of $dst" %}
9579 size(0);
9580 ins_encode( /*empty*/ );
9581 ins_pipe(pipe_class_default);
9582 %}
9583
9584 instruct castVV16(vecX dst) %{
9585 match(Set dst (CastVV dst));
9586 format %{ " -- \t// castVV of $dst" %}
9587 size(0);
9588 ins_encode( /*empty*/ );
9589 ins_pipe(pipe_class_default);
9590 %}
9591
9592 instruct checkCastPP(iRegPdst dst) %{
9593 match(Set dst (CheckCastPP dst));
9594 format %{ " -- \t// checkcastPP of $dst" %}
9595 size(0);
9596 ins_encode( /*empty*/ );
9597 ins_pipe(pipe_class_default);
9598 %}
9599
9600 //----------Convert instructions-----------------------------------------------
9601
9602 // Convert to boolean.
9603
9604 // int_to_bool(src) : { 1 if src != 0
9605 // { 0 else
9606 //
9607 // strategy:
9608 // 1) Count leading zeros of 32 bit-value src,
9609 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
9610 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9611 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9612
9613 // convI2Bool
9614 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
9615 match(Set dst (Conv2B src));
9616 predicate(UseCountLeadingZerosInstructionsPPC64);
9617 ins_cost(DEFAULT_COST);
9618
9619 expand %{
9620 immI shiftAmount %{ 0x5 %}
9621 uimmI16 mask %{ 0x1 %}
9622 iRegIdst tmp1;
9623 iRegIdst tmp2;
9624 countLeadingZerosI(tmp1, src);
9625 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9626 xorI_reg_uimm16(dst, tmp2, mask);
9627 %}
9628 %}
9629
9630 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
9631 match(Set dst (Conv2B src));
9632 effect(TEMP crx);
9633 predicate(!UseCountLeadingZerosInstructionsPPC64);
9634 ins_cost(DEFAULT_COST);
9635
9636 format %{ "CMPWI $crx, $src, #0 \t// convI2B"
9637 "LI $dst, #0\n\t"
9638 "BEQ $crx, done\n\t"
9639 "LI $dst, #1\n"
9640 "done:" %}
9641 size(16);
9642 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
9643 ins_pipe(pipe_class_compare);
9644 %}
9645
9646 // ConvI2B + XorI
9647 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
9648 match(Set dst (XorI (Conv2B src) mask));
9649 predicate(UseCountLeadingZerosInstructionsPPC64);
9650 ins_cost(DEFAULT_COST);
9651
9652 expand %{
9653 immI shiftAmount %{ 0x5 %}
9654 iRegIdst tmp1;
9655 countLeadingZerosI(tmp1, src);
9656 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9657 %}
9658 %}
9659
9660 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
9661 match(Set dst (XorI (Conv2B src) mask));
9662 effect(TEMP crx);
9663 predicate(!UseCountLeadingZerosInstructionsPPC64);
9664 ins_cost(DEFAULT_COST);
9665
9666 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
9667 "LI $dst, #1\n\t"
9668 "BEQ $crx, done\n\t"
9669 "LI $dst, #0\n"
9670 "done:" %}
9671 size(16);
9672 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
9673 ins_pipe(pipe_class_compare);
9674 %}
9675
9676 // AndI 0b0..010..0 + ConvI2B
9677 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
9678 match(Set dst (Conv2B (AndI src mask)));
9679 predicate(UseRotateAndMaskInstructionsPPC64);
9680 ins_cost(DEFAULT_COST);
9681
9682 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
9683 size(4);
9684 ins_encode %{
9685 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31);
9686 %}
9687 ins_pipe(pipe_class_default);
9688 %}
9689
9690 // Convert pointer to boolean.
9691 //
9692 // ptr_to_bool(src) : { 1 if src != 0
9693 // { 0 else
9694 //
9695 // strategy:
9696 // 1) Count leading zeros of 64 bit-value src,
9697 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
9698 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9699 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9700
9701 // ConvP2B
9702 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
9703 match(Set dst (Conv2B src));
9704 predicate(UseCountLeadingZerosInstructionsPPC64);
9705 ins_cost(DEFAULT_COST);
9706
9707 expand %{
9708 immI shiftAmount %{ 0x6 %}
9709 uimmI16 mask %{ 0x1 %}
9710 iRegIdst tmp1;
9711 iRegIdst tmp2;
9712 countLeadingZerosP(tmp1, src);
9713 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9714 xorI_reg_uimm16(dst, tmp2, mask);
9715 %}
9716 %}
9717
9718 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
9719 match(Set dst (Conv2B src));
9720 effect(TEMP crx);
9721 predicate(!UseCountLeadingZerosInstructionsPPC64);
9722 ins_cost(DEFAULT_COST);
9723
9724 format %{ "CMPDI $crx, $src, #0 \t// convP2B"
9725 "LI $dst, #0\n\t"
9726 "BEQ $crx, done\n\t"
9727 "LI $dst, #1\n"
9728 "done:" %}
9729 size(16);
9730 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
9731 ins_pipe(pipe_class_compare);
9732 %}
9733
9734 // ConvP2B + XorI
9735 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
9736 match(Set dst (XorI (Conv2B src) mask));
9737 predicate(UseCountLeadingZerosInstructionsPPC64);
9738 ins_cost(DEFAULT_COST);
9739
9740 expand %{
9741 immI shiftAmount %{ 0x6 %}
9742 iRegIdst tmp1;
9743 countLeadingZerosP(tmp1, src);
9744 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9745 %}
9746 %}
9747
9748 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
9749 match(Set dst (XorI (Conv2B src) mask));
9750 effect(TEMP crx);
9751 predicate(!UseCountLeadingZerosInstructionsPPC64);
9752 ins_cost(DEFAULT_COST);
9753
9754 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
9755 "LI $dst, #1\n\t"
9756 "BEQ $crx, done\n\t"
9757 "LI $dst, #0\n"
9758 "done:" %}
9759 size(16);
9760 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
9761 ins_pipe(pipe_class_compare);
9762 %}
9763
9764 // if src1 < src2, return -1 else return 0
9765 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9766 match(Set dst (CmpLTMask src1 src2));
9767 ins_cost(DEFAULT_COST*4);
9768
9769 expand %{
9770 iRegLdst src1s;
9771 iRegLdst src2s;
9772 iRegLdst diff;
9773 convI2L_reg(src1s, src1); // Ensure proper sign extension.
9774 convI2L_reg(src2s, src2); // Ensure proper sign extension.
9775 subL_reg_reg(diff, src1s, src2s);
9776 // Need to consider >=33 bit result, therefore we need signmaskL.
9777 signmask64I_regL(dst, diff);
9778 %}
9779 %}
9780
9781 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
9782 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
9783 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %}
9784 size(4);
9785 ins_encode %{
9786 __ srawi($dst$$Register, $src1$$Register, 0x1f);
9787 %}
9788 ins_pipe(pipe_class_default);
9789 %}
9790
9791 //----------Arithmetic Conversion Instructions---------------------------------
9792
9793 // Convert to Byte -- nop
9794 // Convert to Short -- nop
9795
9796 // Convert to Int
9797
9798 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
9799 match(Set dst (RShiftI (LShiftI src amount) amount));
9800 format %{ "EXTSB $dst, $src \t// byte->int" %}
9801 size(4);
9802 ins_encode %{
9803 __ extsb($dst$$Register, $src$$Register);
9804 %}
9805 ins_pipe(pipe_class_default);
9806 %}
9807
9808 instruct extsh(iRegIdst dst, iRegIsrc src) %{
9809 effect(DEF dst, USE src);
9810
9811 size(4);
9812 ins_encode %{
9813 __ extsh($dst$$Register, $src$$Register);
9814 %}
9815 ins_pipe(pipe_class_default);
9816 %}
9817
9818 // LShiftI 16 + RShiftI 16 converts short to int.
9819 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
9820 match(Set dst (RShiftI (LShiftI src amount) amount));
9821 format %{ "EXTSH $dst, $src \t// short->int" %}
9822 size(4);
9823 ins_encode %{
9824 __ extsh($dst$$Register, $src$$Register);
9825 %}
9826 ins_pipe(pipe_class_default);
9827 %}
9828
9829 // ConvL2I + ConvI2L: Sign extend int in long register.
9830 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
9831 match(Set dst (ConvI2L (ConvL2I src)));
9832
9833 format %{ "EXTSW $dst, $src \t// long->long" %}
9834 size(4);
9835 ins_encode %{
9836 __ extsw($dst$$Register, $src$$Register);
9837 %}
9838 ins_pipe(pipe_class_default);
9839 %}
9840
9841 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
9842 match(Set dst (ConvL2I src));
9843 format %{ "MR $dst, $src \t// long->int" %}
9844 // variable size, 0 or 4
9845 ins_encode %{
9846 __ mr_if_needed($dst$$Register, $src$$Register);
9847 %}
9848 ins_pipe(pipe_class_default);
9849 %}
9850
9851 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
9852 // no match-rule, false predicate
9853 effect(DEF dst, USE crx, USE src);
9854 predicate(false);
9855
9856 format %{ "CMOVI $crx, $dst, $src" %}
9857 size(8);
9858 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
9859 ins_pipe(pipe_class_default);
9860 %}
9861
9862 instruct cmovI_bso_reg_con0(iRegIdst dst, flagsRegSrc crx, regD src) %{
9863 // no match-rule, false predicate
9864 effect(DEF dst, USE crx, USE src);
9865 predicate(false);
9866
9867 format %{ "CMOVI $dst, $crx, $src, 0 \t// set to 0 if unordered" %}
9868 size(12);
9869 ins_encode %{
9870 Label done;
9871 __ li($dst$$Register, 0);
9872 __ bso($crx$$CondRegister, done);
9873 __ mffprd($dst$$Register, $src$$FloatRegister);
9874 __ bind(done);
9875 %}
9876 ins_pipe(pipe_class_default);
9877 %}
9878
9879 instruct convD2IRaw_regD(regD dst, regD src) %{
9880 // no match-rule, false predicate
9881 effect(DEF dst, USE src);
9882 predicate(false);
9883
9884 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
9885 size(4);
9886 ins_encode %{
9887 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
9888 %}
9889 ins_pipe(pipe_class_default);
9890 %}
9891
9892 // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
9893 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
9894 match(Set dst (ConvD2I src));
9895 ins_cost(DEFAULT_COST);
9896
9897 expand %{
9898 regD tmpD;
9899 flagsReg crx;
9900 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
9901 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
9902 cmovI_bso_reg_con0(dst, crx, tmpD); // Cmove based on NaN check.
9903 %}
9904 %}
9905
9906 instruct convF2IRaw_regF(regF dst, regF src) %{
9907 // no match-rule, false predicate
9908 effect(DEF dst, USE src);
9909 predicate(false);
9910
9911 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
9912 size(4);
9913 ins_encode %{
9914 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
9915 %}
9916 ins_pipe(pipe_class_default);
9917 %}
9918
9919
9920 // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
9921 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
9922 match(Set dst (ConvF2I src));
9923 ins_cost(DEFAULT_COST);
9924
9925 expand %{
9926 regF tmpF;
9927 flagsReg crx;
9928 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
9929 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
9930 cmovI_bso_reg_con0(dst, crx, tmpF); // Cmove based on NaN check.
9931 %}
9932 %}
9933
9934 // Convert to Long
9935
9936 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
9937 match(Set dst (ConvI2L src));
9938 format %{ "EXTSW $dst, $src \t// int->long" %}
9939 size(4);
9940 ins_encode %{
9941 __ extsw($dst$$Register, $src$$Register);
9942 %}
9943 ins_pipe(pipe_class_default);
9944 %}
9945
9946 // Zero-extend: convert unsigned int to long (convUI2L).
9947 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
9948 match(Set dst (AndL (ConvI2L src) mask));
9949 ins_cost(DEFAULT_COST);
9950
9951 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
9952 size(4);
9953 ins_encode %{
9954 __ clrldi($dst$$Register, $src$$Register, 32);
9955 %}
9956 ins_pipe(pipe_class_default);
9957 %}
9958
9959 // Zero-extend: convert unsigned int to long in long register.
9960 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
9961 match(Set dst (AndL src mask));
9962 ins_cost(DEFAULT_COST);
9963
9964 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
9965 size(4);
9966 ins_encode %{
9967 __ clrldi($dst$$Register, $src$$Register, 32);
9968 %}
9969 ins_pipe(pipe_class_default);
9970 %}
9971
9972 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
9973 // no match-rule, false predicate
9974 effect(DEF dst, USE crx, USE src);
9975 predicate(false);
9976
9977 format %{ "CMOVL $crx, $dst, $src" %}
9978 size(8);
9979 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
9980 ins_pipe(pipe_class_default);
9981 %}
9982
9983 instruct cmovL_bso_reg_con0(iRegLdst dst, flagsRegSrc crx, regD src) %{
9984 // no match-rule, false predicate
9985 effect(DEF dst, USE crx, USE src);
9986 predicate(false);
9987
9988 format %{ "CMOVL $dst, $crx, $src, 0 \t// set to 0 if unordered" %}
9989 size(12);
9990 ins_encode %{
9991 Label done;
9992 __ li($dst$$Register, 0);
9993 __ bso($crx$$CondRegister, done);
9994 __ mffprd($dst$$Register, $src$$FloatRegister);
9995 __ bind(done);
9996 %}
9997 ins_pipe(pipe_class_default);
9998 %}
9999
10000 instruct convF2LRaw_regF(regF dst, regF src) %{
10001 // no match-rule, false predicate
10002 effect(DEF dst, USE src);
10003 predicate(false);
10004
10005 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10006 size(4);
10007 ins_encode %{
10008 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10009 %}
10010 ins_pipe(pipe_class_default);
10011 %}
10012
10013 // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
10014 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
10015 match(Set dst (ConvF2L src));
10016 ins_cost(DEFAULT_COST);
10017
10018 expand %{
10019 regF tmpF;
10020 flagsReg crx;
10021 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10022 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
10023 cmovL_bso_reg_con0(dst, crx, tmpF); // Cmove based on NaN check.
10024 %}
10025 %}
10026
10027 instruct convD2LRaw_regD(regD dst, regD src) %{
10028 // no match-rule, false predicate
10029 effect(DEF dst, USE src);
10030 predicate(false);
10031
10032 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
10033 size(4);
10034 ins_encode %{
10035 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10036 %}
10037 ins_pipe(pipe_class_default);
10038 %}
10039
10040 // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
10041 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
10042 match(Set dst (ConvD2L src));
10043 ins_cost(DEFAULT_COST);
10044
10045 expand %{
10046 regD tmpD;
10047 flagsReg crx;
10048 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10049 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
10050 cmovL_bso_reg_con0(dst, crx, tmpD); // Cmove based on NaN check.
10051 %}
10052 %}
10053
10054 // Convert to Float
10055
10056 // Placed here as needed in expand.
10057 instruct convL2DRaw_regD(regD dst, regD src) %{
10058 // no match-rule, false predicate
10059 effect(DEF dst, USE src);
10060 predicate(false);
10061
10062 format %{ "FCFID $dst, $src \t// convL2D" %}
10063 size(4);
10064 ins_encode %{
10065 __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
10066 %}
10067 ins_pipe(pipe_class_default);
10068 %}
10069
10070 // Placed here as needed in expand.
10071 instruct convD2F_reg(regF dst, regD src) %{
10072 match(Set dst (ConvD2F src));
10073 format %{ "FRSP $dst, $src \t// convD2F" %}
10074 size(4);
10075 ins_encode %{
10076 __ frsp($dst$$FloatRegister, $src$$FloatRegister);
10077 %}
10078 ins_pipe(pipe_class_default);
10079 %}
10080
10081 instruct convL2FRaw_regF(regF dst, regD src) %{
10082 // no match-rule, false predicate
10083 effect(DEF dst, USE src);
10084 predicate(false);
10085
10086 format %{ "FCFIDS $dst, $src \t// convL2F" %}
10087 size(4);
10088 ins_encode %{
10089 __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
10090 %}
10091 ins_pipe(pipe_class_default);
10092 %}
10093
10094
10095 // Integer to Float conversion. Special version for Power8.
10096 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
10097 match(Set dst (ConvI2F src));
10098 ins_cost(DEFAULT_COST);
10099
10100 expand %{
10101 regD tmpD;
10102 moveI2D_reg(tmpD, src);
10103 convL2FRaw_regF(dst, tmpD); // Convert to float.
10104 %}
10105 %}
10106
10107
10108 // L2F to avoid runtime call. Special version for Power8.
10109 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
10110 match(Set dst (ConvL2F src));
10111 ins_cost(DEFAULT_COST);
10112
10113 expand %{
10114 regD tmpD;
10115 moveL2D_reg(tmpD, src);
10116 convL2FRaw_regF(dst, tmpD); // Convert to float.
10117 %}
10118 %}
10119
10120 // Moved up as used in expand.
10121 //instruct convD2F_reg(regF dst, regD src) %{%}
10122
10123 // Convert to Double
10124
10125
10126 // Integer to Double conversion. Special version for Power8.
10127 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
10128 match(Set dst (ConvI2D src));
10129 ins_cost(DEFAULT_COST);
10130
10131 expand %{
10132 regD tmpD;
10133 moveI2D_reg(tmpD, src);
10134 convL2DRaw_regD(dst, tmpD); // Convert to double.
10135 %}
10136 %}
10137
10138
10139 // Long to Double conversion. Special version for Power8.
10140 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
10141 match(Set dst (ConvL2D src));
10142 ins_cost(DEFAULT_COST);
10143
10144 expand %{
10145 regD tmpD;
10146 moveL2D_reg(tmpD, src);
10147 convL2DRaw_regD(dst, tmpD); // Convert to double.
10148 %}
10149 %}
10150
10151 instruct convF2D_reg(regD dst, regF src) %{
10152 match(Set dst (ConvF2D src));
10153 format %{ "FMR $dst, $src \t// float->double" %}
10154 // variable size, 0 or 4
10155 ins_encode %{
10156 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
10157 %}
10158 ins_pipe(pipe_class_default);
10159 %}
10160
10161 instruct convF2HF_reg_reg(iRegIdst dst, regF src, regF tmp) %{
10162 match(Set dst (ConvF2HF src));
10163 effect(TEMP tmp);
10164 ins_cost(3 * DEFAULT_COST);
10165 size(12);
10166 format %{ "XSCVDPHP $tmp, $src\t# convert to half precision\n\t"
10167 "MFFPRD $dst, $tmp\t# move result from $tmp to $dst\n\t"
10168 "EXTSH $dst, $dst\t# make it a proper short"
10169 %}
10170 ins_encode %{
10171 __ f2hf($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
10172 %}
10173 ins_pipe(pipe_class_default);
10174 %}
10175
10176 instruct convHF2F_reg_reg(regF dst, iRegIsrc src) %{
10177 match(Set dst (ConvHF2F src));
10178 ins_cost(2 * DEFAULT_COST);
10179 size(8);
10180 format %{ "MTFPRD $dst, $src\t# move source from $src to $dst\n\t"
10181 "XSCVHPDP $dst, $dst\t# convert from half precision"
10182 %}
10183 ins_encode %{
10184 __ hf2f($dst$$FloatRegister, $src$$Register);
10185 %}
10186 ins_pipe(pipe_class_default);
10187 %}
10188
10189 //----------Control Flow Instructions------------------------------------------
10190 // Compare Instructions
10191
10192 // Compare Integers
10193 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10194 match(Set crx (CmpI src1 src2));
10195 size(4);
10196 format %{ "CMPW $crx, $src1, $src2" %}
10197 ins_encode %{
10198 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10199 %}
10200 ins_pipe(pipe_class_compare);
10201 %}
10202
10203 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
10204 match(Set crx (CmpI src1 src2));
10205 format %{ "CMPWI $crx, $src1, $src2" %}
10206 size(4);
10207 ins_encode %{
10208 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10209 %}
10210 ins_pipe(pipe_class_compare);
10211 %}
10212
10213 // (src1 & src2) == 0?
10214 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
10215 match(Set cr0 (CmpI (AndI src1 src2) zero));
10216 // r0 is killed
10217 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
10218 size(4);
10219 ins_encode %{
10220 __ andi_(R0, $src1$$Register, $src2$$constant);
10221 %}
10222 ins_pipe(pipe_class_compare);
10223 %}
10224
10225 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10226 match(Set crx (CmpL src1 src2));
10227 format %{ "CMPD $crx, $src1, $src2" %}
10228 size(4);
10229 ins_encode %{
10230 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
10231 %}
10232 ins_pipe(pipe_class_compare);
10233 %}
10234
10235 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
10236 match(Set crx (CmpL src1 src2));
10237 format %{ "CMPDI $crx, $src1, $src2" %}
10238 size(4);
10239 ins_encode %{
10240 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10241 %}
10242 ins_pipe(pipe_class_compare);
10243 %}
10244
10245 // Added CmpUL for LoopPredicate.
10246 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10247 match(Set crx (CmpUL src1 src2));
10248 format %{ "CMPLD $crx, $src1, $src2" %}
10249 size(4);
10250 ins_encode %{
10251 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10252 %}
10253 ins_pipe(pipe_class_compare);
10254 %}
10255
10256 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
10257 match(Set crx (CmpUL src1 src2));
10258 format %{ "CMPLDI $crx, $src1, $src2" %}
10259 size(4);
10260 ins_encode %{
10261 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10262 %}
10263 ins_pipe(pipe_class_compare);
10264 %}
10265
10266 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
10267 match(Set cr0 (CmpL (AndL src1 src2) zero));
10268 // r0 is killed
10269 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
10270 size(4);
10271 ins_encode %{
10272 __ and_(R0, $src1$$Register, $src2$$Register);
10273 %}
10274 ins_pipe(pipe_class_compare);
10275 %}
10276
10277 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
10278 match(Set cr0 (CmpL (AndL src1 src2) zero));
10279 // r0 is killed
10280 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
10281 size(4);
10282 ins_encode %{
10283 __ andi_(R0, $src1$$Register, $src2$$constant);
10284 %}
10285 ins_pipe(pipe_class_compare);
10286 %}
10287
10288 // Manifest a CmpL3 result in an integer register.
10289 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10290 match(Set dst (CmpL3 src1 src2));
10291 effect(KILL cr0);
10292 ins_cost(DEFAULT_COST * 5);
10293 size((VM_Version::has_brw() ? 16 : 20));
10294
10295 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %}
10296
10297 ins_encode %{
10298 __ cmpd(CR0, $src1$$Register, $src2$$Register);
10299 __ set_cmp3($dst$$Register);
10300 %}
10301 ins_pipe(pipe_class_default);
10302 %}
10303
10304 instruct cmpU3_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
10305 match(Set dst (CmpU3 src1 src2));
10306 effect(KILL cr0);
10307 ins_cost(DEFAULT_COST * 5);
10308 size((VM_Version::has_brw() ? 16 : 20));
10309
10310 format %{ "cmpU3_reg_reg $dst, $src1, $src2" %}
10311
10312 ins_encode %{
10313 __ cmplw(CR0, $src1$$Register, $src2$$Register);
10314 __ set_cmp3($dst$$Register);
10315 %}
10316 ins_pipe(pipe_class_default);
10317 %}
10318
10319 instruct cmpUL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10320 match(Set dst (CmpUL3 src1 src2));
10321 effect(KILL cr0);
10322 ins_cost(DEFAULT_COST * 5);
10323 size((VM_Version::has_brw() ? 16 : 20));
10324
10325 format %{ "cmpUL3_reg_reg $dst, $src1, $src2" %}
10326
10327 ins_encode %{
10328 __ cmpld(CR0, $src1$$Register, $src2$$Register);
10329 __ set_cmp3($dst$$Register);
10330 %}
10331 ins_pipe(pipe_class_default);
10332 %}
10333
10334 // Implicit range checks.
10335 // A range check in the ideal world has one of the following shapes:
10336 // - (If le (CmpU length index)), (IfTrue throw exception)
10337 // - (If lt (CmpU index length)), (IfFalse throw exception)
10338 //
10339 // Match range check 'If le (CmpU length index)'.
10340 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
10341 match(If cmp (CmpU src_length index));
10342 effect(USE labl);
10343 predicate(TrapBasedRangeChecks &&
10344 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
10345 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
10346 (Matcher::branches_to_uncommon_trap(_leaf)));
10347
10348 ins_is_TrapBasedCheckNode(true);
10349
10350 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %}
10351 size(4);
10352 ins_encode %{
10353 if ($cmp$$cmpcode == 0x1 /* less_equal */) {
10354 __ trap_range_check_le($src_length$$Register, $index$$constant);
10355 } else {
10356 // Both successors are uncommon traps, probability is 0.
10357 // Node got flipped during fixup flow.
10358 assert($cmp$$cmpcode == 0x9, "must be greater");
10359 __ trap_range_check_g($src_length$$Register, $index$$constant);
10360 }
10361 %}
10362 ins_pipe(pipe_class_trap);
10363 %}
10364
10365 // Match range check 'If lt (CmpU index length)'.
10366 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
10367 match(If cmp (CmpU src_index src_length));
10368 effect(USE labl);
10369 predicate(TrapBasedRangeChecks &&
10370 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10371 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10372 (Matcher::branches_to_uncommon_trap(_leaf)));
10373
10374 ins_is_TrapBasedCheckNode(true);
10375
10376 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
10377 size(4);
10378 ins_encode %{
10379 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10380 __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
10381 } else {
10382 // Both successors are uncommon traps, probability is 0.
10383 // Node got flipped during fixup flow.
10384 assert($cmp$$cmpcode == 0x8, "must be less");
10385 __ trap_range_check_l($src_index$$Register, $src_length$$Register);
10386 }
10387 %}
10388 ins_pipe(pipe_class_trap);
10389 %}
10390
10391 // Match range check 'If lt (CmpU index length)'.
10392 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
10393 match(If cmp (CmpU src_index length));
10394 effect(USE labl);
10395 predicate(TrapBasedRangeChecks &&
10396 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10397 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10398 (Matcher::branches_to_uncommon_trap(_leaf)));
10399
10400 ins_is_TrapBasedCheckNode(true);
10401
10402 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %}
10403 size(4);
10404 ins_encode %{
10405 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10406 __ trap_range_check_ge($src_index$$Register, $length$$constant);
10407 } else {
10408 // Both successors are uncommon traps, probability is 0.
10409 // Node got flipped during fixup flow.
10410 assert($cmp$$cmpcode == 0x8, "must be less");
10411 __ trap_range_check_l($src_index$$Register, $length$$constant);
10412 }
10413 %}
10414 ins_pipe(pipe_class_trap);
10415 %}
10416
10417 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10418 match(Set crx (CmpU src1 src2));
10419 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %}
10420 size(4);
10421 ins_encode %{
10422 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10423 %}
10424 ins_pipe(pipe_class_compare);
10425 %}
10426
10427 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
10428 match(Set crx (CmpU src1 src2));
10429 size(4);
10430 format %{ "CMPLWI $crx, $src1, $src2" %}
10431 ins_encode %{
10432 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10433 %}
10434 ins_pipe(pipe_class_compare);
10435 %}
10436
10437 // Implicit zero checks (more implicit null checks).
10438 // No constant pool entries required.
10439 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
10440 match(If cmp (CmpN value zero));
10441 effect(USE labl);
10442 predicate(TrapBasedNullChecks &&
10443 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10444 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10445 Matcher::branches_to_uncommon_trap(_leaf));
10446 ins_cost(1);
10447
10448 ins_is_TrapBasedCheckNode(true);
10449
10450 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
10451 size(4);
10452 ins_encode %{
10453 if ($cmp$$cmpcode == 0xA) {
10454 __ trap_null_check($value$$Register);
10455 } else {
10456 // Both successors are uncommon traps, probability is 0.
10457 // Node got flipped during fixup flow.
10458 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10459 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10460 }
10461 %}
10462 ins_pipe(pipe_class_trap);
10463 %}
10464
10465 // Compare narrow oops.
10466 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
10467 match(Set crx (CmpN src1 src2));
10468
10469 size(4);
10470 ins_cost(2);
10471 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %}
10472 ins_encode %{
10473 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10474 %}
10475 ins_pipe(pipe_class_compare);
10476 %}
10477
10478 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
10479 match(Set crx (CmpN src1 src2));
10480 // Make this more expensive than zeroCheckN_iReg_imm0.
10481 ins_cost(2);
10482
10483 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %}
10484 size(4);
10485 ins_encode %{
10486 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10487 %}
10488 ins_pipe(pipe_class_compare);
10489 %}
10490
10491 // Implicit zero checks (more implicit null checks).
10492 // No constant pool entries required.
10493 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
10494 match(If cmp (CmpP value zero));
10495 effect(USE labl);
10496 predicate(TrapBasedNullChecks &&
10497 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10498 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10499 Matcher::branches_to_uncommon_trap(_leaf));
10500 ins_cost(1); // Should not be cheaper than zeroCheckN.
10501
10502 ins_is_TrapBasedCheckNode(true);
10503
10504 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
10505 size(4);
10506 ins_encode %{
10507 if ($cmp$$cmpcode == 0xA) {
10508 __ trap_null_check($value$$Register);
10509 } else {
10510 // Both successors are uncommon traps, probability is 0.
10511 // Node got flipped during fixup flow.
10512 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10513 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10514 }
10515 %}
10516 ins_pipe(pipe_class_trap);
10517 %}
10518
10519 // Compare Pointers
10520 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
10521 match(Set crx (CmpP src1 src2));
10522 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %}
10523 size(4);
10524 ins_encode %{
10525 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10526 %}
10527 ins_pipe(pipe_class_compare);
10528 %}
10529
10530 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
10531 match(Set crx (CmpP src1 src2));
10532 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %}
10533 size(4);
10534 ins_encode %{
10535 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
10536 %}
10537 ins_pipe(pipe_class_compare);
10538 %}
10539
10540 // Used in postalloc expand.
10541 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
10542 // This match rule prevents reordering of node before a safepoint.
10543 // This only makes sense if this instructions is used exclusively
10544 // for the expansion of EncodeP!
10545 match(Set crx (CmpP src1 src2));
10546 predicate(false);
10547
10548 format %{ "CMPDI $crx, $src1, $src2" %}
10549 size(4);
10550 ins_encode %{
10551 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10552 %}
10553 ins_pipe(pipe_class_compare);
10554 %}
10555
10556 //----------Float Compares----------------------------------------------------
10557
10558 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
10559 // Needs matchrule, see cmpDUnordered.
10560 match(Set crx (CmpF src1 src2));
10561 // no match-rule, false predicate
10562 predicate(false);
10563
10564 format %{ "cmpFUrd $crx, $src1, $src2" %}
10565 size(4);
10566 ins_encode %{
10567 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10568 %}
10569 ins_pipe(pipe_class_default);
10570 %}
10571
10572 // Compare floating, generate condition code.
10573 instruct cmpF_reg_reg(flagsReg crx, regF src1, regF src2) %{
10574 match(Set crx (CmpF src1 src2));
10575 ins_cost(DEFAULT_COST+BRANCH_COST);
10576
10577 format %{ "CMPF $crx, $src1, $src2" %}
10578 size(16);
10579 ins_encode %{
10580 Label done;
10581 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10582 __ bns($crx$$CondRegister, done);
10583 __ li(R0, 0);
10584 __ cmpwi($crx$$CondRegister, R0, 1);
10585 __ bind(done);
10586 %}
10587 ins_pipe(pipe_class_default);
10588 %}
10589
10590 // Compare float, generate -1,0,1
10591 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{
10592 match(Set dst (CmpF3 src1 src2));
10593 effect(KILL cr0);
10594 ins_cost(DEFAULT_COST * 6);
10595 size((VM_Version::has_brw() ? 20 : 24));
10596
10597 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %}
10598
10599 ins_encode %{
10600 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
10601 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
10602 %}
10603 ins_pipe(pipe_class_default);
10604 %}
10605
10606 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
10607 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
10608 // node right before the conditional move using it.
10609 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
10610 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
10611 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
10612 // conditional move was supposed to be spilled.
10613 match(Set crx (CmpD src1 src2));
10614 // False predicate, shall not be matched.
10615 predicate(false);
10616
10617 format %{ "cmpFUrd $crx, $src1, $src2" %}
10618 size(4);
10619 ins_encode %{
10620 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10621 %}
10622 ins_pipe(pipe_class_default);
10623 %}
10624
10625 instruct cmpD_reg_reg(flagsReg crx, regD src1, regD src2) %{
10626 match(Set crx (CmpD src1 src2));
10627 ins_cost(DEFAULT_COST+BRANCH_COST);
10628
10629 format %{ "CMPD $crx, $src1, $src2" %}
10630 size(16);
10631 ins_encode %{
10632 Label done;
10633 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10634 __ bns($crx$$CondRegister, done);
10635 __ li(R0, 0);
10636 __ cmpwi($crx$$CondRegister, R0, 1);
10637 __ bind(done);
10638 %}
10639 ins_pipe(pipe_class_default);
10640 %}
10641
10642 // Compare double, generate -1,0,1
10643 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{
10644 match(Set dst (CmpD3 src1 src2));
10645 effect(KILL cr0);
10646 ins_cost(DEFAULT_COST * 6);
10647 size((VM_Version::has_brw() ? 20 : 24));
10648
10649 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %}
10650
10651 ins_encode %{
10652 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
10653 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
10654 %}
10655 ins_pipe(pipe_class_default);
10656 %}
10657
10658 // Compare char
10659 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10660 match(Set dst (Digit src1));
10661 effect(TEMP src2, TEMP crx);
10662 ins_cost(3 * DEFAULT_COST);
10663
10664 format %{ "LI $src2, 0x3930\n\t"
10665 "CMPRB $crx, 0, $src1, $src2\n\t"
10666 "SETB $dst, $crx" %}
10667 size(12);
10668 ins_encode %{
10669 // 0x30: 0, 0x39: 9
10670 __ li($src2$$Register, 0x3930);
10671 // compare src1 with ranges 0x30 to 0x39
10672 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
10673 __ setb($dst$$Register, $crx$$CondRegister);
10674 %}
10675 ins_pipe(pipe_class_default);
10676 %}
10677
10678 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10679 match(Set dst (LowerCase src1));
10680 effect(TEMP src2, TEMP crx);
10681 ins_cost(12 * DEFAULT_COST);
10682
10683 format %{ "LI $src2, 0x7A61\n\t"
10684 "CMPRB $crx, 0, $src1, $src2\n\t"
10685 "BGT $crx, done\n\t"
10686 "LIS $src2, (signed short)0xF6DF\n\t"
10687 "ORI $src2, $src2, 0xFFF8\n\t"
10688 "CMPRB $crx, 1, $src1, $src2\n\t"
10689 "BGT $crx, done\n\t"
10690 "LIS $src2, (signed short)0xAAB5\n\t"
10691 "ORI $src2, $src2, 0xBABA\n\t"
10692 "INSRDI $src2, $src2, 32, 0\n\t"
10693 "CMPEQB $crx, 1, $src1, $src2\n"
10694 "done:\n\t"
10695 "SETB $dst, $crx" %}
10696
10697 size(48);
10698 ins_encode %{
10699 Label done;
10700 // 0x61: a, 0x7A: z
10701 __ li($src2$$Register, 0x7A61);
10702 // compare src1 with ranges 0x61 to 0x7A
10703 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
10704 __ bgt($crx$$CondRegister, done);
10705
10706 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
10707 __ lis($src2$$Register, (signed short)0xF6DF);
10708 __ ori($src2$$Register, $src2$$Register, 0xFFF8);
10709 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
10710 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10711 __ bgt($crx$$CondRegister, done);
10712
10713 // 0xAA: feminine ordinal indicator
10714 // 0xB5: micro sign
10715 // 0xBA: masculine ordinal indicator
10716 __ lis($src2$$Register, (signed short)0xAAB5);
10717 __ ori($src2$$Register, $src2$$Register, 0xBABA);
10718 __ insrdi($src2$$Register, $src2$$Register, 32, 0);
10719 // compare src1 with 0xAA, 0xB5, and 0xBA
10720 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
10721
10722 __ bind(done);
10723 __ setb($dst$$Register, $crx$$CondRegister);
10724 %}
10725 ins_pipe(pipe_class_default);
10726 %}
10727
10728 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10729 match(Set dst (UpperCase src1));
10730 effect(TEMP src2, TEMP crx);
10731 ins_cost(7 * DEFAULT_COST);
10732
10733 format %{ "LI $src2, 0x5A41\n\t"
10734 "CMPRB $crx, 0, $src1, $src2\n\t"
10735 "BGT $crx, done\n\t"
10736 "LIS $src2, (signed short)0xD6C0\n\t"
10737 "ORI $src2, $src2, 0xDED8\n\t"
10738 "CMPRB $crx, 1, $src1, $src2\n"
10739 "done:\n\t"
10740 "SETB $dst, $crx" %}
10741
10742 size(28);
10743 ins_encode %{
10744 Label done;
10745 // 0x41: A, 0x5A: Z
10746 __ li($src2$$Register, 0x5A41);
10747 // compare src1 with a range 0x41 to 0x5A
10748 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
10749 __ bgt($crx$$CondRegister, done);
10750
10751 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
10752 __ lis($src2$$Register, (signed short)0xD6C0);
10753 __ ori($src2$$Register, $src2$$Register, 0xDED8);
10754 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
10755 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10756
10757 __ bind(done);
10758 __ setb($dst$$Register, $crx$$CondRegister);
10759 %}
10760 ins_pipe(pipe_class_default);
10761 %}
10762
10763 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10764 match(Set dst (Whitespace src1));
10765 predicate(PowerArchitecturePPC64 <= 9);
10766 effect(TEMP src2, TEMP crx);
10767 ins_cost(4 * DEFAULT_COST);
10768
10769 format %{ "LI $src2, 0x0D09\n\t"
10770 "ADDIS $src2, 0x201C\n\t"
10771 "CMPRB $crx, 1, $src1, $src2\n\t"
10772 "SETB $dst, $crx" %}
10773 size(16);
10774 ins_encode %{
10775 // 0x09 to 0x0D, 0x1C to 0x20
10776 __ li($src2$$Register, 0x0D09);
10777 __ addis($src2$$Register, $src2$$Register, 0x0201C);
10778 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
10779 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10780 __ setb($dst$$Register, $crx$$CondRegister);
10781 %}
10782 ins_pipe(pipe_class_default);
10783 %}
10784
10785 // Power 10 version, using prefixed addi to load 32-bit constant
10786 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10787 match(Set dst (Whitespace src1));
10788 predicate(PowerArchitecturePPC64 >= 10);
10789 effect(TEMP src2, TEMP crx);
10790 ins_cost(3 * DEFAULT_COST);
10791
10792 format %{ "PLI $src2, 0x201C0D09\n\t"
10793 "CMPRB $crx, 1, $src1, $src2\n\t"
10794 "SETB $dst, $crx" %}
10795 size(16);
10796 ins_encode %{
10797 // 0x09 to 0x0D, 0x1C to 0x20
10798 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
10799 __ pli($src2$$Register, 0x201C0D09);
10800 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
10801 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10802 __ setb($dst$$Register, $crx$$CondRegister);
10803 %}
10804 ins_pipe(pipe_class_default);
10805 ins_alignment(2);
10806 %}
10807
10808 //----------Branches---------------------------------------------------------
10809 // Jump
10810
10811 // Direct Branch.
10812 instruct branch(label labl) %{
10813 match(Goto);
10814 effect(USE labl);
10815 ins_cost(BRANCH_COST);
10816
10817 format %{ "B $labl" %}
10818 size(4);
10819 ins_encode %{
10820 Label d; // dummy
10821 __ bind(d);
10822 Label* p = $labl$$label;
10823 // `p' is `nullptr' when this encoding class is used only to
10824 // determine the size of the encoded instruction.
10825 Label& l = (nullptr == p)? d : *(p);
10826 __ b(l);
10827 %}
10828 ins_pipe(pipe_class_default);
10829 %}
10830
10831 // Conditional Near Branch
10832 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
10833 // Same match rule as `branchConFar'.
10834 match(If cmp crx);
10835 effect(USE lbl);
10836 ins_cost(BRANCH_COST);
10837
10838 // If set to 1 this indicates that the current instruction is a
10839 // short variant of a long branch. This avoids using this
10840 // instruction in first-pass matching. It will then only be used in
10841 // the `Shorten_branches' pass.
10842 ins_short_branch(1);
10843
10844 format %{ "B$cmp $crx, $lbl" %}
10845 size(4);
10846 ins_encode( enc_bc(crx, cmp, lbl) );
10847 ins_pipe(pipe_class_default);
10848 %}
10849
10850 // This is for cases when the ppc64 `bc' instruction does not
10851 // reach far enough. So we emit a far branch here, which is more
10852 // expensive.
10853 //
10854 // Conditional Far Branch
10855 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
10856 // Same match rule as `branchCon'.
10857 match(If cmp crx);
10858 effect(USE crx, USE lbl);
10859 // Higher cost than `branchCon'.
10860 ins_cost(5*BRANCH_COST);
10861
10862 // This is not a short variant of a branch, but the long variant.
10863 ins_short_branch(0);
10864
10865 format %{ "B_FAR$cmp $crx, $lbl" %}
10866 size(8);
10867 ins_encode( enc_bc_far(crx, cmp, lbl) );
10868 ins_pipe(pipe_class_default);
10869 %}
10870
10871 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
10872 match(CountedLoopEnd cmp crx);
10873 effect(USE labl);
10874 ins_cost(BRANCH_COST);
10875
10876 // short variant.
10877 ins_short_branch(1);
10878
10879 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
10880 size(4);
10881 ins_encode( enc_bc(crx, cmp, labl) );
10882 ins_pipe(pipe_class_default);
10883 %}
10884
10885 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
10886 match(CountedLoopEnd cmp crx);
10887 effect(USE labl);
10888 ins_cost(BRANCH_COST);
10889
10890 // Long variant.
10891 ins_short_branch(0);
10892
10893 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
10894 size(8);
10895 ins_encode( enc_bc_far(crx, cmp, labl) );
10896 ins_pipe(pipe_class_default);
10897 %}
10898
10899 // ============================================================================
10900 // Java runtime operations, intrinsics and other complex operations.
10901
10902 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
10903 // array for an instance of the superklass. Set a hidden internal cache on a
10904 // hit (cache is checked with exposed code in gen_subtype_check()). Return
10905 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
10906 //
10907 // GL TODO: Improve this.
10908 // - result should not be a TEMP
10909 // - Add match rule as on sparc avoiding additional Cmp.
10910 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
10911 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
10912 match(Set result (PartialSubtypeCheck subklass superklass));
10913 predicate(!UseSecondarySupersTable);
10914 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
10915 ins_cost(DEFAULT_COST*10);
10916
10917 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
10918 ins_encode %{
10919 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
10920 $tmp_klass$$Register, nullptr, $result$$Register);
10921 %}
10922 ins_pipe(pipe_class_default);
10923 %}
10924
10925 // Two versions of partialSubtypeCheck, both used when we need to
10926 // search for a super class in the secondary supers array. The first
10927 // is used when we don't know _a priori_ the class being searched
10928 // for. The second, far more common, is used when we do know: this is
10929 // used for instanceof, checkcast, and any case where C2 can determine
10930 // it by constant propagation.
10931 instruct partialSubtypeCheckVarSuper(iRegPsrc sub, iRegPsrc super, iRegPdst result,
10932 iRegPdst tempR1, iRegPdst tempR2, iRegPdst tempR3, iRegPdst tempR4,
10933 flagsRegCR0 cr0, regCTR ctr)
10934 %{
10935 match(Set result (PartialSubtypeCheck sub super));
10936 predicate(UseSecondarySupersTable);
10937 effect(KILL cr0, KILL ctr, TEMP_DEF result, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
10938
10939 ins_cost(DEFAULT_COST * 10); // slightly larger than the next version
10940 format %{ "partialSubtypeCheck $result, $sub, $super" %}
10941 ins_encode %{
10942 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register,
10943 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
10944 $result$$Register);
10945 %}
10946 ins_pipe(pipe_class_memory);
10947 %}
10948
10949 instruct partialSubtypeCheckConstSuper(rarg3RegP sub, rarg2RegP super_reg, immP super_con, rarg6RegP result,
10950 rarg1RegP tempR1, rarg5RegP tempR2, rarg4RegP tempR3, rscratch1RegP tempR4,
10951 flagsRegCR0 cr0, regCTR ctr)
10952 %{
10953 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
10954 predicate(UseSecondarySupersTable);
10955 effect(KILL cr0, KILL ctr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
10956
10957 ins_cost(DEFAULT_COST*8); // smaller than the other version
10958 format %{ "partialSubtypeCheck $result, $sub, $super_reg" %}
10959
10960 ins_encode %{
10961 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
10962 if (InlineSecondarySupersTest) {
10963 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register,
10964 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
10965 $result$$Register, super_klass_slot);
10966 } else {
10967 address stub = StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot);
10968 Register r_stub_addr = $tempR1$$Register;
10969 __ add_const_optimized(r_stub_addr, R29_TOC, MacroAssembler::offset_to_global_toc(stub), R0);
10970 __ mtctr(r_stub_addr);
10971 __ bctrl();
10972 }
10973 %}
10974
10975 ins_pipe(pipe_class_memory);
10976 %}
10977
10978 // inlined locking and unlocking
10979
10980 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
10981 predicate(!UseObjectMonitorTable);
10982 match(Set crx (FastLock oop box));
10983 effect(TEMP tmp1, TEMP tmp2);
10984
10985 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %}
10986 ins_encode %{
10987 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
10988 $tmp1$$Register, $tmp2$$Register, noreg /*tmp3*/);
10989 // If locking was successful, crx should indicate 'EQ'.
10990 // The compiler generates a branch to the runtime call to
10991 // _complete_monitor_locking_Java for the case where crx is 'NE'.
10992 %}
10993 ins_pipe(pipe_class_compare);
10994 %}
10995
10996 instruct cmpFastLockMonitorTable(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, flagsRegCR1 cr1) %{
10997 predicate(UseObjectMonitorTable);
10998 match(Set crx (FastLock oop box));
10999 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr1);
11000
11001 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3" %}
11002 ins_encode %{
11003 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11004 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11005 // If locking was successful, crx should indicate 'EQ'.
11006 // The compiler generates a branch to the runtime call to
11007 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11008 %}
11009 ins_pipe(pipe_class_compare);
11010 %}
11011
11012 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11013 match(Set crx (FastUnlock oop box));
11014 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11015
11016 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
11017 ins_encode %{
11018 __ fast_unlock($crx$$CondRegister, $oop$$Register, $box$$Register,
11019 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11020 // If unlocking was successful, crx should indicate 'EQ'.
11021 // The compiler generates a branch to the runtime call to
11022 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11023 %}
11024 ins_pipe(pipe_class_compare);
11025 %}
11026
11027 // Align address.
11028 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11029 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11030
11031 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
11032 size(4);
11033 ins_encode %{
11034 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant));
11035 %}
11036 ins_pipe(pipe_class_default);
11037 %}
11038
11039 // Array size computation.
11040 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11041 match(Set dst (SubL (CastP2X end) (CastP2X start)));
11042
11043 format %{ "SUB $dst, $end, $start \t// array size in bytes" %}
11044 size(4);
11045 ins_encode %{
11046 __ subf($dst$$Register, $start$$Register, $end$$Register);
11047 %}
11048 ins_pipe(pipe_class_default);
11049 %}
11050
11051 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
11052 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11053 match(Set dummy (ClearArray cnt base));
11054 effect(USE_KILL base, KILL ctr);
11055 ins_cost(2 * MEMORY_REF_COST);
11056
11057 format %{ "ClearArray $cnt, $base" %}
11058 ins_encode %{
11059 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
11060 %}
11061 ins_pipe(pipe_class_default);
11062 %}
11063
11064 // Clear-array with constant large array length.
11065 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{
11066 match(Set dummy (ClearArray cnt base));
11067 effect(USE_KILL base, TEMP tmp, KILL ctr);
11068 ins_cost(3 * MEMORY_REF_COST);
11069
11070 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
11071 ins_encode %{
11072 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
11073 %}
11074 ins_pipe(pipe_class_default);
11075 %}
11076
11077 // Clear-array with dynamic array length.
11078 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11079 match(Set dummy (ClearArray cnt base));
11080 effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11081 ins_cost(4 * MEMORY_REF_COST);
11082
11083 format %{ "ClearArray $cnt, $base" %}
11084 ins_encode %{
11085 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
11086 %}
11087 ins_pipe(pipe_class_default);
11088 %}
11089
11090 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11091 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11092 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11093 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11094 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11095 ins_cost(300);
11096 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11097 ins_encode %{
11098 __ string_compare($str1$$Register, $str2$$Register,
11099 $cnt1$$Register, $cnt2$$Register,
11100 $tmp$$Register,
11101 $result$$Register, StrIntrinsicNode::LL);
11102 %}
11103 ins_pipe(pipe_class_default);
11104 %}
11105
11106 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11107 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11108 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11109 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11110 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11111 ins_cost(300);
11112 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11113 ins_encode %{
11114 __ string_compare($str1$$Register, $str2$$Register,
11115 $cnt1$$Register, $cnt2$$Register,
11116 $tmp$$Register,
11117 $result$$Register, StrIntrinsicNode::UU);
11118 %}
11119 ins_pipe(pipe_class_default);
11120 %}
11121
11122 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11123 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11124 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11125 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11126 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11127 ins_cost(300);
11128 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11129 ins_encode %{
11130 __ string_compare($str1$$Register, $str2$$Register,
11131 $cnt1$$Register, $cnt2$$Register,
11132 $tmp$$Register,
11133 $result$$Register, StrIntrinsicNode::LU);
11134 %}
11135 ins_pipe(pipe_class_default);
11136 %}
11137
11138 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11139 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11140 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11141 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11142 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11143 ins_cost(300);
11144 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11145 ins_encode %{
11146 __ string_compare($str2$$Register, $str1$$Register,
11147 $cnt2$$Register, $cnt1$$Register,
11148 $tmp$$Register,
11149 $result$$Register, StrIntrinsicNode::UL);
11150 %}
11151 ins_pipe(pipe_class_default);
11152 %}
11153
11154 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11155 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11156 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11157 match(Set result (StrEquals (Binary str1 str2) cnt));
11158 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11159 ins_cost(300);
11160 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11161 ins_encode %{
11162 __ array_equals(false, $str1$$Register, $str2$$Register,
11163 $cnt$$Register, $tmp$$Register,
11164 $result$$Register, true /* byte */);
11165 %}
11166 ins_pipe(pipe_class_default);
11167 %}
11168
11169 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11170 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11171 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11172 match(Set result (AryEq ary1 ary2));
11173 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11174 ins_cost(300);
11175 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11176 ins_encode %{
11177 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11178 $tmp1$$Register, $tmp2$$Register,
11179 $result$$Register, true /* byte */);
11180 %}
11181 ins_pipe(pipe_class_default);
11182 %}
11183
11184 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11185 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11186 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11187 match(Set result (AryEq ary1 ary2));
11188 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11189 ins_cost(300);
11190 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11191 ins_encode %{
11192 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11193 $tmp1$$Register, $tmp2$$Register,
11194 $result$$Register, false /* byte */);
11195 %}
11196 ins_pipe(pipe_class_default);
11197 %}
11198
11199 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11200 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11201 iRegIdst tmp1, iRegIdst tmp2,
11202 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11203 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11204 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11205 // Required for EA: check if it is still a type_array.
11206 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11207 ins_cost(150);
11208
11209 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11210 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11211
11212 ins_encode %{
11213 immPOper *needleOper = (immPOper *)$needleImm;
11214 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11215 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11216 jchar chr;
11217 #ifdef VM_LITTLE_ENDIAN
11218 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11219 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11220 #else
11221 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11222 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11223 #endif
11224 __ string_indexof_char($result$$Register,
11225 $haystack$$Register, $haycnt$$Register,
11226 R0, chr,
11227 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11228 %}
11229 ins_pipe(pipe_class_compare);
11230 %}
11231
11232 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11233 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11234 iRegIdst tmp1, iRegIdst tmp2,
11235 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11236 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11237 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11238 // Required for EA: check if it is still a type_array.
11239 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11240 ins_cost(150);
11241
11242 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11243 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11244
11245 ins_encode %{
11246 immPOper *needleOper = (immPOper *)$needleImm;
11247 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11248 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11249 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11250 __ string_indexof_char($result$$Register,
11251 $haystack$$Register, $haycnt$$Register,
11252 R0, chr,
11253 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11254 %}
11255 ins_pipe(pipe_class_compare);
11256 %}
11257
11258 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11259 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11260 iRegIdst tmp1, iRegIdst tmp2,
11261 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11262 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11263 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11264 // Required for EA: check if it is still a type_array.
11265 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11266 ins_cost(150);
11267
11268 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11269 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11270
11271 ins_encode %{
11272 immPOper *needleOper = (immPOper *)$needleImm;
11273 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11274 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11275 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11276 __ string_indexof_char($result$$Register,
11277 $haystack$$Register, $haycnt$$Register,
11278 R0, chr,
11279 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11280 %}
11281 ins_pipe(pipe_class_compare);
11282 %}
11283
11284 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11285 rscratch2RegP needle, immI_1 needlecntImm,
11286 iRegIdst tmp1, iRegIdst tmp2,
11287 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11288 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11289 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11290 // Required for EA: check if it is still a type_array.
11291 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11292 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11293 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11294 ins_cost(180);
11295
11296 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11297 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11298 ins_encode %{
11299 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11300 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11301 guarantee(needle_values, "sanity");
11302 jchar chr;
11303 #ifdef VM_LITTLE_ENDIAN
11304 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11305 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11306 #else
11307 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11308 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11309 #endif
11310 __ string_indexof_char($result$$Register,
11311 $haystack$$Register, $haycnt$$Register,
11312 R0, chr,
11313 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11314 %}
11315 ins_pipe(pipe_class_compare);
11316 %}
11317
11318 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11319 rscratch2RegP needle, immI_1 needlecntImm,
11320 iRegIdst tmp1, iRegIdst tmp2,
11321 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11322 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11323 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11324 // Required for EA: check if it is still a type_array.
11325 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11326 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11327 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11328 ins_cost(180);
11329
11330 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11331 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11332 ins_encode %{
11333 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11334 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11335 guarantee(needle_values, "sanity");
11336 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11337 __ string_indexof_char($result$$Register,
11338 $haystack$$Register, $haycnt$$Register,
11339 R0, chr,
11340 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11341 %}
11342 ins_pipe(pipe_class_compare);
11343 %}
11344
11345 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11346 rscratch2RegP needle, immI_1 needlecntImm,
11347 iRegIdst tmp1, iRegIdst tmp2,
11348 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11349 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11350 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11351 // Required for EA: check if it is still a type_array.
11352 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11353 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11354 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11355 ins_cost(180);
11356
11357 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11358 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11359 ins_encode %{
11360 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11361 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11362 guarantee(needle_values, "sanity");
11363 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11364 __ string_indexof_char($result$$Register,
11365 $haystack$$Register, $haycnt$$Register,
11366 R0, chr,
11367 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11368 %}
11369 ins_pipe(pipe_class_compare);
11370 %}
11371
11372 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11373 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11374 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11375 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11376 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11377 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
11378 ins_cost(180);
11379
11380 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch"
11381 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11382 ins_encode %{
11383 __ string_indexof_char($result$$Register,
11384 $haystack$$Register, $haycnt$$Register,
11385 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11386 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11387 %}
11388 ins_pipe(pipe_class_compare);
11389 %}
11390
11391 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11392 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11393 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11394 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11395 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11396 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
11397 ins_cost(180);
11398
11399 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch"
11400 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11401 ins_encode %{
11402 __ string_indexof_char($result$$Register,
11403 $haystack$$Register, $haycnt$$Register,
11404 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11405 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11406 %}
11407 ins_pipe(pipe_class_compare);
11408 %}
11409
11410 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11411 iRegPsrc needle, uimmI15 needlecntImm,
11412 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11413 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11414 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11415 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11416 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11417 // Required for EA: check if it is still a type_array.
11418 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11419 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11420 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11421 ins_cost(250);
11422
11423 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11424 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11425 ins_encode %{
11426 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11427 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11428
11429 __ string_indexof($result$$Register,
11430 $haystack$$Register, $haycnt$$Register,
11431 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11432 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11433 %}
11434 ins_pipe(pipe_class_compare);
11435 %}
11436
11437 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11438 iRegPsrc needle, uimmI15 needlecntImm,
11439 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11440 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11441 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11442 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11443 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11444 // Required for EA: check if it is still a type_array.
11445 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11446 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11447 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11448 ins_cost(250);
11449
11450 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11451 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11452 ins_encode %{
11453 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11454 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11455
11456 __ string_indexof($result$$Register,
11457 $haystack$$Register, $haycnt$$Register,
11458 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11459 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11460 %}
11461 ins_pipe(pipe_class_compare);
11462 %}
11463
11464 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11465 iRegPsrc needle, uimmI15 needlecntImm,
11466 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11467 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11468 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11469 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11470 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11471 // Required for EA: check if it is still a type_array.
11472 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11473 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11474 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11475 ins_cost(250);
11476
11477 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11478 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11479 ins_encode %{
11480 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11481 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11482
11483 __ string_indexof($result$$Register,
11484 $haystack$$Register, $haycnt$$Register,
11485 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11486 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11487 %}
11488 ins_pipe(pipe_class_compare);
11489 %}
11490
11491 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11492 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11493 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11494 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11495 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11496 TEMP_DEF result,
11497 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11498 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11499 ins_cost(300);
11500
11501 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11502 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11503 ins_encode %{
11504 __ string_indexof($result$$Register,
11505 $haystack$$Register, $haycnt$$Register,
11506 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11507 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11508 %}
11509 ins_pipe(pipe_class_compare);
11510 %}
11511
11512 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11513 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11514 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11515 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11516 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11517 TEMP_DEF result,
11518 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11519 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11520 ins_cost(300);
11521
11522 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11523 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11524 ins_encode %{
11525 __ string_indexof($result$$Register,
11526 $haystack$$Register, $haycnt$$Register,
11527 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11528 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11529 %}
11530 ins_pipe(pipe_class_compare);
11531 %}
11532
11533 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11534 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11535 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11536 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11537 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11538 TEMP_DEF result,
11539 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11540 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11541 ins_cost(300);
11542
11543 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11544 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11545 ins_encode %{
11546 __ string_indexof($result$$Register,
11547 $haystack$$Register, $haycnt$$Register,
11548 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11549 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11550 %}
11551 ins_pipe(pipe_class_compare);
11552 %}
11553
11554 // char[] to byte[] compression
11555 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11556 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11557 match(Set result (StrCompressedCopy src (Binary dst len)));
11558 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11559 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11560 ins_cost(300);
11561 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11562 ins_encode %{
11563 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11564 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11565 %}
11566 ins_pipe(pipe_class_default);
11567 %}
11568
11569 // byte[] to char[] inflation
11570 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
11571 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11572 match(Set dummy (StrInflatedCopy src (Binary dst len)));
11573 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11574 ins_cost(300);
11575 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11576 ins_encode %{
11577 Label Ldone;
11578 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
11579 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11580 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
11581 __ beq(CR0, Ldone);
11582 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
11583 __ bind(Ldone);
11584 %}
11585 ins_pipe(pipe_class_default);
11586 %}
11587
11588 // StringCoding.java intrinsics
11589 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
11590 regCTR ctr, flagsRegCR0 cr0)
11591 %{
11592 match(Set result (CountPositives ary1 len));
11593 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
11594 ins_cost(300);
11595 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
11596 ins_encode %{
11597 __ count_positives($ary1$$Register, $len$$Register, $result$$Register,
11598 $tmp1$$Register, $tmp2$$Register);
11599 %}
11600 ins_pipe(pipe_class_default);
11601 %}
11602
11603 // encode char[] to byte[] in ISO_8859_1
11604 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11605 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11606 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
11607 match(Set result (EncodeISOArray src (Binary dst len)));
11608 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11609 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11610 ins_cost(300);
11611 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11612 ins_encode %{
11613 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11614 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11615 %}
11616 ins_pipe(pipe_class_default);
11617 %}
11618
11619 // encode char[] to byte[] in ASCII
11620 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11621 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11622 predicate(((EncodeISOArrayNode*)n)->is_ascii());
11623 match(Set result (EncodeISOArray src (Binary dst len)));
11624 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11625 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11626 ins_cost(300);
11627 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11628 ins_encode %{
11629 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11630 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
11631 %}
11632 ins_pipe(pipe_class_default);
11633 %}
11634
11635
11636 //---------- Min/Max Instructions ---------------------------------------------
11637
11638
11639 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
11640 match(Set dst (MinI src1 src2));
11641 effect(KILL cr0);
11642 ins_cost(DEFAULT_COST*2);
11643
11644 size(8);
11645 ins_encode %{
11646 __ cmpw(CR0, $src1$$Register, $src2$$Register);
11647 __ isel($dst$$Register, CR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
11648 %}
11649 ins_pipe(pipe_class_default);
11650 %}
11651
11652
11653 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
11654 match(Set dst (MaxI src1 src2));
11655 effect(KILL cr0);
11656 ins_cost(DEFAULT_COST*2);
11657
11658 size(8);
11659 ins_encode %{
11660 __ cmpw(CR0, $src1$$Register, $src2$$Register);
11661 __ isel($dst$$Register, CR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
11662 %}
11663 ins_pipe(pipe_class_default);
11664 %}
11665
11666 instruct minF(regF dst, regF src1, regF src2) %{
11667 match(Set dst (MinF src1 src2));
11668 predicate(PowerArchitecturePPC64 >= 9);
11669 ins_cost(DEFAULT_COST);
11670
11671 format %{ "XSMINJDP $dst, $src1, $src2\t// MinF" %}
11672 size(4);
11673 ins_encode %{
11674 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11675 %}
11676 ins_pipe(pipe_class_default);
11677 %}
11678
11679 instruct minD(regD dst, regD src1, regD src2) %{
11680 match(Set dst (MinD src1 src2));
11681 predicate(PowerArchitecturePPC64 >= 9);
11682 ins_cost(DEFAULT_COST);
11683
11684 format %{ "XSMINJDP $dst, $src1, $src2\t// MinD" %}
11685 size(4);
11686 ins_encode %{
11687 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11688 %}
11689 ins_pipe(pipe_class_default);
11690 %}
11691
11692 instruct maxF(regF dst, regF src1, regF src2) %{
11693 match(Set dst (MaxF src1 src2));
11694 predicate(PowerArchitecturePPC64 >= 9);
11695 ins_cost(DEFAULT_COST);
11696
11697 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxF" %}
11698 size(4);
11699 ins_encode %{
11700 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11701 %}
11702 ins_pipe(pipe_class_default);
11703 %}
11704
11705 instruct maxD(regD dst, regD src1, regD src2) %{
11706 match(Set dst (MaxD src1 src2));
11707 predicate(PowerArchitecturePPC64 >= 9);
11708 ins_cost(DEFAULT_COST);
11709
11710 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxD" %}
11711 size(4);
11712 ins_encode %{
11713 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11714 %}
11715 ins_pipe(pipe_class_default);
11716 %}
11717
11718 //---------- Population Count Instructions ------------------------------------
11719
11720 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
11721 match(Set dst (PopCountI src));
11722 predicate(UsePopCountInstruction);
11723 ins_cost(DEFAULT_COST);
11724
11725 format %{ "POPCNTW $dst, $src" %}
11726 size(4);
11727 ins_encode %{
11728 __ popcntw($dst$$Register, $src$$Register);
11729 %}
11730 ins_pipe(pipe_class_default);
11731 %}
11732
11733 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
11734 predicate(UsePopCountInstruction);
11735 match(Set dst (PopCountL src));
11736 ins_cost(DEFAULT_COST);
11737
11738 format %{ "POPCNTD $dst, $src" %}
11739 size(4);
11740 ins_encode %{
11741 __ popcntd($dst$$Register, $src$$Register);
11742 %}
11743 ins_pipe(pipe_class_default);
11744 %}
11745
11746 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
11747 match(Set dst (CountLeadingZerosI src));
11748 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
11749 ins_cost(DEFAULT_COST);
11750
11751 format %{ "CNTLZW $dst, $src" %}
11752 size(4);
11753 ins_encode %{
11754 __ cntlzw($dst$$Register, $src$$Register);
11755 %}
11756 ins_pipe(pipe_class_default);
11757 %}
11758
11759 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
11760 match(Set dst (CountLeadingZerosL src));
11761 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
11762 ins_cost(DEFAULT_COST);
11763
11764 format %{ "CNTLZD $dst, $src" %}
11765 size(4);
11766 ins_encode %{
11767 __ cntlzd($dst$$Register, $src$$Register);
11768 %}
11769 ins_pipe(pipe_class_default);
11770 %}
11771
11772 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
11773 // no match-rule, false predicate
11774 effect(DEF dst, USE src);
11775 predicate(false);
11776
11777 format %{ "CNTLZD $dst, $src" %}
11778 size(4);
11779 ins_encode %{
11780 __ cntlzd($dst$$Register, $src$$Register);
11781 %}
11782 ins_pipe(pipe_class_default);
11783 %}
11784
11785 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
11786 match(Set dst (CountTrailingZerosI src));
11787 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
11788 ins_cost(DEFAULT_COST);
11789
11790 expand %{
11791 immI16 imm1 %{ (int)-1 %}
11792 immI16 imm2 %{ (int)32 %}
11793 immI_minus1 m1 %{ -1 %}
11794 iRegIdst tmpI1;
11795 iRegIdst tmpI2;
11796 iRegIdst tmpI3;
11797 addI_reg_imm16(tmpI1, src, imm1);
11798 andcI_reg_reg(tmpI2, src, m1, tmpI1);
11799 countLeadingZerosI(tmpI3, tmpI2);
11800 subI_imm16_reg(dst, imm2, tmpI3);
11801 %}
11802 %}
11803
11804 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{
11805 match(Set dst (CountTrailingZerosI src));
11806 predicate(UseCountTrailingZerosInstructionsPPC64);
11807 ins_cost(DEFAULT_COST);
11808
11809 format %{ "CNTTZW $dst, $src" %}
11810 size(4);
11811 ins_encode %{
11812 __ cnttzw($dst$$Register, $src$$Register);
11813 %}
11814 ins_pipe(pipe_class_default);
11815 %}
11816
11817 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
11818 match(Set dst (CountTrailingZerosL src));
11819 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
11820 ins_cost(DEFAULT_COST);
11821
11822 expand %{
11823 immL16 imm1 %{ (long)-1 %}
11824 immI16 imm2 %{ (int)64 %}
11825 iRegLdst tmpL1;
11826 iRegLdst tmpL2;
11827 iRegIdst tmpL3;
11828 addL_reg_imm16(tmpL1, src, imm1);
11829 andcL_reg_reg(tmpL2, tmpL1, src);
11830 countLeadingZerosL(tmpL3, tmpL2);
11831 subI_imm16_reg(dst, imm2, tmpL3);
11832 %}
11833 %}
11834
11835 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{
11836 match(Set dst (CountTrailingZerosL src));
11837 predicate(UseCountTrailingZerosInstructionsPPC64);
11838 ins_cost(DEFAULT_COST);
11839
11840 format %{ "CNTTZD $dst, $src" %}
11841 size(4);
11842 ins_encode %{
11843 __ cnttzd($dst$$Register, $src$$Register);
11844 %}
11845 ins_pipe(pipe_class_default);
11846 %}
11847
11848 // Expand nodes for byte_reverse_int/ushort/short.
11849 instruct rlwinm(iRegIdst dst, iRegIsrc src, immI16 shift, immI16 mb, immI16 me) %{
11850 effect(DEF dst, USE src, USE shift, USE mb, USE me);
11851 predicate(false);
11852
11853 format %{ "RLWINM $dst, $src, $shift, $mb, $me" %}
11854 size(4);
11855 ins_encode %{
11856 __ rlwinm($dst$$Register, $src$$Register, $shift$$constant, $mb$$constant, $me$$constant);
11857 %}
11858 ins_pipe(pipe_class_default);
11859 %}
11860
11861 // Expand nodes for byte_reverse_int.
11862 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
11863 effect(DEF dst, USE src, USE n, USE b);
11864 predicate(false);
11865
11866 format %{ "INSRWI $dst, $src, $n, $b" %}
11867 size(4);
11868 ins_encode %{
11869 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
11870 %}
11871 ins_pipe(pipe_class_default);
11872 %}
11873
11874 // As insrwi_a, but with USE_DEF.
11875 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
11876 effect(USE_DEF dst, USE src, USE n, USE b);
11877 predicate(false);
11878
11879 format %{ "INSRWI $dst, $src, $n, $b" %}
11880 size(4);
11881 ins_encode %{
11882 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
11883 %}
11884 ins_pipe(pipe_class_default);
11885 %}
11886
11887 // Just slightly faster than java implementation.
11888 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
11889 match(Set dst (ReverseBytesI src));
11890 predicate(!UseByteReverseInstructions);
11891 ins_cost(7*DEFAULT_COST);
11892
11893 expand %{
11894 immI16 imm24 %{ (int) 24 %}
11895 immI16 imm16 %{ (int) 16 %}
11896 immI16 imm8 %{ (int) 8 %}
11897 immI16 imm4 %{ (int) 4 %}
11898 immI16 imm0 %{ (int) 0 %}
11899 iRegLdst tmpI1;
11900 iRegLdst tmpI2;
11901 iRegLdst tmpI3;
11902
11903 urShiftI_reg_imm(tmpI1, src, imm24);
11904 insrwi_a(dst, tmpI1, imm8, imm24);
11905 urShiftI_reg_imm(tmpI2, src, imm16);
11906 insrwi(dst, tmpI2, imm16, imm8);
11907 urShiftI_reg_imm(tmpI3, src, imm8);
11908 insrwi(dst, tmpI3, imm8, imm8);
11909 insrwi(dst, src, imm8, imm0);
11910 %}
11911 %}
11912
11913 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{
11914 match(Set dst (ReverseBytesI src));
11915 predicate(UseVectorByteReverseInstructionsPPC64);
11916 effect(TEMP tmpV);
11917 ins_cost(DEFAULT_COST*3);
11918 size(12);
11919 format %{ "MTVSRWZ $tmpV, $src\n"
11920 "\tXXBRW $tmpV, $tmpV\n"
11921 "\tMFVSRWZ $dst, $tmpV" %}
11922
11923 ins_encode %{
11924 __ mtvsrwz($tmpV$$VectorRegister.to_vsr(), $src$$Register);
11925 __ xxbrw($tmpV$$VectorRegister.to_vsr(), $tmpV$$VectorRegister->to_vsr());
11926 __ mfvsrwz($dst$$Register, $tmpV$$VectorRegister->to_vsr());
11927 %}
11928 ins_pipe(pipe_class_default);
11929 %}
11930
11931 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{
11932 match(Set dst (ReverseBytesI src));
11933 predicate(UseByteReverseInstructions);
11934 ins_cost(DEFAULT_COST);
11935 size(4);
11936
11937 format %{ "BRW $dst, $src" %}
11938
11939 ins_encode %{
11940 __ brw($dst$$Register, $src$$Register);
11941 %}
11942 ins_pipe(pipe_class_default);
11943 %}
11944
11945 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
11946 match(Set dst (ReverseBytesL src));
11947 predicate(!UseByteReverseInstructions);
11948 ins_cost(15*DEFAULT_COST);
11949
11950 expand %{
11951 immI16 imm56 %{ (int) 56 %}
11952 immI16 imm48 %{ (int) 48 %}
11953 immI16 imm40 %{ (int) 40 %}
11954 immI16 imm32 %{ (int) 32 %}
11955 immI16 imm24 %{ (int) 24 %}
11956 immI16 imm16 %{ (int) 16 %}
11957 immI16 imm8 %{ (int) 8 %}
11958 immI16 imm0 %{ (int) 0 %}
11959 iRegLdst tmpL1;
11960 iRegLdst tmpL2;
11961 iRegLdst tmpL3;
11962 iRegLdst tmpL4;
11963 iRegLdst tmpL5;
11964 iRegLdst tmpL6;
11965
11966 // src : |a|b|c|d|e|f|g|h|
11967 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
11968 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
11969 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
11970 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
11971 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
11972 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
11973 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
11974 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
11975 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
11976 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
11977 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
11978 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
11979 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
11980 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
11981 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
11982 %}
11983 %}
11984
11985 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{
11986 match(Set dst (ReverseBytesL src));
11987 predicate(UseVectorByteReverseInstructionsPPC64);
11988 effect(TEMP tmpV);
11989 ins_cost(DEFAULT_COST*3);
11990 size(12);
11991 format %{ "MTVSRD $tmpV, $src\n"
11992 "\tXXBRD $tmpV, $tmpV\n"
11993 "\tMFVSRD $dst, $tmpV" %}
11994
11995 ins_encode %{
11996 __ mtvsrd($tmpV$$VectorRegister->to_vsr(), $src$$Register);
11997 __ xxbrd($tmpV$$VectorRegister->to_vsr(), $tmpV$$VectorRegister->to_vsr());
11998 __ mfvsrd($dst$$Register, $tmpV$$VectorRegister->to_vsr());
11999 %}
12000 ins_pipe(pipe_class_default);
12001 %}
12002
12003 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{
12004 match(Set dst (ReverseBytesL src));
12005 predicate(UseByteReverseInstructions);
12006 ins_cost(DEFAULT_COST);
12007 size(4);
12008
12009 format %{ "BRD $dst, $src" %}
12010
12011 ins_encode %{
12012 __ brd($dst$$Register, $src$$Register);
12013 %}
12014 ins_pipe(pipe_class_default);
12015 %}
12016
12017 // Need zero extend. Must not use brh only.
12018 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
12019 match(Set dst (ReverseBytesUS src));
12020 ins_cost(2*DEFAULT_COST);
12021
12022 expand %{
12023 immI16 imm31 %{ (int) 31 %}
12024 immI16 imm24 %{ (int) 24 %}
12025 immI16 imm16 %{ (int) 16 %}
12026 immI16 imm8 %{ (int) 8 %}
12027
12028 rlwinm(dst, src, imm24, imm24, imm31);
12029 insrwi(dst, src, imm8, imm16);
12030 %}
12031 %}
12032
12033 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
12034 match(Set dst (ReverseBytesS src));
12035 predicate(!UseByteReverseInstructions);
12036 ins_cost(3*DEFAULT_COST);
12037
12038 expand %{
12039 immI16 imm16 %{ (int) 16 %}
12040 immI16 imm8 %{ (int) 8 %}
12041 iRegLdst tmpI1;
12042
12043 urShiftI_reg_imm(tmpI1, src, imm8);
12044 insrwi(tmpI1, src, imm8, imm16);
12045 extsh(dst, tmpI1);
12046 %}
12047 %}
12048
12049 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{
12050 match(Set dst (ReverseBytesS src));
12051 predicate(UseByteReverseInstructions);
12052 ins_cost(DEFAULT_COST);
12053 size(8);
12054
12055 format %{ "BRH $dst, $src\n\t"
12056 "EXTSH $dst, $dst" %}
12057
12058 ins_encode %{
12059 __ brh($dst$$Register, $src$$Register);
12060 __ extsh($dst$$Register, $dst$$Register);
12061 %}
12062 ins_pipe(pipe_class_default);
12063 %}
12064
12065 // Load Integer reversed byte order
12066 instruct loadI_reversed(iRegIdst dst, indirect mem) %{
12067 match(Set dst (ReverseBytesI (LoadI mem)));
12068 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12069 ins_cost(MEMORY_REF_COST);
12070
12071 size(4);
12072 ins_encode %{
12073 __ lwbrx($dst$$Register, $mem$$Register);
12074 %}
12075 ins_pipe(pipe_class_default);
12076 %}
12077
12078 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{
12079 match(Set dst (ReverseBytesI (LoadI mem)));
12080 ins_cost(2 * MEMORY_REF_COST);
12081
12082 size(12);
12083 ins_encode %{
12084 __ lwbrx($dst$$Register, $mem$$Register);
12085 __ twi_0($dst$$Register);
12086 __ isync();
12087 %}
12088 ins_pipe(pipe_class_default);
12089 %}
12090
12091 // Load Long - aligned and reversed
12092 instruct loadL_reversed(iRegLdst dst, indirect mem) %{
12093 match(Set dst (ReverseBytesL (LoadL mem)));
12094 predicate((n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))));
12095 ins_cost(MEMORY_REF_COST);
12096
12097 size(4);
12098 ins_encode %{
12099 __ ldbrx($dst$$Register, $mem$$Register);
12100 %}
12101 ins_pipe(pipe_class_default);
12102 %}
12103
12104 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{
12105 match(Set dst (ReverseBytesL (LoadL mem)));
12106 ins_cost(2 * MEMORY_REF_COST);
12107
12108 size(12);
12109 ins_encode %{
12110 __ ldbrx($dst$$Register, $mem$$Register);
12111 __ twi_0($dst$$Register);
12112 __ isync();
12113 %}
12114 ins_pipe(pipe_class_default);
12115 %}
12116
12117 // Load unsigned short / char reversed byte order
12118 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
12119 match(Set dst (ReverseBytesUS (LoadUS mem)));
12120 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12121 ins_cost(MEMORY_REF_COST);
12122
12123 size(4);
12124 ins_encode %{
12125 __ lhbrx($dst$$Register, $mem$$Register);
12126 %}
12127 ins_pipe(pipe_class_default);
12128 %}
12129
12130 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{
12131 match(Set dst (ReverseBytesUS (LoadUS mem)));
12132 ins_cost(2 * MEMORY_REF_COST);
12133
12134 size(12);
12135 ins_encode %{
12136 __ lhbrx($dst$$Register, $mem$$Register);
12137 __ twi_0($dst$$Register);
12138 __ isync();
12139 %}
12140 ins_pipe(pipe_class_default);
12141 %}
12142
12143 // Load short reversed byte order
12144 instruct loadS_reversed(iRegIdst dst, indirect mem) %{
12145 match(Set dst (ReverseBytesS (LoadS mem)));
12146 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12147 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
12148
12149 size(8);
12150 ins_encode %{
12151 __ lhbrx($dst$$Register, $mem$$Register);
12152 __ extsh($dst$$Register, $dst$$Register);
12153 %}
12154 ins_pipe(pipe_class_default);
12155 %}
12156
12157 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{
12158 match(Set dst (ReverseBytesS (LoadS mem)));
12159 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12160
12161 size(16);
12162 ins_encode %{
12163 __ lhbrx($dst$$Register, $mem$$Register);
12164 __ twi_0($dst$$Register);
12165 __ extsh($dst$$Register, $dst$$Register);
12166 __ isync();
12167 %}
12168 ins_pipe(pipe_class_default);
12169 %}
12170
12171 // Store Integer reversed byte order
12172 instruct storeI_reversed(iRegIsrc src, indirect mem) %{
12173 match(Set mem (StoreI mem (ReverseBytesI src)));
12174 ins_cost(MEMORY_REF_COST);
12175
12176 size(4);
12177 ins_encode %{
12178 __ stwbrx($src$$Register, $mem$$Register);
12179 %}
12180 ins_pipe(pipe_class_default);
12181 %}
12182
12183 // Store Long reversed byte order
12184 instruct storeL_reversed(iRegLsrc src, indirect mem) %{
12185 match(Set mem (StoreL mem (ReverseBytesL src)));
12186 ins_cost(MEMORY_REF_COST);
12187
12188 size(4);
12189 ins_encode %{
12190 __ stdbrx($src$$Register, $mem$$Register);
12191 %}
12192 ins_pipe(pipe_class_default);
12193 %}
12194
12195 // Store unsigned short / char reversed byte order
12196 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
12197 match(Set mem (StoreC mem (ReverseBytesUS src)));
12198 ins_cost(MEMORY_REF_COST);
12199
12200 size(4);
12201 ins_encode %{
12202 __ sthbrx($src$$Register, $mem$$Register);
12203 %}
12204 ins_pipe(pipe_class_default);
12205 %}
12206
12207 // Store short reversed byte order
12208 instruct storeS_reversed(iRegIsrc src, indirect mem) %{
12209 match(Set mem (StoreC mem (ReverseBytesS src)));
12210 ins_cost(MEMORY_REF_COST);
12211
12212 size(4);
12213 ins_encode %{
12214 __ sthbrx($src$$Register, $mem$$Register);
12215 %}
12216 ins_pipe(pipe_class_default);
12217 %}
12218
12219 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
12220 effect(DEF temp1, USE src);
12221
12222 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %}
12223 size(4);
12224 ins_encode %{
12225 __ mtvsrwz($temp1$$VectorRegister->to_vsr(), $src$$Register);
12226 %}
12227 ins_pipe(pipe_class_default);
12228 %}
12229
12230 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{
12231 effect(DEF dst, USE src, USE imm1);
12232
12233 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %}
12234 size(4);
12235 ins_encode %{
12236 __ xxspltw($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $imm1$$constant);
12237 %}
12238 ins_pipe(pipe_class_default);
12239 %}
12240
12241 instruct xscvdpspn_regF(vecX dst, regF src) %{
12242 effect(DEF dst, USE src);
12243
12244 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %}
12245 size(4);
12246 ins_encode %{
12247 __ xscvdpspn($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr());
12248 %}
12249 ins_pipe(pipe_class_default);
12250 %}
12251
12252 //---------- Replicate Vector Instructions ------------------------------------
12253
12254 // Insrdi does replicate if src == dst.
12255 instruct repl32(iRegLdst dst) %{
12256 predicate(false);
12257 effect(USE_DEF dst);
12258
12259 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %}
12260 size(4);
12261 ins_encode %{
12262 __ insrdi($dst$$Register, $dst$$Register, 32, 0);
12263 %}
12264 ins_pipe(pipe_class_default);
12265 %}
12266
12267 // Insrdi does replicate if src == dst.
12268 instruct repl48(iRegLdst dst) %{
12269 predicate(false);
12270 effect(USE_DEF dst);
12271
12272 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %}
12273 size(4);
12274 ins_encode %{
12275 __ insrdi($dst$$Register, $dst$$Register, 48, 0);
12276 %}
12277 ins_pipe(pipe_class_default);
12278 %}
12279
12280 // Insrdi does replicate if src == dst.
12281 instruct repl56(iRegLdst dst) %{
12282 predicate(false);
12283 effect(USE_DEF dst);
12284
12285 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %}
12286 size(4);
12287 ins_encode %{
12288 __ insrdi($dst$$Register, $dst$$Register, 56, 0);
12289 %}
12290 ins_pipe(pipe_class_default);
12291 %}
12292
12293 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12294 match(Set dst (Replicate src));
12295 predicate(n->as_Vector()->length() == 8 &&
12296 Matcher::vector_element_basic_type(n) == T_BYTE);
12297 expand %{
12298 moveReg(dst, src);
12299 repl56(dst);
12300 repl48(dst);
12301 repl32(dst);
12302 %}
12303 %}
12304
12305 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
12306 match(Set dst (Replicate zero));
12307 predicate(n->as_Vector()->length() == 8 &&
12308 Matcher::vector_element_basic_type(n) == T_BYTE);
12309 format %{ "LI $dst, #0 \t// replicate8B" %}
12310 size(4);
12311 ins_encode %{
12312 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12313 %}
12314 ins_pipe(pipe_class_default);
12315 %}
12316
12317 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
12318 match(Set dst (Replicate src));
12319 predicate(n->as_Vector()->length() == 8 &&
12320 Matcher::vector_element_basic_type(n) == T_BYTE);
12321 format %{ "LI $dst, #-1 \t// replicate8B" %}
12322 size(4);
12323 ins_encode %{
12324 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12325 %}
12326 ins_pipe(pipe_class_default);
12327 %}
12328
12329 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{
12330 match(Set dst (Replicate src));
12331 predicate(n->as_Vector()->length() == 16 &&
12332 Matcher::vector_element_basic_type(n) == T_BYTE);
12333
12334 expand %{
12335 iRegLdst tmpL;
12336 vecX tmpV;
12337 immI8 imm1 %{ (int) 1 %}
12338 moveReg(tmpL, src);
12339 repl56(tmpL);
12340 repl48(tmpL);
12341 mtvsrwz(tmpV, tmpL);
12342 xxspltw(dst, tmpV, imm1);
12343 %}
12344 %}
12345
12346 instruct repl16B_immI0(vecX dst, immI_0 zero) %{
12347 match(Set dst (Replicate zero));
12348 predicate(n->as_Vector()->length() == 16 &&
12349 Matcher::vector_element_basic_type(n) == T_BYTE);
12350
12351 format %{ "XXLXOR $dst, $zero \t// replicate16B" %}
12352 size(4);
12353 ins_encode %{
12354 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12355 %}
12356 ins_pipe(pipe_class_default);
12357 %}
12358
12359 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{
12360 match(Set dst (Replicate src));
12361 predicate(n->as_Vector()->length() == 16 &&
12362 Matcher::vector_element_basic_type(n) == T_BYTE);
12363
12364 format %{ "XXLEQV $dst, $src \t// replicate16B" %}
12365 size(4);
12366 ins_encode %{
12367 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12368 %}
12369 ins_pipe(pipe_class_default);
12370 %}
12371
12372 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12373 match(Set dst (Replicate src));
12374 predicate(n->as_Vector()->length() == 4 &&
12375 Matcher::vector_element_basic_type(n) == T_SHORT);
12376 expand %{
12377 moveReg(dst, src);
12378 repl48(dst);
12379 repl32(dst);
12380 %}
12381 %}
12382
12383 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
12384 match(Set dst (Replicate zero));
12385 predicate(n->as_Vector()->length() == 4 &&
12386 Matcher::vector_element_basic_type(n) == T_SHORT);
12387 format %{ "LI $dst, #0 \t// replicate4S" %}
12388 size(4);
12389 ins_encode %{
12390 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12391 %}
12392 ins_pipe(pipe_class_default);
12393 %}
12394
12395 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
12396 match(Set dst (Replicate src));
12397 predicate(n->as_Vector()->length() == 4 &&
12398 Matcher::vector_element_basic_type(n) == T_SHORT);
12399 format %{ "LI $dst, -1 \t// replicate4S" %}
12400 size(4);
12401 ins_encode %{
12402 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12403 %}
12404 ins_pipe(pipe_class_default);
12405 %}
12406
12407 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{
12408 match(Set dst (Replicate src));
12409 predicate(n->as_Vector()->length() == 8 &&
12410 Matcher::vector_element_basic_type(n) == T_SHORT);
12411
12412 expand %{
12413 iRegLdst tmpL;
12414 vecX tmpV;
12415 immI8 zero %{ (int) 0 %}
12416 moveReg(tmpL, src);
12417 repl48(tmpL);
12418 repl32(tmpL);
12419 mtvsrd(tmpV, tmpL);
12420 xxpermdi(dst, tmpV, tmpV, zero);
12421 %}
12422 %}
12423
12424 instruct repl8S_immI0(vecX dst, immI_0 zero) %{
12425 match(Set dst (Replicate zero));
12426 predicate(n->as_Vector()->length() == 8 &&
12427 Matcher::vector_element_basic_type(n) == T_SHORT);
12428
12429 format %{ "XXLXOR $dst, $zero \t// replicate8S" %}
12430 size(4);
12431 ins_encode %{
12432 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12433 %}
12434 ins_pipe(pipe_class_default);
12435 %}
12436
12437 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{
12438 match(Set dst (Replicate src));
12439 predicate(n->as_Vector()->length() == 8 &&
12440 Matcher::vector_element_basic_type(n) == T_SHORT);
12441
12442 format %{ "XXLEQV $dst, $src \t// replicate8S" %}
12443 size(4);
12444 ins_encode %{
12445 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12446 %}
12447 ins_pipe(pipe_class_default);
12448 %}
12449
12450 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12451 match(Set dst (Replicate src));
12452 predicate(n->as_Vector()->length() == 2 &&
12453 Matcher::vector_element_basic_type(n) == T_INT);
12454 ins_cost(2 * DEFAULT_COST);
12455 expand %{
12456 moveReg(dst, src);
12457 repl32(dst);
12458 %}
12459 %}
12460
12461 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
12462 match(Set dst (Replicate zero));
12463 predicate(n->as_Vector()->length() == 2 &&
12464 Matcher::vector_element_basic_type(n) == T_INT);
12465 format %{ "LI $dst, #0 \t// replicate2I" %}
12466 size(4);
12467 ins_encode %{
12468 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12469 %}
12470 ins_pipe(pipe_class_default);
12471 %}
12472
12473 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
12474 match(Set dst (Replicate src));
12475 predicate(n->as_Vector()->length() == 2 &&
12476 Matcher::vector_element_basic_type(n) == T_INT);
12477 format %{ "LI $dst, -1 \t// replicate2I" %}
12478 size(4);
12479 ins_encode %{
12480 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12481 %}
12482 ins_pipe(pipe_class_default);
12483 %}
12484
12485 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{
12486 match(Set dst (Replicate src));
12487 predicate(n->as_Vector()->length() == 4 &&
12488 Matcher::vector_element_basic_type(n) == T_INT);
12489 ins_cost(2 * DEFAULT_COST);
12490
12491 expand %{
12492 iRegLdst tmpL;
12493 vecX tmpV;
12494 immI8 zero %{ (int) 0 %}
12495 moveReg(tmpL, src);
12496 repl32(tmpL);
12497 mtvsrd(tmpV, tmpL);
12498 xxpermdi(dst, tmpV, tmpV, zero);
12499 %}
12500 %}
12501
12502 instruct repl4I_immI0(vecX dst, immI_0 zero) %{
12503 match(Set dst (Replicate zero));
12504 predicate(n->as_Vector()->length() == 4 &&
12505 Matcher::vector_element_basic_type(n) == T_INT);
12506
12507 format %{ "XXLXOR $dst, $zero \t// replicate4I" %}
12508 size(4);
12509 ins_encode %{
12510 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12511 %}
12512 ins_pipe(pipe_class_default);
12513 %}
12514
12515 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{
12516 match(Set dst (Replicate src));
12517 predicate(n->as_Vector()->length() == 4 &&
12518 Matcher::vector_element_basic_type(n) == T_INT);
12519
12520 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %}
12521 size(4);
12522 ins_encode %{
12523 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12524 %}
12525 ins_pipe(pipe_class_default);
12526 %}
12527
12528 // Move float to int register via stack, replicate.
12529 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
12530 match(Set dst (Replicate src));
12531 predicate(n->as_Vector()->length() == 2 &&
12532 Matcher::vector_element_basic_type(n) == T_FLOAT);
12533 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12534 expand %{
12535 stackSlotL tmpS;
12536 iRegIdst tmpI;
12537 moveF2I_reg_stack(tmpS, src); // Move float to stack.
12538 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
12539 moveReg(dst, tmpI); // Move int to long reg.
12540 repl32(dst); // Replicate bitpattern.
12541 %}
12542 %}
12543
12544 // Replicate scalar constant to packed float values in Double register
12545 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
12546 match(Set dst (Replicate src));
12547 predicate(n->as_Vector()->length() == 2 &&
12548 Matcher::vector_element_basic_type(n) == T_FLOAT);
12549 ins_cost(5 * DEFAULT_COST);
12550
12551 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
12552 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
12553 %}
12554
12555 // Replicate scalar zero constant to packed float values in Double register
12556 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
12557 match(Set dst (Replicate zero));
12558 predicate(n->as_Vector()->length() == 2 &&
12559 Matcher::vector_element_basic_type(n) == T_FLOAT);
12560
12561 format %{ "LI $dst, #0 \t// replicate2F" %}
12562 size(4);
12563 ins_encode %{
12564 __ li($dst$$Register, 0x0);
12565 %}
12566 ins_pipe(pipe_class_default);
12567 %}
12568
12569
12570 //----------Vector Arithmetic Instructions--------------------------------------
12571
12572 // Vector Addition Instructions
12573
12574 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
12575 match(Set dst (AddVB src1 src2));
12576 predicate(n->as_Vector()->length() == 16);
12577 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %}
12578 size(4);
12579 ins_encode %{
12580 __ vaddubm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12581 %}
12582 ins_pipe(pipe_class_default);
12583 %}
12584
12585 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
12586 match(Set dst (AddVS src1 src2));
12587 predicate(n->as_Vector()->length() == 8);
12588 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %}
12589 size(4);
12590 ins_encode %{
12591 __ vadduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12592 %}
12593 ins_pipe(pipe_class_default);
12594 %}
12595
12596 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
12597 match(Set dst (AddVI src1 src2));
12598 predicate(n->as_Vector()->length() == 4);
12599 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %}
12600 size(4);
12601 ins_encode %{
12602 __ vadduwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12603 %}
12604 ins_pipe(pipe_class_default);
12605 %}
12606
12607 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
12608 match(Set dst (AddVF src1 src2));
12609 predicate(n->as_Vector()->length() == 4);
12610 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %}
12611 size(4);
12612 ins_encode %{
12613 __ vaddfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12614 %}
12615 ins_pipe(pipe_class_default);
12616 %}
12617
12618 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
12619 match(Set dst (AddVL src1 src2));
12620 predicate(n->as_Vector()->length() == 2);
12621 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %}
12622 size(4);
12623 ins_encode %{
12624 __ vaddudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12625 %}
12626 ins_pipe(pipe_class_default);
12627 %}
12628
12629 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
12630 match(Set dst (AddVD src1 src2));
12631 predicate(n->as_Vector()->length() == 2);
12632 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %}
12633 size(4);
12634 ins_encode %{
12635 __ xvadddp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12636 %}
12637 ins_pipe(pipe_class_default);
12638 %}
12639
12640 // Vector Subtraction Instructions
12641
12642 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
12643 match(Set dst (SubVB src1 src2));
12644 predicate(n->as_Vector()->length() == 16);
12645 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %}
12646 size(4);
12647 ins_encode %{
12648 __ vsububm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12649 %}
12650 ins_pipe(pipe_class_default);
12651 %}
12652
12653 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
12654 match(Set dst (SubVS src1 src2));
12655 predicate(n->as_Vector()->length() == 8);
12656 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %}
12657 size(4);
12658 ins_encode %{
12659 __ vsubuhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12660 %}
12661 ins_pipe(pipe_class_default);
12662 %}
12663
12664 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
12665 match(Set dst (SubVI src1 src2));
12666 predicate(n->as_Vector()->length() == 4);
12667 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %}
12668 size(4);
12669 ins_encode %{
12670 __ vsubuwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12671 %}
12672 ins_pipe(pipe_class_default);
12673 %}
12674
12675 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
12676 match(Set dst (SubVF src1 src2));
12677 predicate(n->as_Vector()->length() == 4);
12678 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %}
12679 size(4);
12680 ins_encode %{
12681 __ vsubfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12682 %}
12683 ins_pipe(pipe_class_default);
12684 %}
12685
12686 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
12687 match(Set dst (SubVL src1 src2));
12688 predicate(n->as_Vector()->length() == 2);
12689 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %}
12690 size(4);
12691 ins_encode %{
12692 __ vsubudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12693 %}
12694 ins_pipe(pipe_class_default);
12695 %}
12696
12697 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
12698 match(Set dst (SubVD src1 src2));
12699 predicate(n->as_Vector()->length() == 2);
12700 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %}
12701 size(4);
12702 ins_encode %{
12703 __ xvsubdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12704 %}
12705 ins_pipe(pipe_class_default);
12706 %}
12707
12708 // Vector Multiplication Instructions
12709
12710 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
12711 match(Set dst (MulVS src1 src2));
12712 predicate(n->as_Vector()->length() == 8);
12713 effect(TEMP tmp);
12714 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %}
12715 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %}
12716 size(8);
12717 ins_encode %{
12718 __ vspltish($tmp$$VectorRegister, 0);
12719 __ vmladduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister, $tmp$$VectorRegister);
12720 %}
12721 ins_pipe(pipe_class_default);
12722 %}
12723
12724 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
12725 match(Set dst (MulVI src1 src2));
12726 predicate(n->as_Vector()->length() == 4);
12727 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %}
12728 size(4);
12729 ins_encode %{
12730 __ vmuluwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12731 %}
12732 ins_pipe(pipe_class_default);
12733 %}
12734
12735 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
12736 match(Set dst (MulVF src1 src2));
12737 predicate(n->as_Vector()->length() == 4);
12738 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %}
12739 size(4);
12740 ins_encode %{
12741 __ xvmulsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12742 %}
12743 ins_pipe(pipe_class_default);
12744 %}
12745
12746 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
12747 match(Set dst (MulVD src1 src2));
12748 predicate(n->as_Vector()->length() == 2);
12749 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %}
12750 size(4);
12751 ins_encode %{
12752 __ xvmuldp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12753 %}
12754 ins_pipe(pipe_class_default);
12755 %}
12756
12757 // Vector Division Instructions
12758
12759 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
12760 match(Set dst (DivVF src1 src2));
12761 predicate(n->as_Vector()->length() == 4);
12762 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %}
12763 size(4);
12764 ins_encode %{
12765 __ xvdivsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12766 %}
12767 ins_pipe(pipe_class_default);
12768 %}
12769
12770 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
12771 match(Set dst (DivVD src1 src2));
12772 predicate(n->as_Vector()->length() == 2);
12773 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %}
12774 size(4);
12775 ins_encode %{
12776 __ xvdivdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12777 %}
12778 ins_pipe(pipe_class_default);
12779 %}
12780
12781 // Vector Min / Max Instructions
12782
12783 instruct vmin_reg(vecX dst, vecX src1, vecX src2) %{
12784 match(Set dst (MinV src1 src2));
12785 format %{ "VMIN $dst,$src1,$src2\t// vector min" %}
12786 size(4);
12787 ins_encode %{
12788 BasicType bt = Matcher::vector_element_basic_type(this);
12789 switch (bt) {
12790 case T_INT:
12791 __ vminsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12792 break;
12793 case T_LONG:
12794 __ vminsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12795 break;
12796 default:
12797 ShouldNotReachHere();
12798 }
12799 %}
12800 ins_pipe(pipe_class_default);
12801 %}
12802
12803 instruct vmax_reg(vecX dst, vecX src1, vecX src2) %{
12804 match(Set dst (MaxV src1 src2));
12805 format %{ "VMAX $dst,$src1,$src2\t// vector max" %}
12806 size(4);
12807 ins_encode %{
12808 BasicType bt = Matcher::vector_element_basic_type(this);
12809 switch (bt) {
12810 case T_INT:
12811 __ vmaxsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12812 break;
12813 case T_LONG:
12814 __ vmaxsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12815 break;
12816 default:
12817 ShouldNotReachHere();
12818 }
12819 %}
12820 ins_pipe(pipe_class_default);
12821 %}
12822
12823 instruct vminu_reg(vecX dst, vecX src1, vecX src2) %{
12824 match(Set dst (UMinV src1 src2));
12825 format %{ "VMINU $dst,$src1,$src2\t// vector unsigned min" %}
12826 size(4);
12827 ins_encode %{
12828 BasicType bt = Matcher::vector_element_basic_type(this);
12829 switch (bt) {
12830 case T_INT:
12831 __ vminuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12832 break;
12833 case T_LONG:
12834 __ vminud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12835 break;
12836 default:
12837 ShouldNotReachHere();
12838 }
12839 %}
12840 ins_pipe(pipe_class_default);
12841 %}
12842
12843 instruct vmaxu_reg(vecX dst, vecX src1, vecX src2) %{
12844 match(Set dst (UMaxV src1 src2));
12845 format %{ "VMAXU $dst,$src1,$src2\t// vector unsigned max" %}
12846 size(4);
12847 ins_encode %{
12848 BasicType bt = Matcher::vector_element_basic_type(this);
12849 switch (bt) {
12850 case T_INT:
12851 __ vmaxuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12852 break;
12853 case T_LONG:
12854 __ vmaxud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12855 break;
12856 default:
12857 ShouldNotReachHere();
12858 }
12859 %}
12860 ins_pipe(pipe_class_default);
12861 %}
12862
12863 instruct vand(vecX dst, vecX src1, vecX src2) %{
12864 match(Set dst (AndV src1 src2));
12865 size(4);
12866 format %{ "VAND $dst,$src1,$src2\t// and vectors" %}
12867 ins_encode %{
12868 __ vand($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12869 %}
12870 ins_pipe(pipe_class_default);
12871 %}
12872
12873 instruct vor(vecX dst, vecX src1, vecX src2) %{
12874 match(Set dst (OrV src1 src2));
12875 size(4);
12876 format %{ "VOR $dst,$src1,$src2\t// or vectors" %}
12877 ins_encode %{
12878 __ vor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12879 %}
12880 ins_pipe(pipe_class_default);
12881 %}
12882
12883 instruct vxor(vecX dst, vecX src1, vecX src2) %{
12884 match(Set dst (XorV src1 src2));
12885 size(4);
12886 format %{ "VXOR $dst,$src1,$src2\t// xor vectors" %}
12887 ins_encode %{
12888 __ vxor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12889 %}
12890 ins_pipe(pipe_class_default);
12891 %}
12892
12893 instruct reductionI_arith_logic(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2) %{
12894 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
12895 match(Set dst (AddReductionVI srcInt srcVec));
12896 match(Set dst (MulReductionVI srcInt srcVec));
12897 match(Set dst (AndReductionV srcInt srcVec));
12898 match(Set dst ( OrReductionV srcInt srcVec));
12899 match(Set dst (XorReductionV srcInt srcVec));
12900 effect(TEMP tmp1, TEMP tmp2);
12901 ins_cost(DEFAULT_COST * 6);
12902 format %{ "REDUCEI_ARITH_LOGIC // $dst,$srcInt,$srcVec,$tmp1,$tmp2\t// reduce vector int add/mul/and/or/xor" %}
12903 size(24);
12904 ins_encode %{
12905 int opcode = this->ideal_Opcode();
12906 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
12907 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
12908 %}
12909 ins_pipe(pipe_class_default);
12910 %}
12911
12912 instruct reductionI_min_max(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2, flagsRegCR0 cr0) %{
12913 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
12914 match(Set dst (MinReductionV srcInt srcVec));
12915 match(Set dst (MaxReductionV srcInt srcVec));
12916 effect(TEMP tmp1, TEMP tmp2, KILL cr0);
12917 ins_cost(DEFAULT_COST * 7);
12918 format %{ "REDUCEI_MINMAX // $dst,$srcInt,$srcVec,$tmp1,$tmp2,cr0\t// reduce vector int min/max" %}
12919 size(28);
12920 ins_encode %{
12921 int opcode = this->ideal_Opcode();
12922 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
12923 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
12924 %}
12925 ins_pipe(pipe_class_default);
12926 %}
12927
12928 // Vector Absolute Instructions
12929
12930 instruct vabs4F_reg(vecX dst, vecX src) %{
12931 match(Set dst (AbsVF src));
12932 predicate(n->as_Vector()->length() == 4);
12933 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
12934 size(4);
12935 ins_encode %{
12936 __ xvabssp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
12937 %}
12938 ins_pipe(pipe_class_default);
12939 %}
12940
12941 instruct vabs2D_reg(vecX dst, vecX src) %{
12942 match(Set dst (AbsVD src));
12943 predicate(n->as_Vector()->length() == 2);
12944 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
12945 size(4);
12946 ins_encode %{
12947 __ xvabsdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
12948 %}
12949 ins_pipe(pipe_class_default);
12950 %}
12951
12952 // Round Instructions
12953 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{
12954 match(Set dst (RoundDoubleMode src rmode));
12955 format %{ "RoundDoubleMode $src,$rmode" %}
12956 size(4);
12957 ins_encode %{
12958 switch ($rmode$$constant) {
12959 case RoundDoubleModeNode::rmode_rint:
12960 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr());
12961 break;
12962 case RoundDoubleModeNode::rmode_floor:
12963 __ frim($dst$$FloatRegister, $src$$FloatRegister);
12964 break;
12965 case RoundDoubleModeNode::rmode_ceil:
12966 __ frip($dst$$FloatRegister, $src$$FloatRegister);
12967 break;
12968 default:
12969 ShouldNotReachHere();
12970 }
12971 %}
12972 ins_pipe(pipe_class_default);
12973 %}
12974
12975 // Vector Round Instructions
12976 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
12977 match(Set dst (RoundDoubleModeV src rmode));
12978 predicate(n->as_Vector()->length() == 2);
12979 format %{ "RoundDoubleModeV $src,$rmode" %}
12980 size(4);
12981 ins_encode %{
12982 switch ($rmode$$constant) {
12983 case RoundDoubleModeNode::rmode_rint:
12984 __ xvrdpic($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
12985 break;
12986 case RoundDoubleModeNode::rmode_floor:
12987 __ xvrdpim($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
12988 break;
12989 case RoundDoubleModeNode::rmode_ceil:
12990 __ xvrdpip($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
12991 break;
12992 default:
12993 ShouldNotReachHere();
12994 }
12995 %}
12996 ins_pipe(pipe_class_default);
12997 %}
12998
12999 // Vector Negate Instructions
13000
13001 instruct vneg4F_reg(vecX dst, vecX src) %{
13002 match(Set dst (NegVF src));
13003 predicate(n->as_Vector()->length() == 4);
13004 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
13005 size(4);
13006 ins_encode %{
13007 __ xvnegsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13008 %}
13009 ins_pipe(pipe_class_default);
13010 %}
13011
13012 instruct vneg2D_reg(vecX dst, vecX src) %{
13013 match(Set dst (NegVD src));
13014 predicate(n->as_Vector()->length() == 2);
13015 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
13016 size(4);
13017 ins_encode %{
13018 __ xvnegdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13019 %}
13020 ins_pipe(pipe_class_default);
13021 %}
13022
13023 instruct vneg4I_reg(vecX dst, vecX src) %{
13024 match(Set dst (NegVI src));
13025 predicate(Matcher::vector_element_basic_type(n) == T_INT);
13026 format %{ "VNEGW $dst,$src\t// negate int vector" %}
13027 size(4);
13028 ins_encode %{
13029 __ vnegw($dst$$VectorRegister, $src$$VectorRegister);
13030 %}
13031 ins_pipe(pipe_class_default);
13032 %}
13033
13034 // Vector Square Root Instructions
13035
13036 instruct vsqrt4F_reg(vecX dst, vecX src) %{
13037 match(Set dst (SqrtVF src));
13038 predicate(n->as_Vector()->length() == 4);
13039 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
13040 size(4);
13041 ins_encode %{
13042 __ xvsqrtsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13043 %}
13044 ins_pipe(pipe_class_default);
13045 %}
13046
13047 instruct vsqrt2D_reg(vecX dst, vecX src) %{
13048 match(Set dst (SqrtVD src));
13049 predicate(n->as_Vector()->length() == 2);
13050 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %}
13051 size(4);
13052 ins_encode %{
13053 __ xvsqrtdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13054 %}
13055 ins_pipe(pipe_class_default);
13056 %}
13057
13058 // Vector Population Count and Zeros Count Instructions
13059
13060 instruct vpopcnt_reg(vecX dst, vecX src) %{
13061 match(Set dst (PopCountVI src));
13062 match(Set dst (PopCountVL src));
13063 format %{ "VPOPCNT $dst,$src\t// pop count packed" %}
13064 size(4);
13065 ins_encode %{
13066 BasicType bt = Matcher::vector_element_basic_type(this);
13067 switch (bt) {
13068 case T_BYTE:
13069 __ vpopcntb($dst$$VectorRegister, $src$$VectorRegister);
13070 break;
13071 case T_SHORT:
13072 __ vpopcnth($dst$$VectorRegister, $src$$VectorRegister);
13073 break;
13074 case T_INT:
13075 __ vpopcntw($dst$$VectorRegister, $src$$VectorRegister);
13076 break;
13077 case T_LONG:
13078 __ vpopcntd($dst$$VectorRegister, $src$$VectorRegister);
13079 break;
13080 default:
13081 ShouldNotReachHere();
13082 }
13083 %}
13084 ins_pipe(pipe_class_default);
13085 %}
13086
13087 instruct vcount_leading_zeros_reg(vecX dst, vecX src) %{
13088 match(Set dst (CountLeadingZerosV src));
13089 format %{ "VCLZ $dst,$src\t// leading zeros count packed" %}
13090 size(4);
13091 ins_encode %{
13092 BasicType bt = Matcher::vector_element_basic_type(this);
13093 switch (bt) {
13094 case T_BYTE:
13095 __ vclzb($dst$$VectorRegister, $src$$VectorRegister);
13096 break;
13097 case T_SHORT:
13098 __ vclzh($dst$$VectorRegister, $src$$VectorRegister);
13099 break;
13100 case T_INT:
13101 __ vclzw($dst$$VectorRegister, $src$$VectorRegister);
13102 break;
13103 case T_LONG:
13104 __ vclzd($dst$$VectorRegister, $src$$VectorRegister);
13105 break;
13106 default:
13107 ShouldNotReachHere();
13108 }
13109 %}
13110 ins_pipe(pipe_class_default);
13111 %}
13112
13113 instruct vcount_trailing_zeros_reg(vecX dst, vecX src) %{
13114 match(Set dst (CountTrailingZerosV src));
13115 format %{ "VCTZ $dst,$src\t// trailing zeros count packed" %}
13116 size(4);
13117 ins_encode %{
13118 BasicType bt = Matcher::vector_element_basic_type(this);
13119 switch (bt) {
13120 case T_BYTE:
13121 __ vctzb($dst$$VectorRegister, $src$$VectorRegister);
13122 break;
13123 case T_SHORT:
13124 __ vctzh($dst$$VectorRegister, $src$$VectorRegister);
13125 break;
13126 case T_INT:
13127 __ vctzw($dst$$VectorRegister, $src$$VectorRegister);
13128 break;
13129 case T_LONG:
13130 __ vctzd($dst$$VectorRegister, $src$$VectorRegister);
13131 break;
13132 default:
13133 ShouldNotReachHere();
13134 }
13135 %}
13136 ins_pipe(pipe_class_default);
13137 %}
13138
13139 // --------------------------------- FMA --------------------------------------
13140 // src1 * src2 + dst
13141 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{
13142 match(Set dst (FmaVF dst (Binary src1 src2)));
13143 predicate(n->as_Vector()->length() == 4);
13144
13145 format %{ "XVMADDASP $dst, $src1, $src2" %}
13146
13147 size(4);
13148 ins_encode %{
13149 assert(UseFMA, "Needs FMA instructions support.");
13150 __ xvmaddasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13151 %}
13152 ins_pipe(pipe_class_default);
13153 %}
13154
13155 // src1 * (-src2) + dst
13156 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13157 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{
13158 match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
13159 predicate(n->as_Vector()->length() == 4);
13160
13161 format %{ "XVNMSUBASP $dst, $src1, $src2" %}
13162
13163 size(4);
13164 ins_encode %{
13165 assert(UseFMA, "Needs FMA instructions support.");
13166 __ xvnmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13167 %}
13168 ins_pipe(pipe_class_default);
13169 %}
13170
13171 // src1 * src2 - dst
13172 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{
13173 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2)));
13174 predicate(n->as_Vector()->length() == 4);
13175
13176 format %{ "XVMSUBASP $dst, $src1, $src2" %}
13177
13178 size(4);
13179 ins_encode %{
13180 assert(UseFMA, "Needs FMA instructions support.");
13181 __ xvmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13182 %}
13183 ins_pipe(pipe_class_default);
13184 %}
13185
13186 // src1 * src2 + dst
13187 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{
13188 match(Set dst (FmaVD dst (Binary src1 src2)));
13189 predicate(n->as_Vector()->length() == 2);
13190
13191 format %{ "XVMADDADP $dst, $src1, $src2" %}
13192
13193 size(4);
13194 ins_encode %{
13195 assert(UseFMA, "Needs FMA instructions support.");
13196 __ xvmaddadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13197 %}
13198 ins_pipe(pipe_class_default);
13199 %}
13200
13201 // src1 * (-src2) + dst
13202 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13203 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{
13204 match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
13205 predicate(n->as_Vector()->length() == 2);
13206
13207 format %{ "XVNMSUBADP $dst, $src1, $src2" %}
13208
13209 size(4);
13210 ins_encode %{
13211 assert(UseFMA, "Needs FMA instructions support.");
13212 __ xvnmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13213 %}
13214 ins_pipe(pipe_class_default);
13215 %}
13216
13217 // src1 * src2 - dst
13218 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
13219 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2)));
13220 predicate(n->as_Vector()->length() == 2);
13221
13222 format %{ "XVMSUBADP $dst, $src1, $src2" %}
13223
13224 size(4);
13225 ins_encode %{
13226 assert(UseFMA, "Needs FMA instructions support.");
13227 __ xvmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13228 %}
13229 ins_pipe(pipe_class_default);
13230 %}
13231
13232 //----------Overflow Math Instructions-----------------------------------------
13233
13234 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
13235 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
13236 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
13237
13238 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13239 match(Set cr0 (OverflowAddL op1 op2));
13240
13241 format %{ "ADD_ $op1, $op2\t# overflow check long" %}
13242 size(12);
13243 ins_encode %{
13244 __ li(R0, 0);
13245 __ mtxer(R0); // clear XER.SO
13246 __ addo_(R0, $op1$$Register, $op2$$Register);
13247 %}
13248 ins_pipe(pipe_class_default);
13249 %}
13250
13251 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13252 match(Set cr0 (OverflowSubL op1 op2));
13253
13254 format %{ "SUBFO_ R0, $op2, $op1\t# overflow check long" %}
13255 size(12);
13256 ins_encode %{
13257 __ li(R0, 0);
13258 __ mtxer(R0); // clear XER.SO
13259 __ subfo_(R0, $op2$$Register, $op1$$Register);
13260 %}
13261 ins_pipe(pipe_class_default);
13262 %}
13263
13264 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
13265 match(Set cr0 (OverflowSubL zero op2));
13266
13267 format %{ "NEGO_ R0, $op2\t# overflow check long" %}
13268 size(12);
13269 ins_encode %{
13270 __ li(R0, 0);
13271 __ mtxer(R0); // clear XER.SO
13272 __ nego_(R0, $op2$$Register);
13273 %}
13274 ins_pipe(pipe_class_default);
13275 %}
13276
13277 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13278 match(Set cr0 (OverflowMulL op1 op2));
13279
13280 format %{ "MULLDO_ R0, $op1, $op2\t# overflow check long" %}
13281 size(12);
13282 ins_encode %{
13283 __ li(R0, 0);
13284 __ mtxer(R0); // clear XER.SO
13285 __ mulldo_(R0, $op1$$Register, $op2$$Register);
13286 %}
13287 ins_pipe(pipe_class_default);
13288 %}
13289
13290 instruct repl4F_reg_Ex(vecX dst, regF src) %{
13291 match(Set dst (Replicate src));
13292 predicate(n->as_Vector()->length() == 4 &&
13293 Matcher::vector_element_basic_type(n) == T_FLOAT);
13294 ins_cost(DEFAULT_COST);
13295 expand %{
13296 vecX tmpV;
13297 immI8 zero %{ (int) 0 %}
13298
13299 xscvdpspn_regF(tmpV, src);
13300 xxspltw(dst, tmpV, zero);
13301 %}
13302 %}
13303
13304 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{
13305 match(Set dst (Replicate src));
13306 predicate(n->as_Vector()->length() == 4 &&
13307 Matcher::vector_element_basic_type(n) == T_FLOAT);
13308 effect(TEMP tmp);
13309 ins_cost(10 * DEFAULT_COST);
13310
13311 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) );
13312 %}
13313
13314 instruct repl4F_immF0(vecX dst, immF_0 zero) %{
13315 match(Set dst (Replicate zero));
13316 predicate(n->as_Vector()->length() == 4 &&
13317 Matcher::vector_element_basic_type(n) == T_FLOAT);
13318
13319 format %{ "XXLXOR $dst, $zero \t// replicate4F" %}
13320 size(4);
13321 ins_encode %{
13322 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13323 %}
13324 ins_pipe(pipe_class_default);
13325 %}
13326
13327 instruct repl2D_reg_Ex(vecX dst, regD src) %{
13328 match(Set dst (Replicate src));
13329 predicate(n->as_Vector()->length() == 2 &&
13330 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13331
13332 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %}
13333 size(4);
13334 ins_encode %{
13335 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0);
13336 %}
13337 ins_pipe(pipe_class_default);
13338 %}
13339
13340 instruct repl2D_immD0(vecX dst, immD_0 zero) %{
13341 match(Set dst (Replicate zero));
13342 predicate(n->as_Vector()->length() == 2 &&
13343 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13344
13345 format %{ "XXLXOR $dst, $zero \t// replicate2D" %}
13346 size(4);
13347 ins_encode %{
13348 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13349 %}
13350 ins_pipe(pipe_class_default);
13351 %}
13352
13353 instruct mtvsrd(vecX dst, iRegLsrc src) %{
13354 predicate(false);
13355 effect(DEF dst, USE src);
13356
13357 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %}
13358 size(4);
13359 ins_encode %{
13360 __ mtvsrd($dst$$VectorRegister->to_vsr(), $src$$Register);
13361 %}
13362 ins_pipe(pipe_class_default);
13363 %}
13364
13365 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{
13366 effect(DEF dst, USE src, USE zero);
13367
13368 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %}
13369 size(4);
13370 ins_encode %{
13371 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $zero$$constant);
13372 %}
13373 ins_pipe(pipe_class_default);
13374 %}
13375
13376 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{
13377 effect(DEF dst, USE src1, USE src2, USE zero);
13378
13379 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %}
13380 size(4);
13381 ins_encode %{
13382 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr(), $zero$$constant);
13383 %}
13384 ins_pipe(pipe_class_default);
13385 %}
13386
13387 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{
13388 predicate(Matcher::vector_element_basic_type(n) == T_LONG);
13389 match(Set dst (Replicate src));
13390 predicate(n->as_Vector()->length() == 2);
13391 expand %{
13392 vecX tmpV;
13393 immI8 zero %{ (int) 0 %}
13394 mtvsrd(tmpV, src);
13395 xxpermdi(dst, tmpV, tmpV, zero);
13396 %}
13397 %}
13398
13399 instruct repl2L_immI0(vecX dst, immI_0 zero) %{
13400 match(Set dst (Replicate zero));
13401 predicate(n->as_Vector()->length() == 2 &&
13402 Matcher::vector_element_basic_type(n) == T_LONG);
13403
13404 format %{ "XXLXOR $dst, $zero \t// replicate2L" %}
13405 size(4);
13406 ins_encode %{
13407 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13408 %}
13409 ins_pipe(pipe_class_default);
13410 %}
13411
13412 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{
13413 match(Set dst (Replicate src));
13414 predicate(n->as_Vector()->length() == 2 &&
13415 Matcher::vector_element_basic_type(n) == T_LONG);
13416
13417 format %{ "XXLEQV $dst, $src \t// replicate2L" %}
13418 size(4);
13419 ins_encode %{
13420 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13421 %}
13422 ins_pipe(pipe_class_default);
13423 %}
13424
13425 // ============================================================================
13426 // Safepoint Instruction
13427
13428 instruct safePoint_poll(iRegPdst poll) %{
13429 match(SafePoint poll);
13430
13431 // It caused problems to add the effect that r0 is killed, but this
13432 // effect no longer needs to be mentioned, since r0 is not contained
13433 // in a reg_class.
13434
13435 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
13436 size(4);
13437 ins_encode( enc_poll(0x0, poll) );
13438 ins_pipe(pipe_class_default);
13439 %}
13440
13441 // ============================================================================
13442 // Call Instructions
13443
13444 source %{
13445
13446 #include "runtime/continuation.hpp"
13447
13448 %}
13449
13450 // Call Java Static Instruction
13451
13452 instruct CallStaticJavaDirect(method meth) %{
13453 match(CallStaticJava);
13454 effect(USE meth);
13455 ins_cost(CALL_COST);
13456
13457 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
13458
13459 format %{ "CALL,static $meth \t// ==> " %}
13460 size((Continuations::enabled() ? 8 : 4));
13461 ins_encode( enc_java_static_call(meth) );
13462 ins_pipe(pipe_class_call);
13463 %}
13464
13465 // Call Java Dynamic Instruction
13466
13467 instruct CallDynamicJavaDirect(method meth) %{
13468 match(CallDynamicJava);
13469 effect(USE meth);
13470 ins_cost(CALL_COST);
13471
13472 // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
13473 ins_num_consts(4);
13474
13475 format %{ "CALL,dynamic $meth \t// ==> " %}
13476 ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
13477 ins_pipe(pipe_class_call);
13478 %}
13479
13480 // Call Runtime Instruction
13481
13482 instruct CallRuntimeDirect(method meth) %{
13483 match(CallRuntime);
13484 effect(USE meth);
13485 ins_cost(CALL_COST);
13486
13487 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13488 // env for callee, C-toc.
13489 ins_num_consts(3);
13490
13491 format %{ "CALL,runtime" %}
13492 ins_encode( enc_java_to_runtime_call(meth) );
13493 ins_pipe(pipe_class_call);
13494 %}
13495
13496 // Call Leaf
13497
13498 // Used by postalloc expand of CallLeafDirect_Ex (mtctr).
13499 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
13500 effect(DEF dst, USE src);
13501
13502 ins_num_consts(1);
13503
13504 format %{ "MTCTR $src" %}
13505 size(4);
13506 ins_encode( enc_leaf_call_mtctr(src) );
13507 ins_pipe(pipe_class_default);
13508 %}
13509
13510 // Used by postalloc expand of CallLeafDirect_Ex (actual call).
13511 instruct CallLeafDirect(method meth) %{
13512 match(CallLeaf); // To get the data all the data fields we need ...
13513 effect(USE meth);
13514 predicate(false); // but never match.
13515
13516 format %{ "BCTRL \t// leaf call $meth ==> " %}
13517 size((Continuations::enabled() ? 8 : 4));
13518 ins_encode %{
13519 __ bctrl();
13520 __ post_call_nop();
13521 %}
13522 ins_pipe(pipe_class_call);
13523 %}
13524
13525 // postalloc expand of CallLeafDirect.
13526 // Load address to call from TOC, then bl to it.
13527 instruct CallLeafDirect_Ex(method meth) %{
13528 match(CallLeaf);
13529 effect(USE meth);
13530 ins_cost(CALL_COST);
13531
13532 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
13533 // env for callee, C-toc.
13534 ins_num_consts(3);
13535
13536 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
13537 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13538 %}
13539
13540 // Call runtime without safepoint - same as CallLeaf.
13541 // postalloc expand of CallLeafNoFPDirect.
13542 // Load address to call from TOC, then bl to it.
13543 instruct CallLeafNoFPDirect_Ex(method meth) %{
13544 match(CallLeafNoFP);
13545 effect(USE meth);
13546 ins_cost(CALL_COST);
13547
13548 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13549 // env for callee, C-toc.
13550 ins_num_consts(3);
13551
13552 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
13553 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13554 %}
13555
13556 // Tail Call; Jump from runtime stub to Java code.
13557 // Also known as an 'interprocedural jump'.
13558 // Target of jump will eventually return to caller.
13559 // TailJump below removes the return address.
13560 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{
13561 match(TailCall jump_target method_ptr);
13562 ins_cost(CALL_COST);
13563
13564 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t"
13565 "BCTR \t// tail call" %}
13566 size(8);
13567 ins_encode %{
13568 __ mtctr($jump_target$$Register);
13569 __ bctr();
13570 %}
13571 ins_pipe(pipe_class_call);
13572 %}
13573
13574 // Return Instruction
13575 instruct Ret() %{
13576 match(Return);
13577 format %{ "BLR \t// branch to link register" %}
13578 size(4);
13579 ins_encode %{
13580 // LR is restored in MachEpilogNode. Just do the RET here.
13581 __ blr();
13582 %}
13583 ins_pipe(pipe_class_default);
13584 %}
13585
13586 // Tail Jump; remove the return address; jump to target.
13587 // TailCall above leaves the return address around.
13588 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13589 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13590 // "restore" before this instruction (in Epilogue), we need to materialize it
13591 // in %i0.
13592 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
13593 match(TailJump jump_target ex_oop);
13594 ins_cost(CALL_COST);
13595
13596 format %{ "LD R4_ARG2 = LR\n\t"
13597 "MTCTR $jump_target\n\t"
13598 "BCTR \t// TailJump, exception oop: $ex_oop" %}
13599 size(12);
13600 ins_encode %{
13601 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP);
13602 __ mtctr($jump_target$$Register);
13603 __ bctr();
13604 %}
13605 ins_pipe(pipe_class_call);
13606 %}
13607
13608 // Forward exception.
13609 instruct ForwardExceptionjmp()
13610 %{
13611 match(ForwardException);
13612 ins_cost(CALL_COST);
13613
13614 format %{ "JMP forward_exception_stub" %}
13615 ins_encode %{
13616 __ set_inst_mark();
13617 __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
13618 __ clear_inst_mark();
13619 %}
13620 ins_pipe(pipe_class_call);
13621 %}
13622
13623 // Create exception oop: created by stack-crawling runtime code.
13624 // Created exception is now available to this handler, and is setup
13625 // just prior to jumping to this handler. No code emitted.
13626 instruct CreateException(rarg1RegP ex_oop) %{
13627 match(Set ex_oop (CreateEx));
13628 ins_cost(0);
13629
13630 format %{ " -- \t// exception oop; no code emitted" %}
13631 size(0);
13632 ins_encode( /*empty*/ );
13633 ins_pipe(pipe_class_default);
13634 %}
13635
13636 // Rethrow exception: The exception oop will come in the first
13637 // argument position. Then JUMP (not call) to the rethrow stub code.
13638 instruct RethrowException() %{
13639 match(Rethrow);
13640 ins_cost(CALL_COST);
13641
13642 format %{ "JMP rethrow_stub" %}
13643 ins_encode %{
13644 __ set_inst_mark();
13645 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
13646 __ clear_inst_mark();
13647 %}
13648 ins_pipe(pipe_class_call);
13649 %}
13650
13651 // Die now.
13652 instruct ShouldNotReachHere() %{
13653 match(Halt);
13654 ins_cost(CALL_COST);
13655
13656 format %{ "ShouldNotReachHere" %}
13657 ins_encode %{
13658 if (is_reachable()) {
13659 const char* str = __ code_string(_halt_reason);
13660 __ stop(str);
13661 }
13662 %}
13663 ins_pipe(pipe_class_default);
13664 %}
13665
13666 // This name is KNOWN by the ADLC and cannot be changed. The ADLC
13667 // forces a 'TypeRawPtr::BOTTOM' output type for this guy.
13668 // Get a DEF on threadRegP, no costs, no encoding, use
13669 // 'ins_should_rematerialize(true)' to avoid spilling.
13670 instruct tlsLoadP(threadRegP dst) %{
13671 match(Set dst (ThreadLocal));
13672 ins_cost(0);
13673
13674 ins_should_rematerialize(true);
13675
13676 format %{ " -- \t// $dst=Thread::current(), empty" %}
13677 size(0);
13678 ins_encode( /*empty*/ );
13679 ins_pipe(pipe_class_empty);
13680 %}
13681
13682 //---Some PPC specific nodes---------------------------------------------------
13683
13684 // Nop instructions
13685
13686 instruct fxNop() %{
13687 ins_cost(0);
13688
13689 ins_is_nop(true);
13690
13691 format %{ "fxNop" %}
13692 size(4);
13693 ins_encode %{
13694 __ nop();
13695 %}
13696 ins_pipe(pipe_class_default);
13697 %}
13698
13699 instruct fpNop0() %{
13700 ins_cost(0);
13701
13702 ins_is_nop(true);
13703
13704 format %{ "fpNop0" %}
13705 size(4);
13706 ins_encode %{
13707 __ fpnop0();
13708 %}
13709 ins_pipe(pipe_class_default);
13710 %}
13711
13712 instruct fpNop1() %{
13713 ins_cost(0);
13714
13715 ins_is_nop(true);
13716
13717 format %{ "fpNop1" %}
13718 size(4);
13719 ins_encode %{
13720 __ fpnop1();
13721 %}
13722 ins_pipe(pipe_class_default);
13723 %}
13724
13725 instruct brNop0() %{
13726 ins_cost(0);
13727 size(4);
13728 format %{ "brNop0" %}
13729 ins_encode %{
13730 __ brnop0();
13731 %}
13732 ins_is_nop(true);
13733 ins_pipe(pipe_class_default);
13734 %}
13735
13736 instruct brNop1() %{
13737 ins_cost(0);
13738
13739 ins_is_nop(true);
13740
13741 format %{ "brNop1" %}
13742 size(4);
13743 ins_encode %{
13744 __ brnop1();
13745 %}
13746 ins_pipe(pipe_class_default);
13747 %}
13748
13749 instruct brNop2() %{
13750 ins_cost(0);
13751
13752 ins_is_nop(true);
13753
13754 format %{ "brNop2" %}
13755 size(4);
13756 ins_encode %{
13757 __ brnop2();
13758 %}
13759 ins_pipe(pipe_class_default);
13760 %}
13761
13762 instruct cacheWB(indirect addr)
13763 %{
13764 match(CacheWB addr);
13765
13766 ins_cost(100);
13767 format %{ "cache writeback, address = $addr" %}
13768 ins_encode %{
13769 assert($addr->index_position() < 0, "should be");
13770 assert($addr$$disp == 0, "should be");
13771 __ cache_wb(Address($addr$$base$$Register));
13772 %}
13773 ins_pipe(pipe_class_default);
13774 %}
13775
13776 instruct cacheWBPreSync()
13777 %{
13778 match(CacheWBPreSync);
13779
13780 ins_cost(0);
13781 format %{ "cache writeback presync" %}
13782 ins_encode %{
13783 __ cache_wbsync(true);
13784 %}
13785 ins_pipe(pipe_class_default);
13786 %}
13787
13788 instruct cacheWBPostSync()
13789 %{
13790 match(CacheWBPostSync);
13791
13792 ins_cost(100);
13793 format %{ "cache writeback postsync" %}
13794 ins_encode %{
13795 __ cache_wbsync(false);
13796 %}
13797 ins_pipe(pipe_class_default);
13798 %}
13799
13800 //----------PEEPHOLE RULES-----------------------------------------------------
13801 // These must follow all instruction definitions as they use the names
13802 // defined in the instructions definitions.
13803 //
13804 // peepmatch ( root_instr_name [preceeding_instruction]* );
13805 //
13806 // peepconstraint %{
13807 // (instruction_number.operand_name relational_op instruction_number.operand_name
13808 // [, ...] );
13809 // // instruction numbers are zero-based using left to right order in peepmatch
13810 //
13811 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
13812 // // provide an instruction_number.operand_name for each operand that appears
13813 // // in the replacement instruction's match rule
13814 //
13815 // ---------VM FLAGS---------------------------------------------------------
13816 //
13817 // All peephole optimizations can be turned off using -XX:-OptoPeephole
13818 //
13819 // Each peephole rule is given an identifying number starting with zero and
13820 // increasing by one in the order seen by the parser. An individual peephole
13821 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
13822 // on the command-line.
13823 //
13824 // ---------CURRENT LIMITATIONS----------------------------------------------
13825 //
13826 // Only match adjacent instructions in same basic block
13827 // Only equality constraints
13828 // Only constraints between operands, not (0.dest_reg == EAX_enc)
13829 // Only one replacement instruction
13830 //
13831 // ---------EXAMPLE----------------------------------------------------------
13832 //
13833 // // pertinent parts of existing instructions in architecture description
13834 // instruct movI(eRegI dst, eRegI src) %{
13835 // match(Set dst (CopyI src));
13836 // %}
13837 //
13838 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
13839 // match(Set dst (AddI dst src));
13840 // effect(KILL cr);
13841 // %}
13842 //
13843 // // Change (inc mov) to lea
13844 // peephole %{
13845 // // increment preceded by register-register move
13846 // peepmatch ( incI_eReg movI );
13847 // // require that the destination register of the increment
13848 // // match the destination register of the move
13849 // peepconstraint ( 0.dst == 1.dst );
13850 // // construct a replacement instruction that sets
13851 // // the destination to ( move's source register + one )
13852 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13853 // %}
13854 //
13855 // Implementation no longer uses movX instructions since
13856 // machine-independent system no longer uses CopyX nodes.
13857 //
13858 // peephole %{
13859 // peepmatch ( incI_eReg movI );
13860 // peepconstraint ( 0.dst == 1.dst );
13861 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13862 // %}
13863 //
13864 // peephole %{
13865 // peepmatch ( decI_eReg movI );
13866 // peepconstraint ( 0.dst == 1.dst );
13867 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13868 // %}
13869 //
13870 // peephole %{
13871 // peepmatch ( addI_eReg_imm movI );
13872 // peepconstraint ( 0.dst == 1.dst );
13873 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13874 // %}
13875 //
13876 // peephole %{
13877 // peepmatch ( addP_eReg_imm movP );
13878 // peepconstraint ( 0.dst == 1.dst );
13879 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
13880 // %}
13881
13882 // // Change load of spilled value to only a spill
13883 // instruct storeI(memory mem, eRegI src) %{
13884 // match(Set mem (StoreI mem src));
13885 // %}
13886 //
13887 // instruct loadI(eRegI dst, memory mem) %{
13888 // match(Set dst (LoadI mem));
13889 // %}
13890 //
13891 peephole %{
13892 peepmatch ( loadI storeI );
13893 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
13894 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
13895 %}
13896
13897 peephole %{
13898 peepmatch ( loadL storeL );
13899 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
13900 peepreplace ( storeL( 1.mem 1.mem 1.src ) );
13901 %}
13902
13903 peephole %{
13904 peepmatch ( loadP storeP );
13905 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
13906 peepreplace ( storeP( 1.dst 1.dst 1.src ) );
13907 %}
13908
13909 //----------SMARTSPILL RULES---------------------------------------------------
13910 // These must follow all instruction definitions as they use the names
13911 // defined in the instructions definitions.