1 //
2 // Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved.
3 // Copyright (c) 2012, 2026 SAP SE. All rights reserved.
4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 //
6 // This code is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License version 2 only, as
8 // published by the Free Software Foundation.
9 //
10 // This code is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // version 2 for more details (a copy is included in the LICENSE file that
14 // accompanied this code).
15 //
16 // You should have received a copy of the GNU General Public License version
17 // 2 along with this work; if not, write to the Free Software Foundation,
18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 // or visit www.oracle.com if you need additional information or have any
22 // questions.
23 //
24 //
25
26 //
27 // PPC64 Architecture Description File
28 //
29
30 //----------REGISTER DEFINITION BLOCK------------------------------------------
31 // This information is used by the matcher and the register allocator to
32 // describe individual registers and classes of registers within the target
33 // architecture.
34 register %{
35 //----------Architecture Description Register Definitions----------------------
36 // General Registers
37 // "reg_def" name (register save type, C convention save type,
38 // ideal register type, encoding);
39 //
40 // Register Save Types:
41 //
42 // NS = No-Save: The register allocator assumes that these registers
43 // can be used without saving upon entry to the method, &
44 // that they do not need to be saved at call sites.
45 //
46 // SOC = Save-On-Call: The register allocator assumes that these registers
47 // can be used without saving upon entry to the method,
48 // but that they must be saved at call sites.
49 // These are called "volatiles" on ppc.
50 //
51 // SOE = Save-On-Entry: The register allocator assumes that these registers
52 // must be saved before using them upon entry to the
53 // method, but they do not need to be saved at call
54 // sites.
55 // These are called "nonvolatiles" on ppc.
56 //
57 // AS = Always-Save: The register allocator assumes that these registers
58 // must be saved before using them upon entry to the
59 // method, & that they must be saved at call sites.
60 //
61 // Ideal Register Type is used to determine how to save & restore a
62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
64 //
65 // The encoding number is the actual bit-pattern placed into the opcodes.
66 //
67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI
68 // Supplement Version 1.7 as of 2003-10-29.
69 //
70 // For each 64-bit register we must define two registers: the register
71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half',
72 // e.g. R3_H, which is needed by the allocator, but is not used
73 // for stores, loads, etc.
74
75 // ----------------------------
76 // Integer/Long Registers
77 // ----------------------------
78
79 // PPC64 has 32 64-bit integer registers.
80
81 // types: v = volatile, nv = non-volatile, s = system
82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs
83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() );
84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP
85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() );
86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC
87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() );
88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret
89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() );
90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2
91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() );
92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3
93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() );
94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4
95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() );
96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5
97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() );
98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6
99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() );
100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7
101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() );
102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8
103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next());
104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch
105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next());
106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch
107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next());
108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id
109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next());
110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv
111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next());
112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv
113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next());
114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv
115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next());
116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv
117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next());
118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv
119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next());
120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv
121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next());
122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv
123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next());
124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv
125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next());
126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv
127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next());
128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv
129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next());
130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv
131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next());
132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv
133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next());
134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv
135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next());
136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv
137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next());
138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv
139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next());
140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv
141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next());
142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv
143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next());
144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv
145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next());
146
147
148 // ----------------------------
149 // Float/Double Registers
150 // ----------------------------
151
152 // Double Registers
153 // The rules of ADL require that double registers be defined in pairs.
154 // Each pair must be two 32-bit values, but not necessarily a pair of
155 // single float registers. In each pair, ADLC-assigned register numbers
156 // must be adjacent, with the lower number even. Finally, when the
157 // CPU stores such a register pair to memory, the word associated with
158 // the lower ADLC-assigned number must be stored to the lower address.
159
160 // PPC64 has 32 64-bit floating-point registers. Each can store a single
161 // or double precision floating-point value.
162
163 // types: v = volatile, nv = non-volatile, s = system
164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch
165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() );
166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret
167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() );
168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2
169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() );
170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3
171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() );
172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4
173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() );
174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5
175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() );
176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6
177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() );
178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7
179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() );
180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8
181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() );
182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9
183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() );
184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10
185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next());
186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11
187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next());
188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12
189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next());
190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13
191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next());
192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv
193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next());
194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv
195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next());
196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv
197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next());
198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv
199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next());
200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv
201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next());
202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv
203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next());
204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv
205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next());
206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv
207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next());
208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv
209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next());
210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv
211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next());
212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv
213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next());
214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv
215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next());
216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv
217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next());
218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv
219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next());
220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv
221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next());
222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv
223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next());
224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv
225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next());
226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv
227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next());
228
229 // ----------------------------
230 // Special Registers
231 // ----------------------------
232
233 // Condition Codes Flag Registers
234
235 // PPC64 has 8 condition code "registers" which are all contained
236 // in the CR register.
237
238 // types: v = volatile, nv = non-volatile, s = system
239 reg_def CR0(SOC, SOC, Op_RegFlags, 0, CR0->as_VMReg()); // v
240 reg_def CR1(SOC, SOC, Op_RegFlags, 1, CR1->as_VMReg()); // v
241 reg_def CR2(SOC, SOC, Op_RegFlags, 2, CR2->as_VMReg()); // nv
242 reg_def CR3(SOC, SOC, Op_RegFlags, 3, CR3->as_VMReg()); // nv
243 reg_def CR4(SOC, SOC, Op_RegFlags, 4, CR4->as_VMReg()); // nv
244 reg_def CR5(SOC, SOC, Op_RegFlags, 5, CR5->as_VMReg()); // v
245 reg_def CR6(SOC, SOC, Op_RegFlags, 6, CR6->as_VMReg()); // v
246 reg_def CR7(SOC, SOC, Op_RegFlags, 7, CR7->as_VMReg()); // v
247
248 // Special registers of PPC64
249
250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v
251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v
252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v
253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v
254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v
255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v
256
257 // ----------------------------
258 // Vector Registers
259 // ----------------------------
260
261 reg_def VR0 (SOC, SOC, Op_RegF, 0, VR0->as_VMReg() );
262 reg_def VR0_H(SOC, SOC, Op_RegF, 0, VR0->as_VMReg()->next() );
263 reg_def VR0_J(SOC, SOC, Op_RegF, 0, VR0->as_VMReg()->next(2));
264 reg_def VR0_K(SOC, SOC, Op_RegF, 0, VR0->as_VMReg()->next(3));
265
266 reg_def VR1 (SOC, SOC, Op_RegF, 1, VR1->as_VMReg() );
267 reg_def VR1_H(SOC, SOC, Op_RegF, 1, VR1->as_VMReg()->next() );
268 reg_def VR1_J(SOC, SOC, Op_RegF, 1, VR1->as_VMReg()->next(2));
269 reg_def VR1_K(SOC, SOC, Op_RegF, 1, VR1->as_VMReg()->next(3));
270
271 reg_def VR2 (SOC, SOC, Op_RegF, 2, VR2->as_VMReg() );
272 reg_def VR2_H(SOC, SOC, Op_RegF, 2, VR2->as_VMReg()->next() );
273 reg_def VR2_J(SOC, SOC, Op_RegF, 2, VR2->as_VMReg()->next(2));
274 reg_def VR2_K(SOC, SOC, Op_RegF, 2, VR2->as_VMReg()->next(3));
275
276 reg_def VR3 (SOC, SOC, Op_RegF, 3, VR3->as_VMReg() );
277 reg_def VR3_H(SOC, SOC, Op_RegF, 3, VR3->as_VMReg()->next() );
278 reg_def VR3_J(SOC, SOC, Op_RegF, 3, VR3->as_VMReg()->next(2));
279 reg_def VR3_K(SOC, SOC, Op_RegF, 3, VR3->as_VMReg()->next(3));
280
281 reg_def VR4 (SOC, SOC, Op_RegF, 4, VR4->as_VMReg() );
282 reg_def VR4_H(SOC, SOC, Op_RegF, 4, VR4->as_VMReg()->next() );
283 reg_def VR4_J(SOC, SOC, Op_RegF, 4, VR4->as_VMReg()->next(2));
284 reg_def VR4_K(SOC, SOC, Op_RegF, 4, VR4->as_VMReg()->next(3));
285
286 reg_def VR5 (SOC, SOC, Op_RegF, 5, VR5->as_VMReg() );
287 reg_def VR5_H(SOC, SOC, Op_RegF, 5, VR5->as_VMReg()->next() );
288 reg_def VR5_J(SOC, SOC, Op_RegF, 5, VR5->as_VMReg()->next(2));
289 reg_def VR5_K(SOC, SOC, Op_RegF, 5, VR5->as_VMReg()->next(3));
290
291 reg_def VR6 (SOC, SOC, Op_RegF, 6, VR6->as_VMReg() );
292 reg_def VR6_H(SOC, SOC, Op_RegF, 6, VR6->as_VMReg()->next() );
293 reg_def VR6_J(SOC, SOC, Op_RegF, 6, VR6->as_VMReg()->next(2));
294 reg_def VR6_K(SOC, SOC, Op_RegF, 6, VR6->as_VMReg()->next(3));
295
296 reg_def VR7 (SOC, SOC, Op_RegF, 7, VR7->as_VMReg() );
297 reg_def VR7_H(SOC, SOC, Op_RegF, 7, VR7->as_VMReg()->next() );
298 reg_def VR7_J(SOC, SOC, Op_RegF, 7, VR7->as_VMReg()->next(2));
299 reg_def VR7_K(SOC, SOC, Op_RegF, 7, VR7->as_VMReg()->next(3));
300
301 reg_def VR8 (SOC, SOC, Op_RegF, 8, VR8->as_VMReg() );
302 reg_def VR8_H(SOC, SOC, Op_RegF, 8, VR8->as_VMReg()->next() );
303 reg_def VR8_J(SOC, SOC, Op_RegF, 8, VR8->as_VMReg()->next(2));
304 reg_def VR8_K(SOC, SOC, Op_RegF, 8, VR8->as_VMReg()->next(3));
305
306 reg_def VR9 (SOC, SOC, Op_RegF, 9, VR9->as_VMReg() );
307 reg_def VR9_H(SOC, SOC, Op_RegF, 9, VR9->as_VMReg()->next() );
308 reg_def VR9_J(SOC, SOC, Op_RegF, 9, VR9->as_VMReg()->next(2));
309 reg_def VR9_K(SOC, SOC, Op_RegF, 9, VR9->as_VMReg()->next(3));
310
311 reg_def VR10 (SOC, SOC, Op_RegF, 10, VR10->as_VMReg() );
312 reg_def VR10_H(SOC, SOC, Op_RegF, 10, VR10->as_VMReg()->next() );
313 reg_def VR10_J(SOC, SOC, Op_RegF, 10, VR10->as_VMReg()->next(2));
314 reg_def VR10_K(SOC, SOC, Op_RegF, 10, VR10->as_VMReg()->next(3));
315
316 reg_def VR11 (SOC, SOC, Op_RegF, 11, VR11->as_VMReg() );
317 reg_def VR11_H(SOC, SOC, Op_RegF, 11, VR11->as_VMReg()->next() );
318 reg_def VR11_J(SOC, SOC, Op_RegF, 11, VR11->as_VMReg()->next(2));
319 reg_def VR11_K(SOC, SOC, Op_RegF, 11, VR11->as_VMReg()->next(3));
320
321 reg_def VR12 (SOC, SOC, Op_RegF, 12, VR12->as_VMReg() );
322 reg_def VR12_H(SOC, SOC, Op_RegF, 12, VR12->as_VMReg()->next() );
323 reg_def VR12_J(SOC, SOC, Op_RegF, 12, VR12->as_VMReg()->next(2));
324 reg_def VR12_K(SOC, SOC, Op_RegF, 12, VR12->as_VMReg()->next(3));
325
326 reg_def VR13 (SOC, SOC, Op_RegF, 13, VR13->as_VMReg() );
327 reg_def VR13_H(SOC, SOC, Op_RegF, 13, VR13->as_VMReg()->next() );
328 reg_def VR13_J(SOC, SOC, Op_RegF, 13, VR13->as_VMReg()->next(2));
329 reg_def VR13_K(SOC, SOC, Op_RegF, 13, VR13->as_VMReg()->next(3));
330
331 reg_def VR14 (SOC, SOC, Op_RegF, 14, VR14->as_VMReg() );
332 reg_def VR14_H(SOC, SOC, Op_RegF, 14, VR14->as_VMReg()->next() );
333 reg_def VR14_J(SOC, SOC, Op_RegF, 14, VR14->as_VMReg()->next(2));
334 reg_def VR14_K(SOC, SOC, Op_RegF, 14, VR14->as_VMReg()->next(3));
335
336 reg_def VR15 (SOC, SOC, Op_RegF, 15, VR15->as_VMReg() );
337 reg_def VR15_H(SOC, SOC, Op_RegF, 15, VR15->as_VMReg()->next() );
338 reg_def VR15_J(SOC, SOC, Op_RegF, 15, VR15->as_VMReg()->next(2));
339 reg_def VR15_K(SOC, SOC, Op_RegF, 15, VR15->as_VMReg()->next(3));
340
341 reg_def VR16 (SOC, SOC, Op_RegF, 16, VR16->as_VMReg() );
342 reg_def VR16_H(SOC, SOC, Op_RegF, 16, VR16->as_VMReg()->next() );
343 reg_def VR16_J(SOC, SOC, Op_RegF, 16, VR16->as_VMReg()->next(2));
344 reg_def VR16_K(SOC, SOC, Op_RegF, 16, VR16->as_VMReg()->next(3));
345
346 reg_def VR17 (SOC, SOC, Op_RegF, 17, VR17->as_VMReg() );
347 reg_def VR17_H(SOC, SOC, Op_RegF, 17, VR17->as_VMReg()->next() );
348 reg_def VR17_J(SOC, SOC, Op_RegF, 17, VR17->as_VMReg()->next(2));
349 reg_def VR17_K(SOC, SOC, Op_RegF, 17, VR17->as_VMReg()->next(3));
350
351 reg_def VR18 (SOC, SOC, Op_RegF, 18, VR18->as_VMReg() );
352 reg_def VR18_H(SOC, SOC, Op_RegF, 18, VR18->as_VMReg()->next() );
353 reg_def VR18_J(SOC, SOC, Op_RegF, 18, VR18->as_VMReg()->next(2));
354 reg_def VR18_K(SOC, SOC, Op_RegF, 18, VR18->as_VMReg()->next(3));
355
356 reg_def VR19 (SOC, SOC, Op_RegF, 19, VR19->as_VMReg() );
357 reg_def VR19_H(SOC, SOC, Op_RegF, 19, VR19->as_VMReg()->next() );
358 reg_def VR19_J(SOC, SOC, Op_RegF, 19, VR19->as_VMReg()->next(2));
359 reg_def VR19_K(SOC, SOC, Op_RegF, 19, VR19->as_VMReg()->next(3));
360
361 reg_def VR20 (SOC, SOE, Op_RegF, 20, VR20->as_VMReg() );
362 reg_def VR20_H(SOC, SOE, Op_RegF, 20, VR20->as_VMReg()->next() );
363 reg_def VR20_J(SOC, SOE, Op_RegF, 20, VR20->as_VMReg()->next(2));
364 reg_def VR20_K(SOC, SOE, Op_RegF, 20, VR20->as_VMReg()->next(3));
365
366 reg_def VR21 (SOC, SOE, Op_RegF, 21, VR21->as_VMReg() );
367 reg_def VR21_H(SOC, SOE, Op_RegF, 21, VR21->as_VMReg()->next() );
368 reg_def VR21_J(SOC, SOE, Op_RegF, 21, VR21->as_VMReg()->next(2));
369 reg_def VR21_K(SOC, SOE, Op_RegF, 21, VR21->as_VMReg()->next(3));
370
371 reg_def VR22 (SOC, SOE, Op_RegF, 22, VR22->as_VMReg() );
372 reg_def VR22_H(SOC, SOE, Op_RegF, 22, VR22->as_VMReg()->next() );
373 reg_def VR22_J(SOC, SOE, Op_RegF, 22, VR22->as_VMReg()->next(2));
374 reg_def VR22_K(SOC, SOE, Op_RegF, 22, VR22->as_VMReg()->next(3));
375
376 reg_def VR23 (SOC, SOE, Op_RegF, 23, VR23->as_VMReg() );
377 reg_def VR23_H(SOC, SOE, Op_RegF, 23, VR23->as_VMReg()->next() );
378 reg_def VR23_J(SOC, SOE, Op_RegF, 23, VR23->as_VMReg()->next(2));
379 reg_def VR23_K(SOC, SOE, Op_RegF, 23, VR23->as_VMReg()->next(3));
380
381 reg_def VR24 (SOC, SOE, Op_RegF, 24, VR24->as_VMReg() );
382 reg_def VR24_H(SOC, SOE, Op_RegF, 24, VR24->as_VMReg()->next() );
383 reg_def VR24_J(SOC, SOE, Op_RegF, 24, VR24->as_VMReg()->next(2));
384 reg_def VR24_K(SOC, SOE, Op_RegF, 24, VR24->as_VMReg()->next(3));
385
386 reg_def VR25 (SOC, SOE, Op_RegF, 25, VR25->as_VMReg() );
387 reg_def VR25_H(SOC, SOE, Op_RegF, 25, VR25->as_VMReg()->next() );
388 reg_def VR25_J(SOC, SOE, Op_RegF, 25, VR25->as_VMReg()->next(2));
389 reg_def VR25_K(SOC, SOE, Op_RegF, 25, VR25->as_VMReg()->next(3));
390
391 reg_def VR26 (SOC, SOE, Op_RegF, 26, VR26->as_VMReg() );
392 reg_def VR26_H(SOC, SOE, Op_RegF, 26, VR26->as_VMReg()->next() );
393 reg_def VR26_J(SOC, SOE, Op_RegF, 26, VR26->as_VMReg()->next(2));
394 reg_def VR26_K(SOC, SOE, Op_RegF, 26, VR26->as_VMReg()->next(3));
395
396 reg_def VR27 (SOC, SOE, Op_RegF, 27, VR27->as_VMReg() );
397 reg_def VR27_H(SOC, SOE, Op_RegF, 27, VR27->as_VMReg()->next() );
398 reg_def VR27_J(SOC, SOE, Op_RegF, 27, VR27->as_VMReg()->next(2));
399 reg_def VR27_K(SOC, SOE, Op_RegF, 27, VR27->as_VMReg()->next(3));
400
401 reg_def VR28 (SOC, SOE, Op_RegF, 28, VR28->as_VMReg() );
402 reg_def VR28_H(SOC, SOE, Op_RegF, 28, VR28->as_VMReg()->next() );
403 reg_def VR28_J(SOC, SOE, Op_RegF, 28, VR28->as_VMReg()->next(2));
404 reg_def VR28_K(SOC, SOE, Op_RegF, 28, VR28->as_VMReg()->next(3));
405
406 reg_def VR29 (SOC, SOE, Op_RegF, 29, VR29->as_VMReg() );
407 reg_def VR29_H(SOC, SOE, Op_RegF, 29, VR29->as_VMReg()->next() );
408 reg_def VR29_J(SOC, SOE, Op_RegF, 29, VR29->as_VMReg()->next(2));
409 reg_def VR29_K(SOC, SOE, Op_RegF, 29, VR29->as_VMReg()->next(3));
410
411 reg_def VR30 (SOC, SOE, Op_RegF, 30, VR30->as_VMReg() );
412 reg_def VR30_H(SOC, SOE, Op_RegF, 30, VR30->as_VMReg()->next() );
413 reg_def VR30_J(SOC, SOE, Op_RegF, 30, VR30->as_VMReg()->next(2));
414 reg_def VR30_K(SOC, SOE, Op_RegF, 30, VR30->as_VMReg()->next(3));
415
416 reg_def VR31 (SOC, SOE, Op_RegF, 31, VR31->as_VMReg() );
417 reg_def VR31_H(SOC, SOE, Op_RegF, 31, VR31->as_VMReg()->next() );
418 reg_def VR31_J(SOC, SOE, Op_RegF, 31, VR31->as_VMReg()->next(2));
419 reg_def VR31_K(SOC, SOE, Op_RegF, 31, VR31->as_VMReg()->next(3));
420
421 // ----------------------------
422 // Specify priority of register selection within phases of register
423 // allocation. Highest priority is first. A useful heuristic is to
424 // give registers a low priority when they are required by machine
425 // instructions, like EAX and EDX on I486, and choose no-save registers
426 // before save-on-call, & save-on-call before save-on-entry. Registers
427 // which participate in fixed calling sequences should come last.
428 // Registers which are used as pairs must fall on an even boundary.
429
430 // It's worth about 1% on SPEC geomean to get this right.
431
432 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration
433 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g.
434 // R3_num. Therefore, R3_num may not be (and in reality is not)
435 // the same as R3->encoding()! Furthermore, we cannot make any
436 // assumptions on ordering, e.g. R3_num may be less than R2_num.
437 // Additionally, the function
438 // static enum RC rc_class(OptoReg::Name reg )
439 // maps a given <register>_num value to its chunk type (except for flags)
440 // and its current implementation relies on chunk0 and chunk1 having a
441 // size of 64 each.
442
443 // If you change this allocation class, please have a look at the
444 // default values for the parameters RoundRobinIntegerRegIntervalStart
445 // and RoundRobinFloatRegIntervalStart
446
447 alloc_class chunk0 (
448 // Chunk0 contains *all* 64 integer registers halves.
449
450 // "non-volatile" registers
451 R14, R14_H,
452 R15, R15_H,
453 R17, R17_H,
454 R18, R18_H,
455 R19, R19_H,
456 R20, R20_H,
457 R21, R21_H,
458 R22, R22_H,
459 R23, R23_H,
460 R24, R24_H,
461 R25, R25_H,
462 R26, R26_H,
463 R27, R27_H,
464 R28, R28_H,
465 R29, R29_H,
466 R30, R30_H,
467 R31, R31_H,
468
469 // scratch/special registers
470 R11, R11_H,
471 R12, R12_H,
472
473 // argument registers
474 R10, R10_H,
475 R9, R9_H,
476 R8, R8_H,
477 R7, R7_H,
478 R6, R6_H,
479 R5, R5_H,
480 R4, R4_H,
481 R3, R3_H,
482
483 // special registers, not available for allocation
484 R16, R16_H, // R16_thread
485 R13, R13_H, // system thread id
486 R2, R2_H, // may be used for TOC
487 R1, R1_H, // SP
488 R0, R0_H // R0 (scratch)
489 );
490
491 // If you change this allocation class, please have a look at the
492 // default values for the parameters RoundRobinIntegerRegIntervalStart
493 // and RoundRobinFloatRegIntervalStart
494
495 alloc_class chunk1 (
496 // Chunk1 contains *all* 64 floating-point registers halves.
497
498 // scratch register
499 F0, F0_H,
500
501 // argument registers
502 F13, F13_H,
503 F12, F12_H,
504 F11, F11_H,
505 F10, F10_H,
506 F9, F9_H,
507 F8, F8_H,
508 F7, F7_H,
509 F6, F6_H,
510 F5, F5_H,
511 F4, F4_H,
512 F3, F3_H,
513 F2, F2_H,
514 F1, F1_H,
515
516 // non-volatile registers
517 F14, F14_H,
518 F15, F15_H,
519 F16, F16_H,
520 F17, F17_H,
521 F18, F18_H,
522 F19, F19_H,
523 F20, F20_H,
524 F21, F21_H,
525 F22, F22_H,
526 F23, F23_H,
527 F24, F24_H,
528 F25, F25_H,
529 F26, F26_H,
530 F27, F27_H,
531 F28, F28_H,
532 F29, F29_H,
533 F30, F30_H,
534 F31, F31_H
535 );
536
537 alloc_class chunk2 (
538 VR0 , VR0_H , VR0_J , VR0_K ,
539 VR1 , VR1_H , VR1_J , VR1_K ,
540 VR2 , VR2_H , VR2_J , VR2_K ,
541 VR3 , VR3_H , VR3_J , VR3_K ,
542 VR4 , VR4_H , VR4_J , VR4_K ,
543 VR5 , VR5_H , VR5_J , VR5_K ,
544 VR6 , VR6_H , VR6_J , VR6_K ,
545 VR7 , VR7_H , VR7_J , VR7_K ,
546 VR8 , VR8_H , VR8_J , VR8_K ,
547 VR9 , VR9_H , VR9_J , VR9_K ,
548 VR10, VR10_H, VR10_J, VR10_K,
549 VR11, VR11_H, VR11_J, VR11_K,
550 VR12, VR12_H, VR12_J, VR12_K,
551 VR13, VR13_H, VR13_J, VR13_K,
552 VR14, VR14_H, VR14_J, VR14_K,
553 VR15, VR15_H, VR15_J, VR15_K,
554 VR16, VR16_H, VR16_J, VR16_K,
555 VR17, VR17_H, VR17_J, VR17_K,
556 VR18, VR18_H, VR18_J, VR18_K,
557 VR19, VR19_H, VR19_J, VR19_K,
558 VR20, VR20_H, VR20_J, VR20_K,
559 VR21, VR21_H, VR21_J, VR21_K,
560 VR22, VR22_H, VR22_J, VR22_K,
561 VR23, VR23_H, VR23_J, VR23_K,
562 VR24, VR24_H, VR24_J, VR24_K,
563 VR25, VR25_H, VR25_J, VR25_K,
564 VR26, VR26_H, VR26_J, VR26_K,
565 VR27, VR27_H, VR27_J, VR27_K,
566 VR28, VR28_H, VR28_J, VR28_K,
567 VR29, VR29_H, VR29_J, VR29_K,
568 VR30, VR30_H, VR30_J, VR30_K,
569 VR31, VR31_H, VR31_J, VR31_K
570 );
571
572 alloc_class chunk3 (
573 // Chunk2 contains *all* 8 condition code registers.
574 CR0,
575 CR1,
576 CR2,
577 CR3,
578 CR4,
579 CR5,
580 CR6,
581 CR7
582 );
583
584 alloc_class chunk4 (
585 // special registers
586 // These registers are not allocated, but used for nodes generated by postalloc expand.
587 SR_XER,
588 SR_LR,
589 SR_CTR,
590 SR_VRSAVE,
591 SR_SPEFSCR,
592 SR_PPR
593 );
594
595 //-------Architecture Description Register Classes-----------------------
596
597 // Several register classes are automatically defined based upon
598 // information in this architecture description.
599
600 // 1) reg_class inline_cache_reg ( as defined in frame section )
601 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
602 //
603
604 // ----------------------------
605 // 32 Bit Register Classes
606 // ----------------------------
607
608 // We specify registers twice, once as read/write, and once read-only.
609 // We use the read-only registers for source operands. With this, we
610 // can include preset read only registers in this class, as a hard-coded
611 // '0'-register. (We used to simulate this on ppc.)
612
613 // 32 bit registers that can be read and written i.e. these registers
614 // can be dest (or src) of normal instructions.
615 reg_class bits32_reg_rw(
616 /*R0*/ // R0
617 /*R1*/ // SP
618 R2, // TOC
619 R3,
620 R4,
621 R5,
622 R6,
623 R7,
624 R8,
625 R9,
626 R10,
627 R11,
628 R12,
629 /*R13*/ // system thread id
630 R14,
631 R15,
632 /*R16*/ // R16_thread
633 R17,
634 R18,
635 R19,
636 R20,
637 R21,
638 R22,
639 R23,
640 R24,
641 R25,
642 R26,
643 R27,
644 R28,
645 /*R29,*/ // global TOC
646 R30,
647 R31
648 );
649
650 // 32 bit registers that can only be read i.e. these registers can
651 // only be src of all instructions.
652 reg_class bits32_reg_ro(
653 /*R0*/ // R0
654 /*R1*/ // SP
655 R2 // TOC
656 R3,
657 R4,
658 R5,
659 R6,
660 R7,
661 R8,
662 R9,
663 R10,
664 R11,
665 R12,
666 /*R13*/ // system thread id
667 R14,
668 R15,
669 /*R16*/ // R16_thread
670 R17,
671 R18,
672 R19,
673 R20,
674 R21,
675 R22,
676 R23,
677 R24,
678 R25,
679 R26,
680 R27,
681 R28,
682 /*R29,*/
683 R30,
684 R31
685 );
686
687 reg_class rscratch1_bits32_reg(R11);
688 reg_class rscratch2_bits32_reg(R12);
689 reg_class rarg1_bits32_reg(R3);
690 reg_class rarg2_bits32_reg(R4);
691 reg_class rarg3_bits32_reg(R5);
692 reg_class rarg4_bits32_reg(R6);
693
694 // ----------------------------
695 // 64 Bit Register Classes
696 // ----------------------------
697 // 64-bit build means 64-bit pointers means hi/lo pairs
698
699 reg_class rscratch1_bits64_reg(R11_H, R11);
700 reg_class rscratch2_bits64_reg(R12_H, R12);
701 reg_class rarg1_bits64_reg(R3_H, R3);
702 reg_class rarg2_bits64_reg(R4_H, R4);
703 reg_class rarg3_bits64_reg(R5_H, R5);
704 reg_class rarg4_bits64_reg(R6_H, R6);
705 reg_class rarg5_bits64_reg(R7_H, R7);
706 reg_class rarg6_bits64_reg(R8_H, R8);
707 // Thread register, 'written' by tlsLoadP, see there.
708 reg_class thread_bits64_reg(R16_H, R16);
709
710 reg_class r19_bits64_reg(R19_H, R19);
711
712 // 64 bit registers that can be read and written i.e. these registers
713 // can be dest (or src) of normal instructions.
714 reg_class bits64_reg_rw(
715 /*R0_H, R0*/ // R0
716 /*R1_H, R1*/ // SP
717 R2_H, R2, // TOC
718 R3_H, R3,
719 R4_H, R4,
720 R5_H, R5,
721 R6_H, R6,
722 R7_H, R7,
723 R8_H, R8,
724 R9_H, R9,
725 R10_H, R10,
726 R11_H, R11,
727 R12_H, R12,
728 /*R13_H, R13*/ // system thread id
729 R14_H, R14,
730 R15_H, R15,
731 /*R16_H, R16*/ // R16_thread
732 R17_H, R17,
733 R18_H, R18,
734 R19_H, R19,
735 R20_H, R20,
736 R21_H, R21,
737 R22_H, R22,
738 R23_H, R23,
739 R24_H, R24,
740 R25_H, R25,
741 R26_H, R26,
742 R27_H, R27,
743 R28_H, R28,
744 /*R29_H, R29,*/
745 R30_H, R30,
746 R31_H, R31
747 );
748
749 // 64 bit registers used excluding r2, r11 and r12
750 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses
751 // r2, r11 and r12 internally.
752 reg_class bits64_reg_leaf_call(
753 /*R0_H, R0*/ // R0
754 /*R1_H, R1*/ // SP
755 /*R2_H, R2*/ // TOC
756 R3_H, R3,
757 R4_H, R4,
758 R5_H, R5,
759 R6_H, R6,
760 R7_H, R7,
761 R8_H, R8,
762 R9_H, R9,
763 R10_H, R10,
764 /*R11_H, R11*/
765 /*R12_H, R12*/
766 /*R13_H, R13*/ // system thread id
767 R14_H, R14,
768 R15_H, R15,
769 /*R16_H, R16*/ // R16_thread
770 R17_H, R17,
771 R18_H, R18,
772 R19_H, R19,
773 R20_H, R20,
774 R21_H, R21,
775 R22_H, R22,
776 R23_H, R23,
777 R24_H, R24,
778 R25_H, R25,
779 R26_H, R26,
780 R27_H, R27,
781 R28_H, R28,
782 /*R29_H, R29,*/
783 R30_H, R30,
784 R31_H, R31
785 );
786
787 // Used to hold the TOC to avoid collisions with expanded DynamicCall
788 // which uses r19 as inline cache internally and expanded LeafCall which uses
789 // r2, r11 and r12 internally.
790 reg_class bits64_constant_table_base(
791 /*R0_H, R0*/ // R0
792 /*R1_H, R1*/ // SP
793 /*R2_H, R2*/ // TOC
794 R3_H, R3,
795 R4_H, R4,
796 R5_H, R5,
797 R6_H, R6,
798 R7_H, R7,
799 R8_H, R8,
800 R9_H, R9,
801 R10_H, R10,
802 /*R11_H, R11*/
803 /*R12_H, R12*/
804 /*R13_H, R13*/ // system thread id
805 R14_H, R14,
806 R15_H, R15,
807 /*R16_H, R16*/ // R16_thread
808 R17_H, R17,
809 R18_H, R18,
810 /*R19_H, R19*/
811 R20_H, R20,
812 R21_H, R21,
813 R22_H, R22,
814 R23_H, R23,
815 R24_H, R24,
816 R25_H, R25,
817 R26_H, R26,
818 R27_H, R27,
819 R28_H, R28,
820 /*R29_H, R29,*/
821 R30_H, R30,
822 R31_H, R31
823 );
824
825 // 64 bit registers that can only be read i.e. these registers can
826 // only be src of all instructions.
827 reg_class bits64_reg_ro(
828 /*R0_H, R0*/ // R0
829 R1_H, R1,
830 R2_H, R2, // TOC
831 R3_H, R3,
832 R4_H, R4,
833 R5_H, R5,
834 R6_H, R6,
835 R7_H, R7,
836 R8_H, R8,
837 R9_H, R9,
838 R10_H, R10,
839 R11_H, R11,
840 R12_H, R12,
841 /*R13_H, R13*/ // system thread id
842 R14_H, R14,
843 R15_H, R15,
844 R16_H, R16, // R16_thread
845 R17_H, R17,
846 R18_H, R18,
847 R19_H, R19,
848 R20_H, R20,
849 R21_H, R21,
850 R22_H, R22,
851 R23_H, R23,
852 R24_H, R24,
853 R25_H, R25,
854 R26_H, R26,
855 R27_H, R27,
856 R28_H, R28,
857 /*R29_H, R29,*/ // TODO: let allocator handle TOC!!
858 R30_H, R30,
859 R31_H, R31
860 );
861
862
863 // ----------------------------
864 // Special Class for Condition Code Flags Register
865
866 reg_class int_flags(
867 /*CR0*/ // scratch
868 /*CR1*/ // scratch
869 /*CR2*/ // nv!
870 /*CR3*/ // nv!
871 /*CR4*/ // nv!
872 CR5,
873 CR6,
874 CR7
875 );
876
877 reg_class int_flags_ro(
878 CR0,
879 CR1,
880 CR2,
881 CR3,
882 CR4,
883 CR5,
884 CR6,
885 CR7
886 );
887
888 reg_class int_flags_CR0(CR0);
889 reg_class int_flags_CR1(CR1);
890 reg_class int_flags_CR6(CR6);
891 reg_class ctr_reg(SR_CTR);
892
893 // ----------------------------
894 // Float Register Classes
895 // ----------------------------
896
897 reg_class flt_reg(
898 F0,
899 F1,
900 F2,
901 F3,
902 F4,
903 F5,
904 F6,
905 F7,
906 F8,
907 F9,
908 F10,
909 F11,
910 F12,
911 F13,
912 F14, // nv!
913 F15, // nv!
914 F16, // nv!
915 F17, // nv!
916 F18, // nv!
917 F19, // nv!
918 F20, // nv!
919 F21, // nv!
920 F22, // nv!
921 F23, // nv!
922 F24, // nv!
923 F25, // nv!
924 F26, // nv!
925 F27, // nv!
926 F28, // nv!
927 F29, // nv!
928 F30, // nv!
929 F31 // nv!
930 );
931
932 // Double precision float registers have virtual `high halves' that
933 // are needed by the allocator.
934 reg_class dbl_reg(
935 F0, F0_H,
936 F1, F1_H,
937 F2, F2_H,
938 F3, F3_H,
939 F4, F4_H,
940 F5, F5_H,
941 F6, F6_H,
942 F7, F7_H,
943 F8, F8_H,
944 F9, F9_H,
945 F10, F10_H,
946 F11, F11_H,
947 F12, F12_H,
948 F13, F13_H,
949 F14, F14_H, // nv!
950 F15, F15_H, // nv!
951 F16, F16_H, // nv!
952 F17, F17_H, // nv!
953 F18, F18_H, // nv!
954 F19, F19_H, // nv!
955 F20, F20_H, // nv!
956 F21, F21_H, // nv!
957 F22, F22_H, // nv!
958 F23, F23_H, // nv!
959 F24, F24_H, // nv!
960 F25, F25_H, // nv!
961 F26, F26_H, // nv!
962 F27, F27_H, // nv!
963 F28, F28_H, // nv!
964 F29, F29_H, // nv!
965 F30, F30_H, // nv!
966 F31, F31_H // nv!
967 );
968
969 // ----------------------------
970 // Vector-Scalar Register Class
971 // ----------------------------
972
973 reg_class v_reg(
974 VR0 , VR0_H , VR0_J , VR0_K ,
975 VR1 , VR1_H , VR1_J , VR1_K ,
976 VR2 , VR2_H , VR2_J , VR2_K ,
977 VR3 , VR3_H , VR3_J , VR3_K ,
978 VR4 , VR4_H , VR4_J , VR4_K ,
979 VR5 , VR5_H , VR5_J , VR5_K ,
980 VR6 , VR6_H , VR6_J , VR6_K ,
981 VR7 , VR7_H , VR7_J , VR7_K ,
982 VR8 , VR8_H , VR8_J , VR8_K ,
983 VR9 , VR9_H , VR9_J , VR9_K ,
984 VR10, VR10_H, VR10_J, VR10_K,
985 VR11, VR11_H, VR11_J, VR11_K,
986 VR12, VR12_H, VR12_J, VR12_K,
987 VR13, VR13_H, VR13_J, VR13_K,
988 VR14, VR14_H, VR14_J, VR14_K,
989 VR15, VR15_H, VR15_J, VR15_K,
990 VR16, VR16_H, VR16_J, VR16_K,
991 VR17, VR17_H, VR17_J, VR17_K,
992 VR18, VR18_H, VR18_J, VR18_K,
993 VR19, VR19_H, VR19_J, VR19_K,
994 VR20, VR20_H, VR20_J, VR20_K,
995 VR21, VR21_H, VR21_J, VR21_K,
996 VR22, VR22_H, VR22_J, VR22_K,
997 VR23, VR23_H, VR23_J, VR23_K,
998 VR24, VR24_H, VR24_J, VR24_K,
999 VR25, VR25_H, VR25_J, VR25_K,
1000 VR26, VR26_H, VR26_J, VR26_K,
1001 VR27, VR27_H, VR27_J, VR27_K,
1002 VR28, VR28_H, VR28_J, VR28_K,
1003 VR29, VR29_H, VR29_J, VR29_K,
1004 VR30, VR30_H, VR30_J, VR30_K,
1005 VR31, VR31_H, VR31_J, VR31_K
1006 );
1007
1008 %}
1009
1010 //----------DEFINITION BLOCK---------------------------------------------------
1011 // Define name --> value mappings to inform the ADLC of an integer valued name
1012 // Current support includes integer values in the range [0, 0x7FFFFFFF]
1013 // Format:
1014 // int_def <name> ( <int_value>, <expression>);
1015 // Generated Code in ad_<arch>.hpp
1016 // #define <name> (<expression>)
1017 // // value == <int_value>
1018 // Generated code in ad_<arch>.cpp adlc_verification()
1019 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
1020 //
1021 definitions %{
1022 // The default cost (of an ALU instruction).
1023 int_def DEFAULT_COST_LOW ( 30, 30);
1024 int_def DEFAULT_COST ( 100, 100);
1025 int_def HUGE_COST (1000000, 1000000);
1026
1027 // Memory refs
1028 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2);
1029 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3);
1030
1031 // Branches are even more expensive.
1032 int_def BRANCH_COST ( 900, DEFAULT_COST * 9);
1033 int_def CALL_COST ( 1300, DEFAULT_COST * 13);
1034 %}
1035
1036
1037 //----------SOURCE BLOCK-------------------------------------------------------
1038 // This is a block of C++ code which provides values, functions, and
1039 // definitions necessary in the rest of the architecture description.
1040 source_hpp %{
1041 // Header information of the source block.
1042 // Method declarations/definitions which are used outside
1043 // the ad-scope can conveniently be defined here.
1044 //
1045 // To keep related declarations/definitions/uses close together,
1046 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
1047
1048 #include "opto/convertnode.hpp"
1049
1050 // Returns true if Node n is followed by a MemBar node that
1051 // will do an acquire. If so, this node must not do the acquire
1052 // operation.
1053 bool followed_by_acquire(const Node *n);
1054 %}
1055
1056 source %{
1057
1058 #include "opto/c2_CodeStubs.hpp"
1059 #include "oops/klass.inline.hpp"
1060
1061 void PhaseOutput::pd_perform_mach_node_analysis() {
1062 }
1063
1064 int MachNode::pd_alignment_required() const {
1065 return 1;
1066 }
1067
1068 int MachNode::compute_padding(int current_offset) const {
1069 return 0;
1070 }
1071
1072 // Should the matcher clone input 'm' of node 'n'?
1073 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
1074 if (is_encode_and_store_pattern(n, m)) {
1075 mstack.push(m, Visit);
1076 return true;
1077 }
1078 return false;
1079 }
1080
1081 // Should the Matcher clone shifts on addressing modes, expecting them
1082 // to be subsumed into complex addressing expressions or compute them
1083 // into registers?
1084 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
1085 return clone_base_plus_offset_address(m, mstack, address_visited);
1086 }
1087
1088 // Optimize load-acquire.
1089 //
1090 // Check if acquire is unnecessary due to following operation that does
1091 // acquire anyways.
1092 // Walk the pattern:
1093 //
1094 // n: Load.acq
1095 // |
1096 // MemBarAcquire
1097 // | |
1098 // Proj(ctrl) Proj(mem)
1099 // | |
1100 // MemBarRelease/Volatile
1101 //
1102 bool followed_by_acquire(const Node *load) {
1103 assert(load->is_Load(), "So far implemented only for loads.");
1104
1105 // Find MemBarAcquire.
1106 const Node *mba = nullptr;
1107 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) {
1108 const Node *out = load->fast_out(i);
1109 if (out->Opcode() == Op_MemBarAcquire) {
1110 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge.
1111 mba = out;
1112 break;
1113 }
1114 }
1115 if (!mba) return false;
1116
1117 // Find following MemBar node.
1118 //
1119 // The following node must be reachable by control AND memory
1120 // edge to assure no other operations are in between the two nodes.
1121 //
1122 // So first get the Proj node, mem_proj, to use it to iterate forward.
1123 Node *mem_proj = nullptr;
1124 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) {
1125 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found.
1126 assert(mem_proj->is_Proj(), "only projections here");
1127 ProjNode *proj = mem_proj->as_Proj();
1128 if (proj->_con == TypeFunc::Memory &&
1129 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only
1130 break;
1131 }
1132 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken");
1133
1134 // Search MemBar behind Proj. If there are other memory operations
1135 // behind the Proj we lost.
1136 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) {
1137 Node *x = mem_proj->fast_out(j);
1138 // Proj might have an edge to a store or load node which precedes the membar.
1139 if (x->is_Mem()) return false;
1140
1141 // On PPC64 release and volatile are implemented by an instruction
1142 // that also has acquire semantics. I.e. there is no need for an
1143 // acquire before these.
1144 int xop = x->Opcode();
1145 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) {
1146 // Make sure we're not missing Call/Phi/MergeMem by checking
1147 // control edges. The control edge must directly lead back
1148 // to the MemBarAcquire
1149 Node *ctrl_proj = x->in(0);
1150 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) {
1151 return true;
1152 }
1153 }
1154 }
1155
1156 return false;
1157 }
1158
1159 #define __ masm->
1160
1161 // Tertiary op of a LoadP or StoreP encoding.
1162 #define REGP_OP true
1163
1164 // ****************************************************************************
1165
1166 // REQUIRED FUNCTIONALITY
1167
1168 // !!!!! Special hack to get all type of calls to specify the byte offset
1169 // from the start of the call to the point where the return address
1170 // will point.
1171
1172 // PPC port: Removed use of lazy constant construct.
1173
1174 int MachCallStaticJavaNode::ret_addr_offset() {
1175 // It's only a single branch-and-link instruction.
1176 return 4;
1177 }
1178
1179 int MachCallDynamicJavaNode::ret_addr_offset() {
1180 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use
1181 // postalloc expanded calls if we use inline caches and do not update method data.
1182 if (UseInlineCaches) return 4;
1183
1184 int vtable_index = this->_vtable_index;
1185 if (vtable_index < 0) {
1186 // Must be invalid_vtable_index, not nonvirtual_vtable_index.
1187 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value");
1188 return 12;
1189 } else {
1190 return 20 + MacroAssembler::instr_size_for_load_klass();
1191 }
1192 }
1193
1194 int MachCallRuntimeNode::ret_addr_offset() {
1195 if (rule() == CallRuntimeDirect_rule) {
1196 // CallRuntimeDirectNode uses call_c.
1197 #if defined(ABI_ELFv2)
1198 return 28;
1199 #else
1200 return 40;
1201 #endif
1202 }
1203 assert(rule() == CallLeafDirect_rule, "unexpected node with rule %u", rule());
1204 // CallLeafDirectNode uses bl.
1205 return 4;
1206 }
1207
1208 //=============================================================================
1209
1210 // condition code conversions
1211
1212 static int cc_to_boint(int cc) {
1213 return Assembler::bcondCRbiIs0 | (cc & 8);
1214 }
1215
1216 static int cc_to_inverse_boint(int cc) {
1217 return Assembler::bcondCRbiIs0 | (8-(cc & 8));
1218 }
1219
1220 static int cc_to_biint(int cc, int flags_reg) {
1221 return (flags_reg << 2) | (cc & 3);
1222 }
1223
1224 //=============================================================================
1225
1226 // Compute padding required for nodes which need alignment. The padding
1227 // is the number of bytes (not instructions) which will be inserted before
1228 // the instruction. The padding must match the size of a NOP instruction.
1229
1230 // Add nop if a prefixed (two-word) instruction is going to cross a 64-byte boundary.
1231 // (See Section 1.6 of Power ISA Version 3.1)
1232 static int compute_prefix_padding(int current_offset) {
1233 assert(PowerArchitecturePPC64 >= 10 && (CodeEntryAlignment & 63) == 0,
1234 "Code buffer must be aligned to a multiple of 64 bytes");
1235 if (is_aligned(current_offset + BytesPerInstWord, 64)) {
1236 return BytesPerInstWord;
1237 }
1238 return 0;
1239 }
1240
1241 int loadConI32Node::compute_padding(int current_offset) const {
1242 return compute_prefix_padding(current_offset);
1243 }
1244
1245 int loadConL34Node::compute_padding(int current_offset) const {
1246 return compute_prefix_padding(current_offset);
1247 }
1248
1249 int addI_reg_imm32Node::compute_padding(int current_offset) const {
1250 return compute_prefix_padding(current_offset);
1251 }
1252
1253 int addL_reg_imm34Node::compute_padding(int current_offset) const {
1254 return compute_prefix_padding(current_offset);
1255 }
1256
1257 int addP_reg_imm34Node::compute_padding(int current_offset) const {
1258 return compute_prefix_padding(current_offset);
1259 }
1260
1261 int cmprb_Whitespace_reg_reg_prefixedNode::compute_padding(int current_offset) const {
1262 return compute_prefix_padding(current_offset);
1263 }
1264
1265
1266 //=============================================================================
1267
1268 // Emit an interrupt that is caught by the debugger (for debugging compiler).
1269 void emit_break(C2_MacroAssembler *masm) {
1270 __ illtrap();
1271 }
1272
1273 #ifndef PRODUCT
1274 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1275 st->print("BREAKPOINT");
1276 }
1277 #endif
1278
1279 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1280 emit_break(masm);
1281 }
1282
1283 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1284 return MachNode::size(ra_);
1285 }
1286
1287 //=============================================================================
1288
1289 void emit_nop(C2_MacroAssembler *masm) {
1290 __ nop();
1291 }
1292
1293 static inline void emit_long(C2_MacroAssembler *masm, int value) {
1294 *((int*)(__ pc())) = value;
1295 __ set_inst_end(__ pc() + BytesPerInstWord);
1296 }
1297
1298 //=============================================================================
1299
1300 %} // interrupt source
1301
1302 source_hpp %{ // Header information of the source block.
1303
1304 //--------------------------------------------------------------
1305 //---< Used for optimization in Compile::Shorten_branches >---
1306 //--------------------------------------------------------------
1307
1308 class C2_MacroAssembler;
1309
1310 class CallStubImpl {
1311
1312 public:
1313
1314 // Emit call stub, compiled java to interpreter.
1315 static void emit_trampoline_stub(C2_MacroAssembler *masm, int destination_toc_offset, int insts_call_instruction_offset);
1316
1317 // Size of call trampoline stub.
1318 // This doesn't need to be accurate to the byte, but it
1319 // must be larger than or equal to the real size of the stub.
1320 static uint size_call_trampoline() {
1321 return MacroAssembler::trampoline_stub_size;
1322 }
1323
1324 // number of relocations needed by a call trampoline stub
1325 static uint reloc_call_trampoline() {
1326 return 5;
1327 }
1328
1329 };
1330
1331 %} // end source_hpp
1332
1333 source %{
1334
1335 // Emit a trampoline stub for a call to a target which is too far away.
1336 //
1337 // code sequences:
1338 //
1339 // call-site:
1340 // branch-and-link to <destination> or <trampoline stub>
1341 //
1342 // Related trampoline stub for this call-site in the stub section:
1343 // load the call target from the constant pool
1344 // branch via CTR (LR/link still points to the call-site above)
1345
1346 void CallStubImpl::emit_trampoline_stub(C2_MacroAssembler *masm, int destination_toc_offset, int insts_call_instruction_offset) {
1347 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset);
1348 if (stub == nullptr) {
1349 ciEnv::current()->record_out_of_memory_failure();
1350 }
1351 }
1352
1353 //=============================================================================
1354
1355 // Emit an inline branch-and-link call and a related trampoline stub.
1356 //
1357 // code sequences:
1358 //
1359 // call-site:
1360 // branch-and-link to <destination> or <trampoline stub>
1361 //
1362 // Related trampoline stub for this call-site in the stub section:
1363 // load the call target from the constant pool
1364 // branch via CTR (LR/link still points to the call-site above)
1365 //
1366
1367 typedef struct {
1368 int insts_call_instruction_offset;
1369 int ret_addr_offset;
1370 } EmitCallOffsets;
1371
1372 // Emit a branch-and-link instruction that branches to a trampoline.
1373 // - Remember the offset of the branch-and-link instruction.
1374 // - Add a relocation at the branch-and-link instruction.
1375 // - Emit a branch-and-link.
1376 // - Remember the return pc offset.
1377 EmitCallOffsets emit_call_with_trampoline_stub(C2_MacroAssembler *masm, address entry_point, relocInfo::relocType rtype) {
1378 EmitCallOffsets offsets = { -1, -1 };
1379 const int start_offset = __ offset();
1380 offsets.insts_call_instruction_offset = __ offset();
1381
1382 // No entry point given, use the current pc.
1383 if (entry_point == nullptr) entry_point = __ pc();
1384
1385 // Put the entry point as a constant into the constant pool.
1386 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
1387 if (entry_point_toc_addr == nullptr) {
1388 ciEnv::current()->record_out_of_memory_failure();
1389 return offsets;
1390 }
1391 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
1392
1393 // Emit the trampoline stub which will be related to the branch-and-link below.
1394 CallStubImpl::emit_trampoline_stub(masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
1395 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
1396 __ relocate(rtype);
1397
1398 // Note: At this point we do not have the address of the trampoline
1399 // stub, and the entry point might be too far away for bl, so __ pc()
1400 // serves as dummy and the bl will be patched later.
1401 __ bl((address) __ pc());
1402
1403 offsets.ret_addr_offset = __ offset() - start_offset;
1404
1405 return offsets;
1406 }
1407
1408 //=============================================================================
1409
1410 // Factory for creating loadConL* nodes for large/small constant pool.
1411
1412 static inline jlong replicate_immF(float con) {
1413 // Replicate float con 2 times and pack into vector.
1414 int val = *((int*)&con);
1415 jlong lval = val;
1416 lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1417 return lval;
1418 }
1419
1420 //=============================================================================
1421
1422 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1423 int ConstantTable::calculate_table_base_offset() const {
1424 return 0; // absolute addressing, no offset
1425 }
1426
1427 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1428 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1429 iRegPdstOper *op_dst = new iRegPdstOper();
1430 MachNode *m1 = new loadToc_hiNode();
1431 MachNode *m2 = new loadToc_loNode();
1432
1433 m1->add_req(nullptr);
1434 m2->add_req(nullptr, m1);
1435 m1->_opnds[0] = op_dst;
1436 m2->_opnds[0] = op_dst;
1437 m2->_opnds[1] = op_dst;
1438 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1439 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1440 nodes->push(m1);
1441 nodes->push(m2);
1442 }
1443
1444 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const {
1445 // Is postalloc expanded.
1446 ShouldNotReachHere();
1447 }
1448
1449 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1450 return 0;
1451 }
1452
1453 #ifndef PRODUCT
1454 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1455 st->print("-- \t// MachConstantBaseNode (empty encoding)");
1456 }
1457 #endif
1458
1459 //=============================================================================
1460
1461 #ifndef PRODUCT
1462 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1463 Compile* C = ra_->C;
1464 const long framesize = C->output()->frame_slots() << LogBytesPerInt;
1465
1466 st->print("PROLOG\n\t");
1467 if (C->output()->need_stack_bang(framesize)) {
1468 st->print("stack_overflow_check\n\t");
1469 }
1470
1471 if (!false /* TODO: PPC port C->is_frameless_method()*/) {
1472 st->print("save return pc\n\t");
1473 st->print("push frame %ld\n\t", -framesize);
1474 }
1475
1476 if (C->stub_function() == nullptr) {
1477 st->print("nmethod entry barrier\n\t");
1478 }
1479 }
1480 #endif
1481
1482 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1483 Compile* C = ra_->C;
1484
1485 const long framesize = C->output()->frame_size_in_bytes();
1486 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment");
1487
1488 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1489
1490 const Register return_pc = R20; // Must match return_addr() in frame section.
1491 const Register callers_sp = R21;
1492 const Register push_frame_temp = R22;
1493 const Register toc_temp = R23;
1494 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp);
1495
1496 if (!method_is_frameless) {
1497 // Get return pc.
1498 __ mflr(return_pc);
1499 }
1500
1501 if (C->clinit_barrier_on_entry()) {
1502 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
1503
1504 Label L_skip_barrier;
1505 Register klass = toc_temp;
1506
1507 // Notify OOP recorder (don't need the relocation)
1508 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding());
1509 __ load_const_optimized(klass, md.value(), R0);
1510 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/);
1511
1512 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0);
1513 __ mtctr(klass);
1514 __ bctr();
1515
1516 __ bind(L_skip_barrier);
1517 }
1518
1519 // Calls to C2R adapters often do not accept exceptional returns.
1520 // We require that their callers must bang for them. But be
1521 // careful, because some VM calls (such as call site linkage) can
1522 // use several kilobytes of stack. But the stack safety zone should
1523 // account for that. See bugs 4446381, 4468289, 4497237.
1524
1525 int bangsize = C->output()->bang_size_in_bytes();
1526 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect");
1527 if (C->output()->need_stack_bang(bangsize)) {
1528 // Unfortunately we cannot use the function provided in
1529 // assembler.cpp as we have to emulate the pipes. So I had to
1530 // insert the code of generate_stack_overflow_check(), see
1531 // assembler.cpp for some illuminative comments.
1532 const int page_size = os::vm_page_size();
1533 int bang_end = StackOverflow::stack_shadow_zone_size();
1534
1535 // This is how far the previous frame's stack banging extended.
1536 const int bang_end_safe = bang_end;
1537
1538 if (bangsize > page_size) {
1539 bang_end += bangsize;
1540 }
1541
1542 int bang_offset = bang_end_safe;
1543
1544 while (bang_offset <= bang_end) {
1545 // Need at least one stack bang at end of shadow zone.
1546
1547 // Again I had to copy code, this time from assembler_ppc.cpp,
1548 // bang_stack_with_offset - see there for comments.
1549
1550 // Stack grows down, caller passes positive offset.
1551 assert(bang_offset > 0, "must bang with positive offset");
1552
1553 long stdoffset = -bang_offset;
1554
1555 if (Assembler::is_simm(stdoffset, 16)) {
1556 // Signed 16 bit offset, a simple std is ok.
1557 if (UseLoadInstructionsForStackBangingPPC64) {
1558 __ ld(R0, (int)(signed short)stdoffset, R1_SP);
1559 } else {
1560 __ std(R0, (int)(signed short)stdoffset, R1_SP);
1561 }
1562 } else if (Assembler::is_simm(stdoffset, 31)) {
1563 // Use largeoffset calculations for addis & ld/std.
1564 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset);
1565 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset);
1566
1567 Register tmp = R11;
1568 __ addis(tmp, R1_SP, hi);
1569 if (UseLoadInstructionsForStackBangingPPC64) {
1570 __ ld(R0, lo, tmp);
1571 } else {
1572 __ std(R0, lo, tmp);
1573 }
1574 } else {
1575 ShouldNotReachHere();
1576 }
1577
1578 bang_offset += page_size;
1579 }
1580 // R11 trashed
1581 } // C->output()->need_stack_bang(framesize)
1582
1583 unsigned int bytes = (unsigned int)framesize;
1584 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
1585 ciMethod *currMethod = C->method();
1586
1587 if (!method_is_frameless) {
1588 // Get callers sp.
1589 __ mr(callers_sp, R1_SP);
1590
1591 // Push method's frame, modifies SP.
1592 assert(Assembler::is_uimm(framesize, 32U), "wrong type");
1593 // The ABI is already accounted for in 'framesize' via the
1594 // 'out_preserve' area.
1595 Register tmp = push_frame_temp;
1596 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp).
1597 if (Assembler::is_simm(-offset, 16)) {
1598 __ stdu(R1_SP, -offset, R1_SP);
1599 } else {
1600 long x = -offset;
1601 // Had to insert load_const(tmp, -offset).
1602 __ lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16)));
1603 __ ori( tmp, tmp, ((x >> 32) & 0x0000ffff));
1604 __ sldi(tmp, tmp, 32);
1605 __ oris(tmp, tmp, (x & 0xffff0000) >> 16);
1606 __ ori( tmp, tmp, (x & 0x0000ffff));
1607
1608 __ stdux(R1_SP, R1_SP, tmp);
1609 }
1610 }
1611 #if 0 // TODO: PPC port
1612 // For testing large constant pools, emit a lot of constants to constant pool.
1613 // "Randomize" const_size.
1614 if (ConstantsALot) {
1615 const int num_consts = const_size();
1616 for (int i = 0; i < num_consts; i++) {
1617 __ long_constant(0xB0B5B00BBABE);
1618 }
1619 }
1620 #endif
1621 if (!method_is_frameless) {
1622 // Save return pc.
1623 __ std(return_pc, _abi0(lr), callers_sp);
1624 }
1625
1626 if (C->stub_function() == nullptr) {
1627 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
1628 bs->nmethod_entry_barrier(masm, push_frame_temp);
1629 }
1630
1631 C->output()->set_frame_complete(__ offset());
1632 }
1633
1634 int MachPrologNode::reloc() const {
1635 // Return number of relocatable values contained in this instruction.
1636 return 1; // 1 reloc entry for load_const(toc).
1637 }
1638
1639 //=============================================================================
1640
1641 #ifndef PRODUCT
1642 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1643 Compile* C = ra_->C;
1644
1645 st->print("EPILOG\n\t");
1646 st->print("restore return pc\n\t");
1647 st->print("pop frame\n\t");
1648
1649 if (do_polling() && C->is_method_compilation()) {
1650 st->print("safepoint poll\n\t");
1651 }
1652 }
1653 #endif
1654
1655 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1656 Compile* C = ra_->C;
1657
1658 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt;
1659 assert(framesize >= 0, "negative frame-size?");
1660
1661 const bool method_needs_polling = do_polling() && C->is_method_compilation();
1662 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1663 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
1664 const Register temp = R12;
1665
1666 if (!method_is_frameless) {
1667 // Restore return pc relative to callers' sp.
1668 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP);
1669 // Move return pc to LR.
1670 __ mtlr(return_pc);
1671 // Pop frame (fixed frame-size).
1672 __ addi(R1_SP, R1_SP, (int)framesize);
1673 }
1674
1675 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1676 __ reserved_stack_check(return_pc);
1677 }
1678
1679 if (method_needs_polling) {
1680 Label dummy_label;
1681 Label* code_stub = &dummy_label;
1682 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) {
1683 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1684 C->output()->add_stub(stub);
1685 code_stub = &stub->entry();
1686 __ relocate(relocInfo::poll_return_type);
1687 }
1688 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */);
1689 }
1690 }
1691
1692 int MachEpilogNode::reloc() const {
1693 // Return number of relocatable values contained in this instruction.
1694 return 1; // 1 for load_from_polling_page.
1695 }
1696
1697 const Pipeline * MachEpilogNode::pipeline() const {
1698 return MachNode::pipeline_class();
1699 }
1700
1701 // =============================================================================
1702
1703 // Figure out which register class each belongs in: rc_int, rc_float, rc_vec or
1704 // rc_stack.
1705 enum RC { rc_bad, rc_int, rc_float, rc_vec, rc_stack };
1706
1707 static enum RC rc_class(OptoReg::Name reg) {
1708 // Return the register class for the given register. The given register
1709 // reg is a <register>_num value, which is an index into the MachRegisterNumbers
1710 // enumeration in adGlobals_ppc.hpp.
1711
1712 if (reg == OptoReg::Bad) return rc_bad;
1713
1714 // We have 64 integer register halves, starting at index 0.
1715 STATIC_ASSERT((int)ConcreteRegisterImpl::max_gpr == (int)MachRegisterNumbers::F0_num);
1716 if (reg < ConcreteRegisterImpl::max_gpr) return rc_int;
1717
1718 // We have 64 floating-point register halves, starting at index 64.
1719 STATIC_ASSERT((int)ConcreteRegisterImpl::max_fpr == (int)MachRegisterNumbers::VR0_num);
1720 if (reg < ConcreteRegisterImpl::max_fpr) return rc_float;
1721
1722 // We have 64 vector-scalar registers, starting at index 128.
1723 STATIC_ASSERT((int)ConcreteRegisterImpl::max_vr == (int)MachRegisterNumbers::CR0_num);
1724 if (reg < ConcreteRegisterImpl::max_vr) return rc_vec;
1725
1726 // Condition and special purpose registers are not allocated. We only accept stack from here.
1727 assert(OptoReg::is_stack(reg), "what else is it?");
1728 return rc_stack;
1729 }
1730
1731 static int ld_st_helper(C2_MacroAssembler *masm, const char *op_str, uint opcode, int reg, int offset,
1732 bool do_print, Compile* C, outputStream *st) {
1733
1734 assert(opcode == Assembler::LD_OPCODE ||
1735 opcode == Assembler::STD_OPCODE ||
1736 opcode == Assembler::LWZ_OPCODE ||
1737 opcode == Assembler::STW_OPCODE ||
1738 opcode == Assembler::LFD_OPCODE ||
1739 opcode == Assembler::STFD_OPCODE ||
1740 opcode == Assembler::LFS_OPCODE ||
1741 opcode == Assembler::STFS_OPCODE,
1742 "opcode not supported");
1743
1744 if (masm) {
1745 int d =
1746 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ?
1747 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/)
1748 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build.
1749 emit_long(masm, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP));
1750 }
1751 #ifndef PRODUCT
1752 else if (do_print) {
1753 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy",
1754 op_str,
1755 Matcher::regName[reg],
1756 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/);
1757 }
1758 #endif
1759 return 4; // size
1760 }
1761
1762 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1763 Compile* C = ra_->C;
1764
1765 // Get registers to move.
1766 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1767 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1768 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1769 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1770
1771 enum RC src_hi_rc = rc_class(src_hi);
1772 enum RC src_lo_rc = rc_class(src_lo);
1773 enum RC dst_hi_rc = rc_class(dst_hi);
1774 enum RC dst_lo_rc = rc_class(dst_lo);
1775
1776 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1777 if (src_hi != OptoReg::Bad)
1778 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1779 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1780 "expected aligned-adjacent pairs");
1781 // Generate spill code!
1782 int size = 0;
1783
1784 if (src_lo == dst_lo && src_hi == dst_hi)
1785 return size; // Self copy, no move.
1786
1787 if (bottom_type()->isa_vect() != nullptr && ideal_reg() == Op_VecX) {
1788 int src_offset = ra_->reg2offset(src_lo);
1789 int dst_offset = ra_->reg2offset(dst_lo);
1790 DEBUG_ONLY(int algm = MIN2(RegMask::num_registers(ideal_reg()), (int)Matcher::stack_alignment_in_slots()) * VMRegImpl::stack_slot_size);
1791 assert((src_lo_rc != rc_stack) || is_aligned(src_offset, algm), "unaligned vector spill sp offset %d (src)", src_offset);
1792 assert((dst_lo_rc != rc_stack) || is_aligned(dst_offset, algm), "unaligned vector spill sp offset %d (dst)", dst_offset);
1793 // Memory->Memory Spill.
1794 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1795 if (masm) {
1796 __ ld(R0, src_offset, R1_SP);
1797 __ std(R0, dst_offset, R1_SP);
1798 __ ld(R0, src_offset+8, R1_SP);
1799 __ std(R0, dst_offset+8, R1_SP);
1800 }
1801 size += 16;
1802 #ifndef PRODUCT
1803 if (st != nullptr) {
1804 st->print("%-7s [R1_SP + #%d] -> [R1_SP + #%d] \t// vector spill copy", "SPILL", src_offset, dst_offset);
1805 }
1806 #endif // !PRODUCT
1807 }
1808 // VectorRegister->Memory Spill.
1809 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_stack) {
1810 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1811 if (masm) {
1812 __ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16
1813 }
1814 size += 4;
1815 #ifndef PRODUCT
1816 if (st != nullptr) {
1817 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "STXV", Matcher::regName[src_lo], dst_offset);
1818 }
1819 #endif // !PRODUCT
1820 }
1821 // Memory->VectorRegister Spill.
1822 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vec) {
1823 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1824 if (masm) {
1825 __ lxv(Rdst, src_offset, R1_SP);
1826 }
1827 size += 4;
1828 #ifndef PRODUCT
1829 if (st != nullptr) {
1830 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "LXV", Matcher::regName[dst_lo], src_offset);
1831 }
1832 #endif // !PRODUCT
1833 }
1834 // VectorRegister->VectorRegister.
1835 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_vec) {
1836 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1837 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1838 if (masm) {
1839 __ xxlor(Rdst, Rsrc, Rsrc);
1840 }
1841 size += 4;
1842 #ifndef PRODUCT
1843 if (st != nullptr) {
1844 st->print("%-7s %s, %s, %s\t// vector spill copy",
1845 "XXLOR", Matcher::regName[dst_lo], Matcher::regName[src_lo], Matcher::regName[src_lo]);
1846 }
1847 #endif // !PRODUCT
1848 }
1849 else {
1850 ShouldNotReachHere(); // No VR spill.
1851 }
1852 return size;
1853 }
1854
1855 // --------------------------------------
1856 // Memory->Memory Spill. Use R0 to hold the value.
1857 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1858 int src_offset = ra_->reg2offset(src_lo);
1859 int dst_offset = ra_->reg2offset(dst_lo);
1860 if (src_hi != OptoReg::Bad) {
1861 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack,
1862 "expected same type of move for high parts");
1863 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st);
1864 if (!masm && !do_size) st->print("\n\t");
1865 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st);
1866 } else {
1867 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st);
1868 if (!masm && !do_size) st->print("\n\t");
1869 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st);
1870 }
1871 return size;
1872 }
1873
1874 // --------------------------------------
1875 // Check for float->int copy; requires a trip through memory.
1876 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1877 Unimplemented();
1878 }
1879
1880 // --------------------------------------
1881 // Check for integer reg-reg copy.
1882 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1883 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1884 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1885 size = (Rsrc != Rdst) ? 4 : 0;
1886
1887 if (masm) {
1888 if (size) {
1889 __ mr(Rdst, Rsrc);
1890 }
1891 }
1892 #ifndef PRODUCT
1893 else if (!do_size) {
1894 if (size) {
1895 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1896 } else {
1897 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1898 }
1899 }
1900 #endif
1901 return size;
1902 }
1903
1904 // Check for integer store.
1905 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1906 int dst_offset = ra_->reg2offset(dst_lo);
1907 if (src_hi != OptoReg::Bad) {
1908 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack,
1909 "expected same type of move for high parts");
1910 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1911 } else {
1912 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st);
1913 }
1914 return size;
1915 }
1916
1917 // Check for integer load.
1918 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1919 int src_offset = ra_->reg2offset(src_lo);
1920 if (src_hi != OptoReg::Bad) {
1921 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack,
1922 "expected same type of move for high parts");
1923 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1924 } else {
1925 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st);
1926 }
1927 return size;
1928 }
1929
1930 // Check for float reg-reg copy.
1931 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1932 if (masm) {
1933 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]);
1934 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]);
1935 __ fmr(Rdst, Rsrc);
1936 }
1937 #ifndef PRODUCT
1938 else if (!do_size) {
1939 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1940 }
1941 #endif
1942 return 4;
1943 }
1944
1945 // Check for float store.
1946 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1947 int dst_offset = ra_->reg2offset(dst_lo);
1948 if (src_hi != OptoReg::Bad) {
1949 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack,
1950 "expected same type of move for high parts");
1951 size += ld_st_helper(masm, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1952 } else {
1953 size += ld_st_helper(masm, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st);
1954 }
1955 return size;
1956 }
1957
1958 // Check for float load.
1959 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1960 int src_offset = ra_->reg2offset(src_lo);
1961 if (src_hi != OptoReg::Bad) {
1962 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack,
1963 "expected same type of move for high parts");
1964 size += ld_st_helper(masm, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1965 } else {
1966 size += ld_st_helper(masm, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st);
1967 }
1968 return size;
1969 }
1970
1971 // --------------------------------------------------------------------
1972 // Check for hi bits still needing moving. Only happens for misaligned
1973 // arguments to native calls.
1974 if (src_hi == dst_hi)
1975 return size; // Self copy; no move.
1976
1977 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad");
1978 ShouldNotReachHere(); // Unimplemented
1979 return 0;
1980 }
1981
1982 #ifndef PRODUCT
1983 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1984 if (!ra_)
1985 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1986 else
1987 implementation(nullptr, ra_, false, st);
1988 }
1989 #endif
1990
1991 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1992 implementation(masm, ra_, false, nullptr);
1993 }
1994
1995 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1996 return implementation(nullptr, ra_, true, nullptr);
1997 }
1998
1999 #ifndef PRODUCT
2000 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2001 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count);
2002 }
2003 #endif
2004
2005 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *) const {
2006 // _count contains the number of nops needed for padding.
2007 for (int i = 0; i < _count; i++) {
2008 __ nop();
2009 }
2010 }
2011
2012 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
2013 return _count * 4;
2014 }
2015
2016 #ifndef PRODUCT
2017 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2018 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2019 char reg_str[128];
2020 ra_->dump_register(this, reg_str, sizeof(reg_str));
2021 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset);
2022 }
2023 #endif
2024
2025 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
2026 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2027 int reg = ra_->get_encode(this);
2028
2029 if (Assembler::is_simm(offset, 16)) {
2030 __ addi(as_Register(reg), R1, offset);
2031 } else {
2032 ShouldNotReachHere();
2033 }
2034 }
2035
2036 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
2037 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
2038 return 4;
2039 }
2040
2041 #ifndef PRODUCT
2042 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
2043 {
2044 Unimplemented();
2045 }
2046 #endif
2047
2048 void MachVEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc* ra_) const
2049 {
2050 Unimplemented();
2051 }
2052
2053 #ifndef PRODUCT
2054 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2055 st->print_cr("---- MachUEPNode ----");
2056 st->print_cr("...");
2057 }
2058 #endif
2059
2060 void MachUEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
2061 // This is the unverified entry point.
2062 __ ic_check(CodeEntryAlignment);
2063 // Argument is valid and klass is as expected, continue.
2064 }
2065
2066 //=============================================================================
2067
2068 %} // interrupt source
2069
2070 source_hpp %{ // Header information of the source block.
2071
2072 class HandlerImpl {
2073
2074 public:
2075
2076 static int emit_deopt_handler(C2_MacroAssembler* masm);
2077
2078 static uint size_deopt_handler() {
2079 // The deopt_handler is a bl64_patchable.
2080 return MacroAssembler::bl64_patchable_size + BytesPerInstWord;
2081 }
2082
2083 };
2084
2085 class Node::PD {
2086 public:
2087 enum NodeFlags {
2088 _last_flag = Node::_last_flag
2089 };
2090 };
2091
2092 %} // end source_hpp
2093
2094 source %{
2095
2096 // The deopt_handler is like the exception handler, but it calls to
2097 // the deoptimization blob instead of jumping to the exception blob.
2098 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
2099 address base = __ start_a_stub(size_deopt_handler());
2100 if (base == nullptr) {
2101 ciEnv::current()->record_failure("CodeCache is full");
2102 return 0; // CodeBuffer::expand failed
2103 }
2104
2105 int offset = __ offset();
2106
2107 Label start;
2108 __ bind(start);
2109
2110 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
2111 relocInfo::runtime_call_type);
2112
2113 int entry_offset = __ offset();
2114
2115 __ b(start);
2116
2117 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
2118 assert(__ offset() - entry_offset >= NativePostCallNop::first_check_size,
2119 "out of bounds read in post-call NOP check");
2120 __ end_a_stub();
2121
2122 return entry_offset;
2123 }
2124
2125 //=============================================================================
2126
2127 // Use a frame slots bias for frameless methods if accessing the stack.
2128 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) {
2129 if (as_Register(reg_enc) == R1_SP) {
2130 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes();
2131 }
2132 return 0;
2133 }
2134
2135 bool Matcher::match_rule_supported(int opcode) {
2136 if (!has_match_rule(opcode)) {
2137 return false; // no match rule present
2138 }
2139
2140 switch (opcode) {
2141 case Op_CountLeadingZerosI:
2142 case Op_CountLeadingZerosL:
2143 return UseCountLeadingZerosInstructionsPPC64;
2144 case Op_CountTrailingZerosI:
2145 case Op_CountTrailingZerosL:
2146 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64);
2147 case Op_PopCountI:
2148 case Op_PopCountL:
2149 return UsePopCountInstruction;
2150 case Op_ConvF2HF:
2151 case Op_ConvHF2F:
2152 return VM_Version::supports_float16();
2153 case Op_AddVB:
2154 case Op_AddVS:
2155 case Op_AddVI:
2156 case Op_AddVF:
2157 case Op_AddVD:
2158 case Op_SubVB:
2159 case Op_SubVS:
2160 case Op_SubVI:
2161 case Op_SubVF:
2162 case Op_SubVD:
2163 case Op_MulVS:
2164 case Op_MulVF:
2165 case Op_MulVD:
2166 case Op_DivVF:
2167 case Op_DivVD:
2168 case Op_AbsVF:
2169 case Op_AbsVD:
2170 case Op_NegVI:
2171 case Op_NegVF:
2172 case Op_NegVD:
2173 case Op_SqrtVF:
2174 case Op_SqrtVD:
2175 case Op_AddVL:
2176 case Op_SubVL:
2177 case Op_MulVI:
2178 case Op_RoundDoubleModeV:
2179 case Op_MinV:
2180 case Op_MaxV:
2181 case Op_UMinV:
2182 case Op_UMaxV:
2183 case Op_AndV:
2184 case Op_OrV:
2185 case Op_XorV:
2186 case Op_AddReductionVI:
2187 case Op_MulReductionVI:
2188 case Op_AndReductionV:
2189 case Op_OrReductionV:
2190 case Op_XorReductionV:
2191 case Op_MinReductionV:
2192 case Op_MaxReductionV:
2193 return SuperwordUseVSX;
2194 case Op_PopCountVI:
2195 case Op_PopCountVL:
2196 return (SuperwordUseVSX && UsePopCountInstruction);
2197 case Op_CountLeadingZerosV:
2198 return SuperwordUseVSX && UseCountLeadingZerosInstructionsPPC64;
2199 case Op_CountTrailingZerosV:
2200 return SuperwordUseVSX && UseCountTrailingZerosInstructionsPPC64;
2201 case Op_FmaF:
2202 case Op_FmaD:
2203 return UseFMA;
2204 case Op_FmaVF:
2205 case Op_FmaVD:
2206 return (SuperwordUseVSX && UseFMA);
2207
2208 case Op_MinF:
2209 case Op_MaxF:
2210 case Op_MinD:
2211 case Op_MaxD:
2212 return (PowerArchitecturePPC64 >= 9);
2213
2214 case Op_Digit:
2215 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit);
2216 case Op_LowerCase:
2217 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase);
2218 case Op_UpperCase:
2219 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase);
2220 case Op_Whitespace:
2221 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace);
2222
2223 case Op_CacheWB:
2224 case Op_CacheWBPreSync:
2225 case Op_CacheWBPostSync:
2226 return VM_Version::supports_data_cache_line_flush();
2227 }
2228
2229 return true; // Per default match rules are supported.
2230 }
2231
2232 bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
2233 return match_rule_supported_vector(opcode, vlen, bt);
2234 }
2235
2236 bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
2237 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
2238 return false;
2239 }
2240 // Special cases
2241 switch (opcode) {
2242 // Reductions only support INT at the moment.
2243 case Op_AddReductionVI:
2244 case Op_MulReductionVI:
2245 case Op_AndReductionV:
2246 case Op_OrReductionV:
2247 case Op_XorReductionV:
2248 case Op_MinReductionV:
2249 case Op_MaxReductionV:
2250 return bt == T_INT;
2251 // MaxV, MinV need types == INT || LONG.
2252 case Op_MaxV:
2253 case Op_MinV:
2254 case Op_UMinV:
2255 case Op_UMaxV:
2256 return bt == T_INT || bt == T_LONG;
2257 case Op_NegVI:
2258 return bt == T_INT;
2259 }
2260 return true; // Per default match rules are supported.
2261 }
2262
2263 bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
2264 return false;
2265 }
2266
2267 bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
2268 return false;
2269 }
2270
2271 bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
2272 return false;
2273 }
2274
2275 bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
2276 return false;
2277 }
2278
2279 const RegMask* Matcher::predicate_reg_mask(void) {
2280 return nullptr;
2281 }
2282
2283 // Vector calling convention not yet implemented.
2284 bool Matcher::supports_vector_calling_convention(void) {
2285 return false;
2286 }
2287
2288 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2289 Unimplemented();
2290 return OptoRegPair(0, 0);
2291 }
2292
2293 // Vector width in bytes.
2294 int Matcher::vector_width_in_bytes(BasicType bt) {
2295 if (SuperwordUseVSX) {
2296 assert(MaxVectorSize == 16,
2297 "SuperwordUseVSX requires MaxVectorSize 16, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2298 return 16;
2299 } else {
2300 assert(MaxVectorSize == 8,
2301 "expected MaxVectorSize 8, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2302 return 8;
2303 }
2304 }
2305
2306 // Vector ideal reg.
2307 uint Matcher::vector_ideal_reg(int size) {
2308 if (SuperwordUseVSX) {
2309 assert(MaxVectorSize == 16 && size == 16,
2310 "SuperwordUseVSX requires MaxVectorSize 16 and size 16, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2311 (int64_t)MaxVectorSize, size);
2312 return Op_VecX;
2313 } else {
2314 assert(MaxVectorSize == 8 && size == 8,
2315 "expected MaxVectorSize 8 and size 8, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2316 (int64_t)MaxVectorSize, size);
2317 return Op_RegL;
2318 }
2319 }
2320
2321 // Limits on vector size (number of elements) loaded into vector.
2322 int Matcher::max_vector_size(const BasicType bt) {
2323 assert(is_java_primitive(bt), "only primitive type vectors");
2324 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2325 }
2326
2327 int Matcher::min_vector_size(const BasicType bt) {
2328 return max_vector_size(bt); // Same as max.
2329 }
2330
2331 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
2332 return Matcher::max_vector_size(bt);
2333 }
2334
2335 int Matcher::scalable_vector_reg_size(const BasicType bt) {
2336 return -1;
2337 }
2338
2339 // RETURNS: whether this branch offset is short enough that a short
2340 // branch can be used.
2341 //
2342 // If the platform does not provide any short branch variants, then
2343 // this method should return `false' for offset 0.
2344 //
2345 // `Compile::Fill_buffer' will decide on basis of this information
2346 // whether to do the pass `Compile::Shorten_branches' at all.
2347 //
2348 // And `Compile::Shorten_branches' will decide on basis of this
2349 // information whether to replace particular branch sites by short
2350 // ones.
2351 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2352 // Is the offset within the range of a ppc64 pc relative branch?
2353 bool b;
2354
2355 const int safety_zone = 3 * BytesPerInstWord;
2356 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2357 29 - 16 + 1 + 2);
2358 return b;
2359 }
2360
2361 /* TODO: PPC port
2362 // Make a new machine dependent decode node (with its operands).
2363 MachTypeNode *Matcher::make_decode_node() {
2364 assert(CompressedOops::base() == nullptr && CompressedOops::shift() == 0,
2365 "This method is only implemented for unscaled cOops mode so far");
2366 MachTypeNode *decode = new decodeN_unscaledNode();
2367 decode->set_opnd_array(0, new iRegPdstOper());
2368 decode->set_opnd_array(1, new iRegNsrcOper());
2369 return decode;
2370 }
2371 */
2372
2373 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
2374 ShouldNotReachHere(); // generic vector operands not supported
2375 return nullptr;
2376 }
2377
2378 bool Matcher::is_reg2reg_move(MachNode* m) {
2379 ShouldNotReachHere(); // generic vector operands not supported
2380 return false;
2381 }
2382
2383 bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
2384 return false;
2385 }
2386
2387 bool Matcher::is_generic_vector(MachOper* opnd) {
2388 ShouldNotReachHere(); // generic vector operands not supported
2389 return false;
2390 }
2391
2392 #ifdef ASSERT
2393 // Return whether or not this register is ever used as an argument.
2394 bool Matcher::can_be_java_arg(int reg) {
2395 // We must include the virtual halves in order to get STDs and LDs
2396 // instead of STWs and LWs in the trampoline stubs.
2397
2398 if ( reg == R3_num || reg == R3_H_num
2399 || reg == R4_num || reg == R4_H_num
2400 || reg == R5_num || reg == R5_H_num
2401 || reg == R6_num || reg == R6_H_num
2402 || reg == R7_num || reg == R7_H_num
2403 || reg == R8_num || reg == R8_H_num
2404 || reg == R9_num || reg == R9_H_num
2405 || reg == R10_num || reg == R10_H_num)
2406 return true;
2407
2408 if ( reg == F1_num || reg == F1_H_num
2409 || reg == F2_num || reg == F2_H_num
2410 || reg == F3_num || reg == F3_H_num
2411 || reg == F4_num || reg == F4_H_num
2412 || reg == F5_num || reg == F5_H_num
2413 || reg == F6_num || reg == F6_H_num
2414 || reg == F7_num || reg == F7_H_num
2415 || reg == F8_num || reg == F8_H_num
2416 || reg == F9_num || reg == F9_H_num
2417 || reg == F10_num || reg == F10_H_num
2418 || reg == F11_num || reg == F11_H_num
2419 || reg == F12_num || reg == F12_H_num
2420 || reg == F13_num || reg == F13_H_num)
2421 return true;
2422
2423 return false;
2424 }
2425 #endif
2426
2427 uint Matcher::int_pressure_limit()
2428 {
2429 return (INTPRESSURE == -1) ? 26 : INTPRESSURE;
2430 }
2431
2432 uint Matcher::float_pressure_limit()
2433 {
2434 return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE;
2435 }
2436
2437 // Register for DIVI projection of divmodI.
2438 const RegMask& Matcher::divI_proj_mask() {
2439 ShouldNotReachHere();
2440 return RegMask::EMPTY;
2441 }
2442
2443 // Register for MODI projection of divmodI.
2444 const RegMask& Matcher::modI_proj_mask() {
2445 ShouldNotReachHere();
2446 return RegMask::EMPTY;
2447 }
2448
2449 // Register for DIVL projection of divmodL.
2450 const RegMask& Matcher::divL_proj_mask() {
2451 ShouldNotReachHere();
2452 return RegMask::EMPTY;
2453 }
2454
2455 // Register for MODL projection of divmodL.
2456 const RegMask& Matcher::modL_proj_mask() {
2457 ShouldNotReachHere();
2458 return RegMask::EMPTY;
2459 }
2460
2461 %}
2462
2463 //----------ENCODING BLOCK-----------------------------------------------------
2464 // This block specifies the encoding classes used by the compiler to output
2465 // byte streams. Encoding classes are parameterized macros used by
2466 // Machine Instruction Nodes in order to generate the bit encoding of the
2467 // instruction. Operands specify their base encoding interface with the
2468 // interface keyword. There are currently supported four interfaces,
2469 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
2470 // operand to generate a function which returns its register number when
2471 // queried. CONST_INTER causes an operand to generate a function which
2472 // returns the value of the constant when queried. MEMORY_INTER causes an
2473 // operand to generate four functions which return the Base Register, the
2474 // Index Register, the Scale Value, and the Offset Value of the operand when
2475 // queried. COND_INTER causes an operand to generate six functions which
2476 // return the encoding code (ie - encoding bits for the instruction)
2477 // associated with each basic boolean condition for a conditional instruction.
2478 //
2479 // Instructions specify two basic values for encoding. Again, a function
2480 // is available to check if the constant displacement is an oop. They use the
2481 // ins_encode keyword to specify their encoding classes (which must be
2482 // a sequence of enc_class names, and their parameters, specified in
2483 // the encoding block), and they use the
2484 // opcode keyword to specify, in order, their primary, secondary, and
2485 // tertiary opcode. Only the opcode sections which a particular instruction
2486 // needs for encoding need to be specified.
2487 encode %{
2488 enc_class enc_unimplemented %{
2489 __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
2490 %}
2491
2492 enc_class enc_untested %{
2493 #ifdef ASSERT
2494 __ untested("Untested mach node encoding in AD file.");
2495 #else
2496 #endif
2497 %}
2498
2499 enc_class enc_lbz(iRegIdst dst, memory mem) %{
2500 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2501 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2502 %}
2503
2504 // Load acquire.
2505 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
2506 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2507 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2508 __ twi_0($dst$$Register);
2509 __ isync();
2510 %}
2511
2512 enc_class enc_lhz(iRegIdst dst, memory mem) %{
2513 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2514 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2515 %}
2516
2517 // Load acquire.
2518 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
2519 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2520 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2521 __ twi_0($dst$$Register);
2522 __ isync();
2523 %}
2524
2525 enc_class enc_lwz(iRegIdst dst, memory mem) %{
2526 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2527 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2528 %}
2529
2530 // Load acquire.
2531 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
2532 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2533 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2534 __ twi_0($dst$$Register);
2535 __ isync();
2536 %}
2537
2538 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
2539 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2540 // Operand 'ds' requires 4-alignment.
2541 assert((Idisp & 0x3) == 0, "unaligned offset");
2542 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2543 %}
2544
2545 // Load acquire.
2546 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
2547 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2548 // Operand 'ds' requires 4-alignment.
2549 assert((Idisp & 0x3) == 0, "unaligned offset");
2550 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2551 __ twi_0($dst$$Register);
2552 __ isync();
2553 %}
2554
2555 enc_class enc_lfd(RegF dst, memory mem) %{
2556 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2557 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2558 %}
2559
2560 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2561 int toc_offset = 0;
2562
2563 address const_toc_addr;
2564 // Create a non-oop constant, no relocation needed.
2565 // If it is an IC, it has a virtual_call_Relocation.
2566 const_toc_addr = __ long_constant((jlong)$src$$constant);
2567 if (const_toc_addr == nullptr) {
2568 ciEnv::current()->record_out_of_memory_failure();
2569 return;
2570 }
2571
2572 // Get the constant's TOC offset.
2573 toc_offset = __ offset_to_method_toc(const_toc_addr);
2574
2575 // Keep the current instruction offset in mind.
2576 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2577
2578 __ ld($dst$$Register, toc_offset, $toc$$Register);
2579 %}
2580
2581 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2582 if (!ra_->C->output()->in_scratch_emit_size()) {
2583 address const_toc_addr;
2584 // Create a non-oop constant, no relocation needed.
2585 // If it is an IC, it has a virtual_call_Relocation.
2586 const_toc_addr = __ long_constant((jlong)$src$$constant);
2587 if (const_toc_addr == nullptr) {
2588 ciEnv::current()->record_out_of_memory_failure();
2589 return;
2590 }
2591
2592 // Get the constant's TOC offset.
2593 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2594 // Store the toc offset of the constant.
2595 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2596
2597 // Also keep the current instruction offset in mind.
2598 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2599 }
2600
2601 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2602 %}
2603
2604 %} // encode
2605
2606 source %{
2607
2608 typedef struct {
2609 loadConL_hiNode *_large_hi;
2610 loadConL_loNode *_large_lo;
2611 loadConLNode *_small;
2612 MachNode *_last;
2613 } loadConLNodesTuple;
2614
2615 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2616 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2617 loadConLNodesTuple nodes;
2618
2619 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2620 if (large_constant_pool) {
2621 // Create new nodes.
2622 loadConL_hiNode *m1 = new loadConL_hiNode();
2623 loadConL_loNode *m2 = new loadConL_loNode();
2624
2625 // inputs for new nodes
2626 m1->add_req(nullptr, toc);
2627 m2->add_req(nullptr, m1);
2628
2629 // operands for new nodes
2630 m1->_opnds[0] = new iRegLdstOper(); // dst
2631 m1->_opnds[1] = immSrc; // src
2632 m1->_opnds[2] = new iRegPdstOper(); // toc
2633 m2->_opnds[0] = new iRegLdstOper(); // dst
2634 m2->_opnds[1] = immSrc; // src
2635 m2->_opnds[2] = new iRegLdstOper(); // base
2636
2637 // Initialize ins_attrib TOC fields.
2638 m1->_const_toc_offset = -1;
2639 m2->_const_toc_offset_hi_node = m1;
2640
2641 // Initialize ins_attrib instruction offset.
2642 m1->_cbuf_insts_offset = -1;
2643
2644 // register allocation for new nodes
2645 ra_->set_pair(m1->_idx, reg_second, reg_first);
2646 ra_->set_pair(m2->_idx, reg_second, reg_first);
2647
2648 // Create result.
2649 nodes._large_hi = m1;
2650 nodes._large_lo = m2;
2651 nodes._small = nullptr;
2652 nodes._last = nodes._large_lo;
2653 assert(m2->bottom_type()->isa_long(), "must be long");
2654 } else {
2655 loadConLNode *m2 = new loadConLNode();
2656
2657 // inputs for new nodes
2658 m2->add_req(nullptr, toc);
2659
2660 // operands for new nodes
2661 m2->_opnds[0] = new iRegLdstOper(); // dst
2662 m2->_opnds[1] = immSrc; // src
2663 m2->_opnds[2] = new iRegPdstOper(); // toc
2664
2665 // Initialize ins_attrib instruction offset.
2666 m2->_cbuf_insts_offset = -1;
2667
2668 // register allocation for new nodes
2669 ra_->set_pair(m2->_idx, reg_second, reg_first);
2670
2671 // Create result.
2672 nodes._large_hi = nullptr;
2673 nodes._large_lo = nullptr;
2674 nodes._small = m2;
2675 nodes._last = nodes._small;
2676 assert(m2->bottom_type()->isa_long(), "must be long");
2677 }
2678
2679 return nodes;
2680 }
2681
2682 typedef struct {
2683 loadConL_hiNode *_large_hi;
2684 loadConL_loNode *_large_lo;
2685 mtvsrdNode *_moved;
2686 xxspltdNode *_replicated;
2687 loadConLNode *_small;
2688 MachNode *_last;
2689 } loadConLReplicatedNodesTuple;
2690
2691 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2692 vecXOper *dst, immI_0Oper *zero,
2693 OptoReg::Name reg_second, OptoReg::Name reg_first,
2694 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) {
2695 loadConLReplicatedNodesTuple nodes;
2696
2697 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2698 if (large_constant_pool) {
2699 // Create new nodes.
2700 loadConL_hiNode *m1 = new loadConL_hiNode();
2701 loadConL_loNode *m2 = new loadConL_loNode();
2702 mtvsrdNode *m3 = new mtvsrdNode();
2703 xxspltdNode *m4 = new xxspltdNode();
2704
2705 // inputs for new nodes
2706 m1->add_req(nullptr, toc);
2707 m2->add_req(nullptr, m1);
2708 m3->add_req(nullptr, m2);
2709 m4->add_req(nullptr, m3);
2710
2711 // operands for new nodes
2712 m1->_opnds[0] = new iRegLdstOper(); // dst
2713 m1->_opnds[1] = immSrc; // src
2714 m1->_opnds[2] = new iRegPdstOper(); // toc
2715
2716 m2->_opnds[0] = new iRegLdstOper(); // dst
2717 m2->_opnds[1] = immSrc; // src
2718 m2->_opnds[2] = new iRegLdstOper(); // base
2719
2720 m3->_opnds[0] = new vecXOper(); // dst
2721 m3->_opnds[1] = new iRegLdstOper(); // src
2722
2723 m4->_opnds[0] = new vecXOper(); // dst
2724 m4->_opnds[1] = new vecXOper(); // src
2725 m4->_opnds[2] = zero;
2726
2727 // Initialize ins_attrib TOC fields.
2728 m1->_const_toc_offset = -1;
2729 m2->_const_toc_offset_hi_node = m1;
2730
2731 // Initialize ins_attrib instruction offset.
2732 m1->_cbuf_insts_offset = -1;
2733
2734 // register allocation for new nodes
2735 ra_->set_pair(m1->_idx, reg_second, reg_first);
2736 ra_->set_pair(m2->_idx, reg_second, reg_first);
2737 ra_->set1(m3->_idx, reg_second);
2738 ra_->set2(m3->_idx, reg_vec_first);
2739 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2740
2741 // Create result.
2742 nodes._large_hi = m1;
2743 nodes._large_lo = m2;
2744 nodes._moved = m3;
2745 nodes._replicated = m4;
2746 nodes._small = nullptr;
2747 nodes._last = nodes._replicated;
2748 assert(m2->bottom_type()->isa_long(), "must be long");
2749 } else {
2750 loadConLNode *m2 = new loadConLNode();
2751 mtvsrdNode *m3 = new mtvsrdNode();
2752 xxspltdNode *m4 = new xxspltdNode();
2753
2754 // inputs for new nodes
2755 m2->add_req(nullptr, toc);
2756
2757 // operands for new nodes
2758 m2->_opnds[0] = new iRegLdstOper(); // dst
2759 m2->_opnds[1] = immSrc; // src
2760 m2->_opnds[2] = new iRegPdstOper(); // toc
2761
2762 m3->_opnds[0] = new vecXOper(); // dst
2763 m3->_opnds[1] = new iRegLdstOper(); // src
2764
2765 m4->_opnds[0] = new vecXOper(); // dst
2766 m4->_opnds[1] = new vecXOper(); // src
2767 m4->_opnds[2] = zero;
2768
2769 // Initialize ins_attrib instruction offset.
2770 m2->_cbuf_insts_offset = -1;
2771 ra_->set1(m3->_idx, reg_second);
2772 ra_->set2(m3->_idx, reg_vec_first);
2773 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2774
2775 // register allocation for new nodes
2776 ra_->set_pair(m2->_idx, reg_second, reg_first);
2777
2778 // Create result.
2779 nodes._large_hi = nullptr;
2780 nodes._large_lo = nullptr;
2781 nodes._small = m2;
2782 nodes._moved = m3;
2783 nodes._replicated = m4;
2784 nodes._last = nodes._replicated;
2785 assert(m2->bottom_type()->isa_long(), "must be long");
2786 }
2787
2788 return nodes;
2789 }
2790
2791 %} // source
2792
2793 encode %{
2794 // Postalloc expand emitter for loading a long constant from the method's TOC.
2795 // Enc_class needed as consttanttablebase is not supported by postalloc
2796 // expand.
2797 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2798 // Create new nodes.
2799 loadConLNodesTuple loadConLNodes =
2800 loadConLNodesTuple_create(ra_, n_toc, op_src,
2801 ra_->get_reg_second(this), ra_->get_reg_first(this));
2802
2803 // Push new nodes.
2804 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2805 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2806
2807 // some asserts
2808 assert(nodes->length() >= 1, "must have created at least 1 node");
2809 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2810 %}
2811
2812 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2813 int toc_offset = 0;
2814
2815 intptr_t val = $src$$constant;
2816 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2817 address const_toc_addr;
2818 RelocationHolder r; // Initializes type to none.
2819 if (constant_reloc == relocInfo::oop_type) {
2820 // Create an oop constant and a corresponding relocation.
2821 AddressLiteral a = __ constant_oop_address((jobject)val);
2822 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2823 r = a.rspec();
2824 } else if (constant_reloc == relocInfo::metadata_type) {
2825 // Notify OOP recorder (don't need the relocation)
2826 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2827 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2828 } else {
2829 // Create a non-oop constant, no relocation needed.
2830 const_toc_addr = __ long_constant((jlong)$src$$constant);
2831 }
2832
2833 if (const_toc_addr == nullptr) {
2834 ciEnv::current()->record_out_of_memory_failure();
2835 return;
2836 }
2837 __ relocate(r); // If set above.
2838 // Get the constant's TOC offset.
2839 toc_offset = __ offset_to_method_toc(const_toc_addr);
2840
2841 __ ld($dst$$Register, toc_offset, $toc$$Register);
2842 %}
2843
2844 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2845 if (!ra_->C->output()->in_scratch_emit_size()) {
2846 intptr_t val = $src$$constant;
2847 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2848 address const_toc_addr;
2849 RelocationHolder r; // Initializes type to none.
2850 if (constant_reloc == relocInfo::oop_type) {
2851 // Create an oop constant and a corresponding relocation.
2852 AddressLiteral a = __ constant_oop_address((jobject)val);
2853 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2854 r = a.rspec();
2855 } else if (constant_reloc == relocInfo::metadata_type) {
2856 // Notify OOP recorder (don't need the relocation)
2857 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2858 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2859 } else { // non-oop pointers, e.g. card mark base, heap top
2860 // Create a non-oop constant, no relocation needed.
2861 const_toc_addr = __ long_constant((jlong)$src$$constant);
2862 }
2863
2864 if (const_toc_addr == nullptr) {
2865 ciEnv::current()->record_out_of_memory_failure();
2866 return;
2867 }
2868 __ relocate(r); // If set above.
2869 // Get the constant's TOC offset.
2870 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2871 // Store the toc offset of the constant.
2872 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2873 }
2874
2875 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2876 %}
2877
2878 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2879 // Enc_class needed as consttanttablebase is not supported by postalloc
2880 // expand.
2881 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2882 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2883 if (large_constant_pool) {
2884 // Create new nodes.
2885 loadConP_hiNode *m1 = new loadConP_hiNode();
2886 loadConP_loNode *m2 = new loadConP_loNode();
2887
2888 // inputs for new nodes
2889 m1->add_req(nullptr, n_toc);
2890 m2->add_req(nullptr, m1);
2891
2892 // operands for new nodes
2893 m1->_opnds[0] = new iRegPdstOper(); // dst
2894 m1->_opnds[1] = op_src; // src
2895 m1->_opnds[2] = new iRegPdstOper(); // toc
2896 m2->_opnds[0] = new iRegPdstOper(); // dst
2897 m2->_opnds[1] = op_src; // src
2898 m2->_opnds[2] = new iRegLdstOper(); // base
2899
2900 // Initialize ins_attrib TOC fields.
2901 m1->_const_toc_offset = -1;
2902 m2->_const_toc_offset_hi_node = m1;
2903
2904 // Register allocation for new nodes.
2905 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2906 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2907
2908 nodes->push(m1);
2909 nodes->push(m2);
2910 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2911 } else {
2912 loadConPNode *m2 = new loadConPNode();
2913
2914 // inputs for new nodes
2915 m2->add_req(nullptr, n_toc);
2916
2917 // operands for new nodes
2918 m2->_opnds[0] = new iRegPdstOper(); // dst
2919 m2->_opnds[1] = op_src; // src
2920 m2->_opnds[2] = new iRegPdstOper(); // toc
2921
2922 // Register allocation for new nodes.
2923 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2924
2925 nodes->push(m2);
2926 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2927 }
2928 %}
2929
2930 // Enc_class needed as consttanttablebase is not supported by postalloc
2931 // expand.
2932 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2933 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2934
2935 MachNode *m2;
2936 if (large_constant_pool) {
2937 m2 = new loadConFCompNode();
2938 } else {
2939 m2 = new loadConFNode();
2940 }
2941 // inputs for new nodes
2942 m2->add_req(nullptr, n_toc);
2943
2944 // operands for new nodes
2945 m2->_opnds[0] = op_dst;
2946 m2->_opnds[1] = op_src;
2947 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase
2948
2949 // register allocation for new nodes
2950 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2951 nodes->push(m2);
2952 %}
2953
2954 // Enc_class needed as consttanttablebase is not supported by postalloc
2955 // expand.
2956 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2957 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2958
2959 MachNode *m2;
2960 if (large_constant_pool) {
2961 m2 = new loadConDCompNode();
2962 } else {
2963 m2 = new loadConDNode();
2964 }
2965 // inputs for new nodes
2966 m2->add_req(nullptr, n_toc);
2967
2968 // operands for new nodes
2969 m2->_opnds[0] = op_dst;
2970 m2->_opnds[1] = op_src;
2971 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase
2972
2973 // register allocation for new nodes
2974 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2975 nodes->push(m2);
2976 %}
2977
2978 enc_class enc_stw(iRegIsrc src, memory mem) %{
2979 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2980 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2981 %}
2982
2983 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2984 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2985 // Operand 'ds' requires 4-alignment.
2986 assert((Idisp & 0x3) == 0, "unaligned offset");
2987 __ std($src$$Register, Idisp, $mem$$base$$Register);
2988 %}
2989
2990 enc_class enc_stfs(RegF src, memory mem) %{
2991 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2992 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2993 %}
2994
2995 enc_class enc_stfd(RegF src, memory mem) %{
2996 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2997 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2998 %}
2999
3000 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
3001 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
3002 encodeP_subNode *n_sub_base = new encodeP_subNode();
3003 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
3004 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode();
3005
3006 n_compare->add_req(n_region, n_src);
3007 n_compare->_opnds[0] = op_crx;
3008 n_compare->_opnds[1] = op_src;
3009 n_compare->_opnds[2] = new immL16Oper(0);
3010
3011 n_sub_base->add_req(n_region, n_src);
3012 n_sub_base->_opnds[0] = op_dst;
3013 n_sub_base->_opnds[1] = op_src;
3014 n_sub_base->_bottom_type = _bottom_type;
3015
3016 n_shift->add_req(n_region, n_sub_base);
3017 n_shift->_opnds[0] = op_dst;
3018 n_shift->_opnds[1] = op_dst;
3019 n_shift->_bottom_type = _bottom_type;
3020
3021 n_cond_set->add_req(n_region, n_compare, n_shift);
3022 n_cond_set->_opnds[0] = op_dst;
3023 n_cond_set->_opnds[1] = op_crx;
3024 n_cond_set->_opnds[2] = op_dst;
3025 n_cond_set->_bottom_type = _bottom_type;
3026
3027 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3028 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3029 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3030 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3031
3032 nodes->push(n_compare);
3033 nodes->push(n_sub_base);
3034 nodes->push(n_shift);
3035 nodes->push(n_cond_set);
3036
3037 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
3038 %}
3039
3040 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
3041
3042 encodeP_subNode *n1 = new encodeP_subNode();
3043 n1->add_req(n_region, n_src);
3044 n1->_opnds[0] = op_dst;
3045 n1->_opnds[1] = op_src;
3046 n1->_bottom_type = _bottom_type;
3047
3048 encodeP_shiftNode *n2 = new encodeP_shiftNode();
3049 n2->add_req(n_region, n1);
3050 n2->_opnds[0] = op_dst;
3051 n2->_opnds[1] = op_dst;
3052 n2->_bottom_type = _bottom_type;
3053 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3054 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3055
3056 nodes->push(n1);
3057 nodes->push(n2);
3058 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
3059 %}
3060
3061 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
3062 decodeN_shiftNode *n_shift = new decodeN_shiftNode();
3063 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
3064
3065 n_compare->add_req(n_region, n_src);
3066 n_compare->_opnds[0] = op_crx;
3067 n_compare->_opnds[1] = op_src;
3068 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
3069
3070 n_shift->add_req(n_region, n_src);
3071 n_shift->_opnds[0] = op_dst;
3072 n_shift->_opnds[1] = op_src;
3073 n_shift->_bottom_type = _bottom_type;
3074
3075 decodeN_addNode *n_add_base = new decodeN_addNode();
3076 n_add_base->add_req(n_region, n_shift);
3077 n_add_base->_opnds[0] = op_dst;
3078 n_add_base->_opnds[1] = op_dst;
3079 n_add_base->_bottom_type = _bottom_type;
3080
3081 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
3082 n_cond_set->add_req(n_region, n_compare, n_add_base);
3083 n_cond_set->_opnds[0] = op_dst;
3084 n_cond_set->_opnds[1] = op_crx;
3085 n_cond_set->_opnds[2] = op_dst;
3086 n_cond_set->_bottom_type = _bottom_type;
3087
3088 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3089 ra_->set_oop(n_cond_set, true);
3090
3091 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3092 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3093 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3094 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3095
3096 nodes->push(n_compare);
3097 nodes->push(n_shift);
3098 nodes->push(n_add_base);
3099 nodes->push(n_cond_set);
3100
3101 %}
3102
3103 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3104 decodeN_shiftNode *n1 = new decodeN_shiftNode();
3105 n1->add_req(n_region, n_src);
3106 n1->_opnds[0] = op_dst;
3107 n1->_opnds[1] = op_src;
3108 n1->_bottom_type = _bottom_type;
3109
3110 decodeN_addNode *n2 = new decodeN_addNode();
3111 n2->add_req(n_region, n1);
3112 n2->_opnds[0] = op_dst;
3113 n2->_opnds[1] = op_dst;
3114 n2->_bottom_type = _bottom_type;
3115 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3116 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3117
3118 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3119 ra_->set_oop(n2, true);
3120
3121 nodes->push(n1);
3122 nodes->push(n2);
3123 %}
3124
3125
3126 // This enc_class is needed so that scheduler gets proper
3127 // input mapping for latency computation.
3128 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
3129 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
3130 %}
3131
3132 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3133 Label done;
3134 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3135 __ li($dst$$Register, $zero$$constant);
3136 __ beq($crx$$CondRegister, done);
3137 __ li($dst$$Register, $notzero$$constant);
3138 __ bind(done);
3139 %}
3140
3141 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3142 Label done;
3143 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3144 __ li($dst$$Register, $zero$$constant);
3145 __ beq($crx$$CondRegister, done);
3146 __ li($dst$$Register, $notzero$$constant);
3147 __ bind(done);
3148 %}
3149
3150 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3151 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3152 Label done;
3153 __ bso($crx$$CondRegister, done);
3154 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3155 __ bind(done);
3156 %}
3157
3158 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
3159 Label done;
3160 __ bso($crx$$CondRegister, done);
3161 __ mffprd($dst$$Register, $src$$FloatRegister);
3162 __ bind(done);
3163 %}
3164
3165 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3166 Label d; // dummy
3167 __ bind(d);
3168 Label* p = ($lbl$$label);
3169 // `p' is `nullptr' when this encoding class is used only to
3170 // determine the size of the encoded instruction.
3171 Label& l = (nullptr == p)? d : *(p);
3172 int cc = $cmp$$cmpcode;
3173 int flags_reg = $crx$$reg;
3174 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3175 int bhint = Assembler::bhintNoHint;
3176
3177 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3178 if (_prob <= PROB_NEVER) {
3179 bhint = Assembler::bhintIsNotTaken;
3180 } else if (_prob >= PROB_ALWAYS) {
3181 bhint = Assembler::bhintIsTaken;
3182 }
3183 }
3184
3185 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3186 cc_to_biint(cc, flags_reg),
3187 l);
3188 %}
3189
3190 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3191 // The scheduler doesn't know about branch shortening, so we set the opcode
3192 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3193 Label d; // dummy
3194 __ bind(d);
3195 Label* p = ($lbl$$label);
3196 // `p' is `nullptr' when this encoding class is used only to
3197 // determine the size of the encoded instruction.
3198 Label& l = (nullptr == p)? d : *(p);
3199 int cc = $cmp$$cmpcode;
3200 int flags_reg = $crx$$reg;
3201 int bhint = Assembler::bhintNoHint;
3202
3203 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3204 if (_prob <= PROB_NEVER) {
3205 bhint = Assembler::bhintIsNotTaken;
3206 } else if (_prob >= PROB_ALWAYS) {
3207 bhint = Assembler::bhintIsTaken;
3208 }
3209 }
3210
3211 // Tell the conditional far branch to optimize itself when being relocated.
3212 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3213 cc_to_biint(cc, flags_reg),
3214 l,
3215 MacroAssembler::bc_far_optimize_on_relocate);
3216 %}
3217
3218 // Postalloc expand emitter for loading a replicatef float constant from
3219 // the method's TOC.
3220 // Enc_class needed as consttanttablebase is not supported by postalloc
3221 // expand.
3222 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3223 // Create new nodes.
3224
3225 // Make an operand with the bit pattern to load as float.
3226 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3227
3228 loadConLNodesTuple loadConLNodes =
3229 loadConLNodesTuple_create(ra_, n_toc, op_repl,
3230 ra_->get_reg_second(this), ra_->get_reg_first(this));
3231
3232 // Push new nodes.
3233 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3234 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3235
3236 assert(nodes->length() >= 1, "must have created at least 1 node");
3237 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3238 %}
3239
3240 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{
3241 // Create new nodes.
3242
3243 // Make an operand with the bit pattern to load as float.
3244 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3245 immI_0Oper *op_zero = new immI_0Oper(0);
3246
3247 loadConLReplicatedNodesTuple loadConLNodes =
3248 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero,
3249 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp),
3250 ra_->get_reg_second(this), ra_->get_reg_first(this));
3251
3252 // Push new nodes.
3253 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); }
3254 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); }
3255 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); }
3256 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); }
3257
3258 assert(nodes->length() >= 1, "must have created at least 1 node");
3259 %}
3260
3261 // This enc_class is needed so that scheduler gets proper
3262 // input mapping for latency computation.
3263 enc_class enc_poll(immI dst, iRegLdst poll) %{
3264 // Fake operand dst needed for PPC scheduler.
3265 assert($dst$$constant == 0x0, "dst must be 0x0");
3266
3267 // Mark the code position where the load from the safepoint
3268 // polling page was emitted as relocInfo::poll_type.
3269 __ relocate(relocInfo::poll_type);
3270 __ load_from_polling_page($poll$$Register);
3271 %}
3272
3273 // A Java static call or a runtime call.
3274 //
3275 // Branch-and-link relative to a trampoline.
3276 // The trampoline loads the target address and does a long branch to there.
3277 // In case we call java, the trampoline branches to a interpreter_stub
3278 // which loads the inline cache and the real call target from the constant pool.
3279 //
3280 // This basically looks like this:
3281 //
3282 // >>>> consts -+ -+
3283 // | |- offset1
3284 // [call target1] | <-+
3285 // [IC cache] |- offset2
3286 // [call target2] <--+
3287 //
3288 // <<<< consts
3289 // >>>> insts
3290 //
3291 // bl offset16 -+ -+ ??? // How many bits available?
3292 // | |
3293 // <<<< insts | |
3294 // >>>> stubs | |
3295 // | |- trampoline_stub_Reloc
3296 // trampoline stub: | <-+
3297 // r2 = toc |
3298 // r2 = [r2 + offset1] | // Load call target1 from const section
3299 // mtctr r2 |
3300 // bctr |- static_stub_Reloc
3301 // comp_to_interp_stub: <---+
3302 // r1 = toc
3303 // ICreg = [r1 + IC_offset] // Load IC from const section
3304 // r1 = [r1 + offset2] // Load call target2 from const section
3305 // mtctr r1
3306 // bctr
3307 //
3308 // <<<< stubs
3309 //
3310 // The call instruction in the code either
3311 // - Branches directly to a compiled method if the offset is encodable in instruction.
3312 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3313 // - Branches to the compiled_to_interp stub if the target is interpreted.
3314 //
3315 // Further there are three relocations from the loads to the constants in
3316 // the constant section.
3317 //
3318 // Usage of r1 and r2 in the stubs allows to distinguish them.
3319 enc_class enc_java_static_call(method meth) %{
3320 address entry_point = (address)$meth$$method;
3321
3322 if (!_method) {
3323 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3324 emit_call_with_trampoline_stub(masm, entry_point, relocInfo::runtime_call_type);
3325 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3326 } else {
3327 // Remember the offset not the address.
3328 const int start_offset = __ offset();
3329
3330 // The trampoline stub.
3331 // No entry point given, use the current pc.
3332 // Make sure branch fits into
3333 if (entry_point == nullptr) entry_point = __ pc();
3334
3335 // Put the entry point as a constant into the constant pool.
3336 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
3337 if (entry_point_toc_addr == nullptr) {
3338 ciEnv::current()->record_out_of_memory_failure();
3339 return;
3340 }
3341 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
3342
3343 // Emit the trampoline stub which will be related to the branch-and-link below.
3344 CallStubImpl::emit_trampoline_stub(masm, entry_point_toc_offset, start_offset);
3345 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3346 int method_index = resolved_method_index(masm);
3347 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3348 : static_call_Relocation::spec(method_index));
3349
3350 // The real call.
3351 // Note: At this point we do not have the address of the trampoline
3352 // stub, and the entry point might be too far away for bl, so __ pc()
3353 // serves as dummy and the bl will be patched later.
3354 __ set_inst_mark();
3355 __ bl(__ pc()); // Emits a relocation.
3356
3357 // The stub for call to interpreter.
3358 address stub = CompiledDirectCall::emit_to_interp_stub(masm);
3359 __ clear_inst_mark();
3360 if (stub == nullptr) {
3361 ciEnv::current()->record_failure("CodeCache is full");
3362 return;
3363 }
3364 }
3365 __ post_call_nop();
3366 %}
3367
3368 // Second node of expanded dynamic call - the call.
3369 enc_class enc_java_dynamic_call_sched(method meth) %{
3370 if (!ra_->C->output()->in_scratch_emit_size()) {
3371 // Create a call trampoline stub for the given method.
3372 const address entry_point = !($meth$$method) ? nullptr : (address)$meth$$method;
3373 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none);
3374 if (entry_point_const == nullptr) {
3375 ciEnv::current()->record_out_of_memory_failure();
3376 return;
3377 }
3378 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const);
3379 CallStubImpl::emit_trampoline_stub(masm, entry_point_const_toc_offset, __ offset());
3380 if (ra_->C->env()->failing()) { return; } // Code cache may be full.
3381
3382 // Build relocation at call site with ic position as data.
3383 assert((_load_ic_hi_node != nullptr && _load_ic_node == nullptr) ||
3384 (_load_ic_hi_node == nullptr && _load_ic_node != nullptr),
3385 "must have one, but can't have both");
3386 assert((_load_ic_hi_node != nullptr && _load_ic_hi_node->_cbuf_insts_offset != -1) ||
3387 (_load_ic_node != nullptr && _load_ic_node->_cbuf_insts_offset != -1),
3388 "must contain instruction offset");
3389 const int virtual_call_oop_addr_offset = _load_ic_hi_node != nullptr
3390 ? _load_ic_hi_node->_cbuf_insts_offset
3391 : _load_ic_node->_cbuf_insts_offset;
3392 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset);
3393 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr),
3394 "should be load from TOC");
3395 int method_index = resolved_method_index(masm);
3396 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
3397 }
3398
3399 // At this point I do not have the address of the trampoline stub,
3400 // and the entry point might be too far away for bl. Pc() serves
3401 // as dummy and bl will be patched later.
3402 __ bl((address) __ pc());
3403 __ post_call_nop();
3404 %}
3405
3406 // postalloc expand emitter for virtual calls.
3407 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{
3408
3409 // Create the nodes for loading the IC from the TOC.
3410 loadConLNodesTuple loadConLNodes_IC =
3411 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) Universe::non_oop_word()),
3412 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num));
3413
3414 // Create the call node.
3415 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode();
3416 call->_vtable_index = _vtable_index;
3417 call->_method = _method;
3418 call->_optimized_virtual = _optimized_virtual;
3419 call->_tf = _tf;
3420 call->_entry_point = _entry_point;
3421 call->_cnt = _cnt;
3422 call->_guaranteed_safepoint = true;
3423 call->_oop_map = _oop_map;
3424 call->_jvms = _jvms;
3425 call->_jvmadj = _jvmadj;
3426 call->_has_ea_local_in_scope = _has_ea_local_in_scope;
3427 call->_in_rms = _in_rms;
3428 call->_nesting = _nesting;
3429 call->_override_symbolic_info = _override_symbolic_info;
3430 call->_arg_escape = _arg_escape;
3431
3432 // New call needs all inputs of old call.
3433 // Req...
3434 for (uint i = 0; i < req(); ++i) {
3435 // The expanded node does not need toc any more.
3436 // Add the inline cache constant here instead. This expresses the
3437 // register of the inline cache must be live at the call.
3438 // Else we would have to adapt JVMState by -1.
3439 if (i == mach_constant_base_node_input()) {
3440 call->add_req(loadConLNodes_IC._last);
3441 } else {
3442 call->add_req(in(i));
3443 }
3444 }
3445 // ...as well as prec
3446 for (uint i = req(); i < len(); ++i) {
3447 call->add_prec(in(i));
3448 }
3449
3450 // Remember nodes loading the inline cache into r19.
3451 call->_load_ic_hi_node = loadConLNodes_IC._large_hi;
3452 call->_load_ic_node = loadConLNodes_IC._small;
3453
3454 // Operands for new nodes.
3455 call->_opnds[0] = _opnds[0];
3456 call->_opnds[1] = _opnds[1];
3457
3458 // Only the inline cache is associated with a register.
3459 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19");
3460
3461 // Push new nodes.
3462 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi);
3463 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last);
3464 nodes->push(call);
3465 %}
3466
3467 // Compound version of call dynamic
3468 // Toc is only passed so that it can be used in ins_encode statement.
3469 // In the code we have to use $constanttablebase.
3470 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
3471 int start_offset = __ offset();
3472
3473 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC;
3474
3475 int vtable_index = this->_vtable_index;
3476 if (vtable_index < 0) {
3477 // Must be invalid_vtable_index, not nonvirtual_vtable_index.
3478 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value");
3479 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode());
3480
3481 // Virtual call relocation will point to ic load.
3482 address virtual_call_meta_addr = __ pc();
3483 // Load a clear inline cache.
3484 AddressLiteral empty_ic((address) Universe::non_oop_word());
3485 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true);
3486 if (!success) {
3487 ciEnv::current()->record_out_of_memory_failure();
3488 return;
3489 }
3490 // CALL to fixup routine. Fixup routine uses ScopeDesc info
3491 // to determine who we intended to call.
3492 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr));
3493 emit_call_with_trampoline_stub(masm, (address)$meth$$method, relocInfo::none);
3494 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3495 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3496 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3497 } else {
3498 assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
3499 // Go thru the vtable. Get receiver klass. Receiver already
3500 // checked for non-null. If we'll go thru a C2I adapter, the
3501 // interpreter expects method in R19_method.
3502
3503 __ load_klass(R11_scratch1, R3);
3504
3505 int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index * vtableEntry::size_in_bytes();
3506 int v_off = entry_offset + in_bytes(vtableEntry::method_offset());
3507 __ li(R19_method, v_off);
3508 __ ldx(R19_method/*method*/, R19_method/*method offset*/, R11_scratch1/*class*/);
3509 // NOTE: for vtable dispatches, the vtable entry will never be
3510 // null. However it may very well end up in handle_wrong_method
3511 // if the method is abstract for the particular class.
3512 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method);
3513 // Call target. Either compiled code or C2I adapter.
3514 __ mtctr(R11_scratch1);
3515 __ bctrl();
3516 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3517 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3518 }
3519 __ post_call_nop();
3520 %}
3521
3522 // a runtime call
3523 enc_class enc_java_to_runtime_call (method meth) %{
3524 const address start_pc = __ pc();
3525
3526 #if defined(ABI_ELFv2)
3527 address entry= !($meth$$method) ? nullptr : (address)$meth$$method;
3528 __ call_c(entry, relocInfo::runtime_call_type);
3529 __ post_call_nop();
3530 #else
3531 // The function we're going to call.
3532 FunctionDescriptor fdtemp;
3533 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3534
3535 Register Rtoc = R12_scratch2;
3536 // Calculate the method's TOC.
3537 __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3538 // Put entry, env, toc into the constant pool, this needs up to 3 constant
3539 // pool entries; call_c_using_toc will optimize the call.
3540 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3541 if (!success) {
3542 ciEnv::current()->record_out_of_memory_failure();
3543 return;
3544 }
3545 __ post_call_nop();
3546 #endif
3547
3548 // Check the ret_addr_offset.
3549 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3550 "Fix constant in ret_addr_offset()");
3551 %}
3552
3553 // Move to ctr for leaf call.
3554 // This enc_class is needed so that scheduler gets proper
3555 // input mapping for latency computation.
3556 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3557 __ mtctr($src$$Register);
3558 %}
3559
3560 // Postalloc expand emitter for runtime leaf calls.
3561 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3562 loadConLNodesTuple loadConLNodes_Entry;
3563 #if defined(ABI_ELFv2)
3564 jlong entry_address = (jlong) this->entry_point();
3565 assert(entry_address, "need address here");
3566 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3567 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3568 #else
3569 // Get the struct that describes the function we are about to call.
3570 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3571 assert(fd, "need fd here");
3572 jlong entry_address = (jlong) fd->entry();
3573 // new nodes
3574 loadConLNodesTuple loadConLNodes_Env;
3575 loadConLNodesTuple loadConLNodes_Toc;
3576
3577 // Create nodes and operands for loading the entry point.
3578 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3579 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3580
3581
3582 // Create nodes and operands for loading the env pointer.
3583 if (fd->env() != nullptr) {
3584 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3585 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3586 } else {
3587 loadConLNodes_Env._large_hi = nullptr;
3588 loadConLNodes_Env._large_lo = nullptr;
3589 loadConLNodes_Env._small = nullptr;
3590 loadConLNodes_Env._last = new loadConL16Node();
3591 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3592 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3593 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3594 }
3595
3596 // Create nodes and operands for loading the Toc point.
3597 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3598 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3599 #endif // ABI_ELFv2
3600 // mtctr node
3601 MachNode *mtctr = new CallLeafDirect_mtctrNode();
3602
3603 assert(loadConLNodes_Entry._last != nullptr, "entry must exist");
3604 mtctr->add_req(nullptr, loadConLNodes_Entry._last);
3605
3606 mtctr->_opnds[0] = new iRegLdstOper();
3607 mtctr->_opnds[1] = new iRegLdstOper();
3608
3609 // call node
3610 MachCallLeafNode *call = new CallLeafDirectNode();
3611
3612 call->_opnds[0] = _opnds[0];
3613 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3614
3615 // Make the new call node look like the old one.
3616 call->_name = _name;
3617 call->_tf = _tf;
3618 call->_entry_point = _entry_point;
3619 call->_cnt = _cnt;
3620 call->_guaranteed_safepoint = false;
3621 call->_oop_map = _oop_map;
3622 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3623 call->_jvms = nullptr;
3624 call->_jvmadj = _jvmadj;
3625 call->_in_rms = _in_rms;
3626 call->_nesting = _nesting;
3627
3628 // New call needs all inputs of old call.
3629 // Req...
3630 for (uint i = 0; i < req(); ++i) {
3631 if (i != mach_constant_base_node_input()) {
3632 call->add_req(in(i));
3633 }
3634 }
3635
3636 // These must be reqired edges, as the registers are live up to
3637 // the call. Else the constants are handled as kills.
3638 call->add_req(mtctr);
3639 #if !defined(ABI_ELFv2)
3640 call->add_req(loadConLNodes_Env._last);
3641 call->add_req(loadConLNodes_Toc._last);
3642 #endif
3643
3644 // ...as well as prec
3645 for (uint i = req(); i < len(); ++i) {
3646 call->add_prec(in(i));
3647 }
3648
3649 // registers
3650 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3651
3652 // Insert the new nodes.
3653 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3654 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last);
3655 #if !defined(ABI_ELFv2)
3656 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi);
3657 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last);
3658 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi);
3659 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last);
3660 #endif
3661 nodes->push(mtctr);
3662 nodes->push(call);
3663 %}
3664 %}
3665
3666 //----------FRAME--------------------------------------------------------------
3667 // Definition of frame structure and management information.
3668
3669 frame %{
3670 // These two registers define part of the calling convention between
3671 // compiled code and the interpreter.
3672
3673 // Inline Cache Register or method for I2C.
3674 inline_cache_reg(R19); // R19_method
3675
3676 // Optional: name the operand used by cisc-spilling to access
3677 // [stack_pointer + offset].
3678 cisc_spilling_operand_name(indOffset);
3679
3680 // Number of stack slots consumed by a Monitor enter.
3681 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size));
3682
3683 // Compiled code's Frame Pointer.
3684 frame_pointer(R1); // R1_SP
3685
3686 stack_alignment(frame::alignment_in_bytes);
3687
3688 // Number of outgoing stack slots killed above the
3689 // out_preserve_stack_slots for calls to C. Supports the var-args
3690 // backing area for register parms.
3691 //
3692 varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3693
3694 // The after-PROLOG location of the return address. Location of
3695 // return address specifies a type (REG or STACK) and a number
3696 // representing the register number (i.e. - use a register name) or
3697 // stack slot.
3698 //
3699 // A: Link register is stored in stack slot ...
3700 // M: ... but it's in the caller's frame according to PPC-64 ABI.
3701 // J: Therefore, we make sure that the link register is also in R11_scratch1
3702 // at the end of the prolog.
3703 // B: We use R20, now.
3704 //return_addr(REG R20);
3705
3706 // G: After reading the comments made by all the luminaries on their
3707 // failure to tell the compiler where the return address really is,
3708 // I hardly dare to try myself. However, I'm convinced it's in slot
3709 // 4 what apparently works and saves us some spills.
3710 return_addr(STACK 4);
3711
3712 // Location of native (C/C++) and interpreter return values. This
3713 // is specified to be the same as Java. In the 32-bit VM, long
3714 // values are actually returned from native calls in O0:O1 and
3715 // returned to the interpreter in I0:I1. The copying to and from
3716 // the register pairs is done by the appropriate call and epilog
3717 // opcodes. This simplifies the register allocator.
3718 c_return_value %{
3719 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3720 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3721 "only return normal values");
3722 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3723 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3724 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3725 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3726 %}
3727
3728 // Location of compiled Java return values. Same as C
3729 return_value %{
3730 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3731 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3732 "only return normal values");
3733 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3734 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3735 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3736 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3737 %}
3738 %}
3739
3740
3741 //----------ATTRIBUTES---------------------------------------------------------
3742
3743 //----------Operand Attributes-------------------------------------------------
3744 op_attrib op_cost(1); // Required cost attribute.
3745
3746 //----------Instruction Attributes---------------------------------------------
3747
3748 // Cost attribute. required.
3749 ins_attrib ins_cost(DEFAULT_COST);
3750
3751 // Is this instruction a non-matching short branch variant of some
3752 // long branch? Not required.
3753 ins_attrib ins_short_branch(0);
3754
3755 ins_attrib ins_is_TrapBasedCheckNode(true);
3756
3757 // Number of constants.
3758 // This instruction uses the given number of constants
3759 // (optional attribute).
3760 // This is needed to determine in time whether the constant pool will
3761 // exceed 4000 entries. Before postalloc_expand the overall number of constants
3762 // is determined. It's also used to compute the constant pool size
3763 // in Output().
3764 ins_attrib ins_num_consts(0);
3765
3766 // Required alignment attribute (must be a power of 2) specifies the
3767 // alignment that some part of the instruction (not necessarily the
3768 // start) requires. If > 1, a compute_padding() function must be
3769 // provided for the instruction.
3770 ins_attrib ins_alignment(1);
3771
3772 // Enforce/prohibit rematerializations.
3773 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3774 // then rematerialization of that instruction is prohibited and the
3775 // instruction's value will be spilled if necessary.
3776 // Causes that MachNode::rematerialize() returns false.
3777 // - If an instruction is attributed with 'ins_should_rematerialize(true)'
3778 // then rematerialization should be enforced and a copy of the instruction
3779 // should be inserted if possible; rematerialization is not guaranteed.
3780 // Note: this may result in rematerializations in front of every use.
3781 // Causes that MachNode::rematerialize() can return true.
3782 // (optional attribute)
3783 ins_attrib ins_cannot_rematerialize(false);
3784 ins_attrib ins_should_rematerialize(false);
3785
3786 // Instruction has variable size depending on alignment.
3787 ins_attrib ins_variable_size_depending_on_alignment(false);
3788
3789 // Instruction is a nop.
3790 ins_attrib ins_is_nop(false);
3791
3792 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock).
3793 ins_attrib ins_use_mach_if_fast_lock_node(false);
3794
3795 // Field for the toc offset of a constant.
3796 //
3797 // This is needed if the toc offset is not encodable as an immediate in
3798 // the PPC load instruction. If so, the upper (hi) bits of the offset are
3799 // added to the toc, and from this a load with immediate is performed.
3800 // With postalloc expand, we get two nodes that require the same offset
3801 // but which don't know about each other. The offset is only known
3802 // when the constant is added to the constant pool during emitting.
3803 // It is generated in the 'hi'-node adding the upper bits, and saved
3804 // in this node. The 'lo'-node has a link to the 'hi'-node and reads
3805 // the offset from there when it gets encoded.
3806 ins_attrib ins_field_const_toc_offset(0);
3807 ins_attrib ins_field_const_toc_offset_hi_node(0);
3808
3809 // A field that can hold the instructions offset in the code buffer.
3810 // Set in the nodes emitter.
3811 ins_attrib ins_field_cbuf_insts_offset(-1);
3812
3813 // Fields for referencing a call's load-IC-node.
3814 // If the toc offset can not be encoded as an immediate in a load, we
3815 // use two nodes.
3816 ins_attrib ins_field_load_ic_hi_node(0);
3817 ins_attrib ins_field_load_ic_node(0);
3818
3819 // Whether this node is expanded during code emission into a sequence of
3820 // instructions and the first instruction can perform an implicit null check.
3821 ins_attrib ins_is_late_expanded_null_check_candidate(false);
3822
3823 //----------OPERANDS-----------------------------------------------------------
3824 // Operand definitions must precede instruction definitions for correct
3825 // parsing in the ADLC because operands constitute user defined types
3826 // which are used in instruction definitions.
3827 //
3828 // Formats are generated automatically for constants and base registers.
3829
3830 operand vecX() %{
3831 constraint(ALLOC_IN_RC(v_reg));
3832 match(VecX);
3833
3834 format %{ %}
3835 interface(REG_INTER);
3836 %}
3837
3838 //----------Simple Operands----------------------------------------------------
3839 // Immediate Operands
3840
3841 // Integer Immediate: 32-bit
3842 operand immI() %{
3843 match(ConI);
3844 op_cost(40);
3845 format %{ %}
3846 interface(CONST_INTER);
3847 %}
3848
3849 operand immI8() %{
3850 predicate(Assembler::is_simm(n->get_int(), 8));
3851 op_cost(0);
3852 match(ConI);
3853 format %{ %}
3854 interface(CONST_INTER);
3855 %}
3856
3857 // Integer Immediate: 16-bit
3858 operand immI16() %{
3859 predicate(Assembler::is_simm(n->get_int(), 16));
3860 op_cost(0);
3861 match(ConI);
3862 format %{ %}
3863 interface(CONST_INTER);
3864 %}
3865
3866 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000.
3867 operand immIhi16() %{
3868 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0));
3869 match(ConI);
3870 op_cost(0);
3871 format %{ %}
3872 interface(CONST_INTER);
3873 %}
3874
3875 // Integer Immediate: 32-bit immediate for prefixed addi and load/store.
3876 operand immI32() %{
3877 predicate(PowerArchitecturePPC64 >= 10);
3878 op_cost(0);
3879 match(ConI);
3880 format %{ %}
3881 interface(CONST_INTER);
3882 %}
3883
3884 operand immInegpow2() %{
3885 predicate(is_power_of_2(-(juint)(n->get_int())));
3886 match(ConI);
3887 op_cost(0);
3888 format %{ %}
3889 interface(CONST_INTER);
3890 %}
3891
3892 operand immIpow2minus1() %{
3893 predicate(is_power_of_2((juint)(n->get_int()) + 1u));
3894 match(ConI);
3895 op_cost(0);
3896 format %{ %}
3897 interface(CONST_INTER);
3898 %}
3899
3900 operand immIpowerOf2() %{
3901 predicate(is_power_of_2((juint)(n->get_int())));
3902 match(ConI);
3903 op_cost(0);
3904 format %{ %}
3905 interface(CONST_INTER);
3906 %}
3907
3908 // Unsigned Integer Immediate: the values 0-31
3909 operand uimmI5() %{
3910 predicate(Assembler::is_uimm(n->get_int(), 5));
3911 match(ConI);
3912 op_cost(0);
3913 format %{ %}
3914 interface(CONST_INTER);
3915 %}
3916
3917 // Unsigned Integer Immediate: 6-bit
3918 operand uimmI6() %{
3919 predicate(Assembler::is_uimm(n->get_int(), 6));
3920 match(ConI);
3921 op_cost(0);
3922 format %{ %}
3923 interface(CONST_INTER);
3924 %}
3925
3926 // Unsigned Integer Immediate: 6-bit int, greater than 32
3927 operand uimmI6_ge32() %{
3928 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32);
3929 match(ConI);
3930 op_cost(0);
3931 format %{ %}
3932 interface(CONST_INTER);
3933 %}
3934
3935 // Unsigned Integer Immediate: 15-bit
3936 operand uimmI15() %{
3937 predicate(Assembler::is_uimm(n->get_int(), 15));
3938 match(ConI);
3939 op_cost(0);
3940 format %{ %}
3941 interface(CONST_INTER);
3942 %}
3943
3944 // Unsigned Integer Immediate: 16-bit
3945 operand uimmI16() %{
3946 predicate(Assembler::is_uimm(n->get_int(), 16));
3947 match(ConI);
3948 op_cost(0);
3949 format %{ %}
3950 interface(CONST_INTER);
3951 %}
3952
3953 // constant 'int 0'.
3954 operand immI_0() %{
3955 predicate(n->get_int() == 0);
3956 match(ConI);
3957 op_cost(0);
3958 format %{ %}
3959 interface(CONST_INTER);
3960 %}
3961
3962 // constant 'int 1'.
3963 operand immI_1() %{
3964 predicate(n->get_int() == 1);
3965 match(ConI);
3966 op_cost(0);
3967 format %{ %}
3968 interface(CONST_INTER);
3969 %}
3970
3971 // constant 'int -1'.
3972 operand immI_minus1() %{
3973 predicate(n->get_int() == -1);
3974 match(ConI);
3975 op_cost(0);
3976 format %{ %}
3977 interface(CONST_INTER);
3978 %}
3979
3980 // int value 16.
3981 operand immI_16() %{
3982 predicate(n->get_int() == 16);
3983 match(ConI);
3984 op_cost(0);
3985 format %{ %}
3986 interface(CONST_INTER);
3987 %}
3988
3989 // int value 24.
3990 operand immI_24() %{
3991 predicate(n->get_int() == 24);
3992 match(ConI);
3993 op_cost(0);
3994 format %{ %}
3995 interface(CONST_INTER);
3996 %}
3997
3998 // Compressed oops constants
3999 // Pointer Immediate
4000 operand immN() %{
4001 match(ConN);
4002
4003 op_cost(10);
4004 format %{ %}
4005 interface(CONST_INTER);
4006 %}
4007
4008 // nullptr Pointer Immediate
4009 operand immN_0() %{
4010 predicate(n->get_narrowcon() == 0);
4011 match(ConN);
4012
4013 op_cost(0);
4014 format %{ %}
4015 interface(CONST_INTER);
4016 %}
4017
4018 // Compressed klass constants
4019 operand immNKlass() %{
4020 match(ConNKlass);
4021
4022 op_cost(0);
4023 format %{ %}
4024 interface(CONST_INTER);
4025 %}
4026
4027 // This operand can be used to avoid matching of an instruct
4028 // with chain rule.
4029 operand immNKlass_NM() %{
4030 match(ConNKlass);
4031 predicate(false);
4032 op_cost(0);
4033 format %{ %}
4034 interface(CONST_INTER);
4035 %}
4036
4037 // Pointer Immediate: 64-bit
4038 operand immP() %{
4039 match(ConP);
4040 op_cost(0);
4041 format %{ %}
4042 interface(CONST_INTER);
4043 %}
4044
4045 // Operand to avoid match of loadConP.
4046 // This operand can be used to avoid matching of an instruct
4047 // with chain rule.
4048 operand immP_NM() %{
4049 match(ConP);
4050 predicate(false);
4051 op_cost(0);
4052 format %{ %}
4053 interface(CONST_INTER);
4054 %}
4055
4056 // constant 'pointer 0'.
4057 operand immP_0() %{
4058 predicate(n->get_ptr() == 0);
4059 match(ConP);
4060 op_cost(0);
4061 format %{ %}
4062 interface(CONST_INTER);
4063 %}
4064
4065 // pointer 0x0 or 0x1
4066 operand immP_0or1() %{
4067 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
4068 match(ConP);
4069 op_cost(0);
4070 format %{ %}
4071 interface(CONST_INTER);
4072 %}
4073
4074 operand immL() %{
4075 match(ConL);
4076 op_cost(40);
4077 format %{ %}
4078 interface(CONST_INTER);
4079 %}
4080
4081 operand immLmax30() %{
4082 predicate((n->get_long() <= 30));
4083 match(ConL);
4084 op_cost(0);
4085 format %{ %}
4086 interface(CONST_INTER);
4087 %}
4088
4089 // Long Immediate: 16-bit
4090 operand immL16() %{
4091 predicate(Assembler::is_simm(n->get_long(), 16));
4092 match(ConL);
4093 op_cost(0);
4094 format %{ %}
4095 interface(CONST_INTER);
4096 %}
4097
4098 // Long Immediate: 16-bit, 4-aligned
4099 operand immL16Alg4() %{
4100 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
4101 match(ConL);
4102 op_cost(0);
4103 format %{ %}
4104 interface(CONST_INTER);
4105 %}
4106
4107 // Long Immediate: 16-bit, 16-aligned
4108 operand immL16Alg16() %{
4109 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0xf) == 0));
4110 match(ConL);
4111 op_cost(0);
4112 format %{ %}
4113 interface(CONST_INTER);
4114 %}
4115
4116 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
4117 operand immL32hi16() %{
4118 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L));
4119 match(ConL);
4120 op_cost(0);
4121 format %{ %}
4122 interface(CONST_INTER);
4123 %}
4124
4125 // Long Immediate: 32-bit
4126 operand immL32() %{
4127 predicate(Assembler::is_simm(n->get_long(), 32));
4128 match(ConL);
4129 op_cost(0);
4130 format %{ %}
4131 interface(CONST_INTER);
4132 %}
4133
4134 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store.
4135 operand immL34() %{
4136 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34));
4137 match(ConL);
4138 op_cost(0);
4139 format %{ %}
4140 interface(CONST_INTER);
4141 %}
4142
4143 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000.
4144 operand immLhighest16() %{
4145 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L);
4146 match(ConL);
4147 op_cost(0);
4148 format %{ %}
4149 interface(CONST_INTER);
4150 %}
4151
4152 operand immLnegpow2() %{
4153 predicate(is_power_of_2(-(julong)(n->get_long())));
4154 match(ConL);
4155 op_cost(0);
4156 format %{ %}
4157 interface(CONST_INTER);
4158 %}
4159
4160 operand immLpow2minus1() %{
4161 predicate(is_power_of_2((julong)(n->get_long()) + 1ull));
4162 match(ConL);
4163 op_cost(0);
4164 format %{ %}
4165 interface(CONST_INTER);
4166 %}
4167
4168 // constant 'long 0'.
4169 operand immL_0() %{
4170 predicate(n->get_long() == 0L);
4171 match(ConL);
4172 op_cost(0);
4173 format %{ %}
4174 interface(CONST_INTER);
4175 %}
4176
4177 // constat ' long -1'.
4178 operand immL_minus1() %{
4179 predicate(n->get_long() == -1L);
4180 match(ConL);
4181 op_cost(0);
4182 format %{ %}
4183 interface(CONST_INTER);
4184 %}
4185
4186 // Long Immediate: low 32-bit mask
4187 operand immL_32bits() %{
4188 predicate(n->get_long() == 0xFFFFFFFFL);
4189 match(ConL);
4190 op_cost(0);
4191 format %{ %}
4192 interface(CONST_INTER);
4193 %}
4194
4195 // Unsigned Long Immediate: 16-bit
4196 operand uimmL16() %{
4197 predicate(Assembler::is_uimm(n->get_long(), 16));
4198 match(ConL);
4199 op_cost(0);
4200 format %{ %}
4201 interface(CONST_INTER);
4202 %}
4203
4204 // Float Immediate
4205 operand immF() %{
4206 match(ConF);
4207 op_cost(40);
4208 format %{ %}
4209 interface(CONST_INTER);
4210 %}
4211
4212 // Float Immediate: +0.0f.
4213 operand immF_0() %{
4214 predicate(jint_cast(n->getf()) == 0);
4215 match(ConF);
4216
4217 op_cost(0);
4218 format %{ %}
4219 interface(CONST_INTER);
4220 %}
4221
4222 // Double Immediate
4223 operand immD() %{
4224 match(ConD);
4225 op_cost(40);
4226 format %{ %}
4227 interface(CONST_INTER);
4228 %}
4229
4230 // Double Immediate: +0.0d.
4231 operand immD_0() %{
4232 predicate(jlong_cast(n->getd()) == 0);
4233 match(ConD);
4234
4235 op_cost(0);
4236 format %{ %}
4237 interface(CONST_INTER);
4238 %}
4239
4240 // Integer Register Operands
4241 // Integer Destination Register
4242 // See definition of reg_class bits32_reg_rw.
4243 operand iRegIdst() %{
4244 constraint(ALLOC_IN_RC(bits32_reg_rw));
4245 match(RegI);
4246 match(rscratch1RegI);
4247 match(rscratch2RegI);
4248 match(rarg1RegI);
4249 match(rarg2RegI);
4250 match(rarg3RegI);
4251 match(rarg4RegI);
4252 format %{ %}
4253 interface(REG_INTER);
4254 %}
4255
4256 // Integer Source Register
4257 // See definition of reg_class bits32_reg_ro.
4258 operand iRegIsrc() %{
4259 constraint(ALLOC_IN_RC(bits32_reg_ro));
4260 match(RegI);
4261 match(rscratch1RegI);
4262 match(rscratch2RegI);
4263 match(rarg1RegI);
4264 match(rarg2RegI);
4265 match(rarg3RegI);
4266 match(rarg4RegI);
4267 format %{ %}
4268 interface(REG_INTER);
4269 %}
4270
4271 operand rscratch1RegI() %{
4272 constraint(ALLOC_IN_RC(rscratch1_bits32_reg));
4273 match(iRegIdst);
4274 format %{ %}
4275 interface(REG_INTER);
4276 %}
4277
4278 operand rscratch2RegI() %{
4279 constraint(ALLOC_IN_RC(rscratch2_bits32_reg));
4280 match(iRegIdst);
4281 format %{ %}
4282 interface(REG_INTER);
4283 %}
4284
4285 operand rarg1RegI() %{
4286 constraint(ALLOC_IN_RC(rarg1_bits32_reg));
4287 match(iRegIdst);
4288 format %{ %}
4289 interface(REG_INTER);
4290 %}
4291
4292 operand rarg2RegI() %{
4293 constraint(ALLOC_IN_RC(rarg2_bits32_reg));
4294 match(iRegIdst);
4295 format %{ %}
4296 interface(REG_INTER);
4297 %}
4298
4299 operand rarg3RegI() %{
4300 constraint(ALLOC_IN_RC(rarg3_bits32_reg));
4301 match(iRegIdst);
4302 format %{ %}
4303 interface(REG_INTER);
4304 %}
4305
4306 operand rarg4RegI() %{
4307 constraint(ALLOC_IN_RC(rarg4_bits32_reg));
4308 match(iRegIdst);
4309 format %{ %}
4310 interface(REG_INTER);
4311 %}
4312
4313 operand rarg1RegL() %{
4314 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4315 match(iRegLdst);
4316 format %{ %}
4317 interface(REG_INTER);
4318 %}
4319
4320 // Pointer Destination Register
4321 // See definition of reg_class bits64_reg_rw.
4322 operand iRegPdst() %{
4323 constraint(ALLOC_IN_RC(bits64_reg_rw));
4324 match(RegP);
4325 match(rscratch1RegP);
4326 match(rscratch2RegP);
4327 match(rarg1RegP);
4328 match(rarg2RegP);
4329 match(rarg3RegP);
4330 match(rarg4RegP);
4331 format %{ %}
4332 interface(REG_INTER);
4333 %}
4334
4335 // Pointer Destination Register
4336 // Operand not using r11 and r12 (killed in epilog).
4337 operand iRegPdstNoScratch() %{
4338 constraint(ALLOC_IN_RC(bits64_reg_leaf_call));
4339 match(RegP);
4340 match(rarg1RegP);
4341 match(rarg2RegP);
4342 match(rarg3RegP);
4343 match(rarg4RegP);
4344 format %{ %}
4345 interface(REG_INTER);
4346 %}
4347
4348 // Pointer Source Register
4349 // See definition of reg_class bits64_reg_ro.
4350 operand iRegPsrc() %{
4351 constraint(ALLOC_IN_RC(bits64_reg_ro));
4352 match(RegP);
4353 match(iRegPdst);
4354 match(rscratch1RegP);
4355 match(rscratch2RegP);
4356 match(rarg1RegP);
4357 match(rarg2RegP);
4358 match(rarg3RegP);
4359 match(rarg4RegP);
4360 match(rarg5RegP);
4361 match(rarg6RegP);
4362 match(threadRegP);
4363 format %{ %}
4364 interface(REG_INTER);
4365 %}
4366
4367 // Thread operand.
4368 operand threadRegP() %{
4369 constraint(ALLOC_IN_RC(thread_bits64_reg));
4370 match(iRegPdst);
4371 format %{ "R16" %}
4372 interface(REG_INTER);
4373 %}
4374
4375 operand rscratch1RegP() %{
4376 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4377 match(iRegPdst);
4378 format %{ "R11" %}
4379 interface(REG_INTER);
4380 %}
4381
4382 operand rscratch2RegP() %{
4383 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4384 match(iRegPdst);
4385 format %{ %}
4386 interface(REG_INTER);
4387 %}
4388
4389 operand rarg1RegP() %{
4390 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4391 match(iRegPdst);
4392 format %{ %}
4393 interface(REG_INTER);
4394 %}
4395
4396 operand rarg2RegP() %{
4397 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4398 match(iRegPdst);
4399 format %{ %}
4400 interface(REG_INTER);
4401 %}
4402
4403 operand rarg3RegP() %{
4404 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4405 match(iRegPdst);
4406 format %{ %}
4407 interface(REG_INTER);
4408 %}
4409
4410 operand rarg4RegP() %{
4411 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4412 match(iRegPdst);
4413 format %{ %}
4414 interface(REG_INTER);
4415 %}
4416
4417 operand rarg5RegP() %{
4418 constraint(ALLOC_IN_RC(rarg5_bits64_reg));
4419 match(iRegPdst);
4420 format %{ %}
4421 interface(REG_INTER);
4422 %}
4423
4424 operand rarg6RegP() %{
4425 constraint(ALLOC_IN_RC(rarg6_bits64_reg));
4426 match(iRegPdst);
4427 format %{ %}
4428 interface(REG_INTER);
4429 %}
4430
4431 operand iRegNsrc() %{
4432 constraint(ALLOC_IN_RC(bits32_reg_ro));
4433 match(RegN);
4434 match(iRegNdst);
4435
4436 format %{ %}
4437 interface(REG_INTER);
4438 %}
4439
4440 operand iRegNdst() %{
4441 constraint(ALLOC_IN_RC(bits32_reg_rw));
4442 match(RegN);
4443
4444 format %{ %}
4445 interface(REG_INTER);
4446 %}
4447
4448 // Long Destination Register
4449 // See definition of reg_class bits64_reg_rw.
4450 operand iRegLdst() %{
4451 constraint(ALLOC_IN_RC(bits64_reg_rw));
4452 match(RegL);
4453 match(rscratch1RegL);
4454 match(rscratch2RegL);
4455 format %{ %}
4456 interface(REG_INTER);
4457 %}
4458
4459 // Long Source Register
4460 // See definition of reg_class bits64_reg_ro.
4461 operand iRegLsrc() %{
4462 constraint(ALLOC_IN_RC(bits64_reg_ro));
4463 match(RegL);
4464 match(iRegLdst);
4465 match(rscratch1RegL);
4466 match(rscratch2RegL);
4467 format %{ %}
4468 interface(REG_INTER);
4469 %}
4470
4471 // Special operand for ConvL2I.
4472 operand iRegL2Isrc(iRegLsrc reg) %{
4473 constraint(ALLOC_IN_RC(bits64_reg_ro));
4474 match(ConvL2I reg);
4475 format %{ "ConvL2I($reg)" %}
4476 interface(REG_INTER)
4477 %}
4478
4479 operand rscratch1RegL() %{
4480 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4481 match(RegL);
4482 format %{ %}
4483 interface(REG_INTER);
4484 %}
4485
4486 operand rscratch2RegL() %{
4487 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4488 match(RegL);
4489 format %{ %}
4490 interface(REG_INTER);
4491 %}
4492
4493 // Condition Code Flag Registers
4494 operand flagsReg() %{
4495 constraint(ALLOC_IN_RC(int_flags));
4496 match(RegFlags);
4497 format %{ %}
4498 interface(REG_INTER);
4499 %}
4500
4501 operand flagsRegSrc() %{
4502 constraint(ALLOC_IN_RC(int_flags_ro));
4503 match(RegFlags);
4504 match(flagsReg);
4505 match(flagsRegCR0);
4506 format %{ %}
4507 interface(REG_INTER);
4508 %}
4509
4510 // Condition Code Flag Register CR0
4511 operand flagsRegCR0() %{
4512 constraint(ALLOC_IN_RC(int_flags_CR0));
4513 match(RegFlags);
4514 format %{ "CR0" %}
4515 interface(REG_INTER);
4516 %}
4517
4518 operand flagsRegCR1() %{
4519 constraint(ALLOC_IN_RC(int_flags_CR1));
4520 match(RegFlags);
4521 format %{ "CR1" %}
4522 interface(REG_INTER);
4523 %}
4524
4525 operand flagsRegCR6() %{
4526 constraint(ALLOC_IN_RC(int_flags_CR6));
4527 match(RegFlags);
4528 format %{ "CR6" %}
4529 interface(REG_INTER);
4530 %}
4531
4532 operand regCTR() %{
4533 constraint(ALLOC_IN_RC(ctr_reg));
4534 // RegFlags should work. Introducing a RegSpecial type would cause a
4535 // lot of changes.
4536 match(RegFlags);
4537 format %{"SR_CTR" %}
4538 interface(REG_INTER);
4539 %}
4540
4541 operand regD() %{
4542 constraint(ALLOC_IN_RC(dbl_reg));
4543 match(RegD);
4544 format %{ %}
4545 interface(REG_INTER);
4546 %}
4547
4548 operand regF() %{
4549 constraint(ALLOC_IN_RC(flt_reg));
4550 match(RegF);
4551 format %{ %}
4552 interface(REG_INTER);
4553 %}
4554
4555 // Special Registers
4556
4557 // Method Register
4558 operand inline_cache_regP(iRegPdst reg) %{
4559 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg
4560 match(reg);
4561 format %{ %}
4562 interface(REG_INTER);
4563 %}
4564
4565 // Operands to remove register moves in unscaled mode.
4566 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4567 operand iRegP2N(iRegPsrc reg) %{
4568 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0);
4569 constraint(ALLOC_IN_RC(bits64_reg_ro));
4570 match(EncodeP reg);
4571 format %{ "$reg" %}
4572 interface(REG_INTER)
4573 %}
4574
4575 operand iRegN2P(iRegNsrc reg) %{
4576 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4577 constraint(ALLOC_IN_RC(bits32_reg_ro));
4578 match(DecodeN reg);
4579 format %{ "$reg" %}
4580 interface(REG_INTER)
4581 %}
4582
4583 operand iRegN2P_klass(iRegNsrc reg) %{
4584 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4585 constraint(ALLOC_IN_RC(bits32_reg_ro));
4586 match(DecodeNKlass reg);
4587 format %{ "$reg" %}
4588 interface(REG_INTER)
4589 %}
4590
4591 //----------Complex Operands---------------------------------------------------
4592 // Indirect Memory Reference
4593 operand indirect(iRegPsrc reg) %{
4594 constraint(ALLOC_IN_RC(bits64_reg_ro));
4595 match(reg);
4596 op_cost(100);
4597 format %{ "[$reg]" %}
4598 interface(MEMORY_INTER) %{
4599 base($reg);
4600 index(0x0);
4601 scale(0x0);
4602 disp(0x0);
4603 %}
4604 %}
4605
4606 // Indirect with Offset
4607 operand indOffset16(iRegPsrc reg, immL16 offset) %{
4608 constraint(ALLOC_IN_RC(bits64_reg_ro));
4609 match(AddP reg offset);
4610 op_cost(100);
4611 format %{ "[$reg + $offset]" %}
4612 interface(MEMORY_INTER) %{
4613 base($reg);
4614 index(0x0);
4615 scale(0x0);
4616 disp($offset);
4617 %}
4618 %}
4619
4620 // Indirect with 4-aligned Offset
4621 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{
4622 constraint(ALLOC_IN_RC(bits64_reg_ro));
4623 match(AddP reg offset);
4624 op_cost(100);
4625 format %{ "[$reg + $offset]" %}
4626 interface(MEMORY_INTER) %{
4627 base($reg);
4628 index(0x0);
4629 scale(0x0);
4630 disp($offset);
4631 %}
4632 %}
4633
4634 // Indirect with 16-aligned Offset
4635 operand indOffset16Alg16(iRegPsrc reg, immL16Alg16 offset) %{
4636 constraint(ALLOC_IN_RC(bits64_reg_ro));
4637 match(AddP reg offset);
4638 op_cost(100);
4639 format %{ "[$reg + $offset]" %}
4640 interface(MEMORY_INTER) %{
4641 base($reg);
4642 index(0x0);
4643 scale(0x0);
4644 disp($offset);
4645 %}
4646 %}
4647
4648 //----------Complex Operands for Compressed OOPs-------------------------------
4649 // Compressed OOPs with narrow_oop_shift == 0.
4650
4651 // Indirect Memory Reference, compressed OOP
4652 operand indirectNarrow(iRegNsrc reg) %{
4653 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4654 constraint(ALLOC_IN_RC(bits64_reg_ro));
4655 match(DecodeN reg);
4656 op_cost(100);
4657 format %{ "[$reg]" %}
4658 interface(MEMORY_INTER) %{
4659 base($reg);
4660 index(0x0);
4661 scale(0x0);
4662 disp(0x0);
4663 %}
4664 %}
4665
4666 operand indirectNarrow_klass(iRegNsrc reg) %{
4667 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4668 constraint(ALLOC_IN_RC(bits64_reg_ro));
4669 match(DecodeNKlass reg);
4670 op_cost(100);
4671 format %{ "[$reg]" %}
4672 interface(MEMORY_INTER) %{
4673 base($reg);
4674 index(0x0);
4675 scale(0x0);
4676 disp(0x0);
4677 %}
4678 %}
4679
4680 // Indirect with Offset, compressed OOP
4681 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4682 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4683 constraint(ALLOC_IN_RC(bits64_reg_ro));
4684 match(AddP (DecodeN reg) offset);
4685 op_cost(100);
4686 format %{ "[$reg + $offset]" %}
4687 interface(MEMORY_INTER) %{
4688 base($reg);
4689 index(0x0);
4690 scale(0x0);
4691 disp($offset);
4692 %}
4693 %}
4694
4695 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4696 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4697 constraint(ALLOC_IN_RC(bits64_reg_ro));
4698 match(AddP (DecodeNKlass reg) offset);
4699 op_cost(100);
4700 format %{ "[$reg + $offset]" %}
4701 interface(MEMORY_INTER) %{
4702 base($reg);
4703 index(0x0);
4704 scale(0x0);
4705 disp($offset);
4706 %}
4707 %}
4708
4709 // Indirect with 4-aligned Offset, compressed OOP
4710 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4711 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4712 constraint(ALLOC_IN_RC(bits64_reg_ro));
4713 match(AddP (DecodeN reg) offset);
4714 op_cost(100);
4715 format %{ "[$reg + $offset]" %}
4716 interface(MEMORY_INTER) %{
4717 base($reg);
4718 index(0x0);
4719 scale(0x0);
4720 disp($offset);
4721 %}
4722 %}
4723
4724 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4725 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4726 constraint(ALLOC_IN_RC(bits64_reg_ro));
4727 match(AddP (DecodeNKlass reg) offset);
4728 op_cost(100);
4729 format %{ "[$reg + $offset]" %}
4730 interface(MEMORY_INTER) %{
4731 base($reg);
4732 index(0x0);
4733 scale(0x0);
4734 disp($offset);
4735 %}
4736 %}
4737
4738 //----------Special Memory Operands--------------------------------------------
4739 // Stack Slot Operand
4740 //
4741 // This operand is used for loading and storing temporary values on
4742 // the stack where a match requires a value to flow through memory.
4743 operand stackSlotI(sRegI reg) %{
4744 constraint(ALLOC_IN_RC(stack_slots));
4745 op_cost(100);
4746 //match(RegI);
4747 format %{ "[sp+$reg]" %}
4748 interface(MEMORY_INTER) %{
4749 base(0x1); // R1_SP
4750 index(0x0);
4751 scale(0x0);
4752 disp($reg); // Stack Offset
4753 %}
4754 %}
4755
4756 operand stackSlotL(sRegL reg) %{
4757 constraint(ALLOC_IN_RC(stack_slots));
4758 op_cost(100);
4759 //match(RegL);
4760 format %{ "[sp+$reg]" %}
4761 interface(MEMORY_INTER) %{
4762 base(0x1); // R1_SP
4763 index(0x0);
4764 scale(0x0);
4765 disp($reg); // Stack Offset
4766 %}
4767 %}
4768
4769 operand stackSlotP(sRegP reg) %{
4770 constraint(ALLOC_IN_RC(stack_slots));
4771 op_cost(100);
4772 //match(RegP);
4773 format %{ "[sp+$reg]" %}
4774 interface(MEMORY_INTER) %{
4775 base(0x1); // R1_SP
4776 index(0x0);
4777 scale(0x0);
4778 disp($reg); // Stack Offset
4779 %}
4780 %}
4781
4782 operand stackSlotF(sRegF reg) %{
4783 constraint(ALLOC_IN_RC(stack_slots));
4784 op_cost(100);
4785 //match(RegF);
4786 format %{ "[sp+$reg]" %}
4787 interface(MEMORY_INTER) %{
4788 base(0x1); // R1_SP
4789 index(0x0);
4790 scale(0x0);
4791 disp($reg); // Stack Offset
4792 %}
4793 %}
4794
4795 operand stackSlotD(sRegD reg) %{
4796 constraint(ALLOC_IN_RC(stack_slots));
4797 op_cost(100);
4798 //match(RegD);
4799 format %{ "[sp+$reg]" %}
4800 interface(MEMORY_INTER) %{
4801 base(0x1); // R1_SP
4802 index(0x0);
4803 scale(0x0);
4804 disp($reg); // Stack Offset
4805 %}
4806 %}
4807
4808 // Operands for expressing Control Flow
4809 // NOTE: Label is a predefined operand which should not be redefined in
4810 // the AD file. It is generically handled within the ADLC.
4811
4812 //----------Conditional Branch Operands----------------------------------------
4813 // Comparison Op
4814 //
4815 // This is the operation of the comparison, and is limited to the
4816 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE
4817 // (!=).
4818 //
4819 // Other attributes of the comparison, such as unsignedness, are specified
4820 // by the comparison instruction that sets a condition code flags register.
4821 // That result is represented by a flags operand whose subtype is appropriate
4822 // to the unsignedness (etc.) of the comparison.
4823 //
4824 // Later, the instruction which matches both the Comparison Op (a Bool) and
4825 // the flags (produced by the Cmp) specifies the coding of the comparison op
4826 // by matching a specific subtype of Bool operand below.
4827
4828 // When used for floating point comparisons: unordered same as less.
4829 operand cmpOp() %{
4830 match(Bool);
4831 format %{ "" %}
4832 interface(COND_INTER) %{
4833 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'.
4834 // BO & BI
4835 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4836 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4837 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4838 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4839 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4840 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4841 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4842 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4843 %}
4844 %}
4845
4846 //----------OPERAND CLASSES----------------------------------------------------
4847 // Operand Classes are groups of operands that are used to simplify
4848 // instruction definitions by not requiring the AD writer to specify
4849 // separate instructions for every form of operand when the
4850 // instruction accepts multiple operand types with the same basic
4851 // encoding and format. The classic case of this is memory operands.
4852 // Indirect is not included since its use is limited to Compare & Swap.
4853
4854 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4855 // Memory operand where offsets are 4-aligned. Required for ld, std.
4856 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4857 opclass memoryAlg16(indirect, indOffset16Alg16);
4858 opclass indirectMemory(indirect, indirectNarrow);
4859
4860 // Special opclass for I and ConvL2I.
4861 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4862
4863 // Operand classes to match encode and decode. iRegN_P2N is only used
4864 // for storeN. I have never seen an encode node elsewhere.
4865 opclass iRegN_P2N(iRegNsrc, iRegP2N);
4866 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4867
4868 //----------PIPELINE-----------------------------------------------------------
4869
4870 pipeline %{
4871
4872 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4873 // J. Res. & Dev., No. 1, Jan. 2002.
4874
4875 //----------ATTRIBUTES---------------------------------------------------------
4876 attributes %{
4877
4878 // Power4 instructions are of fixed length.
4879 fixed_size_instructions;
4880
4881 // TODO: if `bundle' means number of instructions fetched
4882 // per cycle, this is 8. If `bundle' means Power4 `group', that is
4883 // max instructions issued per cycle, this is 5.
4884 max_instructions_per_bundle = 8;
4885
4886 // A Power4 instruction is 4 bytes long.
4887 instruction_unit_size = 4;
4888
4889 // The Power4 processor fetches 64 bytes...
4890 instruction_fetch_unit_size = 64;
4891
4892 // ...in one line
4893 instruction_fetch_units = 1
4894 %}
4895
4896 //----------RESOURCES----------------------------------------------------------
4897 // Resources are the functional units available to the machine
4898 resources(
4899 PPC_BR, // branch unit
4900 PPC_CR, // condition unit
4901 PPC_FX1, // integer arithmetic unit 1
4902 PPC_FX2, // integer arithmetic unit 2
4903 PPC_LDST1, // load/store unit 1
4904 PPC_LDST2, // load/store unit 2
4905 PPC_FP1, // float arithmetic unit 1
4906 PPC_FP2, // float arithmetic unit 2
4907 PPC_LDST = PPC_LDST1 | PPC_LDST2,
4908 PPC_FX = PPC_FX1 | PPC_FX2,
4909 PPC_FP = PPC_FP1 | PPC_FP2
4910 );
4911
4912 //----------PIPELINE DESCRIPTION-----------------------------------------------
4913 // Pipeline Description specifies the stages in the machine's pipeline
4914 pipe_desc(
4915 // Power4 longest pipeline path
4916 PPC_IF, // instruction fetch
4917 PPC_IC,
4918 //PPC_BP, // branch prediction
4919 PPC_D0, // decode
4920 PPC_D1, // decode
4921 PPC_D2, // decode
4922 PPC_D3, // decode
4923 PPC_Xfer1,
4924 PPC_GD, // group definition
4925 PPC_MP, // map
4926 PPC_ISS, // issue
4927 PPC_RF, // resource fetch
4928 PPC_EX1, // execute (all units)
4929 PPC_EX2, // execute (FP, LDST)
4930 PPC_EX3, // execute (FP, LDST)
4931 PPC_EX4, // execute (FP)
4932 PPC_EX5, // execute (FP)
4933 PPC_EX6, // execute (FP)
4934 PPC_WB, // write back
4935 PPC_Xfer2,
4936 PPC_CP
4937 );
4938
4939 //----------PIPELINE CLASSES---------------------------------------------------
4940 // Pipeline Classes describe the stages in which input and output are
4941 // referenced by the hardware pipeline.
4942
4943 // Simple pipeline classes.
4944
4945 // Default pipeline class.
4946 pipe_class pipe_class_default() %{
4947 single_instruction;
4948 fixed_latency(2);
4949 %}
4950
4951 // Pipeline class for empty instructions.
4952 pipe_class pipe_class_empty() %{
4953 single_instruction;
4954 fixed_latency(0);
4955 %}
4956
4957 // Pipeline class for compares.
4958 pipe_class pipe_class_compare() %{
4959 single_instruction;
4960 fixed_latency(16);
4961 %}
4962
4963 // Pipeline class for traps.
4964 pipe_class pipe_class_trap() %{
4965 single_instruction;
4966 fixed_latency(100);
4967 %}
4968
4969 // Pipeline class for memory operations.
4970 pipe_class pipe_class_memory() %{
4971 single_instruction;
4972 fixed_latency(16);
4973 %}
4974
4975 // Pipeline class for call.
4976 pipe_class pipe_class_call() %{
4977 single_instruction;
4978 fixed_latency(100);
4979 %}
4980
4981 // Define the class for the Nop node.
4982 define %{
4983 MachNop = pipe_class_default;
4984 %}
4985
4986 %}
4987
4988 //----------INSTRUCTIONS-------------------------------------------------------
4989
4990 // Naming of instructions:
4991 // opA_operB / opA_operB_operC:
4992 // Operation 'op' with one or two source operands 'oper'. Result
4993 // type is A, source operand types are B and C.
4994 // Iff A == B == C, B and C are left out.
4995 //
4996 // The instructions are ordered according to the following scheme:
4997 // - loads
4998 // - load constants
4999 // - prefetch
5000 // - store
5001 // - encode/decode
5002 // - membar
5003 // - conditional moves
5004 // - compare & swap
5005 // - arithmetic and logic operations
5006 // * int: Add, Sub, Mul, Div, Mod
5007 // * int: lShift, arShift, urShift, rot
5008 // * float: Add, Sub, Mul, Div
5009 // * and, or, xor ...
5010 // - register moves: float <-> int, reg <-> stack, repl
5011 // - cast (high level type cast, XtoP, castPP, castII, not_null etc.
5012 // - conv (low level type cast requiring bit changes (sign extend etc)
5013 // - compares, range & zero checks.
5014 // - branches
5015 // - complex operations, intrinsics, min, max, replicate
5016 // - lock
5017 // - Calls
5018 //
5019 // If there are similar instructions with different types they are sorted:
5020 // int before float
5021 // small before big
5022 // signed before unsigned
5023 // e.g., loadS before loadUS before loadI before loadF.
5024
5025
5026 //----------Load/Store Instructions--------------------------------------------
5027
5028 //----------Load Instructions--------------------------------------------------
5029
5030 // Converts byte to int.
5031 // As convB2I_reg, but without match rule. The match rule of convB2I_reg
5032 // reuses the 'amount' operand, but adlc expects that operand specification
5033 // and operands in match rule are equivalent.
5034 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
5035 effect(DEF dst, USE src);
5036 format %{ "EXTSB $dst, $src \t// byte->int" %}
5037 size(4);
5038 ins_encode %{
5039 __ extsb($dst$$Register, $src$$Register);
5040 %}
5041 ins_pipe(pipe_class_default);
5042 %}
5043
5044 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{
5045 // match-rule, false predicate
5046 match(Set dst (LoadB mem));
5047 predicate(false);
5048
5049 format %{ "LBZ $dst, $mem" %}
5050 size(4);
5051 ins_encode( enc_lbz(dst, mem) );
5052 ins_pipe(pipe_class_memory);
5053 %}
5054
5055 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{
5056 // match-rule, false predicate
5057 match(Set dst (LoadB mem));
5058 predicate(false);
5059
5060 format %{ "LBZ $dst, $mem\n\t"
5061 "TWI $dst\n\t"
5062 "ISYNC" %}
5063 size(12);
5064 ins_encode( enc_lbz_ac(dst, mem) );
5065 ins_pipe(pipe_class_memory);
5066 %}
5067
5068 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
5069 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{
5070 match(Set dst (LoadB mem));
5071 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5072 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5073 expand %{
5074 iRegIdst tmp;
5075 loadUB_indirect(tmp, mem);
5076 convB2I_reg_2(dst, tmp);
5077 %}
5078 %}
5079
5080 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{
5081 match(Set dst (LoadB mem));
5082 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
5083 expand %{
5084 iRegIdst tmp;
5085 loadUB_indirect_ac(tmp, mem);
5086 convB2I_reg_2(dst, tmp);
5087 %}
5088 %}
5089
5090 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{
5091 // match-rule, false predicate
5092 match(Set dst (LoadB mem));
5093 predicate(false);
5094
5095 format %{ "LBZ $dst, $mem" %}
5096 size(4);
5097 ins_encode( enc_lbz(dst, mem) );
5098 ins_pipe(pipe_class_memory);
5099 %}
5100
5101 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{
5102 // match-rule, false predicate
5103 match(Set dst (LoadB mem));
5104 predicate(false);
5105
5106 format %{ "LBZ $dst, $mem\n\t"
5107 "TWI $dst\n\t"
5108 "ISYNC" %}
5109 size(12);
5110 ins_encode( enc_lbz_ac(dst, mem) );
5111 ins_pipe(pipe_class_memory);
5112 %}
5113
5114 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
5115 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{
5116 match(Set dst (LoadB mem));
5117 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5118 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5119
5120 expand %{
5121 iRegIdst tmp;
5122 loadUB_indOffset16(tmp, mem);
5123 convB2I_reg_2(dst, tmp);
5124 %}
5125 %}
5126
5127 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{
5128 match(Set dst (LoadB mem));
5129 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
5130
5131 expand %{
5132 iRegIdst tmp;
5133 loadUB_indOffset16_ac(tmp, mem);
5134 convB2I_reg_2(dst, tmp);
5135 %}
5136 %}
5137
5138 // Load Unsigned Byte (8bit UNsigned) into an int reg.
5139 instruct loadUB(iRegIdst dst, memory mem) %{
5140 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5141 match(Set dst (LoadUB mem));
5142 ins_cost(MEMORY_REF_COST);
5143
5144 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %}
5145 size(4);
5146 ins_encode( enc_lbz(dst, mem) );
5147 ins_pipe(pipe_class_memory);
5148 %}
5149
5150 // Load Unsigned Byte (8bit UNsigned) acquire.
5151 instruct loadUB_ac(iRegIdst dst, memory mem) %{
5152 match(Set dst (LoadUB mem));
5153 ins_cost(3*MEMORY_REF_COST);
5154
5155 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t"
5156 "TWI $dst\n\t"
5157 "ISYNC" %}
5158 size(12);
5159 ins_encode( enc_lbz_ac(dst, mem) );
5160 ins_pipe(pipe_class_memory);
5161 %}
5162
5163 // Load Unsigned Byte (8bit UNsigned) into a Long Register.
5164 instruct loadUB2L(iRegLdst dst, memory mem) %{
5165 match(Set dst (ConvI2L (LoadUB mem)));
5166 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5167 ins_cost(MEMORY_REF_COST);
5168
5169 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %}
5170 size(4);
5171 ins_encode( enc_lbz(dst, mem) );
5172 ins_pipe(pipe_class_memory);
5173 %}
5174
5175 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{
5176 match(Set dst (ConvI2L (LoadUB mem)));
5177 ins_cost(3*MEMORY_REF_COST);
5178
5179 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t"
5180 "TWI $dst\n\t"
5181 "ISYNC" %}
5182 size(12);
5183 ins_encode( enc_lbz_ac(dst, mem) );
5184 ins_pipe(pipe_class_memory);
5185 %}
5186
5187 // Load Short (16bit signed)
5188 instruct loadS(iRegIdst dst, memory mem) %{
5189 match(Set dst (LoadS mem));
5190 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5191 ins_cost(MEMORY_REF_COST);
5192
5193 format %{ "LHA $dst, $mem" %}
5194 size(4);
5195 ins_encode %{
5196 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5197 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
5198 %}
5199 ins_pipe(pipe_class_memory);
5200 %}
5201
5202 // Load Short (16bit signed) acquire.
5203 instruct loadS_ac(iRegIdst dst, memory mem) %{
5204 match(Set dst (LoadS mem));
5205 ins_cost(3*MEMORY_REF_COST);
5206
5207 format %{ "LHA $dst, $mem\t acquire\n\t"
5208 "TWI $dst\n\t"
5209 "ISYNC" %}
5210 size(12);
5211 ins_encode %{
5212 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5213 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
5214 __ twi_0($dst$$Register);
5215 __ isync();
5216 %}
5217 ins_pipe(pipe_class_memory);
5218 %}
5219
5220 // Load Char (16bit unsigned)
5221 instruct loadUS(iRegIdst dst, memory mem) %{
5222 match(Set dst (LoadUS mem));
5223 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5224 ins_cost(MEMORY_REF_COST);
5225
5226 format %{ "LHZ $dst, $mem" %}
5227 size(4);
5228 ins_encode( enc_lhz(dst, mem) );
5229 ins_pipe(pipe_class_memory);
5230 %}
5231
5232 // Load Char (16bit unsigned) acquire.
5233 instruct loadUS_ac(iRegIdst dst, memory mem) %{
5234 match(Set dst (LoadUS mem));
5235 ins_cost(3*MEMORY_REF_COST);
5236
5237 format %{ "LHZ $dst, $mem \t// acquire\n\t"
5238 "TWI $dst\n\t"
5239 "ISYNC" %}
5240 size(12);
5241 ins_encode( enc_lhz_ac(dst, mem) );
5242 ins_pipe(pipe_class_memory);
5243 %}
5244
5245 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register.
5246 instruct loadUS2L(iRegLdst dst, memory mem) %{
5247 match(Set dst (ConvI2L (LoadUS mem)));
5248 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5249 ins_cost(MEMORY_REF_COST);
5250
5251 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %}
5252 size(4);
5253 ins_encode( enc_lhz(dst, mem) );
5254 ins_pipe(pipe_class_memory);
5255 %}
5256
5257 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire.
5258 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{
5259 match(Set dst (ConvI2L (LoadUS mem)));
5260 ins_cost(3*MEMORY_REF_COST);
5261
5262 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t"
5263 "TWI $dst\n\t"
5264 "ISYNC" %}
5265 size(12);
5266 ins_encode( enc_lhz_ac(dst, mem) );
5267 ins_pipe(pipe_class_memory);
5268 %}
5269
5270 // Load Integer.
5271 instruct loadI(iRegIdst dst, memory mem) %{
5272 match(Set dst (LoadI mem));
5273 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5274 ins_cost(MEMORY_REF_COST);
5275
5276 format %{ "LWZ $dst, $mem" %}
5277 size(4);
5278 ins_encode( enc_lwz(dst, mem) );
5279 ins_pipe(pipe_class_memory);
5280 %}
5281
5282 // Load Integer acquire.
5283 instruct loadI_ac(iRegIdst dst, memory mem) %{
5284 match(Set dst (LoadI mem));
5285 ins_cost(3*MEMORY_REF_COST);
5286
5287 format %{ "LWZ $dst, $mem \t// load acquire\n\t"
5288 "TWI $dst\n\t"
5289 "ISYNC" %}
5290 size(12);
5291 ins_encode( enc_lwz_ac(dst, mem) );
5292 ins_pipe(pipe_class_memory);
5293 %}
5294
5295 // Match loading integer and casting it to unsigned int in
5296 // long register.
5297 // LoadI + ConvI2L + AndL 0xffffffff.
5298 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
5299 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5300 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered());
5301 ins_cost(MEMORY_REF_COST);
5302
5303 format %{ "LWZ $dst, $mem \t// zero-extend to long" %}
5304 size(4);
5305 ins_encode( enc_lwz(dst, mem) );
5306 ins_pipe(pipe_class_memory);
5307 %}
5308
5309 // Match loading integer and casting it to long.
5310 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
5311 match(Set dst (ConvI2L (LoadI mem)));
5312 predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5313 ins_cost(MEMORY_REF_COST);
5314
5315 format %{ "LWA $dst, $mem \t// loadI2L" %}
5316 size(4);
5317 ins_encode %{
5318 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5319 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5320 %}
5321 ins_pipe(pipe_class_memory);
5322 %}
5323
5324 // Match loading integer and casting it to long - acquire.
5325 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
5326 match(Set dst (ConvI2L (LoadI mem)));
5327 ins_cost(3*MEMORY_REF_COST);
5328
5329 format %{ "LWA $dst, $mem \t// loadI2L acquire"
5330 "TWI $dst\n\t"
5331 "ISYNC" %}
5332 size(12);
5333 ins_encode %{
5334 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5335 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5336 __ twi_0($dst$$Register);
5337 __ isync();
5338 %}
5339 ins_pipe(pipe_class_memory);
5340 %}
5341
5342 // Load Long - aligned
5343 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{
5344 match(Set dst (LoadL mem));
5345 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5346 ins_cost(MEMORY_REF_COST);
5347
5348 format %{ "LD $dst, $mem \t// long" %}
5349 size(4);
5350 ins_encode( enc_ld(dst, mem) );
5351 ins_pipe(pipe_class_memory);
5352 %}
5353
5354 // Load Long - aligned acquire.
5355 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{
5356 match(Set dst (LoadL mem));
5357 ins_cost(3*MEMORY_REF_COST);
5358
5359 format %{ "LD $dst, $mem \t// long acquire\n\t"
5360 "TWI $dst\n\t"
5361 "ISYNC" %}
5362 size(12);
5363 ins_encode( enc_ld_ac(dst, mem) );
5364 ins_pipe(pipe_class_memory);
5365 %}
5366
5367 // Load Long - UNaligned
5368 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{
5369 match(Set dst (LoadL_unaligned mem));
5370 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5371 ins_cost(MEMORY_REF_COST);
5372
5373 format %{ "LD $dst, $mem \t// unaligned long" %}
5374 size(4);
5375 ins_encode( enc_ld(dst, mem) );
5376 ins_pipe(pipe_class_memory);
5377 %}
5378
5379 // Load nodes for superwords
5380
5381 // Load Aligned Packed Byte
5382 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{
5383 predicate(n->as_LoadVector()->memory_size() == 8);
5384 match(Set dst (LoadVector mem));
5385 ins_cost(MEMORY_REF_COST);
5386
5387 format %{ "LD $dst, $mem \t// load 8-byte Vector" %}
5388 size(4);
5389 ins_encode( enc_ld(dst, mem) );
5390 ins_pipe(pipe_class_memory);
5391 %}
5392
5393
5394 instruct loadV16(vecX dst, memoryAlg16 mem) %{
5395 predicate(n->as_LoadVector()->memory_size() == 16);
5396 match(Set dst (LoadVector mem));
5397 ins_cost(MEMORY_REF_COST);
5398
5399 format %{ "LXV $dst, $mem \t// load 16-byte Vector" %}
5400 size(4);
5401 ins_encode %{
5402 __ lxv($dst$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
5403 %}
5404 ins_pipe(pipe_class_default);
5405 %}
5406
5407 // Load Range, range = array length (=jint)
5408 instruct loadRange(iRegIdst dst, memory mem) %{
5409 match(Set dst (LoadRange mem));
5410 ins_cost(MEMORY_REF_COST);
5411
5412 format %{ "LWZ $dst, $mem \t// range" %}
5413 size(4);
5414 ins_encode( enc_lwz(dst, mem) );
5415 ins_pipe(pipe_class_memory);
5416 %}
5417
5418 // Load Compressed Pointer
5419 instruct loadN(iRegNdst dst, memory mem) %{
5420 match(Set dst (LoadN mem));
5421 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5422 ins_cost(MEMORY_REF_COST);
5423
5424 format %{ "LWZ $dst, $mem \t// load compressed ptr" %}
5425 size(4);
5426 ins_encode( enc_lwz(dst, mem) );
5427 ins_pipe(pipe_class_memory);
5428 %}
5429
5430 // Load Compressed Pointer acquire.
5431 instruct loadN_ac(iRegNdst dst, memory mem) %{
5432 match(Set dst (LoadN mem));
5433 predicate(n->as_Load()->barrier_data() == 0);
5434 ins_cost(3*MEMORY_REF_COST);
5435
5436 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5437 "TWI $dst\n\t"
5438 "ISYNC" %}
5439 size(12);
5440 ins_encode( enc_lwz_ac(dst, mem) );
5441 ins_pipe(pipe_class_memory);
5442 %}
5443
5444 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5445 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5446 match(Set dst (DecodeN (LoadN mem)));
5447 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0 && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5448 ins_cost(MEMORY_REF_COST);
5449
5450 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5451 size(4);
5452 ins_encode( enc_lwz(dst, mem) );
5453 ins_pipe(pipe_class_memory);
5454 %}
5455
5456 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5457 match(Set dst (DecodeNKlass (LoadNKlass mem)));
5458 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0 &&
5459 _kids[0]->_leaf->as_Load()->is_unordered());
5460 ins_cost(MEMORY_REF_COST);
5461
5462 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5463 size(4);
5464 ins_encode( enc_lwz(dst, mem) );
5465 ins_pipe(pipe_class_memory);
5466 %}
5467
5468 // Load Pointer
5469 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5470 match(Set dst (LoadP mem));
5471 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5472 ins_cost(MEMORY_REF_COST);
5473
5474 format %{ "LD $dst, $mem \t// ptr" %}
5475 size(4);
5476 ins_encode( enc_ld(dst, mem) );
5477 ins_pipe(pipe_class_memory);
5478 %}
5479
5480 // Load Pointer acquire.
5481 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5482 match(Set dst (LoadP mem));
5483 ins_cost(3*MEMORY_REF_COST);
5484
5485 predicate(n->as_Load()->barrier_data() == 0);
5486
5487 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5488 "TWI $dst\n\t"
5489 "ISYNC" %}
5490 size(12);
5491 ins_encode( enc_ld_ac(dst, mem) );
5492 ins_pipe(pipe_class_memory);
5493 %}
5494
5495 // LoadP + CastP2L
5496 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
5497 match(Set dst (CastP2X (LoadP mem)));
5498 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5499 ins_cost(MEMORY_REF_COST);
5500
5501 format %{ "LD $dst, $mem \t// ptr + p2x" %}
5502 size(4);
5503 ins_encode( enc_ld(dst, mem) );
5504 ins_pipe(pipe_class_memory);
5505 %}
5506
5507 // Load compressed klass pointer.
5508 instruct loadNKlass(iRegNdst dst, memory mem) %{
5509 match(Set dst (LoadNKlass mem));
5510 predicate(!UseCompactObjectHeaders);
5511 ins_cost(MEMORY_REF_COST);
5512
5513 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %}
5514 size(4);
5515 ins_encode( enc_lwz(dst, mem) );
5516 ins_pipe(pipe_class_memory);
5517 %}
5518
5519 instruct loadNKlassCompactHeaders(iRegNdst dst, memory mem) %{
5520 match(Set dst (LoadNKlass mem));
5521 predicate(UseCompactObjectHeaders);
5522 ins_cost(MEMORY_REF_COST);
5523
5524 format %{ "load_narrow_klass_compact $dst, $mem \t// compressed class ptr" %}
5525 size(8);
5526 ins_encode %{
5527 assert($mem$$index$$Register == R0, "must not have indexed address: %s[%s]", $mem$$base$$Register.name(), $mem$$index$$Register.name());
5528 __ load_narrow_klass_compact_c2($dst$$Register, $mem$$base$$Register, $mem$$disp);
5529 %}
5530 ins_pipe(pipe_class_memory);
5531 %}
5532
5533 // Load Klass Pointer
5534 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
5535 match(Set dst (LoadKlass mem));
5536 ins_cost(MEMORY_REF_COST);
5537
5538 format %{ "LD $dst, $mem \t// klass ptr" %}
5539 size(4);
5540 ins_encode( enc_ld(dst, mem) );
5541 ins_pipe(pipe_class_memory);
5542 %}
5543
5544 // Load Float
5545 instruct loadF(regF dst, memory mem) %{
5546 match(Set dst (LoadF mem));
5547 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5548 ins_cost(MEMORY_REF_COST);
5549
5550 format %{ "LFS $dst, $mem" %}
5551 size(4);
5552 ins_encode %{
5553 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5554 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5555 %}
5556 ins_pipe(pipe_class_memory);
5557 %}
5558
5559 // Load Float acquire.
5560 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5561 match(Set dst (LoadF mem));
5562 effect(TEMP cr0);
5563 ins_cost(3*MEMORY_REF_COST);
5564
5565 format %{ "LFS $dst, $mem \t// acquire\n\t"
5566 "FCMPU cr0, $dst, $dst\n\t"
5567 "BNE cr0, next\n"
5568 "next:\n\t"
5569 "ISYNC" %}
5570 size(16);
5571 ins_encode %{
5572 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5573 Label next;
5574 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5575 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5576 __ bne(CR0, next);
5577 __ bind(next);
5578 __ isync();
5579 %}
5580 ins_pipe(pipe_class_memory);
5581 %}
5582
5583 // Load Double - aligned
5584 instruct loadD(regD dst, memory mem) %{
5585 match(Set dst (LoadD mem));
5586 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5587 ins_cost(MEMORY_REF_COST);
5588
5589 format %{ "LFD $dst, $mem" %}
5590 size(4);
5591 ins_encode( enc_lfd(dst, mem) );
5592 ins_pipe(pipe_class_memory);
5593 %}
5594
5595 // Load Double - aligned acquire.
5596 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5597 match(Set dst (LoadD mem));
5598 effect(TEMP cr0);
5599 ins_cost(3*MEMORY_REF_COST);
5600
5601 format %{ "LFD $dst, $mem \t// acquire\n\t"
5602 "FCMPU cr0, $dst, $dst\n\t"
5603 "BNE cr0, next\n"
5604 "next:\n\t"
5605 "ISYNC" %}
5606 size(16);
5607 ins_encode %{
5608 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5609 Label next;
5610 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5611 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5612 __ bne(CR0, next);
5613 __ bind(next);
5614 __ isync();
5615 %}
5616 ins_pipe(pipe_class_memory);
5617 %}
5618
5619 // Load Double - UNaligned
5620 instruct loadD_unaligned(regD dst, memory mem) %{
5621 match(Set dst (LoadD_unaligned mem));
5622 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5623 ins_cost(MEMORY_REF_COST);
5624
5625 format %{ "LFD $dst, $mem" %}
5626 size(4);
5627 ins_encode( enc_lfd(dst, mem) );
5628 ins_pipe(pipe_class_memory);
5629 %}
5630
5631 //----------Constants--------------------------------------------------------
5632
5633 // Load MachConstantTableBase: add hi offset to global toc.
5634 // TODO: Handle hidden register r29 in bundler!
5635 instruct loadToc_hi(iRegLdst dst) %{
5636 effect(DEF dst);
5637 ins_cost(DEFAULT_COST);
5638
5639 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %}
5640 size(4);
5641 ins_encode %{
5642 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
5643 %}
5644 ins_pipe(pipe_class_default);
5645 %}
5646
5647 // Load MachConstantTableBase: add lo offset to global toc.
5648 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
5649 effect(DEF dst, USE src);
5650 ins_cost(DEFAULT_COST);
5651
5652 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %}
5653 size(4);
5654 ins_encode %{
5655 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
5656 %}
5657 ins_pipe(pipe_class_default);
5658 %}
5659
5660 // Load 16-bit integer constant 0xssss????
5661 instruct loadConI16(iRegIdst dst, immI16 src) %{
5662 match(Set dst src);
5663
5664 format %{ "LI $dst, $src" %}
5665 size(4);
5666 ins_encode %{
5667 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5668 %}
5669 ins_pipe(pipe_class_default);
5670 %}
5671
5672 // Load integer constant 0x????0000
5673 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
5674 match(Set dst src);
5675 ins_cost(DEFAULT_COST);
5676
5677 format %{ "LIS $dst, $src.hi" %}
5678 size(4);
5679 ins_encode %{
5680 // Lis sign extends 16-bit src then shifts it 16 bit to the left.
5681 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5682 %}
5683 ins_pipe(pipe_class_default);
5684 %}
5685
5686 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted
5687 // and sign extended), this adds the low 16 bits.
5688 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
5689 // no match-rule, false predicate
5690 effect(DEF dst, USE src1, USE src2);
5691 predicate(false);
5692
5693 format %{ "ORI $dst, $src1.hi, $src2.lo" %}
5694 size(4);
5695 ins_encode %{
5696 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5697 %}
5698 ins_pipe(pipe_class_default);
5699 %}
5700
5701 instruct loadConI32(iRegIdst dst, immI32 src) %{
5702 match(Set dst src);
5703 // This macro is valid only in Power 10 and up, but adding the following predicate here
5704 // caused a build error, so we comment it out for now.
5705 // predicate(PowerArchitecturePPC64 >= 10);
5706 ins_cost(DEFAULT_COST+1);
5707
5708 format %{ "PLI $dst, $src" %}
5709 size(8);
5710 ins_encode %{
5711 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5712 __ pli($dst$$Register, $src$$constant);
5713 %}
5714 ins_pipe(pipe_class_default);
5715 ins_alignment(2);
5716 %}
5717
5718 instruct loadConI_Ex(iRegIdst dst, immI src) %{
5719 match(Set dst src);
5720 ins_cost(DEFAULT_COST*2);
5721
5722 expand %{
5723 // Would like to use $src$$constant.
5724 immI16 srcLo %{ _opnds[1]->constant() %}
5725 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5726 immIhi16 srcHi %{ _opnds[1]->constant() %}
5727 iRegIdst tmpI;
5728 loadConIhi16(tmpI, srcHi);
5729 loadConI32_lo16(dst, tmpI, srcLo);
5730 %}
5731 %}
5732
5733 // No constant pool entries required.
5734 instruct loadConL16(iRegLdst dst, immL16 src) %{
5735 match(Set dst src);
5736
5737 format %{ "LI $dst, $src \t// long" %}
5738 size(4);
5739 ins_encode %{
5740 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
5741 %}
5742 ins_pipe(pipe_class_default);
5743 %}
5744
5745 // Load long constant 0xssssssss????0000
5746 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
5747 match(Set dst src);
5748 ins_cost(DEFAULT_COST);
5749
5750 format %{ "LIS $dst, $src.hi \t// long" %}
5751 size(4);
5752 ins_encode %{
5753 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5754 %}
5755 ins_pipe(pipe_class_default);
5756 %}
5757
5758 // To load a 32 bit constant: merge lower 16 bits into already loaded
5759 // high 16 bits.
5760 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
5761 // no match-rule, false predicate
5762 effect(DEF dst, USE src1, USE src2);
5763 predicate(false);
5764
5765 format %{ "ORI $dst, $src1, $src2.lo" %}
5766 size(4);
5767 ins_encode %{
5768 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5769 %}
5770 ins_pipe(pipe_class_default);
5771 %}
5772
5773 // Load 32-bit long constant
5774 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{
5775 match(Set dst src);
5776 ins_cost(DEFAULT_COST*2);
5777
5778 expand %{
5779 // Would like to use $src$$constant.
5780 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%}
5781 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5782 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%}
5783 iRegLdst tmpL;
5784 loadConL32hi16(tmpL, srcHi);
5785 loadConL32_lo16(dst, tmpL, srcLo);
5786 %}
5787 %}
5788
5789 // Load 34-bit long constant using prefixed addi. No constant pool entries required.
5790 instruct loadConL34(iRegLdst dst, immL34 src) %{
5791 match(Set dst src);
5792 // This macro is valid only in Power 10 and up, but adding the following predicate here
5793 // caused a build error, so we comment it out for now.
5794 // predicate(PowerArchitecturePPC64 >= 10);
5795 ins_cost(DEFAULT_COST+1);
5796
5797 format %{ "PLI $dst, $src \t// long" %}
5798 size(8);
5799 ins_encode %{
5800 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5801 __ pli($dst$$Register, $src$$constant);
5802 %}
5803 ins_pipe(pipe_class_default);
5804 ins_alignment(2);
5805 %}
5806
5807 // Load long constant 0x????000000000000.
5808 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{
5809 match(Set dst src);
5810 ins_cost(DEFAULT_COST);
5811
5812 expand %{
5813 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%}
5814 immI shift32 %{ 32 %}
5815 iRegLdst tmpL;
5816 loadConL32hi16(tmpL, srcHi);
5817 lshiftL_regL_immI(dst, tmpL, shift32);
5818 %}
5819 %}
5820
5821 // Expand node for constant pool load: small offset.
5822 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{
5823 effect(DEF dst, USE src, USE toc);
5824 ins_cost(MEMORY_REF_COST);
5825
5826 ins_num_consts(1);
5827 // Needed so that CallDynamicJavaDirect can compute the address of this
5828 // instruction for relocation.
5829 ins_field_cbuf_insts_offset(int);
5830
5831 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %}
5832 size(4);
5833 ins_encode( enc_load_long_constL(dst, src, toc) );
5834 ins_pipe(pipe_class_memory);
5835 %}
5836
5837 // Expand node for constant pool load: large offset.
5838 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{
5839 effect(DEF dst, USE src, USE toc);
5840 predicate(false);
5841
5842 ins_num_consts(1);
5843 ins_field_const_toc_offset(int);
5844 // Needed so that CallDynamicJavaDirect can compute the address of this
5845 // instruction for relocation.
5846 ins_field_cbuf_insts_offset(int);
5847
5848 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %}
5849 size(4);
5850 ins_encode( enc_load_long_constL_hi(dst, toc, src) );
5851 ins_pipe(pipe_class_default);
5852 %}
5853
5854 // Expand node for constant pool load: large offset.
5855 // No constant pool entries required.
5856 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
5857 effect(DEF dst, USE src, USE base);
5858 predicate(false);
5859
5860 ins_field_const_toc_offset_hi_node(loadConL_hiNode*);
5861
5862 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %}
5863 size(4);
5864 ins_encode %{
5865 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5866 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5867 %}
5868 ins_pipe(pipe_class_memory);
5869 %}
5870
5871 // Load long constant from constant table. Expand in case of
5872 // offset > 16 bit is needed.
5873 // Adlc adds toc node MachConstantTableBase.
5874 instruct loadConL_Ex(iRegLdst dst, immL src) %{
5875 match(Set dst src);
5876 ins_cost(MEMORY_REF_COST);
5877
5878 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %}
5879 // We can not inline the enc_class for the expand as that does not support constanttablebase.
5880 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) );
5881 %}
5882
5883 // Load nullptr as compressed oop.
5884 instruct loadConN0(iRegNdst dst, immN_0 src) %{
5885 match(Set dst src);
5886 ins_cost(DEFAULT_COST);
5887
5888 format %{ "LI $dst, $src \t// compressed ptr" %}
5889 size(4);
5890 ins_encode %{
5891 __ li($dst$$Register, 0);
5892 %}
5893 ins_pipe(pipe_class_default);
5894 %}
5895
5896 // Load hi part of compressed oop constant.
5897 instruct loadConN_hi(iRegNdst dst, immN src) %{
5898 effect(DEF dst, USE src);
5899 ins_cost(DEFAULT_COST);
5900
5901 format %{ "LIS $dst, $src \t// narrow oop hi" %}
5902 size(4);
5903 ins_encode %{
5904 __ lis($dst$$Register, 0); // Will get patched.
5905 %}
5906 ins_pipe(pipe_class_default);
5907 %}
5908
5909 // Add lo part of compressed oop constant to already loaded hi part.
5910 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
5911 effect(DEF dst, USE src1, USE src2);
5912 ins_cost(DEFAULT_COST);
5913
5914 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %}
5915 size(4);
5916 ins_encode %{
5917 AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant);
5918 __ relocate(addrlit.rspec(), /*compressed format*/ 1);
5919 __ ori($dst$$Register, $src1$$Register, 0); // Will get patched.
5920 %}
5921 ins_pipe(pipe_class_default);
5922 %}
5923
5924 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
5925 effect(DEF dst, USE src, USE shift, USE mask_begin);
5926
5927 size(4);
5928 ins_encode %{
5929 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
5930 %}
5931 ins_pipe(pipe_class_default);
5932 %}
5933
5934 // Needed to postalloc expand loadConN: ConN is loaded as ConI
5935 // leaving the upper 32 bits with sign-extension bits.
5936 // This clears these bits: dst = src & 0xFFFFFFFF.
5937 // TODO: Eventually call this maskN_regN_FFFFFFFF.
5938 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
5939 effect(DEF dst, USE src);
5940 predicate(false);
5941
5942 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
5943 size(4);
5944 ins_encode %{
5945 __ clrldi($dst$$Register, $src$$Register, 0x20);
5946 %}
5947 ins_pipe(pipe_class_default);
5948 %}
5949
5950 // Optimize DecodeN for disjoint base.
5951 // Load base of compressed oops into a register
5952 instruct loadBase(iRegLdst dst) %{
5953 effect(DEF dst);
5954
5955 format %{ "LoadConst $dst, heapbase" %}
5956 ins_encode %{
5957 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0);
5958 %}
5959 ins_pipe(pipe_class_default);
5960 %}
5961
5962 // Loading ConN must be postalloc expanded so that edges between
5963 // the nodes are safe. They may not interfere with a safepoint.
5964 // GL TODO: This needs three instructions: better put this into the constant pool.
5965 instruct loadConN_Ex(iRegNdst dst, immN src) %{
5966 match(Set dst src);
5967 ins_cost(DEFAULT_COST*2);
5968
5969 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5970 postalloc_expand %{
5971 MachNode *m1 = new loadConN_hiNode();
5972 MachNode *m2 = new loadConN_loNode();
5973 MachNode *m3 = new clearMs32bNode();
5974 m1->add_req(nullptr);
5975 m2->add_req(nullptr, m1);
5976 m3->add_req(nullptr, m2);
5977 m1->_opnds[0] = op_dst;
5978 m1->_opnds[1] = op_src;
5979 m2->_opnds[0] = op_dst;
5980 m2->_opnds[1] = op_dst;
5981 m2->_opnds[2] = op_src;
5982 m3->_opnds[0] = op_dst;
5983 m3->_opnds[1] = op_dst;
5984 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5985 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5986 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5987 nodes->push(m1);
5988 nodes->push(m2);
5989 nodes->push(m3);
5990 %}
5991 %}
5992
5993 // We have seen a safepoint between the hi and lo parts, and this node was handled
5994 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is
5995 // not a narrow oop.
5996 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
5997 match(Set dst src);
5998 effect(DEF dst, USE src);
5999 ins_cost(DEFAULT_COST);
6000
6001 format %{ "LIS $dst, $src \t// narrow klass hi" %}
6002 size(4);
6003 ins_encode %{
6004 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant);
6005 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
6006 %}
6007 ins_pipe(pipe_class_default);
6008 %}
6009
6010 // As loadConNKlass_hi this must be recognized as narrow klass, not oop!
6011 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
6012 match(Set dst src1);
6013 effect(TEMP src2);
6014 ins_cost(DEFAULT_COST);
6015
6016 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
6017 size(4);
6018 ins_encode %{
6019 __ clrldi($dst$$Register, $src2$$Register, 0x20);
6020 %}
6021 ins_pipe(pipe_class_default);
6022 %}
6023
6024 // This needs a match rule so that build_oop_map knows this is
6025 // not a narrow oop.
6026 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
6027 match(Set dst src1);
6028 effect(TEMP src2);
6029 ins_cost(DEFAULT_COST);
6030
6031 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
6032 size(4);
6033 ins_encode %{
6034 // Notify OOP recorder (don't need the relocation)
6035 AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant);
6036 intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value());
6037 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
6038 %}
6039 ins_pipe(pipe_class_default);
6040 %}
6041
6042 // Loading ConNKlass must be postalloc expanded so that edges between
6043 // the nodes are safe. They may not interfere with a safepoint.
6044 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
6045 match(Set dst src);
6046 ins_cost(DEFAULT_COST*2);
6047
6048 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6049 postalloc_expand %{
6050 // Load high bits into register. Sign extended.
6051 MachNode *m1 = new loadConNKlass_hiNode();
6052 m1->add_req(nullptr);
6053 m1->_opnds[0] = op_dst;
6054 m1->_opnds[1] = op_src;
6055 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6056 nodes->push(m1);
6057
6058 MachNode *m2 = m1;
6059 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) {
6060 // Value might be 1-extended. Mask out these bits.
6061 m2 = new loadConNKlass_maskNode();
6062 m2->add_req(nullptr, m1);
6063 m2->_opnds[0] = op_dst;
6064 m2->_opnds[1] = op_src;
6065 m2->_opnds[2] = op_dst;
6066 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6067 nodes->push(m2);
6068 }
6069
6070 MachNode *m3 = new loadConNKlass_loNode();
6071 m3->add_req(nullptr, m2);
6072 m3->_opnds[0] = op_dst;
6073 m3->_opnds[1] = op_src;
6074 m3->_opnds[2] = op_dst;
6075 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6076 nodes->push(m3);
6077 %}
6078 %}
6079
6080 // 0x1 is used in object initialization (initial object header).
6081 // No constant pool entries required.
6082 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
6083 match(Set dst src);
6084
6085 format %{ "LI $dst, $src \t// ptr" %}
6086 size(4);
6087 ins_encode %{
6088 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
6089 %}
6090 ins_pipe(pipe_class_default);
6091 %}
6092
6093 // Expand node for constant pool load: small offset.
6094 // The match rule is needed to generate the correct bottom_type(),
6095 // however this node should never match. The use of predicate is not
6096 // possible since ADLC forbids predicates for chain rules. The higher
6097 // costs do not prevent matching in this case. For that reason the
6098 // operand immP_NM with predicate(false) is used.
6099 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{
6100 match(Set dst src);
6101 effect(TEMP toc);
6102
6103 ins_num_consts(1);
6104
6105 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %}
6106 size(4);
6107 ins_encode( enc_load_long_constP(dst, src, toc) );
6108 ins_pipe(pipe_class_memory);
6109 %}
6110
6111 // Expand node for constant pool load: large offset.
6112 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{
6113 effect(DEF dst, USE src, USE toc);
6114 predicate(false);
6115
6116 ins_num_consts(1);
6117 ins_field_const_toc_offset(int);
6118
6119 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %}
6120 size(4);
6121 ins_encode( enc_load_long_constP_hi(dst, src, toc) );
6122 ins_pipe(pipe_class_default);
6123 %}
6124
6125 // Expand node for constant pool load: large offset.
6126 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
6127 match(Set dst src);
6128 effect(TEMP base);
6129
6130 ins_field_const_toc_offset_hi_node(loadConP_hiNode*);
6131
6132 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
6133 size(4);
6134 ins_encode %{
6135 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
6136 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
6137 %}
6138 ins_pipe(pipe_class_memory);
6139 %}
6140
6141 // Load pointer constant from constant table. Expand in case an
6142 // offset > 16 bit is needed.
6143 // Adlc adds toc node MachConstantTableBase.
6144 instruct loadConP_Ex(iRegPdst dst, immP src) %{
6145 match(Set dst src);
6146 ins_cost(MEMORY_REF_COST);
6147
6148 // This rule does not use "expand" because then
6149 // the result type is not known to be an Oop. An ADLC
6150 // enhancement will be needed to make that work - not worth it!
6151
6152 // If this instruction rematerializes, it prolongs the live range
6153 // of the toc node, causing illegal graphs.
6154 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule().
6155 ins_cannot_rematerialize(true);
6156
6157 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %}
6158 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) );
6159 %}
6160
6161 // Expand node for constant pool load: small offset.
6162 instruct loadConF(regF dst, immF src, iRegLdst toc) %{
6163 effect(DEF dst, USE src, USE toc);
6164 ins_cost(MEMORY_REF_COST);
6165
6166 ins_num_consts(1);
6167
6168 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %}
6169 size(4);
6170 ins_encode %{
6171 address float_address = __ float_constant($src$$constant);
6172 if (float_address == nullptr) {
6173 ciEnv::current()->record_out_of_memory_failure();
6174 return;
6175 }
6176 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register);
6177 %}
6178 ins_pipe(pipe_class_memory);
6179 %}
6180
6181 // Expand node for constant pool load: large offset.
6182 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
6183 effect(DEF dst, USE src, USE toc);
6184 ins_cost(MEMORY_REF_COST);
6185
6186 ins_num_consts(1);
6187
6188 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6189 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t"
6190 "ADDIS $toc, $toc, -offset_hi"%}
6191 size(12);
6192 ins_encode %{
6193 FloatRegister Rdst = $dst$$FloatRegister;
6194 Register Rtoc = $toc$$Register;
6195 address float_address = __ float_constant($src$$constant);
6196 if (float_address == nullptr) {
6197 ciEnv::current()->record_out_of_memory_failure();
6198 return;
6199 }
6200 int offset = __ offset_to_method_toc(float_address);
6201 int hi = (offset + (1<<15))>>16;
6202 int lo = offset - hi * (1<<16);
6203
6204 __ addis(Rtoc, Rtoc, hi);
6205 __ lfs(Rdst, lo, Rtoc);
6206 __ addis(Rtoc, Rtoc, -hi);
6207 %}
6208 ins_pipe(pipe_class_memory);
6209 %}
6210
6211 // Adlc adds toc node MachConstantTableBase.
6212 instruct loadConF_Ex(regF dst, immF src) %{
6213 match(Set dst src);
6214 ins_cost(MEMORY_REF_COST);
6215
6216 // See loadConP.
6217 ins_cannot_rematerialize(true);
6218
6219 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6220 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) );
6221 %}
6222
6223 // Expand node for constant pool load: small offset.
6224 instruct loadConD(regD dst, immD src, iRegLdst toc) %{
6225 effect(DEF dst, USE src, USE toc);
6226 ins_cost(MEMORY_REF_COST);
6227
6228 ins_num_consts(1);
6229
6230 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %}
6231 size(4);
6232 ins_encode %{
6233 address float_address = __ double_constant($src$$constant);
6234 if (float_address == nullptr) {
6235 ciEnv::current()->record_out_of_memory_failure();
6236 return;
6237 }
6238 int offset = __ offset_to_method_toc(float_address);
6239 __ lfd($dst$$FloatRegister, offset, $toc$$Register);
6240 %}
6241 ins_pipe(pipe_class_memory);
6242 %}
6243
6244 // Expand node for constant pool load: large offset.
6245 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
6246 effect(DEF dst, USE src, USE toc);
6247 ins_cost(MEMORY_REF_COST);
6248
6249 ins_num_consts(1);
6250
6251 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6252 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t"
6253 "ADDIS $toc, $toc, -offset_hi" %}
6254 size(12);
6255 ins_encode %{
6256 FloatRegister Rdst = $dst$$FloatRegister;
6257 Register Rtoc = $toc$$Register;
6258 address float_address = __ double_constant($src$$constant);
6259 if (float_address == nullptr) {
6260 ciEnv::current()->record_out_of_memory_failure();
6261 return;
6262 }
6263 int offset = __ offset_to_method_toc(float_address);
6264 int hi = (offset + (1<<15))>>16;
6265 int lo = offset - hi * (1<<16);
6266
6267 __ addis(Rtoc, Rtoc, hi);
6268 __ lfd(Rdst, lo, Rtoc);
6269 __ addis(Rtoc, Rtoc, -hi);
6270 %}
6271 ins_pipe(pipe_class_memory);
6272 %}
6273
6274 // Adlc adds toc node MachConstantTableBase.
6275 instruct loadConD_Ex(regD dst, immD src) %{
6276 match(Set dst src);
6277 ins_cost(MEMORY_REF_COST);
6278
6279 // See loadConP.
6280 ins_cannot_rematerialize(true);
6281
6282 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6283 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) );
6284 %}
6285
6286 // Prefetch instructions.
6287 // Must be safe to execute with invalid address (cannot fault).
6288
6289 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
6290 match(PrefetchAllocation (AddP mem src));
6291 ins_cost(MEMORY_REF_COST);
6292
6293 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
6294 size(4);
6295 ins_encode %{
6296 __ dcbtst($src$$Register, $mem$$base$$Register);
6297 %}
6298 ins_pipe(pipe_class_memory);
6299 %}
6300
6301 instruct prefetch_alloc_no_offset(indirectMemory mem) %{
6302 match(PrefetchAllocation mem);
6303 ins_cost(MEMORY_REF_COST);
6304
6305 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
6306 size(4);
6307 ins_encode %{
6308 __ dcbtst($mem$$base$$Register);
6309 %}
6310 ins_pipe(pipe_class_memory);
6311 %}
6312
6313 //----------Store Instructions-------------------------------------------------
6314
6315 // Store Byte
6316 instruct storeB(memory mem, iRegIsrc src) %{
6317 match(Set mem (StoreB mem src));
6318 ins_cost(MEMORY_REF_COST);
6319
6320 format %{ "STB $src, $mem \t// byte" %}
6321 size(4);
6322 ins_encode %{
6323 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6324 __ stb($src$$Register, Idisp, $mem$$base$$Register);
6325 %}
6326 ins_pipe(pipe_class_memory);
6327 %}
6328
6329 // Store Char/Short
6330 instruct storeC(memory mem, iRegIsrc src) %{
6331 match(Set mem (StoreC mem src));
6332 ins_cost(MEMORY_REF_COST);
6333
6334 format %{ "STH $src, $mem \t// short" %}
6335 size(4);
6336 ins_encode %{
6337 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6338 __ sth($src$$Register, Idisp, $mem$$base$$Register);
6339 %}
6340 ins_pipe(pipe_class_memory);
6341 %}
6342
6343 // Store Integer
6344 instruct storeI(memory mem, iRegIsrc src) %{
6345 match(Set mem (StoreI mem src));
6346 ins_cost(MEMORY_REF_COST);
6347
6348 format %{ "STW $src, $mem" %}
6349 size(4);
6350 ins_encode( enc_stw(src, mem) );
6351 ins_pipe(pipe_class_memory);
6352 %}
6353
6354 // ConvL2I + StoreI.
6355 instruct storeI_convL2I(memory mem, iRegLsrc src) %{
6356 match(Set mem (StoreI mem (ConvL2I src)));
6357 ins_cost(MEMORY_REF_COST);
6358
6359 format %{ "STW l2i($src), $mem" %}
6360 size(4);
6361 ins_encode( enc_stw(src, mem) );
6362 ins_pipe(pipe_class_memory);
6363 %}
6364
6365 // Store Long
6366 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{
6367 match(Set mem (StoreL mem src));
6368 ins_cost(MEMORY_REF_COST);
6369
6370 format %{ "STD $src, $mem \t// long" %}
6371 size(4);
6372 ins_encode( enc_std(src, mem) );
6373 ins_pipe(pipe_class_memory);
6374 %}
6375
6376 // Store super word nodes.
6377
6378 // Store Aligned Packed Byte long register to memory
6379 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{
6380 predicate(n->as_StoreVector()->memory_size() == 8);
6381 match(Set mem (StoreVector mem src));
6382 ins_cost(MEMORY_REF_COST);
6383
6384 format %{ "STD $mem, $src \t// packed8B" %}
6385 size(4);
6386 ins_encode( enc_std(src, mem) );
6387 ins_pipe(pipe_class_memory);
6388 %}
6389
6390
6391 instruct storeV16(memoryAlg16 mem, vecX src) %{
6392 predicate(n->as_StoreVector()->memory_size() == 16);
6393 match(Set mem (StoreVector mem src));
6394 ins_cost(MEMORY_REF_COST);
6395
6396 format %{ "STXV $mem, $src \t// store 16-byte Vector" %}
6397 size(4);
6398 ins_encode %{
6399 __ stxv($src$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
6400 %}
6401 ins_pipe(pipe_class_default);
6402 %}
6403
6404 // Reinterpret: only one vector size used: either L or X
6405 instruct reinterpretL(iRegLdst dst) %{
6406 match(Set dst (VectorReinterpret dst));
6407 ins_cost(0);
6408 format %{ "reinterpret $dst" %}
6409 size(0);
6410 ins_encode( /*empty*/ );
6411 ins_pipe(pipe_class_empty);
6412 %}
6413
6414 instruct reinterpretX(vecX dst) %{
6415 match(Set dst (VectorReinterpret dst));
6416 ins_cost(0);
6417 format %{ "reinterpret $dst" %}
6418 size(0);
6419 ins_encode( /*empty*/ );
6420 ins_pipe(pipe_class_empty);
6421 %}
6422
6423 // Store Compressed Oop
6424 instruct storeN(memory dst, iRegN_P2N src) %{
6425 match(Set dst (StoreN dst src));
6426 predicate(n->as_Store()->barrier_data() == 0);
6427 ins_cost(MEMORY_REF_COST);
6428
6429 format %{ "STW $src, $dst \t// compressed oop" %}
6430 size(4);
6431 ins_encode( enc_stw(src, dst) );
6432 ins_pipe(pipe_class_memory);
6433 %}
6434
6435 // Store Compressed KLass
6436 instruct storeNKlass(memory dst, iRegN_P2N src) %{
6437 match(Set dst (StoreNKlass dst src));
6438 ins_cost(MEMORY_REF_COST);
6439
6440 format %{ "STW $src, $dst \t// compressed klass" %}
6441 size(4);
6442 ins_encode( enc_stw(src, dst) );
6443 ins_pipe(pipe_class_memory);
6444 %}
6445
6446 // Store Pointer
6447 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{
6448 match(Set dst (StoreP dst src));
6449 predicate(n->as_Store()->barrier_data() == 0);
6450 ins_cost(MEMORY_REF_COST);
6451
6452 format %{ "STD $src, $dst \t// ptr" %}
6453 size(4);
6454 ins_encode( enc_std(src, dst) );
6455 ins_pipe(pipe_class_memory);
6456 %}
6457
6458 // Store Float
6459 instruct storeF(memory mem, regF src) %{
6460 match(Set mem (StoreF mem src));
6461 ins_cost(MEMORY_REF_COST);
6462
6463 format %{ "STFS $src, $mem" %}
6464 size(4);
6465 ins_encode( enc_stfs(src, mem) );
6466 ins_pipe(pipe_class_memory);
6467 %}
6468
6469 // Store Double
6470 instruct storeD(memory mem, regD src) %{
6471 match(Set mem (StoreD mem src));
6472 ins_cost(MEMORY_REF_COST);
6473
6474 format %{ "STFD $src, $mem" %}
6475 size(4);
6476 ins_encode( enc_stfd(src, mem) );
6477 ins_pipe(pipe_class_memory);
6478 %}
6479
6480 // Convert oop pointer into compressed form.
6481
6482 // Nodes for postalloc expand.
6483
6484 // Shift node for expand.
6485 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
6486 // The match rule is needed to make it a 'MachTypeNode'!
6487 match(Set dst (EncodeP src));
6488 predicate(false);
6489
6490 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6491 size(4);
6492 ins_encode %{
6493 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6494 %}
6495 ins_pipe(pipe_class_default);
6496 %}
6497
6498 // Add node for expand.
6499 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6500 // The match rule is needed to make it a 'MachTypeNode'!
6501 match(Set dst (EncodeP src));
6502 predicate(false);
6503
6504 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6505 ins_encode %{
6506 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6507 %}
6508 ins_pipe(pipe_class_default);
6509 %}
6510
6511 // Conditional sub base.
6512 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6513 // The match rule is needed to make it a 'MachTypeNode'!
6514 match(Set dst (EncodeP (Binary crx src1)));
6515 predicate(false);
6516
6517 format %{ "BEQ $crx, done\n\t"
6518 "SUB $dst, $src1, heapbase \t// encode: subtract base if != nullptr\n"
6519 "done:" %}
6520 ins_encode %{
6521 Label done;
6522 __ beq($crx$$CondRegister, done);
6523 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0);
6524 __ bind(done);
6525 %}
6526 ins_pipe(pipe_class_default);
6527 %}
6528
6529 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6530 // The match rule is needed to make it a 'MachTypeNode'!
6531 match(Set dst (EncodeP (Binary crx src1)));
6532 predicate(false);
6533
6534 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6535 size(4);
6536 ins_encode %{
6537 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6538 %}
6539 ins_pipe(pipe_class_default);
6540 %}
6541
6542 // Disjoint narrow oop base.
6543 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6544 match(Set dst (EncodeP src));
6545 predicate(CompressedOops::base_disjoint());
6546
6547 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6548 size(4);
6549 ins_encode %{
6550 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32);
6551 %}
6552 ins_pipe(pipe_class_default);
6553 %}
6554
6555 // shift != 0, base != 0
6556 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6557 match(Set dst (EncodeP src));
6558 effect(TEMP crx);
6559 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6560 CompressedOops::shift() != 0 &&
6561 CompressedOops::base_overlaps());
6562
6563 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6564 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6565 %}
6566
6567 // shift != 0, base != 0
6568 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6569 match(Set dst (EncodeP src));
6570 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6571 CompressedOops::shift() != 0 &&
6572 CompressedOops::base_overlaps());
6573
6574 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6575 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6576 %}
6577
6578 // shift != 0, base == 0
6579 // TODO: This is the same as encodeP_shift. Merge!
6580 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6581 match(Set dst (EncodeP src));
6582 predicate(CompressedOops::shift() != 0 &&
6583 CompressedOops::base() == nullptr);
6584
6585 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != nullptr" %}
6586 size(4);
6587 ins_encode %{
6588 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6589 %}
6590 ins_pipe(pipe_class_default);
6591 %}
6592
6593 // Compressed OOPs with narrow_oop_shift == 0.
6594 // shift == 0, base == 0
6595 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
6596 match(Set dst (EncodeP src));
6597 predicate(CompressedOops::shift() == 0);
6598
6599 format %{ "MR $dst, $src \t// Ptr->Narrow" %}
6600 // variable size, 0 or 4.
6601 ins_encode %{
6602 __ mr_if_needed($dst$$Register, $src$$Register);
6603 %}
6604 ins_pipe(pipe_class_default);
6605 %}
6606
6607 // Decode nodes.
6608
6609 // Shift node for expand.
6610 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6611 // The match rule is needed to make it a 'MachTypeNode'!
6612 match(Set dst (DecodeN src));
6613 predicate(false);
6614
6615 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6616 size(4);
6617 ins_encode %{
6618 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6619 %}
6620 ins_pipe(pipe_class_default);
6621 %}
6622
6623 // Add node for expand.
6624 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6625 // The match rule is needed to make it a 'MachTypeNode'!
6626 match(Set dst (DecodeN src));
6627 predicate(false);
6628
6629 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %}
6630 ins_encode %{
6631 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6632 %}
6633 ins_pipe(pipe_class_default);
6634 %}
6635
6636 // conditianal add base for expand
6637 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6638 // The match rule is needed to make it a 'MachTypeNode'!
6639 // NOTICE that the rule is nonsense - we just have to make sure that:
6640 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6641 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6642 match(Set dst (DecodeN (Binary crx src)));
6643 predicate(false);
6644
6645 format %{ "BEQ $crx, done\n\t"
6646 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != nullptr\n"
6647 "done:" %}
6648 ins_encode %{
6649 Label done;
6650 __ beq($crx$$CondRegister, done);
6651 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6652 __ bind(done);
6653 %}
6654 ins_pipe(pipe_class_default);
6655 %}
6656
6657 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6658 // The match rule is needed to make it a 'MachTypeNode'!
6659 // NOTICE that the rule is nonsense - we just have to make sure that:
6660 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6661 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6662 match(Set dst (DecodeN (Binary crx src1)));
6663 predicate(false);
6664
6665 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6666 size(4);
6667 ins_encode %{
6668 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6669 %}
6670 ins_pipe(pipe_class_default);
6671 %}
6672
6673 // shift != 0, base != 0
6674 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6675 match(Set dst (DecodeN src));
6676 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6677 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6678 CompressedOops::shift() != 0 &&
6679 CompressedOops::base() != nullptr);
6680 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6681 effect(TEMP crx);
6682
6683 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6684 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6685 %}
6686
6687 // shift != 0, base == 0
6688 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6689 match(Set dst (DecodeN src));
6690 predicate(CompressedOops::shift() != 0 &&
6691 CompressedOops::base() == nullptr);
6692
6693 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %}
6694 size(4);
6695 ins_encode %{
6696 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6697 %}
6698 ins_pipe(pipe_class_default);
6699 %}
6700
6701 // Optimize DecodeN for disjoint base.
6702 // Shift narrow oop and or it into register that already contains the heap base.
6703 // Base == dst must hold, and is assured by construction in postaloc_expand.
6704 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6705 match(Set dst (DecodeN src));
6706 effect(TEMP base);
6707 predicate(false);
6708
6709 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6710 size(4);
6711 ins_encode %{
6712 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift());
6713 %}
6714 ins_pipe(pipe_class_default);
6715 %}
6716
6717 // Optimize DecodeN for disjoint base.
6718 // This node requires only one cycle on the critical path.
6719 // We must postalloc_expand as we can not express use_def effects where
6720 // the used register is L and the def'ed register P.
6721 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6722 match(Set dst (DecodeN src));
6723 effect(TEMP_DEF dst);
6724 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6725 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6726 CompressedOops::base_disjoint());
6727 ins_cost(DEFAULT_COST);
6728
6729 format %{ "MOV $dst, heapbase \t\n"
6730 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6731 postalloc_expand %{
6732 loadBaseNode *n1 = new loadBaseNode();
6733 n1->add_req(nullptr);
6734 n1->_opnds[0] = op_dst;
6735
6736 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6737 n2->add_req(n_region, n_src, n1);
6738 n2->_opnds[0] = op_dst;
6739 n2->_opnds[1] = op_src;
6740 n2->_opnds[2] = op_dst;
6741 n2->_bottom_type = _bottom_type;
6742
6743 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6744 ra_->set_oop(n2, true);
6745
6746 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6747 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6748
6749 nodes->push(n1);
6750 nodes->push(n2);
6751 %}
6752 %}
6753
6754 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6755 match(Set dst (DecodeN src));
6756 effect(TEMP_DEF dst, TEMP crx);
6757 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6758 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6759 CompressedOops::base_disjoint());
6760 ins_cost(3 * DEFAULT_COST);
6761
6762 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %}
6763 postalloc_expand %{
6764 loadBaseNode *n1 = new loadBaseNode();
6765 n1->add_req(nullptr);
6766 n1->_opnds[0] = op_dst;
6767
6768 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
6769 n_compare->add_req(n_region, n_src);
6770 n_compare->_opnds[0] = op_crx;
6771 n_compare->_opnds[1] = op_src;
6772 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6773
6774 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6775 n2->add_req(n_region, n_src, n1);
6776 n2->_opnds[0] = op_dst;
6777 n2->_opnds[1] = op_src;
6778 n2->_opnds[2] = op_dst;
6779 n2->_bottom_type = _bottom_type;
6780
6781 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6782 n_cond_set->add_req(n_region, n_compare, n2);
6783 n_cond_set->_opnds[0] = op_dst;
6784 n_cond_set->_opnds[1] = op_crx;
6785 n_cond_set->_opnds[2] = op_dst;
6786 n_cond_set->_bottom_type = _bottom_type;
6787
6788 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6789 ra_->set_oop(n_cond_set, true);
6790
6791 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6792 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
6793 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6794 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6795
6796 nodes->push(n1);
6797 nodes->push(n_compare);
6798 nodes->push(n2);
6799 nodes->push(n_cond_set);
6800 %}
6801 %}
6802
6803 // src != 0, shift != 0, base != 0
6804 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6805 match(Set dst (DecodeN src));
6806 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6807 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6808 CompressedOops::shift() != 0 &&
6809 CompressedOops::base() != nullptr);
6810 ins_cost(2 * DEFAULT_COST);
6811
6812 format %{ "DecodeN $dst, $src \t// $src != nullptr, postalloc expanded" %}
6813 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6814 %}
6815
6816 // Compressed OOPs with narrow_oop_shift == 0.
6817 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6818 match(Set dst (DecodeN src));
6819 predicate(CompressedOops::shift() == 0);
6820 ins_cost(DEFAULT_COST);
6821
6822 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %}
6823 // variable size, 0 or 4.
6824 ins_encode %{
6825 __ mr_if_needed($dst$$Register, $src$$Register);
6826 %}
6827 ins_pipe(pipe_class_default);
6828 %}
6829
6830 // Convert compressed oop into int for vectors alignment masking.
6831 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
6832 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6833 predicate(CompressedOops::shift() == 0);
6834 ins_cost(DEFAULT_COST);
6835
6836 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %}
6837 // variable size, 0 or 4.
6838 ins_encode %{
6839 __ mr_if_needed($dst$$Register, $src$$Register);
6840 %}
6841 ins_pipe(pipe_class_default);
6842 %}
6843
6844 // Convert klass pointer into compressed form.
6845
6846 // Nodes for postalloc expand.
6847
6848 // Shift node for expand.
6849 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
6850 // The match rule is needed to make it a 'MachTypeNode'!
6851 match(Set dst (EncodePKlass src));
6852 predicate(false);
6853
6854 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6855 size(4);
6856 ins_encode %{
6857 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6858 %}
6859 ins_pipe(pipe_class_default);
6860 %}
6861
6862 // Add node for expand.
6863 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6864 // The match rule is needed to make it a 'MachTypeNode'!
6865 match(Set dst (EncodePKlass (Binary base src)));
6866 predicate(false);
6867
6868 format %{ "SUB $dst, $base, $src \t// encode" %}
6869 size(4);
6870 ins_encode %{
6871 __ subf($dst$$Register, $base$$Register, $src$$Register);
6872 %}
6873 ins_pipe(pipe_class_default);
6874 %}
6875
6876 // Disjoint narrow oop base.
6877 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
6878 match(Set dst (EncodePKlass src));
6879 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/);
6880
6881 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6882 size(4);
6883 ins_encode %{
6884 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
6885 %}
6886 ins_pipe(pipe_class_default);
6887 %}
6888
6889 // shift != 0, base != 0
6890 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6891 match(Set dst (EncodePKlass (Binary base src)));
6892 predicate(false);
6893
6894 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6895 postalloc_expand %{
6896 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
6897 n1->add_req(n_region, n_base, n_src);
6898 n1->_opnds[0] = op_dst;
6899 n1->_opnds[1] = op_base;
6900 n1->_opnds[2] = op_src;
6901 n1->_bottom_type = _bottom_type;
6902
6903 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode();
6904 n2->add_req(n_region, n1);
6905 n2->_opnds[0] = op_dst;
6906 n2->_opnds[1] = op_dst;
6907 n2->_bottom_type = _bottom_type;
6908 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6909 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6910
6911 nodes->push(n1);
6912 nodes->push(n2);
6913 %}
6914 %}
6915
6916 // shift != 0, base != 0
6917 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
6918 match(Set dst (EncodePKlass src));
6919 //predicate(CompressedKlassPointers::shift() != 0 &&
6920 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/);
6921
6922 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6923 ins_cost(DEFAULT_COST*2); // Don't count constant.
6924 expand %{
6925 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %}
6926 iRegLdst base;
6927 loadConL_Ex(base, baseImm);
6928 encodePKlass_not_null_Ex(dst, base, src);
6929 %}
6930 %}
6931
6932 // Decode nodes.
6933
6934 // Shift node for expand.
6935 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
6936 // The match rule is needed to make it a 'MachTypeNode'!
6937 match(Set dst (DecodeNKlass src));
6938 predicate(false);
6939
6940 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %}
6941 size(4);
6942 ins_encode %{
6943 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6944 %}
6945 ins_pipe(pipe_class_default);
6946 %}
6947
6948 // Add node for expand.
6949
6950 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6951 // The match rule is needed to make it a 'MachTypeNode'!
6952 match(Set dst (DecodeNKlass (Binary base src)));
6953 predicate(false);
6954
6955 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
6956 size(4);
6957 ins_encode %{
6958 __ add($dst$$Register, $base$$Register, $src$$Register);
6959 %}
6960 ins_pipe(pipe_class_default);
6961 %}
6962
6963 // src != 0, shift != 0, base != 0
6964 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
6965 match(Set dst (DecodeNKlass (Binary base src)));
6966 //effect(kill src); // We need a register for the immediate result after shifting.
6967 predicate(false);
6968
6969 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != nullptr, postalloc expanded" %}
6970 postalloc_expand %{
6971 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode();
6972 n1->add_req(n_region, n_base, n_src);
6973 n1->_opnds[0] = op_dst;
6974 n1->_opnds[1] = op_base;
6975 n1->_opnds[2] = op_src;
6976 n1->_bottom_type = _bottom_type;
6977
6978 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode();
6979 n2->add_req(n_region, n1);
6980 n2->_opnds[0] = op_dst;
6981 n2->_opnds[1] = op_dst;
6982 n2->_bottom_type = _bottom_type;
6983
6984 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6985 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6986
6987 nodes->push(n1);
6988 nodes->push(n2);
6989 %}
6990 %}
6991
6992 // src != 0, shift != 0, base != 0
6993 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
6994 match(Set dst (DecodeNKlass src));
6995 // predicate(CompressedKlassPointers::shift() != 0 &&
6996 // CompressedKlassPointers::base() != 0);
6997
6998 //format %{ "DecodeNKlass $dst, $src \t// $src != nullptr, expanded" %}
6999
7000 ins_cost(DEFAULT_COST*2); // Don't count constant.
7001 expand %{
7002 // We add first, then we shift. Like this, we can get along with one register less.
7003 // But we have to load the base pre-shifted.
7004 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %}
7005 iRegLdst base;
7006 loadConL_Ex(base, baseImm);
7007 decodeNKlass_notNull_addBase_Ex(dst, base, src);
7008 %}
7009 %}
7010
7011 //----------MemBar Instructions-----------------------------------------------
7012 // Memory barrier flavors
7013
7014 instruct membar_acquire() %{
7015 match(LoadFence);
7016 ins_cost(4*MEMORY_REF_COST);
7017
7018 format %{ "MEMBAR-acquire" %}
7019 size(4);
7020 ins_encode %{
7021 __ acquire();
7022 %}
7023 ins_pipe(pipe_class_default);
7024 %}
7025
7026 instruct unnecessary_membar_acquire() %{
7027 match(MemBarAcquire);
7028 ins_cost(0);
7029
7030 format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
7031 size(0);
7032 ins_encode( /*empty*/ );
7033 ins_pipe(pipe_class_default);
7034 %}
7035
7036 instruct membar_acquire_lock() %{
7037 match(MemBarAcquireLock);
7038 ins_cost(0);
7039
7040 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
7041 size(0);
7042 ins_encode( /*empty*/ );
7043 ins_pipe(pipe_class_default);
7044 %}
7045
7046 instruct membar_release() %{
7047 match(MemBarRelease);
7048 match(StoreFence);
7049 ins_cost(4*MEMORY_REF_COST);
7050
7051 format %{ "MEMBAR-release" %}
7052 size(4);
7053 ins_encode %{
7054 __ release();
7055 %}
7056 ins_pipe(pipe_class_default);
7057 %}
7058
7059 instruct membar_storestore() %{
7060 match(MemBarStoreStore);
7061 match(StoreStoreFence);
7062 ins_cost(4*MEMORY_REF_COST);
7063
7064 format %{ "MEMBAR-store-store" %}
7065 size(4);
7066 ins_encode %{
7067 __ membar(Assembler::StoreStore);
7068 %}
7069 ins_pipe(pipe_class_default);
7070 %}
7071
7072 instruct membar_release_lock() %{
7073 match(MemBarReleaseLock);
7074 ins_cost(0);
7075
7076 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
7077 size(0);
7078 ins_encode( /*empty*/ );
7079 ins_pipe(pipe_class_default);
7080 %}
7081
7082 instruct membar_storeload() %{
7083 match(MemBarStoreLoad);
7084 ins_cost(4*MEMORY_REF_COST);
7085
7086 format %{ "MEMBAR-store-load" %}
7087 size(4);
7088 ins_encode %{
7089 __ fence();
7090 %}
7091 ins_pipe(pipe_class_default);
7092 %}
7093
7094 instruct membar_volatile() %{
7095 match(MemBarVolatile);
7096 ins_cost(4*MEMORY_REF_COST);
7097
7098 format %{ "MEMBAR-volatile" %}
7099 size(4);
7100 ins_encode %{
7101 __ fence();
7102 %}
7103 ins_pipe(pipe_class_default);
7104 %}
7105
7106 // This optimization is wrong on PPC. The following pattern is not supported:
7107 // MemBarVolatile
7108 // ^ ^
7109 // | |
7110 // CtrlProj MemProj
7111 // ^ ^
7112 // | |
7113 // | Load
7114 // |
7115 // MemBarVolatile
7116 //
7117 // The first MemBarVolatile could get optimized out! According to
7118 // Vladimir, this pattern can not occur on Oracle platforms.
7119 // However, it does occur on PPC64 (because of membars in
7120 // inline_unsafe_load_store).
7121 //
7122 // Add this node again if we found a good solution for inline_unsafe_load_store().
7123 // Don't forget to look at the implementation of post_store_load_barrier again,
7124 // we did other fixes in that method.
7125 //instruct unnecessary_membar_volatile() %{
7126 // match(MemBarVolatile);
7127 // predicate(Matcher::post_store_load_barrier(n));
7128 // ins_cost(0);
7129 //
7130 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
7131 // size(0);
7132 // ins_encode( /*empty*/ );
7133 // ins_pipe(pipe_class_default);
7134 //%}
7135
7136 instruct membar_full() %{
7137 match(MemBarFull);
7138 ins_cost(4*MEMORY_REF_COST);
7139
7140 format %{ "MEMBAR-full" %}
7141 size(4);
7142 ins_encode %{
7143 __ fence();
7144 %}
7145 ins_pipe(pipe_class_default);
7146 %}
7147
7148 instruct membar_CPUOrder() %{
7149 match(MemBarCPUOrder);
7150 ins_cost(0);
7151
7152 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
7153 size(0);
7154 ins_encode( /*empty*/ );
7155 ins_pipe(pipe_class_default);
7156 %}
7157
7158 //----------Conditional Move---------------------------------------------------
7159
7160 // Cmove using isel.
7161 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
7162 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7163 ins_cost(DEFAULT_COST);
7164
7165 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7166 size(4);
7167 ins_encode %{
7168 int cc = $cmp$$cmpcode;
7169 __ isel($dst$$Register, $crx$$CondRegister,
7170 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7171 %}
7172 ins_pipe(pipe_class_default);
7173 %}
7174
7175 // Cmove using isel.
7176 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
7177 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7178 ins_cost(DEFAULT_COST);
7179
7180 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7181 size(4);
7182 ins_encode %{
7183 int cc = $cmp$$cmpcode;
7184 __ isel($dst$$Register, $crx$$CondRegister,
7185 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7186 %}
7187 ins_pipe(pipe_class_default);
7188 %}
7189
7190 // Cmove using isel.
7191 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
7192 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7193 ins_cost(DEFAULT_COST);
7194
7195 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7196 size(4);
7197 ins_encode %{
7198 int cc = $cmp$$cmpcode;
7199 __ isel($dst$$Register, $crx$$CondRegister,
7200 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7201 %}
7202 ins_pipe(pipe_class_default);
7203 %}
7204
7205 // Cmove using isel.
7206 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
7207 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7208 ins_cost(DEFAULT_COST);
7209
7210 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7211 size(4);
7212 ins_encode %{
7213 int cc = $cmp$$cmpcode;
7214 __ isel($dst$$Register, $crx$$CondRegister,
7215 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7216 %}
7217 ins_pipe(pipe_class_default);
7218 %}
7219
7220 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
7221 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
7222 ins_cost(DEFAULT_COST+BRANCH_COST);
7223
7224 ins_variable_size_depending_on_alignment(true);
7225
7226 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7227 size(8);
7228 ins_encode %{
7229 Label done;
7230 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7231 // Branch if not (cmp crx).
7232 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7233 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7234 __ bind(done);
7235 %}
7236 ins_pipe(pipe_class_default);
7237 %}
7238
7239 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7240 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7241 ins_cost(DEFAULT_COST+BRANCH_COST);
7242
7243 ins_variable_size_depending_on_alignment(true);
7244
7245 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7246 size(8);
7247 ins_encode %{
7248 Label done;
7249 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7250 // Branch if not (cmp crx).
7251 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7252 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7253 __ bind(done);
7254 %}
7255 ins_pipe(pipe_class_default);
7256 %}
7257
7258 instruct cmovF_cmpF(cmpOp cop, regF op1, regF op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7259 match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7260 predicate(PowerArchitecturePPC64 >= 9);
7261 effect(TEMP tmp);
7262 ins_cost(2*DEFAULT_COST);
7263 format %{ "cmovF_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7264 size(8);
7265 ins_encode %{
7266 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7267 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7268 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7269 $tmp$$FloatRegister->to_vsr());
7270 %}
7271 ins_pipe(pipe_class_default);
7272 %}
7273
7274 instruct cmovF_cmpD(cmpOp cop, regD op1, regD op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7275 match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7276 predicate(PowerArchitecturePPC64 >= 9);
7277 effect(TEMP tmp);
7278 ins_cost(2*DEFAULT_COST);
7279 format %{ "cmovF_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7280 size(8);
7281 ins_encode %{
7282 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7283 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7284 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7285 $tmp$$FloatRegister->to_vsr());
7286 %}
7287 ins_pipe(pipe_class_default);
7288 %}
7289
7290 instruct cmovD_cmpD(cmpOp cop, regD op1, regD op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7291 match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7292 predicate(PowerArchitecturePPC64 >= 9);
7293 effect(TEMP tmp);
7294 ins_cost(2*DEFAULT_COST);
7295 format %{ "cmovD_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7296 size(8);
7297 ins_encode %{
7298 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7299 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7300 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7301 $tmp$$FloatRegister->to_vsr());
7302 %}
7303 ins_pipe(pipe_class_default);
7304 %}
7305
7306 instruct cmovD_cmpF(cmpOp cop, regF op1, regF op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7307 match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7308 predicate(PowerArchitecturePPC64 >= 9);
7309 effect(TEMP tmp);
7310 ins_cost(2*DEFAULT_COST);
7311 format %{ "cmovD_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7312 size(8);
7313 ins_encode %{
7314 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7315 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7316 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7317 $tmp$$FloatRegister->to_vsr());
7318 %}
7319 ins_pipe(pipe_class_default);
7320 %}
7321
7322 //----------Compare-And-Swap---------------------------------------------------
7323
7324 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7325 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7326 // matched.
7327
7328 // Strong versions:
7329
7330 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7331 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7332 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7333 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7334 ins_encode %{
7335 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7336 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7337 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7338 $res$$Register, nullptr, true);
7339 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7340 __ isync();
7341 } else {
7342 __ sync();
7343 }
7344 %}
7345 ins_pipe(pipe_class_default);
7346 %}
7347
7348 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7349 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7350 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7351 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7352 ins_encode %{
7353 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7354 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7355 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7356 $res$$Register, nullptr, true);
7357 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7358 __ isync();
7359 } else {
7360 __ sync();
7361 }
7362 %}
7363 ins_pipe(pipe_class_default);
7364 %}
7365
7366 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7367 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7368 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7369 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7370 ins_encode %{
7371 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7372 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7373 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7374 $res$$Register, nullptr, true);
7375 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7376 __ isync();
7377 } else {
7378 __ sync();
7379 }
7380 %}
7381 ins_pipe(pipe_class_default);
7382 %}
7383
7384 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7385 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7386 predicate(n->as_LoadStore()->barrier_data() == 0);
7387 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7388 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7389 ins_encode %{
7390 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7391 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7392 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7393 $res$$Register, nullptr, true);
7394 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7395 __ isync();
7396 } else {
7397 __ sync();
7398 }
7399 %}
7400 ins_pipe(pipe_class_default);
7401 %}
7402
7403 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7404 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7405 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7406 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7407 ins_encode %{
7408 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7409 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7410 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7411 $res$$Register, nullptr, true);
7412 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7413 __ isync();
7414 } else {
7415 __ sync();
7416 }
7417 %}
7418 ins_pipe(pipe_class_default);
7419 %}
7420
7421 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7422 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7423 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7424 predicate(n->as_LoadStore()->barrier_data() == 0);
7425 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7426 ins_encode %{
7427 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7428 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7429 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7430 $res$$Register, nullptr, true);
7431 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7432 __ isync();
7433 } else {
7434 __ sync();
7435 }
7436 %}
7437 ins_pipe(pipe_class_default);
7438 %}
7439
7440 // Weak versions:
7441
7442 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7443 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7444 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7445 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7446 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7447 ins_encode %{
7448 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7449 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7450 MacroAssembler::MemBarNone,
7451 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7452 %}
7453 ins_pipe(pipe_class_default);
7454 %}
7455
7456 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7457 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7458 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) );
7459 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7460 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7461 ins_encode %{
7462 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7463 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7464 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7465 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7466 %}
7467 ins_pipe(pipe_class_default);
7468 %}
7469
7470 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7471 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7472 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7473 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7474 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7475 ins_encode %{
7476 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7477 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7478 MacroAssembler::MemBarNone,
7479 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7480 %}
7481 ins_pipe(pipe_class_default);
7482 %}
7483
7484 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7485 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7486 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7487 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7488 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7489 ins_encode %{
7490 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7491 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7492 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7493 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7494 %}
7495 ins_pipe(pipe_class_default);
7496 %}
7497
7498 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7499 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7500 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7501 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7502 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7503 ins_encode %{
7504 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7505 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7506 MacroAssembler::MemBarNone,
7507 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7508 %}
7509 ins_pipe(pipe_class_default);
7510 %}
7511
7512 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7513 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7514 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7515 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7516 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7517 ins_encode %{
7518 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7519 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7520 // value is never passed to caller.
7521 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7522 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7523 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7524 %}
7525 ins_pipe(pipe_class_default);
7526 %}
7527
7528 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7529 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7530 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7531 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7532 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7533 ins_encode %{
7534 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7535 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7536 MacroAssembler::MemBarNone,
7537 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7538 %}
7539 ins_pipe(pipe_class_default);
7540 %}
7541
7542 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7543 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7544 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7545 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7546 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7547 ins_encode %{
7548 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7549 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7550 // value is never passed to caller.
7551 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7552 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7553 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7554 %}
7555 ins_pipe(pipe_class_default);
7556 %}
7557
7558 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7559 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7560 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7561 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7562 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7563 ins_encode %{
7564 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7565 // value is never passed to caller.
7566 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7567 MacroAssembler::MemBarNone,
7568 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7569 %}
7570 ins_pipe(pipe_class_default);
7571 %}
7572
7573 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7574 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7575 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7576 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7577 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7578 ins_encode %{
7579 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7580 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7581 // value is never passed to caller.
7582 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7583 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7584 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7585 %}
7586 ins_pipe(pipe_class_default);
7587 %}
7588
7589 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7590 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7591 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7592 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7593 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7594 ins_encode %{
7595 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7596 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7597 MacroAssembler::MemBarNone,
7598 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7599 %}
7600 ins_pipe(pipe_class_default);
7601 %}
7602
7603 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7604 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7605 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7606 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7607 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7608 ins_encode %{
7609 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7610 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7611 // value is never passed to caller.
7612 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7613 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7614 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7615 %}
7616 ins_pipe(pipe_class_default);
7617 %}
7618
7619 // CompareAndExchange
7620
7621 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7622 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7623 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7624 effect(TEMP_DEF res, TEMP cr0);
7625 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7626 ins_encode %{
7627 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7628 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7629 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7630 noreg, nullptr, true);
7631 %}
7632 ins_pipe(pipe_class_default);
7633 %}
7634
7635 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7636 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7637 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7638 effect(TEMP_DEF res, TEMP cr0);
7639 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7640 ins_encode %{
7641 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7642 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7643 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7644 noreg, nullptr, true);
7645 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7646 __ isync();
7647 } else {
7648 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7649 __ sync();
7650 }
7651 %}
7652 ins_pipe(pipe_class_default);
7653 %}
7654
7655
7656 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7657 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7658 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7659 effect(TEMP_DEF res, TEMP cr0);
7660 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7661 ins_encode %{
7662 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7663 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7664 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7665 noreg, nullptr, true);
7666 %}
7667 ins_pipe(pipe_class_default);
7668 %}
7669
7670 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7671 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7672 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7673 effect(TEMP_DEF res, TEMP cr0);
7674 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7675 ins_encode %{
7676 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7677 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7678 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7679 noreg, nullptr, true);
7680 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7681 __ isync();
7682 } else {
7683 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7684 __ sync();
7685 }
7686 %}
7687 ins_pipe(pipe_class_default);
7688 %}
7689
7690 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7691 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7692 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7693 effect(TEMP_DEF res, TEMP cr0);
7694 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
7695 ins_encode %{
7696 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7697 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7698 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7699 noreg, nullptr, true);
7700 %}
7701 ins_pipe(pipe_class_default);
7702 %}
7703
7704 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7705 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7706 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7707 effect(TEMP_DEF res, TEMP cr0);
7708 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
7709 ins_encode %{
7710 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7711 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7712 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7713 noreg, nullptr, true);
7714 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7715 __ isync();
7716 } else {
7717 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7718 __ sync();
7719 }
7720 %}
7721 ins_pipe(pipe_class_default);
7722 %}
7723
7724 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7725 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7726 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7727 effect(TEMP_DEF res, TEMP cr0);
7728 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7729 ins_encode %{
7730 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7731 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7732 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7733 noreg, nullptr, true);
7734 %}
7735 ins_pipe(pipe_class_default);
7736 %}
7737
7738 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7739 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7740 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7741 effect(TEMP_DEF res, TEMP cr0);
7742 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7743 ins_encode %{
7744 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7745 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7746 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7747 noreg, nullptr, true);
7748 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7749 __ isync();
7750 } else {
7751 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7752 __ sync();
7753 }
7754 %}
7755 ins_pipe(pipe_class_default);
7756 %}
7757
7758 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7759 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7760 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7761 effect(TEMP_DEF res, TEMP cr0);
7762 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
7763 ins_encode %{
7764 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7765 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7766 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7767 noreg, nullptr, true);
7768 %}
7769 ins_pipe(pipe_class_default);
7770 %}
7771
7772 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7773 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7774 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7775 effect(TEMP_DEF res, TEMP cr0);
7776 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
7777 ins_encode %{
7778 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7779 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7780 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7781 noreg, nullptr, true);
7782 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7783 __ isync();
7784 } else {
7785 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7786 __ sync();
7787 }
7788 %}
7789 ins_pipe(pipe_class_default);
7790 %}
7791
7792 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7793 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7794 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst)
7795 && n->as_LoadStore()->barrier_data() == 0);
7796 effect(TEMP_DEF res, TEMP cr0);
7797 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7798 ins_encode %{
7799 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7800 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7801 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7802 noreg, nullptr, true);
7803 %}
7804 ins_pipe(pipe_class_default);
7805 %}
7806
7807 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7808 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7809 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst)
7810 && n->as_LoadStore()->barrier_data() == 0);
7811 effect(TEMP_DEF res, TEMP cr0);
7812 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7813 ins_encode %{
7814 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7815 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7816 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7817 noreg, nullptr, true);
7818 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7819 __ isync();
7820 } else {
7821 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7822 __ sync();
7823 }
7824 %}
7825 ins_pipe(pipe_class_default);
7826 %}
7827
7828 // Special RMW
7829
7830 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7831 match(Set res (GetAndAddB mem_ptr src));
7832 effect(TEMP_DEF res, TEMP cr0);
7833 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
7834 ins_encode %{
7835 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
7836 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7837 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7838 __ isync();
7839 } else {
7840 __ sync();
7841 }
7842 %}
7843 ins_pipe(pipe_class_default);
7844 %}
7845
7846 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7847 match(Set res (GetAndAddS mem_ptr src));
7848 effect(TEMP_DEF res, TEMP cr0);
7849 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
7850 ins_encode %{
7851 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
7852 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7853 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7854 __ isync();
7855 } else {
7856 __ sync();
7857 }
7858 %}
7859 ins_pipe(pipe_class_default);
7860 %}
7861
7862
7863 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7864 match(Set res (GetAndAddI mem_ptr src));
7865 effect(TEMP_DEF res, TEMP cr0);
7866 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
7867 ins_encode %{
7868 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
7869 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7870 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7871 __ isync();
7872 } else {
7873 __ sync();
7874 }
7875 %}
7876 ins_pipe(pipe_class_default);
7877 %}
7878
7879 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7880 match(Set res (GetAndAddL mem_ptr src));
7881 effect(TEMP_DEF res, TEMP cr0);
7882 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
7883 ins_encode %{
7884 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
7885 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7886 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7887 __ isync();
7888 } else {
7889 __ sync();
7890 }
7891 %}
7892 ins_pipe(pipe_class_default);
7893 %}
7894
7895 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7896 match(Set res (GetAndSetB mem_ptr src));
7897 effect(TEMP_DEF res, TEMP cr0);
7898 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
7899 ins_encode %{
7900 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
7901 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7902 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7903 __ isync();
7904 } else {
7905 __ sync();
7906 }
7907 %}
7908 ins_pipe(pipe_class_default);
7909 %}
7910
7911 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7912 match(Set res (GetAndSetS mem_ptr src));
7913 effect(TEMP_DEF res, TEMP cr0);
7914 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
7915 ins_encode %{
7916 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
7917 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7918 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7919 __ isync();
7920 } else {
7921 __ sync();
7922 }
7923 %}
7924 ins_pipe(pipe_class_default);
7925 %}
7926
7927
7928 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7929 match(Set res (GetAndSetI mem_ptr src));
7930 effect(TEMP_DEF res, TEMP cr0);
7931 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
7932 ins_encode %{
7933 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7934 MacroAssembler::cmpxchgx_hint_atomic_update());
7935 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7936 __ isync();
7937 } else {
7938 __ sync();
7939 }
7940 %}
7941 ins_pipe(pipe_class_default);
7942 %}
7943
7944 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7945 match(Set res (GetAndSetL mem_ptr src));
7946 effect(TEMP_DEF res, TEMP cr0);
7947 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
7948 ins_encode %{
7949 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7950 MacroAssembler::cmpxchgx_hint_atomic_update());
7951 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7952 __ isync();
7953 } else {
7954 __ sync();
7955 }
7956 %}
7957 ins_pipe(pipe_class_default);
7958 %}
7959
7960 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
7961 match(Set res (GetAndSetP mem_ptr src));
7962 predicate(n->as_LoadStore()->barrier_data() == 0);
7963 effect(TEMP_DEF res, TEMP cr0);
7964 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
7965 ins_encode %{
7966 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7967 MacroAssembler::cmpxchgx_hint_atomic_update());
7968 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7969 __ isync();
7970 } else {
7971 __ sync();
7972 }
7973 %}
7974 ins_pipe(pipe_class_default);
7975 %}
7976
7977 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
7978 match(Set res (GetAndSetN mem_ptr src));
7979 predicate(n->as_LoadStore()->barrier_data() == 0);
7980 effect(TEMP_DEF res, TEMP cr0);
7981 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
7982 ins_encode %{
7983 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7984 MacroAssembler::cmpxchgx_hint_atomic_update());
7985 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7986 __ isync();
7987 } else {
7988 __ sync();
7989 }
7990 %}
7991 ins_pipe(pipe_class_default);
7992 %}
7993
7994 //----------Arithmetic Instructions--------------------------------------------
7995 // Addition Instructions
7996
7997 // Register Addition
7998 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
7999 match(Set dst (AddI src1 src2));
8000 format %{ "ADD $dst, $src1, $src2" %}
8001 size(4);
8002 ins_encode %{
8003 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8004 %}
8005 ins_pipe(pipe_class_default);
8006 %}
8007
8008 // Expand does not work with above instruct. (??)
8009 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8010 // no match-rule
8011 effect(DEF dst, USE src1, USE src2);
8012 format %{ "ADD $dst, $src1, $src2" %}
8013 size(4);
8014 ins_encode %{
8015 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8016 %}
8017 ins_pipe(pipe_class_default);
8018 %}
8019
8020 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
8021 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
8022 ins_cost(DEFAULT_COST*3);
8023
8024 expand %{
8025 // FIXME: we should do this in the ideal world.
8026 iRegIdst tmp1;
8027 iRegIdst tmp2;
8028 addI_reg_reg(tmp1, src1, src2);
8029 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
8030 addI_reg_reg(dst, tmp1, tmp2);
8031 %}
8032 %}
8033
8034 // Immediate Addition
8035 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8036 match(Set dst (AddI src1 src2));
8037 format %{ "ADDI $dst, $src1, $src2" %}
8038 size(4);
8039 ins_encode %{
8040 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8041 %}
8042 ins_pipe(pipe_class_default);
8043 %}
8044
8045 // Immediate Addition with 16-bit shifted operand
8046 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
8047 match(Set dst (AddI src1 src2));
8048 format %{ "ADDIS $dst, $src1, $src2" %}
8049 size(4);
8050 ins_encode %{
8051 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8052 %}
8053 ins_pipe(pipe_class_default);
8054 %}
8055
8056 // Immediate Addition using prefixed addi
8057 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{
8058 match(Set dst (AddI src1 src2));
8059 predicate(PowerArchitecturePPC64 >= 10);
8060 ins_cost(DEFAULT_COST+1);
8061 format %{ "PADDI $dst, $src1, $src2" %}
8062 size(8);
8063 ins_encode %{
8064 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8065 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8066 %}
8067 ins_pipe(pipe_class_default);
8068 ins_alignment(2);
8069 %}
8070
8071 // Long Addition
8072 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8073 match(Set dst (AddL src1 src2));
8074 format %{ "ADD $dst, $src1, $src2 \t// long" %}
8075 size(4);
8076 ins_encode %{
8077 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8078 %}
8079 ins_pipe(pipe_class_default);
8080 %}
8081
8082 // Expand does not work with above instruct. (??)
8083 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8084 // no match-rule
8085 effect(DEF dst, USE src1, USE src2);
8086 format %{ "ADD $dst, $src1, $src2 \t// long" %}
8087 size(4);
8088 ins_encode %{
8089 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8090 %}
8091 ins_pipe(pipe_class_default);
8092 %}
8093
8094 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
8095 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
8096 ins_cost(DEFAULT_COST*3);
8097
8098 expand %{
8099 // FIXME: we should do this in the ideal world.
8100 iRegLdst tmp1;
8101 iRegLdst tmp2;
8102 addL_reg_reg(tmp1, src1, src2);
8103 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
8104 addL_reg_reg(dst, tmp1, tmp2);
8105 %}
8106 %}
8107
8108 // AddL + ConvL2I.
8109 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8110 match(Set dst (ConvL2I (AddL src1 src2)));
8111
8112 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %}
8113 size(4);
8114 ins_encode %{
8115 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8116 %}
8117 ins_pipe(pipe_class_default);
8118 %}
8119
8120 // No constant pool entries required.
8121 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8122 match(Set dst (AddL src1 src2));
8123
8124 format %{ "ADDI $dst, $src1, $src2" %}
8125 size(4);
8126 ins_encode %{
8127 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8128 %}
8129 ins_pipe(pipe_class_default);
8130 %}
8131
8132 // Long Immediate Addition with 16-bit shifted operand.
8133 // No constant pool entries required.
8134 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
8135 match(Set dst (AddL src1 src2));
8136
8137 format %{ "ADDIS $dst, $src1, $src2" %}
8138 size(4);
8139 ins_encode %{
8140 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8141 %}
8142 ins_pipe(pipe_class_default);
8143 %}
8144
8145 // Long Immediate Addition using prefixed addi
8146 // No constant pool entries required.
8147 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{
8148 match(Set dst (AddL src1 src2));
8149 predicate(PowerArchitecturePPC64 >= 10);
8150 ins_cost(DEFAULT_COST+1);
8151
8152 format %{ "PADDI $dst, $src1, $src2" %}
8153 size(8);
8154 ins_encode %{
8155 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8156 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8157 %}
8158 ins_pipe(pipe_class_default);
8159 ins_alignment(2);
8160 %}
8161
8162 // Pointer Register Addition
8163 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
8164 match(Set dst (AddP src1 src2));
8165 format %{ "ADD $dst, $src1, $src2" %}
8166 size(4);
8167 ins_encode %{
8168 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8169 %}
8170 ins_pipe(pipe_class_default);
8171 %}
8172
8173 // Pointer Immediate Addition
8174 // No constant pool entries required.
8175 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
8176 match(Set dst (AddP src1 src2));
8177
8178 format %{ "ADDI $dst, $src1, $src2" %}
8179 size(4);
8180 ins_encode %{
8181 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8182 %}
8183 ins_pipe(pipe_class_default);
8184 %}
8185
8186 // Pointer Immediate Addition with 16-bit shifted operand.
8187 // No constant pool entries required.
8188 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
8189 match(Set dst (AddP src1 src2));
8190
8191 format %{ "ADDIS $dst, $src1, $src2" %}
8192 size(4);
8193 ins_encode %{
8194 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8195 %}
8196 ins_pipe(pipe_class_default);
8197 %}
8198
8199 // Pointer Immediate Addition using prefixed addi
8200 // No constant pool entries required.
8201 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{
8202 match(Set dst (AddP src1 src2));
8203 predicate(PowerArchitecturePPC64 >= 10);
8204 ins_cost(DEFAULT_COST+1);
8205
8206 format %{ "PADDI $dst, $src1, $src2" %}
8207 size(8);
8208 ins_encode %{
8209 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8210 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8211 %}
8212 ins_pipe(pipe_class_default);
8213 ins_alignment(2);
8214 %}
8215
8216 //---------------------
8217 // Subtraction Instructions
8218
8219 // Register Subtraction
8220 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8221 match(Set dst (SubI src1 src2));
8222 format %{ "SUBF $dst, $src2, $src1" %}
8223 size(4);
8224 ins_encode %{
8225 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8226 %}
8227 ins_pipe(pipe_class_default);
8228 %}
8229
8230 // Immediate Subtraction
8231 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
8232 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
8233
8234 // SubI from constant (using subfic).
8235 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
8236 match(Set dst (SubI src1 src2));
8237 format %{ "SUBI $dst, $src1, $src2" %}
8238
8239 size(4);
8240 ins_encode %{
8241 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
8242 %}
8243 ins_pipe(pipe_class_default);
8244 %}
8245
8246 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
8247 // positive integers and 0xF...F for negative ones.
8248 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
8249 // no match-rule, false predicate
8250 effect(DEF dst, USE src);
8251 predicate(false);
8252
8253 format %{ "SRAWI $dst, $src, #31" %}
8254 size(4);
8255 ins_encode %{
8256 __ srawi($dst$$Register, $src$$Register, 0x1f);
8257 %}
8258 ins_pipe(pipe_class_default);
8259 %}
8260
8261 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
8262 match(Set dst (AbsI src));
8263 ins_cost(DEFAULT_COST*3);
8264
8265 expand %{
8266 iRegIdst tmp1;
8267 iRegIdst tmp2;
8268 signmask32I_regI(tmp1, src);
8269 xorI_reg_reg(tmp2, tmp1, src);
8270 subI_reg_reg(dst, tmp2, tmp1);
8271 %}
8272 %}
8273
8274 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
8275 match(Set dst (SubI zero src2));
8276 format %{ "NEG $dst, $src2" %}
8277 size(4);
8278 ins_encode %{
8279 __ neg($dst$$Register, $src2$$Register);
8280 %}
8281 ins_pipe(pipe_class_default);
8282 %}
8283
8284 // Long subtraction
8285 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8286 match(Set dst (SubL src1 src2));
8287 format %{ "SUBF $dst, $src2, $src1 \t// long" %}
8288 size(4);
8289 ins_encode %{
8290 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8291 %}
8292 ins_pipe(pipe_class_default);
8293 %}
8294
8295 // SubL + convL2I.
8296 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8297 match(Set dst (ConvL2I (SubL src1 src2)));
8298
8299 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
8300 size(4);
8301 ins_encode %{
8302 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8303 %}
8304 ins_pipe(pipe_class_default);
8305 %}
8306
8307 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8308 // positive longs and 0xF...F for negative ones.
8309 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8310 // no match-rule, false predicate
8311 effect(DEF dst, USE src);
8312 predicate(false);
8313
8314 format %{ "SRADI $dst, $src, #63" %}
8315 size(4);
8316 ins_encode %{
8317 __ sradi($dst$$Register, $src$$Register, 0x3f);
8318 %}
8319 ins_pipe(pipe_class_default);
8320 %}
8321
8322 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8323 // positive longs and 0xF...F for negative ones.
8324 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8325 // no match-rule, false predicate
8326 effect(DEF dst, USE src);
8327 predicate(false);
8328
8329 format %{ "SRADI $dst, $src, #63" %}
8330 size(4);
8331 ins_encode %{
8332 __ sradi($dst$$Register, $src$$Register, 0x3f);
8333 %}
8334 ins_pipe(pipe_class_default);
8335 %}
8336
8337 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{
8338 match(Set dst (AbsL src));
8339 ins_cost(DEFAULT_COST*3);
8340
8341 expand %{
8342 iRegLdst tmp1;
8343 iRegLdst tmp2;
8344 signmask64L_regL(tmp1, src);
8345 xorL_reg_reg(tmp2, tmp1, src);
8346 subL_reg_reg(dst, tmp2, tmp1);
8347 %}
8348 %}
8349
8350 // Long negation
8351 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8352 match(Set dst (SubL zero src2));
8353 format %{ "NEG $dst, $src2 \t// long" %}
8354 size(4);
8355 ins_encode %{
8356 __ neg($dst$$Register, $src2$$Register);
8357 %}
8358 ins_pipe(pipe_class_default);
8359 %}
8360
8361 // NegL + ConvL2I.
8362 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8363 match(Set dst (ConvL2I (SubL zero src2)));
8364
8365 format %{ "NEG $dst, $src2 \t// long + l2i" %}
8366 size(4);
8367 ins_encode %{
8368 __ neg($dst$$Register, $src2$$Register);
8369 %}
8370 ins_pipe(pipe_class_default);
8371 %}
8372
8373 // Multiplication Instructions
8374 // Integer Multiplication
8375
8376 // Register Multiplication
8377 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8378 match(Set dst (MulI src1 src2));
8379 ins_cost(DEFAULT_COST);
8380
8381 format %{ "MULLW $dst, $src1, $src2" %}
8382 size(4);
8383 ins_encode %{
8384 __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8385 %}
8386 ins_pipe(pipe_class_default);
8387 %}
8388
8389 // Immediate Multiplication
8390 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8391 match(Set dst (MulI src1 src2));
8392 ins_cost(DEFAULT_COST);
8393
8394 format %{ "MULLI $dst, $src1, $src2" %}
8395 size(4);
8396 ins_encode %{
8397 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8398 %}
8399 ins_pipe(pipe_class_default);
8400 %}
8401
8402 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8403 match(Set dst (MulL src1 src2));
8404 ins_cost(DEFAULT_COST);
8405
8406 format %{ "MULLD $dst $src1, $src2 \t// long" %}
8407 size(4);
8408 ins_encode %{
8409 __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8410 %}
8411 ins_pipe(pipe_class_default);
8412 %}
8413
8414 // Multiply high for optimized long division by constant.
8415 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8416 match(Set dst (MulHiL src1 src2));
8417 ins_cost(DEFAULT_COST);
8418
8419 format %{ "MULHD $dst $src1, $src2 \t// long" %}
8420 size(4);
8421 ins_encode %{
8422 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8423 %}
8424 ins_pipe(pipe_class_default);
8425 %}
8426
8427 instruct uMulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8428 match(Set dst (UMulHiL src1 src2));
8429 ins_cost(DEFAULT_COST);
8430
8431 format %{ "MULHDU $dst $src1, $src2 \t// unsigned long" %}
8432 size(4);
8433 ins_encode %{
8434 __ mulhdu($dst$$Register, $src1$$Register, $src2$$Register);
8435 %}
8436 ins_pipe(pipe_class_default);
8437 %}
8438
8439 // Immediate Multiplication
8440 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8441 match(Set dst (MulL src1 src2));
8442 ins_cost(DEFAULT_COST);
8443
8444 format %{ "MULLI $dst, $src1, $src2" %}
8445 size(4);
8446 ins_encode %{
8447 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8448 %}
8449 ins_pipe(pipe_class_default);
8450 %}
8451
8452 // Integer Division with Immediate -1: Negate.
8453 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8454 match(Set dst (DivI src1 src2));
8455 ins_cost(DEFAULT_COST);
8456
8457 format %{ "NEG $dst, $src1 \t// /-1" %}
8458 size(4);
8459 ins_encode %{
8460 __ neg($dst$$Register, $src1$$Register);
8461 %}
8462 ins_pipe(pipe_class_default);
8463 %}
8464
8465 // Integer Division with constant, but not -1.
8466 // We should be able to improve this by checking the type of src2.
8467 // It might well be that src2 is known to be positive.
8468 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8469 match(Set dst (DivI src1 src2));
8470 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8471 ins_cost(2*DEFAULT_COST);
8472
8473 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8474 size(4);
8475 ins_encode %{
8476 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8477 %}
8478 ins_pipe(pipe_class_default);
8479 %}
8480
8481 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8482 effect(USE_DEF dst, USE src1, USE crx);
8483 predicate(false);
8484
8485 ins_variable_size_depending_on_alignment(true);
8486
8487 format %{ "CMOVE $dst, neg($src1), $crx" %}
8488 size(8);
8489 ins_encode %{
8490 Label done;
8491 __ bne($crx$$CondRegister, done);
8492 __ neg($dst$$Register, $src1$$Register);
8493 __ bind(done);
8494 %}
8495 ins_pipe(pipe_class_default);
8496 %}
8497
8498 // Integer Division with Registers not containing constants.
8499 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8500 match(Set dst (DivI src1 src2));
8501 ins_cost(10*DEFAULT_COST);
8502
8503 expand %{
8504 immI16 imm %{ (int)-1 %}
8505 flagsReg tmp1;
8506 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8507 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8508 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8509 %}
8510 %}
8511
8512 // Long Division with Immediate -1: Negate.
8513 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8514 match(Set dst (DivL src1 src2));
8515 ins_cost(DEFAULT_COST);
8516
8517 format %{ "NEG $dst, $src1 \t// /-1, long" %}
8518 size(4);
8519 ins_encode %{
8520 __ neg($dst$$Register, $src1$$Register);
8521 %}
8522 ins_pipe(pipe_class_default);
8523 %}
8524
8525 // Long Division with constant, but not -1.
8526 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8527 match(Set dst (DivL src1 src2));
8528 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8529 ins_cost(2*DEFAULT_COST);
8530
8531 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8532 size(4);
8533 ins_encode %{
8534 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8535 %}
8536 ins_pipe(pipe_class_default);
8537 %}
8538
8539 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8540 effect(USE_DEF dst, USE src1, USE crx);
8541 predicate(false);
8542
8543 ins_variable_size_depending_on_alignment(true);
8544
8545 format %{ "CMOVE $dst, neg($src1), $crx" %}
8546 size(8);
8547 ins_encode %{
8548 Label done;
8549 __ bne($crx$$CondRegister, done);
8550 __ neg($dst$$Register, $src1$$Register);
8551 __ bind(done);
8552 %}
8553 ins_pipe(pipe_class_default);
8554 %}
8555
8556 // Long Division with Registers not containing constants.
8557 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8558 match(Set dst (DivL src1 src2));
8559 ins_cost(10*DEFAULT_COST);
8560
8561 expand %{
8562 immL16 imm %{ (int)-1 %}
8563 flagsReg tmp1;
8564 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8565 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8566 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8567 %}
8568 %}
8569
8570 // Integer Remainder with registers.
8571 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8572 match(Set dst (ModI src1 src2));
8573 ins_cost(10*DEFAULT_COST);
8574
8575 expand %{
8576 immI16 imm %{ (int)-1 %}
8577 flagsReg tmp1;
8578 iRegIdst tmp2;
8579 iRegIdst tmp3;
8580 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8581 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8582 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8583 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8584 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8585 %}
8586 %}
8587
8588 // Long Remainder with registers
8589 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8590 match(Set dst (ModL src1 src2));
8591 ins_cost(10*DEFAULT_COST);
8592
8593 expand %{
8594 immL16 imm %{ (int)-1 %}
8595 flagsReg tmp1;
8596 iRegLdst tmp2;
8597 iRegLdst tmp3;
8598 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8599 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8600 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8601 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8602 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8603 %}
8604 %}
8605
8606 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8607 match(Set dst (UDivI src1 src2));
8608 format %{ "DIVWU $dst, $src1, $src2" %}
8609 size(4);
8610 ins_encode %{
8611 __ divwu($dst$$Register, $src1$$Register, $src2$$Register);
8612 %}
8613 ins_pipe(pipe_class_default);
8614 %}
8615
8616 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8617 match(Set dst (UModI src1 src2));
8618 expand %{
8619 iRegIdst tmp1;
8620 iRegIdst tmp2;
8621 udivI_reg_reg(tmp1, src1, src2);
8622 // Compute lower 32 bit result using signed instructions as suggested by ISA.
8623 // Upper 32 bit will contain garbage.
8624 mulI_reg_reg(tmp2, src2, tmp1);
8625 subI_reg_reg(dst, src1, tmp2);
8626 %}
8627 %}
8628
8629 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8630 match(Set dst (UDivL src1 src2));
8631 format %{ "DIVDU $dst, $src1, $src2" %}
8632 size(4);
8633 ins_encode %{
8634 __ divdu($dst$$Register, $src1$$Register, $src2$$Register);
8635 %}
8636 ins_pipe(pipe_class_default);
8637 %}
8638
8639 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8640 match(Set dst (UModL src1 src2));
8641 expand %{
8642 iRegLdst tmp1;
8643 iRegLdst tmp2;
8644 udivL_reg_reg(tmp1, src1, src2);
8645 mulL_reg_reg(tmp2, src2, tmp1);
8646 subL_reg_reg(dst, src1, tmp2);
8647 %}
8648 %}
8649
8650 // Integer Shift Instructions
8651
8652 // Register Shift Left
8653
8654 // Clear all but the lowest #mask bits.
8655 // Used to normalize shift amounts in registers.
8656 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
8657 // no match-rule, false predicate
8658 effect(DEF dst, USE src, USE mask);
8659 predicate(false);
8660
8661 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %}
8662 size(4);
8663 ins_encode %{
8664 __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
8665 %}
8666 ins_pipe(pipe_class_default);
8667 %}
8668
8669 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8670 // no match-rule, false predicate
8671 effect(DEF dst, USE src1, USE src2);
8672 predicate(false);
8673
8674 format %{ "SLW $dst, $src1, $src2" %}
8675 size(4);
8676 ins_encode %{
8677 __ slw($dst$$Register, $src1$$Register, $src2$$Register);
8678 %}
8679 ins_pipe(pipe_class_default);
8680 %}
8681
8682 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8683 match(Set dst (LShiftI src1 src2));
8684 ins_cost(DEFAULT_COST*2);
8685 expand %{
8686 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8687 iRegIdst tmpI;
8688 maskI_reg_imm(tmpI, src2, mask);
8689 lShiftI_reg_reg(dst, src1, tmpI);
8690 %}
8691 %}
8692
8693 // Register Shift Left Immediate
8694 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8695 match(Set dst (LShiftI src1 src2));
8696
8697 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %}
8698 size(4);
8699 ins_encode %{
8700 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8701 %}
8702 ins_pipe(pipe_class_default);
8703 %}
8704
8705 // AndI with negpow2-constant + LShiftI
8706 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8707 match(Set dst (LShiftI (AndI src1 src2) src3));
8708 predicate(UseRotateAndMaskInstructionsPPC64);
8709
8710 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %}
8711 size(4);
8712 ins_encode %{
8713 long src3 = $src3$$constant;
8714 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8715 if (maskbits >= 32) {
8716 __ li($dst$$Register, 0); // addi
8717 } else {
8718 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
8719 }
8720 %}
8721 ins_pipe(pipe_class_default);
8722 %}
8723
8724 // RShiftI + AndI with negpow2-constant + LShiftI
8725 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8726 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
8727 predicate(UseRotateAndMaskInstructionsPPC64);
8728
8729 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
8730 size(4);
8731 ins_encode %{
8732 long src3 = $src3$$constant;
8733 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8734 if (maskbits >= 32) {
8735 __ li($dst$$Register, 0); // addi
8736 } else {
8737 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
8738 }
8739 %}
8740 ins_pipe(pipe_class_default);
8741 %}
8742
8743 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8744 // no match-rule, false predicate
8745 effect(DEF dst, USE src1, USE src2);
8746 predicate(false);
8747
8748 format %{ "SLD $dst, $src1, $src2" %}
8749 size(4);
8750 ins_encode %{
8751 __ sld($dst$$Register, $src1$$Register, $src2$$Register);
8752 %}
8753 ins_pipe(pipe_class_default);
8754 %}
8755
8756 // Register Shift Left
8757 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8758 match(Set dst (LShiftL src1 src2));
8759 ins_cost(DEFAULT_COST*2);
8760 expand %{
8761 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8762 iRegIdst tmpI;
8763 maskI_reg_imm(tmpI, src2, mask);
8764 lShiftL_regL_regI(dst, src1, tmpI);
8765 %}
8766 %}
8767
8768 // Register Shift Left Immediate
8769 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8770 match(Set dst (LShiftL src1 src2));
8771 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %}
8772 size(4);
8773 ins_encode %{
8774 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8775 %}
8776 ins_pipe(pipe_class_default);
8777 %}
8778
8779 // If we shift more than 32 bits, we need not convert I2L.
8780 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
8781 match(Set dst (LShiftL (ConvI2L src1) src2));
8782 ins_cost(DEFAULT_COST);
8783
8784 size(4);
8785 format %{ "SLDI $dst, i2l($src1), $src2" %}
8786 ins_encode %{
8787 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8788 %}
8789 ins_pipe(pipe_class_default);
8790 %}
8791
8792 // Shift a postivie int to the left.
8793 // Clrlsldi clears the upper 32 bits and shifts.
8794 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
8795 match(Set dst (LShiftL (ConvI2L src1) src2));
8796 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
8797
8798 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %}
8799 size(4);
8800 ins_encode %{
8801 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
8802 %}
8803 ins_pipe(pipe_class_default);
8804 %}
8805
8806 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8807 // no match-rule, false predicate
8808 effect(DEF dst, USE src1, USE src2);
8809 predicate(false);
8810
8811 format %{ "SRAW $dst, $src1, $src2" %}
8812 size(4);
8813 ins_encode %{
8814 __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
8815 %}
8816 ins_pipe(pipe_class_default);
8817 %}
8818
8819 // Register Arithmetic Shift Right
8820 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8821 match(Set dst (RShiftI src1 src2));
8822 ins_cost(DEFAULT_COST*2);
8823 expand %{
8824 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8825 iRegIdst tmpI;
8826 maskI_reg_imm(tmpI, src2, mask);
8827 arShiftI_reg_reg(dst, src1, tmpI);
8828 %}
8829 %}
8830
8831 // Register Arithmetic Shift Right Immediate
8832 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8833 match(Set dst (RShiftI src1 src2));
8834
8835 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %}
8836 size(4);
8837 ins_encode %{
8838 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8839 %}
8840 ins_pipe(pipe_class_default);
8841 %}
8842
8843 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8844 // no match-rule, false predicate
8845 effect(DEF dst, USE src1, USE src2);
8846 predicate(false);
8847
8848 format %{ "SRAD $dst, $src1, $src2" %}
8849 size(4);
8850 ins_encode %{
8851 __ srad($dst$$Register, $src1$$Register, $src2$$Register);
8852 %}
8853 ins_pipe(pipe_class_default);
8854 %}
8855
8856 // Register Shift Right Arithmetic Long
8857 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8858 match(Set dst (RShiftL src1 src2));
8859 ins_cost(DEFAULT_COST*2);
8860
8861 expand %{
8862 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8863 iRegIdst tmpI;
8864 maskI_reg_imm(tmpI, src2, mask);
8865 arShiftL_regL_regI(dst, src1, tmpI);
8866 %}
8867 %}
8868
8869 // Register Shift Right Immediate
8870 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8871 match(Set dst (RShiftL src1 src2));
8872
8873 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %}
8874 size(4);
8875 ins_encode %{
8876 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8877 %}
8878 ins_pipe(pipe_class_default);
8879 %}
8880
8881 // RShiftL + ConvL2I
8882 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8883 match(Set dst (ConvL2I (RShiftL src1 src2)));
8884
8885 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8886 size(4);
8887 ins_encode %{
8888 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8889 %}
8890 ins_pipe(pipe_class_default);
8891 %}
8892
8893 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8894 // no match-rule, false predicate
8895 effect(DEF dst, USE src1, USE src2);
8896 predicate(false);
8897
8898 format %{ "SRW $dst, $src1, $src2" %}
8899 size(4);
8900 ins_encode %{
8901 __ srw($dst$$Register, $src1$$Register, $src2$$Register);
8902 %}
8903 ins_pipe(pipe_class_default);
8904 %}
8905
8906 // Register Shift Right
8907 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8908 match(Set dst (URShiftI src1 src2));
8909 ins_cost(DEFAULT_COST*2);
8910
8911 expand %{
8912 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8913 iRegIdst tmpI;
8914 maskI_reg_imm(tmpI, src2, mask);
8915 urShiftI_reg_reg(dst, src1, tmpI);
8916 %}
8917 %}
8918
8919 // Register Shift Right Immediate
8920 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8921 match(Set dst (URShiftI src1 src2));
8922
8923 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %}
8924 size(4);
8925 ins_encode %{
8926 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8927 %}
8928 ins_pipe(pipe_class_default);
8929 %}
8930
8931 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8932 // no match-rule, false predicate
8933 effect(DEF dst, USE src1, USE src2);
8934 predicate(false);
8935
8936 format %{ "SRD $dst, $src1, $src2" %}
8937 size(4);
8938 ins_encode %{
8939 __ srd($dst$$Register, $src1$$Register, $src2$$Register);
8940 %}
8941 ins_pipe(pipe_class_default);
8942 %}
8943
8944 // Register Shift Right
8945 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8946 match(Set dst (URShiftL src1 src2));
8947 ins_cost(DEFAULT_COST*2);
8948
8949 expand %{
8950 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8951 iRegIdst tmpI;
8952 maskI_reg_imm(tmpI, src2, mask);
8953 urShiftL_regL_regI(dst, src1, tmpI);
8954 %}
8955 %}
8956
8957 // Register Shift Right Immediate
8958 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8959 match(Set dst (URShiftL src1 src2));
8960
8961 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %}
8962 size(4);
8963 ins_encode %{
8964 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8965 %}
8966 ins_pipe(pipe_class_default);
8967 %}
8968
8969 // URShiftL + ConvL2I.
8970 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8971 match(Set dst (ConvL2I (URShiftL src1 src2)));
8972
8973 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8974 size(4);
8975 ins_encode %{
8976 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8977 %}
8978 ins_pipe(pipe_class_default);
8979 %}
8980
8981 // Register Shift Right Immediate with a CastP2X
8982 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
8983 match(Set dst (URShiftL (CastP2X src1) src2));
8984
8985 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
8986 size(4);
8987 ins_encode %{
8988 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8989 %}
8990 ins_pipe(pipe_class_default);
8991 %}
8992
8993 // Bitfield Extract: URShiftI + AndI
8994 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
8995 match(Set dst (AndI (URShiftI src1 src2) src3));
8996
8997 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
8998 size(4);
8999 ins_encode %{
9000 int rshift = ($src2$$constant) & 0x1f;
9001 int length = log2i_exact((juint)$src3$$constant + 1u);
9002 if (rshift + length > 32) {
9003 // if necessary, adjust mask to omit rotated bits.
9004 length = 32 - rshift;
9005 }
9006 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
9007 %}
9008 ins_pipe(pipe_class_default);
9009 %}
9010
9011 // Bitfield Extract: URShiftL + AndL
9012 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
9013 match(Set dst (AndL (URShiftL src1 src2) src3));
9014
9015 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
9016 size(4);
9017 ins_encode %{
9018 int rshift = ($src2$$constant) & 0x3f;
9019 int length = log2i_exact((julong)$src3$$constant + 1ull);
9020 if (rshift + length > 64) {
9021 // if necessary, adjust mask to omit rotated bits.
9022 length = 64 - rshift;
9023 }
9024 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
9025 %}
9026 ins_pipe(pipe_class_default);
9027 %}
9028
9029 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
9030 match(Set dst (ConvL2I (ConvI2L src)));
9031
9032 format %{ "EXTSW $dst, $src \t// int->int" %}
9033 size(4);
9034 ins_encode %{
9035 __ extsw($dst$$Register, $src$$Register);
9036 %}
9037 ins_pipe(pipe_class_default);
9038 %}
9039
9040 //----------Rotate Instructions------------------------------------------------
9041
9042 // Rotate Left by 8-bit immediate
9043 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
9044 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
9045 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9046
9047 format %{ "ROTLWI $dst, $src, $lshift" %}
9048 size(4);
9049 ins_encode %{
9050 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
9051 %}
9052 ins_pipe(pipe_class_default);
9053 %}
9054
9055 // Rotate Right by 8-bit immediate
9056 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
9057 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
9058 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9059
9060 format %{ "ROTRWI $dst, $rshift" %}
9061 size(4);
9062 ins_encode %{
9063 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
9064 %}
9065 ins_pipe(pipe_class_default);
9066 %}
9067
9068 //----------Floating Point Arithmetic Instructions-----------------------------
9069
9070 // Add float single precision
9071 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
9072 match(Set dst (AddF src1 src2));
9073
9074 format %{ "FADDS $dst, $src1, $src2" %}
9075 size(4);
9076 ins_encode %{
9077 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9078 %}
9079 ins_pipe(pipe_class_default);
9080 %}
9081
9082 // Add float double precision
9083 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
9084 match(Set dst (AddD src1 src2));
9085
9086 format %{ "FADD $dst, $src1, $src2" %}
9087 size(4);
9088 ins_encode %{
9089 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9090 %}
9091 ins_pipe(pipe_class_default);
9092 %}
9093
9094 // Sub float single precision
9095 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
9096 match(Set dst (SubF src1 src2));
9097
9098 format %{ "FSUBS $dst, $src1, $src2" %}
9099 size(4);
9100 ins_encode %{
9101 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9102 %}
9103 ins_pipe(pipe_class_default);
9104 %}
9105
9106 // Sub float double precision
9107 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
9108 match(Set dst (SubD src1 src2));
9109 format %{ "FSUB $dst, $src1, $src2" %}
9110 size(4);
9111 ins_encode %{
9112 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9113 %}
9114 ins_pipe(pipe_class_default);
9115 %}
9116
9117 // Mul float single precision
9118 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
9119 match(Set dst (MulF src1 src2));
9120 format %{ "FMULS $dst, $src1, $src2" %}
9121 size(4);
9122 ins_encode %{
9123 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9124 %}
9125 ins_pipe(pipe_class_default);
9126 %}
9127
9128 // Mul float double precision
9129 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
9130 match(Set dst (MulD src1 src2));
9131 format %{ "FMUL $dst, $src1, $src2" %}
9132 size(4);
9133 ins_encode %{
9134 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9135 %}
9136 ins_pipe(pipe_class_default);
9137 %}
9138
9139 // Div float single precision
9140 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
9141 match(Set dst (DivF src1 src2));
9142 format %{ "FDIVS $dst, $src1, $src2" %}
9143 size(4);
9144 ins_encode %{
9145 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9146 %}
9147 ins_pipe(pipe_class_default);
9148 %}
9149
9150 // Div float double precision
9151 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
9152 match(Set dst (DivD src1 src2));
9153 format %{ "FDIV $dst, $src1, $src2" %}
9154 size(4);
9155 ins_encode %{
9156 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9157 %}
9158 ins_pipe(pipe_class_default);
9159 %}
9160
9161 // Absolute float single precision
9162 instruct absF_reg(regF dst, regF src) %{
9163 match(Set dst (AbsF src));
9164 format %{ "FABS $dst, $src \t// float" %}
9165 size(4);
9166 ins_encode %{
9167 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
9168 %}
9169 ins_pipe(pipe_class_default);
9170 %}
9171
9172 // Absolute float double precision
9173 instruct absD_reg(regD dst, regD src) %{
9174 match(Set dst (AbsD src));
9175 format %{ "FABS $dst, $src \t// double" %}
9176 size(4);
9177 ins_encode %{
9178 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
9179 %}
9180 ins_pipe(pipe_class_default);
9181 %}
9182
9183 instruct negF_reg(regF dst, regF src) %{
9184 match(Set dst (NegF src));
9185 format %{ "FNEG $dst, $src \t// float" %}
9186 size(4);
9187 ins_encode %{
9188 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
9189 %}
9190 ins_pipe(pipe_class_default);
9191 %}
9192
9193 instruct negD_reg(regD dst, regD src) %{
9194 match(Set dst (NegD src));
9195 format %{ "FNEG $dst, $src \t// double" %}
9196 size(4);
9197 ins_encode %{
9198 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
9199 %}
9200 ins_pipe(pipe_class_default);
9201 %}
9202
9203 // AbsF + NegF.
9204 instruct negF_absF_reg(regF dst, regF src) %{
9205 match(Set dst (NegF (AbsF src)));
9206 format %{ "FNABS $dst, $src \t// float" %}
9207 size(4);
9208 ins_encode %{
9209 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9210 %}
9211 ins_pipe(pipe_class_default);
9212 %}
9213
9214 // AbsD + NegD.
9215 instruct negD_absD_reg(regD dst, regD src) %{
9216 match(Set dst (NegD (AbsD src)));
9217 format %{ "FNABS $dst, $src \t// double" %}
9218 size(4);
9219 ins_encode %{
9220 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9221 %}
9222 ins_pipe(pipe_class_default);
9223 %}
9224
9225 // Sqrt float double precision
9226 instruct sqrtD_reg(regD dst, regD src) %{
9227 match(Set dst (SqrtD src));
9228 format %{ "FSQRT $dst, $src" %}
9229 size(4);
9230 ins_encode %{
9231 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
9232 %}
9233 ins_pipe(pipe_class_default);
9234 %}
9235
9236 // Single-precision sqrt.
9237 instruct sqrtF_reg(regF dst, regF src) %{
9238 match(Set dst (SqrtF src));
9239 ins_cost(DEFAULT_COST);
9240
9241 format %{ "FSQRTS $dst, $src" %}
9242 size(4);
9243 ins_encode %{
9244 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
9245 %}
9246 ins_pipe(pipe_class_default);
9247 %}
9248
9249
9250 // Multiply-Accumulate
9251 // src1 * src2 + src3
9252 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9253 match(Set dst (FmaF src3 (Binary src1 src2)));
9254
9255 format %{ "FMADDS $dst, $src1, $src2, $src3" %}
9256 size(4);
9257 ins_encode %{
9258 assert(UseFMA, "Needs FMA instructions support.");
9259 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9260 %}
9261 ins_pipe(pipe_class_default);
9262 %}
9263
9264 // src1 * src2 + src3
9265 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9266 match(Set dst (FmaD src3 (Binary src1 src2)));
9267
9268 format %{ "FMADD $dst, $src1, $src2, $src3" %}
9269 size(4);
9270 ins_encode %{
9271 assert(UseFMA, "Needs FMA instructions support.");
9272 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9273 %}
9274 ins_pipe(pipe_class_default);
9275 %}
9276
9277 // src1 * (-src2) + src3 = -(src1*src2-src3)
9278 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9279 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9280 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
9281
9282 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
9283 size(4);
9284 ins_encode %{
9285 assert(UseFMA, "Needs FMA instructions support.");
9286 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9287 %}
9288 ins_pipe(pipe_class_default);
9289 %}
9290
9291 // src1 * (-src2) + src3 = -(src1*src2-src3)
9292 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9293 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9294 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
9295
9296 format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
9297 size(4);
9298 ins_encode %{
9299 assert(UseFMA, "Needs FMA instructions support.");
9300 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9301 %}
9302 ins_pipe(pipe_class_default);
9303 %}
9304
9305 // src1 * (-src2) - src3 = -(src1*src2+src3)
9306 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9307 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9308 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
9309
9310 format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
9311 size(4);
9312 ins_encode %{
9313 assert(UseFMA, "Needs FMA instructions support.");
9314 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9315 %}
9316 ins_pipe(pipe_class_default);
9317 %}
9318
9319 // src1 * (-src2) - src3 = -(src1*src2+src3)
9320 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9321 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9322 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9323
9324 format %{ "FNMADD $dst, $src1, $src2, $src3" %}
9325 size(4);
9326 ins_encode %{
9327 assert(UseFMA, "Needs FMA instructions support.");
9328 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9329 %}
9330 ins_pipe(pipe_class_default);
9331 %}
9332
9333 // src1 * src2 - src3
9334 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9335 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9336
9337 format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
9338 size(4);
9339 ins_encode %{
9340 assert(UseFMA, "Needs FMA instructions support.");
9341 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9342 %}
9343 ins_pipe(pipe_class_default);
9344 %}
9345
9346 // src1 * src2 - src3
9347 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9348 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9349
9350 format %{ "FMSUB $dst, $src1, $src2, $src3" %}
9351 size(4);
9352 ins_encode %{
9353 assert(UseFMA, "Needs FMA instructions support.");
9354 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9355 %}
9356 ins_pipe(pipe_class_default);
9357 %}
9358
9359
9360 //----------Logical Instructions-----------------------------------------------
9361
9362 // And Instructions
9363
9364 // Register And
9365 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9366 match(Set dst (AndI src1 src2));
9367 format %{ "AND $dst, $src1, $src2" %}
9368 size(4);
9369 ins_encode %{
9370 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9371 %}
9372 ins_pipe(pipe_class_default);
9373 %}
9374
9375 // Left shifted Immediate And
9376 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{
9377 match(Set dst (AndI src1 src2));
9378 effect(KILL cr0);
9379 format %{ "ANDIS $dst, $src1, $src2.hi" %}
9380 size(4);
9381 ins_encode %{
9382 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16)));
9383 %}
9384 ins_pipe(pipe_class_default);
9385 %}
9386
9387 // Immediate And
9388 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{
9389 match(Set dst (AndI src1 src2));
9390 effect(KILL cr0);
9391
9392 format %{ "ANDI $dst, $src1, $src2" %}
9393 size(4);
9394 ins_encode %{
9395 // FIXME: avoid andi_ ?
9396 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9397 %}
9398 ins_pipe(pipe_class_default);
9399 %}
9400
9401 // Immediate And where the immediate is a negative power of 2.
9402 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{
9403 match(Set dst (AndI src1 src2));
9404 format %{ "ANDWI $dst, $src1, $src2" %}
9405 size(4);
9406 ins_encode %{
9407 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant));
9408 %}
9409 ins_pipe(pipe_class_default);
9410 %}
9411
9412 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{
9413 match(Set dst (AndI src1 src2));
9414 format %{ "ANDWI $dst, $src1, $src2" %}
9415 size(4);
9416 ins_encode %{
9417 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u));
9418 %}
9419 ins_pipe(pipe_class_default);
9420 %}
9421
9422 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{
9423 match(Set dst (AndI src1 src2));
9424 predicate(UseRotateAndMaskInstructionsPPC64);
9425 format %{ "ANDWI $dst, $src1, $src2" %}
9426 size(4);
9427 ins_encode %{
9428 int bitpos = 31 - log2i_exact((juint)$src2$$constant);
9429 __ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos);
9430 %}
9431 ins_pipe(pipe_class_default);
9432 %}
9433
9434 // Register And Long
9435 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9436 match(Set dst (AndL src1 src2));
9437 ins_cost(DEFAULT_COST);
9438
9439 format %{ "AND $dst, $src1, $src2 \t// long" %}
9440 size(4);
9441 ins_encode %{
9442 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9443 %}
9444 ins_pipe(pipe_class_default);
9445 %}
9446
9447 // Immediate And long
9448 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
9449 match(Set dst (AndL src1 src2));
9450 effect(KILL cr0);
9451
9452 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9453 size(4);
9454 ins_encode %{
9455 // FIXME: avoid andi_ ?
9456 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9457 %}
9458 ins_pipe(pipe_class_default);
9459 %}
9460
9461 // Immediate And Long where the immediate is a negative power of 2.
9462 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
9463 match(Set dst (AndL src1 src2));
9464 format %{ "ANDDI $dst, $src1, $src2" %}
9465 size(4);
9466 ins_encode %{
9467 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant));
9468 %}
9469 ins_pipe(pipe_class_default);
9470 %}
9471
9472 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9473 match(Set dst (AndL src1 src2));
9474 format %{ "ANDDI $dst, $src1, $src2" %}
9475 size(4);
9476 ins_encode %{
9477 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9478 %}
9479 ins_pipe(pipe_class_default);
9480 %}
9481
9482 // AndL + ConvL2I.
9483 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9484 match(Set dst (ConvL2I (AndL src1 src2)));
9485 ins_cost(DEFAULT_COST);
9486
9487 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %}
9488 size(4);
9489 ins_encode %{
9490 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9491 %}
9492 ins_pipe(pipe_class_default);
9493 %}
9494
9495 // Or Instructions
9496
9497 // Register Or
9498 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9499 match(Set dst (OrI src1 src2));
9500 format %{ "OR $dst, $src1, $src2" %}
9501 size(4);
9502 ins_encode %{
9503 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9504 %}
9505 ins_pipe(pipe_class_default);
9506 %}
9507
9508 // Expand does not work with above instruct. (??)
9509 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9510 // no match-rule
9511 effect(DEF dst, USE src1, USE src2);
9512 format %{ "OR $dst, $src1, $src2" %}
9513 size(4);
9514 ins_encode %{
9515 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9516 %}
9517 ins_pipe(pipe_class_default);
9518 %}
9519
9520 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9521 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9522 ins_cost(DEFAULT_COST*3);
9523
9524 expand %{
9525 // FIXME: we should do this in the ideal world.
9526 iRegIdst tmp1;
9527 iRegIdst tmp2;
9528 orI_reg_reg(tmp1, src1, src2);
9529 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9530 orI_reg_reg(dst, tmp1, tmp2);
9531 %}
9532 %}
9533
9534 // Immediate Or
9535 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9536 match(Set dst (OrI src1 src2));
9537 format %{ "ORI $dst, $src1, $src2" %}
9538 size(4);
9539 ins_encode %{
9540 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9541 %}
9542 ins_pipe(pipe_class_default);
9543 %}
9544
9545 // Register Or Long
9546 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9547 match(Set dst (OrL src1 src2));
9548 ins_cost(DEFAULT_COST);
9549
9550 size(4);
9551 format %{ "OR $dst, $src1, $src2 \t// long" %}
9552 ins_encode %{
9553 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9554 %}
9555 ins_pipe(pipe_class_default);
9556 %}
9557
9558 // OrL + ConvL2I.
9559 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9560 match(Set dst (ConvL2I (OrL src1 src2)));
9561 ins_cost(DEFAULT_COST);
9562
9563 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %}
9564 size(4);
9565 ins_encode %{
9566 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9567 %}
9568 ins_pipe(pipe_class_default);
9569 %}
9570
9571 // Immediate Or long
9572 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9573 match(Set dst (OrL src1 con));
9574 ins_cost(DEFAULT_COST);
9575
9576 format %{ "ORI $dst, $src1, $con \t// long" %}
9577 size(4);
9578 ins_encode %{
9579 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9580 %}
9581 ins_pipe(pipe_class_default);
9582 %}
9583
9584 // Xor Instructions
9585
9586 // Register Xor
9587 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9588 match(Set dst (XorI src1 src2));
9589 format %{ "XOR $dst, $src1, $src2" %}
9590 size(4);
9591 ins_encode %{
9592 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9593 %}
9594 ins_pipe(pipe_class_default);
9595 %}
9596
9597 // Expand does not work with above instruct. (??)
9598 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9599 // no match-rule
9600 effect(DEF dst, USE src1, USE src2);
9601 format %{ "XOR $dst, $src1, $src2" %}
9602 size(4);
9603 ins_encode %{
9604 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9605 %}
9606 ins_pipe(pipe_class_default);
9607 %}
9608
9609 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9610 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
9611 ins_cost(DEFAULT_COST*3);
9612
9613 expand %{
9614 // FIXME: we should do this in the ideal world.
9615 iRegIdst tmp1;
9616 iRegIdst tmp2;
9617 xorI_reg_reg(tmp1, src1, src2);
9618 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
9619 xorI_reg_reg(dst, tmp1, tmp2);
9620 %}
9621 %}
9622
9623 // Immediate Xor
9624 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9625 match(Set dst (XorI src1 src2));
9626 format %{ "XORI $dst, $src1, $src2" %}
9627 size(4);
9628 ins_encode %{
9629 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9630 %}
9631 ins_pipe(pipe_class_default);
9632 %}
9633
9634 // Register Xor Long
9635 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9636 match(Set dst (XorL src1 src2));
9637 ins_cost(DEFAULT_COST);
9638
9639 format %{ "XOR $dst, $src1, $src2 \t// long" %}
9640 size(4);
9641 ins_encode %{
9642 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9643 %}
9644 ins_pipe(pipe_class_default);
9645 %}
9646
9647 // XorL + ConvL2I.
9648 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9649 match(Set dst (ConvL2I (XorL src1 src2)));
9650 ins_cost(DEFAULT_COST);
9651
9652 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %}
9653 size(4);
9654 ins_encode %{
9655 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9656 %}
9657 ins_pipe(pipe_class_default);
9658 %}
9659
9660 // Immediate Xor Long
9661 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
9662 match(Set dst (XorL src1 src2));
9663 ins_cost(DEFAULT_COST);
9664
9665 format %{ "XORI $dst, $src1, $src2 \t// long" %}
9666 size(4);
9667 ins_encode %{
9668 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9669 %}
9670 ins_pipe(pipe_class_default);
9671 %}
9672
9673 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
9674 match(Set dst (XorI src1 src2));
9675 ins_cost(DEFAULT_COST);
9676
9677 format %{ "NOT $dst, $src1 ($src2)" %}
9678 size(4);
9679 ins_encode %{
9680 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9681 %}
9682 ins_pipe(pipe_class_default);
9683 %}
9684
9685 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
9686 match(Set dst (XorL src1 src2));
9687 ins_cost(DEFAULT_COST);
9688
9689 format %{ "NOT $dst, $src1 ($src2) \t// long" %}
9690 size(4);
9691 ins_encode %{
9692 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9693 %}
9694 ins_pipe(pipe_class_default);
9695 %}
9696
9697 // And-complement
9698 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
9699 match(Set dst (AndI (XorI src1 src2) src3));
9700 ins_cost(DEFAULT_COST);
9701
9702 format %{ "ANDW $dst, xori($src1, $src2), $src3" %}
9703 size(4);
9704 ins_encode( enc_andc(dst, src3, src1) );
9705 ins_pipe(pipe_class_default);
9706 %}
9707
9708 // And-complement
9709 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9710 // no match-rule, false predicate
9711 effect(DEF dst, USE src1, USE src2);
9712 predicate(false);
9713
9714 format %{ "ANDC $dst, $src1, $src2" %}
9715 size(4);
9716 ins_encode %{
9717 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
9718 %}
9719 ins_pipe(pipe_class_default);
9720 %}
9721
9722 //----------Moves between int/long and float/double----------------------------
9723 //
9724 // The following rules move values from int/long registers/stack-locations
9725 // to float/double registers/stack-locations and vice versa, without doing any
9726 // conversions. These rules are used to implement the bit-conversion methods
9727 // of java.lang.Float etc., e.g.
9728 // int floatToIntBits(float value)
9729 // float intBitsToFloat(int bits)
9730
9731 instruct moveL2D_reg(regD dst, iRegLsrc src) %{
9732 match(Set dst (MoveL2D src));
9733
9734 format %{ "MTFPRD $dst, $src" %}
9735 size(4);
9736 ins_encode %{
9737 __ mtfprd($dst$$FloatRegister, $src$$Register);
9738 %}
9739 ins_pipe(pipe_class_default);
9740 %}
9741
9742 instruct moveI2D_reg(regD dst, iRegIsrc src) %{
9743 // no match-rule, false predicate
9744 effect(DEF dst, USE src);
9745 predicate(false);
9746
9747 format %{ "MTFPRWA $dst, $src" %}
9748 size(4);
9749 ins_encode %{
9750 __ mtfprwa($dst$$FloatRegister, $src$$Register);
9751 %}
9752 ins_pipe(pipe_class_default);
9753 %}
9754
9755 //---------- Chain stack slots between similar types --------
9756
9757 // These are needed so that the rules below can match.
9758
9759 // Load integer from stack slot
9760 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
9761 match(Set dst src);
9762 ins_cost(MEMORY_REF_COST);
9763
9764 format %{ "LWZ $dst, $src" %}
9765 size(4);
9766 ins_encode( enc_lwz(dst, src) );
9767 ins_pipe(pipe_class_memory);
9768 %}
9769
9770 // Store integer to stack slot
9771 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
9772 match(Set dst src);
9773 ins_cost(MEMORY_REF_COST);
9774
9775 format %{ "STW $src, $dst \t// stk" %}
9776 size(4);
9777 ins_encode( enc_stw(src, dst) ); // rs=rt
9778 ins_pipe(pipe_class_memory);
9779 %}
9780
9781 // Load long from stack slot
9782 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
9783 match(Set dst src);
9784 ins_cost(MEMORY_REF_COST);
9785
9786 format %{ "LD $dst, $src \t// long" %}
9787 size(4);
9788 ins_encode( enc_ld(dst, src) );
9789 ins_pipe(pipe_class_memory);
9790 %}
9791
9792 // Store long to stack slot
9793 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
9794 match(Set dst src);
9795 ins_cost(MEMORY_REF_COST);
9796
9797 format %{ "STD $src, $dst \t// long" %}
9798 size(4);
9799 ins_encode( enc_std(src, dst) ); // rs=rt
9800 ins_pipe(pipe_class_memory);
9801 %}
9802
9803 //----------Moves between int and float
9804
9805 // Move float value from float stack-location to integer register.
9806 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
9807 match(Set dst (MoveF2I src));
9808 ins_cost(MEMORY_REF_COST);
9809
9810 format %{ "LWZ $dst, $src \t// MoveF2I" %}
9811 size(4);
9812 ins_encode( enc_lwz(dst, src) );
9813 ins_pipe(pipe_class_memory);
9814 %}
9815
9816 // Move float value from float register to integer stack-location.
9817 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
9818 match(Set dst (MoveF2I src));
9819 ins_cost(MEMORY_REF_COST);
9820
9821 format %{ "STFS $src, $dst \t// MoveF2I" %}
9822 size(4);
9823 ins_encode( enc_stfs(src, dst) );
9824 ins_pipe(pipe_class_memory);
9825 %}
9826
9827 // Move integer value from integer stack-location to float register.
9828 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
9829 match(Set dst (MoveI2F src));
9830 ins_cost(MEMORY_REF_COST);
9831
9832 format %{ "LFS $dst, $src \t// MoveI2F" %}
9833 size(4);
9834 ins_encode %{
9835 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
9836 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
9837 %}
9838 ins_pipe(pipe_class_memory);
9839 %}
9840
9841 // Move integer value from integer register to float stack-location.
9842 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
9843 match(Set dst (MoveI2F src));
9844 ins_cost(MEMORY_REF_COST);
9845
9846 format %{ "STW $src, $dst \t// MoveI2F" %}
9847 size(4);
9848 ins_encode( enc_stw(src, dst) );
9849 ins_pipe(pipe_class_memory);
9850 %}
9851
9852
9853 //----------Moves between long and double
9854
9855 // Move double value from double stack-location to long register.
9856 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
9857 match(Set dst (MoveD2L src));
9858 ins_cost(MEMORY_REF_COST);
9859 size(4);
9860 format %{ "LD $dst, $src \t// MoveD2L" %}
9861 ins_encode( enc_ld(dst, src) );
9862 ins_pipe(pipe_class_memory);
9863 %}
9864
9865 // Move double value from double register to long stack-location.
9866 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
9867 match(Set dst (MoveD2L src));
9868 effect(DEF dst, USE src);
9869 ins_cost(MEMORY_REF_COST);
9870
9871 format %{ "STFD $src, $dst \t// MoveD2L" %}
9872 size(4);
9873 ins_encode( enc_stfd(src, dst) );
9874 ins_pipe(pipe_class_memory);
9875 %}
9876
9877
9878 //----------Register Move Instructions-----------------------------------------
9879
9880 // Replicate for Superword
9881
9882 instruct moveReg(iRegLdst dst, iRegIsrc src) %{
9883 predicate(false);
9884 effect(DEF dst, USE src);
9885
9886 format %{ "MR $dst, $src \t// replicate " %}
9887 // variable size, 0 or 4.
9888 ins_encode %{
9889 __ mr_if_needed($dst$$Register, $src$$Register);
9890 %}
9891 ins_pipe(pipe_class_default);
9892 %}
9893
9894 //----------Cast instructions (Java-level type cast)---------------------------
9895
9896 // Cast Long to Pointer for unsafe natives.
9897 instruct castX2P(iRegPdst dst, iRegLsrc src) %{
9898 match(Set dst (CastX2P src));
9899
9900 format %{ "MR $dst, $src \t// Long->Ptr" %}
9901 // variable size, 0 or 4.
9902 ins_encode %{
9903 __ mr_if_needed($dst$$Register, $src$$Register);
9904 %}
9905 ins_pipe(pipe_class_default);
9906 %}
9907
9908 // Cast Pointer to Long for unsafe natives.
9909 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
9910 match(Set dst (CastP2X src));
9911
9912 format %{ "MR $dst, $src \t// Ptr->Long" %}
9913 // variable size, 0 or 4.
9914 ins_encode %{
9915 __ mr_if_needed($dst$$Register, $src$$Register);
9916 %}
9917 ins_pipe(pipe_class_default);
9918 %}
9919
9920 instruct castPP(iRegPdst dst) %{
9921 match(Set dst (CastPP dst));
9922 format %{ " -- \t// castPP of $dst" %}
9923 size(0);
9924 ins_encode( /*empty*/ );
9925 ins_pipe(pipe_class_default);
9926 %}
9927
9928 instruct castII(iRegIdst dst) %{
9929 match(Set dst (CastII dst));
9930 format %{ " -- \t// castII of $dst" %}
9931 size(0);
9932 ins_encode( /*empty*/ );
9933 ins_pipe(pipe_class_default);
9934 %}
9935
9936 instruct castLL(iRegLdst dst) %{
9937 match(Set dst (CastLL dst));
9938 format %{ " -- \t// castLL of $dst" %}
9939 size(0);
9940 ins_encode( /*empty*/ );
9941 ins_pipe(pipe_class_default);
9942 %}
9943
9944 instruct castFF(regF dst) %{
9945 match(Set dst (CastFF dst));
9946 format %{ " -- \t// castFF of $dst" %}
9947 size(0);
9948 ins_encode( /*empty*/ );
9949 ins_pipe(pipe_class_default);
9950 %}
9951
9952 instruct castDD(regD dst) %{
9953 match(Set dst (CastDD dst));
9954 format %{ " -- \t// castDD of $dst" %}
9955 size(0);
9956 ins_encode( /*empty*/ );
9957 ins_pipe(pipe_class_default);
9958 %}
9959
9960 instruct castVV8(iRegLdst dst) %{
9961 match(Set dst (CastVV dst));
9962 format %{ " -- \t// castVV of $dst" %}
9963 size(0);
9964 ins_encode( /*empty*/ );
9965 ins_pipe(pipe_class_default);
9966 %}
9967
9968 instruct castVV16(vecX dst) %{
9969 match(Set dst (CastVV dst));
9970 format %{ " -- \t// castVV of $dst" %}
9971 size(0);
9972 ins_encode( /*empty*/ );
9973 ins_pipe(pipe_class_default);
9974 %}
9975
9976 instruct checkCastPP(iRegPdst dst) %{
9977 match(Set dst (CheckCastPP dst));
9978 format %{ " -- \t// checkcastPP of $dst" %}
9979 size(0);
9980 ins_encode( /*empty*/ );
9981 ins_pipe(pipe_class_default);
9982 %}
9983
9984 //----------Convert instructions-----------------------------------------------
9985
9986 // Convert to boolean.
9987
9988 // int_to_bool(src) : { 1 if src != 0
9989 // { 0 else
9990 //
9991 // strategy:
9992 // 1) Count leading zeros of 32 bit-value src,
9993 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
9994 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9995 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9996
9997 // convI2Bool
9998 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
9999 match(Set dst (Conv2B src));
10000 predicate(UseCountLeadingZerosInstructionsPPC64);
10001 ins_cost(DEFAULT_COST);
10002
10003 expand %{
10004 immI shiftAmount %{ 0x5 %}
10005 uimmI16 mask %{ 0x1 %}
10006 iRegIdst tmp1;
10007 iRegIdst tmp2;
10008 countLeadingZerosI(tmp1, src);
10009 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
10010 xorI_reg_uimm16(dst, tmp2, mask);
10011 %}
10012 %}
10013
10014 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
10015 match(Set dst (Conv2B src));
10016 effect(TEMP crx);
10017 predicate(!UseCountLeadingZerosInstructionsPPC64);
10018 ins_cost(DEFAULT_COST);
10019
10020 format %{ "CMPWI $crx, $src, #0 \t// convI2B"
10021 "LI $dst, #0\n\t"
10022 "BEQ $crx, done\n\t"
10023 "LI $dst, #1\n"
10024 "done:" %}
10025 size(16);
10026 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
10027 ins_pipe(pipe_class_compare);
10028 %}
10029
10030 // ConvI2B + XorI
10031 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
10032 match(Set dst (XorI (Conv2B src) mask));
10033 predicate(UseCountLeadingZerosInstructionsPPC64);
10034 ins_cost(DEFAULT_COST);
10035
10036 expand %{
10037 immI shiftAmount %{ 0x5 %}
10038 iRegIdst tmp1;
10039 countLeadingZerosI(tmp1, src);
10040 urShiftI_reg_imm(dst, tmp1, shiftAmount);
10041 %}
10042 %}
10043
10044 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
10045 match(Set dst (XorI (Conv2B src) mask));
10046 effect(TEMP crx);
10047 predicate(!UseCountLeadingZerosInstructionsPPC64);
10048 ins_cost(DEFAULT_COST);
10049
10050 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
10051 "LI $dst, #1\n\t"
10052 "BEQ $crx, done\n\t"
10053 "LI $dst, #0\n"
10054 "done:" %}
10055 size(16);
10056 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
10057 ins_pipe(pipe_class_compare);
10058 %}
10059
10060 // AndI 0b0..010..0 + ConvI2B
10061 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
10062 match(Set dst (Conv2B (AndI src mask)));
10063 predicate(UseRotateAndMaskInstructionsPPC64);
10064 ins_cost(DEFAULT_COST);
10065
10066 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
10067 size(4);
10068 ins_encode %{
10069 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31);
10070 %}
10071 ins_pipe(pipe_class_default);
10072 %}
10073
10074 // Convert pointer to boolean.
10075 //
10076 // ptr_to_bool(src) : { 1 if src != 0
10077 // { 0 else
10078 //
10079 // strategy:
10080 // 1) Count leading zeros of 64 bit-value src,
10081 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
10082 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
10083 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
10084
10085 // ConvP2B
10086 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
10087 match(Set dst (Conv2B src));
10088 predicate(UseCountLeadingZerosInstructionsPPC64);
10089 ins_cost(DEFAULT_COST);
10090
10091 expand %{
10092 immI shiftAmount %{ 0x6 %}
10093 uimmI16 mask %{ 0x1 %}
10094 iRegIdst tmp1;
10095 iRegIdst tmp2;
10096 countLeadingZerosP(tmp1, src);
10097 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
10098 xorI_reg_uimm16(dst, tmp2, mask);
10099 %}
10100 %}
10101
10102 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
10103 match(Set dst (Conv2B src));
10104 effect(TEMP crx);
10105 predicate(!UseCountLeadingZerosInstructionsPPC64);
10106 ins_cost(DEFAULT_COST);
10107
10108 format %{ "CMPDI $crx, $src, #0 \t// convP2B"
10109 "LI $dst, #0\n\t"
10110 "BEQ $crx, done\n\t"
10111 "LI $dst, #1\n"
10112 "done:" %}
10113 size(16);
10114 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
10115 ins_pipe(pipe_class_compare);
10116 %}
10117
10118 // ConvP2B + XorI
10119 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
10120 match(Set dst (XorI (Conv2B src) mask));
10121 predicate(UseCountLeadingZerosInstructionsPPC64);
10122 ins_cost(DEFAULT_COST);
10123
10124 expand %{
10125 immI shiftAmount %{ 0x6 %}
10126 iRegIdst tmp1;
10127 countLeadingZerosP(tmp1, src);
10128 urShiftI_reg_imm(dst, tmp1, shiftAmount);
10129 %}
10130 %}
10131
10132 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
10133 match(Set dst (XorI (Conv2B src) mask));
10134 effect(TEMP crx);
10135 predicate(!UseCountLeadingZerosInstructionsPPC64);
10136 ins_cost(DEFAULT_COST);
10137
10138 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
10139 "LI $dst, #1\n\t"
10140 "BEQ $crx, done\n\t"
10141 "LI $dst, #0\n"
10142 "done:" %}
10143 size(16);
10144 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
10145 ins_pipe(pipe_class_compare);
10146 %}
10147
10148 // if src1 < src2, return -1 else return 0
10149 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
10150 match(Set dst (CmpLTMask src1 src2));
10151 ins_cost(DEFAULT_COST*4);
10152
10153 expand %{
10154 iRegLdst src1s;
10155 iRegLdst src2s;
10156 iRegLdst diff;
10157 convI2L_reg(src1s, src1); // Ensure proper sign extension.
10158 convI2L_reg(src2s, src2); // Ensure proper sign extension.
10159 subL_reg_reg(diff, src1s, src2s);
10160 // Need to consider >=33 bit result, therefore we need signmaskL.
10161 signmask64I_regL(dst, diff);
10162 %}
10163 %}
10164
10165 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
10166 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
10167 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %}
10168 size(4);
10169 ins_encode %{
10170 __ srawi($dst$$Register, $src1$$Register, 0x1f);
10171 %}
10172 ins_pipe(pipe_class_default);
10173 %}
10174
10175 //----------Arithmetic Conversion Instructions---------------------------------
10176
10177 // Convert to Byte -- nop
10178 // Convert to Short -- nop
10179
10180 // Convert to Int
10181
10182 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
10183 match(Set dst (RShiftI (LShiftI src amount) amount));
10184 format %{ "EXTSB $dst, $src \t// byte->int" %}
10185 size(4);
10186 ins_encode %{
10187 __ extsb($dst$$Register, $src$$Register);
10188 %}
10189 ins_pipe(pipe_class_default);
10190 %}
10191
10192 instruct extsh(iRegIdst dst, iRegIsrc src) %{
10193 effect(DEF dst, USE src);
10194
10195 size(4);
10196 ins_encode %{
10197 __ extsh($dst$$Register, $src$$Register);
10198 %}
10199 ins_pipe(pipe_class_default);
10200 %}
10201
10202 // LShiftI 16 + RShiftI 16 converts short to int.
10203 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
10204 match(Set dst (RShiftI (LShiftI src amount) amount));
10205 format %{ "EXTSH $dst, $src \t// short->int" %}
10206 size(4);
10207 ins_encode %{
10208 __ extsh($dst$$Register, $src$$Register);
10209 %}
10210 ins_pipe(pipe_class_default);
10211 %}
10212
10213 // ConvL2I + ConvI2L: Sign extend int in long register.
10214 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
10215 match(Set dst (ConvI2L (ConvL2I src)));
10216
10217 format %{ "EXTSW $dst, $src \t// long->long" %}
10218 size(4);
10219 ins_encode %{
10220 __ extsw($dst$$Register, $src$$Register);
10221 %}
10222 ins_pipe(pipe_class_default);
10223 %}
10224
10225 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
10226 match(Set dst (ConvL2I src));
10227 format %{ "MR $dst, $src \t// long->int" %}
10228 // variable size, 0 or 4
10229 ins_encode %{
10230 __ mr_if_needed($dst$$Register, $src$$Register);
10231 %}
10232 ins_pipe(pipe_class_default);
10233 %}
10234
10235 instruct convD2IRaw_regD(regD dst, regD src) %{
10236 // no match-rule, false predicate
10237 effect(DEF dst, USE src);
10238 predicate(false);
10239
10240 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
10241 size(4);
10242 ins_encode %{
10243 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10244 %}
10245 ins_pipe(pipe_class_default);
10246 %}
10247
10248 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
10249 // no match-rule, false predicate
10250 effect(DEF dst, USE crx, USE src);
10251 predicate(false);
10252
10253 ins_variable_size_depending_on_alignment(true);
10254
10255 format %{ "CMOVI $crx, $dst, $src" %}
10256 size(8);
10257 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10258 ins_pipe(pipe_class_default);
10259 %}
10260
10261 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
10262 // no match-rule, false predicate
10263 effect(DEF dst, USE crx, USE src);
10264 predicate(false);
10265
10266 ins_variable_size_depending_on_alignment(true);
10267
10268 format %{ "CMOVI $crx, $dst, $src" %}
10269 size(8);
10270 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10271 ins_pipe(pipe_class_default);
10272 %}
10273
10274
10275 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{
10276 // no match-rule, false predicate
10277 effect(DEF dst, USE crx, USE src);
10278 predicate(false);
10279
10280 format %{ "CMOVI $dst, $crx, $src \t// postalloc expanded" %}
10281 postalloc_expand %{
10282 //
10283 // replaces
10284 //
10285 // region dst crx src
10286 // \ | | /
10287 // dst=cmovI_bso_reg_conLvalue0
10288 //
10289 // with
10290 //
10291 // region dst
10292 // \ /
10293 // dst=loadConI16(0)
10294 // |
10295 // ^ region dst crx src
10296 // | \ | | /
10297 // dst=cmovI_bso_reg
10298 //
10299
10300 // Create new nodes.
10301 MachNode *m1 = new loadConI16Node();
10302 MachNode *m2 = new cmovI_bso_regNode();
10303
10304 // inputs for new nodes
10305 m1->add_req(n_region);
10306 m2->add_req(n_region, n_crx, n_src);
10307
10308 // precedences for new nodes
10309 m2->add_prec(m1);
10310
10311 // operands for new nodes
10312 m1->_opnds[0] = op_dst;
10313 m1->_opnds[1] = new immI16Oper(0);
10314
10315 m2->_opnds[0] = op_dst;
10316 m2->_opnds[1] = op_crx;
10317 m2->_opnds[2] = op_src;
10318
10319 // registers for new nodes
10320 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10321 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10322
10323 // Insert new nodes.
10324 nodes->push(m1);
10325 nodes->push(m2);
10326 %}
10327 %}
10328
10329
10330 // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
10331 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
10332 match(Set dst (ConvD2I src));
10333 ins_cost(DEFAULT_COST);
10334
10335 expand %{
10336 regD tmpD;
10337 flagsReg crx;
10338 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10339 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
10340 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10341 %}
10342 %}
10343
10344 instruct convF2IRaw_regF(regF dst, regF src) %{
10345 // no match-rule, false predicate
10346 effect(DEF dst, USE src);
10347 predicate(false);
10348
10349 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
10350 size(4);
10351 ins_encode %{
10352 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10353 %}
10354 ins_pipe(pipe_class_default);
10355 %}
10356
10357
10358 // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
10359 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
10360 match(Set dst (ConvF2I src));
10361 ins_cost(DEFAULT_COST);
10362
10363 expand %{
10364 regF tmpF;
10365 flagsReg crx;
10366 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10367 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10368 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10369 %}
10370 %}
10371
10372 // Convert to Long
10373
10374 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
10375 match(Set dst (ConvI2L src));
10376 format %{ "EXTSW $dst, $src \t// int->long" %}
10377 size(4);
10378 ins_encode %{
10379 __ extsw($dst$$Register, $src$$Register);
10380 %}
10381 ins_pipe(pipe_class_default);
10382 %}
10383
10384 // Zero-extend: convert unsigned int to long (convUI2L).
10385 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
10386 match(Set dst (AndL (ConvI2L src) mask));
10387 ins_cost(DEFAULT_COST);
10388
10389 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10390 size(4);
10391 ins_encode %{
10392 __ clrldi($dst$$Register, $src$$Register, 32);
10393 %}
10394 ins_pipe(pipe_class_default);
10395 %}
10396
10397 // Zero-extend: convert unsigned int to long in long register.
10398 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
10399 match(Set dst (AndL src mask));
10400 ins_cost(DEFAULT_COST);
10401
10402 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10403 size(4);
10404 ins_encode %{
10405 __ clrldi($dst$$Register, $src$$Register, 32);
10406 %}
10407 ins_pipe(pipe_class_default);
10408 %}
10409
10410 instruct convF2LRaw_regF(regF dst, regF src) %{
10411 // no match-rule, false predicate
10412 effect(DEF dst, USE src);
10413 predicate(false);
10414
10415 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10416 size(4);
10417 ins_encode %{
10418 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10419 %}
10420 ins_pipe(pipe_class_default);
10421 %}
10422
10423 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
10424 // no match-rule, false predicate
10425 effect(DEF dst, USE crx, USE src);
10426 predicate(false);
10427
10428 ins_variable_size_depending_on_alignment(true);
10429
10430 format %{ "CMOVL $crx, $dst, $src" %}
10431 size(8);
10432 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10433 ins_pipe(pipe_class_default);
10434 %}
10435
10436 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
10437 // no match-rule, false predicate
10438 effect(DEF dst, USE crx, USE src);
10439 predicate(false);
10440
10441 ins_variable_size_depending_on_alignment(true);
10442
10443 format %{ "CMOVL $crx, $dst, $src" %}
10444 size(8);
10445 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10446 ins_pipe(pipe_class_default);
10447 %}
10448
10449
10450 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{
10451 // no match-rule, false predicate
10452 effect(DEF dst, USE crx, USE src);
10453 predicate(false);
10454
10455 format %{ "CMOVL $dst, $crx, $src \t// postalloc expanded" %}
10456 postalloc_expand %{
10457 //
10458 // replaces
10459 //
10460 // region dst crx src
10461 // \ | | /
10462 // dst=cmovL_bso_reg_conLvalue0
10463 //
10464 // with
10465 //
10466 // region dst
10467 // \ /
10468 // dst=loadConL16(0)
10469 // |
10470 // ^ region dst crx src
10471 // | \ | | /
10472 // dst=cmovL_bso_reg
10473 //
10474
10475 // Create new nodes.
10476 MachNode *m1 = new loadConL16Node();
10477 MachNode *m2 = new cmovL_bso_regNode();
10478
10479 // inputs for new nodes
10480 m1->add_req(n_region);
10481 m2->add_req(n_region, n_crx, n_src);
10482 m2->add_prec(m1);
10483
10484 // operands for new nodes
10485 m1->_opnds[0] = op_dst;
10486 m1->_opnds[1] = new immL16Oper(0);
10487 m2->_opnds[0] = op_dst;
10488 m2->_opnds[1] = op_crx;
10489 m2->_opnds[2] = op_src;
10490
10491 // registers for new nodes
10492 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10493 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10494
10495 // Insert new nodes.
10496 nodes->push(m1);
10497 nodes->push(m2);
10498 %}
10499 %}
10500
10501
10502 // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
10503 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
10504 match(Set dst (ConvF2L src));
10505 ins_cost(DEFAULT_COST);
10506
10507 expand %{
10508 regF tmpF;
10509 flagsReg crx;
10510 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10511 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
10512 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10513 %}
10514 %}
10515
10516 instruct convD2LRaw_regD(regD dst, regD src) %{
10517 // no match-rule, false predicate
10518 effect(DEF dst, USE src);
10519 predicate(false);
10520
10521 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
10522 size(4);
10523 ins_encode %{
10524 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10525 %}
10526 ins_pipe(pipe_class_default);
10527 %}
10528
10529
10530 // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
10531 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
10532 match(Set dst (ConvD2L src));
10533 ins_cost(DEFAULT_COST);
10534
10535 expand %{
10536 regD tmpD;
10537 flagsReg crx;
10538 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10539 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
10540 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10541 %}
10542 %}
10543
10544 // Convert to Float
10545
10546 // Placed here as needed in expand.
10547 instruct convL2DRaw_regD(regD dst, regD src) %{
10548 // no match-rule, false predicate
10549 effect(DEF dst, USE src);
10550 predicate(false);
10551
10552 format %{ "FCFID $dst, $src \t// convL2D" %}
10553 size(4);
10554 ins_encode %{
10555 __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
10556 %}
10557 ins_pipe(pipe_class_default);
10558 %}
10559
10560 // Placed here as needed in expand.
10561 instruct convD2F_reg(regF dst, regD src) %{
10562 match(Set dst (ConvD2F src));
10563 format %{ "FRSP $dst, $src \t// convD2F" %}
10564 size(4);
10565 ins_encode %{
10566 __ frsp($dst$$FloatRegister, $src$$FloatRegister);
10567 %}
10568 ins_pipe(pipe_class_default);
10569 %}
10570
10571 instruct convL2FRaw_regF(regF dst, regD src) %{
10572 // no match-rule, false predicate
10573 effect(DEF dst, USE src);
10574 predicate(false);
10575
10576 format %{ "FCFIDS $dst, $src \t// convL2F" %}
10577 size(4);
10578 ins_encode %{
10579 __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
10580 %}
10581 ins_pipe(pipe_class_default);
10582 %}
10583
10584
10585 // Integer to Float conversion. Special version for Power8.
10586 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
10587 match(Set dst (ConvI2F src));
10588 ins_cost(DEFAULT_COST);
10589
10590 expand %{
10591 regD tmpD;
10592 moveI2D_reg(tmpD, src);
10593 convL2FRaw_regF(dst, tmpD); // Convert to float.
10594 %}
10595 %}
10596
10597
10598 // L2F to avoid runtime call. Special version for Power8.
10599 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
10600 match(Set dst (ConvL2F src));
10601 ins_cost(DEFAULT_COST);
10602
10603 expand %{
10604 regD tmpD;
10605 moveL2D_reg(tmpD, src);
10606 convL2FRaw_regF(dst, tmpD); // Convert to float.
10607 %}
10608 %}
10609
10610 // Moved up as used in expand.
10611 //instruct convD2F_reg(regF dst, regD src) %{%}
10612
10613 // Convert to Double
10614
10615
10616 // Integer to Double conversion. Special version for Power8.
10617 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
10618 match(Set dst (ConvI2D src));
10619 ins_cost(DEFAULT_COST);
10620
10621 expand %{
10622 regD tmpD;
10623 moveI2D_reg(tmpD, src);
10624 convL2DRaw_regD(dst, tmpD); // Convert to double.
10625 %}
10626 %}
10627
10628
10629 // Long to Double conversion. Special version for Power8.
10630 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
10631 match(Set dst (ConvL2D src));
10632 ins_cost(DEFAULT_COST);
10633
10634 expand %{
10635 regD tmpD;
10636 moveL2D_reg(tmpD, src);
10637 convL2DRaw_regD(dst, tmpD); // Convert to double.
10638 %}
10639 %}
10640
10641 instruct convF2D_reg(regD dst, regF src) %{
10642 match(Set dst (ConvF2D src));
10643 format %{ "FMR $dst, $src \t// float->double" %}
10644 // variable size, 0 or 4
10645 ins_encode %{
10646 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
10647 %}
10648 ins_pipe(pipe_class_default);
10649 %}
10650
10651 instruct convF2HF_reg_reg(iRegIdst dst, regF src, regF tmp) %{
10652 match(Set dst (ConvF2HF src));
10653 effect(TEMP tmp);
10654 ins_cost(3 * DEFAULT_COST);
10655 size(12);
10656 format %{ "XSCVDPHP $tmp, $src\t# convert to half precision\n\t"
10657 "MFFPRD $dst, $tmp\t# move result from $tmp to $dst\n\t"
10658 "EXTSH $dst, $dst\t# make it a proper short"
10659 %}
10660 ins_encode %{
10661 __ f2hf($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
10662 %}
10663 ins_pipe(pipe_class_default);
10664 %}
10665
10666 instruct convHF2F_reg_reg(regF dst, iRegIsrc src) %{
10667 match(Set dst (ConvHF2F src));
10668 ins_cost(2 * DEFAULT_COST);
10669 size(8);
10670 format %{ "MTFPRD $dst, $src\t# move source from $src to $dst\n\t"
10671 "XSCVHPDP $dst, $dst\t# convert from half precision"
10672 %}
10673 ins_encode %{
10674 __ hf2f($dst$$FloatRegister, $src$$Register);
10675 %}
10676 ins_pipe(pipe_class_default);
10677 %}
10678
10679 //----------Control Flow Instructions------------------------------------------
10680 // Compare Instructions
10681
10682 // Compare Integers
10683 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10684 match(Set crx (CmpI src1 src2));
10685 size(4);
10686 format %{ "CMPW $crx, $src1, $src2" %}
10687 ins_encode %{
10688 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10689 %}
10690 ins_pipe(pipe_class_compare);
10691 %}
10692
10693 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
10694 match(Set crx (CmpI src1 src2));
10695 format %{ "CMPWI $crx, $src1, $src2" %}
10696 size(4);
10697 ins_encode %{
10698 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10699 %}
10700 ins_pipe(pipe_class_compare);
10701 %}
10702
10703 // (src1 & src2) == 0?
10704 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
10705 match(Set cr0 (CmpI (AndI src1 src2) zero));
10706 // r0 is killed
10707 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
10708 size(4);
10709 ins_encode %{
10710 __ andi_(R0, $src1$$Register, $src2$$constant);
10711 %}
10712 ins_pipe(pipe_class_compare);
10713 %}
10714
10715 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10716 match(Set crx (CmpL src1 src2));
10717 format %{ "CMPD $crx, $src1, $src2" %}
10718 size(4);
10719 ins_encode %{
10720 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
10721 %}
10722 ins_pipe(pipe_class_compare);
10723 %}
10724
10725 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
10726 match(Set crx (CmpL src1 src2));
10727 format %{ "CMPDI $crx, $src1, $src2" %}
10728 size(4);
10729 ins_encode %{
10730 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10731 %}
10732 ins_pipe(pipe_class_compare);
10733 %}
10734
10735 // Added CmpUL for LoopPredicate.
10736 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10737 match(Set crx (CmpUL src1 src2));
10738 format %{ "CMPLD $crx, $src1, $src2" %}
10739 size(4);
10740 ins_encode %{
10741 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10742 %}
10743 ins_pipe(pipe_class_compare);
10744 %}
10745
10746 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
10747 match(Set crx (CmpUL src1 src2));
10748 format %{ "CMPLDI $crx, $src1, $src2" %}
10749 size(4);
10750 ins_encode %{
10751 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10752 %}
10753 ins_pipe(pipe_class_compare);
10754 %}
10755
10756 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
10757 match(Set cr0 (CmpL (AndL src1 src2) zero));
10758 // r0 is killed
10759 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
10760 size(4);
10761 ins_encode %{
10762 __ and_(R0, $src1$$Register, $src2$$Register);
10763 %}
10764 ins_pipe(pipe_class_compare);
10765 %}
10766
10767 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
10768 match(Set cr0 (CmpL (AndL src1 src2) zero));
10769 // r0 is killed
10770 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
10771 size(4);
10772 ins_encode %{
10773 __ andi_(R0, $src1$$Register, $src2$$constant);
10774 %}
10775 ins_pipe(pipe_class_compare);
10776 %}
10777
10778 // Manifest a CmpL3 result in an integer register.
10779 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10780 match(Set dst (CmpL3 src1 src2));
10781 effect(KILL cr0);
10782 ins_cost(DEFAULT_COST * 5);
10783 size((VM_Version::has_brw() ? 16 : 20));
10784
10785 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %}
10786
10787 ins_encode %{
10788 __ cmpd(CR0, $src1$$Register, $src2$$Register);
10789 __ set_cmp3($dst$$Register);
10790 %}
10791 ins_pipe(pipe_class_default);
10792 %}
10793
10794 instruct cmpU3_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
10795 match(Set dst (CmpU3 src1 src2));
10796 effect(KILL cr0);
10797 ins_cost(DEFAULT_COST * 5);
10798 size((VM_Version::has_brw() ? 16 : 20));
10799
10800 format %{ "cmpU3_reg_reg $dst, $src1, $src2" %}
10801
10802 ins_encode %{
10803 __ cmplw(CR0, $src1$$Register, $src2$$Register);
10804 __ set_cmp3($dst$$Register);
10805 %}
10806 ins_pipe(pipe_class_default);
10807 %}
10808
10809 instruct cmpUL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10810 match(Set dst (CmpUL3 src1 src2));
10811 effect(KILL cr0);
10812 ins_cost(DEFAULT_COST * 5);
10813 size((VM_Version::has_brw() ? 16 : 20));
10814
10815 format %{ "cmpUL3_reg_reg $dst, $src1, $src2" %}
10816
10817 ins_encode %{
10818 __ cmpld(CR0, $src1$$Register, $src2$$Register);
10819 __ set_cmp3($dst$$Register);
10820 %}
10821 ins_pipe(pipe_class_default);
10822 %}
10823
10824 // Implicit range checks.
10825 // A range check in the ideal world has one of the following shapes:
10826 // - (If le (CmpU length index)), (IfTrue throw exception)
10827 // - (If lt (CmpU index length)), (IfFalse throw exception)
10828 //
10829 // Match range check 'If le (CmpU length index)'.
10830 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
10831 match(If cmp (CmpU src_length index));
10832 effect(USE labl);
10833 predicate(TrapBasedRangeChecks &&
10834 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
10835 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
10836 (Matcher::branches_to_uncommon_trap(_leaf)));
10837
10838 ins_is_TrapBasedCheckNode(true);
10839
10840 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %}
10841 size(4);
10842 ins_encode %{
10843 if ($cmp$$cmpcode == 0x1 /* less_equal */) {
10844 __ trap_range_check_le($src_length$$Register, $index$$constant);
10845 } else {
10846 // Both successors are uncommon traps, probability is 0.
10847 // Node got flipped during fixup flow.
10848 assert($cmp$$cmpcode == 0x9, "must be greater");
10849 __ trap_range_check_g($src_length$$Register, $index$$constant);
10850 }
10851 %}
10852 ins_pipe(pipe_class_trap);
10853 %}
10854
10855 // Match range check 'If lt (CmpU index length)'.
10856 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
10857 match(If cmp (CmpU src_index src_length));
10858 effect(USE labl);
10859 predicate(TrapBasedRangeChecks &&
10860 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10861 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10862 (Matcher::branches_to_uncommon_trap(_leaf)));
10863
10864 ins_is_TrapBasedCheckNode(true);
10865
10866 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
10867 size(4);
10868 ins_encode %{
10869 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10870 __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
10871 } else {
10872 // Both successors are uncommon traps, probability is 0.
10873 // Node got flipped during fixup flow.
10874 assert($cmp$$cmpcode == 0x8, "must be less");
10875 __ trap_range_check_l($src_index$$Register, $src_length$$Register);
10876 }
10877 %}
10878 ins_pipe(pipe_class_trap);
10879 %}
10880
10881 // Match range check 'If lt (CmpU index length)'.
10882 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
10883 match(If cmp (CmpU src_index length));
10884 effect(USE labl);
10885 predicate(TrapBasedRangeChecks &&
10886 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10887 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10888 (Matcher::branches_to_uncommon_trap(_leaf)));
10889
10890 ins_is_TrapBasedCheckNode(true);
10891
10892 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %}
10893 size(4);
10894 ins_encode %{
10895 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10896 __ trap_range_check_ge($src_index$$Register, $length$$constant);
10897 } else {
10898 // Both successors are uncommon traps, probability is 0.
10899 // Node got flipped during fixup flow.
10900 assert($cmp$$cmpcode == 0x8, "must be less");
10901 __ trap_range_check_l($src_index$$Register, $length$$constant);
10902 }
10903 %}
10904 ins_pipe(pipe_class_trap);
10905 %}
10906
10907 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10908 match(Set crx (CmpU src1 src2));
10909 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %}
10910 size(4);
10911 ins_encode %{
10912 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10913 %}
10914 ins_pipe(pipe_class_compare);
10915 %}
10916
10917 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
10918 match(Set crx (CmpU src1 src2));
10919 size(4);
10920 format %{ "CMPLWI $crx, $src1, $src2" %}
10921 ins_encode %{
10922 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10923 %}
10924 ins_pipe(pipe_class_compare);
10925 %}
10926
10927 // Implicit zero checks (more implicit null checks).
10928 // No constant pool entries required.
10929 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
10930 match(If cmp (CmpN value zero));
10931 effect(USE labl);
10932 predicate(TrapBasedNullChecks &&
10933 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10934 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10935 Matcher::branches_to_uncommon_trap(_leaf));
10936 ins_cost(1);
10937
10938 ins_is_TrapBasedCheckNode(true);
10939
10940 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
10941 size(4);
10942 ins_encode %{
10943 if ($cmp$$cmpcode == 0xA) {
10944 __ trap_null_check($value$$Register);
10945 } else {
10946 // Both successors are uncommon traps, probability is 0.
10947 // Node got flipped during fixup flow.
10948 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10949 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10950 }
10951 %}
10952 ins_pipe(pipe_class_trap);
10953 %}
10954
10955 // Compare narrow oops.
10956 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
10957 match(Set crx (CmpN src1 src2));
10958
10959 size(4);
10960 ins_cost(2);
10961 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %}
10962 ins_encode %{
10963 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10964 %}
10965 ins_pipe(pipe_class_compare);
10966 %}
10967
10968 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
10969 match(Set crx (CmpN src1 src2));
10970 // Make this more expensive than zeroCheckN_iReg_imm0.
10971 ins_cost(2);
10972
10973 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %}
10974 size(4);
10975 ins_encode %{
10976 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10977 %}
10978 ins_pipe(pipe_class_compare);
10979 %}
10980
10981 // Implicit zero checks (more implicit null checks).
10982 // No constant pool entries required.
10983 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
10984 match(If cmp (CmpP value zero));
10985 effect(USE labl);
10986 predicate(TrapBasedNullChecks &&
10987 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10988 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10989 Matcher::branches_to_uncommon_trap(_leaf));
10990 ins_cost(1); // Should not be cheaper than zeroCheckN.
10991
10992 ins_is_TrapBasedCheckNode(true);
10993
10994 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
10995 size(4);
10996 ins_encode %{
10997 if ($cmp$$cmpcode == 0xA) {
10998 __ trap_null_check($value$$Register);
10999 } else {
11000 // Both successors are uncommon traps, probability is 0.
11001 // Node got flipped during fixup flow.
11002 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
11003 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
11004 }
11005 %}
11006 ins_pipe(pipe_class_trap);
11007 %}
11008
11009 // Compare Pointers
11010 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
11011 match(Set crx (CmpP src1 src2));
11012 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %}
11013 size(4);
11014 ins_encode %{
11015 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
11016 %}
11017 ins_pipe(pipe_class_compare);
11018 %}
11019
11020 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
11021 match(Set crx (CmpP src1 src2));
11022 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %}
11023 size(4);
11024 ins_encode %{
11025 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
11026 %}
11027 ins_pipe(pipe_class_compare);
11028 %}
11029
11030 // Used in postalloc expand.
11031 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
11032 // This match rule prevents reordering of node before a safepoint.
11033 // This only makes sense if this instructions is used exclusively
11034 // for the expansion of EncodeP!
11035 match(Set crx (CmpP src1 src2));
11036 predicate(false);
11037
11038 format %{ "CMPDI $crx, $src1, $src2" %}
11039 size(4);
11040 ins_encode %{
11041 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11042 %}
11043 ins_pipe(pipe_class_compare);
11044 %}
11045
11046 //----------Float Compares----------------------------------------------------
11047
11048 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
11049 // Needs matchrule, see cmpDUnordered.
11050 match(Set crx (CmpF src1 src2));
11051 // no match-rule, false predicate
11052 predicate(false);
11053
11054 format %{ "cmpFUrd $crx, $src1, $src2" %}
11055 size(4);
11056 ins_encode %{
11057 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11058 %}
11059 ins_pipe(pipe_class_default);
11060 %}
11061
11062 instruct cmov_bns_less(flagsReg crx) %{
11063 // no match-rule, false predicate
11064 effect(DEF crx);
11065 predicate(false);
11066
11067 ins_variable_size_depending_on_alignment(true);
11068
11069 format %{ "CMOV $crx" %}
11070 size(12);
11071 ins_encode %{
11072 Label done;
11073 __ bns($crx$$CondRegister, done); // not unordered -> keep crx
11074 __ li(R0, 0);
11075 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less'
11076 __ bind(done);
11077 %}
11078 ins_pipe(pipe_class_default);
11079 %}
11080
11081 // Compare floating, generate condition code.
11082 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{
11083 // FIXME: should we match 'If cmp (CmpF src1 src2))' ??
11084 //
11085 // The following code sequence occurs a lot in mpegaudio:
11086 //
11087 // block BXX:
11088 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0):
11089 // cmpFUrd CR6, F11, F9
11090 // 4: instruct cmov_bns_less (cmpF_reg_reg-1):
11091 // cmov CR6
11092 // 8: instruct branchConSched:
11093 // B_FARle CR6, B56 P=0.500000 C=-1.000000
11094 match(Set crx (CmpF src1 src2));
11095 ins_cost(DEFAULT_COST+BRANCH_COST);
11096
11097 format %{ "CMPF $crx, $src1, $src2 \t// postalloc expanded" %}
11098 postalloc_expand %{
11099 //
11100 // replaces
11101 //
11102 // region src1 src2
11103 // \ | |
11104 // crx=cmpF_reg_reg
11105 //
11106 // with
11107 //
11108 // region src1 src2
11109 // \ | |
11110 // crx=cmpFUnordered_reg_reg
11111 // |
11112 // ^ region
11113 // | \
11114 // crx=cmov_bns_less
11115 //
11116
11117 // Create new nodes.
11118 MachNode *m1 = new cmpFUnordered_reg_regNode();
11119 MachNode *m2 = new cmov_bns_lessNode();
11120
11121 // inputs for new nodes
11122 m1->add_req(n_region, n_src1, n_src2);
11123 m2->add_req(n_region);
11124 m2->add_prec(m1);
11125
11126 // operands for new nodes
11127 m1->_opnds[0] = op_crx;
11128 m1->_opnds[1] = op_src1;
11129 m1->_opnds[2] = op_src2;
11130 m2->_opnds[0] = op_crx;
11131
11132 // registers for new nodes
11133 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11134 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11135
11136 // Insert new nodes.
11137 nodes->push(m1);
11138 nodes->push(m2);
11139 %}
11140 %}
11141
11142 // Compare float, generate -1,0,1
11143 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{
11144 match(Set dst (CmpF3 src1 src2));
11145 effect(KILL cr0);
11146 ins_cost(DEFAULT_COST * 6);
11147 size((VM_Version::has_brw() ? 20 : 24));
11148
11149 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %}
11150
11151 ins_encode %{
11152 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
11153 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11154 %}
11155 ins_pipe(pipe_class_default);
11156 %}
11157
11158 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
11159 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
11160 // node right before the conditional move using it.
11161 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
11162 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
11163 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
11164 // conditional move was supposed to be spilled.
11165 match(Set crx (CmpD src1 src2));
11166 // False predicate, shall not be matched.
11167 predicate(false);
11168
11169 format %{ "cmpFUrd $crx, $src1, $src2" %}
11170 size(4);
11171 ins_encode %{
11172 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11173 %}
11174 ins_pipe(pipe_class_default);
11175 %}
11176
11177 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{
11178 match(Set crx (CmpD src1 src2));
11179 ins_cost(DEFAULT_COST+BRANCH_COST);
11180
11181 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %}
11182 postalloc_expand %{
11183 //
11184 // replaces
11185 //
11186 // region src1 src2
11187 // \ | |
11188 // crx=cmpD_reg_reg
11189 //
11190 // with
11191 //
11192 // region src1 src2
11193 // \ | |
11194 // crx=cmpDUnordered_reg_reg
11195 // |
11196 // ^ region
11197 // | \
11198 // crx=cmov_bns_less
11199 //
11200
11201 // create new nodes
11202 MachNode *m1 = new cmpDUnordered_reg_regNode();
11203 MachNode *m2 = new cmov_bns_lessNode();
11204
11205 // inputs for new nodes
11206 m1->add_req(n_region, n_src1, n_src2);
11207 m2->add_req(n_region);
11208 m2->add_prec(m1);
11209
11210 // operands for new nodes
11211 m1->_opnds[0] = op_crx;
11212 m1->_opnds[1] = op_src1;
11213 m1->_opnds[2] = op_src2;
11214 m2->_opnds[0] = op_crx;
11215
11216 // registers for new nodes
11217 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11218 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11219
11220 // Insert new nodes.
11221 nodes->push(m1);
11222 nodes->push(m2);
11223 %}
11224 %}
11225
11226 // Compare double, generate -1,0,1
11227 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{
11228 match(Set dst (CmpD3 src1 src2));
11229 effect(KILL cr0);
11230 ins_cost(DEFAULT_COST * 6);
11231 size((VM_Version::has_brw() ? 20 : 24));
11232
11233 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %}
11234
11235 ins_encode %{
11236 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
11237 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11238 %}
11239 ins_pipe(pipe_class_default);
11240 %}
11241
11242 // Compare char
11243 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11244 match(Set dst (Digit src1));
11245 effect(TEMP src2, TEMP crx);
11246 ins_cost(3 * DEFAULT_COST);
11247
11248 format %{ "LI $src2, 0x3930\n\t"
11249 "CMPRB $crx, 0, $src1, $src2\n\t"
11250 "SETB $dst, $crx" %}
11251 size(12);
11252 ins_encode %{
11253 // 0x30: 0, 0x39: 9
11254 __ li($src2$$Register, 0x3930);
11255 // compare src1 with ranges 0x30 to 0x39
11256 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11257 __ setb($dst$$Register, $crx$$CondRegister);
11258 %}
11259 ins_pipe(pipe_class_default);
11260 %}
11261
11262 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11263 match(Set dst (LowerCase src1));
11264 effect(TEMP src2, TEMP crx);
11265 ins_cost(12 * DEFAULT_COST);
11266
11267 format %{ "LI $src2, 0x7A61\n\t"
11268 "CMPRB $crx, 0, $src1, $src2\n\t"
11269 "BGT $crx, done\n\t"
11270 "LIS $src2, (signed short)0xF6DF\n\t"
11271 "ORI $src2, $src2, 0xFFF8\n\t"
11272 "CMPRB $crx, 1, $src1, $src2\n\t"
11273 "BGT $crx, done\n\t"
11274 "LIS $src2, (signed short)0xAAB5\n\t"
11275 "ORI $src2, $src2, 0xBABA\n\t"
11276 "INSRDI $src2, $src2, 32, 0\n\t"
11277 "CMPEQB $crx, 1, $src1, $src2\n"
11278 "done:\n\t"
11279 "SETB $dst, $crx" %}
11280
11281 size(48);
11282 ins_encode %{
11283 Label done;
11284 // 0x61: a, 0x7A: z
11285 __ li($src2$$Register, 0x7A61);
11286 // compare src1 with ranges 0x61 to 0x7A
11287 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11288 __ bgt($crx$$CondRegister, done);
11289
11290 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
11291 __ lis($src2$$Register, (signed short)0xF6DF);
11292 __ ori($src2$$Register, $src2$$Register, 0xFFF8);
11293 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
11294 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11295 __ bgt($crx$$CondRegister, done);
11296
11297 // 0xAA: feminine ordinal indicator
11298 // 0xB5: micro sign
11299 // 0xBA: masculine ordinal indicator
11300 __ lis($src2$$Register, (signed short)0xAAB5);
11301 __ ori($src2$$Register, $src2$$Register, 0xBABA);
11302 __ insrdi($src2$$Register, $src2$$Register, 32, 0);
11303 // compare src1 with 0xAA, 0xB5, and 0xBA
11304 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
11305
11306 __ bind(done);
11307 __ setb($dst$$Register, $crx$$CondRegister);
11308 %}
11309 ins_pipe(pipe_class_default);
11310 %}
11311
11312 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11313 match(Set dst (UpperCase src1));
11314 effect(TEMP src2, TEMP crx);
11315 ins_cost(7 * DEFAULT_COST);
11316
11317 format %{ "LI $src2, 0x5A41\n\t"
11318 "CMPRB $crx, 0, $src1, $src2\n\t"
11319 "BGT $crx, done\n\t"
11320 "LIS $src2, (signed short)0xD6C0\n\t"
11321 "ORI $src2, $src2, 0xDED8\n\t"
11322 "CMPRB $crx, 1, $src1, $src2\n"
11323 "done:\n\t"
11324 "SETB $dst, $crx" %}
11325
11326 size(28);
11327 ins_encode %{
11328 Label done;
11329 // 0x41: A, 0x5A: Z
11330 __ li($src2$$Register, 0x5A41);
11331 // compare src1 with a range 0x41 to 0x5A
11332 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11333 __ bgt($crx$$CondRegister, done);
11334
11335 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
11336 __ lis($src2$$Register, (signed short)0xD6C0);
11337 __ ori($src2$$Register, $src2$$Register, 0xDED8);
11338 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
11339 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11340
11341 __ bind(done);
11342 __ setb($dst$$Register, $crx$$CondRegister);
11343 %}
11344 ins_pipe(pipe_class_default);
11345 %}
11346
11347 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11348 match(Set dst (Whitespace src1));
11349 predicate(PowerArchitecturePPC64 <= 9);
11350 effect(TEMP src2, TEMP crx);
11351 ins_cost(4 * DEFAULT_COST);
11352
11353 format %{ "LI $src2, 0x0D09\n\t"
11354 "ADDIS $src2, 0x201C\n\t"
11355 "CMPRB $crx, 1, $src1, $src2\n\t"
11356 "SETB $dst, $crx" %}
11357 size(16);
11358 ins_encode %{
11359 // 0x09 to 0x0D, 0x1C to 0x20
11360 __ li($src2$$Register, 0x0D09);
11361 __ addis($src2$$Register, $src2$$Register, 0x0201C);
11362 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11363 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11364 __ setb($dst$$Register, $crx$$CondRegister);
11365 %}
11366 ins_pipe(pipe_class_default);
11367 %}
11368
11369 // Power 10 version, using prefixed addi to load 32-bit constant
11370 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11371 match(Set dst (Whitespace src1));
11372 predicate(PowerArchitecturePPC64 >= 10);
11373 effect(TEMP src2, TEMP crx);
11374 ins_cost(3 * DEFAULT_COST);
11375
11376 format %{ "PLI $src2, 0x201C0D09\n\t"
11377 "CMPRB $crx, 1, $src1, $src2\n\t"
11378 "SETB $dst, $crx" %}
11379 size(16);
11380 ins_encode %{
11381 // 0x09 to 0x0D, 0x1C to 0x20
11382 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
11383 __ pli($src2$$Register, 0x201C0D09);
11384 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11385 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11386 __ setb($dst$$Register, $crx$$CondRegister);
11387 %}
11388 ins_pipe(pipe_class_default);
11389 ins_alignment(2);
11390 %}
11391
11392 //----------Branches---------------------------------------------------------
11393 // Jump
11394
11395 // Direct Branch.
11396 instruct branch(label labl) %{
11397 match(Goto);
11398 effect(USE labl);
11399 ins_cost(BRANCH_COST);
11400
11401 format %{ "B $labl" %}
11402 size(4);
11403 ins_encode %{
11404 Label d; // dummy
11405 __ bind(d);
11406 Label* p = $labl$$label;
11407 // `p' is `nullptr' when this encoding class is used only to
11408 // determine the size of the encoded instruction.
11409 Label& l = (nullptr == p)? d : *(p);
11410 __ b(l);
11411 %}
11412 ins_pipe(pipe_class_default);
11413 %}
11414
11415 // Conditional Near Branch
11416 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11417 // Same match rule as `branchConFar'.
11418 match(If cmp crx);
11419 effect(USE lbl);
11420 ins_cost(BRANCH_COST);
11421
11422 // If set to 1 this indicates that the current instruction is a
11423 // short variant of a long branch. This avoids using this
11424 // instruction in first-pass matching. It will then only be used in
11425 // the `Shorten_branches' pass.
11426 ins_short_branch(1);
11427
11428 format %{ "B$cmp $crx, $lbl" %}
11429 size(4);
11430 ins_encode( enc_bc(crx, cmp, lbl) );
11431 ins_pipe(pipe_class_default);
11432 %}
11433
11434 // This is for cases when the ppc64 `bc' instruction does not
11435 // reach far enough. So we emit a far branch here, which is more
11436 // expensive.
11437 //
11438 // Conditional Far Branch
11439 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11440 // Same match rule as `branchCon'.
11441 match(If cmp crx);
11442 effect(USE crx, USE lbl);
11443 // Higher cost than `branchCon'.
11444 ins_cost(5*BRANCH_COST);
11445
11446 // This is not a short variant of a branch, but the long variant.
11447 ins_short_branch(0);
11448
11449 format %{ "B_FAR$cmp $crx, $lbl" %}
11450 size(8);
11451 ins_encode( enc_bc_far(crx, cmp, lbl) );
11452 ins_pipe(pipe_class_default);
11453 %}
11454
11455 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
11456 match(CountedLoopEnd cmp crx);
11457 effect(USE labl);
11458 ins_cost(BRANCH_COST);
11459
11460 // short variant.
11461 ins_short_branch(1);
11462
11463 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
11464 size(4);
11465 ins_encode( enc_bc(crx, cmp, labl) );
11466 ins_pipe(pipe_class_default);
11467 %}
11468
11469 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
11470 match(CountedLoopEnd cmp crx);
11471 effect(USE labl);
11472 ins_cost(BRANCH_COST);
11473
11474 // Long variant.
11475 ins_short_branch(0);
11476
11477 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
11478 size(8);
11479 ins_encode( enc_bc_far(crx, cmp, labl) );
11480 ins_pipe(pipe_class_default);
11481 %}
11482
11483 // ============================================================================
11484 // Java runtime operations, intrinsics and other complex operations.
11485
11486 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
11487 // array for an instance of the superklass. Set a hidden internal cache on a
11488 // hit (cache is checked with exposed code in gen_subtype_check()). Return
11489 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
11490 //
11491 // GL TODO: Improve this.
11492 // - result should not be a TEMP
11493 // - Add match rule as on sparc avoiding additional Cmp.
11494 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
11495 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
11496 match(Set result (PartialSubtypeCheck subklass superklass));
11497 predicate(!UseSecondarySupersTable);
11498 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
11499 ins_cost(DEFAULT_COST*10);
11500
11501 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
11502 ins_encode %{
11503 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
11504 $tmp_klass$$Register, nullptr, $result$$Register);
11505 %}
11506 ins_pipe(pipe_class_default);
11507 %}
11508
11509 // Two versions of partialSubtypeCheck, both used when we need to
11510 // search for a super class in the secondary supers array. The first
11511 // is used when we don't know _a priori_ the class being searched
11512 // for. The second, far more common, is used when we do know: this is
11513 // used for instanceof, checkcast, and any case where C2 can determine
11514 // it by constant propagation.
11515 instruct partialSubtypeCheckVarSuper(iRegPsrc sub, iRegPsrc super, iRegPdst result,
11516 iRegPdst tempR1, iRegPdst tempR2, iRegPdst tempR3, iRegPdst tempR4,
11517 flagsRegCR0 cr0, regCTR ctr)
11518 %{
11519 match(Set result (PartialSubtypeCheck sub super));
11520 predicate(UseSecondarySupersTable);
11521 effect(KILL cr0, KILL ctr, TEMP_DEF result, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11522
11523 ins_cost(DEFAULT_COST * 10); // slightly larger than the next version
11524 format %{ "partialSubtypeCheck $result, $sub, $super" %}
11525 ins_encode %{
11526 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register,
11527 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11528 $result$$Register);
11529 %}
11530 ins_pipe(pipe_class_memory);
11531 %}
11532
11533 instruct partialSubtypeCheckConstSuper(rarg3RegP sub, rarg2RegP super_reg, immP super_con, rarg6RegP result,
11534 rarg1RegP tempR1, rarg5RegP tempR2, rarg4RegP tempR3, rscratch1RegP tempR4,
11535 flagsRegCR0 cr0, regCTR ctr)
11536 %{
11537 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
11538 predicate(UseSecondarySupersTable);
11539 effect(KILL cr0, KILL ctr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11540
11541 ins_cost(DEFAULT_COST*8); // smaller than the other version
11542 format %{ "partialSubtypeCheck $result, $sub, $super_reg" %}
11543
11544 ins_encode %{
11545 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
11546 if (InlineSecondarySupersTest) {
11547 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register,
11548 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11549 $result$$Register, super_klass_slot);
11550 } else {
11551 address stub = StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot);
11552 Register r_stub_addr = $tempR1$$Register;
11553 __ add_const_optimized(r_stub_addr, R29_TOC, MacroAssembler::offset_to_global_toc(stub), R0);
11554 __ mtctr(r_stub_addr);
11555 __ bctrl();
11556 }
11557 %}
11558
11559 ins_pipe(pipe_class_memory);
11560 %}
11561
11562 // inlined locking and unlocking
11563
11564 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
11565 predicate(!UseObjectMonitorTable);
11566 match(Set crx (FastLock oop box));
11567 effect(TEMP tmp1, TEMP tmp2);
11568
11569 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %}
11570 ins_encode %{
11571 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11572 $tmp1$$Register, $tmp2$$Register, noreg /*tmp3*/);
11573 // If locking was successful, crx should indicate 'EQ'.
11574 // The compiler generates a branch to the runtime call to
11575 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11576 %}
11577 ins_pipe(pipe_class_compare);
11578 %}
11579
11580 instruct cmpFastLockMonitorTable(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, flagsRegCR1 cr1) %{
11581 predicate(UseObjectMonitorTable);
11582 match(Set crx (FastLock oop box));
11583 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr1);
11584
11585 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3" %}
11586 ins_encode %{
11587 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11588 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11589 // If locking was successful, crx should indicate 'EQ'.
11590 // The compiler generates a branch to the runtime call to
11591 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11592 %}
11593 ins_pipe(pipe_class_compare);
11594 %}
11595
11596 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11597 match(Set crx (FastUnlock oop box));
11598 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11599
11600 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
11601 ins_encode %{
11602 __ fast_unlock($crx$$CondRegister, $oop$$Register, $box$$Register,
11603 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11604 // If unlocking was successful, crx should indicate 'EQ'.
11605 // The compiler generates a branch to the runtime call to
11606 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11607 %}
11608 ins_pipe(pipe_class_compare);
11609 %}
11610
11611 // Align address.
11612 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11613 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11614
11615 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
11616 size(4);
11617 ins_encode %{
11618 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant));
11619 %}
11620 ins_pipe(pipe_class_default);
11621 %}
11622
11623 // Array size computation.
11624 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11625 match(Set dst (SubL (CastP2X end) (CastP2X start)));
11626
11627 format %{ "SUB $dst, $end, $start \t// array size in bytes" %}
11628 size(4);
11629 ins_encode %{
11630 __ subf($dst$$Register, $start$$Register, $end$$Register);
11631 %}
11632 ins_pipe(pipe_class_default);
11633 %}
11634
11635 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
11636 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11637 match(Set dummy (ClearArray cnt base));
11638 effect(USE_KILL base, KILL ctr);
11639 ins_cost(2 * MEMORY_REF_COST);
11640
11641 format %{ "ClearArray $cnt, $base" %}
11642 ins_encode %{
11643 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
11644 %}
11645 ins_pipe(pipe_class_default);
11646 %}
11647
11648 // Clear-array with constant large array length.
11649 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{
11650 match(Set dummy (ClearArray cnt base));
11651 effect(USE_KILL base, TEMP tmp, KILL ctr);
11652 ins_cost(3 * MEMORY_REF_COST);
11653
11654 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
11655 ins_encode %{
11656 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
11657 %}
11658 ins_pipe(pipe_class_default);
11659 %}
11660
11661 // Clear-array with dynamic array length.
11662 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11663 match(Set dummy (ClearArray cnt base));
11664 effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11665 ins_cost(4 * MEMORY_REF_COST);
11666
11667 format %{ "ClearArray $cnt, $base" %}
11668 ins_encode %{
11669 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
11670 %}
11671 ins_pipe(pipe_class_default);
11672 %}
11673
11674 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11675 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11676 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11677 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11678 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11679 ins_cost(300);
11680 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11681 ins_encode %{
11682 __ string_compare($str1$$Register, $str2$$Register,
11683 $cnt1$$Register, $cnt2$$Register,
11684 $tmp$$Register,
11685 $result$$Register, StrIntrinsicNode::LL);
11686 %}
11687 ins_pipe(pipe_class_default);
11688 %}
11689
11690 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11691 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11692 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11693 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11694 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11695 ins_cost(300);
11696 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11697 ins_encode %{
11698 __ string_compare($str1$$Register, $str2$$Register,
11699 $cnt1$$Register, $cnt2$$Register,
11700 $tmp$$Register,
11701 $result$$Register, StrIntrinsicNode::UU);
11702 %}
11703 ins_pipe(pipe_class_default);
11704 %}
11705
11706 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11707 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11708 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11709 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11710 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11711 ins_cost(300);
11712 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11713 ins_encode %{
11714 __ string_compare($str1$$Register, $str2$$Register,
11715 $cnt1$$Register, $cnt2$$Register,
11716 $tmp$$Register,
11717 $result$$Register, StrIntrinsicNode::LU);
11718 %}
11719 ins_pipe(pipe_class_default);
11720 %}
11721
11722 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11723 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11724 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11725 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11726 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11727 ins_cost(300);
11728 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11729 ins_encode %{
11730 __ string_compare($str2$$Register, $str1$$Register,
11731 $cnt2$$Register, $cnt1$$Register,
11732 $tmp$$Register,
11733 $result$$Register, StrIntrinsicNode::UL);
11734 %}
11735 ins_pipe(pipe_class_default);
11736 %}
11737
11738 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11739 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11740 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11741 match(Set result (StrEquals (Binary str1 str2) cnt));
11742 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11743 ins_cost(300);
11744 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11745 ins_encode %{
11746 __ array_equals(false, $str1$$Register, $str2$$Register,
11747 $cnt$$Register, $tmp$$Register,
11748 $result$$Register, true /* byte */);
11749 %}
11750 ins_pipe(pipe_class_default);
11751 %}
11752
11753 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11754 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11755 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11756 match(Set result (AryEq ary1 ary2));
11757 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11758 ins_cost(300);
11759 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11760 ins_encode %{
11761 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11762 $tmp1$$Register, $tmp2$$Register,
11763 $result$$Register, true /* byte */);
11764 %}
11765 ins_pipe(pipe_class_default);
11766 %}
11767
11768 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11769 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11770 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11771 match(Set result (AryEq ary1 ary2));
11772 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11773 ins_cost(300);
11774 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11775 ins_encode %{
11776 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11777 $tmp1$$Register, $tmp2$$Register,
11778 $result$$Register, false /* byte */);
11779 %}
11780 ins_pipe(pipe_class_default);
11781 %}
11782
11783 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11784 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11785 iRegIdst tmp1, iRegIdst tmp2,
11786 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11787 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11788 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11789 // Required for EA: check if it is still a type_array.
11790 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11791 ins_cost(150);
11792
11793 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11794 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11795
11796 ins_encode %{
11797 immPOper *needleOper = (immPOper *)$needleImm;
11798 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11799 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11800 jchar chr;
11801 #ifdef VM_LITTLE_ENDIAN
11802 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11803 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11804 #else
11805 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11806 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11807 #endif
11808 __ string_indexof_char($result$$Register,
11809 $haystack$$Register, $haycnt$$Register,
11810 R0, chr,
11811 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11812 %}
11813 ins_pipe(pipe_class_compare);
11814 %}
11815
11816 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11817 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11818 iRegIdst tmp1, iRegIdst tmp2,
11819 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11820 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11821 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11822 // Required for EA: check if it is still a type_array.
11823 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11824 ins_cost(150);
11825
11826 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11827 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11828
11829 ins_encode %{
11830 immPOper *needleOper = (immPOper *)$needleImm;
11831 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11832 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11833 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11834 __ string_indexof_char($result$$Register,
11835 $haystack$$Register, $haycnt$$Register,
11836 R0, chr,
11837 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11838 %}
11839 ins_pipe(pipe_class_compare);
11840 %}
11841
11842 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11843 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11844 iRegIdst tmp1, iRegIdst tmp2,
11845 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11846 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11847 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11848 // Required for EA: check if it is still a type_array.
11849 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11850 ins_cost(150);
11851
11852 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11853 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11854
11855 ins_encode %{
11856 immPOper *needleOper = (immPOper *)$needleImm;
11857 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11858 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11859 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11860 __ string_indexof_char($result$$Register,
11861 $haystack$$Register, $haycnt$$Register,
11862 R0, chr,
11863 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11864 %}
11865 ins_pipe(pipe_class_compare);
11866 %}
11867
11868 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11869 rscratch2RegP needle, immI_1 needlecntImm,
11870 iRegIdst tmp1, iRegIdst tmp2,
11871 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11872 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11873 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11874 // Required for EA: check if it is still a type_array.
11875 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11876 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11877 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11878 ins_cost(180);
11879
11880 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11881 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11882 ins_encode %{
11883 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11884 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11885 guarantee(needle_values, "sanity");
11886 jchar chr;
11887 #ifdef VM_LITTLE_ENDIAN
11888 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11889 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11890 #else
11891 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11892 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11893 #endif
11894 __ string_indexof_char($result$$Register,
11895 $haystack$$Register, $haycnt$$Register,
11896 R0, chr,
11897 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11898 %}
11899 ins_pipe(pipe_class_compare);
11900 %}
11901
11902 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11903 rscratch2RegP needle, immI_1 needlecntImm,
11904 iRegIdst tmp1, iRegIdst tmp2,
11905 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11906 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11907 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11908 // Required for EA: check if it is still a type_array.
11909 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11910 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11911 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11912 ins_cost(180);
11913
11914 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11915 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11916 ins_encode %{
11917 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11918 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11919 guarantee(needle_values, "sanity");
11920 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11921 __ string_indexof_char($result$$Register,
11922 $haystack$$Register, $haycnt$$Register,
11923 R0, chr,
11924 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11925 %}
11926 ins_pipe(pipe_class_compare);
11927 %}
11928
11929 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11930 rscratch2RegP needle, immI_1 needlecntImm,
11931 iRegIdst tmp1, iRegIdst tmp2,
11932 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11933 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11934 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11935 // Required for EA: check if it is still a type_array.
11936 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11937 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11938 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11939 ins_cost(180);
11940
11941 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11942 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11943 ins_encode %{
11944 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11945 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11946 guarantee(needle_values, "sanity");
11947 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11948 __ string_indexof_char($result$$Register,
11949 $haystack$$Register, $haycnt$$Register,
11950 R0, chr,
11951 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11952 %}
11953 ins_pipe(pipe_class_compare);
11954 %}
11955
11956 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11957 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11958 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11959 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11960 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11961 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
11962 ins_cost(180);
11963
11964 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch"
11965 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11966 ins_encode %{
11967 __ string_indexof_char($result$$Register,
11968 $haystack$$Register, $haycnt$$Register,
11969 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11970 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11971 %}
11972 ins_pipe(pipe_class_compare);
11973 %}
11974
11975 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11976 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11977 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11978 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11979 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11980 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
11981 ins_cost(180);
11982
11983 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch"
11984 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11985 ins_encode %{
11986 __ string_indexof_char($result$$Register,
11987 $haystack$$Register, $haycnt$$Register,
11988 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11989 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11990 %}
11991 ins_pipe(pipe_class_compare);
11992 %}
11993
11994 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11995 iRegPsrc needle, uimmI15 needlecntImm,
11996 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11997 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11998 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11999 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12000 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12001 // Required for EA: check if it is still a type_array.
12002 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
12003 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12004 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12005 ins_cost(250);
12006
12007 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12008 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12009 ins_encode %{
12010 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12011 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12012
12013 __ string_indexof($result$$Register,
12014 $haystack$$Register, $haycnt$$Register,
12015 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12016 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
12017 %}
12018 ins_pipe(pipe_class_compare);
12019 %}
12020
12021 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12022 iRegPsrc needle, uimmI15 needlecntImm,
12023 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12024 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12025 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12026 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12027 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12028 // Required for EA: check if it is still a type_array.
12029 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
12030 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12031 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12032 ins_cost(250);
12033
12034 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12035 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12036 ins_encode %{
12037 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12038 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12039
12040 __ string_indexof($result$$Register,
12041 $haystack$$Register, $haycnt$$Register,
12042 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12043 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
12044 %}
12045 ins_pipe(pipe_class_compare);
12046 %}
12047
12048 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12049 iRegPsrc needle, uimmI15 needlecntImm,
12050 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12051 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12052 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12053 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12054 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12055 // Required for EA: check if it is still a type_array.
12056 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
12057 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12058 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12059 ins_cost(250);
12060
12061 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12062 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12063 ins_encode %{
12064 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12065 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12066
12067 __ string_indexof($result$$Register,
12068 $haystack$$Register, $haycnt$$Register,
12069 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12070 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
12071 %}
12072 ins_pipe(pipe_class_compare);
12073 %}
12074
12075 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12076 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12077 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12078 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12079 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12080 TEMP_DEF result,
12081 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12082 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
12083 ins_cost(300);
12084
12085 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12086 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12087 ins_encode %{
12088 __ string_indexof($result$$Register,
12089 $haystack$$Register, $haycnt$$Register,
12090 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
12091 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
12092 %}
12093 ins_pipe(pipe_class_compare);
12094 %}
12095
12096 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12097 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12098 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12099 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12100 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12101 TEMP_DEF result,
12102 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12103 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
12104 ins_cost(300);
12105
12106 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12107 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12108 ins_encode %{
12109 __ string_indexof($result$$Register,
12110 $haystack$$Register, $haycnt$$Register,
12111 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
12112 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
12113 %}
12114 ins_pipe(pipe_class_compare);
12115 %}
12116
12117 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12118 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12119 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12120 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12121 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12122 TEMP_DEF result,
12123 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12124 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
12125 ins_cost(300);
12126
12127 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12128 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12129 ins_encode %{
12130 __ string_indexof($result$$Register,
12131 $haystack$$Register, $haycnt$$Register,
12132 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
12133 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
12134 %}
12135 ins_pipe(pipe_class_compare);
12136 %}
12137
12138 // char[] to byte[] compression
12139 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12140 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12141 match(Set result (StrCompressedCopy src (Binary dst len)));
12142 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12143 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12144 ins_cost(300);
12145 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12146 ins_encode %{
12147 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12148 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
12149 %}
12150 ins_pipe(pipe_class_default);
12151 %}
12152
12153 // byte[] to char[] inflation
12154 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
12155 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12156 match(Set dummy (StrInflatedCopy src (Binary dst len)));
12157 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12158 ins_cost(300);
12159 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12160 ins_encode %{
12161 Label Ldone;
12162 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
12163 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
12164 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
12165 __ beq(CR0, Ldone);
12166 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
12167 __ bind(Ldone);
12168 %}
12169 ins_pipe(pipe_class_default);
12170 %}
12171
12172 // StringCoding.java intrinsics
12173 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
12174 regCTR ctr, flagsRegCR0 cr0)
12175 %{
12176 match(Set result (CountPositives ary1 len));
12177 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
12178 ins_cost(300);
12179 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
12180 ins_encode %{
12181 __ count_positives($ary1$$Register, $len$$Register, $result$$Register,
12182 $tmp1$$Register, $tmp2$$Register);
12183 %}
12184 ins_pipe(pipe_class_default);
12185 %}
12186
12187 // encode char[] to byte[] in ISO_8859_1
12188 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12189 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12190 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
12191 match(Set result (EncodeISOArray src (Binary dst len)));
12192 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12193 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12194 ins_cost(300);
12195 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12196 ins_encode %{
12197 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12198 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
12199 %}
12200 ins_pipe(pipe_class_default);
12201 %}
12202
12203 // encode char[] to byte[] in ASCII
12204 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12205 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12206 predicate(((EncodeISOArrayNode*)n)->is_ascii());
12207 match(Set result (EncodeISOArray src (Binary dst len)));
12208 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12209 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12210 ins_cost(300);
12211 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12212 ins_encode %{
12213 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12214 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
12215 %}
12216 ins_pipe(pipe_class_default);
12217 %}
12218
12219
12220 //---------- Min/Max Instructions ---------------------------------------------
12221
12222
12223 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12224 match(Set dst (MinI src1 src2));
12225 effect(KILL cr0);
12226 ins_cost(DEFAULT_COST*2);
12227
12228 size(8);
12229 ins_encode %{
12230 __ cmpw(CR0, $src1$$Register, $src2$$Register);
12231 __ isel($dst$$Register, CR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
12232 %}
12233 ins_pipe(pipe_class_default);
12234 %}
12235
12236
12237 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12238 match(Set dst (MaxI src1 src2));
12239 effect(KILL cr0);
12240 ins_cost(DEFAULT_COST*2);
12241
12242 size(8);
12243 ins_encode %{
12244 __ cmpw(CR0, $src1$$Register, $src2$$Register);
12245 __ isel($dst$$Register, CR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
12246 %}
12247 ins_pipe(pipe_class_default);
12248 %}
12249
12250 instruct minF(regF dst, regF src1, regF src2) %{
12251 match(Set dst (MinF src1 src2));
12252 predicate(PowerArchitecturePPC64 >= 9);
12253 ins_cost(DEFAULT_COST);
12254
12255 format %{ "XSMINJDP $dst, $src1, $src2\t// MinF" %}
12256 size(4);
12257 ins_encode %{
12258 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12259 %}
12260 ins_pipe(pipe_class_default);
12261 %}
12262
12263 instruct minD(regD dst, regD src1, regD src2) %{
12264 match(Set dst (MinD src1 src2));
12265 predicate(PowerArchitecturePPC64 >= 9);
12266 ins_cost(DEFAULT_COST);
12267
12268 format %{ "XSMINJDP $dst, $src1, $src2\t// MinD" %}
12269 size(4);
12270 ins_encode %{
12271 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12272 %}
12273 ins_pipe(pipe_class_default);
12274 %}
12275
12276 instruct maxF(regF dst, regF src1, regF src2) %{
12277 match(Set dst (MaxF src1 src2));
12278 predicate(PowerArchitecturePPC64 >= 9);
12279 ins_cost(DEFAULT_COST);
12280
12281 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxF" %}
12282 size(4);
12283 ins_encode %{
12284 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12285 %}
12286 ins_pipe(pipe_class_default);
12287 %}
12288
12289 instruct maxD(regD dst, regD src1, regD src2) %{
12290 match(Set dst (MaxD src1 src2));
12291 predicate(PowerArchitecturePPC64 >= 9);
12292 ins_cost(DEFAULT_COST);
12293
12294 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxD" %}
12295 size(4);
12296 ins_encode %{
12297 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12298 %}
12299 ins_pipe(pipe_class_default);
12300 %}
12301
12302 //---------- Population Count Instructions ------------------------------------
12303
12304 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
12305 match(Set dst (PopCountI src));
12306 predicate(UsePopCountInstruction);
12307 ins_cost(DEFAULT_COST);
12308
12309 format %{ "POPCNTW $dst, $src" %}
12310 size(4);
12311 ins_encode %{
12312 __ popcntw($dst$$Register, $src$$Register);
12313 %}
12314 ins_pipe(pipe_class_default);
12315 %}
12316
12317 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
12318 predicate(UsePopCountInstruction);
12319 match(Set dst (PopCountL src));
12320 ins_cost(DEFAULT_COST);
12321
12322 format %{ "POPCNTD $dst, $src" %}
12323 size(4);
12324 ins_encode %{
12325 __ popcntd($dst$$Register, $src$$Register);
12326 %}
12327 ins_pipe(pipe_class_default);
12328 %}
12329
12330 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
12331 match(Set dst (CountLeadingZerosI src));
12332 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12333 ins_cost(DEFAULT_COST);
12334
12335 format %{ "CNTLZW $dst, $src" %}
12336 size(4);
12337 ins_encode %{
12338 __ cntlzw($dst$$Register, $src$$Register);
12339 %}
12340 ins_pipe(pipe_class_default);
12341 %}
12342
12343 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
12344 match(Set dst (CountLeadingZerosL src));
12345 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12346 ins_cost(DEFAULT_COST);
12347
12348 format %{ "CNTLZD $dst, $src" %}
12349 size(4);
12350 ins_encode %{
12351 __ cntlzd($dst$$Register, $src$$Register);
12352 %}
12353 ins_pipe(pipe_class_default);
12354 %}
12355
12356 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
12357 // no match-rule, false predicate
12358 effect(DEF dst, USE src);
12359 predicate(false);
12360
12361 format %{ "CNTLZD $dst, $src" %}
12362 size(4);
12363 ins_encode %{
12364 __ cntlzd($dst$$Register, $src$$Register);
12365 %}
12366 ins_pipe(pipe_class_default);
12367 %}
12368
12369 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
12370 match(Set dst (CountTrailingZerosI src));
12371 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12372 ins_cost(DEFAULT_COST);
12373
12374 expand %{
12375 immI16 imm1 %{ (int)-1 %}
12376 immI16 imm2 %{ (int)32 %}
12377 immI_minus1 m1 %{ -1 %}
12378 iRegIdst tmpI1;
12379 iRegIdst tmpI2;
12380 iRegIdst tmpI3;
12381 addI_reg_imm16(tmpI1, src, imm1);
12382 andcI_reg_reg(tmpI2, src, m1, tmpI1);
12383 countLeadingZerosI(tmpI3, tmpI2);
12384 subI_imm16_reg(dst, imm2, tmpI3);
12385 %}
12386 %}
12387
12388 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{
12389 match(Set dst (CountTrailingZerosI src));
12390 predicate(UseCountTrailingZerosInstructionsPPC64);
12391 ins_cost(DEFAULT_COST);
12392
12393 format %{ "CNTTZW $dst, $src" %}
12394 size(4);
12395 ins_encode %{
12396 __ cnttzw($dst$$Register, $src$$Register);
12397 %}
12398 ins_pipe(pipe_class_default);
12399 %}
12400
12401 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
12402 match(Set dst (CountTrailingZerosL src));
12403 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12404 ins_cost(DEFAULT_COST);
12405
12406 expand %{
12407 immL16 imm1 %{ (long)-1 %}
12408 immI16 imm2 %{ (int)64 %}
12409 iRegLdst tmpL1;
12410 iRegLdst tmpL2;
12411 iRegIdst tmpL3;
12412 addL_reg_imm16(tmpL1, src, imm1);
12413 andcL_reg_reg(tmpL2, tmpL1, src);
12414 countLeadingZerosL(tmpL3, tmpL2);
12415 subI_imm16_reg(dst, imm2, tmpL3);
12416 %}
12417 %}
12418
12419 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{
12420 match(Set dst (CountTrailingZerosL src));
12421 predicate(UseCountTrailingZerosInstructionsPPC64);
12422 ins_cost(DEFAULT_COST);
12423
12424 format %{ "CNTTZD $dst, $src" %}
12425 size(4);
12426 ins_encode %{
12427 __ cnttzd($dst$$Register, $src$$Register);
12428 %}
12429 ins_pipe(pipe_class_default);
12430 %}
12431
12432 // Expand nodes for byte_reverse_int/ushort/short.
12433 instruct rlwinm(iRegIdst dst, iRegIsrc src, immI16 shift, immI16 mb, immI16 me) %{
12434 effect(DEF dst, USE src, USE shift, USE mb, USE me);
12435 predicate(false);
12436
12437 format %{ "RLWINM $dst, $src, $shift, $mb, $me" %}
12438 size(4);
12439 ins_encode %{
12440 __ rlwinm($dst$$Register, $src$$Register, $shift$$constant, $mb$$constant, $me$$constant);
12441 %}
12442 ins_pipe(pipe_class_default);
12443 %}
12444
12445 // Expand nodes for byte_reverse_int.
12446 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
12447 effect(DEF dst, USE src, USE n, USE b);
12448 predicate(false);
12449
12450 format %{ "INSRWI $dst, $src, $n, $b" %}
12451 size(4);
12452 ins_encode %{
12453 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
12454 %}
12455 ins_pipe(pipe_class_default);
12456 %}
12457
12458 // As insrwi_a, but with USE_DEF.
12459 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
12460 effect(USE_DEF dst, USE src, USE n, USE b);
12461 predicate(false);
12462
12463 format %{ "INSRWI $dst, $src, $n, $b" %}
12464 size(4);
12465 ins_encode %{
12466 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
12467 %}
12468 ins_pipe(pipe_class_default);
12469 %}
12470
12471 // Just slightly faster than java implementation.
12472 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
12473 match(Set dst (ReverseBytesI src));
12474 predicate(!UseByteReverseInstructions);
12475 ins_cost(7*DEFAULT_COST);
12476
12477 expand %{
12478 immI16 imm24 %{ (int) 24 %}
12479 immI16 imm16 %{ (int) 16 %}
12480 immI16 imm8 %{ (int) 8 %}
12481 immI16 imm4 %{ (int) 4 %}
12482 immI16 imm0 %{ (int) 0 %}
12483 iRegLdst tmpI1;
12484 iRegLdst tmpI2;
12485 iRegLdst tmpI3;
12486
12487 urShiftI_reg_imm(tmpI1, src, imm24);
12488 insrwi_a(dst, tmpI1, imm8, imm24);
12489 urShiftI_reg_imm(tmpI2, src, imm16);
12490 insrwi(dst, tmpI2, imm16, imm8);
12491 urShiftI_reg_imm(tmpI3, src, imm8);
12492 insrwi(dst, tmpI3, imm8, imm8);
12493 insrwi(dst, src, imm8, imm0);
12494 %}
12495 %}
12496
12497 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{
12498 match(Set dst (ReverseBytesI src));
12499 predicate(UseVectorByteReverseInstructionsPPC64);
12500 effect(TEMP tmpV);
12501 ins_cost(DEFAULT_COST*3);
12502 size(12);
12503 format %{ "MTVSRWZ $tmpV, $src\n"
12504 "\tXXBRW $tmpV, $tmpV\n"
12505 "\tMFVSRWZ $dst, $tmpV" %}
12506
12507 ins_encode %{
12508 __ mtvsrwz($tmpV$$VectorRegister.to_vsr(), $src$$Register);
12509 __ xxbrw($tmpV$$VectorRegister.to_vsr(), $tmpV$$VectorRegister->to_vsr());
12510 __ mfvsrwz($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12511 %}
12512 ins_pipe(pipe_class_default);
12513 %}
12514
12515 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{
12516 match(Set dst (ReverseBytesI src));
12517 predicate(UseByteReverseInstructions);
12518 ins_cost(DEFAULT_COST);
12519 size(4);
12520
12521 format %{ "BRW $dst, $src" %}
12522
12523 ins_encode %{
12524 __ brw($dst$$Register, $src$$Register);
12525 %}
12526 ins_pipe(pipe_class_default);
12527 %}
12528
12529 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
12530 match(Set dst (ReverseBytesL src));
12531 predicate(!UseByteReverseInstructions);
12532 ins_cost(15*DEFAULT_COST);
12533
12534 expand %{
12535 immI16 imm56 %{ (int) 56 %}
12536 immI16 imm48 %{ (int) 48 %}
12537 immI16 imm40 %{ (int) 40 %}
12538 immI16 imm32 %{ (int) 32 %}
12539 immI16 imm24 %{ (int) 24 %}
12540 immI16 imm16 %{ (int) 16 %}
12541 immI16 imm8 %{ (int) 8 %}
12542 immI16 imm0 %{ (int) 0 %}
12543 iRegLdst tmpL1;
12544 iRegLdst tmpL2;
12545 iRegLdst tmpL3;
12546 iRegLdst tmpL4;
12547 iRegLdst tmpL5;
12548 iRegLdst tmpL6;
12549
12550 // src : |a|b|c|d|e|f|g|h|
12551 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
12552 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
12553 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
12554 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
12555 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
12556 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
12557 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
12558 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
12559 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
12560 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
12561 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
12562 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
12563 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
12564 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
12565 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
12566 %}
12567 %}
12568
12569 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{
12570 match(Set dst (ReverseBytesL src));
12571 predicate(UseVectorByteReverseInstructionsPPC64);
12572 effect(TEMP tmpV);
12573 ins_cost(DEFAULT_COST*3);
12574 size(12);
12575 format %{ "MTVSRD $tmpV, $src\n"
12576 "\tXXBRD $tmpV, $tmpV\n"
12577 "\tMFVSRD $dst, $tmpV" %}
12578
12579 ins_encode %{
12580 __ mtvsrd($tmpV$$VectorRegister->to_vsr(), $src$$Register);
12581 __ xxbrd($tmpV$$VectorRegister->to_vsr(), $tmpV$$VectorRegister->to_vsr());
12582 __ mfvsrd($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12583 %}
12584 ins_pipe(pipe_class_default);
12585 %}
12586
12587 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{
12588 match(Set dst (ReverseBytesL src));
12589 predicate(UseByteReverseInstructions);
12590 ins_cost(DEFAULT_COST);
12591 size(4);
12592
12593 format %{ "BRD $dst, $src" %}
12594
12595 ins_encode %{
12596 __ brd($dst$$Register, $src$$Register);
12597 %}
12598 ins_pipe(pipe_class_default);
12599 %}
12600
12601 // Need zero extend. Must not use brh only.
12602 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
12603 match(Set dst (ReverseBytesUS src));
12604 ins_cost(2*DEFAULT_COST);
12605
12606 expand %{
12607 immI16 imm31 %{ (int) 31 %}
12608 immI16 imm24 %{ (int) 24 %}
12609 immI16 imm16 %{ (int) 16 %}
12610 immI16 imm8 %{ (int) 8 %}
12611
12612 rlwinm(dst, src, imm24, imm24, imm31);
12613 insrwi(dst, src, imm8, imm16);
12614 %}
12615 %}
12616
12617 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
12618 match(Set dst (ReverseBytesS src));
12619 predicate(!UseByteReverseInstructions);
12620 ins_cost(3*DEFAULT_COST);
12621
12622 expand %{
12623 immI16 imm16 %{ (int) 16 %}
12624 immI16 imm8 %{ (int) 8 %}
12625 iRegLdst tmpI1;
12626
12627 urShiftI_reg_imm(tmpI1, src, imm8);
12628 insrwi(tmpI1, src, imm8, imm16);
12629 extsh(dst, tmpI1);
12630 %}
12631 %}
12632
12633 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{
12634 match(Set dst (ReverseBytesS src));
12635 predicate(UseByteReverseInstructions);
12636 ins_cost(DEFAULT_COST);
12637 size(8);
12638
12639 format %{ "BRH $dst, $src\n\t"
12640 "EXTSH $dst, $dst" %}
12641
12642 ins_encode %{
12643 __ brh($dst$$Register, $src$$Register);
12644 __ extsh($dst$$Register, $dst$$Register);
12645 %}
12646 ins_pipe(pipe_class_default);
12647 %}
12648
12649 // Load Integer reversed byte order
12650 instruct loadI_reversed(iRegIdst dst, indirect mem) %{
12651 match(Set dst (ReverseBytesI (LoadI mem)));
12652 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12653 ins_cost(MEMORY_REF_COST);
12654
12655 size(4);
12656 ins_encode %{
12657 __ lwbrx($dst$$Register, $mem$$Register);
12658 %}
12659 ins_pipe(pipe_class_default);
12660 %}
12661
12662 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{
12663 match(Set dst (ReverseBytesI (LoadI mem)));
12664 ins_cost(2 * MEMORY_REF_COST);
12665
12666 size(12);
12667 ins_encode %{
12668 __ lwbrx($dst$$Register, $mem$$Register);
12669 __ twi_0($dst$$Register);
12670 __ isync();
12671 %}
12672 ins_pipe(pipe_class_default);
12673 %}
12674
12675 // Load Long - aligned and reversed
12676 instruct loadL_reversed(iRegLdst dst, indirect mem) %{
12677 match(Set dst (ReverseBytesL (LoadL mem)));
12678 predicate((n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))));
12679 ins_cost(MEMORY_REF_COST);
12680
12681 size(4);
12682 ins_encode %{
12683 __ ldbrx($dst$$Register, $mem$$Register);
12684 %}
12685 ins_pipe(pipe_class_default);
12686 %}
12687
12688 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{
12689 match(Set dst (ReverseBytesL (LoadL mem)));
12690 ins_cost(2 * MEMORY_REF_COST);
12691
12692 size(12);
12693 ins_encode %{
12694 __ ldbrx($dst$$Register, $mem$$Register);
12695 __ twi_0($dst$$Register);
12696 __ isync();
12697 %}
12698 ins_pipe(pipe_class_default);
12699 %}
12700
12701 // Load unsigned short / char reversed byte order
12702 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
12703 match(Set dst (ReverseBytesUS (LoadUS mem)));
12704 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12705 ins_cost(MEMORY_REF_COST);
12706
12707 size(4);
12708 ins_encode %{
12709 __ lhbrx($dst$$Register, $mem$$Register);
12710 %}
12711 ins_pipe(pipe_class_default);
12712 %}
12713
12714 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{
12715 match(Set dst (ReverseBytesUS (LoadUS mem)));
12716 ins_cost(2 * MEMORY_REF_COST);
12717
12718 size(12);
12719 ins_encode %{
12720 __ lhbrx($dst$$Register, $mem$$Register);
12721 __ twi_0($dst$$Register);
12722 __ isync();
12723 %}
12724 ins_pipe(pipe_class_default);
12725 %}
12726
12727 // Load short reversed byte order
12728 instruct loadS_reversed(iRegIdst dst, indirect mem) %{
12729 match(Set dst (ReverseBytesS (LoadS mem)));
12730 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12731 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
12732
12733 size(8);
12734 ins_encode %{
12735 __ lhbrx($dst$$Register, $mem$$Register);
12736 __ extsh($dst$$Register, $dst$$Register);
12737 %}
12738 ins_pipe(pipe_class_default);
12739 %}
12740
12741 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{
12742 match(Set dst (ReverseBytesS (LoadS mem)));
12743 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12744
12745 size(16);
12746 ins_encode %{
12747 __ lhbrx($dst$$Register, $mem$$Register);
12748 __ twi_0($dst$$Register);
12749 __ extsh($dst$$Register, $dst$$Register);
12750 __ isync();
12751 %}
12752 ins_pipe(pipe_class_default);
12753 %}
12754
12755 // Store Integer reversed byte order
12756 instruct storeI_reversed(iRegIsrc src, indirect mem) %{
12757 match(Set mem (StoreI mem (ReverseBytesI src)));
12758 ins_cost(MEMORY_REF_COST);
12759
12760 size(4);
12761 ins_encode %{
12762 __ stwbrx($src$$Register, $mem$$Register);
12763 %}
12764 ins_pipe(pipe_class_default);
12765 %}
12766
12767 // Store Long reversed byte order
12768 instruct storeL_reversed(iRegLsrc src, indirect mem) %{
12769 match(Set mem (StoreL mem (ReverseBytesL src)));
12770 ins_cost(MEMORY_REF_COST);
12771
12772 size(4);
12773 ins_encode %{
12774 __ stdbrx($src$$Register, $mem$$Register);
12775 %}
12776 ins_pipe(pipe_class_default);
12777 %}
12778
12779 // Store unsigned short / char reversed byte order
12780 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
12781 match(Set mem (StoreC mem (ReverseBytesUS src)));
12782 ins_cost(MEMORY_REF_COST);
12783
12784 size(4);
12785 ins_encode %{
12786 __ sthbrx($src$$Register, $mem$$Register);
12787 %}
12788 ins_pipe(pipe_class_default);
12789 %}
12790
12791 // Store short reversed byte order
12792 instruct storeS_reversed(iRegIsrc src, indirect mem) %{
12793 match(Set mem (StoreC mem (ReverseBytesS src)));
12794 ins_cost(MEMORY_REF_COST);
12795
12796 size(4);
12797 ins_encode %{
12798 __ sthbrx($src$$Register, $mem$$Register);
12799 %}
12800 ins_pipe(pipe_class_default);
12801 %}
12802
12803 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
12804 effect(DEF temp1, USE src);
12805
12806 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %}
12807 size(4);
12808 ins_encode %{
12809 __ mtvsrwz($temp1$$VectorRegister->to_vsr(), $src$$Register);
12810 %}
12811 ins_pipe(pipe_class_default);
12812 %}
12813
12814 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{
12815 effect(DEF dst, USE src, USE imm1);
12816
12817 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %}
12818 size(4);
12819 ins_encode %{
12820 __ xxspltw($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $imm1$$constant);
12821 %}
12822 ins_pipe(pipe_class_default);
12823 %}
12824
12825 instruct xscvdpspn_regF(vecX dst, regF src) %{
12826 effect(DEF dst, USE src);
12827
12828 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %}
12829 size(4);
12830 ins_encode %{
12831 __ xscvdpspn($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr());
12832 %}
12833 ins_pipe(pipe_class_default);
12834 %}
12835
12836 //---------- Replicate Vector Instructions ------------------------------------
12837
12838 // Insrdi does replicate if src == dst.
12839 instruct repl32(iRegLdst dst) %{
12840 predicate(false);
12841 effect(USE_DEF dst);
12842
12843 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %}
12844 size(4);
12845 ins_encode %{
12846 __ insrdi($dst$$Register, $dst$$Register, 32, 0);
12847 %}
12848 ins_pipe(pipe_class_default);
12849 %}
12850
12851 // Insrdi does replicate if src == dst.
12852 instruct repl48(iRegLdst dst) %{
12853 predicate(false);
12854 effect(USE_DEF dst);
12855
12856 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %}
12857 size(4);
12858 ins_encode %{
12859 __ insrdi($dst$$Register, $dst$$Register, 48, 0);
12860 %}
12861 ins_pipe(pipe_class_default);
12862 %}
12863
12864 // Insrdi does replicate if src == dst.
12865 instruct repl56(iRegLdst dst) %{
12866 predicate(false);
12867 effect(USE_DEF dst);
12868
12869 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %}
12870 size(4);
12871 ins_encode %{
12872 __ insrdi($dst$$Register, $dst$$Register, 56, 0);
12873 %}
12874 ins_pipe(pipe_class_default);
12875 %}
12876
12877 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12878 match(Set dst (Replicate src));
12879 predicate(n->as_Vector()->length() == 8 &&
12880 Matcher::vector_element_basic_type(n) == T_BYTE);
12881 expand %{
12882 moveReg(dst, src);
12883 repl56(dst);
12884 repl48(dst);
12885 repl32(dst);
12886 %}
12887 %}
12888
12889 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
12890 match(Set dst (Replicate zero));
12891 predicate(n->as_Vector()->length() == 8 &&
12892 Matcher::vector_element_basic_type(n) == T_BYTE);
12893 format %{ "LI $dst, #0 \t// replicate8B" %}
12894 size(4);
12895 ins_encode %{
12896 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12897 %}
12898 ins_pipe(pipe_class_default);
12899 %}
12900
12901 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
12902 match(Set dst (Replicate src));
12903 predicate(n->as_Vector()->length() == 8 &&
12904 Matcher::vector_element_basic_type(n) == T_BYTE);
12905 format %{ "LI $dst, #-1 \t// replicate8B" %}
12906 size(4);
12907 ins_encode %{
12908 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12909 %}
12910 ins_pipe(pipe_class_default);
12911 %}
12912
12913 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{
12914 match(Set dst (Replicate src));
12915 predicate(n->as_Vector()->length() == 16 &&
12916 Matcher::vector_element_basic_type(n) == T_BYTE);
12917
12918 expand %{
12919 iRegLdst tmpL;
12920 vecX tmpV;
12921 immI8 imm1 %{ (int) 1 %}
12922 moveReg(tmpL, src);
12923 repl56(tmpL);
12924 repl48(tmpL);
12925 mtvsrwz(tmpV, tmpL);
12926 xxspltw(dst, tmpV, imm1);
12927 %}
12928 %}
12929
12930 instruct repl16B_immI0(vecX dst, immI_0 zero) %{
12931 match(Set dst (Replicate zero));
12932 predicate(n->as_Vector()->length() == 16 &&
12933 Matcher::vector_element_basic_type(n) == T_BYTE);
12934
12935 format %{ "XXLXOR $dst, $zero \t// replicate16B" %}
12936 size(4);
12937 ins_encode %{
12938 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12939 %}
12940 ins_pipe(pipe_class_default);
12941 %}
12942
12943 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{
12944 match(Set dst (Replicate src));
12945 predicate(n->as_Vector()->length() == 16 &&
12946 Matcher::vector_element_basic_type(n) == T_BYTE);
12947
12948 format %{ "XXLEQV $dst, $src \t// replicate16B" %}
12949 size(4);
12950 ins_encode %{
12951 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12952 %}
12953 ins_pipe(pipe_class_default);
12954 %}
12955
12956 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12957 match(Set dst (Replicate src));
12958 predicate(n->as_Vector()->length() == 4 &&
12959 Matcher::vector_element_basic_type(n) == T_SHORT);
12960 expand %{
12961 moveReg(dst, src);
12962 repl48(dst);
12963 repl32(dst);
12964 %}
12965 %}
12966
12967 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
12968 match(Set dst (Replicate zero));
12969 predicate(n->as_Vector()->length() == 4 &&
12970 Matcher::vector_element_basic_type(n) == T_SHORT);
12971 format %{ "LI $dst, #0 \t// replicate4S" %}
12972 size(4);
12973 ins_encode %{
12974 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12975 %}
12976 ins_pipe(pipe_class_default);
12977 %}
12978
12979 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
12980 match(Set dst (Replicate src));
12981 predicate(n->as_Vector()->length() == 4 &&
12982 Matcher::vector_element_basic_type(n) == T_SHORT);
12983 format %{ "LI $dst, -1 \t// replicate4S" %}
12984 size(4);
12985 ins_encode %{
12986 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12987 %}
12988 ins_pipe(pipe_class_default);
12989 %}
12990
12991 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{
12992 match(Set dst (Replicate src));
12993 predicate(n->as_Vector()->length() == 8 &&
12994 Matcher::vector_element_basic_type(n) == T_SHORT);
12995
12996 expand %{
12997 iRegLdst tmpL;
12998 vecX tmpV;
12999 immI8 zero %{ (int) 0 %}
13000 moveReg(tmpL, src);
13001 repl48(tmpL);
13002 repl32(tmpL);
13003 mtvsrd(tmpV, tmpL);
13004 xxpermdi(dst, tmpV, tmpV, zero);
13005 %}
13006 %}
13007
13008 instruct repl8S_immI0(vecX dst, immI_0 zero) %{
13009 match(Set dst (Replicate zero));
13010 predicate(n->as_Vector()->length() == 8 &&
13011 Matcher::vector_element_basic_type(n) == T_SHORT);
13012
13013 format %{ "XXLXOR $dst, $zero \t// replicate8S" %}
13014 size(4);
13015 ins_encode %{
13016 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13017 %}
13018 ins_pipe(pipe_class_default);
13019 %}
13020
13021 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{
13022 match(Set dst (Replicate src));
13023 predicate(n->as_Vector()->length() == 8 &&
13024 Matcher::vector_element_basic_type(n) == T_SHORT);
13025
13026 format %{ "XXLEQV $dst, $src \t// replicate8S" %}
13027 size(4);
13028 ins_encode %{
13029 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13030 %}
13031 ins_pipe(pipe_class_default);
13032 %}
13033
13034 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
13035 match(Set dst (Replicate src));
13036 predicate(n->as_Vector()->length() == 2 &&
13037 Matcher::vector_element_basic_type(n) == T_INT);
13038 ins_cost(2 * DEFAULT_COST);
13039 expand %{
13040 moveReg(dst, src);
13041 repl32(dst);
13042 %}
13043 %}
13044
13045 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
13046 match(Set dst (Replicate zero));
13047 predicate(n->as_Vector()->length() == 2 &&
13048 Matcher::vector_element_basic_type(n) == T_INT);
13049 format %{ "LI $dst, #0 \t// replicate2I" %}
13050 size(4);
13051 ins_encode %{
13052 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
13053 %}
13054 ins_pipe(pipe_class_default);
13055 %}
13056
13057 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
13058 match(Set dst (Replicate src));
13059 predicate(n->as_Vector()->length() == 2 &&
13060 Matcher::vector_element_basic_type(n) == T_INT);
13061 format %{ "LI $dst, -1 \t// replicate2I" %}
13062 size(4);
13063 ins_encode %{
13064 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
13065 %}
13066 ins_pipe(pipe_class_default);
13067 %}
13068
13069 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{
13070 match(Set dst (Replicate src));
13071 predicate(n->as_Vector()->length() == 4 &&
13072 Matcher::vector_element_basic_type(n) == T_INT);
13073 ins_cost(2 * DEFAULT_COST);
13074
13075 expand %{
13076 iRegLdst tmpL;
13077 vecX tmpV;
13078 immI8 zero %{ (int) 0 %}
13079 moveReg(tmpL, src);
13080 repl32(tmpL);
13081 mtvsrd(tmpV, tmpL);
13082 xxpermdi(dst, tmpV, tmpV, zero);
13083 %}
13084 %}
13085
13086 instruct repl4I_immI0(vecX dst, immI_0 zero) %{
13087 match(Set dst (Replicate zero));
13088 predicate(n->as_Vector()->length() == 4 &&
13089 Matcher::vector_element_basic_type(n) == T_INT);
13090
13091 format %{ "XXLXOR $dst, $zero \t// replicate4I" %}
13092 size(4);
13093 ins_encode %{
13094 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13095 %}
13096 ins_pipe(pipe_class_default);
13097 %}
13098
13099 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{
13100 match(Set dst (Replicate src));
13101 predicate(n->as_Vector()->length() == 4 &&
13102 Matcher::vector_element_basic_type(n) == T_INT);
13103
13104 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %}
13105 size(4);
13106 ins_encode %{
13107 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13108 %}
13109 ins_pipe(pipe_class_default);
13110 %}
13111
13112 // Move float to int register via stack, replicate.
13113 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
13114 match(Set dst (Replicate src));
13115 predicate(n->as_Vector()->length() == 2 &&
13116 Matcher::vector_element_basic_type(n) == T_FLOAT);
13117 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
13118 expand %{
13119 stackSlotL tmpS;
13120 iRegIdst tmpI;
13121 moveF2I_reg_stack(tmpS, src); // Move float to stack.
13122 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
13123 moveReg(dst, tmpI); // Move int to long reg.
13124 repl32(dst); // Replicate bitpattern.
13125 %}
13126 %}
13127
13128 // Replicate scalar constant to packed float values in Double register
13129 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
13130 match(Set dst (Replicate src));
13131 predicate(n->as_Vector()->length() == 2 &&
13132 Matcher::vector_element_basic_type(n) == T_FLOAT);
13133 ins_cost(5 * DEFAULT_COST);
13134
13135 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
13136 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
13137 %}
13138
13139 // Replicate scalar zero constant to packed float values in Double register
13140 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
13141 match(Set dst (Replicate zero));
13142 predicate(n->as_Vector()->length() == 2 &&
13143 Matcher::vector_element_basic_type(n) == T_FLOAT);
13144
13145 format %{ "LI $dst, #0 \t// replicate2F" %}
13146 size(4);
13147 ins_encode %{
13148 __ li($dst$$Register, 0x0);
13149 %}
13150 ins_pipe(pipe_class_default);
13151 %}
13152
13153
13154 //----------Vector Arithmetic Instructions--------------------------------------
13155
13156 // Vector Addition Instructions
13157
13158 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
13159 match(Set dst (AddVB src1 src2));
13160 predicate(n->as_Vector()->length() == 16);
13161 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %}
13162 size(4);
13163 ins_encode %{
13164 __ vaddubm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13165 %}
13166 ins_pipe(pipe_class_default);
13167 %}
13168
13169 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
13170 match(Set dst (AddVS src1 src2));
13171 predicate(n->as_Vector()->length() == 8);
13172 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %}
13173 size(4);
13174 ins_encode %{
13175 __ vadduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13176 %}
13177 ins_pipe(pipe_class_default);
13178 %}
13179
13180 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
13181 match(Set dst (AddVI src1 src2));
13182 predicate(n->as_Vector()->length() == 4);
13183 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %}
13184 size(4);
13185 ins_encode %{
13186 __ vadduwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13187 %}
13188 ins_pipe(pipe_class_default);
13189 %}
13190
13191 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
13192 match(Set dst (AddVF src1 src2));
13193 predicate(n->as_Vector()->length() == 4);
13194 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %}
13195 size(4);
13196 ins_encode %{
13197 __ vaddfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13198 %}
13199 ins_pipe(pipe_class_default);
13200 %}
13201
13202 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
13203 match(Set dst (AddVL src1 src2));
13204 predicate(n->as_Vector()->length() == 2);
13205 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %}
13206 size(4);
13207 ins_encode %{
13208 __ vaddudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13209 %}
13210 ins_pipe(pipe_class_default);
13211 %}
13212
13213 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
13214 match(Set dst (AddVD src1 src2));
13215 predicate(n->as_Vector()->length() == 2);
13216 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %}
13217 size(4);
13218 ins_encode %{
13219 __ xvadddp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13220 %}
13221 ins_pipe(pipe_class_default);
13222 %}
13223
13224 // Vector Subtraction Instructions
13225
13226 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
13227 match(Set dst (SubVB src1 src2));
13228 predicate(n->as_Vector()->length() == 16);
13229 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %}
13230 size(4);
13231 ins_encode %{
13232 __ vsububm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13233 %}
13234 ins_pipe(pipe_class_default);
13235 %}
13236
13237 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
13238 match(Set dst (SubVS src1 src2));
13239 predicate(n->as_Vector()->length() == 8);
13240 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %}
13241 size(4);
13242 ins_encode %{
13243 __ vsubuhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13244 %}
13245 ins_pipe(pipe_class_default);
13246 %}
13247
13248 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
13249 match(Set dst (SubVI src1 src2));
13250 predicate(n->as_Vector()->length() == 4);
13251 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %}
13252 size(4);
13253 ins_encode %{
13254 __ vsubuwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13255 %}
13256 ins_pipe(pipe_class_default);
13257 %}
13258
13259 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
13260 match(Set dst (SubVF src1 src2));
13261 predicate(n->as_Vector()->length() == 4);
13262 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %}
13263 size(4);
13264 ins_encode %{
13265 __ vsubfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13266 %}
13267 ins_pipe(pipe_class_default);
13268 %}
13269
13270 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
13271 match(Set dst (SubVL src1 src2));
13272 predicate(n->as_Vector()->length() == 2);
13273 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %}
13274 size(4);
13275 ins_encode %{
13276 __ vsubudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13277 %}
13278 ins_pipe(pipe_class_default);
13279 %}
13280
13281 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
13282 match(Set dst (SubVD src1 src2));
13283 predicate(n->as_Vector()->length() == 2);
13284 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %}
13285 size(4);
13286 ins_encode %{
13287 __ xvsubdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13288 %}
13289 ins_pipe(pipe_class_default);
13290 %}
13291
13292 // Vector Multiplication Instructions
13293
13294 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
13295 match(Set dst (MulVS src1 src2));
13296 predicate(n->as_Vector()->length() == 8);
13297 effect(TEMP tmp);
13298 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %}
13299 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %}
13300 size(8);
13301 ins_encode %{
13302 __ vspltish($tmp$$VectorRegister, 0);
13303 __ vmladduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister, $tmp$$VectorRegister);
13304 %}
13305 ins_pipe(pipe_class_default);
13306 %}
13307
13308 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
13309 match(Set dst (MulVI src1 src2));
13310 predicate(n->as_Vector()->length() == 4);
13311 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %}
13312 size(4);
13313 ins_encode %{
13314 __ vmuluwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13315 %}
13316 ins_pipe(pipe_class_default);
13317 %}
13318
13319 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
13320 match(Set dst (MulVF src1 src2));
13321 predicate(n->as_Vector()->length() == 4);
13322 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %}
13323 size(4);
13324 ins_encode %{
13325 __ xvmulsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13326 %}
13327 ins_pipe(pipe_class_default);
13328 %}
13329
13330 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
13331 match(Set dst (MulVD src1 src2));
13332 predicate(n->as_Vector()->length() == 2);
13333 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %}
13334 size(4);
13335 ins_encode %{
13336 __ xvmuldp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13337 %}
13338 ins_pipe(pipe_class_default);
13339 %}
13340
13341 // Vector Division Instructions
13342
13343 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
13344 match(Set dst (DivVF src1 src2));
13345 predicate(n->as_Vector()->length() == 4);
13346 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %}
13347 size(4);
13348 ins_encode %{
13349 __ xvdivsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13350 %}
13351 ins_pipe(pipe_class_default);
13352 %}
13353
13354 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
13355 match(Set dst (DivVD src1 src2));
13356 predicate(n->as_Vector()->length() == 2);
13357 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %}
13358 size(4);
13359 ins_encode %{
13360 __ xvdivdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13361 %}
13362 ins_pipe(pipe_class_default);
13363 %}
13364
13365 // Vector Min / Max Instructions
13366
13367 instruct vmin_reg(vecX dst, vecX src1, vecX src2) %{
13368 match(Set dst (MinV src1 src2));
13369 format %{ "VMIN $dst,$src1,$src2\t// vector min" %}
13370 size(4);
13371 ins_encode %{
13372 BasicType bt = Matcher::vector_element_basic_type(this);
13373 switch (bt) {
13374 case T_INT:
13375 __ vminsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13376 break;
13377 case T_LONG:
13378 __ vminsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13379 break;
13380 default:
13381 ShouldNotReachHere();
13382 }
13383 %}
13384 ins_pipe(pipe_class_default);
13385 %}
13386
13387 instruct vmax_reg(vecX dst, vecX src1, vecX src2) %{
13388 match(Set dst (MaxV src1 src2));
13389 format %{ "VMAX $dst,$src1,$src2\t// vector max" %}
13390 size(4);
13391 ins_encode %{
13392 BasicType bt = Matcher::vector_element_basic_type(this);
13393 switch (bt) {
13394 case T_INT:
13395 __ vmaxsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13396 break;
13397 case T_LONG:
13398 __ vmaxsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13399 break;
13400 default:
13401 ShouldNotReachHere();
13402 }
13403 %}
13404 ins_pipe(pipe_class_default);
13405 %}
13406
13407 instruct vminu_reg(vecX dst, vecX src1, vecX src2) %{
13408 match(Set dst (UMinV src1 src2));
13409 format %{ "VMINU $dst,$src1,$src2\t// vector unsigned min" %}
13410 size(4);
13411 ins_encode %{
13412 BasicType bt = Matcher::vector_element_basic_type(this);
13413 switch (bt) {
13414 case T_INT:
13415 __ vminuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13416 break;
13417 case T_LONG:
13418 __ vminud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13419 break;
13420 default:
13421 ShouldNotReachHere();
13422 }
13423 %}
13424 ins_pipe(pipe_class_default);
13425 %}
13426
13427 instruct vmaxu_reg(vecX dst, vecX src1, vecX src2) %{
13428 match(Set dst (UMaxV src1 src2));
13429 format %{ "VMAXU $dst,$src1,$src2\t// vector unsigned max" %}
13430 size(4);
13431 ins_encode %{
13432 BasicType bt = Matcher::vector_element_basic_type(this);
13433 switch (bt) {
13434 case T_INT:
13435 __ vmaxuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13436 break;
13437 case T_LONG:
13438 __ vmaxud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13439 break;
13440 default:
13441 ShouldNotReachHere();
13442 }
13443 %}
13444 ins_pipe(pipe_class_default);
13445 %}
13446
13447 instruct vand(vecX dst, vecX src1, vecX src2) %{
13448 match(Set dst (AndV src1 src2));
13449 size(4);
13450 format %{ "VAND $dst,$src1,$src2\t// and vectors" %}
13451 ins_encode %{
13452 __ vand($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13453 %}
13454 ins_pipe(pipe_class_default);
13455 %}
13456
13457 instruct vor(vecX dst, vecX src1, vecX src2) %{
13458 match(Set dst (OrV src1 src2));
13459 size(4);
13460 format %{ "VOR $dst,$src1,$src2\t// or vectors" %}
13461 ins_encode %{
13462 __ vor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13463 %}
13464 ins_pipe(pipe_class_default);
13465 %}
13466
13467 instruct vxor(vecX dst, vecX src1, vecX src2) %{
13468 match(Set dst (XorV src1 src2));
13469 size(4);
13470 format %{ "VXOR $dst,$src1,$src2\t// xor vectors" %}
13471 ins_encode %{
13472 __ vxor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13473 %}
13474 ins_pipe(pipe_class_default);
13475 %}
13476
13477 instruct reductionI_arith_logic(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2) %{
13478 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13479 match(Set dst (AddReductionVI srcInt srcVec));
13480 match(Set dst (MulReductionVI srcInt srcVec));
13481 match(Set dst (AndReductionV srcInt srcVec));
13482 match(Set dst ( OrReductionV srcInt srcVec));
13483 match(Set dst (XorReductionV srcInt srcVec));
13484 effect(TEMP tmp1, TEMP tmp2);
13485 ins_cost(DEFAULT_COST * 6);
13486 format %{ "REDUCEI_ARITH_LOGIC // $dst,$srcInt,$srcVec,$tmp1,$tmp2\t// reduce vector int add/mul/and/or/xor" %}
13487 size(24);
13488 ins_encode %{
13489 int opcode = this->ideal_Opcode();
13490 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13491 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13492 %}
13493 ins_pipe(pipe_class_default);
13494 %}
13495
13496 instruct reductionI_min_max(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2, flagsRegCR0 cr0) %{
13497 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13498 match(Set dst (MinReductionV srcInt srcVec));
13499 match(Set dst (MaxReductionV srcInt srcVec));
13500 effect(TEMP tmp1, TEMP tmp2, KILL cr0);
13501 ins_cost(DEFAULT_COST * 7);
13502 format %{ "REDUCEI_MINMAX // $dst,$srcInt,$srcVec,$tmp1,$tmp2,cr0\t// reduce vector int min/max" %}
13503 size(28);
13504 ins_encode %{
13505 int opcode = this->ideal_Opcode();
13506 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13507 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13508 %}
13509 ins_pipe(pipe_class_default);
13510 %}
13511
13512 // Vector Absolute Instructions
13513
13514 instruct vabs4F_reg(vecX dst, vecX src) %{
13515 match(Set dst (AbsVF src));
13516 predicate(n->as_Vector()->length() == 4);
13517 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
13518 size(4);
13519 ins_encode %{
13520 __ xvabssp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13521 %}
13522 ins_pipe(pipe_class_default);
13523 %}
13524
13525 instruct vabs2D_reg(vecX dst, vecX src) %{
13526 match(Set dst (AbsVD src));
13527 predicate(n->as_Vector()->length() == 2);
13528 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
13529 size(4);
13530 ins_encode %{
13531 __ xvabsdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13532 %}
13533 ins_pipe(pipe_class_default);
13534 %}
13535
13536 // Round Instructions
13537 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{
13538 match(Set dst (RoundDoubleMode src rmode));
13539 format %{ "RoundDoubleMode $src,$rmode" %}
13540 size(4);
13541 ins_encode %{
13542 switch ($rmode$$constant) {
13543 case RoundDoubleModeNode::rmode_rint:
13544 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr());
13545 break;
13546 case RoundDoubleModeNode::rmode_floor:
13547 __ frim($dst$$FloatRegister, $src$$FloatRegister);
13548 break;
13549 case RoundDoubleModeNode::rmode_ceil:
13550 __ frip($dst$$FloatRegister, $src$$FloatRegister);
13551 break;
13552 default:
13553 ShouldNotReachHere();
13554 }
13555 %}
13556 ins_pipe(pipe_class_default);
13557 %}
13558
13559 // Vector Round Instructions
13560 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
13561 match(Set dst (RoundDoubleModeV src rmode));
13562 predicate(n->as_Vector()->length() == 2);
13563 format %{ "RoundDoubleModeV $src,$rmode" %}
13564 size(4);
13565 ins_encode %{
13566 switch ($rmode$$constant) {
13567 case RoundDoubleModeNode::rmode_rint:
13568 __ xvrdpic($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13569 break;
13570 case RoundDoubleModeNode::rmode_floor:
13571 __ xvrdpim($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13572 break;
13573 case RoundDoubleModeNode::rmode_ceil:
13574 __ xvrdpip($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13575 break;
13576 default:
13577 ShouldNotReachHere();
13578 }
13579 %}
13580 ins_pipe(pipe_class_default);
13581 %}
13582
13583 // Vector Negate Instructions
13584
13585 instruct vneg4F_reg(vecX dst, vecX src) %{
13586 match(Set dst (NegVF src));
13587 predicate(n->as_Vector()->length() == 4);
13588 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
13589 size(4);
13590 ins_encode %{
13591 __ xvnegsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13592 %}
13593 ins_pipe(pipe_class_default);
13594 %}
13595
13596 instruct vneg2D_reg(vecX dst, vecX src) %{
13597 match(Set dst (NegVD src));
13598 predicate(n->as_Vector()->length() == 2);
13599 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
13600 size(4);
13601 ins_encode %{
13602 __ xvnegdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13603 %}
13604 ins_pipe(pipe_class_default);
13605 %}
13606
13607 instruct vneg4I_reg(vecX dst, vecX src) %{
13608 match(Set dst (NegVI src));
13609 predicate(Matcher::vector_element_basic_type(n) == T_INT);
13610 format %{ "VNEGW $dst,$src\t// negate int vector" %}
13611 size(4);
13612 ins_encode %{
13613 __ vnegw($dst$$VectorRegister, $src$$VectorRegister);
13614 %}
13615 ins_pipe(pipe_class_default);
13616 %}
13617
13618 // Vector Square Root Instructions
13619
13620 instruct vsqrt4F_reg(vecX dst, vecX src) %{
13621 match(Set dst (SqrtVF src));
13622 predicate(n->as_Vector()->length() == 4);
13623 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
13624 size(4);
13625 ins_encode %{
13626 __ xvsqrtsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13627 %}
13628 ins_pipe(pipe_class_default);
13629 %}
13630
13631 instruct vsqrt2D_reg(vecX dst, vecX src) %{
13632 match(Set dst (SqrtVD src));
13633 predicate(n->as_Vector()->length() == 2);
13634 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %}
13635 size(4);
13636 ins_encode %{
13637 __ xvsqrtdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13638 %}
13639 ins_pipe(pipe_class_default);
13640 %}
13641
13642 // Vector Population Count and Zeros Count Instructions
13643
13644 instruct vpopcnt_reg(vecX dst, vecX src) %{
13645 match(Set dst (PopCountVI src));
13646 match(Set dst (PopCountVL src));
13647 format %{ "VPOPCNT $dst,$src\t// pop count packed" %}
13648 size(4);
13649 ins_encode %{
13650 BasicType bt = Matcher::vector_element_basic_type(this);
13651 switch (bt) {
13652 case T_BYTE:
13653 __ vpopcntb($dst$$VectorRegister, $src$$VectorRegister);
13654 break;
13655 case T_SHORT:
13656 __ vpopcnth($dst$$VectorRegister, $src$$VectorRegister);
13657 break;
13658 case T_INT:
13659 __ vpopcntw($dst$$VectorRegister, $src$$VectorRegister);
13660 break;
13661 case T_LONG:
13662 __ vpopcntd($dst$$VectorRegister, $src$$VectorRegister);
13663 break;
13664 default:
13665 ShouldNotReachHere();
13666 }
13667 %}
13668 ins_pipe(pipe_class_default);
13669 %}
13670
13671 instruct vcount_leading_zeros_reg(vecX dst, vecX src) %{
13672 match(Set dst (CountLeadingZerosV src));
13673 format %{ "VCLZ $dst,$src\t// leading zeros count packed" %}
13674 size(4);
13675 ins_encode %{
13676 BasicType bt = Matcher::vector_element_basic_type(this);
13677 switch (bt) {
13678 case T_BYTE:
13679 __ vclzb($dst$$VectorRegister, $src$$VectorRegister);
13680 break;
13681 case T_SHORT:
13682 __ vclzh($dst$$VectorRegister, $src$$VectorRegister);
13683 break;
13684 case T_INT:
13685 __ vclzw($dst$$VectorRegister, $src$$VectorRegister);
13686 break;
13687 case T_LONG:
13688 __ vclzd($dst$$VectorRegister, $src$$VectorRegister);
13689 break;
13690 default:
13691 ShouldNotReachHere();
13692 }
13693 %}
13694 ins_pipe(pipe_class_default);
13695 %}
13696
13697 instruct vcount_trailing_zeros_reg(vecX dst, vecX src) %{
13698 match(Set dst (CountTrailingZerosV src));
13699 format %{ "VCTZ $dst,$src\t// trailing zeros count packed" %}
13700 size(4);
13701 ins_encode %{
13702 BasicType bt = Matcher::vector_element_basic_type(this);
13703 switch (bt) {
13704 case T_BYTE:
13705 __ vctzb($dst$$VectorRegister, $src$$VectorRegister);
13706 break;
13707 case T_SHORT:
13708 __ vctzh($dst$$VectorRegister, $src$$VectorRegister);
13709 break;
13710 case T_INT:
13711 __ vctzw($dst$$VectorRegister, $src$$VectorRegister);
13712 break;
13713 case T_LONG:
13714 __ vctzd($dst$$VectorRegister, $src$$VectorRegister);
13715 break;
13716 default:
13717 ShouldNotReachHere();
13718 }
13719 %}
13720 ins_pipe(pipe_class_default);
13721 %}
13722
13723 // --------------------------------- FMA --------------------------------------
13724 // src1 * src2 + dst
13725 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{
13726 match(Set dst (FmaVF dst (Binary src1 src2)));
13727 predicate(n->as_Vector()->length() == 4);
13728
13729 format %{ "XVMADDASP $dst, $src1, $src2" %}
13730
13731 size(4);
13732 ins_encode %{
13733 assert(UseFMA, "Needs FMA instructions support.");
13734 __ xvmaddasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13735 %}
13736 ins_pipe(pipe_class_default);
13737 %}
13738
13739 // src1 * (-src2) + dst
13740 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13741 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{
13742 match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
13743 predicate(n->as_Vector()->length() == 4);
13744
13745 format %{ "XVNMSUBASP $dst, $src1, $src2" %}
13746
13747 size(4);
13748 ins_encode %{
13749 assert(UseFMA, "Needs FMA instructions support.");
13750 __ xvnmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13751 %}
13752 ins_pipe(pipe_class_default);
13753 %}
13754
13755 // src1 * src2 - dst
13756 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{
13757 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2)));
13758 predicate(n->as_Vector()->length() == 4);
13759
13760 format %{ "XVMSUBASP $dst, $src1, $src2" %}
13761
13762 size(4);
13763 ins_encode %{
13764 assert(UseFMA, "Needs FMA instructions support.");
13765 __ xvmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13766 %}
13767 ins_pipe(pipe_class_default);
13768 %}
13769
13770 // src1 * src2 + dst
13771 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{
13772 match(Set dst (FmaVD dst (Binary src1 src2)));
13773 predicate(n->as_Vector()->length() == 2);
13774
13775 format %{ "XVMADDADP $dst, $src1, $src2" %}
13776
13777 size(4);
13778 ins_encode %{
13779 assert(UseFMA, "Needs FMA instructions support.");
13780 __ xvmaddadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13781 %}
13782 ins_pipe(pipe_class_default);
13783 %}
13784
13785 // src1 * (-src2) + dst
13786 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13787 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{
13788 match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
13789 predicate(n->as_Vector()->length() == 2);
13790
13791 format %{ "XVNMSUBADP $dst, $src1, $src2" %}
13792
13793 size(4);
13794 ins_encode %{
13795 assert(UseFMA, "Needs FMA instructions support.");
13796 __ xvnmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13797 %}
13798 ins_pipe(pipe_class_default);
13799 %}
13800
13801 // src1 * src2 - dst
13802 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
13803 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2)));
13804 predicate(n->as_Vector()->length() == 2);
13805
13806 format %{ "XVMSUBADP $dst, $src1, $src2" %}
13807
13808 size(4);
13809 ins_encode %{
13810 assert(UseFMA, "Needs FMA instructions support.");
13811 __ xvmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13812 %}
13813 ins_pipe(pipe_class_default);
13814 %}
13815
13816 //----------Overflow Math Instructions-----------------------------------------
13817
13818 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
13819 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
13820 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
13821
13822 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13823 match(Set cr0 (OverflowAddL op1 op2));
13824
13825 format %{ "ADD_ $op1, $op2\t# overflow check long" %}
13826 size(12);
13827 ins_encode %{
13828 __ li(R0, 0);
13829 __ mtxer(R0); // clear XER.SO
13830 __ addo_(R0, $op1$$Register, $op2$$Register);
13831 %}
13832 ins_pipe(pipe_class_default);
13833 %}
13834
13835 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13836 match(Set cr0 (OverflowSubL op1 op2));
13837
13838 format %{ "SUBFO_ R0, $op2, $op1\t# overflow check long" %}
13839 size(12);
13840 ins_encode %{
13841 __ li(R0, 0);
13842 __ mtxer(R0); // clear XER.SO
13843 __ subfo_(R0, $op2$$Register, $op1$$Register);
13844 %}
13845 ins_pipe(pipe_class_default);
13846 %}
13847
13848 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
13849 match(Set cr0 (OverflowSubL zero op2));
13850
13851 format %{ "NEGO_ R0, $op2\t# overflow check long" %}
13852 size(12);
13853 ins_encode %{
13854 __ li(R0, 0);
13855 __ mtxer(R0); // clear XER.SO
13856 __ nego_(R0, $op2$$Register);
13857 %}
13858 ins_pipe(pipe_class_default);
13859 %}
13860
13861 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13862 match(Set cr0 (OverflowMulL op1 op2));
13863
13864 format %{ "MULLDO_ R0, $op1, $op2\t# overflow check long" %}
13865 size(12);
13866 ins_encode %{
13867 __ li(R0, 0);
13868 __ mtxer(R0); // clear XER.SO
13869 __ mulldo_(R0, $op1$$Register, $op2$$Register);
13870 %}
13871 ins_pipe(pipe_class_default);
13872 %}
13873
13874 instruct repl4F_reg_Ex(vecX dst, regF src) %{
13875 match(Set dst (Replicate src));
13876 predicate(n->as_Vector()->length() == 4 &&
13877 Matcher::vector_element_basic_type(n) == T_FLOAT);
13878 ins_cost(DEFAULT_COST);
13879 expand %{
13880 vecX tmpV;
13881 immI8 zero %{ (int) 0 %}
13882
13883 xscvdpspn_regF(tmpV, src);
13884 xxspltw(dst, tmpV, zero);
13885 %}
13886 %}
13887
13888 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{
13889 match(Set dst (Replicate src));
13890 predicate(n->as_Vector()->length() == 4 &&
13891 Matcher::vector_element_basic_type(n) == T_FLOAT);
13892 effect(TEMP tmp);
13893 ins_cost(10 * DEFAULT_COST);
13894
13895 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) );
13896 %}
13897
13898 instruct repl4F_immF0(vecX dst, immF_0 zero) %{
13899 match(Set dst (Replicate zero));
13900 predicate(n->as_Vector()->length() == 4 &&
13901 Matcher::vector_element_basic_type(n) == T_FLOAT);
13902
13903 format %{ "XXLXOR $dst, $zero \t// replicate4F" %}
13904 size(4);
13905 ins_encode %{
13906 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13907 %}
13908 ins_pipe(pipe_class_default);
13909 %}
13910
13911 instruct repl2D_reg_Ex(vecX dst, regD src) %{
13912 match(Set dst (Replicate src));
13913 predicate(n->as_Vector()->length() == 2 &&
13914 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13915
13916 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %}
13917 size(4);
13918 ins_encode %{
13919 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0);
13920 %}
13921 ins_pipe(pipe_class_default);
13922 %}
13923
13924 instruct repl2D_immD0(vecX dst, immD_0 zero) %{
13925 match(Set dst (Replicate zero));
13926 predicate(n->as_Vector()->length() == 2 &&
13927 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13928
13929 format %{ "XXLXOR $dst, $zero \t// replicate2D" %}
13930 size(4);
13931 ins_encode %{
13932 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13933 %}
13934 ins_pipe(pipe_class_default);
13935 %}
13936
13937 instruct mtvsrd(vecX dst, iRegLsrc src) %{
13938 predicate(false);
13939 effect(DEF dst, USE src);
13940
13941 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %}
13942 size(4);
13943 ins_encode %{
13944 __ mtvsrd($dst$$VectorRegister->to_vsr(), $src$$Register);
13945 %}
13946 ins_pipe(pipe_class_default);
13947 %}
13948
13949 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{
13950 effect(DEF dst, USE src, USE zero);
13951
13952 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %}
13953 size(4);
13954 ins_encode %{
13955 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $zero$$constant);
13956 %}
13957 ins_pipe(pipe_class_default);
13958 %}
13959
13960 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{
13961 effect(DEF dst, USE src1, USE src2, USE zero);
13962
13963 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %}
13964 size(4);
13965 ins_encode %{
13966 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr(), $zero$$constant);
13967 %}
13968 ins_pipe(pipe_class_default);
13969 %}
13970
13971 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{
13972 predicate(Matcher::vector_element_basic_type(n) == T_LONG);
13973 match(Set dst (Replicate src));
13974 predicate(n->as_Vector()->length() == 2);
13975 expand %{
13976 vecX tmpV;
13977 immI8 zero %{ (int) 0 %}
13978 mtvsrd(tmpV, src);
13979 xxpermdi(dst, tmpV, tmpV, zero);
13980 %}
13981 %}
13982
13983 instruct repl2L_immI0(vecX dst, immI_0 zero) %{
13984 match(Set dst (Replicate zero));
13985 predicate(n->as_Vector()->length() == 2 &&
13986 Matcher::vector_element_basic_type(n) == T_LONG);
13987
13988 format %{ "XXLXOR $dst, $zero \t// replicate2L" %}
13989 size(4);
13990 ins_encode %{
13991 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13992 %}
13993 ins_pipe(pipe_class_default);
13994 %}
13995
13996 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{
13997 match(Set dst (Replicate src));
13998 predicate(n->as_Vector()->length() == 2 &&
13999 Matcher::vector_element_basic_type(n) == T_LONG);
14000
14001 format %{ "XXLEQV $dst, $src \t// replicate2L" %}
14002 size(4);
14003 ins_encode %{
14004 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
14005 %}
14006 ins_pipe(pipe_class_default);
14007 %}
14008
14009 // ============================================================================
14010 // Safepoint Instruction
14011
14012 instruct safePoint_poll(iRegPdst poll) %{
14013 match(SafePoint poll);
14014
14015 // It caused problems to add the effect that r0 is killed, but this
14016 // effect no longer needs to be mentioned, since r0 is not contained
14017 // in a reg_class.
14018
14019 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
14020 size(4);
14021 ins_encode( enc_poll(0x0, poll) );
14022 ins_pipe(pipe_class_default);
14023 %}
14024
14025 // ============================================================================
14026 // Call Instructions
14027
14028 // Call Java Static Instruction
14029
14030 source %{
14031
14032 #include "runtime/continuation.hpp"
14033
14034 %}
14035
14036 // Schedulable version of call static node.
14037 instruct CallStaticJavaDirect(method meth) %{
14038 match(CallStaticJava);
14039 effect(USE meth);
14040 ins_cost(CALL_COST);
14041
14042 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
14043
14044 format %{ "CALL,static $meth \t// ==> " %}
14045 size((Continuations::enabled() ? 8 : 4));
14046 ins_encode( enc_java_static_call(meth) );
14047 ins_pipe(pipe_class_call);
14048 %}
14049
14050 // Call Java Dynamic Instruction
14051
14052 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call).
14053 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable
14054 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node.
14055 // The call destination must still be placed in the constant pool.
14056 instruct CallDynamicJavaDirectSched(method meth) %{
14057 match(CallDynamicJava); // To get all the data fields we need ...
14058 effect(USE meth);
14059 predicate(false); // ... but never match.
14060
14061 ins_field_load_ic_hi_node(loadConL_hiNode*);
14062 ins_field_load_ic_node(loadConLNode*);
14063 ins_num_consts(1 /* 1 patchable constant: call destination */);
14064
14065 format %{ "BL \t// dynamic $meth ==> " %}
14066 size((Continuations::enabled() ? 8 : 4));
14067 ins_encode( enc_java_dynamic_call_sched(meth) );
14068 ins_pipe(pipe_class_call);
14069 %}
14070
14071 // Schedulable (i.e. postalloc expanded) version of call dynamic java.
14072 // We use postalloc expanded calls if we use inline caches
14073 // and do not update method data.
14074 //
14075 // This instruction has two constants: inline cache (IC) and call destination.
14076 // Loading the inline cache will be postalloc expanded, thus leaving a call with
14077 // one constant.
14078 instruct CallDynamicJavaDirectSched_Ex(method meth) %{
14079 match(CallDynamicJava);
14080 effect(USE meth);
14081 predicate(UseInlineCaches);
14082 ins_cost(CALL_COST);
14083
14084 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */);
14085
14086 format %{ "CALL,dynamic $meth \t// postalloc expanded" %}
14087 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) );
14088 %}
14089
14090 // Compound version of call dynamic java
14091 // We use postalloc expanded calls if we use inline caches
14092 // and do not update method data.
14093 instruct CallDynamicJavaDirect(method meth) %{
14094 match(CallDynamicJava);
14095 effect(USE meth);
14096 predicate(!UseInlineCaches);
14097 ins_cost(CALL_COST);
14098
14099 // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
14100 ins_num_consts(4);
14101
14102 format %{ "CALL,dynamic $meth \t// ==> " %}
14103 ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
14104 ins_pipe(pipe_class_call);
14105 %}
14106
14107 // Call Runtime Instruction
14108
14109 instruct CallRuntimeDirect(method meth) %{
14110 match(CallRuntime);
14111 effect(USE meth);
14112 ins_cost(CALL_COST);
14113
14114 // Enc_java_to_runtime_call needs up to 3 constants: call target,
14115 // env for callee, C-toc.
14116 ins_num_consts(3);
14117
14118 format %{ "CALL,runtime" %}
14119 ins_encode( enc_java_to_runtime_call(meth) );
14120 ins_pipe(pipe_class_call);
14121 %}
14122
14123 // Call Leaf
14124
14125 // Used by postalloc expand of CallLeafDirect_Ex (mtctr).
14126 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
14127 effect(DEF dst, USE src);
14128
14129 ins_num_consts(1);
14130
14131 format %{ "MTCTR $src" %}
14132 size(4);
14133 ins_encode( enc_leaf_call_mtctr(src) );
14134 ins_pipe(pipe_class_default);
14135 %}
14136
14137 // Used by postalloc expand of CallLeafDirect_Ex (actual call).
14138 instruct CallLeafDirect(method meth) %{
14139 match(CallLeaf); // To get the data all the data fields we need ...
14140 effect(USE meth);
14141 predicate(false); // but never match.
14142
14143 format %{ "BCTRL \t// leaf call $meth ==> " %}
14144 size((Continuations::enabled() ? 8 : 4));
14145 ins_encode %{
14146 __ bctrl();
14147 __ post_call_nop();
14148 %}
14149 ins_pipe(pipe_class_call);
14150 %}
14151
14152 // postalloc expand of CallLeafDirect.
14153 // Load address to call from TOC, then bl to it.
14154 instruct CallLeafDirect_Ex(method meth) %{
14155 match(CallLeaf);
14156 effect(USE meth);
14157 ins_cost(CALL_COST);
14158
14159 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
14160 // env for callee, C-toc.
14161 ins_num_consts(3);
14162
14163 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
14164 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
14165 %}
14166
14167 // Call runtime without safepoint - same as CallLeaf.
14168 // postalloc expand of CallLeafNoFPDirect.
14169 // Load address to call from TOC, then bl to it.
14170 instruct CallLeafNoFPDirect_Ex(method meth) %{
14171 match(CallLeafNoFP);
14172 effect(USE meth);
14173 ins_cost(CALL_COST);
14174
14175 // Enc_java_to_runtime_call needs up to 3 constants: call target,
14176 // env for callee, C-toc.
14177 ins_num_consts(3);
14178
14179 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
14180 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
14181 %}
14182
14183 // Tail Call; Jump from runtime stub to Java code.
14184 // Also known as an 'interprocedural jump'.
14185 // Target of jump will eventually return to caller.
14186 // TailJump below removes the return address.
14187 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{
14188 match(TailCall jump_target method_ptr);
14189 ins_cost(CALL_COST);
14190
14191 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t"
14192 "BCTR \t// tail call" %}
14193 size(8);
14194 ins_encode %{
14195 __ mtctr($jump_target$$Register);
14196 __ bctr();
14197 %}
14198 ins_pipe(pipe_class_call);
14199 %}
14200
14201 // Return Instruction
14202 instruct Ret() %{
14203 match(Return);
14204 format %{ "BLR \t// branch to link register" %}
14205 size(4);
14206 ins_encode %{
14207 // LR is restored in MachEpilogNode. Just do the RET here.
14208 __ blr();
14209 %}
14210 ins_pipe(pipe_class_default);
14211 %}
14212
14213 // Tail Jump; remove the return address; jump to target.
14214 // TailCall above leaves the return address around.
14215 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
14216 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
14217 // "restore" before this instruction (in Epilogue), we need to materialize it
14218 // in %i0.
14219 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
14220 match(TailJump jump_target ex_oop);
14221 ins_cost(CALL_COST);
14222
14223 format %{ "LD R4_ARG2 = LR\n\t"
14224 "MTCTR $jump_target\n\t"
14225 "BCTR \t// TailJump, exception oop: $ex_oop" %}
14226 size(12);
14227 ins_encode %{
14228 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP);
14229 __ mtctr($jump_target$$Register);
14230 __ bctr();
14231 %}
14232 ins_pipe(pipe_class_call);
14233 %}
14234
14235 // Forward exception.
14236 instruct ForwardExceptionjmp()
14237 %{
14238 match(ForwardException);
14239 ins_cost(CALL_COST);
14240
14241 format %{ "JMP forward_exception_stub" %}
14242 ins_encode %{
14243 __ set_inst_mark();
14244 __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
14245 __ clear_inst_mark();
14246 %}
14247 ins_pipe(pipe_class_call);
14248 %}
14249
14250 // Create exception oop: created by stack-crawling runtime code.
14251 // Created exception is now available to this handler, and is setup
14252 // just prior to jumping to this handler. No code emitted.
14253 instruct CreateException(rarg1RegP ex_oop) %{
14254 match(Set ex_oop (CreateEx));
14255 ins_cost(0);
14256
14257 format %{ " -- \t// exception oop; no code emitted" %}
14258 size(0);
14259 ins_encode( /*empty*/ );
14260 ins_pipe(pipe_class_default);
14261 %}
14262
14263 // Rethrow exception: The exception oop will come in the first
14264 // argument position. Then JUMP (not call) to the rethrow stub code.
14265 instruct RethrowException() %{
14266 match(Rethrow);
14267 ins_cost(CALL_COST);
14268
14269 format %{ "JMP rethrow_stub" %}
14270 ins_encode %{
14271 __ set_inst_mark();
14272 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
14273 __ clear_inst_mark();
14274 %}
14275 ins_pipe(pipe_class_call);
14276 %}
14277
14278 // Die now.
14279 instruct ShouldNotReachHere() %{
14280 match(Halt);
14281 ins_cost(CALL_COST);
14282
14283 format %{ "ShouldNotReachHere" %}
14284 ins_encode %{
14285 if (is_reachable()) {
14286 const char* str = __ code_string(_halt_reason);
14287 __ stop(str);
14288 }
14289 %}
14290 ins_pipe(pipe_class_default);
14291 %}
14292
14293 // This name is KNOWN by the ADLC and cannot be changed. The ADLC
14294 // forces a 'TypeRawPtr::BOTTOM' output type for this guy.
14295 // Get a DEF on threadRegP, no costs, no encoding, use
14296 // 'ins_should_rematerialize(true)' to avoid spilling.
14297 instruct tlsLoadP(threadRegP dst) %{
14298 match(Set dst (ThreadLocal));
14299 ins_cost(0);
14300
14301 ins_should_rematerialize(true);
14302
14303 format %{ " -- \t// $dst=Thread::current(), empty" %}
14304 size(0);
14305 ins_encode( /*empty*/ );
14306 ins_pipe(pipe_class_empty);
14307 %}
14308
14309 //---Some PPC specific nodes---------------------------------------------------
14310
14311 // Nop instructions
14312
14313 instruct fxNop() %{
14314 ins_cost(0);
14315
14316 ins_is_nop(true);
14317
14318 format %{ "fxNop" %}
14319 size(4);
14320 ins_encode %{
14321 __ nop();
14322 %}
14323 ins_pipe(pipe_class_default);
14324 %}
14325
14326 instruct fpNop0() %{
14327 ins_cost(0);
14328
14329 ins_is_nop(true);
14330
14331 format %{ "fpNop0" %}
14332 size(4);
14333 ins_encode %{
14334 __ fpnop0();
14335 %}
14336 ins_pipe(pipe_class_default);
14337 %}
14338
14339 instruct fpNop1() %{
14340 ins_cost(0);
14341
14342 ins_is_nop(true);
14343
14344 format %{ "fpNop1" %}
14345 size(4);
14346 ins_encode %{
14347 __ fpnop1();
14348 %}
14349 ins_pipe(pipe_class_default);
14350 %}
14351
14352 instruct brNop0() %{
14353 ins_cost(0);
14354 size(4);
14355 format %{ "brNop0" %}
14356 ins_encode %{
14357 __ brnop0();
14358 %}
14359 ins_is_nop(true);
14360 ins_pipe(pipe_class_default);
14361 %}
14362
14363 instruct brNop1() %{
14364 ins_cost(0);
14365
14366 ins_is_nop(true);
14367
14368 format %{ "brNop1" %}
14369 size(4);
14370 ins_encode %{
14371 __ brnop1();
14372 %}
14373 ins_pipe(pipe_class_default);
14374 %}
14375
14376 instruct brNop2() %{
14377 ins_cost(0);
14378
14379 ins_is_nop(true);
14380
14381 format %{ "brNop2" %}
14382 size(4);
14383 ins_encode %{
14384 __ brnop2();
14385 %}
14386 ins_pipe(pipe_class_default);
14387 %}
14388
14389 instruct cacheWB(indirect addr)
14390 %{
14391 match(CacheWB addr);
14392
14393 ins_cost(100);
14394 format %{ "cache writeback, address = $addr" %}
14395 ins_encode %{
14396 assert($addr->index_position() < 0, "should be");
14397 assert($addr$$disp == 0, "should be");
14398 __ cache_wb(Address($addr$$base$$Register));
14399 %}
14400 ins_pipe(pipe_class_default);
14401 %}
14402
14403 instruct cacheWBPreSync()
14404 %{
14405 match(CacheWBPreSync);
14406
14407 ins_cost(0);
14408 format %{ "cache writeback presync" %}
14409 ins_encode %{
14410 __ cache_wbsync(true);
14411 %}
14412 ins_pipe(pipe_class_default);
14413 %}
14414
14415 instruct cacheWBPostSync()
14416 %{
14417 match(CacheWBPostSync);
14418
14419 ins_cost(100);
14420 format %{ "cache writeback postsync" %}
14421 ins_encode %{
14422 __ cache_wbsync(false);
14423 %}
14424 ins_pipe(pipe_class_default);
14425 %}
14426
14427 //----------PEEPHOLE RULES-----------------------------------------------------
14428 // These must follow all instruction definitions as they use the names
14429 // defined in the instructions definitions.
14430 //
14431 // peepmatch ( root_instr_name [preceeding_instruction]* );
14432 //
14433 // peepconstraint %{
14434 // (instruction_number.operand_name relational_op instruction_number.operand_name
14435 // [, ...] );
14436 // // instruction numbers are zero-based using left to right order in peepmatch
14437 //
14438 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14439 // // provide an instruction_number.operand_name for each operand that appears
14440 // // in the replacement instruction's match rule
14441 //
14442 // ---------VM FLAGS---------------------------------------------------------
14443 //
14444 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14445 //
14446 // Each peephole rule is given an identifying number starting with zero and
14447 // increasing by one in the order seen by the parser. An individual peephole
14448 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14449 // on the command-line.
14450 //
14451 // ---------CURRENT LIMITATIONS----------------------------------------------
14452 //
14453 // Only match adjacent instructions in same basic block
14454 // Only equality constraints
14455 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14456 // Only one replacement instruction
14457 //
14458 // ---------EXAMPLE----------------------------------------------------------
14459 //
14460 // // pertinent parts of existing instructions in architecture description
14461 // instruct movI(eRegI dst, eRegI src) %{
14462 // match(Set dst (CopyI src));
14463 // %}
14464 //
14465 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14466 // match(Set dst (AddI dst src));
14467 // effect(KILL cr);
14468 // %}
14469 //
14470 // // Change (inc mov) to lea
14471 // peephole %{
14472 // // increment preceded by register-register move
14473 // peepmatch ( incI_eReg movI );
14474 // // require that the destination register of the increment
14475 // // match the destination register of the move
14476 // peepconstraint ( 0.dst == 1.dst );
14477 // // construct a replacement instruction that sets
14478 // // the destination to ( move's source register + one )
14479 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14480 // %}
14481 //
14482 // Implementation no longer uses movX instructions since
14483 // machine-independent system no longer uses CopyX nodes.
14484 //
14485 // peephole %{
14486 // peepmatch ( incI_eReg movI );
14487 // peepconstraint ( 0.dst == 1.dst );
14488 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14489 // %}
14490 //
14491 // peephole %{
14492 // peepmatch ( decI_eReg movI );
14493 // peepconstraint ( 0.dst == 1.dst );
14494 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14495 // %}
14496 //
14497 // peephole %{
14498 // peepmatch ( addI_eReg_imm movI );
14499 // peepconstraint ( 0.dst == 1.dst );
14500 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14501 // %}
14502 //
14503 // peephole %{
14504 // peepmatch ( addP_eReg_imm movP );
14505 // peepconstraint ( 0.dst == 1.dst );
14506 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
14507 // %}
14508
14509 // // Change load of spilled value to only a spill
14510 // instruct storeI(memory mem, eRegI src) %{
14511 // match(Set mem (StoreI mem src));
14512 // %}
14513 //
14514 // instruct loadI(eRegI dst, memory mem) %{
14515 // match(Set dst (LoadI mem));
14516 // %}
14517 //
14518 peephole %{
14519 peepmatch ( loadI storeI );
14520 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14521 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14522 %}
14523
14524 peephole %{
14525 peepmatch ( loadL storeL );
14526 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14527 peepreplace ( storeL( 1.mem 1.mem 1.src ) );
14528 %}
14529
14530 peephole %{
14531 peepmatch ( loadP storeP );
14532 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
14533 peepreplace ( storeP( 1.dst 1.dst 1.src ) );
14534 %}
14535
14536 //----------SMARTSPILL RULES---------------------------------------------------
14537 // These must follow all instruction definitions as they use the names
14538 // defined in the instructions definitions.