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 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1635 // Variable size. determine dynamically.
1636 return MachNode::size(ra_);
1637 }
1638
1639 int MachPrologNode::reloc() const {
1640 // Return number of relocatable values contained in this instruction.
1641 return 1; // 1 reloc entry for load_const(toc).
1642 }
1643
1644 //=============================================================================
1645
1646 #ifndef PRODUCT
1647 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1648 Compile* C = ra_->C;
1649
1650 st->print("EPILOG\n\t");
1651 st->print("restore return pc\n\t");
1652 st->print("pop frame\n\t");
1653
1654 if (do_polling() && C->is_method_compilation()) {
1655 st->print("safepoint poll\n\t");
1656 }
1657 }
1658 #endif
1659
1660 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1661 Compile* C = ra_->C;
1662
1663 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt;
1664 assert(framesize >= 0, "negative frame-size?");
1665
1666 const bool method_needs_polling = do_polling() && C->is_method_compilation();
1667 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1668 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
1669 const Register temp = R12;
1670
1671 if (!method_is_frameless) {
1672 // Restore return pc relative to callers' sp.
1673 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP);
1674 // Move return pc to LR.
1675 __ mtlr(return_pc);
1676 // Pop frame (fixed frame-size).
1677 __ addi(R1_SP, R1_SP, (int)framesize);
1678 }
1679
1680 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1681 __ reserved_stack_check(return_pc);
1682 }
1683
1684 if (method_needs_polling) {
1685 Label dummy_label;
1686 Label* code_stub = &dummy_label;
1687 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) {
1688 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1689 C->output()->add_stub(stub);
1690 code_stub = &stub->entry();
1691 __ relocate(relocInfo::poll_return_type);
1692 }
1693 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */);
1694 }
1695 }
1696
1697 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1698 // Variable size. Determine dynamically.
1699 return MachNode::size(ra_);
1700 }
1701
1702 int MachEpilogNode::reloc() const {
1703 // Return number of relocatable values contained in this instruction.
1704 return 1; // 1 for load_from_polling_page.
1705 }
1706
1707 const Pipeline * MachEpilogNode::pipeline() const {
1708 return MachNode::pipeline_class();
1709 }
1710
1711 // =============================================================================
1712
1713 // Figure out which register class each belongs in: rc_int, rc_float, rc_vec or
1714 // rc_stack.
1715 enum RC { rc_bad, rc_int, rc_float, rc_vec, rc_stack };
1716
1717 static enum RC rc_class(OptoReg::Name reg) {
1718 // Return the register class for the given register. The given register
1719 // reg is a <register>_num value, which is an index into the MachRegisterNumbers
1720 // enumeration in adGlobals_ppc.hpp.
1721
1722 if (reg == OptoReg::Bad) return rc_bad;
1723
1724 // We have 64 integer register halves, starting at index 0.
1725 STATIC_ASSERT((int)ConcreteRegisterImpl::max_gpr == (int)MachRegisterNumbers::F0_num);
1726 if (reg < ConcreteRegisterImpl::max_gpr) return rc_int;
1727
1728 // We have 64 floating-point register halves, starting at index 64.
1729 STATIC_ASSERT((int)ConcreteRegisterImpl::max_fpr == (int)MachRegisterNumbers::VR0_num);
1730 if (reg < ConcreteRegisterImpl::max_fpr) return rc_float;
1731
1732 // We have 64 vector-scalar registers, starting at index 128.
1733 STATIC_ASSERT((int)ConcreteRegisterImpl::max_vr == (int)MachRegisterNumbers::CR0_num);
1734 if (reg < ConcreteRegisterImpl::max_vr) return rc_vec;
1735
1736 // Condition and special purpose registers are not allocated. We only accept stack from here.
1737 assert(OptoReg::is_stack(reg), "what else is it?");
1738 return rc_stack;
1739 }
1740
1741 static int ld_st_helper(C2_MacroAssembler *masm, const char *op_str, uint opcode, int reg, int offset,
1742 bool do_print, Compile* C, outputStream *st) {
1743
1744 assert(opcode == Assembler::LD_OPCODE ||
1745 opcode == Assembler::STD_OPCODE ||
1746 opcode == Assembler::LWZ_OPCODE ||
1747 opcode == Assembler::STW_OPCODE ||
1748 opcode == Assembler::LFD_OPCODE ||
1749 opcode == Assembler::STFD_OPCODE ||
1750 opcode == Assembler::LFS_OPCODE ||
1751 opcode == Assembler::STFS_OPCODE,
1752 "opcode not supported");
1753
1754 if (masm) {
1755 int d =
1756 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ?
1757 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/)
1758 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build.
1759 emit_long(masm, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP));
1760 }
1761 #ifndef PRODUCT
1762 else if (do_print) {
1763 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy",
1764 op_str,
1765 Matcher::regName[reg],
1766 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/);
1767 }
1768 #endif
1769 return 4; // size
1770 }
1771
1772 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1773 Compile* C = ra_->C;
1774
1775 // Get registers to move.
1776 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1777 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1778 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1779 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1780
1781 enum RC src_hi_rc = rc_class(src_hi);
1782 enum RC src_lo_rc = rc_class(src_lo);
1783 enum RC dst_hi_rc = rc_class(dst_hi);
1784 enum RC dst_lo_rc = rc_class(dst_lo);
1785
1786 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1787 if (src_hi != OptoReg::Bad)
1788 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1789 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1790 "expected aligned-adjacent pairs");
1791 // Generate spill code!
1792 int size = 0;
1793
1794 if (src_lo == dst_lo && src_hi == dst_hi)
1795 return size; // Self copy, no move.
1796
1797 if (bottom_type()->isa_vect() != nullptr && ideal_reg() == Op_VecX) {
1798 int src_offset = ra_->reg2offset(src_lo);
1799 int dst_offset = ra_->reg2offset(dst_lo);
1800 DEBUG_ONLY(int algm = MIN2(RegMask::num_registers(ideal_reg()), (int)Matcher::stack_alignment_in_slots()) * VMRegImpl::stack_slot_size);
1801 assert((src_lo_rc != rc_stack) || is_aligned(src_offset, algm), "unaligned vector spill sp offset %d (src)", src_offset);
1802 assert((dst_lo_rc != rc_stack) || is_aligned(dst_offset, algm), "unaligned vector spill sp offset %d (dst)", dst_offset);
1803 // Memory->Memory Spill.
1804 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1805 if (masm) {
1806 __ ld(R0, src_offset, R1_SP);
1807 __ std(R0, dst_offset, R1_SP);
1808 __ ld(R0, src_offset+8, R1_SP);
1809 __ std(R0, dst_offset+8, R1_SP);
1810 }
1811 size += 16;
1812 #ifndef PRODUCT
1813 if (st != nullptr) {
1814 st->print("%-7s [R1_SP + #%d] -> [R1_SP + #%d] \t// vector spill copy", "SPILL", src_offset, dst_offset);
1815 }
1816 #endif // !PRODUCT
1817 }
1818 // VectorRegister->Memory Spill.
1819 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_stack) {
1820 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1821 if (masm) {
1822 __ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16
1823 }
1824 size += 4;
1825 #ifndef PRODUCT
1826 if (st != nullptr) {
1827 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "STXV", Matcher::regName[src_lo], dst_offset);
1828 }
1829 #endif // !PRODUCT
1830 }
1831 // Memory->VectorRegister Spill.
1832 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vec) {
1833 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1834 if (masm) {
1835 __ lxv(Rdst, src_offset, R1_SP);
1836 }
1837 size += 4;
1838 #ifndef PRODUCT
1839 if (st != nullptr) {
1840 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "LXV", Matcher::regName[dst_lo], src_offset);
1841 }
1842 #endif // !PRODUCT
1843 }
1844 // VectorRegister->VectorRegister.
1845 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_vec) {
1846 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1847 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1848 if (masm) {
1849 __ xxlor(Rdst, Rsrc, Rsrc);
1850 }
1851 size += 4;
1852 #ifndef PRODUCT
1853 if (st != nullptr) {
1854 st->print("%-7s %s, %s, %s\t// vector spill copy",
1855 "XXLOR", Matcher::regName[dst_lo], Matcher::regName[src_lo], Matcher::regName[src_lo]);
1856 }
1857 #endif // !PRODUCT
1858 }
1859 else {
1860 ShouldNotReachHere(); // No VR spill.
1861 }
1862 return size;
1863 }
1864
1865 // --------------------------------------
1866 // Memory->Memory Spill. Use R0 to hold the value.
1867 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1868 int src_offset = ra_->reg2offset(src_lo);
1869 int dst_offset = ra_->reg2offset(dst_lo);
1870 if (src_hi != OptoReg::Bad) {
1871 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack,
1872 "expected same type of move for high parts");
1873 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st);
1874 if (!masm && !do_size) st->print("\n\t");
1875 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st);
1876 } else {
1877 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st);
1878 if (!masm && !do_size) st->print("\n\t");
1879 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st);
1880 }
1881 return size;
1882 }
1883
1884 // --------------------------------------
1885 // Check for float->int copy; requires a trip through memory.
1886 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1887 Unimplemented();
1888 }
1889
1890 // --------------------------------------
1891 // Check for integer reg-reg copy.
1892 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1893 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1894 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1895 size = (Rsrc != Rdst) ? 4 : 0;
1896
1897 if (masm) {
1898 if (size) {
1899 __ mr(Rdst, Rsrc);
1900 }
1901 }
1902 #ifndef PRODUCT
1903 else if (!do_size) {
1904 if (size) {
1905 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1906 } else {
1907 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1908 }
1909 }
1910 #endif
1911 return size;
1912 }
1913
1914 // Check for integer store.
1915 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1916 int dst_offset = ra_->reg2offset(dst_lo);
1917 if (src_hi != OptoReg::Bad) {
1918 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack,
1919 "expected same type of move for high parts");
1920 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1921 } else {
1922 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st);
1923 }
1924 return size;
1925 }
1926
1927 // Check for integer load.
1928 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1929 int src_offset = ra_->reg2offset(src_lo);
1930 if (src_hi != OptoReg::Bad) {
1931 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack,
1932 "expected same type of move for high parts");
1933 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1934 } else {
1935 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st);
1936 }
1937 return size;
1938 }
1939
1940 // Check for float reg-reg copy.
1941 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1942 if (masm) {
1943 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]);
1944 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]);
1945 __ fmr(Rdst, Rsrc);
1946 }
1947 #ifndef PRODUCT
1948 else if (!do_size) {
1949 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1950 }
1951 #endif
1952 return 4;
1953 }
1954
1955 // Check for float store.
1956 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1957 int dst_offset = ra_->reg2offset(dst_lo);
1958 if (src_hi != OptoReg::Bad) {
1959 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack,
1960 "expected same type of move for high parts");
1961 size += ld_st_helper(masm, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1962 } else {
1963 size += ld_st_helper(masm, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st);
1964 }
1965 return size;
1966 }
1967
1968 // Check for float load.
1969 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1970 int src_offset = ra_->reg2offset(src_lo);
1971 if (src_hi != OptoReg::Bad) {
1972 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack,
1973 "expected same type of move for high parts");
1974 size += ld_st_helper(masm, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1975 } else {
1976 size += ld_st_helper(masm, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st);
1977 }
1978 return size;
1979 }
1980
1981 // --------------------------------------------------------------------
1982 // Check for hi bits still needing moving. Only happens for misaligned
1983 // arguments to native calls.
1984 if (src_hi == dst_hi)
1985 return size; // Self copy; no move.
1986
1987 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad");
1988 ShouldNotReachHere(); // Unimplemented
1989 return 0;
1990 }
1991
1992 #ifndef PRODUCT
1993 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1994 if (!ra_)
1995 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1996 else
1997 implementation(nullptr, ra_, false, st);
1998 }
1999 #endif
2000
2001 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
2002 implementation(masm, ra_, false, nullptr);
2003 }
2004
2005 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
2006 return implementation(nullptr, ra_, true, nullptr);
2007 }
2008
2009 #ifndef PRODUCT
2010 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2011 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count);
2012 }
2013 #endif
2014
2015 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *) const {
2016 // _count contains the number of nops needed for padding.
2017 for (int i = 0; i < _count; i++) {
2018 __ nop();
2019 }
2020 }
2021
2022 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
2023 return _count * 4;
2024 }
2025
2026 #ifndef PRODUCT
2027 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2028 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2029 char reg_str[128];
2030 ra_->dump_register(this, reg_str, sizeof(reg_str));
2031 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset);
2032 }
2033 #endif
2034
2035 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
2036 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2037 int reg = ra_->get_encode(this);
2038
2039 if (Assembler::is_simm(offset, 16)) {
2040 __ addi(as_Register(reg), R1, offset);
2041 } else {
2042 ShouldNotReachHere();
2043 }
2044 }
2045
2046 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
2047 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
2048 return 4;
2049 }
2050
2051 #ifndef PRODUCT
2052 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2053 st->print_cr("---- MachUEPNode ----");
2054 st->print_cr("...");
2055 }
2056 #endif
2057
2058 void MachUEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
2059 // This is the unverified entry point.
2060 __ ic_check(CodeEntryAlignment);
2061 // Argument is valid and klass is as expected, continue.
2062 }
2063
2064 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
2065 // Variable size. Determine dynamically.
2066 return MachNode::size(ra_);
2067 }
2068
2069 //=============================================================================
2070
2071 %} // interrupt source
2072
2073 source_hpp %{ // Header information of the source block.
2074
2075 class HandlerImpl {
2076
2077 public:
2078
2079 static int emit_deopt_handler(C2_MacroAssembler* masm);
2080
2081 static uint size_deopt_handler() {
2082 // The deopt_handler is a bl64_patchable.
2083 return MacroAssembler::bl64_patchable_size + BytesPerInstWord;
2084 }
2085
2086 };
2087
2088 class Node::PD {
2089 public:
2090 enum NodeFlags {
2091 _last_flag = Node::_last_flag
2092 };
2093 };
2094
2095 %} // end source_hpp
2096
2097 source %{
2098
2099 // The deopt_handler is like the exception handler, but it calls to
2100 // the deoptimization blob instead of jumping to the exception blob.
2101 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
2102 address base = __ start_a_stub(size_deopt_handler());
2103 if (base == nullptr) {
2104 ciEnv::current()->record_failure("CodeCache is full");
2105 return 0; // CodeBuffer::expand failed
2106 }
2107
2108 int offset = __ offset();
2109
2110 Label start;
2111 __ bind(start);
2112
2113 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
2114 relocInfo::runtime_call_type);
2115
2116 int entry_offset = __ offset();
2117
2118 __ b(start);
2119
2120 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
2121 assert(__ offset() - entry_offset >= NativePostCallNop::first_check_size,
2122 "out of bounds read in post-call NOP check");
2123 __ end_a_stub();
2124
2125 return entry_offset;
2126 }
2127
2128 //=============================================================================
2129
2130 // Use a frame slots bias for frameless methods if accessing the stack.
2131 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) {
2132 if (as_Register(reg_enc) == R1_SP) {
2133 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes();
2134 }
2135 return 0;
2136 }
2137
2138 bool Matcher::match_rule_supported(int opcode) {
2139 if (!has_match_rule(opcode)) {
2140 return false; // no match rule present
2141 }
2142
2143 switch (opcode) {
2144 case Op_CountLeadingZerosI:
2145 case Op_CountLeadingZerosL:
2146 return UseCountLeadingZerosInstructionsPPC64;
2147 case Op_CountTrailingZerosI:
2148 case Op_CountTrailingZerosL:
2149 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64);
2150 case Op_PopCountI:
2151 case Op_PopCountL:
2152 return UsePopCountInstruction;
2153 case Op_ConvF2HF:
2154 case Op_ConvHF2F:
2155 return VM_Version::supports_float16();
2156 case Op_AddVB:
2157 case Op_AddVS:
2158 case Op_AddVI:
2159 case Op_AddVF:
2160 case Op_AddVD:
2161 case Op_SubVB:
2162 case Op_SubVS:
2163 case Op_SubVI:
2164 case Op_SubVF:
2165 case Op_SubVD:
2166 case Op_MulVS:
2167 case Op_MulVF:
2168 case Op_MulVD:
2169 case Op_DivVF:
2170 case Op_DivVD:
2171 case Op_AbsVF:
2172 case Op_AbsVD:
2173 case Op_NegVI:
2174 case Op_NegVF:
2175 case Op_NegVD:
2176 case Op_SqrtVF:
2177 case Op_SqrtVD:
2178 case Op_AddVL:
2179 case Op_SubVL:
2180 case Op_MulVI:
2181 case Op_RoundDoubleModeV:
2182 case Op_MinV:
2183 case Op_MaxV:
2184 case Op_UMinV:
2185 case Op_UMaxV:
2186 case Op_AndV:
2187 case Op_OrV:
2188 case Op_XorV:
2189 case Op_AddReductionVI:
2190 case Op_MulReductionVI:
2191 case Op_AndReductionV:
2192 case Op_OrReductionV:
2193 case Op_XorReductionV:
2194 case Op_MinReductionV:
2195 case Op_MaxReductionV:
2196 return SuperwordUseVSX;
2197 case Op_PopCountVI:
2198 case Op_PopCountVL:
2199 return (SuperwordUseVSX && UsePopCountInstruction);
2200 case Op_CountLeadingZerosV:
2201 return SuperwordUseVSX && UseCountLeadingZerosInstructionsPPC64;
2202 case Op_CountTrailingZerosV:
2203 return SuperwordUseVSX && UseCountTrailingZerosInstructionsPPC64;
2204 case Op_FmaF:
2205 case Op_FmaD:
2206 return UseFMA;
2207 case Op_FmaVF:
2208 case Op_FmaVD:
2209 return (SuperwordUseVSX && UseFMA);
2210
2211 case Op_MinF:
2212 case Op_MaxF:
2213 case Op_MinD:
2214 case Op_MaxD:
2215 return (PowerArchitecturePPC64 >= 9);
2216
2217 case Op_Digit:
2218 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit);
2219 case Op_LowerCase:
2220 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase);
2221 case Op_UpperCase:
2222 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase);
2223 case Op_Whitespace:
2224 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace);
2225
2226 case Op_CacheWB:
2227 case Op_CacheWBPreSync:
2228 case Op_CacheWBPostSync:
2229 return VM_Version::supports_data_cache_line_flush();
2230 }
2231
2232 return true; // Per default match rules are supported.
2233 }
2234
2235 bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
2236 return match_rule_supported_vector(opcode, vlen, bt);
2237 }
2238
2239 bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
2240 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
2241 return false;
2242 }
2243 // Special cases
2244 switch (opcode) {
2245 // Reductions only support INT at the moment.
2246 case Op_AddReductionVI:
2247 case Op_MulReductionVI:
2248 case Op_AndReductionV:
2249 case Op_OrReductionV:
2250 case Op_XorReductionV:
2251 case Op_MinReductionV:
2252 case Op_MaxReductionV:
2253 return bt == T_INT;
2254 // MaxV, MinV need types == INT || LONG.
2255 case Op_MaxV:
2256 case Op_MinV:
2257 case Op_UMinV:
2258 case Op_UMaxV:
2259 return bt == T_INT || bt == T_LONG;
2260 case Op_NegVI:
2261 return bt == T_INT;
2262 }
2263 return true; // Per default match rules are supported.
2264 }
2265
2266 bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
2267 return false;
2268 }
2269
2270 bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
2271 return false;
2272 }
2273
2274 bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
2275 return false;
2276 }
2277
2278 bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
2279 return false;
2280 }
2281
2282 const RegMask* Matcher::predicate_reg_mask(void) {
2283 return nullptr;
2284 }
2285
2286 // Vector calling convention not yet implemented.
2287 bool Matcher::supports_vector_calling_convention(void) {
2288 return false;
2289 }
2290
2291 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2292 Unimplemented();
2293 return OptoRegPair(0, 0);
2294 }
2295
2296 // Vector width in bytes.
2297 int Matcher::vector_width_in_bytes(BasicType bt) {
2298 if (SuperwordUseVSX) {
2299 assert(MaxVectorSize == 16,
2300 "SuperwordUseVSX requires MaxVectorSize 16, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2301 return 16;
2302 } else {
2303 assert(MaxVectorSize == 8,
2304 "expected MaxVectorSize 8, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2305 return 8;
2306 }
2307 }
2308
2309 // Vector ideal reg.
2310 uint Matcher::vector_ideal_reg(int size) {
2311 if (SuperwordUseVSX) {
2312 assert(MaxVectorSize == 16 && size == 16,
2313 "SuperwordUseVSX requires MaxVectorSize 16 and size 16, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2314 (int64_t)MaxVectorSize, size);
2315 return Op_VecX;
2316 } else {
2317 assert(MaxVectorSize == 8 && size == 8,
2318 "expected MaxVectorSize 8 and size 8, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2319 (int64_t)MaxVectorSize, size);
2320 return Op_RegL;
2321 }
2322 }
2323
2324 // Limits on vector size (number of elements) loaded into vector.
2325 int Matcher::max_vector_size(const BasicType bt) {
2326 assert(is_java_primitive(bt), "only primitive type vectors");
2327 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2328 }
2329
2330 int Matcher::min_vector_size(const BasicType bt) {
2331 return max_vector_size(bt); // Same as max.
2332 }
2333
2334 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
2335 return Matcher::max_vector_size(bt);
2336 }
2337
2338 int Matcher::scalable_vector_reg_size(const BasicType bt) {
2339 return -1;
2340 }
2341
2342 // RETURNS: whether this branch offset is short enough that a short
2343 // branch can be used.
2344 //
2345 // If the platform does not provide any short branch variants, then
2346 // this method should return `false' for offset 0.
2347 //
2348 // `Compile::Fill_buffer' will decide on basis of this information
2349 // whether to do the pass `Compile::Shorten_branches' at all.
2350 //
2351 // And `Compile::Shorten_branches' will decide on basis of this
2352 // information whether to replace particular branch sites by short
2353 // ones.
2354 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2355 // Is the offset within the range of a ppc64 pc relative branch?
2356 bool b;
2357
2358 const int safety_zone = 3 * BytesPerInstWord;
2359 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2360 29 - 16 + 1 + 2);
2361 return b;
2362 }
2363
2364 /* TODO: PPC port
2365 // Make a new machine dependent decode node (with its operands).
2366 MachTypeNode *Matcher::make_decode_node() {
2367 assert(CompressedOops::base() == nullptr && CompressedOops::shift() == 0,
2368 "This method is only implemented for unscaled cOops mode so far");
2369 MachTypeNode *decode = new decodeN_unscaledNode();
2370 decode->set_opnd_array(0, new iRegPdstOper());
2371 decode->set_opnd_array(1, new iRegNsrcOper());
2372 return decode;
2373 }
2374 */
2375
2376 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
2377 ShouldNotReachHere(); // generic vector operands not supported
2378 return nullptr;
2379 }
2380
2381 bool Matcher::is_reg2reg_move(MachNode* m) {
2382 ShouldNotReachHere(); // generic vector operands not supported
2383 return false;
2384 }
2385
2386 bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
2387 return false;
2388 }
2389
2390 bool Matcher::is_generic_vector(MachOper* opnd) {
2391 ShouldNotReachHere(); // generic vector operands not supported
2392 return false;
2393 }
2394
2395 #ifdef ASSERT
2396 // Return whether or not this register is ever used as an argument.
2397 bool Matcher::can_be_java_arg(int reg) {
2398 // We must include the virtual halves in order to get STDs and LDs
2399 // instead of STWs and LWs in the trampoline stubs.
2400
2401 if ( reg == R3_num || reg == R3_H_num
2402 || reg == R4_num || reg == R4_H_num
2403 || reg == R5_num || reg == R5_H_num
2404 || reg == R6_num || reg == R6_H_num
2405 || reg == R7_num || reg == R7_H_num
2406 || reg == R8_num || reg == R8_H_num
2407 || reg == R9_num || reg == R9_H_num
2408 || reg == R10_num || reg == R10_H_num)
2409 return true;
2410
2411 if ( reg == F1_num || reg == F1_H_num
2412 || reg == F2_num || reg == F2_H_num
2413 || reg == F3_num || reg == F3_H_num
2414 || reg == F4_num || reg == F4_H_num
2415 || reg == F5_num || reg == F5_H_num
2416 || reg == F6_num || reg == F6_H_num
2417 || reg == F7_num || reg == F7_H_num
2418 || reg == F8_num || reg == F8_H_num
2419 || reg == F9_num || reg == F9_H_num
2420 || reg == F10_num || reg == F10_H_num
2421 || reg == F11_num || reg == F11_H_num
2422 || reg == F12_num || reg == F12_H_num
2423 || reg == F13_num || reg == F13_H_num)
2424 return true;
2425
2426 return false;
2427 }
2428 #endif
2429
2430 uint Matcher::int_pressure_limit()
2431 {
2432 return (INTPRESSURE == -1) ? 26 : INTPRESSURE;
2433 }
2434
2435 uint Matcher::float_pressure_limit()
2436 {
2437 return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE;
2438 }
2439
2440 // Register for DIVI projection of divmodI.
2441 const RegMask& Matcher::divI_proj_mask() {
2442 ShouldNotReachHere();
2443 return RegMask::EMPTY;
2444 }
2445
2446 // Register for MODI projection of divmodI.
2447 const RegMask& Matcher::modI_proj_mask() {
2448 ShouldNotReachHere();
2449 return RegMask::EMPTY;
2450 }
2451
2452 // Register for DIVL projection of divmodL.
2453 const RegMask& Matcher::divL_proj_mask() {
2454 ShouldNotReachHere();
2455 return RegMask::EMPTY;
2456 }
2457
2458 // Register for MODL projection of divmodL.
2459 const RegMask& Matcher::modL_proj_mask() {
2460 ShouldNotReachHere();
2461 return RegMask::EMPTY;
2462 }
2463
2464 %}
2465
2466 //----------ENCODING BLOCK-----------------------------------------------------
2467 // This block specifies the encoding classes used by the compiler to output
2468 // byte streams. Encoding classes are parameterized macros used by
2469 // Machine Instruction Nodes in order to generate the bit encoding of the
2470 // instruction. Operands specify their base encoding interface with the
2471 // interface keyword. There are currently supported four interfaces,
2472 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
2473 // operand to generate a function which returns its register number when
2474 // queried. CONST_INTER causes an operand to generate a function which
2475 // returns the value of the constant when queried. MEMORY_INTER causes an
2476 // operand to generate four functions which return the Base Register, the
2477 // Index Register, the Scale Value, and the Offset Value of the operand when
2478 // queried. COND_INTER causes an operand to generate six functions which
2479 // return the encoding code (ie - encoding bits for the instruction)
2480 // associated with each basic boolean condition for a conditional instruction.
2481 //
2482 // Instructions specify two basic values for encoding. Again, a function
2483 // is available to check if the constant displacement is an oop. They use the
2484 // ins_encode keyword to specify their encoding classes (which must be
2485 // a sequence of enc_class names, and their parameters, specified in
2486 // the encoding block), and they use the
2487 // opcode keyword to specify, in order, their primary, secondary, and
2488 // tertiary opcode. Only the opcode sections which a particular instruction
2489 // needs for encoding need to be specified.
2490 encode %{
2491 enc_class enc_unimplemented %{
2492 __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
2493 %}
2494
2495 enc_class enc_untested %{
2496 #ifdef ASSERT
2497 __ untested("Untested mach node encoding in AD file.");
2498 #else
2499 #endif
2500 %}
2501
2502 enc_class enc_lbz(iRegIdst dst, memory mem) %{
2503 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2504 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2505 %}
2506
2507 // Load acquire.
2508 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
2509 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2510 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2511 __ twi_0($dst$$Register);
2512 __ isync();
2513 %}
2514
2515 enc_class enc_lhz(iRegIdst dst, memory mem) %{
2516 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2517 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2518 %}
2519
2520 // Load acquire.
2521 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
2522 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2523 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2524 __ twi_0($dst$$Register);
2525 __ isync();
2526 %}
2527
2528 enc_class enc_lwz(iRegIdst dst, memory mem) %{
2529 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2530 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2531 %}
2532
2533 // Load acquire.
2534 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
2535 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2536 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2537 __ twi_0($dst$$Register);
2538 __ isync();
2539 %}
2540
2541 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
2542 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2543 // Operand 'ds' requires 4-alignment.
2544 assert((Idisp & 0x3) == 0, "unaligned offset");
2545 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2546 %}
2547
2548 // Load acquire.
2549 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
2550 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2551 // Operand 'ds' requires 4-alignment.
2552 assert((Idisp & 0x3) == 0, "unaligned offset");
2553 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2554 __ twi_0($dst$$Register);
2555 __ isync();
2556 %}
2557
2558 enc_class enc_lfd(RegF dst, memory mem) %{
2559 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2560 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2561 %}
2562
2563 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2564 int toc_offset = 0;
2565
2566 address const_toc_addr;
2567 // Create a non-oop constant, no relocation needed.
2568 // If it is an IC, it has a virtual_call_Relocation.
2569 const_toc_addr = __ long_constant((jlong)$src$$constant);
2570 if (const_toc_addr == nullptr) {
2571 ciEnv::current()->record_out_of_memory_failure();
2572 return;
2573 }
2574
2575 // Get the constant's TOC offset.
2576 toc_offset = __ offset_to_method_toc(const_toc_addr);
2577
2578 // Keep the current instruction offset in mind.
2579 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2580
2581 __ ld($dst$$Register, toc_offset, $toc$$Register);
2582 %}
2583
2584 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2585 if (!ra_->C->output()->in_scratch_emit_size()) {
2586 address const_toc_addr;
2587 // Create a non-oop constant, no relocation needed.
2588 // If it is an IC, it has a virtual_call_Relocation.
2589 const_toc_addr = __ long_constant((jlong)$src$$constant);
2590 if (const_toc_addr == nullptr) {
2591 ciEnv::current()->record_out_of_memory_failure();
2592 return;
2593 }
2594
2595 // Get the constant's TOC offset.
2596 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2597 // Store the toc offset of the constant.
2598 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2599
2600 // Also keep the current instruction offset in mind.
2601 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2602 }
2603
2604 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2605 %}
2606
2607 %} // encode
2608
2609 source %{
2610
2611 typedef struct {
2612 loadConL_hiNode *_large_hi;
2613 loadConL_loNode *_large_lo;
2614 loadConLNode *_small;
2615 MachNode *_last;
2616 } loadConLNodesTuple;
2617
2618 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2619 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2620 loadConLNodesTuple nodes;
2621
2622 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2623 if (large_constant_pool) {
2624 // Create new nodes.
2625 loadConL_hiNode *m1 = new loadConL_hiNode();
2626 loadConL_loNode *m2 = new loadConL_loNode();
2627
2628 // inputs for new nodes
2629 m1->add_req(nullptr, toc);
2630 m2->add_req(nullptr, m1);
2631
2632 // operands for new nodes
2633 m1->_opnds[0] = new iRegLdstOper(); // dst
2634 m1->_opnds[1] = immSrc; // src
2635 m1->_opnds[2] = new iRegPdstOper(); // toc
2636 m2->_opnds[0] = new iRegLdstOper(); // dst
2637 m2->_opnds[1] = immSrc; // src
2638 m2->_opnds[2] = new iRegLdstOper(); // base
2639
2640 // Initialize ins_attrib TOC fields.
2641 m1->_const_toc_offset = -1;
2642 m2->_const_toc_offset_hi_node = m1;
2643
2644 // Initialize ins_attrib instruction offset.
2645 m1->_cbuf_insts_offset = -1;
2646
2647 // register allocation for new nodes
2648 ra_->set_pair(m1->_idx, reg_second, reg_first);
2649 ra_->set_pair(m2->_idx, reg_second, reg_first);
2650
2651 // Create result.
2652 nodes._large_hi = m1;
2653 nodes._large_lo = m2;
2654 nodes._small = nullptr;
2655 nodes._last = nodes._large_lo;
2656 assert(m2->bottom_type()->isa_long(), "must be long");
2657 } else {
2658 loadConLNode *m2 = new loadConLNode();
2659
2660 // inputs for new nodes
2661 m2->add_req(nullptr, toc);
2662
2663 // operands for new nodes
2664 m2->_opnds[0] = new iRegLdstOper(); // dst
2665 m2->_opnds[1] = immSrc; // src
2666 m2->_opnds[2] = new iRegPdstOper(); // toc
2667
2668 // Initialize ins_attrib instruction offset.
2669 m2->_cbuf_insts_offset = -1;
2670
2671 // register allocation for new nodes
2672 ra_->set_pair(m2->_idx, reg_second, reg_first);
2673
2674 // Create result.
2675 nodes._large_hi = nullptr;
2676 nodes._large_lo = nullptr;
2677 nodes._small = m2;
2678 nodes._last = nodes._small;
2679 assert(m2->bottom_type()->isa_long(), "must be long");
2680 }
2681
2682 return nodes;
2683 }
2684
2685 typedef struct {
2686 loadConL_hiNode *_large_hi;
2687 loadConL_loNode *_large_lo;
2688 mtvsrdNode *_moved;
2689 xxspltdNode *_replicated;
2690 loadConLNode *_small;
2691 MachNode *_last;
2692 } loadConLReplicatedNodesTuple;
2693
2694 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2695 vecXOper *dst, immI_0Oper *zero,
2696 OptoReg::Name reg_second, OptoReg::Name reg_first,
2697 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) {
2698 loadConLReplicatedNodesTuple nodes;
2699
2700 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2701 if (large_constant_pool) {
2702 // Create new nodes.
2703 loadConL_hiNode *m1 = new loadConL_hiNode();
2704 loadConL_loNode *m2 = new loadConL_loNode();
2705 mtvsrdNode *m3 = new mtvsrdNode();
2706 xxspltdNode *m4 = new xxspltdNode();
2707
2708 // inputs for new nodes
2709 m1->add_req(nullptr, toc);
2710 m2->add_req(nullptr, m1);
2711 m3->add_req(nullptr, m2);
2712 m4->add_req(nullptr, m3);
2713
2714 // operands for new nodes
2715 m1->_opnds[0] = new iRegLdstOper(); // dst
2716 m1->_opnds[1] = immSrc; // src
2717 m1->_opnds[2] = new iRegPdstOper(); // toc
2718
2719 m2->_opnds[0] = new iRegLdstOper(); // dst
2720 m2->_opnds[1] = immSrc; // src
2721 m2->_opnds[2] = new iRegLdstOper(); // base
2722
2723 m3->_opnds[0] = new vecXOper(); // dst
2724 m3->_opnds[1] = new iRegLdstOper(); // src
2725
2726 m4->_opnds[0] = new vecXOper(); // dst
2727 m4->_opnds[1] = new vecXOper(); // src
2728 m4->_opnds[2] = zero;
2729
2730 // Initialize ins_attrib TOC fields.
2731 m1->_const_toc_offset = -1;
2732 m2->_const_toc_offset_hi_node = m1;
2733
2734 // Initialize ins_attrib instruction offset.
2735 m1->_cbuf_insts_offset = -1;
2736
2737 // register allocation for new nodes
2738 ra_->set_pair(m1->_idx, reg_second, reg_first);
2739 ra_->set_pair(m2->_idx, reg_second, reg_first);
2740 ra_->set1(m3->_idx, reg_second);
2741 ra_->set2(m3->_idx, reg_vec_first);
2742 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2743
2744 // Create result.
2745 nodes._large_hi = m1;
2746 nodes._large_lo = m2;
2747 nodes._moved = m3;
2748 nodes._replicated = m4;
2749 nodes._small = nullptr;
2750 nodes._last = nodes._replicated;
2751 assert(m2->bottom_type()->isa_long(), "must be long");
2752 } else {
2753 loadConLNode *m2 = new loadConLNode();
2754 mtvsrdNode *m3 = new mtvsrdNode();
2755 xxspltdNode *m4 = new xxspltdNode();
2756
2757 // inputs for new nodes
2758 m2->add_req(nullptr, toc);
2759
2760 // operands for new nodes
2761 m2->_opnds[0] = new iRegLdstOper(); // dst
2762 m2->_opnds[1] = immSrc; // src
2763 m2->_opnds[2] = new iRegPdstOper(); // toc
2764
2765 m3->_opnds[0] = new vecXOper(); // dst
2766 m3->_opnds[1] = new iRegLdstOper(); // src
2767
2768 m4->_opnds[0] = new vecXOper(); // dst
2769 m4->_opnds[1] = new vecXOper(); // src
2770 m4->_opnds[2] = zero;
2771
2772 // Initialize ins_attrib instruction offset.
2773 m2->_cbuf_insts_offset = -1;
2774 ra_->set1(m3->_idx, reg_second);
2775 ra_->set2(m3->_idx, reg_vec_first);
2776 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2777
2778 // register allocation for new nodes
2779 ra_->set_pair(m2->_idx, reg_second, reg_first);
2780
2781 // Create result.
2782 nodes._large_hi = nullptr;
2783 nodes._large_lo = nullptr;
2784 nodes._small = m2;
2785 nodes._moved = m3;
2786 nodes._replicated = m4;
2787 nodes._last = nodes._replicated;
2788 assert(m2->bottom_type()->isa_long(), "must be long");
2789 }
2790
2791 return nodes;
2792 }
2793
2794 %} // source
2795
2796 encode %{
2797 // Postalloc expand emitter for loading a long constant from the method's TOC.
2798 // Enc_class needed as consttanttablebase is not supported by postalloc
2799 // expand.
2800 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2801 // Create new nodes.
2802 loadConLNodesTuple loadConLNodes =
2803 loadConLNodesTuple_create(ra_, n_toc, op_src,
2804 ra_->get_reg_second(this), ra_->get_reg_first(this));
2805
2806 // Push new nodes.
2807 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2808 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2809
2810 // some asserts
2811 assert(nodes->length() >= 1, "must have created at least 1 node");
2812 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2813 %}
2814
2815 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2816 int toc_offset = 0;
2817
2818 intptr_t val = $src$$constant;
2819 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2820 address const_toc_addr;
2821 RelocationHolder r; // Initializes type to none.
2822 if (constant_reloc == relocInfo::oop_type) {
2823 // Create an oop constant and a corresponding relocation.
2824 AddressLiteral a = __ constant_oop_address((jobject)val);
2825 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2826 r = a.rspec();
2827 } else if (constant_reloc == relocInfo::metadata_type) {
2828 // Notify OOP recorder (don't need the relocation)
2829 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2830 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2831 } else {
2832 // Create a non-oop constant, no relocation needed.
2833 const_toc_addr = __ long_constant((jlong)$src$$constant);
2834 }
2835
2836 if (const_toc_addr == nullptr) {
2837 ciEnv::current()->record_out_of_memory_failure();
2838 return;
2839 }
2840 __ relocate(r); // If set above.
2841 // Get the constant's TOC offset.
2842 toc_offset = __ offset_to_method_toc(const_toc_addr);
2843
2844 __ ld($dst$$Register, toc_offset, $toc$$Register);
2845 %}
2846
2847 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2848 if (!ra_->C->output()->in_scratch_emit_size()) {
2849 intptr_t val = $src$$constant;
2850 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2851 address const_toc_addr;
2852 RelocationHolder r; // Initializes type to none.
2853 if (constant_reloc == relocInfo::oop_type) {
2854 // Create an oop constant and a corresponding relocation.
2855 AddressLiteral a = __ constant_oop_address((jobject)val);
2856 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2857 r = a.rspec();
2858 } else if (constant_reloc == relocInfo::metadata_type) {
2859 // Notify OOP recorder (don't need the relocation)
2860 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2861 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2862 } else { // non-oop pointers, e.g. card mark base, heap top
2863 // Create a non-oop constant, no relocation needed.
2864 const_toc_addr = __ long_constant((jlong)$src$$constant);
2865 }
2866
2867 if (const_toc_addr == nullptr) {
2868 ciEnv::current()->record_out_of_memory_failure();
2869 return;
2870 }
2871 __ relocate(r); // If set above.
2872 // Get the constant's TOC offset.
2873 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2874 // Store the toc offset of the constant.
2875 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2876 }
2877
2878 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2879 %}
2880
2881 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2882 // Enc_class needed as consttanttablebase is not supported by postalloc
2883 // expand.
2884 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2885 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2886 if (large_constant_pool) {
2887 // Create new nodes.
2888 loadConP_hiNode *m1 = new loadConP_hiNode();
2889 loadConP_loNode *m2 = new loadConP_loNode();
2890
2891 // inputs for new nodes
2892 m1->add_req(nullptr, n_toc);
2893 m2->add_req(nullptr, m1);
2894
2895 // operands for new nodes
2896 m1->_opnds[0] = new iRegPdstOper(); // dst
2897 m1->_opnds[1] = op_src; // src
2898 m1->_opnds[2] = new iRegPdstOper(); // toc
2899 m2->_opnds[0] = new iRegPdstOper(); // dst
2900 m2->_opnds[1] = op_src; // src
2901 m2->_opnds[2] = new iRegLdstOper(); // base
2902
2903 // Initialize ins_attrib TOC fields.
2904 m1->_const_toc_offset = -1;
2905 m2->_const_toc_offset_hi_node = m1;
2906
2907 // Register allocation for new nodes.
2908 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2909 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2910
2911 nodes->push(m1);
2912 nodes->push(m2);
2913 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2914 } else {
2915 loadConPNode *m2 = new loadConPNode();
2916
2917 // inputs for new nodes
2918 m2->add_req(nullptr, n_toc);
2919
2920 // operands for new nodes
2921 m2->_opnds[0] = new iRegPdstOper(); // dst
2922 m2->_opnds[1] = op_src; // src
2923 m2->_opnds[2] = new iRegPdstOper(); // toc
2924
2925 // Register allocation for new nodes.
2926 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2927
2928 nodes->push(m2);
2929 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2930 }
2931 %}
2932
2933 // Enc_class needed as consttanttablebase is not supported by postalloc
2934 // expand.
2935 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2936 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2937
2938 MachNode *m2;
2939 if (large_constant_pool) {
2940 m2 = new loadConFCompNode();
2941 } else {
2942 m2 = new loadConFNode();
2943 }
2944 // inputs for new nodes
2945 m2->add_req(nullptr, n_toc);
2946
2947 // operands for new nodes
2948 m2->_opnds[0] = op_dst;
2949 m2->_opnds[1] = op_src;
2950 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase
2951
2952 // register allocation for new nodes
2953 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2954 nodes->push(m2);
2955 %}
2956
2957 // Enc_class needed as consttanttablebase is not supported by postalloc
2958 // expand.
2959 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2960 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2961
2962 MachNode *m2;
2963 if (large_constant_pool) {
2964 m2 = new loadConDCompNode();
2965 } else {
2966 m2 = new loadConDNode();
2967 }
2968 // inputs for new nodes
2969 m2->add_req(nullptr, n_toc);
2970
2971 // operands for new nodes
2972 m2->_opnds[0] = op_dst;
2973 m2->_opnds[1] = op_src;
2974 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase
2975
2976 // register allocation for new nodes
2977 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2978 nodes->push(m2);
2979 %}
2980
2981 enc_class enc_stw(iRegIsrc src, memory mem) %{
2982 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2983 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2984 %}
2985
2986 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2987 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2988 // Operand 'ds' requires 4-alignment.
2989 assert((Idisp & 0x3) == 0, "unaligned offset");
2990 __ std($src$$Register, Idisp, $mem$$base$$Register);
2991 %}
2992
2993 enc_class enc_stfs(RegF src, memory mem) %{
2994 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2995 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2996 %}
2997
2998 enc_class enc_stfd(RegF src, memory mem) %{
2999 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3000 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
3001 %}
3002
3003 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
3004 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
3005 encodeP_subNode *n_sub_base = new encodeP_subNode();
3006 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
3007 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode();
3008
3009 n_compare->add_req(n_region, n_src);
3010 n_compare->_opnds[0] = op_crx;
3011 n_compare->_opnds[1] = op_src;
3012 n_compare->_opnds[2] = new immL16Oper(0);
3013
3014 n_sub_base->add_req(n_region, n_src);
3015 n_sub_base->_opnds[0] = op_dst;
3016 n_sub_base->_opnds[1] = op_src;
3017 n_sub_base->_bottom_type = _bottom_type;
3018
3019 n_shift->add_req(n_region, n_sub_base);
3020 n_shift->_opnds[0] = op_dst;
3021 n_shift->_opnds[1] = op_dst;
3022 n_shift->_bottom_type = _bottom_type;
3023
3024 n_cond_set->add_req(n_region, n_compare, n_shift);
3025 n_cond_set->_opnds[0] = op_dst;
3026 n_cond_set->_opnds[1] = op_crx;
3027 n_cond_set->_opnds[2] = op_dst;
3028 n_cond_set->_bottom_type = _bottom_type;
3029
3030 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3031 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3032 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3033 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3034
3035 nodes->push(n_compare);
3036 nodes->push(n_sub_base);
3037 nodes->push(n_shift);
3038 nodes->push(n_cond_set);
3039
3040 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
3041 %}
3042
3043 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
3044
3045 encodeP_subNode *n1 = new encodeP_subNode();
3046 n1->add_req(n_region, n_src);
3047 n1->_opnds[0] = op_dst;
3048 n1->_opnds[1] = op_src;
3049 n1->_bottom_type = _bottom_type;
3050
3051 encodeP_shiftNode *n2 = new encodeP_shiftNode();
3052 n2->add_req(n_region, n1);
3053 n2->_opnds[0] = op_dst;
3054 n2->_opnds[1] = op_dst;
3055 n2->_bottom_type = _bottom_type;
3056 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3057 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3058
3059 nodes->push(n1);
3060 nodes->push(n2);
3061 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
3062 %}
3063
3064 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
3065 decodeN_shiftNode *n_shift = new decodeN_shiftNode();
3066 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
3067
3068 n_compare->add_req(n_region, n_src);
3069 n_compare->_opnds[0] = op_crx;
3070 n_compare->_opnds[1] = op_src;
3071 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
3072
3073 n_shift->add_req(n_region, n_src);
3074 n_shift->_opnds[0] = op_dst;
3075 n_shift->_opnds[1] = op_src;
3076 n_shift->_bottom_type = _bottom_type;
3077
3078 decodeN_addNode *n_add_base = new decodeN_addNode();
3079 n_add_base->add_req(n_region, n_shift);
3080 n_add_base->_opnds[0] = op_dst;
3081 n_add_base->_opnds[1] = op_dst;
3082 n_add_base->_bottom_type = _bottom_type;
3083
3084 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
3085 n_cond_set->add_req(n_region, n_compare, n_add_base);
3086 n_cond_set->_opnds[0] = op_dst;
3087 n_cond_set->_opnds[1] = op_crx;
3088 n_cond_set->_opnds[2] = op_dst;
3089 n_cond_set->_bottom_type = _bottom_type;
3090
3091 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3092 ra_->set_oop(n_cond_set, true);
3093
3094 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3095 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3096 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3097 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3098
3099 nodes->push(n_compare);
3100 nodes->push(n_shift);
3101 nodes->push(n_add_base);
3102 nodes->push(n_cond_set);
3103
3104 %}
3105
3106 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3107 decodeN_shiftNode *n1 = new decodeN_shiftNode();
3108 n1->add_req(n_region, n_src);
3109 n1->_opnds[0] = op_dst;
3110 n1->_opnds[1] = op_src;
3111 n1->_bottom_type = _bottom_type;
3112
3113 decodeN_addNode *n2 = new decodeN_addNode();
3114 n2->add_req(n_region, n1);
3115 n2->_opnds[0] = op_dst;
3116 n2->_opnds[1] = op_dst;
3117 n2->_bottom_type = _bottom_type;
3118 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3119 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3120
3121 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3122 ra_->set_oop(n2, true);
3123
3124 nodes->push(n1);
3125 nodes->push(n2);
3126 %}
3127
3128
3129 // This enc_class is needed so that scheduler gets proper
3130 // input mapping for latency computation.
3131 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
3132 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
3133 %}
3134
3135 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3136 Label done;
3137 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3138 __ li($dst$$Register, $zero$$constant);
3139 __ beq($crx$$CondRegister, done);
3140 __ li($dst$$Register, $notzero$$constant);
3141 __ bind(done);
3142 %}
3143
3144 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3145 Label done;
3146 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3147 __ li($dst$$Register, $zero$$constant);
3148 __ beq($crx$$CondRegister, done);
3149 __ li($dst$$Register, $notzero$$constant);
3150 __ bind(done);
3151 %}
3152
3153 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3154 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3155 Label done;
3156 __ bso($crx$$CondRegister, done);
3157 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3158 __ bind(done);
3159 %}
3160
3161 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
3162 Label done;
3163 __ bso($crx$$CondRegister, done);
3164 __ mffprd($dst$$Register, $src$$FloatRegister);
3165 __ bind(done);
3166 %}
3167
3168 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3169 Label d; // dummy
3170 __ bind(d);
3171 Label* p = ($lbl$$label);
3172 // `p' is `nullptr' when this encoding class is used only to
3173 // determine the size of the encoded instruction.
3174 Label& l = (nullptr == p)? d : *(p);
3175 int cc = $cmp$$cmpcode;
3176 int flags_reg = $crx$$reg;
3177 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3178 int bhint = Assembler::bhintNoHint;
3179
3180 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3181 if (_prob <= PROB_NEVER) {
3182 bhint = Assembler::bhintIsNotTaken;
3183 } else if (_prob >= PROB_ALWAYS) {
3184 bhint = Assembler::bhintIsTaken;
3185 }
3186 }
3187
3188 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3189 cc_to_biint(cc, flags_reg),
3190 l);
3191 %}
3192
3193 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3194 // The scheduler doesn't know about branch shortening, so we set the opcode
3195 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3196 Label d; // dummy
3197 __ bind(d);
3198 Label* p = ($lbl$$label);
3199 // `p' is `nullptr' when this encoding class is used only to
3200 // determine the size of the encoded instruction.
3201 Label& l = (nullptr == p)? d : *(p);
3202 int cc = $cmp$$cmpcode;
3203 int flags_reg = $crx$$reg;
3204 int bhint = Assembler::bhintNoHint;
3205
3206 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3207 if (_prob <= PROB_NEVER) {
3208 bhint = Assembler::bhintIsNotTaken;
3209 } else if (_prob >= PROB_ALWAYS) {
3210 bhint = Assembler::bhintIsTaken;
3211 }
3212 }
3213
3214 // Tell the conditional far branch to optimize itself when being relocated.
3215 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3216 cc_to_biint(cc, flags_reg),
3217 l,
3218 MacroAssembler::bc_far_optimize_on_relocate);
3219 %}
3220
3221 // Postalloc expand emitter for loading a replicatef float constant from
3222 // the method's TOC.
3223 // Enc_class needed as consttanttablebase is not supported by postalloc
3224 // expand.
3225 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3226 // Create new nodes.
3227
3228 // Make an operand with the bit pattern to load as float.
3229 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3230
3231 loadConLNodesTuple loadConLNodes =
3232 loadConLNodesTuple_create(ra_, n_toc, op_repl,
3233 ra_->get_reg_second(this), ra_->get_reg_first(this));
3234
3235 // Push new nodes.
3236 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3237 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3238
3239 assert(nodes->length() >= 1, "must have created at least 1 node");
3240 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3241 %}
3242
3243 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{
3244 // Create new nodes.
3245
3246 // Make an operand with the bit pattern to load as float.
3247 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3248 immI_0Oper *op_zero = new immI_0Oper(0);
3249
3250 loadConLReplicatedNodesTuple loadConLNodes =
3251 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero,
3252 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp),
3253 ra_->get_reg_second(this), ra_->get_reg_first(this));
3254
3255 // Push new nodes.
3256 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); }
3257 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); }
3258 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); }
3259 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); }
3260
3261 assert(nodes->length() >= 1, "must have created at least 1 node");
3262 %}
3263
3264 // This enc_class is needed so that scheduler gets proper
3265 // input mapping for latency computation.
3266 enc_class enc_poll(immI dst, iRegLdst poll) %{
3267 // Fake operand dst needed for PPC scheduler.
3268 assert($dst$$constant == 0x0, "dst must be 0x0");
3269
3270 // Mark the code position where the load from the safepoint
3271 // polling page was emitted as relocInfo::poll_type.
3272 __ relocate(relocInfo::poll_type);
3273 __ load_from_polling_page($poll$$Register);
3274 %}
3275
3276 // A Java static call or a runtime call.
3277 //
3278 // Branch-and-link relative to a trampoline.
3279 // The trampoline loads the target address and does a long branch to there.
3280 // In case we call java, the trampoline branches to a interpreter_stub
3281 // which loads the inline cache and the real call target from the constant pool.
3282 //
3283 // This basically looks like this:
3284 //
3285 // >>>> consts -+ -+
3286 // | |- offset1
3287 // [call target1] | <-+
3288 // [IC cache] |- offset2
3289 // [call target2] <--+
3290 //
3291 // <<<< consts
3292 // >>>> insts
3293 //
3294 // bl offset16 -+ -+ ??? // How many bits available?
3295 // | |
3296 // <<<< insts | |
3297 // >>>> stubs | |
3298 // | |- trampoline_stub_Reloc
3299 // trampoline stub: | <-+
3300 // r2 = toc |
3301 // r2 = [r2 + offset1] | // Load call target1 from const section
3302 // mtctr r2 |
3303 // bctr |- static_stub_Reloc
3304 // comp_to_interp_stub: <---+
3305 // r1 = toc
3306 // ICreg = [r1 + IC_offset] // Load IC from const section
3307 // r1 = [r1 + offset2] // Load call target2 from const section
3308 // mtctr r1
3309 // bctr
3310 //
3311 // <<<< stubs
3312 //
3313 // The call instruction in the code either
3314 // - Branches directly to a compiled method if the offset is encodable in instruction.
3315 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3316 // - Branches to the compiled_to_interp stub if the target is interpreted.
3317 //
3318 // Further there are three relocations from the loads to the constants in
3319 // the constant section.
3320 //
3321 // Usage of r1 and r2 in the stubs allows to distinguish them.
3322 enc_class enc_java_static_call(method meth) %{
3323 address entry_point = (address)$meth$$method;
3324
3325 if (!_method) {
3326 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3327 emit_call_with_trampoline_stub(masm, entry_point, relocInfo::runtime_call_type);
3328 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3329 } else {
3330 // Remember the offset not the address.
3331 const int start_offset = __ offset();
3332
3333 // The trampoline stub.
3334 // No entry point given, use the current pc.
3335 // Make sure branch fits into
3336 if (entry_point == nullptr) entry_point = __ pc();
3337
3338 // Put the entry point as a constant into the constant pool.
3339 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
3340 if (entry_point_toc_addr == nullptr) {
3341 ciEnv::current()->record_out_of_memory_failure();
3342 return;
3343 }
3344 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
3345
3346 // Emit the trampoline stub which will be related to the branch-and-link below.
3347 CallStubImpl::emit_trampoline_stub(masm, entry_point_toc_offset, start_offset);
3348 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3349 int method_index = resolved_method_index(masm);
3350 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3351 : static_call_Relocation::spec(method_index));
3352
3353 // The real call.
3354 // Note: At this point we do not have the address of the trampoline
3355 // stub, and the entry point might be too far away for bl, so __ pc()
3356 // serves as dummy and the bl will be patched later.
3357 __ set_inst_mark();
3358 __ bl(__ pc()); // Emits a relocation.
3359
3360 // The stub for call to interpreter.
3361 address stub = CompiledDirectCall::emit_to_interp_stub(masm);
3362 __ clear_inst_mark();
3363 if (stub == nullptr) {
3364 ciEnv::current()->record_failure("CodeCache is full");
3365 return;
3366 }
3367 }
3368 __ post_call_nop();
3369 %}
3370
3371 // Second node of expanded dynamic call - the call.
3372 enc_class enc_java_dynamic_call_sched(method meth) %{
3373 if (!ra_->C->output()->in_scratch_emit_size()) {
3374 // Create a call trampoline stub for the given method.
3375 const address entry_point = !($meth$$method) ? nullptr : (address)$meth$$method;
3376 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none);
3377 if (entry_point_const == nullptr) {
3378 ciEnv::current()->record_out_of_memory_failure();
3379 return;
3380 }
3381 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const);
3382 CallStubImpl::emit_trampoline_stub(masm, entry_point_const_toc_offset, __ offset());
3383 if (ra_->C->env()->failing()) { return; } // Code cache may be full.
3384
3385 // Build relocation at call site with ic position as data.
3386 assert((_load_ic_hi_node != nullptr && _load_ic_node == nullptr) ||
3387 (_load_ic_hi_node == nullptr && _load_ic_node != nullptr),
3388 "must have one, but can't have both");
3389 assert((_load_ic_hi_node != nullptr && _load_ic_hi_node->_cbuf_insts_offset != -1) ||
3390 (_load_ic_node != nullptr && _load_ic_node->_cbuf_insts_offset != -1),
3391 "must contain instruction offset");
3392 const int virtual_call_oop_addr_offset = _load_ic_hi_node != nullptr
3393 ? _load_ic_hi_node->_cbuf_insts_offset
3394 : _load_ic_node->_cbuf_insts_offset;
3395 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset);
3396 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr),
3397 "should be load from TOC");
3398 int method_index = resolved_method_index(masm);
3399 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
3400 }
3401
3402 // At this point I do not have the address of the trampoline stub,
3403 // and the entry point might be too far away for bl. Pc() serves
3404 // as dummy and bl will be patched later.
3405 __ bl((address) __ pc());
3406 __ post_call_nop();
3407 %}
3408
3409 // postalloc expand emitter for virtual calls.
3410 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{
3411
3412 // Create the nodes for loading the IC from the TOC.
3413 loadConLNodesTuple loadConLNodes_IC =
3414 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) Universe::non_oop_word()),
3415 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num));
3416
3417 // Create the call node.
3418 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode();
3419 call->_vtable_index = _vtable_index;
3420 call->_method = _method;
3421 call->_optimized_virtual = _optimized_virtual;
3422 call->_tf = _tf;
3423 call->_entry_point = _entry_point;
3424 call->_cnt = _cnt;
3425 call->_guaranteed_safepoint = true;
3426 call->_oop_map = _oop_map;
3427 call->_jvms = _jvms;
3428 call->_jvmadj = _jvmadj;
3429 call->_has_ea_local_in_scope = _has_ea_local_in_scope;
3430 call->_in_rms = _in_rms;
3431 call->_nesting = _nesting;
3432 call->_override_symbolic_info = _override_symbolic_info;
3433 call->_arg_escape = _arg_escape;
3434
3435 // New call needs all inputs of old call.
3436 // Req...
3437 for (uint i = 0; i < req(); ++i) {
3438 // The expanded node does not need toc any more.
3439 // Add the inline cache constant here instead. This expresses the
3440 // register of the inline cache must be live at the call.
3441 // Else we would have to adapt JVMState by -1.
3442 if (i == mach_constant_base_node_input()) {
3443 call->add_req(loadConLNodes_IC._last);
3444 } else {
3445 call->add_req(in(i));
3446 }
3447 }
3448 // ...as well as prec
3449 for (uint i = req(); i < len(); ++i) {
3450 call->add_prec(in(i));
3451 }
3452
3453 // Remember nodes loading the inline cache into r19.
3454 call->_load_ic_hi_node = loadConLNodes_IC._large_hi;
3455 call->_load_ic_node = loadConLNodes_IC._small;
3456
3457 // Operands for new nodes.
3458 call->_opnds[0] = _opnds[0];
3459 call->_opnds[1] = _opnds[1];
3460
3461 // Only the inline cache is associated with a register.
3462 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19");
3463
3464 // Push new nodes.
3465 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi);
3466 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last);
3467 nodes->push(call);
3468 %}
3469
3470 // Compound version of call dynamic
3471 // Toc is only passed so that it can be used in ins_encode statement.
3472 // In the code we have to use $constanttablebase.
3473 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
3474 int start_offset = __ offset();
3475
3476 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC;
3477
3478 int vtable_index = this->_vtable_index;
3479 if (vtable_index < 0) {
3480 // Must be invalid_vtable_index, not nonvirtual_vtable_index.
3481 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value");
3482 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode());
3483
3484 // Virtual call relocation will point to ic load.
3485 address virtual_call_meta_addr = __ pc();
3486 // Load a clear inline cache.
3487 AddressLiteral empty_ic((address) Universe::non_oop_word());
3488 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true);
3489 if (!success) {
3490 ciEnv::current()->record_out_of_memory_failure();
3491 return;
3492 }
3493 // CALL to fixup routine. Fixup routine uses ScopeDesc info
3494 // to determine who we intended to call.
3495 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr));
3496 emit_call_with_trampoline_stub(masm, (address)$meth$$method, relocInfo::none);
3497 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3498 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3499 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3500 } else {
3501 assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
3502 // Go thru the vtable. Get receiver klass. Receiver already
3503 // checked for non-null. If we'll go thru a C2I adapter, the
3504 // interpreter expects method in R19_method.
3505
3506 __ load_klass(R11_scratch1, R3);
3507
3508 int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index * vtableEntry::size_in_bytes();
3509 int v_off = entry_offset + in_bytes(vtableEntry::method_offset());
3510 __ li(R19_method, v_off);
3511 __ ldx(R19_method/*method*/, R19_method/*method offset*/, R11_scratch1/*class*/);
3512 // NOTE: for vtable dispatches, the vtable entry will never be
3513 // null. However it may very well end up in handle_wrong_method
3514 // if the method is abstract for the particular class.
3515 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method);
3516 // Call target. Either compiled code or C2I adapter.
3517 __ mtctr(R11_scratch1);
3518 __ bctrl();
3519 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3520 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3521 }
3522 __ post_call_nop();
3523 %}
3524
3525 // a runtime call
3526 enc_class enc_java_to_runtime_call (method meth) %{
3527 const address start_pc = __ pc();
3528
3529 #if defined(ABI_ELFv2)
3530 address entry= !($meth$$method) ? nullptr : (address)$meth$$method;
3531 __ call_c(entry, relocInfo::runtime_call_type);
3532 __ post_call_nop();
3533 #else
3534 // The function we're going to call.
3535 FunctionDescriptor fdtemp;
3536 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3537
3538 Register Rtoc = R12_scratch2;
3539 // Calculate the method's TOC.
3540 __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3541 // Put entry, env, toc into the constant pool, this needs up to 3 constant
3542 // pool entries; call_c_using_toc will optimize the call.
3543 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3544 if (!success) {
3545 ciEnv::current()->record_out_of_memory_failure();
3546 return;
3547 }
3548 __ post_call_nop();
3549 #endif
3550
3551 // Check the ret_addr_offset.
3552 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3553 "Fix constant in ret_addr_offset()");
3554 %}
3555
3556 // Move to ctr for leaf call.
3557 // This enc_class is needed so that scheduler gets proper
3558 // input mapping for latency computation.
3559 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3560 __ mtctr($src$$Register);
3561 %}
3562
3563 // Postalloc expand emitter for runtime leaf calls.
3564 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3565 loadConLNodesTuple loadConLNodes_Entry;
3566 #if defined(ABI_ELFv2)
3567 jlong entry_address = (jlong) this->entry_point();
3568 assert(entry_address, "need address here");
3569 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3570 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3571 #else
3572 // Get the struct that describes the function we are about to call.
3573 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3574 assert(fd, "need fd here");
3575 jlong entry_address = (jlong) fd->entry();
3576 // new nodes
3577 loadConLNodesTuple loadConLNodes_Env;
3578 loadConLNodesTuple loadConLNodes_Toc;
3579
3580 // Create nodes and operands for loading the entry point.
3581 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3582 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3583
3584
3585 // Create nodes and operands for loading the env pointer.
3586 if (fd->env() != nullptr) {
3587 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3588 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3589 } else {
3590 loadConLNodes_Env._large_hi = nullptr;
3591 loadConLNodes_Env._large_lo = nullptr;
3592 loadConLNodes_Env._small = nullptr;
3593 loadConLNodes_Env._last = new loadConL16Node();
3594 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3595 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3596 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3597 }
3598
3599 // Create nodes and operands for loading the Toc point.
3600 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3601 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3602 #endif // ABI_ELFv2
3603 // mtctr node
3604 MachNode *mtctr = new CallLeafDirect_mtctrNode();
3605
3606 assert(loadConLNodes_Entry._last != nullptr, "entry must exist");
3607 mtctr->add_req(nullptr, loadConLNodes_Entry._last);
3608
3609 mtctr->_opnds[0] = new iRegLdstOper();
3610 mtctr->_opnds[1] = new iRegLdstOper();
3611
3612 // call node
3613 MachCallLeafNode *call = new CallLeafDirectNode();
3614
3615 call->_opnds[0] = _opnds[0];
3616 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3617
3618 // Make the new call node look like the old one.
3619 call->_name = _name;
3620 call->_tf = _tf;
3621 call->_entry_point = _entry_point;
3622 call->_cnt = _cnt;
3623 call->_guaranteed_safepoint = false;
3624 call->_oop_map = _oop_map;
3625 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3626 call->_jvms = nullptr;
3627 call->_jvmadj = _jvmadj;
3628 call->_in_rms = _in_rms;
3629 call->_nesting = _nesting;
3630
3631 // New call needs all inputs of old call.
3632 // Req...
3633 for (uint i = 0; i < req(); ++i) {
3634 if (i != mach_constant_base_node_input()) {
3635 call->add_req(in(i));
3636 }
3637 }
3638
3639 // These must be reqired edges, as the registers are live up to
3640 // the call. Else the constants are handled as kills.
3641 call->add_req(mtctr);
3642 #if !defined(ABI_ELFv2)
3643 call->add_req(loadConLNodes_Env._last);
3644 call->add_req(loadConLNodes_Toc._last);
3645 #endif
3646
3647 // ...as well as prec
3648 for (uint i = req(); i < len(); ++i) {
3649 call->add_prec(in(i));
3650 }
3651
3652 // registers
3653 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3654
3655 // Insert the new nodes.
3656 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3657 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last);
3658 #if !defined(ABI_ELFv2)
3659 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi);
3660 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last);
3661 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi);
3662 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last);
3663 #endif
3664 nodes->push(mtctr);
3665 nodes->push(call);
3666 %}
3667 %}
3668
3669 //----------FRAME--------------------------------------------------------------
3670 // Definition of frame structure and management information.
3671
3672 frame %{
3673 // These two registers define part of the calling convention between
3674 // compiled code and the interpreter.
3675
3676 // Inline Cache Register or method for I2C.
3677 inline_cache_reg(R19); // R19_method
3678
3679 // Optional: name the operand used by cisc-spilling to access
3680 // [stack_pointer + offset].
3681 cisc_spilling_operand_name(indOffset);
3682
3683 // Number of stack slots consumed by a Monitor enter.
3684 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size));
3685
3686 // Compiled code's Frame Pointer.
3687 frame_pointer(R1); // R1_SP
3688
3689 stack_alignment(frame::alignment_in_bytes);
3690
3691 // Number of outgoing stack slots killed above the
3692 // out_preserve_stack_slots for calls to C. Supports the var-args
3693 // backing area for register parms.
3694 //
3695 varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3696
3697 // The after-PROLOG location of the return address. Location of
3698 // return address specifies a type (REG or STACK) and a number
3699 // representing the register number (i.e. - use a register name) or
3700 // stack slot.
3701 //
3702 // A: Link register is stored in stack slot ...
3703 // M: ... but it's in the caller's frame according to PPC-64 ABI.
3704 // J: Therefore, we make sure that the link register is also in R11_scratch1
3705 // at the end of the prolog.
3706 // B: We use R20, now.
3707 //return_addr(REG R20);
3708
3709 // G: After reading the comments made by all the luminaries on their
3710 // failure to tell the compiler where the return address really is,
3711 // I hardly dare to try myself. However, I'm convinced it's in slot
3712 // 4 what apparently works and saves us some spills.
3713 return_addr(STACK 4);
3714
3715 // Location of native (C/C++) and interpreter return values. This
3716 // is specified to be the same as Java. In the 32-bit VM, long
3717 // values are actually returned from native calls in O0:O1 and
3718 // returned to the interpreter in I0:I1. The copying to and from
3719 // the register pairs is done by the appropriate call and epilog
3720 // opcodes. This simplifies the register allocator.
3721 c_return_value %{
3722 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3723 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3724 "only return normal values");
3725 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3726 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3727 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3728 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3729 %}
3730
3731 // Location of compiled Java return values. Same as C
3732 return_value %{
3733 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3734 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3735 "only return normal values");
3736 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3737 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3738 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3739 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3740 %}
3741 %}
3742
3743
3744 //----------ATTRIBUTES---------------------------------------------------------
3745
3746 //----------Operand Attributes-------------------------------------------------
3747 op_attrib op_cost(1); // Required cost attribute.
3748
3749 //----------Instruction Attributes---------------------------------------------
3750
3751 // Cost attribute. required.
3752 ins_attrib ins_cost(DEFAULT_COST);
3753
3754 // Is this instruction a non-matching short branch variant of some
3755 // long branch? Not required.
3756 ins_attrib ins_short_branch(0);
3757
3758 ins_attrib ins_is_TrapBasedCheckNode(true);
3759
3760 // Number of constants.
3761 // This instruction uses the given number of constants
3762 // (optional attribute).
3763 // This is needed to determine in time whether the constant pool will
3764 // exceed 4000 entries. Before postalloc_expand the overall number of constants
3765 // is determined. It's also used to compute the constant pool size
3766 // in Output().
3767 ins_attrib ins_num_consts(0);
3768
3769 // Required alignment attribute (must be a power of 2) specifies the
3770 // alignment that some part of the instruction (not necessarily the
3771 // start) requires. If > 1, a compute_padding() function must be
3772 // provided for the instruction.
3773 ins_attrib ins_alignment(1);
3774
3775 // Enforce/prohibit rematerializations.
3776 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3777 // then rematerialization of that instruction is prohibited and the
3778 // instruction's value will be spilled if necessary.
3779 // Causes that MachNode::rematerialize() returns false.
3780 // - If an instruction is attributed with 'ins_should_rematerialize(true)'
3781 // then rematerialization should be enforced and a copy of the instruction
3782 // should be inserted if possible; rematerialization is not guaranteed.
3783 // Note: this may result in rematerializations in front of every use.
3784 // Causes that MachNode::rematerialize() can return true.
3785 // (optional attribute)
3786 ins_attrib ins_cannot_rematerialize(false);
3787 ins_attrib ins_should_rematerialize(false);
3788
3789 // Instruction has variable size depending on alignment.
3790 ins_attrib ins_variable_size_depending_on_alignment(false);
3791
3792 // Instruction is a nop.
3793 ins_attrib ins_is_nop(false);
3794
3795 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock).
3796 ins_attrib ins_use_mach_if_fast_lock_node(false);
3797
3798 // Field for the toc offset of a constant.
3799 //
3800 // This is needed if the toc offset is not encodable as an immediate in
3801 // the PPC load instruction. If so, the upper (hi) bits of the offset are
3802 // added to the toc, and from this a load with immediate is performed.
3803 // With postalloc expand, we get two nodes that require the same offset
3804 // but which don't know about each other. The offset is only known
3805 // when the constant is added to the constant pool during emitting.
3806 // It is generated in the 'hi'-node adding the upper bits, and saved
3807 // in this node. The 'lo'-node has a link to the 'hi'-node and reads
3808 // the offset from there when it gets encoded.
3809 ins_attrib ins_field_const_toc_offset(0);
3810 ins_attrib ins_field_const_toc_offset_hi_node(0);
3811
3812 // A field that can hold the instructions offset in the code buffer.
3813 // Set in the nodes emitter.
3814 ins_attrib ins_field_cbuf_insts_offset(-1);
3815
3816 // Fields for referencing a call's load-IC-node.
3817 // If the toc offset can not be encoded as an immediate in a load, we
3818 // use two nodes.
3819 ins_attrib ins_field_load_ic_hi_node(0);
3820 ins_attrib ins_field_load_ic_node(0);
3821
3822 // Whether this node is expanded during code emission into a sequence of
3823 // instructions and the first instruction can perform an implicit null check.
3824 ins_attrib ins_is_late_expanded_null_check_candidate(false);
3825
3826 //----------OPERANDS-----------------------------------------------------------
3827 // Operand definitions must precede instruction definitions for correct
3828 // parsing in the ADLC because operands constitute user defined types
3829 // which are used in instruction definitions.
3830 //
3831 // Formats are generated automatically for constants and base registers.
3832
3833 operand vecX() %{
3834 constraint(ALLOC_IN_RC(v_reg));
3835 match(VecX);
3836
3837 format %{ %}
3838 interface(REG_INTER);
3839 %}
3840
3841 //----------Simple Operands----------------------------------------------------
3842 // Immediate Operands
3843
3844 // Integer Immediate: 32-bit
3845 operand immI() %{
3846 match(ConI);
3847 op_cost(40);
3848 format %{ %}
3849 interface(CONST_INTER);
3850 %}
3851
3852 operand immI8() %{
3853 predicate(Assembler::is_simm(n->get_int(), 8));
3854 op_cost(0);
3855 match(ConI);
3856 format %{ %}
3857 interface(CONST_INTER);
3858 %}
3859
3860 // Integer Immediate: 16-bit
3861 operand immI16() %{
3862 predicate(Assembler::is_simm(n->get_int(), 16));
3863 op_cost(0);
3864 match(ConI);
3865 format %{ %}
3866 interface(CONST_INTER);
3867 %}
3868
3869 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000.
3870 operand immIhi16() %{
3871 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0));
3872 match(ConI);
3873 op_cost(0);
3874 format %{ %}
3875 interface(CONST_INTER);
3876 %}
3877
3878 // Integer Immediate: 32-bit immediate for prefixed addi and load/store.
3879 operand immI32() %{
3880 predicate(PowerArchitecturePPC64 >= 10);
3881 op_cost(0);
3882 match(ConI);
3883 format %{ %}
3884 interface(CONST_INTER);
3885 %}
3886
3887 operand immInegpow2() %{
3888 predicate(is_power_of_2(-(juint)(n->get_int())));
3889 match(ConI);
3890 op_cost(0);
3891 format %{ %}
3892 interface(CONST_INTER);
3893 %}
3894
3895 operand immIpow2minus1() %{
3896 predicate(is_power_of_2((juint)(n->get_int()) + 1u));
3897 match(ConI);
3898 op_cost(0);
3899 format %{ %}
3900 interface(CONST_INTER);
3901 %}
3902
3903 operand immIpowerOf2() %{
3904 predicate(is_power_of_2((juint)(n->get_int())));
3905 match(ConI);
3906 op_cost(0);
3907 format %{ %}
3908 interface(CONST_INTER);
3909 %}
3910
3911 // Unsigned Integer Immediate: the values 0-31
3912 operand uimmI5() %{
3913 predicate(Assembler::is_uimm(n->get_int(), 5));
3914 match(ConI);
3915 op_cost(0);
3916 format %{ %}
3917 interface(CONST_INTER);
3918 %}
3919
3920 // Unsigned Integer Immediate: 6-bit
3921 operand uimmI6() %{
3922 predicate(Assembler::is_uimm(n->get_int(), 6));
3923 match(ConI);
3924 op_cost(0);
3925 format %{ %}
3926 interface(CONST_INTER);
3927 %}
3928
3929 // Unsigned Integer Immediate: 6-bit int, greater than 32
3930 operand uimmI6_ge32() %{
3931 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32);
3932 match(ConI);
3933 op_cost(0);
3934 format %{ %}
3935 interface(CONST_INTER);
3936 %}
3937
3938 // Unsigned Integer Immediate: 15-bit
3939 operand uimmI15() %{
3940 predicate(Assembler::is_uimm(n->get_int(), 15));
3941 match(ConI);
3942 op_cost(0);
3943 format %{ %}
3944 interface(CONST_INTER);
3945 %}
3946
3947 // Unsigned Integer Immediate: 16-bit
3948 operand uimmI16() %{
3949 predicate(Assembler::is_uimm(n->get_int(), 16));
3950 match(ConI);
3951 op_cost(0);
3952 format %{ %}
3953 interface(CONST_INTER);
3954 %}
3955
3956 // constant 'int 0'.
3957 operand immI_0() %{
3958 predicate(n->get_int() == 0);
3959 match(ConI);
3960 op_cost(0);
3961 format %{ %}
3962 interface(CONST_INTER);
3963 %}
3964
3965 // constant 'int 1'.
3966 operand immI_1() %{
3967 predicate(n->get_int() == 1);
3968 match(ConI);
3969 op_cost(0);
3970 format %{ %}
3971 interface(CONST_INTER);
3972 %}
3973
3974 // constant 'int -1'.
3975 operand immI_minus1() %{
3976 predicate(n->get_int() == -1);
3977 match(ConI);
3978 op_cost(0);
3979 format %{ %}
3980 interface(CONST_INTER);
3981 %}
3982
3983 // int value 16.
3984 operand immI_16() %{
3985 predicate(n->get_int() == 16);
3986 match(ConI);
3987 op_cost(0);
3988 format %{ %}
3989 interface(CONST_INTER);
3990 %}
3991
3992 // int value 24.
3993 operand immI_24() %{
3994 predicate(n->get_int() == 24);
3995 match(ConI);
3996 op_cost(0);
3997 format %{ %}
3998 interface(CONST_INTER);
3999 %}
4000
4001 // Compressed oops constants
4002 // Pointer Immediate
4003 operand immN() %{
4004 match(ConN);
4005
4006 op_cost(10);
4007 format %{ %}
4008 interface(CONST_INTER);
4009 %}
4010
4011 // nullptr Pointer Immediate
4012 operand immN_0() %{
4013 predicate(n->get_narrowcon() == 0);
4014 match(ConN);
4015
4016 op_cost(0);
4017 format %{ %}
4018 interface(CONST_INTER);
4019 %}
4020
4021 // Compressed klass constants
4022 operand immNKlass() %{
4023 match(ConNKlass);
4024
4025 op_cost(0);
4026 format %{ %}
4027 interface(CONST_INTER);
4028 %}
4029
4030 // This operand can be used to avoid matching of an instruct
4031 // with chain rule.
4032 operand immNKlass_NM() %{
4033 match(ConNKlass);
4034 predicate(false);
4035 op_cost(0);
4036 format %{ %}
4037 interface(CONST_INTER);
4038 %}
4039
4040 // Pointer Immediate: 64-bit
4041 operand immP() %{
4042 match(ConP);
4043 op_cost(0);
4044 format %{ %}
4045 interface(CONST_INTER);
4046 %}
4047
4048 // Operand to avoid match of loadConP.
4049 // This operand can be used to avoid matching of an instruct
4050 // with chain rule.
4051 operand immP_NM() %{
4052 match(ConP);
4053 predicate(false);
4054 op_cost(0);
4055 format %{ %}
4056 interface(CONST_INTER);
4057 %}
4058
4059 // constant 'pointer 0'.
4060 operand immP_0() %{
4061 predicate(n->get_ptr() == 0);
4062 match(ConP);
4063 op_cost(0);
4064 format %{ %}
4065 interface(CONST_INTER);
4066 %}
4067
4068 // pointer 0x0 or 0x1
4069 operand immP_0or1() %{
4070 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
4071 match(ConP);
4072 op_cost(0);
4073 format %{ %}
4074 interface(CONST_INTER);
4075 %}
4076
4077 operand immL() %{
4078 match(ConL);
4079 op_cost(40);
4080 format %{ %}
4081 interface(CONST_INTER);
4082 %}
4083
4084 operand immLmax30() %{
4085 predicate((n->get_long() <= 30));
4086 match(ConL);
4087 op_cost(0);
4088 format %{ %}
4089 interface(CONST_INTER);
4090 %}
4091
4092 // Long Immediate: 16-bit
4093 operand immL16() %{
4094 predicate(Assembler::is_simm(n->get_long(), 16));
4095 match(ConL);
4096 op_cost(0);
4097 format %{ %}
4098 interface(CONST_INTER);
4099 %}
4100
4101 // Long Immediate: 16-bit, 4-aligned
4102 operand immL16Alg4() %{
4103 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
4104 match(ConL);
4105 op_cost(0);
4106 format %{ %}
4107 interface(CONST_INTER);
4108 %}
4109
4110 // Long Immediate: 16-bit, 16-aligned
4111 operand immL16Alg16() %{
4112 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0xf) == 0));
4113 match(ConL);
4114 op_cost(0);
4115 format %{ %}
4116 interface(CONST_INTER);
4117 %}
4118
4119 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
4120 operand immL32hi16() %{
4121 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L));
4122 match(ConL);
4123 op_cost(0);
4124 format %{ %}
4125 interface(CONST_INTER);
4126 %}
4127
4128 // Long Immediate: 32-bit
4129 operand immL32() %{
4130 predicate(Assembler::is_simm(n->get_long(), 32));
4131 match(ConL);
4132 op_cost(0);
4133 format %{ %}
4134 interface(CONST_INTER);
4135 %}
4136
4137 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store.
4138 operand immL34() %{
4139 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34));
4140 match(ConL);
4141 op_cost(0);
4142 format %{ %}
4143 interface(CONST_INTER);
4144 %}
4145
4146 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000.
4147 operand immLhighest16() %{
4148 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L);
4149 match(ConL);
4150 op_cost(0);
4151 format %{ %}
4152 interface(CONST_INTER);
4153 %}
4154
4155 operand immLnegpow2() %{
4156 predicate(is_power_of_2(-(julong)(n->get_long())));
4157 match(ConL);
4158 op_cost(0);
4159 format %{ %}
4160 interface(CONST_INTER);
4161 %}
4162
4163 operand immLpow2minus1() %{
4164 predicate(is_power_of_2((julong)(n->get_long()) + 1ull));
4165 match(ConL);
4166 op_cost(0);
4167 format %{ %}
4168 interface(CONST_INTER);
4169 %}
4170
4171 // constant 'long 0'.
4172 operand immL_0() %{
4173 predicate(n->get_long() == 0L);
4174 match(ConL);
4175 op_cost(0);
4176 format %{ %}
4177 interface(CONST_INTER);
4178 %}
4179
4180 // constat ' long -1'.
4181 operand immL_minus1() %{
4182 predicate(n->get_long() == -1L);
4183 match(ConL);
4184 op_cost(0);
4185 format %{ %}
4186 interface(CONST_INTER);
4187 %}
4188
4189 // Long Immediate: low 32-bit mask
4190 operand immL_32bits() %{
4191 predicate(n->get_long() == 0xFFFFFFFFL);
4192 match(ConL);
4193 op_cost(0);
4194 format %{ %}
4195 interface(CONST_INTER);
4196 %}
4197
4198 // Unsigned Long Immediate: 16-bit
4199 operand uimmL16() %{
4200 predicate(Assembler::is_uimm(n->get_long(), 16));
4201 match(ConL);
4202 op_cost(0);
4203 format %{ %}
4204 interface(CONST_INTER);
4205 %}
4206
4207 // Float Immediate
4208 operand immF() %{
4209 match(ConF);
4210 op_cost(40);
4211 format %{ %}
4212 interface(CONST_INTER);
4213 %}
4214
4215 // Float Immediate: +0.0f.
4216 operand immF_0() %{
4217 predicate(jint_cast(n->getf()) == 0);
4218 match(ConF);
4219
4220 op_cost(0);
4221 format %{ %}
4222 interface(CONST_INTER);
4223 %}
4224
4225 // Double Immediate
4226 operand immD() %{
4227 match(ConD);
4228 op_cost(40);
4229 format %{ %}
4230 interface(CONST_INTER);
4231 %}
4232
4233 // Double Immediate: +0.0d.
4234 operand immD_0() %{
4235 predicate(jlong_cast(n->getd()) == 0);
4236 match(ConD);
4237
4238 op_cost(0);
4239 format %{ %}
4240 interface(CONST_INTER);
4241 %}
4242
4243 // Integer Register Operands
4244 // Integer Destination Register
4245 // See definition of reg_class bits32_reg_rw.
4246 operand iRegIdst() %{
4247 constraint(ALLOC_IN_RC(bits32_reg_rw));
4248 match(RegI);
4249 match(rscratch1RegI);
4250 match(rscratch2RegI);
4251 match(rarg1RegI);
4252 match(rarg2RegI);
4253 match(rarg3RegI);
4254 match(rarg4RegI);
4255 format %{ %}
4256 interface(REG_INTER);
4257 %}
4258
4259 // Integer Source Register
4260 // See definition of reg_class bits32_reg_ro.
4261 operand iRegIsrc() %{
4262 constraint(ALLOC_IN_RC(bits32_reg_ro));
4263 match(RegI);
4264 match(rscratch1RegI);
4265 match(rscratch2RegI);
4266 match(rarg1RegI);
4267 match(rarg2RegI);
4268 match(rarg3RegI);
4269 match(rarg4RegI);
4270 format %{ %}
4271 interface(REG_INTER);
4272 %}
4273
4274 operand rscratch1RegI() %{
4275 constraint(ALLOC_IN_RC(rscratch1_bits32_reg));
4276 match(iRegIdst);
4277 format %{ %}
4278 interface(REG_INTER);
4279 %}
4280
4281 operand rscratch2RegI() %{
4282 constraint(ALLOC_IN_RC(rscratch2_bits32_reg));
4283 match(iRegIdst);
4284 format %{ %}
4285 interface(REG_INTER);
4286 %}
4287
4288 operand rarg1RegI() %{
4289 constraint(ALLOC_IN_RC(rarg1_bits32_reg));
4290 match(iRegIdst);
4291 format %{ %}
4292 interface(REG_INTER);
4293 %}
4294
4295 operand rarg2RegI() %{
4296 constraint(ALLOC_IN_RC(rarg2_bits32_reg));
4297 match(iRegIdst);
4298 format %{ %}
4299 interface(REG_INTER);
4300 %}
4301
4302 operand rarg3RegI() %{
4303 constraint(ALLOC_IN_RC(rarg3_bits32_reg));
4304 match(iRegIdst);
4305 format %{ %}
4306 interface(REG_INTER);
4307 %}
4308
4309 operand rarg4RegI() %{
4310 constraint(ALLOC_IN_RC(rarg4_bits32_reg));
4311 match(iRegIdst);
4312 format %{ %}
4313 interface(REG_INTER);
4314 %}
4315
4316 operand rarg1RegL() %{
4317 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4318 match(iRegLdst);
4319 format %{ %}
4320 interface(REG_INTER);
4321 %}
4322
4323 // Pointer Destination Register
4324 // See definition of reg_class bits64_reg_rw.
4325 operand iRegPdst() %{
4326 constraint(ALLOC_IN_RC(bits64_reg_rw));
4327 match(RegP);
4328 match(rscratch1RegP);
4329 match(rscratch2RegP);
4330 match(rarg1RegP);
4331 match(rarg2RegP);
4332 match(rarg3RegP);
4333 match(rarg4RegP);
4334 format %{ %}
4335 interface(REG_INTER);
4336 %}
4337
4338 // Pointer Destination Register
4339 // Operand not using r11 and r12 (killed in epilog).
4340 operand iRegPdstNoScratch() %{
4341 constraint(ALLOC_IN_RC(bits64_reg_leaf_call));
4342 match(RegP);
4343 match(rarg1RegP);
4344 match(rarg2RegP);
4345 match(rarg3RegP);
4346 match(rarg4RegP);
4347 format %{ %}
4348 interface(REG_INTER);
4349 %}
4350
4351 // Pointer Source Register
4352 // See definition of reg_class bits64_reg_ro.
4353 operand iRegPsrc() %{
4354 constraint(ALLOC_IN_RC(bits64_reg_ro));
4355 match(RegP);
4356 match(iRegPdst);
4357 match(rscratch1RegP);
4358 match(rscratch2RegP);
4359 match(rarg1RegP);
4360 match(rarg2RegP);
4361 match(rarg3RegP);
4362 match(rarg4RegP);
4363 match(rarg5RegP);
4364 match(rarg6RegP);
4365 match(threadRegP);
4366 format %{ %}
4367 interface(REG_INTER);
4368 %}
4369
4370 // Thread operand.
4371 operand threadRegP() %{
4372 constraint(ALLOC_IN_RC(thread_bits64_reg));
4373 match(iRegPdst);
4374 format %{ "R16" %}
4375 interface(REG_INTER);
4376 %}
4377
4378 operand rscratch1RegP() %{
4379 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4380 match(iRegPdst);
4381 format %{ "R11" %}
4382 interface(REG_INTER);
4383 %}
4384
4385 operand rscratch2RegP() %{
4386 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4387 match(iRegPdst);
4388 format %{ %}
4389 interface(REG_INTER);
4390 %}
4391
4392 operand rarg1RegP() %{
4393 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4394 match(iRegPdst);
4395 format %{ %}
4396 interface(REG_INTER);
4397 %}
4398
4399 operand rarg2RegP() %{
4400 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4401 match(iRegPdst);
4402 format %{ %}
4403 interface(REG_INTER);
4404 %}
4405
4406 operand rarg3RegP() %{
4407 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4408 match(iRegPdst);
4409 format %{ %}
4410 interface(REG_INTER);
4411 %}
4412
4413 operand rarg4RegP() %{
4414 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4415 match(iRegPdst);
4416 format %{ %}
4417 interface(REG_INTER);
4418 %}
4419
4420 operand rarg5RegP() %{
4421 constraint(ALLOC_IN_RC(rarg5_bits64_reg));
4422 match(iRegPdst);
4423 format %{ %}
4424 interface(REG_INTER);
4425 %}
4426
4427 operand rarg6RegP() %{
4428 constraint(ALLOC_IN_RC(rarg6_bits64_reg));
4429 match(iRegPdst);
4430 format %{ %}
4431 interface(REG_INTER);
4432 %}
4433
4434 operand iRegNsrc() %{
4435 constraint(ALLOC_IN_RC(bits32_reg_ro));
4436 match(RegN);
4437 match(iRegNdst);
4438
4439 format %{ %}
4440 interface(REG_INTER);
4441 %}
4442
4443 operand iRegNdst() %{
4444 constraint(ALLOC_IN_RC(bits32_reg_rw));
4445 match(RegN);
4446
4447 format %{ %}
4448 interface(REG_INTER);
4449 %}
4450
4451 // Long Destination Register
4452 // See definition of reg_class bits64_reg_rw.
4453 operand iRegLdst() %{
4454 constraint(ALLOC_IN_RC(bits64_reg_rw));
4455 match(RegL);
4456 match(rscratch1RegL);
4457 match(rscratch2RegL);
4458 format %{ %}
4459 interface(REG_INTER);
4460 %}
4461
4462 // Long Source Register
4463 // See definition of reg_class bits64_reg_ro.
4464 operand iRegLsrc() %{
4465 constraint(ALLOC_IN_RC(bits64_reg_ro));
4466 match(RegL);
4467 match(iRegLdst);
4468 match(rscratch1RegL);
4469 match(rscratch2RegL);
4470 format %{ %}
4471 interface(REG_INTER);
4472 %}
4473
4474 // Special operand for ConvL2I.
4475 operand iRegL2Isrc(iRegLsrc reg) %{
4476 constraint(ALLOC_IN_RC(bits64_reg_ro));
4477 match(ConvL2I reg);
4478 format %{ "ConvL2I($reg)" %}
4479 interface(REG_INTER)
4480 %}
4481
4482 operand rscratch1RegL() %{
4483 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4484 match(RegL);
4485 format %{ %}
4486 interface(REG_INTER);
4487 %}
4488
4489 operand rscratch2RegL() %{
4490 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4491 match(RegL);
4492 format %{ %}
4493 interface(REG_INTER);
4494 %}
4495
4496 // Condition Code Flag Registers
4497 operand flagsReg() %{
4498 constraint(ALLOC_IN_RC(int_flags));
4499 match(RegFlags);
4500 format %{ %}
4501 interface(REG_INTER);
4502 %}
4503
4504 operand flagsRegSrc() %{
4505 constraint(ALLOC_IN_RC(int_flags_ro));
4506 match(RegFlags);
4507 match(flagsReg);
4508 match(flagsRegCR0);
4509 format %{ %}
4510 interface(REG_INTER);
4511 %}
4512
4513 // Condition Code Flag Register CR0
4514 operand flagsRegCR0() %{
4515 constraint(ALLOC_IN_RC(int_flags_CR0));
4516 match(RegFlags);
4517 format %{ "CR0" %}
4518 interface(REG_INTER);
4519 %}
4520
4521 operand flagsRegCR1() %{
4522 constraint(ALLOC_IN_RC(int_flags_CR1));
4523 match(RegFlags);
4524 format %{ "CR1" %}
4525 interface(REG_INTER);
4526 %}
4527
4528 operand flagsRegCR6() %{
4529 constraint(ALLOC_IN_RC(int_flags_CR6));
4530 match(RegFlags);
4531 format %{ "CR6" %}
4532 interface(REG_INTER);
4533 %}
4534
4535 operand regCTR() %{
4536 constraint(ALLOC_IN_RC(ctr_reg));
4537 // RegFlags should work. Introducing a RegSpecial type would cause a
4538 // lot of changes.
4539 match(RegFlags);
4540 format %{"SR_CTR" %}
4541 interface(REG_INTER);
4542 %}
4543
4544 operand regD() %{
4545 constraint(ALLOC_IN_RC(dbl_reg));
4546 match(RegD);
4547 format %{ %}
4548 interface(REG_INTER);
4549 %}
4550
4551 operand regF() %{
4552 constraint(ALLOC_IN_RC(flt_reg));
4553 match(RegF);
4554 format %{ %}
4555 interface(REG_INTER);
4556 %}
4557
4558 // Special Registers
4559
4560 // Method Register
4561 operand inline_cache_regP(iRegPdst reg) %{
4562 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg
4563 match(reg);
4564 format %{ %}
4565 interface(REG_INTER);
4566 %}
4567
4568 // Operands to remove register moves in unscaled mode.
4569 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4570 operand iRegP2N(iRegPsrc reg) %{
4571 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0);
4572 constraint(ALLOC_IN_RC(bits64_reg_ro));
4573 match(EncodeP reg);
4574 format %{ "$reg" %}
4575 interface(REG_INTER)
4576 %}
4577
4578 operand iRegN2P(iRegNsrc reg) %{
4579 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4580 constraint(ALLOC_IN_RC(bits32_reg_ro));
4581 match(DecodeN reg);
4582 format %{ "$reg" %}
4583 interface(REG_INTER)
4584 %}
4585
4586 operand iRegN2P_klass(iRegNsrc reg) %{
4587 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4588 constraint(ALLOC_IN_RC(bits32_reg_ro));
4589 match(DecodeNKlass reg);
4590 format %{ "$reg" %}
4591 interface(REG_INTER)
4592 %}
4593
4594 //----------Complex Operands---------------------------------------------------
4595 // Indirect Memory Reference
4596 operand indirect(iRegPsrc reg) %{
4597 constraint(ALLOC_IN_RC(bits64_reg_ro));
4598 match(reg);
4599 op_cost(100);
4600 format %{ "[$reg]" %}
4601 interface(MEMORY_INTER) %{
4602 base($reg);
4603 index(0x0);
4604 scale(0x0);
4605 disp(0x0);
4606 %}
4607 %}
4608
4609 // Indirect with Offset
4610 operand indOffset16(iRegPsrc reg, immL16 offset) %{
4611 constraint(ALLOC_IN_RC(bits64_reg_ro));
4612 match(AddP reg offset);
4613 op_cost(100);
4614 format %{ "[$reg + $offset]" %}
4615 interface(MEMORY_INTER) %{
4616 base($reg);
4617 index(0x0);
4618 scale(0x0);
4619 disp($offset);
4620 %}
4621 %}
4622
4623 // Indirect with 4-aligned Offset
4624 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{
4625 constraint(ALLOC_IN_RC(bits64_reg_ro));
4626 match(AddP reg offset);
4627 op_cost(100);
4628 format %{ "[$reg + $offset]" %}
4629 interface(MEMORY_INTER) %{
4630 base($reg);
4631 index(0x0);
4632 scale(0x0);
4633 disp($offset);
4634 %}
4635 %}
4636
4637 // Indirect with 16-aligned Offset
4638 operand indOffset16Alg16(iRegPsrc reg, immL16Alg16 offset) %{
4639 constraint(ALLOC_IN_RC(bits64_reg_ro));
4640 match(AddP reg offset);
4641 op_cost(100);
4642 format %{ "[$reg + $offset]" %}
4643 interface(MEMORY_INTER) %{
4644 base($reg);
4645 index(0x0);
4646 scale(0x0);
4647 disp($offset);
4648 %}
4649 %}
4650
4651 //----------Complex Operands for Compressed OOPs-------------------------------
4652 // Compressed OOPs with narrow_oop_shift == 0.
4653
4654 // Indirect Memory Reference, compressed OOP
4655 operand indirectNarrow(iRegNsrc reg) %{
4656 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4657 constraint(ALLOC_IN_RC(bits64_reg_ro));
4658 match(DecodeN reg);
4659 op_cost(100);
4660 format %{ "[$reg]" %}
4661 interface(MEMORY_INTER) %{
4662 base($reg);
4663 index(0x0);
4664 scale(0x0);
4665 disp(0x0);
4666 %}
4667 %}
4668
4669 operand indirectNarrow_klass(iRegNsrc reg) %{
4670 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4671 constraint(ALLOC_IN_RC(bits64_reg_ro));
4672 match(DecodeNKlass reg);
4673 op_cost(100);
4674 format %{ "[$reg]" %}
4675 interface(MEMORY_INTER) %{
4676 base($reg);
4677 index(0x0);
4678 scale(0x0);
4679 disp(0x0);
4680 %}
4681 %}
4682
4683 // Indirect with Offset, compressed OOP
4684 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4685 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4686 constraint(ALLOC_IN_RC(bits64_reg_ro));
4687 match(AddP (DecodeN reg) offset);
4688 op_cost(100);
4689 format %{ "[$reg + $offset]" %}
4690 interface(MEMORY_INTER) %{
4691 base($reg);
4692 index(0x0);
4693 scale(0x0);
4694 disp($offset);
4695 %}
4696 %}
4697
4698 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4699 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4700 constraint(ALLOC_IN_RC(bits64_reg_ro));
4701 match(AddP (DecodeNKlass reg) offset);
4702 op_cost(100);
4703 format %{ "[$reg + $offset]" %}
4704 interface(MEMORY_INTER) %{
4705 base($reg);
4706 index(0x0);
4707 scale(0x0);
4708 disp($offset);
4709 %}
4710 %}
4711
4712 // Indirect with 4-aligned Offset, compressed OOP
4713 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4714 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4715 constraint(ALLOC_IN_RC(bits64_reg_ro));
4716 match(AddP (DecodeN reg) offset);
4717 op_cost(100);
4718 format %{ "[$reg + $offset]" %}
4719 interface(MEMORY_INTER) %{
4720 base($reg);
4721 index(0x0);
4722 scale(0x0);
4723 disp($offset);
4724 %}
4725 %}
4726
4727 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4728 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4729 constraint(ALLOC_IN_RC(bits64_reg_ro));
4730 match(AddP (DecodeNKlass reg) offset);
4731 op_cost(100);
4732 format %{ "[$reg + $offset]" %}
4733 interface(MEMORY_INTER) %{
4734 base($reg);
4735 index(0x0);
4736 scale(0x0);
4737 disp($offset);
4738 %}
4739 %}
4740
4741 //----------Special Memory Operands--------------------------------------------
4742 // Stack Slot Operand
4743 //
4744 // This operand is used for loading and storing temporary values on
4745 // the stack where a match requires a value to flow through memory.
4746 operand stackSlotI(sRegI reg) %{
4747 constraint(ALLOC_IN_RC(stack_slots));
4748 op_cost(100);
4749 //match(RegI);
4750 format %{ "[sp+$reg]" %}
4751 interface(MEMORY_INTER) %{
4752 base(0x1); // R1_SP
4753 index(0x0);
4754 scale(0x0);
4755 disp($reg); // Stack Offset
4756 %}
4757 %}
4758
4759 operand stackSlotL(sRegL reg) %{
4760 constraint(ALLOC_IN_RC(stack_slots));
4761 op_cost(100);
4762 //match(RegL);
4763 format %{ "[sp+$reg]" %}
4764 interface(MEMORY_INTER) %{
4765 base(0x1); // R1_SP
4766 index(0x0);
4767 scale(0x0);
4768 disp($reg); // Stack Offset
4769 %}
4770 %}
4771
4772 operand stackSlotP(sRegP reg) %{
4773 constraint(ALLOC_IN_RC(stack_slots));
4774 op_cost(100);
4775 //match(RegP);
4776 format %{ "[sp+$reg]" %}
4777 interface(MEMORY_INTER) %{
4778 base(0x1); // R1_SP
4779 index(0x0);
4780 scale(0x0);
4781 disp($reg); // Stack Offset
4782 %}
4783 %}
4784
4785 operand stackSlotF(sRegF reg) %{
4786 constraint(ALLOC_IN_RC(stack_slots));
4787 op_cost(100);
4788 //match(RegF);
4789 format %{ "[sp+$reg]" %}
4790 interface(MEMORY_INTER) %{
4791 base(0x1); // R1_SP
4792 index(0x0);
4793 scale(0x0);
4794 disp($reg); // Stack Offset
4795 %}
4796 %}
4797
4798 operand stackSlotD(sRegD reg) %{
4799 constraint(ALLOC_IN_RC(stack_slots));
4800 op_cost(100);
4801 //match(RegD);
4802 format %{ "[sp+$reg]" %}
4803 interface(MEMORY_INTER) %{
4804 base(0x1); // R1_SP
4805 index(0x0);
4806 scale(0x0);
4807 disp($reg); // Stack Offset
4808 %}
4809 %}
4810
4811 // Operands for expressing Control Flow
4812 // NOTE: Label is a predefined operand which should not be redefined in
4813 // the AD file. It is generically handled within the ADLC.
4814
4815 //----------Conditional Branch Operands----------------------------------------
4816 // Comparison Op
4817 //
4818 // This is the operation of the comparison, and is limited to the
4819 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE
4820 // (!=).
4821 //
4822 // Other attributes of the comparison, such as unsignedness, are specified
4823 // by the comparison instruction that sets a condition code flags register.
4824 // That result is represented by a flags operand whose subtype is appropriate
4825 // to the unsignedness (etc.) of the comparison.
4826 //
4827 // Later, the instruction which matches both the Comparison Op (a Bool) and
4828 // the flags (produced by the Cmp) specifies the coding of the comparison op
4829 // by matching a specific subtype of Bool operand below.
4830
4831 // When used for floating point comparisons: unordered same as less.
4832 operand cmpOp() %{
4833 match(Bool);
4834 format %{ "" %}
4835 interface(COND_INTER) %{
4836 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'.
4837 // BO & BI
4838 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4839 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4840 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4841 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4842 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4843 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4844 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4845 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4846 %}
4847 %}
4848
4849 //----------OPERAND CLASSES----------------------------------------------------
4850 // Operand Classes are groups of operands that are used to simplify
4851 // instruction definitions by not requiring the AD writer to specify
4852 // separate instructions for every form of operand when the
4853 // instruction accepts multiple operand types with the same basic
4854 // encoding and format. The classic case of this is memory operands.
4855 // Indirect is not included since its use is limited to Compare & Swap.
4856
4857 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4858 // Memory operand where offsets are 4-aligned. Required for ld, std.
4859 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4860 opclass memoryAlg16(indirect, indOffset16Alg16);
4861 opclass indirectMemory(indirect, indirectNarrow);
4862
4863 // Special opclass for I and ConvL2I.
4864 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4865
4866 // Operand classes to match encode and decode. iRegN_P2N is only used
4867 // for storeN. I have never seen an encode node elsewhere.
4868 opclass iRegN_P2N(iRegNsrc, iRegP2N);
4869 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4870
4871 //----------PIPELINE-----------------------------------------------------------
4872
4873 pipeline %{
4874
4875 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4876 // J. Res. & Dev., No. 1, Jan. 2002.
4877
4878 //----------ATTRIBUTES---------------------------------------------------------
4879 attributes %{
4880
4881 // Power4 instructions are of fixed length.
4882 fixed_size_instructions;
4883
4884 // TODO: if `bundle' means number of instructions fetched
4885 // per cycle, this is 8. If `bundle' means Power4 `group', that is
4886 // max instructions issued per cycle, this is 5.
4887 max_instructions_per_bundle = 8;
4888
4889 // A Power4 instruction is 4 bytes long.
4890 instruction_unit_size = 4;
4891
4892 // The Power4 processor fetches 64 bytes...
4893 instruction_fetch_unit_size = 64;
4894
4895 // ...in one line
4896 instruction_fetch_units = 1
4897 %}
4898
4899 //----------RESOURCES----------------------------------------------------------
4900 // Resources are the functional units available to the machine
4901 resources(
4902 PPC_BR, // branch unit
4903 PPC_CR, // condition unit
4904 PPC_FX1, // integer arithmetic unit 1
4905 PPC_FX2, // integer arithmetic unit 2
4906 PPC_LDST1, // load/store unit 1
4907 PPC_LDST2, // load/store unit 2
4908 PPC_FP1, // float arithmetic unit 1
4909 PPC_FP2, // float arithmetic unit 2
4910 PPC_LDST = PPC_LDST1 | PPC_LDST2,
4911 PPC_FX = PPC_FX1 | PPC_FX2,
4912 PPC_FP = PPC_FP1 | PPC_FP2
4913 );
4914
4915 //----------PIPELINE DESCRIPTION-----------------------------------------------
4916 // Pipeline Description specifies the stages in the machine's pipeline
4917 pipe_desc(
4918 // Power4 longest pipeline path
4919 PPC_IF, // instruction fetch
4920 PPC_IC,
4921 //PPC_BP, // branch prediction
4922 PPC_D0, // decode
4923 PPC_D1, // decode
4924 PPC_D2, // decode
4925 PPC_D3, // decode
4926 PPC_Xfer1,
4927 PPC_GD, // group definition
4928 PPC_MP, // map
4929 PPC_ISS, // issue
4930 PPC_RF, // resource fetch
4931 PPC_EX1, // execute (all units)
4932 PPC_EX2, // execute (FP, LDST)
4933 PPC_EX3, // execute (FP, LDST)
4934 PPC_EX4, // execute (FP)
4935 PPC_EX5, // execute (FP)
4936 PPC_EX6, // execute (FP)
4937 PPC_WB, // write back
4938 PPC_Xfer2,
4939 PPC_CP
4940 );
4941
4942 //----------PIPELINE CLASSES---------------------------------------------------
4943 // Pipeline Classes describe the stages in which input and output are
4944 // referenced by the hardware pipeline.
4945
4946 // Simple pipeline classes.
4947
4948 // Default pipeline class.
4949 pipe_class pipe_class_default() %{
4950 single_instruction;
4951 fixed_latency(2);
4952 %}
4953
4954 // Pipeline class for empty instructions.
4955 pipe_class pipe_class_empty() %{
4956 single_instruction;
4957 fixed_latency(0);
4958 %}
4959
4960 // Pipeline class for compares.
4961 pipe_class pipe_class_compare() %{
4962 single_instruction;
4963 fixed_latency(16);
4964 %}
4965
4966 // Pipeline class for traps.
4967 pipe_class pipe_class_trap() %{
4968 single_instruction;
4969 fixed_latency(100);
4970 %}
4971
4972 // Pipeline class for memory operations.
4973 pipe_class pipe_class_memory() %{
4974 single_instruction;
4975 fixed_latency(16);
4976 %}
4977
4978 // Pipeline class for call.
4979 pipe_class pipe_class_call() %{
4980 single_instruction;
4981 fixed_latency(100);
4982 %}
4983
4984 // Define the class for the Nop node.
4985 define %{
4986 MachNop = pipe_class_default;
4987 %}
4988
4989 %}
4990
4991 //----------INSTRUCTIONS-------------------------------------------------------
4992
4993 // Naming of instructions:
4994 // opA_operB / opA_operB_operC:
4995 // Operation 'op' with one or two source operands 'oper'. Result
4996 // type is A, source operand types are B and C.
4997 // Iff A == B == C, B and C are left out.
4998 //
4999 // The instructions are ordered according to the following scheme:
5000 // - loads
5001 // - load constants
5002 // - prefetch
5003 // - store
5004 // - encode/decode
5005 // - membar
5006 // - conditional moves
5007 // - compare & swap
5008 // - arithmetic and logic operations
5009 // * int: Add, Sub, Mul, Div, Mod
5010 // * int: lShift, arShift, urShift, rot
5011 // * float: Add, Sub, Mul, Div
5012 // * and, or, xor ...
5013 // - register moves: float <-> int, reg <-> stack, repl
5014 // - cast (high level type cast, XtoP, castPP, castII, not_null etc.
5015 // - conv (low level type cast requiring bit changes (sign extend etc)
5016 // - compares, range & zero checks.
5017 // - branches
5018 // - complex operations, intrinsics, min, max, replicate
5019 // - lock
5020 // - Calls
5021 //
5022 // If there are similar instructions with different types they are sorted:
5023 // int before float
5024 // small before big
5025 // signed before unsigned
5026 // e.g., loadS before loadUS before loadI before loadF.
5027
5028
5029 //----------Load/Store Instructions--------------------------------------------
5030
5031 //----------Load Instructions--------------------------------------------------
5032
5033 // Converts byte to int.
5034 // As convB2I_reg, but without match rule. The match rule of convB2I_reg
5035 // reuses the 'amount' operand, but adlc expects that operand specification
5036 // and operands in match rule are equivalent.
5037 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
5038 effect(DEF dst, USE src);
5039 format %{ "EXTSB $dst, $src \t// byte->int" %}
5040 size(4);
5041 ins_encode %{
5042 __ extsb($dst$$Register, $src$$Register);
5043 %}
5044 ins_pipe(pipe_class_default);
5045 %}
5046
5047 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{
5048 // match-rule, false predicate
5049 match(Set dst (LoadB mem));
5050 predicate(false);
5051
5052 format %{ "LBZ $dst, $mem" %}
5053 size(4);
5054 ins_encode( enc_lbz(dst, mem) );
5055 ins_pipe(pipe_class_memory);
5056 %}
5057
5058 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{
5059 // match-rule, false predicate
5060 match(Set dst (LoadB mem));
5061 predicate(false);
5062
5063 format %{ "LBZ $dst, $mem\n\t"
5064 "TWI $dst\n\t"
5065 "ISYNC" %}
5066 size(12);
5067 ins_encode( enc_lbz_ac(dst, mem) );
5068 ins_pipe(pipe_class_memory);
5069 %}
5070
5071 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
5072 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{
5073 match(Set dst (LoadB mem));
5074 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5075 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5076 expand %{
5077 iRegIdst tmp;
5078 loadUB_indirect(tmp, mem);
5079 convB2I_reg_2(dst, tmp);
5080 %}
5081 %}
5082
5083 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{
5084 match(Set dst (LoadB mem));
5085 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
5086 expand %{
5087 iRegIdst tmp;
5088 loadUB_indirect_ac(tmp, mem);
5089 convB2I_reg_2(dst, tmp);
5090 %}
5091 %}
5092
5093 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{
5094 // match-rule, false predicate
5095 match(Set dst (LoadB mem));
5096 predicate(false);
5097
5098 format %{ "LBZ $dst, $mem" %}
5099 size(4);
5100 ins_encode( enc_lbz(dst, mem) );
5101 ins_pipe(pipe_class_memory);
5102 %}
5103
5104 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{
5105 // match-rule, false predicate
5106 match(Set dst (LoadB mem));
5107 predicate(false);
5108
5109 format %{ "LBZ $dst, $mem\n\t"
5110 "TWI $dst\n\t"
5111 "ISYNC" %}
5112 size(12);
5113 ins_encode( enc_lbz_ac(dst, mem) );
5114 ins_pipe(pipe_class_memory);
5115 %}
5116
5117 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
5118 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{
5119 match(Set dst (LoadB mem));
5120 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5121 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5122
5123 expand %{
5124 iRegIdst tmp;
5125 loadUB_indOffset16(tmp, mem);
5126 convB2I_reg_2(dst, tmp);
5127 %}
5128 %}
5129
5130 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{
5131 match(Set dst (LoadB mem));
5132 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
5133
5134 expand %{
5135 iRegIdst tmp;
5136 loadUB_indOffset16_ac(tmp, mem);
5137 convB2I_reg_2(dst, tmp);
5138 %}
5139 %}
5140
5141 // Load Unsigned Byte (8bit UNsigned) into an int reg.
5142 instruct loadUB(iRegIdst dst, memory mem) %{
5143 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5144 match(Set dst (LoadUB mem));
5145 ins_cost(MEMORY_REF_COST);
5146
5147 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %}
5148 size(4);
5149 ins_encode( enc_lbz(dst, mem) );
5150 ins_pipe(pipe_class_memory);
5151 %}
5152
5153 // Load Unsigned Byte (8bit UNsigned) acquire.
5154 instruct loadUB_ac(iRegIdst dst, memory mem) %{
5155 match(Set dst (LoadUB mem));
5156 ins_cost(3*MEMORY_REF_COST);
5157
5158 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t"
5159 "TWI $dst\n\t"
5160 "ISYNC" %}
5161 size(12);
5162 ins_encode( enc_lbz_ac(dst, mem) );
5163 ins_pipe(pipe_class_memory);
5164 %}
5165
5166 // Load Unsigned Byte (8bit UNsigned) into a Long Register.
5167 instruct loadUB2L(iRegLdst dst, memory mem) %{
5168 match(Set dst (ConvI2L (LoadUB mem)));
5169 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5170 ins_cost(MEMORY_REF_COST);
5171
5172 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %}
5173 size(4);
5174 ins_encode( enc_lbz(dst, mem) );
5175 ins_pipe(pipe_class_memory);
5176 %}
5177
5178 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{
5179 match(Set dst (ConvI2L (LoadUB mem)));
5180 ins_cost(3*MEMORY_REF_COST);
5181
5182 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t"
5183 "TWI $dst\n\t"
5184 "ISYNC" %}
5185 size(12);
5186 ins_encode( enc_lbz_ac(dst, mem) );
5187 ins_pipe(pipe_class_memory);
5188 %}
5189
5190 // Load Short (16bit signed)
5191 instruct loadS(iRegIdst dst, memory mem) %{
5192 match(Set dst (LoadS mem));
5193 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5194 ins_cost(MEMORY_REF_COST);
5195
5196 format %{ "LHA $dst, $mem" %}
5197 size(4);
5198 ins_encode %{
5199 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5200 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
5201 %}
5202 ins_pipe(pipe_class_memory);
5203 %}
5204
5205 // Load Short (16bit signed) acquire.
5206 instruct loadS_ac(iRegIdst dst, memory mem) %{
5207 match(Set dst (LoadS mem));
5208 ins_cost(3*MEMORY_REF_COST);
5209
5210 format %{ "LHA $dst, $mem\t acquire\n\t"
5211 "TWI $dst\n\t"
5212 "ISYNC" %}
5213 size(12);
5214 ins_encode %{
5215 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5216 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
5217 __ twi_0($dst$$Register);
5218 __ isync();
5219 %}
5220 ins_pipe(pipe_class_memory);
5221 %}
5222
5223 // Load Char (16bit unsigned)
5224 instruct loadUS(iRegIdst dst, memory mem) %{
5225 match(Set dst (LoadUS mem));
5226 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5227 ins_cost(MEMORY_REF_COST);
5228
5229 format %{ "LHZ $dst, $mem" %}
5230 size(4);
5231 ins_encode( enc_lhz(dst, mem) );
5232 ins_pipe(pipe_class_memory);
5233 %}
5234
5235 // Load Char (16bit unsigned) acquire.
5236 instruct loadUS_ac(iRegIdst dst, memory mem) %{
5237 match(Set dst (LoadUS mem));
5238 ins_cost(3*MEMORY_REF_COST);
5239
5240 format %{ "LHZ $dst, $mem \t// acquire\n\t"
5241 "TWI $dst\n\t"
5242 "ISYNC" %}
5243 size(12);
5244 ins_encode( enc_lhz_ac(dst, mem) );
5245 ins_pipe(pipe_class_memory);
5246 %}
5247
5248 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register.
5249 instruct loadUS2L(iRegLdst dst, memory mem) %{
5250 match(Set dst (ConvI2L (LoadUS mem)));
5251 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5252 ins_cost(MEMORY_REF_COST);
5253
5254 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %}
5255 size(4);
5256 ins_encode( enc_lhz(dst, mem) );
5257 ins_pipe(pipe_class_memory);
5258 %}
5259
5260 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire.
5261 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{
5262 match(Set dst (ConvI2L (LoadUS mem)));
5263 ins_cost(3*MEMORY_REF_COST);
5264
5265 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t"
5266 "TWI $dst\n\t"
5267 "ISYNC" %}
5268 size(12);
5269 ins_encode( enc_lhz_ac(dst, mem) );
5270 ins_pipe(pipe_class_memory);
5271 %}
5272
5273 // Load Integer.
5274 instruct loadI(iRegIdst dst, memory mem) %{
5275 match(Set dst (LoadI mem));
5276 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5277 ins_cost(MEMORY_REF_COST);
5278
5279 format %{ "LWZ $dst, $mem" %}
5280 size(4);
5281 ins_encode( enc_lwz(dst, mem) );
5282 ins_pipe(pipe_class_memory);
5283 %}
5284
5285 // Load Integer acquire.
5286 instruct loadI_ac(iRegIdst dst, memory mem) %{
5287 match(Set dst (LoadI mem));
5288 ins_cost(3*MEMORY_REF_COST);
5289
5290 format %{ "LWZ $dst, $mem \t// load acquire\n\t"
5291 "TWI $dst\n\t"
5292 "ISYNC" %}
5293 size(12);
5294 ins_encode( enc_lwz_ac(dst, mem) );
5295 ins_pipe(pipe_class_memory);
5296 %}
5297
5298 // Match loading integer and casting it to unsigned int in
5299 // long register.
5300 // LoadI + ConvI2L + AndL 0xffffffff.
5301 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
5302 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5303 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered());
5304 ins_cost(MEMORY_REF_COST);
5305
5306 format %{ "LWZ $dst, $mem \t// zero-extend to long" %}
5307 size(4);
5308 ins_encode( enc_lwz(dst, mem) );
5309 ins_pipe(pipe_class_memory);
5310 %}
5311
5312 // Match loading integer and casting it to long.
5313 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
5314 match(Set dst (ConvI2L (LoadI mem)));
5315 predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5316 ins_cost(MEMORY_REF_COST);
5317
5318 format %{ "LWA $dst, $mem \t// loadI2L" %}
5319 size(4);
5320 ins_encode %{
5321 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5322 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5323 %}
5324 ins_pipe(pipe_class_memory);
5325 %}
5326
5327 // Match loading integer and casting it to long - acquire.
5328 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
5329 match(Set dst (ConvI2L (LoadI mem)));
5330 ins_cost(3*MEMORY_REF_COST);
5331
5332 format %{ "LWA $dst, $mem \t// loadI2L acquire"
5333 "TWI $dst\n\t"
5334 "ISYNC" %}
5335 size(12);
5336 ins_encode %{
5337 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5338 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5339 __ twi_0($dst$$Register);
5340 __ isync();
5341 %}
5342 ins_pipe(pipe_class_memory);
5343 %}
5344
5345 // Load Long - aligned
5346 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{
5347 match(Set dst (LoadL mem));
5348 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5349 ins_cost(MEMORY_REF_COST);
5350
5351 format %{ "LD $dst, $mem \t// long" %}
5352 size(4);
5353 ins_encode( enc_ld(dst, mem) );
5354 ins_pipe(pipe_class_memory);
5355 %}
5356
5357 // Load Long - aligned acquire.
5358 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{
5359 match(Set dst (LoadL mem));
5360 ins_cost(3*MEMORY_REF_COST);
5361
5362 format %{ "LD $dst, $mem \t// long acquire\n\t"
5363 "TWI $dst\n\t"
5364 "ISYNC" %}
5365 size(12);
5366 ins_encode( enc_ld_ac(dst, mem) );
5367 ins_pipe(pipe_class_memory);
5368 %}
5369
5370 // Load Long - UNaligned
5371 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{
5372 match(Set dst (LoadL_unaligned mem));
5373 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5374 ins_cost(MEMORY_REF_COST);
5375
5376 format %{ "LD $dst, $mem \t// unaligned long" %}
5377 size(4);
5378 ins_encode( enc_ld(dst, mem) );
5379 ins_pipe(pipe_class_memory);
5380 %}
5381
5382 // Load nodes for superwords
5383
5384 // Load Aligned Packed Byte
5385 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{
5386 predicate(n->as_LoadVector()->memory_size() == 8);
5387 match(Set dst (LoadVector mem));
5388 ins_cost(MEMORY_REF_COST);
5389
5390 format %{ "LD $dst, $mem \t// load 8-byte Vector" %}
5391 size(4);
5392 ins_encode( enc_ld(dst, mem) );
5393 ins_pipe(pipe_class_memory);
5394 %}
5395
5396
5397 instruct loadV16(vecX dst, memoryAlg16 mem) %{
5398 predicate(n->as_LoadVector()->memory_size() == 16);
5399 match(Set dst (LoadVector mem));
5400 ins_cost(MEMORY_REF_COST);
5401
5402 format %{ "LXV $dst, $mem \t// load 16-byte Vector" %}
5403 size(4);
5404 ins_encode %{
5405 __ lxv($dst$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
5406 %}
5407 ins_pipe(pipe_class_default);
5408 %}
5409
5410 // Load Range, range = array length (=jint)
5411 instruct loadRange(iRegIdst dst, memory mem) %{
5412 match(Set dst (LoadRange mem));
5413 ins_cost(MEMORY_REF_COST);
5414
5415 format %{ "LWZ $dst, $mem \t// range" %}
5416 size(4);
5417 ins_encode( enc_lwz(dst, mem) );
5418 ins_pipe(pipe_class_memory);
5419 %}
5420
5421 // Load Compressed Pointer
5422 instruct loadN(iRegNdst dst, memory mem) %{
5423 match(Set dst (LoadN mem));
5424 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5425 ins_cost(MEMORY_REF_COST);
5426
5427 format %{ "LWZ $dst, $mem \t// load compressed ptr" %}
5428 size(4);
5429 ins_encode( enc_lwz(dst, mem) );
5430 ins_pipe(pipe_class_memory);
5431 %}
5432
5433 // Load Compressed Pointer acquire.
5434 instruct loadN_ac(iRegNdst dst, memory mem) %{
5435 match(Set dst (LoadN mem));
5436 predicate(n->as_Load()->barrier_data() == 0);
5437 ins_cost(3*MEMORY_REF_COST);
5438
5439 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5440 "TWI $dst\n\t"
5441 "ISYNC" %}
5442 size(12);
5443 ins_encode( enc_lwz_ac(dst, mem) );
5444 ins_pipe(pipe_class_memory);
5445 %}
5446
5447 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5448 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5449 match(Set dst (DecodeN (LoadN mem)));
5450 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0 && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5451 ins_cost(MEMORY_REF_COST);
5452
5453 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5454 size(4);
5455 ins_encode( enc_lwz(dst, mem) );
5456 ins_pipe(pipe_class_memory);
5457 %}
5458
5459 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5460 match(Set dst (DecodeNKlass (LoadNKlass mem)));
5461 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0 &&
5462 _kids[0]->_leaf->as_Load()->is_unordered());
5463 ins_cost(MEMORY_REF_COST);
5464
5465 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5466 size(4);
5467 ins_encode( enc_lwz(dst, mem) );
5468 ins_pipe(pipe_class_memory);
5469 %}
5470
5471 // Load Pointer
5472 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5473 match(Set dst (LoadP mem));
5474 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5475 ins_cost(MEMORY_REF_COST);
5476
5477 format %{ "LD $dst, $mem \t// ptr" %}
5478 size(4);
5479 ins_encode( enc_ld(dst, mem) );
5480 ins_pipe(pipe_class_memory);
5481 %}
5482
5483 // Load Pointer acquire.
5484 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5485 match(Set dst (LoadP mem));
5486 ins_cost(3*MEMORY_REF_COST);
5487
5488 predicate(n->as_Load()->barrier_data() == 0);
5489
5490 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5491 "TWI $dst\n\t"
5492 "ISYNC" %}
5493 size(12);
5494 ins_encode( enc_ld_ac(dst, mem) );
5495 ins_pipe(pipe_class_memory);
5496 %}
5497
5498 // LoadP + CastP2L
5499 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
5500 match(Set dst (CastP2X (LoadP mem)));
5501 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5502 ins_cost(MEMORY_REF_COST);
5503
5504 format %{ "LD $dst, $mem \t// ptr + p2x" %}
5505 size(4);
5506 ins_encode( enc_ld(dst, mem) );
5507 ins_pipe(pipe_class_memory);
5508 %}
5509
5510 // Load compressed klass pointer.
5511 instruct loadNKlass(iRegNdst dst, memory mem) %{
5512 match(Set dst (LoadNKlass mem));
5513 predicate(!UseCompactObjectHeaders);
5514 ins_cost(MEMORY_REF_COST);
5515
5516 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %}
5517 size(4);
5518 ins_encode( enc_lwz(dst, mem) );
5519 ins_pipe(pipe_class_memory);
5520 %}
5521
5522 instruct loadNKlassCompactHeaders(iRegNdst dst, memory mem) %{
5523 match(Set dst (LoadNKlass mem));
5524 predicate(UseCompactObjectHeaders);
5525 ins_cost(MEMORY_REF_COST);
5526
5527 format %{ "load_narrow_klass_compact $dst, $mem \t// compressed class ptr" %}
5528 size(8);
5529 ins_encode %{
5530 assert($mem$$index$$Register == R0, "must not have indexed address: %s[%s]", $mem$$base$$Register.name(), $mem$$index$$Register.name());
5531 __ load_narrow_klass_compact_c2($dst$$Register, $mem$$base$$Register, $mem$$disp);
5532 %}
5533 ins_pipe(pipe_class_memory);
5534 %}
5535
5536 // Load Klass Pointer
5537 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
5538 match(Set dst (LoadKlass mem));
5539 ins_cost(MEMORY_REF_COST);
5540
5541 format %{ "LD $dst, $mem \t// klass ptr" %}
5542 size(4);
5543 ins_encode( enc_ld(dst, mem) );
5544 ins_pipe(pipe_class_memory);
5545 %}
5546
5547 // Load Float
5548 instruct loadF(regF dst, memory mem) %{
5549 match(Set dst (LoadF mem));
5550 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5551 ins_cost(MEMORY_REF_COST);
5552
5553 format %{ "LFS $dst, $mem" %}
5554 size(4);
5555 ins_encode %{
5556 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5557 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5558 %}
5559 ins_pipe(pipe_class_memory);
5560 %}
5561
5562 // Load Float acquire.
5563 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5564 match(Set dst (LoadF mem));
5565 effect(TEMP cr0);
5566 ins_cost(3*MEMORY_REF_COST);
5567
5568 format %{ "LFS $dst, $mem \t// acquire\n\t"
5569 "FCMPU cr0, $dst, $dst\n\t"
5570 "BNE cr0, next\n"
5571 "next:\n\t"
5572 "ISYNC" %}
5573 size(16);
5574 ins_encode %{
5575 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5576 Label next;
5577 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5578 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5579 __ bne(CR0, next);
5580 __ bind(next);
5581 __ isync();
5582 %}
5583 ins_pipe(pipe_class_memory);
5584 %}
5585
5586 // Load Double - aligned
5587 instruct loadD(regD dst, memory mem) %{
5588 match(Set dst (LoadD mem));
5589 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5590 ins_cost(MEMORY_REF_COST);
5591
5592 format %{ "LFD $dst, $mem" %}
5593 size(4);
5594 ins_encode( enc_lfd(dst, mem) );
5595 ins_pipe(pipe_class_memory);
5596 %}
5597
5598 // Load Double - aligned acquire.
5599 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5600 match(Set dst (LoadD mem));
5601 effect(TEMP cr0);
5602 ins_cost(3*MEMORY_REF_COST);
5603
5604 format %{ "LFD $dst, $mem \t// acquire\n\t"
5605 "FCMPU cr0, $dst, $dst\n\t"
5606 "BNE cr0, next\n"
5607 "next:\n\t"
5608 "ISYNC" %}
5609 size(16);
5610 ins_encode %{
5611 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5612 Label next;
5613 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5614 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5615 __ bne(CR0, next);
5616 __ bind(next);
5617 __ isync();
5618 %}
5619 ins_pipe(pipe_class_memory);
5620 %}
5621
5622 // Load Double - UNaligned
5623 instruct loadD_unaligned(regD dst, memory mem) %{
5624 match(Set dst (LoadD_unaligned mem));
5625 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5626 ins_cost(MEMORY_REF_COST);
5627
5628 format %{ "LFD $dst, $mem" %}
5629 size(4);
5630 ins_encode( enc_lfd(dst, mem) );
5631 ins_pipe(pipe_class_memory);
5632 %}
5633
5634 //----------Constants--------------------------------------------------------
5635
5636 // Load MachConstantTableBase: add hi offset to global toc.
5637 // TODO: Handle hidden register r29 in bundler!
5638 instruct loadToc_hi(iRegLdst dst) %{
5639 effect(DEF dst);
5640 ins_cost(DEFAULT_COST);
5641
5642 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %}
5643 size(4);
5644 ins_encode %{
5645 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
5646 %}
5647 ins_pipe(pipe_class_default);
5648 %}
5649
5650 // Load MachConstantTableBase: add lo offset to global toc.
5651 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
5652 effect(DEF dst, USE src);
5653 ins_cost(DEFAULT_COST);
5654
5655 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %}
5656 size(4);
5657 ins_encode %{
5658 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
5659 %}
5660 ins_pipe(pipe_class_default);
5661 %}
5662
5663 // Load 16-bit integer constant 0xssss????
5664 instruct loadConI16(iRegIdst dst, immI16 src) %{
5665 match(Set dst src);
5666
5667 format %{ "LI $dst, $src" %}
5668 size(4);
5669 ins_encode %{
5670 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5671 %}
5672 ins_pipe(pipe_class_default);
5673 %}
5674
5675 // Load integer constant 0x????0000
5676 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
5677 match(Set dst src);
5678 ins_cost(DEFAULT_COST);
5679
5680 format %{ "LIS $dst, $src.hi" %}
5681 size(4);
5682 ins_encode %{
5683 // Lis sign extends 16-bit src then shifts it 16 bit to the left.
5684 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5685 %}
5686 ins_pipe(pipe_class_default);
5687 %}
5688
5689 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted
5690 // and sign extended), this adds the low 16 bits.
5691 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
5692 // no match-rule, false predicate
5693 effect(DEF dst, USE src1, USE src2);
5694 predicate(false);
5695
5696 format %{ "ORI $dst, $src1.hi, $src2.lo" %}
5697 size(4);
5698 ins_encode %{
5699 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5700 %}
5701 ins_pipe(pipe_class_default);
5702 %}
5703
5704 instruct loadConI32(iRegIdst dst, immI32 src) %{
5705 match(Set dst src);
5706 // This macro is valid only in Power 10 and up, but adding the following predicate here
5707 // caused a build error, so we comment it out for now.
5708 // predicate(PowerArchitecturePPC64 >= 10);
5709 ins_cost(DEFAULT_COST+1);
5710
5711 format %{ "PLI $dst, $src" %}
5712 size(8);
5713 ins_encode %{
5714 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5715 __ pli($dst$$Register, $src$$constant);
5716 %}
5717 ins_pipe(pipe_class_default);
5718 ins_alignment(2);
5719 %}
5720
5721 instruct loadConI_Ex(iRegIdst dst, immI src) %{
5722 match(Set dst src);
5723 ins_cost(DEFAULT_COST*2);
5724
5725 expand %{
5726 // Would like to use $src$$constant.
5727 immI16 srcLo %{ _opnds[1]->constant() %}
5728 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5729 immIhi16 srcHi %{ _opnds[1]->constant() %}
5730 iRegIdst tmpI;
5731 loadConIhi16(tmpI, srcHi);
5732 loadConI32_lo16(dst, tmpI, srcLo);
5733 %}
5734 %}
5735
5736 // No constant pool entries required.
5737 instruct loadConL16(iRegLdst dst, immL16 src) %{
5738 match(Set dst src);
5739
5740 format %{ "LI $dst, $src \t// long" %}
5741 size(4);
5742 ins_encode %{
5743 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
5744 %}
5745 ins_pipe(pipe_class_default);
5746 %}
5747
5748 // Load long constant 0xssssssss????0000
5749 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
5750 match(Set dst src);
5751 ins_cost(DEFAULT_COST);
5752
5753 format %{ "LIS $dst, $src.hi \t// long" %}
5754 size(4);
5755 ins_encode %{
5756 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5757 %}
5758 ins_pipe(pipe_class_default);
5759 %}
5760
5761 // To load a 32 bit constant: merge lower 16 bits into already loaded
5762 // high 16 bits.
5763 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
5764 // no match-rule, false predicate
5765 effect(DEF dst, USE src1, USE src2);
5766 predicate(false);
5767
5768 format %{ "ORI $dst, $src1, $src2.lo" %}
5769 size(4);
5770 ins_encode %{
5771 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5772 %}
5773 ins_pipe(pipe_class_default);
5774 %}
5775
5776 // Load 32-bit long constant
5777 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{
5778 match(Set dst src);
5779 ins_cost(DEFAULT_COST*2);
5780
5781 expand %{
5782 // Would like to use $src$$constant.
5783 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%}
5784 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5785 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%}
5786 iRegLdst tmpL;
5787 loadConL32hi16(tmpL, srcHi);
5788 loadConL32_lo16(dst, tmpL, srcLo);
5789 %}
5790 %}
5791
5792 // Load 34-bit long constant using prefixed addi. No constant pool entries required.
5793 instruct loadConL34(iRegLdst dst, immL34 src) %{
5794 match(Set dst src);
5795 // This macro is valid only in Power 10 and up, but adding the following predicate here
5796 // caused a build error, so we comment it out for now.
5797 // predicate(PowerArchitecturePPC64 >= 10);
5798 ins_cost(DEFAULT_COST+1);
5799
5800 format %{ "PLI $dst, $src \t// long" %}
5801 size(8);
5802 ins_encode %{
5803 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5804 __ pli($dst$$Register, $src$$constant);
5805 %}
5806 ins_pipe(pipe_class_default);
5807 ins_alignment(2);
5808 %}
5809
5810 // Load long constant 0x????000000000000.
5811 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{
5812 match(Set dst src);
5813 ins_cost(DEFAULT_COST);
5814
5815 expand %{
5816 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%}
5817 immI shift32 %{ 32 %}
5818 iRegLdst tmpL;
5819 loadConL32hi16(tmpL, srcHi);
5820 lshiftL_regL_immI(dst, tmpL, shift32);
5821 %}
5822 %}
5823
5824 // Expand node for constant pool load: small offset.
5825 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{
5826 effect(DEF dst, USE src, USE toc);
5827 ins_cost(MEMORY_REF_COST);
5828
5829 ins_num_consts(1);
5830 // Needed so that CallDynamicJavaDirect can compute the address of this
5831 // instruction for relocation.
5832 ins_field_cbuf_insts_offset(int);
5833
5834 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %}
5835 size(4);
5836 ins_encode( enc_load_long_constL(dst, src, toc) );
5837 ins_pipe(pipe_class_memory);
5838 %}
5839
5840 // Expand node for constant pool load: large offset.
5841 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{
5842 effect(DEF dst, USE src, USE toc);
5843 predicate(false);
5844
5845 ins_num_consts(1);
5846 ins_field_const_toc_offset(int);
5847 // Needed so that CallDynamicJavaDirect can compute the address of this
5848 // instruction for relocation.
5849 ins_field_cbuf_insts_offset(int);
5850
5851 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %}
5852 size(4);
5853 ins_encode( enc_load_long_constL_hi(dst, toc, src) );
5854 ins_pipe(pipe_class_default);
5855 %}
5856
5857 // Expand node for constant pool load: large offset.
5858 // No constant pool entries required.
5859 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
5860 effect(DEF dst, USE src, USE base);
5861 predicate(false);
5862
5863 ins_field_const_toc_offset_hi_node(loadConL_hiNode*);
5864
5865 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %}
5866 size(4);
5867 ins_encode %{
5868 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5869 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5870 %}
5871 ins_pipe(pipe_class_memory);
5872 %}
5873
5874 // Load long constant from constant table. Expand in case of
5875 // offset > 16 bit is needed.
5876 // Adlc adds toc node MachConstantTableBase.
5877 instruct loadConL_Ex(iRegLdst dst, immL src) %{
5878 match(Set dst src);
5879 ins_cost(MEMORY_REF_COST);
5880
5881 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %}
5882 // We can not inline the enc_class for the expand as that does not support constanttablebase.
5883 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) );
5884 %}
5885
5886 // Load nullptr as compressed oop.
5887 instruct loadConN0(iRegNdst dst, immN_0 src) %{
5888 match(Set dst src);
5889 ins_cost(DEFAULT_COST);
5890
5891 format %{ "LI $dst, $src \t// compressed ptr" %}
5892 size(4);
5893 ins_encode %{
5894 __ li($dst$$Register, 0);
5895 %}
5896 ins_pipe(pipe_class_default);
5897 %}
5898
5899 // Load hi part of compressed oop constant.
5900 instruct loadConN_hi(iRegNdst dst, immN src) %{
5901 effect(DEF dst, USE src);
5902 ins_cost(DEFAULT_COST);
5903
5904 format %{ "LIS $dst, $src \t// narrow oop hi" %}
5905 size(4);
5906 ins_encode %{
5907 __ lis($dst$$Register, 0); // Will get patched.
5908 %}
5909 ins_pipe(pipe_class_default);
5910 %}
5911
5912 // Add lo part of compressed oop constant to already loaded hi part.
5913 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
5914 effect(DEF dst, USE src1, USE src2);
5915 ins_cost(DEFAULT_COST);
5916
5917 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %}
5918 size(4);
5919 ins_encode %{
5920 AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant);
5921 __ relocate(addrlit.rspec(), /*compressed format*/ 1);
5922 __ ori($dst$$Register, $src1$$Register, 0); // Will get patched.
5923 %}
5924 ins_pipe(pipe_class_default);
5925 %}
5926
5927 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
5928 effect(DEF dst, USE src, USE shift, USE mask_begin);
5929
5930 size(4);
5931 ins_encode %{
5932 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
5933 %}
5934 ins_pipe(pipe_class_default);
5935 %}
5936
5937 // Needed to postalloc expand loadConN: ConN is loaded as ConI
5938 // leaving the upper 32 bits with sign-extension bits.
5939 // This clears these bits: dst = src & 0xFFFFFFFF.
5940 // TODO: Eventually call this maskN_regN_FFFFFFFF.
5941 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
5942 effect(DEF dst, USE src);
5943 predicate(false);
5944
5945 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
5946 size(4);
5947 ins_encode %{
5948 __ clrldi($dst$$Register, $src$$Register, 0x20);
5949 %}
5950 ins_pipe(pipe_class_default);
5951 %}
5952
5953 // Optimize DecodeN for disjoint base.
5954 // Load base of compressed oops into a register
5955 instruct loadBase(iRegLdst dst) %{
5956 effect(DEF dst);
5957
5958 format %{ "LoadConst $dst, heapbase" %}
5959 ins_encode %{
5960 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0);
5961 %}
5962 ins_pipe(pipe_class_default);
5963 %}
5964
5965 // Loading ConN must be postalloc expanded so that edges between
5966 // the nodes are safe. They may not interfere with a safepoint.
5967 // GL TODO: This needs three instructions: better put this into the constant pool.
5968 instruct loadConN_Ex(iRegNdst dst, immN src) %{
5969 match(Set dst src);
5970 ins_cost(DEFAULT_COST*2);
5971
5972 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5973 postalloc_expand %{
5974 MachNode *m1 = new loadConN_hiNode();
5975 MachNode *m2 = new loadConN_loNode();
5976 MachNode *m3 = new clearMs32bNode();
5977 m1->add_req(nullptr);
5978 m2->add_req(nullptr, m1);
5979 m3->add_req(nullptr, m2);
5980 m1->_opnds[0] = op_dst;
5981 m1->_opnds[1] = op_src;
5982 m2->_opnds[0] = op_dst;
5983 m2->_opnds[1] = op_dst;
5984 m2->_opnds[2] = op_src;
5985 m3->_opnds[0] = op_dst;
5986 m3->_opnds[1] = op_dst;
5987 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5988 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5989 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5990 nodes->push(m1);
5991 nodes->push(m2);
5992 nodes->push(m3);
5993 %}
5994 %}
5995
5996 // We have seen a safepoint between the hi and lo parts, and this node was handled
5997 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is
5998 // not a narrow oop.
5999 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
6000 match(Set dst src);
6001 effect(DEF dst, USE src);
6002 ins_cost(DEFAULT_COST);
6003
6004 format %{ "LIS $dst, $src \t// narrow klass hi" %}
6005 size(4);
6006 ins_encode %{
6007 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant);
6008 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
6009 %}
6010 ins_pipe(pipe_class_default);
6011 %}
6012
6013 // As loadConNKlass_hi this must be recognized as narrow klass, not oop!
6014 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
6015 match(Set dst src1);
6016 effect(TEMP src2);
6017 ins_cost(DEFAULT_COST);
6018
6019 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
6020 size(4);
6021 ins_encode %{
6022 __ clrldi($dst$$Register, $src2$$Register, 0x20);
6023 %}
6024 ins_pipe(pipe_class_default);
6025 %}
6026
6027 // This needs a match rule so that build_oop_map knows this is
6028 // not a narrow oop.
6029 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
6030 match(Set dst src1);
6031 effect(TEMP src2);
6032 ins_cost(DEFAULT_COST);
6033
6034 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
6035 size(4);
6036 ins_encode %{
6037 // Notify OOP recorder (don't need the relocation)
6038 AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant);
6039 intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value());
6040 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
6041 %}
6042 ins_pipe(pipe_class_default);
6043 %}
6044
6045 // Loading ConNKlass must be postalloc expanded so that edges between
6046 // the nodes are safe. They may not interfere with a safepoint.
6047 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
6048 match(Set dst src);
6049 ins_cost(DEFAULT_COST*2);
6050
6051 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6052 postalloc_expand %{
6053 // Load high bits into register. Sign extended.
6054 MachNode *m1 = new loadConNKlass_hiNode();
6055 m1->add_req(nullptr);
6056 m1->_opnds[0] = op_dst;
6057 m1->_opnds[1] = op_src;
6058 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6059 nodes->push(m1);
6060
6061 MachNode *m2 = m1;
6062 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) {
6063 // Value might be 1-extended. Mask out these bits.
6064 m2 = new loadConNKlass_maskNode();
6065 m2->add_req(nullptr, m1);
6066 m2->_opnds[0] = op_dst;
6067 m2->_opnds[1] = op_src;
6068 m2->_opnds[2] = op_dst;
6069 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6070 nodes->push(m2);
6071 }
6072
6073 MachNode *m3 = new loadConNKlass_loNode();
6074 m3->add_req(nullptr, m2);
6075 m3->_opnds[0] = op_dst;
6076 m3->_opnds[1] = op_src;
6077 m3->_opnds[2] = op_dst;
6078 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6079 nodes->push(m3);
6080 %}
6081 %}
6082
6083 // 0x1 is used in object initialization (initial object header).
6084 // No constant pool entries required.
6085 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
6086 match(Set dst src);
6087
6088 format %{ "LI $dst, $src \t// ptr" %}
6089 size(4);
6090 ins_encode %{
6091 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
6092 %}
6093 ins_pipe(pipe_class_default);
6094 %}
6095
6096 // Expand node for constant pool load: small offset.
6097 // The match rule is needed to generate the correct bottom_type(),
6098 // however this node should never match. The use of predicate is not
6099 // possible since ADLC forbids predicates for chain rules. The higher
6100 // costs do not prevent matching in this case. For that reason the
6101 // operand immP_NM with predicate(false) is used.
6102 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{
6103 match(Set dst src);
6104 effect(TEMP toc);
6105
6106 ins_num_consts(1);
6107
6108 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %}
6109 size(4);
6110 ins_encode( enc_load_long_constP(dst, src, toc) );
6111 ins_pipe(pipe_class_memory);
6112 %}
6113
6114 // Expand node for constant pool load: large offset.
6115 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{
6116 effect(DEF dst, USE src, USE toc);
6117 predicate(false);
6118
6119 ins_num_consts(1);
6120 ins_field_const_toc_offset(int);
6121
6122 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %}
6123 size(4);
6124 ins_encode( enc_load_long_constP_hi(dst, src, toc) );
6125 ins_pipe(pipe_class_default);
6126 %}
6127
6128 // Expand node for constant pool load: large offset.
6129 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
6130 match(Set dst src);
6131 effect(TEMP base);
6132
6133 ins_field_const_toc_offset_hi_node(loadConP_hiNode*);
6134
6135 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
6136 size(4);
6137 ins_encode %{
6138 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
6139 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
6140 %}
6141 ins_pipe(pipe_class_memory);
6142 %}
6143
6144 // Load pointer constant from constant table. Expand in case an
6145 // offset > 16 bit is needed.
6146 // Adlc adds toc node MachConstantTableBase.
6147 instruct loadConP_Ex(iRegPdst dst, immP src) %{
6148 match(Set dst src);
6149 ins_cost(MEMORY_REF_COST);
6150
6151 // This rule does not use "expand" because then
6152 // the result type is not known to be an Oop. An ADLC
6153 // enhancement will be needed to make that work - not worth it!
6154
6155 // If this instruction rematerializes, it prolongs the live range
6156 // of the toc node, causing illegal graphs.
6157 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule().
6158 ins_cannot_rematerialize(true);
6159
6160 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %}
6161 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) );
6162 %}
6163
6164 // Expand node for constant pool load: small offset.
6165 instruct loadConF(regF dst, immF src, iRegLdst toc) %{
6166 effect(DEF dst, USE src, USE toc);
6167 ins_cost(MEMORY_REF_COST);
6168
6169 ins_num_consts(1);
6170
6171 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %}
6172 size(4);
6173 ins_encode %{
6174 address float_address = __ float_constant($src$$constant);
6175 if (float_address == nullptr) {
6176 ciEnv::current()->record_out_of_memory_failure();
6177 return;
6178 }
6179 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register);
6180 %}
6181 ins_pipe(pipe_class_memory);
6182 %}
6183
6184 // Expand node for constant pool load: large offset.
6185 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
6186 effect(DEF dst, USE src, USE toc);
6187 ins_cost(MEMORY_REF_COST);
6188
6189 ins_num_consts(1);
6190
6191 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6192 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t"
6193 "ADDIS $toc, $toc, -offset_hi"%}
6194 size(12);
6195 ins_encode %{
6196 FloatRegister Rdst = $dst$$FloatRegister;
6197 Register Rtoc = $toc$$Register;
6198 address float_address = __ float_constant($src$$constant);
6199 if (float_address == nullptr) {
6200 ciEnv::current()->record_out_of_memory_failure();
6201 return;
6202 }
6203 int offset = __ offset_to_method_toc(float_address);
6204 int hi = (offset + (1<<15))>>16;
6205 int lo = offset - hi * (1<<16);
6206
6207 __ addis(Rtoc, Rtoc, hi);
6208 __ lfs(Rdst, lo, Rtoc);
6209 __ addis(Rtoc, Rtoc, -hi);
6210 %}
6211 ins_pipe(pipe_class_memory);
6212 %}
6213
6214 // Adlc adds toc node MachConstantTableBase.
6215 instruct loadConF_Ex(regF dst, immF src) %{
6216 match(Set dst src);
6217 ins_cost(MEMORY_REF_COST);
6218
6219 // See loadConP.
6220 ins_cannot_rematerialize(true);
6221
6222 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6223 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) );
6224 %}
6225
6226 // Expand node for constant pool load: small offset.
6227 instruct loadConD(regD dst, immD src, iRegLdst toc) %{
6228 effect(DEF dst, USE src, USE toc);
6229 ins_cost(MEMORY_REF_COST);
6230
6231 ins_num_consts(1);
6232
6233 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %}
6234 size(4);
6235 ins_encode %{
6236 address float_address = __ double_constant($src$$constant);
6237 if (float_address == nullptr) {
6238 ciEnv::current()->record_out_of_memory_failure();
6239 return;
6240 }
6241 int offset = __ offset_to_method_toc(float_address);
6242 __ lfd($dst$$FloatRegister, offset, $toc$$Register);
6243 %}
6244 ins_pipe(pipe_class_memory);
6245 %}
6246
6247 // Expand node for constant pool load: large offset.
6248 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
6249 effect(DEF dst, USE src, USE toc);
6250 ins_cost(MEMORY_REF_COST);
6251
6252 ins_num_consts(1);
6253
6254 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6255 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t"
6256 "ADDIS $toc, $toc, -offset_hi" %}
6257 size(12);
6258 ins_encode %{
6259 FloatRegister Rdst = $dst$$FloatRegister;
6260 Register Rtoc = $toc$$Register;
6261 address float_address = __ double_constant($src$$constant);
6262 if (float_address == nullptr) {
6263 ciEnv::current()->record_out_of_memory_failure();
6264 return;
6265 }
6266 int offset = __ offset_to_method_toc(float_address);
6267 int hi = (offset + (1<<15))>>16;
6268 int lo = offset - hi * (1<<16);
6269
6270 __ addis(Rtoc, Rtoc, hi);
6271 __ lfd(Rdst, lo, Rtoc);
6272 __ addis(Rtoc, Rtoc, -hi);
6273 %}
6274 ins_pipe(pipe_class_memory);
6275 %}
6276
6277 // Adlc adds toc node MachConstantTableBase.
6278 instruct loadConD_Ex(regD dst, immD src) %{
6279 match(Set dst src);
6280 ins_cost(MEMORY_REF_COST);
6281
6282 // See loadConP.
6283 ins_cannot_rematerialize(true);
6284
6285 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6286 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) );
6287 %}
6288
6289 // Prefetch instructions.
6290 // Must be safe to execute with invalid address (cannot fault).
6291
6292 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
6293 match(PrefetchAllocation (AddP mem src));
6294 ins_cost(MEMORY_REF_COST);
6295
6296 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
6297 size(4);
6298 ins_encode %{
6299 __ dcbtst($src$$Register, $mem$$base$$Register);
6300 %}
6301 ins_pipe(pipe_class_memory);
6302 %}
6303
6304 instruct prefetch_alloc_no_offset(indirectMemory mem) %{
6305 match(PrefetchAllocation mem);
6306 ins_cost(MEMORY_REF_COST);
6307
6308 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
6309 size(4);
6310 ins_encode %{
6311 __ dcbtst($mem$$base$$Register);
6312 %}
6313 ins_pipe(pipe_class_memory);
6314 %}
6315
6316 //----------Store Instructions-------------------------------------------------
6317
6318 // Store Byte
6319 instruct storeB(memory mem, iRegIsrc src) %{
6320 match(Set mem (StoreB mem src));
6321 ins_cost(MEMORY_REF_COST);
6322
6323 format %{ "STB $src, $mem \t// byte" %}
6324 size(4);
6325 ins_encode %{
6326 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6327 __ stb($src$$Register, Idisp, $mem$$base$$Register);
6328 %}
6329 ins_pipe(pipe_class_memory);
6330 %}
6331
6332 // Store Char/Short
6333 instruct storeC(memory mem, iRegIsrc src) %{
6334 match(Set mem (StoreC mem src));
6335 ins_cost(MEMORY_REF_COST);
6336
6337 format %{ "STH $src, $mem \t// short" %}
6338 size(4);
6339 ins_encode %{
6340 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6341 __ sth($src$$Register, Idisp, $mem$$base$$Register);
6342 %}
6343 ins_pipe(pipe_class_memory);
6344 %}
6345
6346 // Store Integer
6347 instruct storeI(memory mem, iRegIsrc src) %{
6348 match(Set mem (StoreI mem src));
6349 ins_cost(MEMORY_REF_COST);
6350
6351 format %{ "STW $src, $mem" %}
6352 size(4);
6353 ins_encode( enc_stw(src, mem) );
6354 ins_pipe(pipe_class_memory);
6355 %}
6356
6357 // ConvL2I + StoreI.
6358 instruct storeI_convL2I(memory mem, iRegLsrc src) %{
6359 match(Set mem (StoreI mem (ConvL2I src)));
6360 ins_cost(MEMORY_REF_COST);
6361
6362 format %{ "STW l2i($src), $mem" %}
6363 size(4);
6364 ins_encode( enc_stw(src, mem) );
6365 ins_pipe(pipe_class_memory);
6366 %}
6367
6368 // Store Long
6369 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{
6370 match(Set mem (StoreL mem src));
6371 ins_cost(MEMORY_REF_COST);
6372
6373 format %{ "STD $src, $mem \t// long" %}
6374 size(4);
6375 ins_encode( enc_std(src, mem) );
6376 ins_pipe(pipe_class_memory);
6377 %}
6378
6379 // Store super word nodes.
6380
6381 // Store Aligned Packed Byte long register to memory
6382 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{
6383 predicate(n->as_StoreVector()->memory_size() == 8);
6384 match(Set mem (StoreVector mem src));
6385 ins_cost(MEMORY_REF_COST);
6386
6387 format %{ "STD $mem, $src \t// packed8B" %}
6388 size(4);
6389 ins_encode( enc_std(src, mem) );
6390 ins_pipe(pipe_class_memory);
6391 %}
6392
6393
6394 instruct storeV16(memoryAlg16 mem, vecX src) %{
6395 predicate(n->as_StoreVector()->memory_size() == 16);
6396 match(Set mem (StoreVector mem src));
6397 ins_cost(MEMORY_REF_COST);
6398
6399 format %{ "STXV $mem, $src \t// store 16-byte Vector" %}
6400 size(4);
6401 ins_encode %{
6402 __ stxv($src$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
6403 %}
6404 ins_pipe(pipe_class_default);
6405 %}
6406
6407 // Reinterpret: only one vector size used: either L or X
6408 instruct reinterpretL(iRegLdst dst) %{
6409 match(Set dst (VectorReinterpret dst));
6410 ins_cost(0);
6411 format %{ "reinterpret $dst" %}
6412 size(0);
6413 ins_encode( /*empty*/ );
6414 ins_pipe(pipe_class_empty);
6415 %}
6416
6417 instruct reinterpretX(vecX dst) %{
6418 match(Set dst (VectorReinterpret dst));
6419 ins_cost(0);
6420 format %{ "reinterpret $dst" %}
6421 size(0);
6422 ins_encode( /*empty*/ );
6423 ins_pipe(pipe_class_empty);
6424 %}
6425
6426 // Store Compressed Oop
6427 instruct storeN(memory dst, iRegN_P2N src) %{
6428 match(Set dst (StoreN dst src));
6429 predicate(n->as_Store()->barrier_data() == 0);
6430 ins_cost(MEMORY_REF_COST);
6431
6432 format %{ "STW $src, $dst \t// compressed oop" %}
6433 size(4);
6434 ins_encode( enc_stw(src, dst) );
6435 ins_pipe(pipe_class_memory);
6436 %}
6437
6438 // Store Compressed KLass
6439 instruct storeNKlass(memory dst, iRegN_P2N src) %{
6440 match(Set dst (StoreNKlass dst src));
6441 ins_cost(MEMORY_REF_COST);
6442
6443 format %{ "STW $src, $dst \t// compressed klass" %}
6444 size(4);
6445 ins_encode( enc_stw(src, dst) );
6446 ins_pipe(pipe_class_memory);
6447 %}
6448
6449 // Store Pointer
6450 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{
6451 match(Set dst (StoreP dst src));
6452 predicate(n->as_Store()->barrier_data() == 0);
6453 ins_cost(MEMORY_REF_COST);
6454
6455 format %{ "STD $src, $dst \t// ptr" %}
6456 size(4);
6457 ins_encode( enc_std(src, dst) );
6458 ins_pipe(pipe_class_memory);
6459 %}
6460
6461 // Store Float
6462 instruct storeF(memory mem, regF src) %{
6463 match(Set mem (StoreF mem src));
6464 ins_cost(MEMORY_REF_COST);
6465
6466 format %{ "STFS $src, $mem" %}
6467 size(4);
6468 ins_encode( enc_stfs(src, mem) );
6469 ins_pipe(pipe_class_memory);
6470 %}
6471
6472 // Store Double
6473 instruct storeD(memory mem, regD src) %{
6474 match(Set mem (StoreD mem src));
6475 ins_cost(MEMORY_REF_COST);
6476
6477 format %{ "STFD $src, $mem" %}
6478 size(4);
6479 ins_encode( enc_stfd(src, mem) );
6480 ins_pipe(pipe_class_memory);
6481 %}
6482
6483 // Convert oop pointer into compressed form.
6484
6485 // Nodes for postalloc expand.
6486
6487 // Shift node for expand.
6488 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
6489 // The match rule is needed to make it a 'MachTypeNode'!
6490 match(Set dst (EncodeP src));
6491 predicate(false);
6492
6493 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6494 size(4);
6495 ins_encode %{
6496 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6497 %}
6498 ins_pipe(pipe_class_default);
6499 %}
6500
6501 // Add node for expand.
6502 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6503 // The match rule is needed to make it a 'MachTypeNode'!
6504 match(Set dst (EncodeP src));
6505 predicate(false);
6506
6507 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6508 ins_encode %{
6509 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6510 %}
6511 ins_pipe(pipe_class_default);
6512 %}
6513
6514 // Conditional sub base.
6515 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6516 // The match rule is needed to make it a 'MachTypeNode'!
6517 match(Set dst (EncodeP (Binary crx src1)));
6518 predicate(false);
6519
6520 format %{ "BEQ $crx, done\n\t"
6521 "SUB $dst, $src1, heapbase \t// encode: subtract base if != nullptr\n"
6522 "done:" %}
6523 ins_encode %{
6524 Label done;
6525 __ beq($crx$$CondRegister, done);
6526 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0);
6527 __ bind(done);
6528 %}
6529 ins_pipe(pipe_class_default);
6530 %}
6531
6532 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6533 // The match rule is needed to make it a 'MachTypeNode'!
6534 match(Set dst (EncodeP (Binary crx src1)));
6535 predicate(false);
6536
6537 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6538 size(4);
6539 ins_encode %{
6540 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6541 %}
6542 ins_pipe(pipe_class_default);
6543 %}
6544
6545 // Disjoint narrow oop base.
6546 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6547 match(Set dst (EncodeP src));
6548 predicate(CompressedOops::base_disjoint());
6549
6550 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6551 size(4);
6552 ins_encode %{
6553 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32);
6554 %}
6555 ins_pipe(pipe_class_default);
6556 %}
6557
6558 // shift != 0, base != 0
6559 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6560 match(Set dst (EncodeP src));
6561 effect(TEMP crx);
6562 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6563 CompressedOops::shift() != 0 &&
6564 CompressedOops::base_overlaps());
6565
6566 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6567 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6568 %}
6569
6570 // shift != 0, base != 0
6571 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6572 match(Set dst (EncodeP src));
6573 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6574 CompressedOops::shift() != 0 &&
6575 CompressedOops::base_overlaps());
6576
6577 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6578 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6579 %}
6580
6581 // shift != 0, base == 0
6582 // TODO: This is the same as encodeP_shift. Merge!
6583 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6584 match(Set dst (EncodeP src));
6585 predicate(CompressedOops::shift() != 0 &&
6586 CompressedOops::base() == nullptr);
6587
6588 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != nullptr" %}
6589 size(4);
6590 ins_encode %{
6591 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6592 %}
6593 ins_pipe(pipe_class_default);
6594 %}
6595
6596 // Compressed OOPs with narrow_oop_shift == 0.
6597 // shift == 0, base == 0
6598 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
6599 match(Set dst (EncodeP src));
6600 predicate(CompressedOops::shift() == 0);
6601
6602 format %{ "MR $dst, $src \t// Ptr->Narrow" %}
6603 // variable size, 0 or 4.
6604 ins_encode %{
6605 __ mr_if_needed($dst$$Register, $src$$Register);
6606 %}
6607 ins_pipe(pipe_class_default);
6608 %}
6609
6610 // Decode nodes.
6611
6612 // Shift node for expand.
6613 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6614 // The match rule is needed to make it a 'MachTypeNode'!
6615 match(Set dst (DecodeN src));
6616 predicate(false);
6617
6618 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6619 size(4);
6620 ins_encode %{
6621 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6622 %}
6623 ins_pipe(pipe_class_default);
6624 %}
6625
6626 // Add node for expand.
6627 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6628 // The match rule is needed to make it a 'MachTypeNode'!
6629 match(Set dst (DecodeN src));
6630 predicate(false);
6631
6632 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %}
6633 ins_encode %{
6634 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6635 %}
6636 ins_pipe(pipe_class_default);
6637 %}
6638
6639 // conditianal add base for expand
6640 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6641 // The match rule is needed to make it a 'MachTypeNode'!
6642 // NOTICE that the rule is nonsense - we just have to make sure that:
6643 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6644 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6645 match(Set dst (DecodeN (Binary crx src)));
6646 predicate(false);
6647
6648 format %{ "BEQ $crx, done\n\t"
6649 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != nullptr\n"
6650 "done:" %}
6651 ins_encode %{
6652 Label done;
6653 __ beq($crx$$CondRegister, done);
6654 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6655 __ bind(done);
6656 %}
6657 ins_pipe(pipe_class_default);
6658 %}
6659
6660 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6661 // The match rule is needed to make it a 'MachTypeNode'!
6662 // NOTICE that the rule is nonsense - we just have to make sure that:
6663 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6664 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6665 match(Set dst (DecodeN (Binary crx src1)));
6666 predicate(false);
6667
6668 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6669 size(4);
6670 ins_encode %{
6671 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6672 %}
6673 ins_pipe(pipe_class_default);
6674 %}
6675
6676 // shift != 0, base != 0
6677 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6678 match(Set dst (DecodeN src));
6679 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6680 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6681 CompressedOops::shift() != 0 &&
6682 CompressedOops::base() != nullptr);
6683 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6684 effect(TEMP crx);
6685
6686 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6687 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6688 %}
6689
6690 // shift != 0, base == 0
6691 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6692 match(Set dst (DecodeN src));
6693 predicate(CompressedOops::shift() != 0 &&
6694 CompressedOops::base() == nullptr);
6695
6696 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %}
6697 size(4);
6698 ins_encode %{
6699 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6700 %}
6701 ins_pipe(pipe_class_default);
6702 %}
6703
6704 // Optimize DecodeN for disjoint base.
6705 // Shift narrow oop and or it into register that already contains the heap base.
6706 // Base == dst must hold, and is assured by construction in postaloc_expand.
6707 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6708 match(Set dst (DecodeN src));
6709 effect(TEMP base);
6710 predicate(false);
6711
6712 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6713 size(4);
6714 ins_encode %{
6715 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift());
6716 %}
6717 ins_pipe(pipe_class_default);
6718 %}
6719
6720 // Optimize DecodeN for disjoint base.
6721 // This node requires only one cycle on the critical path.
6722 // We must postalloc_expand as we can not express use_def effects where
6723 // the used register is L and the def'ed register P.
6724 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6725 match(Set dst (DecodeN src));
6726 effect(TEMP_DEF dst);
6727 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6728 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6729 CompressedOops::base_disjoint());
6730 ins_cost(DEFAULT_COST);
6731
6732 format %{ "MOV $dst, heapbase \t\n"
6733 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6734 postalloc_expand %{
6735 loadBaseNode *n1 = new loadBaseNode();
6736 n1->add_req(nullptr);
6737 n1->_opnds[0] = op_dst;
6738
6739 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6740 n2->add_req(n_region, n_src, n1);
6741 n2->_opnds[0] = op_dst;
6742 n2->_opnds[1] = op_src;
6743 n2->_opnds[2] = op_dst;
6744 n2->_bottom_type = _bottom_type;
6745
6746 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6747 ra_->set_oop(n2, true);
6748
6749 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6750 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6751
6752 nodes->push(n1);
6753 nodes->push(n2);
6754 %}
6755 %}
6756
6757 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6758 match(Set dst (DecodeN src));
6759 effect(TEMP_DEF dst, TEMP crx);
6760 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6761 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6762 CompressedOops::base_disjoint());
6763 ins_cost(3 * DEFAULT_COST);
6764
6765 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %}
6766 postalloc_expand %{
6767 loadBaseNode *n1 = new loadBaseNode();
6768 n1->add_req(nullptr);
6769 n1->_opnds[0] = op_dst;
6770
6771 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
6772 n_compare->add_req(n_region, n_src);
6773 n_compare->_opnds[0] = op_crx;
6774 n_compare->_opnds[1] = op_src;
6775 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6776
6777 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6778 n2->add_req(n_region, n_src, n1);
6779 n2->_opnds[0] = op_dst;
6780 n2->_opnds[1] = op_src;
6781 n2->_opnds[2] = op_dst;
6782 n2->_bottom_type = _bottom_type;
6783
6784 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6785 n_cond_set->add_req(n_region, n_compare, n2);
6786 n_cond_set->_opnds[0] = op_dst;
6787 n_cond_set->_opnds[1] = op_crx;
6788 n_cond_set->_opnds[2] = op_dst;
6789 n_cond_set->_bottom_type = _bottom_type;
6790
6791 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6792 ra_->set_oop(n_cond_set, true);
6793
6794 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6795 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
6796 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6797 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6798
6799 nodes->push(n1);
6800 nodes->push(n_compare);
6801 nodes->push(n2);
6802 nodes->push(n_cond_set);
6803 %}
6804 %}
6805
6806 // src != 0, shift != 0, base != 0
6807 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6808 match(Set dst (DecodeN src));
6809 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6810 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6811 CompressedOops::shift() != 0 &&
6812 CompressedOops::base() != nullptr);
6813 ins_cost(2 * DEFAULT_COST);
6814
6815 format %{ "DecodeN $dst, $src \t// $src != nullptr, postalloc expanded" %}
6816 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6817 %}
6818
6819 // Compressed OOPs with narrow_oop_shift == 0.
6820 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6821 match(Set dst (DecodeN src));
6822 predicate(CompressedOops::shift() == 0);
6823 ins_cost(DEFAULT_COST);
6824
6825 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %}
6826 // variable size, 0 or 4.
6827 ins_encode %{
6828 __ mr_if_needed($dst$$Register, $src$$Register);
6829 %}
6830 ins_pipe(pipe_class_default);
6831 %}
6832
6833 // Convert compressed oop into int for vectors alignment masking.
6834 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
6835 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6836 predicate(CompressedOops::shift() == 0);
6837 ins_cost(DEFAULT_COST);
6838
6839 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %}
6840 // variable size, 0 or 4.
6841 ins_encode %{
6842 __ mr_if_needed($dst$$Register, $src$$Register);
6843 %}
6844 ins_pipe(pipe_class_default);
6845 %}
6846
6847 // Convert klass pointer into compressed form.
6848
6849 // Nodes for postalloc expand.
6850
6851 // Shift node for expand.
6852 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
6853 // The match rule is needed to make it a 'MachTypeNode'!
6854 match(Set dst (EncodePKlass src));
6855 predicate(false);
6856
6857 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6858 size(4);
6859 ins_encode %{
6860 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6861 %}
6862 ins_pipe(pipe_class_default);
6863 %}
6864
6865 // Add node for expand.
6866 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6867 // The match rule is needed to make it a 'MachTypeNode'!
6868 match(Set dst (EncodePKlass (Binary base src)));
6869 predicate(false);
6870
6871 format %{ "SUB $dst, $base, $src \t// encode" %}
6872 size(4);
6873 ins_encode %{
6874 __ subf($dst$$Register, $base$$Register, $src$$Register);
6875 %}
6876 ins_pipe(pipe_class_default);
6877 %}
6878
6879 // Disjoint narrow oop base.
6880 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
6881 match(Set dst (EncodePKlass src));
6882 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/);
6883
6884 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6885 size(4);
6886 ins_encode %{
6887 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
6888 %}
6889 ins_pipe(pipe_class_default);
6890 %}
6891
6892 // shift != 0, base != 0
6893 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6894 match(Set dst (EncodePKlass (Binary base src)));
6895 predicate(false);
6896
6897 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6898 postalloc_expand %{
6899 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
6900 n1->add_req(n_region, n_base, n_src);
6901 n1->_opnds[0] = op_dst;
6902 n1->_opnds[1] = op_base;
6903 n1->_opnds[2] = op_src;
6904 n1->_bottom_type = _bottom_type;
6905
6906 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode();
6907 n2->add_req(n_region, n1);
6908 n2->_opnds[0] = op_dst;
6909 n2->_opnds[1] = op_dst;
6910 n2->_bottom_type = _bottom_type;
6911 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6912 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6913
6914 nodes->push(n1);
6915 nodes->push(n2);
6916 %}
6917 %}
6918
6919 // shift != 0, base != 0
6920 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
6921 match(Set dst (EncodePKlass src));
6922 //predicate(CompressedKlassPointers::shift() != 0 &&
6923 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/);
6924
6925 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6926 ins_cost(DEFAULT_COST*2); // Don't count constant.
6927 expand %{
6928 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %}
6929 iRegLdst base;
6930 loadConL_Ex(base, baseImm);
6931 encodePKlass_not_null_Ex(dst, base, src);
6932 %}
6933 %}
6934
6935 // Decode nodes.
6936
6937 // Shift node for expand.
6938 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
6939 // The match rule is needed to make it a 'MachTypeNode'!
6940 match(Set dst (DecodeNKlass src));
6941 predicate(false);
6942
6943 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %}
6944 size(4);
6945 ins_encode %{
6946 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6947 %}
6948 ins_pipe(pipe_class_default);
6949 %}
6950
6951 // Add node for expand.
6952
6953 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6954 // The match rule is needed to make it a 'MachTypeNode'!
6955 match(Set dst (DecodeNKlass (Binary base src)));
6956 predicate(false);
6957
6958 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
6959 size(4);
6960 ins_encode %{
6961 __ add($dst$$Register, $base$$Register, $src$$Register);
6962 %}
6963 ins_pipe(pipe_class_default);
6964 %}
6965
6966 // src != 0, shift != 0, base != 0
6967 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
6968 match(Set dst (DecodeNKlass (Binary base src)));
6969 //effect(kill src); // We need a register for the immediate result after shifting.
6970 predicate(false);
6971
6972 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != nullptr, postalloc expanded" %}
6973 postalloc_expand %{
6974 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode();
6975 n1->add_req(n_region, n_base, n_src);
6976 n1->_opnds[0] = op_dst;
6977 n1->_opnds[1] = op_base;
6978 n1->_opnds[2] = op_src;
6979 n1->_bottom_type = _bottom_type;
6980
6981 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode();
6982 n2->add_req(n_region, n1);
6983 n2->_opnds[0] = op_dst;
6984 n2->_opnds[1] = op_dst;
6985 n2->_bottom_type = _bottom_type;
6986
6987 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6988 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6989
6990 nodes->push(n1);
6991 nodes->push(n2);
6992 %}
6993 %}
6994
6995 // src != 0, shift != 0, base != 0
6996 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
6997 match(Set dst (DecodeNKlass src));
6998 // predicate(CompressedKlassPointers::shift() != 0 &&
6999 // CompressedKlassPointers::base() != 0);
7000
7001 //format %{ "DecodeNKlass $dst, $src \t// $src != nullptr, expanded" %}
7002
7003 ins_cost(DEFAULT_COST*2); // Don't count constant.
7004 expand %{
7005 // We add first, then we shift. Like this, we can get along with one register less.
7006 // But we have to load the base pre-shifted.
7007 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %}
7008 iRegLdst base;
7009 loadConL_Ex(base, baseImm);
7010 decodeNKlass_notNull_addBase_Ex(dst, base, src);
7011 %}
7012 %}
7013
7014 //----------MemBar Instructions-----------------------------------------------
7015 // Memory barrier flavors
7016
7017 instruct membar_acquire() %{
7018 match(LoadFence);
7019 ins_cost(4*MEMORY_REF_COST);
7020
7021 format %{ "MEMBAR-acquire" %}
7022 size(4);
7023 ins_encode %{
7024 __ acquire();
7025 %}
7026 ins_pipe(pipe_class_default);
7027 %}
7028
7029 instruct unnecessary_membar_acquire() %{
7030 match(MemBarAcquire);
7031 ins_cost(0);
7032
7033 format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
7034 size(0);
7035 ins_encode( /*empty*/ );
7036 ins_pipe(pipe_class_default);
7037 %}
7038
7039 instruct membar_acquire_lock() %{
7040 match(MemBarAcquireLock);
7041 ins_cost(0);
7042
7043 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
7044 size(0);
7045 ins_encode( /*empty*/ );
7046 ins_pipe(pipe_class_default);
7047 %}
7048
7049 instruct membar_release() %{
7050 match(MemBarRelease);
7051 match(StoreFence);
7052 ins_cost(4*MEMORY_REF_COST);
7053
7054 format %{ "MEMBAR-release" %}
7055 size(4);
7056 ins_encode %{
7057 __ release();
7058 %}
7059 ins_pipe(pipe_class_default);
7060 %}
7061
7062 instruct membar_storestore() %{
7063 match(MemBarStoreStore);
7064 match(StoreStoreFence);
7065 ins_cost(4*MEMORY_REF_COST);
7066
7067 format %{ "MEMBAR-store-store" %}
7068 size(4);
7069 ins_encode %{
7070 __ membar(Assembler::StoreStore);
7071 %}
7072 ins_pipe(pipe_class_default);
7073 %}
7074
7075 instruct membar_release_lock() %{
7076 match(MemBarReleaseLock);
7077 ins_cost(0);
7078
7079 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
7080 size(0);
7081 ins_encode( /*empty*/ );
7082 ins_pipe(pipe_class_default);
7083 %}
7084
7085 instruct membar_storeload() %{
7086 match(MemBarStoreLoad);
7087 ins_cost(4*MEMORY_REF_COST);
7088
7089 format %{ "MEMBAR-store-load" %}
7090 size(4);
7091 ins_encode %{
7092 __ fence();
7093 %}
7094 ins_pipe(pipe_class_default);
7095 %}
7096
7097 instruct membar_volatile() %{
7098 match(MemBarVolatile);
7099 ins_cost(4*MEMORY_REF_COST);
7100
7101 format %{ "MEMBAR-volatile" %}
7102 size(4);
7103 ins_encode %{
7104 __ fence();
7105 %}
7106 ins_pipe(pipe_class_default);
7107 %}
7108
7109 // This optimization is wrong on PPC. The following pattern is not supported:
7110 // MemBarVolatile
7111 // ^ ^
7112 // | |
7113 // CtrlProj MemProj
7114 // ^ ^
7115 // | |
7116 // | Load
7117 // |
7118 // MemBarVolatile
7119 //
7120 // The first MemBarVolatile could get optimized out! According to
7121 // Vladimir, this pattern can not occur on Oracle platforms.
7122 // However, it does occur on PPC64 (because of membars in
7123 // inline_unsafe_load_store).
7124 //
7125 // Add this node again if we found a good solution for inline_unsafe_load_store().
7126 // Don't forget to look at the implementation of post_store_load_barrier again,
7127 // we did other fixes in that method.
7128 //instruct unnecessary_membar_volatile() %{
7129 // match(MemBarVolatile);
7130 // predicate(Matcher::post_store_load_barrier(n));
7131 // ins_cost(0);
7132 //
7133 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
7134 // size(0);
7135 // ins_encode( /*empty*/ );
7136 // ins_pipe(pipe_class_default);
7137 //%}
7138
7139 instruct membar_full() %{
7140 match(MemBarFull);
7141 ins_cost(4*MEMORY_REF_COST);
7142
7143 format %{ "MEMBAR-full" %}
7144 size(4);
7145 ins_encode %{
7146 __ fence();
7147 %}
7148 ins_pipe(pipe_class_default);
7149 %}
7150
7151 instruct membar_CPUOrder() %{
7152 match(MemBarCPUOrder);
7153 ins_cost(0);
7154
7155 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
7156 size(0);
7157 ins_encode( /*empty*/ );
7158 ins_pipe(pipe_class_default);
7159 %}
7160
7161 //----------Conditional Move---------------------------------------------------
7162
7163 // Cmove using isel.
7164 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
7165 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7166 ins_cost(DEFAULT_COST);
7167
7168 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7169 size(4);
7170 ins_encode %{
7171 int cc = $cmp$$cmpcode;
7172 __ isel($dst$$Register, $crx$$CondRegister,
7173 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7174 %}
7175 ins_pipe(pipe_class_default);
7176 %}
7177
7178 // Cmove using isel.
7179 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
7180 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7181 ins_cost(DEFAULT_COST);
7182
7183 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7184 size(4);
7185 ins_encode %{
7186 int cc = $cmp$$cmpcode;
7187 __ isel($dst$$Register, $crx$$CondRegister,
7188 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7189 %}
7190 ins_pipe(pipe_class_default);
7191 %}
7192
7193 // Cmove using isel.
7194 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
7195 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7196 ins_cost(DEFAULT_COST);
7197
7198 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7199 size(4);
7200 ins_encode %{
7201 int cc = $cmp$$cmpcode;
7202 __ isel($dst$$Register, $crx$$CondRegister,
7203 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7204 %}
7205 ins_pipe(pipe_class_default);
7206 %}
7207
7208 // Cmove using isel.
7209 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
7210 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7211 ins_cost(DEFAULT_COST);
7212
7213 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7214 size(4);
7215 ins_encode %{
7216 int cc = $cmp$$cmpcode;
7217 __ isel($dst$$Register, $crx$$CondRegister,
7218 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7219 %}
7220 ins_pipe(pipe_class_default);
7221 %}
7222
7223 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
7224 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
7225 ins_cost(DEFAULT_COST+BRANCH_COST);
7226
7227 ins_variable_size_depending_on_alignment(true);
7228
7229 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7230 size(8);
7231 ins_encode %{
7232 Label done;
7233 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7234 // Branch if not (cmp crx).
7235 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7236 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7237 __ bind(done);
7238 %}
7239 ins_pipe(pipe_class_default);
7240 %}
7241
7242 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7243 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7244 ins_cost(DEFAULT_COST+BRANCH_COST);
7245
7246 ins_variable_size_depending_on_alignment(true);
7247
7248 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7249 size(8);
7250 ins_encode %{
7251 Label done;
7252 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7253 // Branch if not (cmp crx).
7254 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7255 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7256 __ bind(done);
7257 %}
7258 ins_pipe(pipe_class_default);
7259 %}
7260
7261 instruct cmovF_cmpF(cmpOp cop, regF op1, regF op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7262 match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7263 predicate(PowerArchitecturePPC64 >= 9);
7264 effect(TEMP tmp);
7265 ins_cost(2*DEFAULT_COST);
7266 format %{ "cmovF_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7267 size(8);
7268 ins_encode %{
7269 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7270 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7271 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7272 $tmp$$FloatRegister->to_vsr());
7273 %}
7274 ins_pipe(pipe_class_default);
7275 %}
7276
7277 instruct cmovF_cmpD(cmpOp cop, regD op1, regD op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7278 match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7279 predicate(PowerArchitecturePPC64 >= 9);
7280 effect(TEMP tmp);
7281 ins_cost(2*DEFAULT_COST);
7282 format %{ "cmovF_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7283 size(8);
7284 ins_encode %{
7285 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7286 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7287 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7288 $tmp$$FloatRegister->to_vsr());
7289 %}
7290 ins_pipe(pipe_class_default);
7291 %}
7292
7293 instruct cmovD_cmpD(cmpOp cop, regD op1, regD op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7294 match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7295 predicate(PowerArchitecturePPC64 >= 9);
7296 effect(TEMP tmp);
7297 ins_cost(2*DEFAULT_COST);
7298 format %{ "cmovD_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7299 size(8);
7300 ins_encode %{
7301 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7302 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7303 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7304 $tmp$$FloatRegister->to_vsr());
7305 %}
7306 ins_pipe(pipe_class_default);
7307 %}
7308
7309 instruct cmovD_cmpF(cmpOp cop, regF op1, regF op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7310 match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7311 predicate(PowerArchitecturePPC64 >= 9);
7312 effect(TEMP tmp);
7313 ins_cost(2*DEFAULT_COST);
7314 format %{ "cmovD_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7315 size(8);
7316 ins_encode %{
7317 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7318 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7319 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7320 $tmp$$FloatRegister->to_vsr());
7321 %}
7322 ins_pipe(pipe_class_default);
7323 %}
7324
7325 //----------Compare-And-Swap---------------------------------------------------
7326
7327 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7328 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7329 // matched.
7330
7331 // Strong versions:
7332
7333 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7334 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7335 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7336 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7337 ins_encode %{
7338 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7339 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7340 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7341 $res$$Register, nullptr, true);
7342 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7343 __ isync();
7344 } else {
7345 __ sync();
7346 }
7347 %}
7348 ins_pipe(pipe_class_default);
7349 %}
7350
7351 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7352 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7353 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7354 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7355 ins_encode %{
7356 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7357 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7358 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7359 $res$$Register, nullptr, true);
7360 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7361 __ isync();
7362 } else {
7363 __ sync();
7364 }
7365 %}
7366 ins_pipe(pipe_class_default);
7367 %}
7368
7369 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7370 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7371 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7372 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7373 ins_encode %{
7374 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7375 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7376 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7377 $res$$Register, nullptr, true);
7378 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7379 __ isync();
7380 } else {
7381 __ sync();
7382 }
7383 %}
7384 ins_pipe(pipe_class_default);
7385 %}
7386
7387 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7388 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7389 predicate(n->as_LoadStore()->barrier_data() == 0);
7390 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7391 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7392 ins_encode %{
7393 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7394 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7395 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7396 $res$$Register, nullptr, true);
7397 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7398 __ isync();
7399 } else {
7400 __ sync();
7401 }
7402 %}
7403 ins_pipe(pipe_class_default);
7404 %}
7405
7406 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7407 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7408 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7409 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7410 ins_encode %{
7411 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7412 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7413 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7414 $res$$Register, nullptr, true);
7415 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7416 __ isync();
7417 } else {
7418 __ sync();
7419 }
7420 %}
7421 ins_pipe(pipe_class_default);
7422 %}
7423
7424 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7425 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7426 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7427 predicate(n->as_LoadStore()->barrier_data() == 0);
7428 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7429 ins_encode %{
7430 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7431 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7432 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7433 $res$$Register, nullptr, true);
7434 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7435 __ isync();
7436 } else {
7437 __ sync();
7438 }
7439 %}
7440 ins_pipe(pipe_class_default);
7441 %}
7442
7443 // Weak versions:
7444
7445 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7446 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7447 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7448 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7449 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7450 ins_encode %{
7451 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7452 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7453 MacroAssembler::MemBarNone,
7454 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7455 %}
7456 ins_pipe(pipe_class_default);
7457 %}
7458
7459 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7460 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7461 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) );
7462 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7463 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7464 ins_encode %{
7465 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7466 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7467 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7468 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7469 %}
7470 ins_pipe(pipe_class_default);
7471 %}
7472
7473 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7474 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7475 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7476 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7477 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7478 ins_encode %{
7479 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7480 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7481 MacroAssembler::MemBarNone,
7482 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7483 %}
7484 ins_pipe(pipe_class_default);
7485 %}
7486
7487 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7488 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7489 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7490 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7491 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7492 ins_encode %{
7493 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7494 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7495 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7496 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7497 %}
7498 ins_pipe(pipe_class_default);
7499 %}
7500
7501 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7502 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7503 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7504 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7505 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7506 ins_encode %{
7507 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7508 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7509 MacroAssembler::MemBarNone,
7510 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7511 %}
7512 ins_pipe(pipe_class_default);
7513 %}
7514
7515 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7516 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7517 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7518 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7519 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7520 ins_encode %{
7521 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7522 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7523 // value is never passed to caller.
7524 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7525 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7526 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7527 %}
7528 ins_pipe(pipe_class_default);
7529 %}
7530
7531 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7532 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7533 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7534 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7535 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7536 ins_encode %{
7537 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7538 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7539 MacroAssembler::MemBarNone,
7540 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7541 %}
7542 ins_pipe(pipe_class_default);
7543 %}
7544
7545 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7546 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7547 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7548 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7549 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7550 ins_encode %{
7551 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7552 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7553 // value is never passed to caller.
7554 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7555 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7556 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7557 %}
7558 ins_pipe(pipe_class_default);
7559 %}
7560
7561 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7562 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7563 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7564 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7565 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7566 ins_encode %{
7567 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7568 // value is never passed to caller.
7569 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7570 MacroAssembler::MemBarNone,
7571 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7572 %}
7573 ins_pipe(pipe_class_default);
7574 %}
7575
7576 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7577 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7578 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7579 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7580 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7581 ins_encode %{
7582 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7583 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7584 // value is never passed to caller.
7585 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7586 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7587 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7588 %}
7589 ins_pipe(pipe_class_default);
7590 %}
7591
7592 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7593 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7594 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7595 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7596 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7597 ins_encode %{
7598 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7599 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7600 MacroAssembler::MemBarNone,
7601 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7602 %}
7603 ins_pipe(pipe_class_default);
7604 %}
7605
7606 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7607 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7608 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7609 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7610 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7611 ins_encode %{
7612 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7613 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7614 // value is never passed to caller.
7615 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7616 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7617 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7618 %}
7619 ins_pipe(pipe_class_default);
7620 %}
7621
7622 // CompareAndExchange
7623
7624 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7625 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7626 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7627 effect(TEMP_DEF res, TEMP cr0);
7628 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7629 ins_encode %{
7630 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7631 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7632 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7633 noreg, nullptr, true);
7634 %}
7635 ins_pipe(pipe_class_default);
7636 %}
7637
7638 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7639 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7640 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7641 effect(TEMP_DEF res, TEMP cr0);
7642 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7643 ins_encode %{
7644 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7645 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7646 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7647 noreg, nullptr, true);
7648 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7649 __ isync();
7650 } else {
7651 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7652 __ sync();
7653 }
7654 %}
7655 ins_pipe(pipe_class_default);
7656 %}
7657
7658
7659 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7660 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7661 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7662 effect(TEMP_DEF res, TEMP cr0);
7663 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7664 ins_encode %{
7665 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7666 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7667 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7668 noreg, nullptr, true);
7669 %}
7670 ins_pipe(pipe_class_default);
7671 %}
7672
7673 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7674 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7675 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7676 effect(TEMP_DEF res, TEMP cr0);
7677 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7678 ins_encode %{
7679 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7680 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7681 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7682 noreg, nullptr, true);
7683 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7684 __ isync();
7685 } else {
7686 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7687 __ sync();
7688 }
7689 %}
7690 ins_pipe(pipe_class_default);
7691 %}
7692
7693 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7694 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7695 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7696 effect(TEMP_DEF res, TEMP cr0);
7697 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
7698 ins_encode %{
7699 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7700 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7701 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7702 noreg, nullptr, true);
7703 %}
7704 ins_pipe(pipe_class_default);
7705 %}
7706
7707 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7708 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7709 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7710 effect(TEMP_DEF res, TEMP cr0);
7711 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
7712 ins_encode %{
7713 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7714 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7715 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7716 noreg, nullptr, true);
7717 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7718 __ isync();
7719 } else {
7720 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7721 __ sync();
7722 }
7723 %}
7724 ins_pipe(pipe_class_default);
7725 %}
7726
7727 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7728 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7729 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7730 effect(TEMP_DEF res, TEMP cr0);
7731 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7732 ins_encode %{
7733 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7734 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7735 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7736 noreg, nullptr, true);
7737 %}
7738 ins_pipe(pipe_class_default);
7739 %}
7740
7741 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7742 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7743 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7744 effect(TEMP_DEF res, TEMP cr0);
7745 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7746 ins_encode %{
7747 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7748 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7749 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7750 noreg, nullptr, true);
7751 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7752 __ isync();
7753 } else {
7754 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7755 __ sync();
7756 }
7757 %}
7758 ins_pipe(pipe_class_default);
7759 %}
7760
7761 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7762 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7763 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7764 effect(TEMP_DEF res, TEMP cr0);
7765 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
7766 ins_encode %{
7767 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7768 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7769 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7770 noreg, nullptr, true);
7771 %}
7772 ins_pipe(pipe_class_default);
7773 %}
7774
7775 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7776 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7777 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7778 effect(TEMP_DEF res, TEMP cr0);
7779 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
7780 ins_encode %{
7781 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7782 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7783 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7784 noreg, nullptr, true);
7785 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7786 __ isync();
7787 } else {
7788 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7789 __ sync();
7790 }
7791 %}
7792 ins_pipe(pipe_class_default);
7793 %}
7794
7795 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7796 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7797 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst)
7798 && n->as_LoadStore()->barrier_data() == 0);
7799 effect(TEMP_DEF res, TEMP cr0);
7800 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7801 ins_encode %{
7802 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7803 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7804 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7805 noreg, nullptr, true);
7806 %}
7807 ins_pipe(pipe_class_default);
7808 %}
7809
7810 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7811 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7812 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst)
7813 && n->as_LoadStore()->barrier_data() == 0);
7814 effect(TEMP_DEF res, TEMP cr0);
7815 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7816 ins_encode %{
7817 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7818 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7819 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7820 noreg, nullptr, true);
7821 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7822 __ isync();
7823 } else {
7824 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7825 __ sync();
7826 }
7827 %}
7828 ins_pipe(pipe_class_default);
7829 %}
7830
7831 // Special RMW
7832
7833 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7834 match(Set res (GetAndAddB mem_ptr src));
7835 effect(TEMP_DEF res, TEMP cr0);
7836 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
7837 ins_encode %{
7838 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
7839 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7840 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7841 __ isync();
7842 } else {
7843 __ sync();
7844 }
7845 %}
7846 ins_pipe(pipe_class_default);
7847 %}
7848
7849 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7850 match(Set res (GetAndAddS mem_ptr src));
7851 effect(TEMP_DEF res, TEMP cr0);
7852 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
7853 ins_encode %{
7854 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
7855 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7856 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7857 __ isync();
7858 } else {
7859 __ sync();
7860 }
7861 %}
7862 ins_pipe(pipe_class_default);
7863 %}
7864
7865
7866 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7867 match(Set res (GetAndAddI mem_ptr src));
7868 effect(TEMP_DEF res, TEMP cr0);
7869 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
7870 ins_encode %{
7871 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
7872 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7873 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7874 __ isync();
7875 } else {
7876 __ sync();
7877 }
7878 %}
7879 ins_pipe(pipe_class_default);
7880 %}
7881
7882 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7883 match(Set res (GetAndAddL mem_ptr src));
7884 effect(TEMP_DEF res, TEMP cr0);
7885 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
7886 ins_encode %{
7887 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
7888 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7889 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7890 __ isync();
7891 } else {
7892 __ sync();
7893 }
7894 %}
7895 ins_pipe(pipe_class_default);
7896 %}
7897
7898 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7899 match(Set res (GetAndSetB mem_ptr src));
7900 effect(TEMP_DEF res, TEMP cr0);
7901 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
7902 ins_encode %{
7903 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
7904 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7905 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7906 __ isync();
7907 } else {
7908 __ sync();
7909 }
7910 %}
7911 ins_pipe(pipe_class_default);
7912 %}
7913
7914 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7915 match(Set res (GetAndSetS mem_ptr src));
7916 effect(TEMP_DEF res, TEMP cr0);
7917 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
7918 ins_encode %{
7919 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
7920 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7921 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7922 __ isync();
7923 } else {
7924 __ sync();
7925 }
7926 %}
7927 ins_pipe(pipe_class_default);
7928 %}
7929
7930
7931 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7932 match(Set res (GetAndSetI mem_ptr src));
7933 effect(TEMP_DEF res, TEMP cr0);
7934 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
7935 ins_encode %{
7936 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7937 MacroAssembler::cmpxchgx_hint_atomic_update());
7938 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7939 __ isync();
7940 } else {
7941 __ sync();
7942 }
7943 %}
7944 ins_pipe(pipe_class_default);
7945 %}
7946
7947 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7948 match(Set res (GetAndSetL mem_ptr src));
7949 effect(TEMP_DEF res, TEMP cr0);
7950 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
7951 ins_encode %{
7952 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7953 MacroAssembler::cmpxchgx_hint_atomic_update());
7954 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7955 __ isync();
7956 } else {
7957 __ sync();
7958 }
7959 %}
7960 ins_pipe(pipe_class_default);
7961 %}
7962
7963 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
7964 match(Set res (GetAndSetP mem_ptr src));
7965 predicate(n->as_LoadStore()->barrier_data() == 0);
7966 effect(TEMP_DEF res, TEMP cr0);
7967 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
7968 ins_encode %{
7969 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7970 MacroAssembler::cmpxchgx_hint_atomic_update());
7971 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7972 __ isync();
7973 } else {
7974 __ sync();
7975 }
7976 %}
7977 ins_pipe(pipe_class_default);
7978 %}
7979
7980 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
7981 match(Set res (GetAndSetN mem_ptr src));
7982 predicate(n->as_LoadStore()->barrier_data() == 0);
7983 effect(TEMP_DEF res, TEMP cr0);
7984 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
7985 ins_encode %{
7986 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7987 MacroAssembler::cmpxchgx_hint_atomic_update());
7988 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7989 __ isync();
7990 } else {
7991 __ sync();
7992 }
7993 %}
7994 ins_pipe(pipe_class_default);
7995 %}
7996
7997 //----------Arithmetic Instructions--------------------------------------------
7998 // Addition Instructions
7999
8000 // Register Addition
8001 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
8002 match(Set dst (AddI src1 src2));
8003 format %{ "ADD $dst, $src1, $src2" %}
8004 size(4);
8005 ins_encode %{
8006 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8007 %}
8008 ins_pipe(pipe_class_default);
8009 %}
8010
8011 // Expand does not work with above instruct. (??)
8012 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8013 // no match-rule
8014 effect(DEF dst, USE src1, USE src2);
8015 format %{ "ADD $dst, $src1, $src2" %}
8016 size(4);
8017 ins_encode %{
8018 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8019 %}
8020 ins_pipe(pipe_class_default);
8021 %}
8022
8023 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
8024 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
8025 ins_cost(DEFAULT_COST*3);
8026
8027 expand %{
8028 // FIXME: we should do this in the ideal world.
8029 iRegIdst tmp1;
8030 iRegIdst tmp2;
8031 addI_reg_reg(tmp1, src1, src2);
8032 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
8033 addI_reg_reg(dst, tmp1, tmp2);
8034 %}
8035 %}
8036
8037 // Immediate Addition
8038 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8039 match(Set dst (AddI src1 src2));
8040 format %{ "ADDI $dst, $src1, $src2" %}
8041 size(4);
8042 ins_encode %{
8043 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8044 %}
8045 ins_pipe(pipe_class_default);
8046 %}
8047
8048 // Immediate Addition with 16-bit shifted operand
8049 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
8050 match(Set dst (AddI src1 src2));
8051 format %{ "ADDIS $dst, $src1, $src2" %}
8052 size(4);
8053 ins_encode %{
8054 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8055 %}
8056 ins_pipe(pipe_class_default);
8057 %}
8058
8059 // Immediate Addition using prefixed addi
8060 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{
8061 match(Set dst (AddI src1 src2));
8062 predicate(PowerArchitecturePPC64 >= 10);
8063 ins_cost(DEFAULT_COST+1);
8064 format %{ "PADDI $dst, $src1, $src2" %}
8065 size(8);
8066 ins_encode %{
8067 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8068 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8069 %}
8070 ins_pipe(pipe_class_default);
8071 ins_alignment(2);
8072 %}
8073
8074 // Long Addition
8075 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8076 match(Set dst (AddL src1 src2));
8077 format %{ "ADD $dst, $src1, $src2 \t// long" %}
8078 size(4);
8079 ins_encode %{
8080 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8081 %}
8082 ins_pipe(pipe_class_default);
8083 %}
8084
8085 // Expand does not work with above instruct. (??)
8086 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8087 // no match-rule
8088 effect(DEF dst, USE src1, USE src2);
8089 format %{ "ADD $dst, $src1, $src2 \t// long" %}
8090 size(4);
8091 ins_encode %{
8092 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8093 %}
8094 ins_pipe(pipe_class_default);
8095 %}
8096
8097 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
8098 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
8099 ins_cost(DEFAULT_COST*3);
8100
8101 expand %{
8102 // FIXME: we should do this in the ideal world.
8103 iRegLdst tmp1;
8104 iRegLdst tmp2;
8105 addL_reg_reg(tmp1, src1, src2);
8106 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
8107 addL_reg_reg(dst, tmp1, tmp2);
8108 %}
8109 %}
8110
8111 // AddL + ConvL2I.
8112 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8113 match(Set dst (ConvL2I (AddL src1 src2)));
8114
8115 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %}
8116 size(4);
8117 ins_encode %{
8118 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8119 %}
8120 ins_pipe(pipe_class_default);
8121 %}
8122
8123 // No constant pool entries required.
8124 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8125 match(Set dst (AddL src1 src2));
8126
8127 format %{ "ADDI $dst, $src1, $src2" %}
8128 size(4);
8129 ins_encode %{
8130 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8131 %}
8132 ins_pipe(pipe_class_default);
8133 %}
8134
8135 // Long Immediate Addition with 16-bit shifted operand.
8136 // No constant pool entries required.
8137 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
8138 match(Set dst (AddL src1 src2));
8139
8140 format %{ "ADDIS $dst, $src1, $src2" %}
8141 size(4);
8142 ins_encode %{
8143 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8144 %}
8145 ins_pipe(pipe_class_default);
8146 %}
8147
8148 // Long Immediate Addition using prefixed addi
8149 // No constant pool entries required.
8150 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{
8151 match(Set dst (AddL src1 src2));
8152 predicate(PowerArchitecturePPC64 >= 10);
8153 ins_cost(DEFAULT_COST+1);
8154
8155 format %{ "PADDI $dst, $src1, $src2" %}
8156 size(8);
8157 ins_encode %{
8158 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8159 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8160 %}
8161 ins_pipe(pipe_class_default);
8162 ins_alignment(2);
8163 %}
8164
8165 // Pointer Register Addition
8166 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
8167 match(Set dst (AddP src1 src2));
8168 format %{ "ADD $dst, $src1, $src2" %}
8169 size(4);
8170 ins_encode %{
8171 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8172 %}
8173 ins_pipe(pipe_class_default);
8174 %}
8175
8176 // Pointer Immediate Addition
8177 // No constant pool entries required.
8178 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
8179 match(Set dst (AddP src1 src2));
8180
8181 format %{ "ADDI $dst, $src1, $src2" %}
8182 size(4);
8183 ins_encode %{
8184 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8185 %}
8186 ins_pipe(pipe_class_default);
8187 %}
8188
8189 // Pointer Immediate Addition with 16-bit shifted operand.
8190 // No constant pool entries required.
8191 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
8192 match(Set dst (AddP src1 src2));
8193
8194 format %{ "ADDIS $dst, $src1, $src2" %}
8195 size(4);
8196 ins_encode %{
8197 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8198 %}
8199 ins_pipe(pipe_class_default);
8200 %}
8201
8202 // Pointer Immediate Addition using prefixed addi
8203 // No constant pool entries required.
8204 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{
8205 match(Set dst (AddP src1 src2));
8206 predicate(PowerArchitecturePPC64 >= 10);
8207 ins_cost(DEFAULT_COST+1);
8208
8209 format %{ "PADDI $dst, $src1, $src2" %}
8210 size(8);
8211 ins_encode %{
8212 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8213 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8214 %}
8215 ins_pipe(pipe_class_default);
8216 ins_alignment(2);
8217 %}
8218
8219 //---------------------
8220 // Subtraction Instructions
8221
8222 // Register Subtraction
8223 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8224 match(Set dst (SubI src1 src2));
8225 format %{ "SUBF $dst, $src2, $src1" %}
8226 size(4);
8227 ins_encode %{
8228 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8229 %}
8230 ins_pipe(pipe_class_default);
8231 %}
8232
8233 // Immediate Subtraction
8234 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
8235 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
8236
8237 // SubI from constant (using subfic).
8238 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
8239 match(Set dst (SubI src1 src2));
8240 format %{ "SUBI $dst, $src1, $src2" %}
8241
8242 size(4);
8243 ins_encode %{
8244 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
8245 %}
8246 ins_pipe(pipe_class_default);
8247 %}
8248
8249 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
8250 // positive integers and 0xF...F for negative ones.
8251 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
8252 // no match-rule, false predicate
8253 effect(DEF dst, USE src);
8254 predicate(false);
8255
8256 format %{ "SRAWI $dst, $src, #31" %}
8257 size(4);
8258 ins_encode %{
8259 __ srawi($dst$$Register, $src$$Register, 0x1f);
8260 %}
8261 ins_pipe(pipe_class_default);
8262 %}
8263
8264 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
8265 match(Set dst (AbsI src));
8266 ins_cost(DEFAULT_COST*3);
8267
8268 expand %{
8269 iRegIdst tmp1;
8270 iRegIdst tmp2;
8271 signmask32I_regI(tmp1, src);
8272 xorI_reg_reg(tmp2, tmp1, src);
8273 subI_reg_reg(dst, tmp2, tmp1);
8274 %}
8275 %}
8276
8277 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
8278 match(Set dst (SubI zero src2));
8279 format %{ "NEG $dst, $src2" %}
8280 size(4);
8281 ins_encode %{
8282 __ neg($dst$$Register, $src2$$Register);
8283 %}
8284 ins_pipe(pipe_class_default);
8285 %}
8286
8287 // Long subtraction
8288 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8289 match(Set dst (SubL src1 src2));
8290 format %{ "SUBF $dst, $src2, $src1 \t// long" %}
8291 size(4);
8292 ins_encode %{
8293 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8294 %}
8295 ins_pipe(pipe_class_default);
8296 %}
8297
8298 // SubL + convL2I.
8299 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8300 match(Set dst (ConvL2I (SubL src1 src2)));
8301
8302 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
8303 size(4);
8304 ins_encode %{
8305 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8306 %}
8307 ins_pipe(pipe_class_default);
8308 %}
8309
8310 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8311 // positive longs and 0xF...F for negative ones.
8312 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8313 // no match-rule, false predicate
8314 effect(DEF dst, USE src);
8315 predicate(false);
8316
8317 format %{ "SRADI $dst, $src, #63" %}
8318 size(4);
8319 ins_encode %{
8320 __ sradi($dst$$Register, $src$$Register, 0x3f);
8321 %}
8322 ins_pipe(pipe_class_default);
8323 %}
8324
8325 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8326 // positive longs and 0xF...F for negative ones.
8327 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8328 // no match-rule, false predicate
8329 effect(DEF dst, USE src);
8330 predicate(false);
8331
8332 format %{ "SRADI $dst, $src, #63" %}
8333 size(4);
8334 ins_encode %{
8335 __ sradi($dst$$Register, $src$$Register, 0x3f);
8336 %}
8337 ins_pipe(pipe_class_default);
8338 %}
8339
8340 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{
8341 match(Set dst (AbsL src));
8342 ins_cost(DEFAULT_COST*3);
8343
8344 expand %{
8345 iRegLdst tmp1;
8346 iRegLdst tmp2;
8347 signmask64L_regL(tmp1, src);
8348 xorL_reg_reg(tmp2, tmp1, src);
8349 subL_reg_reg(dst, tmp2, tmp1);
8350 %}
8351 %}
8352
8353 // Long negation
8354 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8355 match(Set dst (SubL zero src2));
8356 format %{ "NEG $dst, $src2 \t// long" %}
8357 size(4);
8358 ins_encode %{
8359 __ neg($dst$$Register, $src2$$Register);
8360 %}
8361 ins_pipe(pipe_class_default);
8362 %}
8363
8364 // NegL + ConvL2I.
8365 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8366 match(Set dst (ConvL2I (SubL zero src2)));
8367
8368 format %{ "NEG $dst, $src2 \t// long + l2i" %}
8369 size(4);
8370 ins_encode %{
8371 __ neg($dst$$Register, $src2$$Register);
8372 %}
8373 ins_pipe(pipe_class_default);
8374 %}
8375
8376 // Multiplication Instructions
8377 // Integer Multiplication
8378
8379 // Register Multiplication
8380 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8381 match(Set dst (MulI src1 src2));
8382 ins_cost(DEFAULT_COST);
8383
8384 format %{ "MULLW $dst, $src1, $src2" %}
8385 size(4);
8386 ins_encode %{
8387 __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8388 %}
8389 ins_pipe(pipe_class_default);
8390 %}
8391
8392 // Immediate Multiplication
8393 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8394 match(Set dst (MulI src1 src2));
8395 ins_cost(DEFAULT_COST);
8396
8397 format %{ "MULLI $dst, $src1, $src2" %}
8398 size(4);
8399 ins_encode %{
8400 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8401 %}
8402 ins_pipe(pipe_class_default);
8403 %}
8404
8405 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8406 match(Set dst (MulL src1 src2));
8407 ins_cost(DEFAULT_COST);
8408
8409 format %{ "MULLD $dst $src1, $src2 \t// long" %}
8410 size(4);
8411 ins_encode %{
8412 __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8413 %}
8414 ins_pipe(pipe_class_default);
8415 %}
8416
8417 // Multiply high for optimized long division by constant.
8418 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8419 match(Set dst (MulHiL src1 src2));
8420 ins_cost(DEFAULT_COST);
8421
8422 format %{ "MULHD $dst $src1, $src2 \t// long" %}
8423 size(4);
8424 ins_encode %{
8425 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8426 %}
8427 ins_pipe(pipe_class_default);
8428 %}
8429
8430 instruct uMulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8431 match(Set dst (UMulHiL src1 src2));
8432 ins_cost(DEFAULT_COST);
8433
8434 format %{ "MULHDU $dst $src1, $src2 \t// unsigned long" %}
8435 size(4);
8436 ins_encode %{
8437 __ mulhdu($dst$$Register, $src1$$Register, $src2$$Register);
8438 %}
8439 ins_pipe(pipe_class_default);
8440 %}
8441
8442 // Immediate Multiplication
8443 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8444 match(Set dst (MulL src1 src2));
8445 ins_cost(DEFAULT_COST);
8446
8447 format %{ "MULLI $dst, $src1, $src2" %}
8448 size(4);
8449 ins_encode %{
8450 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8451 %}
8452 ins_pipe(pipe_class_default);
8453 %}
8454
8455 // Integer Division with Immediate -1: Negate.
8456 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8457 match(Set dst (DivI src1 src2));
8458 ins_cost(DEFAULT_COST);
8459
8460 format %{ "NEG $dst, $src1 \t// /-1" %}
8461 size(4);
8462 ins_encode %{
8463 __ neg($dst$$Register, $src1$$Register);
8464 %}
8465 ins_pipe(pipe_class_default);
8466 %}
8467
8468 // Integer Division with constant, but not -1.
8469 // We should be able to improve this by checking the type of src2.
8470 // It might well be that src2 is known to be positive.
8471 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8472 match(Set dst (DivI src1 src2));
8473 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8474 ins_cost(2*DEFAULT_COST);
8475
8476 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8477 size(4);
8478 ins_encode %{
8479 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8480 %}
8481 ins_pipe(pipe_class_default);
8482 %}
8483
8484 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8485 effect(USE_DEF dst, USE src1, USE crx);
8486 predicate(false);
8487
8488 ins_variable_size_depending_on_alignment(true);
8489
8490 format %{ "CMOVE $dst, neg($src1), $crx" %}
8491 size(8);
8492 ins_encode %{
8493 Label done;
8494 __ bne($crx$$CondRegister, done);
8495 __ neg($dst$$Register, $src1$$Register);
8496 __ bind(done);
8497 %}
8498 ins_pipe(pipe_class_default);
8499 %}
8500
8501 // Integer Division with Registers not containing constants.
8502 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8503 match(Set dst (DivI src1 src2));
8504 ins_cost(10*DEFAULT_COST);
8505
8506 expand %{
8507 immI16 imm %{ (int)-1 %}
8508 flagsReg tmp1;
8509 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8510 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8511 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8512 %}
8513 %}
8514
8515 // Long Division with Immediate -1: Negate.
8516 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8517 match(Set dst (DivL src1 src2));
8518 ins_cost(DEFAULT_COST);
8519
8520 format %{ "NEG $dst, $src1 \t// /-1, long" %}
8521 size(4);
8522 ins_encode %{
8523 __ neg($dst$$Register, $src1$$Register);
8524 %}
8525 ins_pipe(pipe_class_default);
8526 %}
8527
8528 // Long Division with constant, but not -1.
8529 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8530 match(Set dst (DivL src1 src2));
8531 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8532 ins_cost(2*DEFAULT_COST);
8533
8534 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8535 size(4);
8536 ins_encode %{
8537 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8538 %}
8539 ins_pipe(pipe_class_default);
8540 %}
8541
8542 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8543 effect(USE_DEF dst, USE src1, USE crx);
8544 predicate(false);
8545
8546 ins_variable_size_depending_on_alignment(true);
8547
8548 format %{ "CMOVE $dst, neg($src1), $crx" %}
8549 size(8);
8550 ins_encode %{
8551 Label done;
8552 __ bne($crx$$CondRegister, done);
8553 __ neg($dst$$Register, $src1$$Register);
8554 __ bind(done);
8555 %}
8556 ins_pipe(pipe_class_default);
8557 %}
8558
8559 // Long Division with Registers not containing constants.
8560 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8561 match(Set dst (DivL src1 src2));
8562 ins_cost(10*DEFAULT_COST);
8563
8564 expand %{
8565 immL16 imm %{ (int)-1 %}
8566 flagsReg tmp1;
8567 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8568 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8569 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8570 %}
8571 %}
8572
8573 // Integer Remainder with registers.
8574 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8575 match(Set dst (ModI src1 src2));
8576 ins_cost(10*DEFAULT_COST);
8577
8578 expand %{
8579 immI16 imm %{ (int)-1 %}
8580 flagsReg tmp1;
8581 iRegIdst tmp2;
8582 iRegIdst tmp3;
8583 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8584 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8585 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8586 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8587 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8588 %}
8589 %}
8590
8591 // Long Remainder with registers
8592 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8593 match(Set dst (ModL src1 src2));
8594 ins_cost(10*DEFAULT_COST);
8595
8596 expand %{
8597 immL16 imm %{ (int)-1 %}
8598 flagsReg tmp1;
8599 iRegLdst tmp2;
8600 iRegLdst tmp3;
8601 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8602 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8603 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8604 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8605 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8606 %}
8607 %}
8608
8609 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8610 match(Set dst (UDivI src1 src2));
8611 format %{ "DIVWU $dst, $src1, $src2" %}
8612 size(4);
8613 ins_encode %{
8614 __ divwu($dst$$Register, $src1$$Register, $src2$$Register);
8615 %}
8616 ins_pipe(pipe_class_default);
8617 %}
8618
8619 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8620 match(Set dst (UModI src1 src2));
8621 expand %{
8622 iRegIdst tmp1;
8623 iRegIdst tmp2;
8624 udivI_reg_reg(tmp1, src1, src2);
8625 // Compute lower 32 bit result using signed instructions as suggested by ISA.
8626 // Upper 32 bit will contain garbage.
8627 mulI_reg_reg(tmp2, src2, tmp1);
8628 subI_reg_reg(dst, src1, tmp2);
8629 %}
8630 %}
8631
8632 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8633 match(Set dst (UDivL src1 src2));
8634 format %{ "DIVDU $dst, $src1, $src2" %}
8635 size(4);
8636 ins_encode %{
8637 __ divdu($dst$$Register, $src1$$Register, $src2$$Register);
8638 %}
8639 ins_pipe(pipe_class_default);
8640 %}
8641
8642 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8643 match(Set dst (UModL src1 src2));
8644 expand %{
8645 iRegLdst tmp1;
8646 iRegLdst tmp2;
8647 udivL_reg_reg(tmp1, src1, src2);
8648 mulL_reg_reg(tmp2, src2, tmp1);
8649 subL_reg_reg(dst, src1, tmp2);
8650 %}
8651 %}
8652
8653 // Integer Shift Instructions
8654
8655 // Register Shift Left
8656
8657 // Clear all but the lowest #mask bits.
8658 // Used to normalize shift amounts in registers.
8659 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
8660 // no match-rule, false predicate
8661 effect(DEF dst, USE src, USE mask);
8662 predicate(false);
8663
8664 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %}
8665 size(4);
8666 ins_encode %{
8667 __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
8668 %}
8669 ins_pipe(pipe_class_default);
8670 %}
8671
8672 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8673 // no match-rule, false predicate
8674 effect(DEF dst, USE src1, USE src2);
8675 predicate(false);
8676
8677 format %{ "SLW $dst, $src1, $src2" %}
8678 size(4);
8679 ins_encode %{
8680 __ slw($dst$$Register, $src1$$Register, $src2$$Register);
8681 %}
8682 ins_pipe(pipe_class_default);
8683 %}
8684
8685 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8686 match(Set dst (LShiftI src1 src2));
8687 ins_cost(DEFAULT_COST*2);
8688 expand %{
8689 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8690 iRegIdst tmpI;
8691 maskI_reg_imm(tmpI, src2, mask);
8692 lShiftI_reg_reg(dst, src1, tmpI);
8693 %}
8694 %}
8695
8696 // Register Shift Left Immediate
8697 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8698 match(Set dst (LShiftI src1 src2));
8699
8700 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %}
8701 size(4);
8702 ins_encode %{
8703 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8704 %}
8705 ins_pipe(pipe_class_default);
8706 %}
8707
8708 // AndI with negpow2-constant + LShiftI
8709 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8710 match(Set dst (LShiftI (AndI src1 src2) src3));
8711 predicate(UseRotateAndMaskInstructionsPPC64);
8712
8713 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %}
8714 size(4);
8715 ins_encode %{
8716 long src3 = $src3$$constant;
8717 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8718 if (maskbits >= 32) {
8719 __ li($dst$$Register, 0); // addi
8720 } else {
8721 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
8722 }
8723 %}
8724 ins_pipe(pipe_class_default);
8725 %}
8726
8727 // RShiftI + AndI with negpow2-constant + LShiftI
8728 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8729 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
8730 predicate(UseRotateAndMaskInstructionsPPC64);
8731
8732 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
8733 size(4);
8734 ins_encode %{
8735 long src3 = $src3$$constant;
8736 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8737 if (maskbits >= 32) {
8738 __ li($dst$$Register, 0); // addi
8739 } else {
8740 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
8741 }
8742 %}
8743 ins_pipe(pipe_class_default);
8744 %}
8745
8746 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8747 // no match-rule, false predicate
8748 effect(DEF dst, USE src1, USE src2);
8749 predicate(false);
8750
8751 format %{ "SLD $dst, $src1, $src2" %}
8752 size(4);
8753 ins_encode %{
8754 __ sld($dst$$Register, $src1$$Register, $src2$$Register);
8755 %}
8756 ins_pipe(pipe_class_default);
8757 %}
8758
8759 // Register Shift Left
8760 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8761 match(Set dst (LShiftL src1 src2));
8762 ins_cost(DEFAULT_COST*2);
8763 expand %{
8764 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8765 iRegIdst tmpI;
8766 maskI_reg_imm(tmpI, src2, mask);
8767 lShiftL_regL_regI(dst, src1, tmpI);
8768 %}
8769 %}
8770
8771 // Register Shift Left Immediate
8772 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8773 match(Set dst (LShiftL src1 src2));
8774 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %}
8775 size(4);
8776 ins_encode %{
8777 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8778 %}
8779 ins_pipe(pipe_class_default);
8780 %}
8781
8782 // If we shift more than 32 bits, we need not convert I2L.
8783 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
8784 match(Set dst (LShiftL (ConvI2L src1) src2));
8785 ins_cost(DEFAULT_COST);
8786
8787 size(4);
8788 format %{ "SLDI $dst, i2l($src1), $src2" %}
8789 ins_encode %{
8790 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8791 %}
8792 ins_pipe(pipe_class_default);
8793 %}
8794
8795 // Shift a postivie int to the left.
8796 // Clrlsldi clears the upper 32 bits and shifts.
8797 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
8798 match(Set dst (LShiftL (ConvI2L src1) src2));
8799 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
8800
8801 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %}
8802 size(4);
8803 ins_encode %{
8804 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
8805 %}
8806 ins_pipe(pipe_class_default);
8807 %}
8808
8809 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8810 // no match-rule, false predicate
8811 effect(DEF dst, USE src1, USE src2);
8812 predicate(false);
8813
8814 format %{ "SRAW $dst, $src1, $src2" %}
8815 size(4);
8816 ins_encode %{
8817 __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
8818 %}
8819 ins_pipe(pipe_class_default);
8820 %}
8821
8822 // Register Arithmetic Shift Right
8823 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8824 match(Set dst (RShiftI src1 src2));
8825 ins_cost(DEFAULT_COST*2);
8826 expand %{
8827 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8828 iRegIdst tmpI;
8829 maskI_reg_imm(tmpI, src2, mask);
8830 arShiftI_reg_reg(dst, src1, tmpI);
8831 %}
8832 %}
8833
8834 // Register Arithmetic Shift Right Immediate
8835 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8836 match(Set dst (RShiftI src1 src2));
8837
8838 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %}
8839 size(4);
8840 ins_encode %{
8841 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8842 %}
8843 ins_pipe(pipe_class_default);
8844 %}
8845
8846 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8847 // no match-rule, false predicate
8848 effect(DEF dst, USE src1, USE src2);
8849 predicate(false);
8850
8851 format %{ "SRAD $dst, $src1, $src2" %}
8852 size(4);
8853 ins_encode %{
8854 __ srad($dst$$Register, $src1$$Register, $src2$$Register);
8855 %}
8856 ins_pipe(pipe_class_default);
8857 %}
8858
8859 // Register Shift Right Arithmetic Long
8860 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8861 match(Set dst (RShiftL src1 src2));
8862 ins_cost(DEFAULT_COST*2);
8863
8864 expand %{
8865 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8866 iRegIdst tmpI;
8867 maskI_reg_imm(tmpI, src2, mask);
8868 arShiftL_regL_regI(dst, src1, tmpI);
8869 %}
8870 %}
8871
8872 // Register Shift Right Immediate
8873 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8874 match(Set dst (RShiftL src1 src2));
8875
8876 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %}
8877 size(4);
8878 ins_encode %{
8879 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8880 %}
8881 ins_pipe(pipe_class_default);
8882 %}
8883
8884 // RShiftL + ConvL2I
8885 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8886 match(Set dst (ConvL2I (RShiftL src1 src2)));
8887
8888 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8889 size(4);
8890 ins_encode %{
8891 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8892 %}
8893 ins_pipe(pipe_class_default);
8894 %}
8895
8896 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8897 // no match-rule, false predicate
8898 effect(DEF dst, USE src1, USE src2);
8899 predicate(false);
8900
8901 format %{ "SRW $dst, $src1, $src2" %}
8902 size(4);
8903 ins_encode %{
8904 __ srw($dst$$Register, $src1$$Register, $src2$$Register);
8905 %}
8906 ins_pipe(pipe_class_default);
8907 %}
8908
8909 // Register Shift Right
8910 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8911 match(Set dst (URShiftI src1 src2));
8912 ins_cost(DEFAULT_COST*2);
8913
8914 expand %{
8915 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8916 iRegIdst tmpI;
8917 maskI_reg_imm(tmpI, src2, mask);
8918 urShiftI_reg_reg(dst, src1, tmpI);
8919 %}
8920 %}
8921
8922 // Register Shift Right Immediate
8923 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8924 match(Set dst (URShiftI src1 src2));
8925
8926 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %}
8927 size(4);
8928 ins_encode %{
8929 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8930 %}
8931 ins_pipe(pipe_class_default);
8932 %}
8933
8934 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8935 // no match-rule, false predicate
8936 effect(DEF dst, USE src1, USE src2);
8937 predicate(false);
8938
8939 format %{ "SRD $dst, $src1, $src2" %}
8940 size(4);
8941 ins_encode %{
8942 __ srd($dst$$Register, $src1$$Register, $src2$$Register);
8943 %}
8944 ins_pipe(pipe_class_default);
8945 %}
8946
8947 // Register Shift Right
8948 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8949 match(Set dst (URShiftL src1 src2));
8950 ins_cost(DEFAULT_COST*2);
8951
8952 expand %{
8953 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8954 iRegIdst tmpI;
8955 maskI_reg_imm(tmpI, src2, mask);
8956 urShiftL_regL_regI(dst, src1, tmpI);
8957 %}
8958 %}
8959
8960 // Register Shift Right Immediate
8961 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8962 match(Set dst (URShiftL src1 src2));
8963
8964 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %}
8965 size(4);
8966 ins_encode %{
8967 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8968 %}
8969 ins_pipe(pipe_class_default);
8970 %}
8971
8972 // URShiftL + ConvL2I.
8973 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8974 match(Set dst (ConvL2I (URShiftL src1 src2)));
8975
8976 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8977 size(4);
8978 ins_encode %{
8979 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8980 %}
8981 ins_pipe(pipe_class_default);
8982 %}
8983
8984 // Register Shift Right Immediate with a CastP2X
8985 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
8986 match(Set dst (URShiftL (CastP2X src1) src2));
8987
8988 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
8989 size(4);
8990 ins_encode %{
8991 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8992 %}
8993 ins_pipe(pipe_class_default);
8994 %}
8995
8996 // Bitfield Extract: URShiftI + AndI
8997 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
8998 match(Set dst (AndI (URShiftI src1 src2) src3));
8999
9000 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
9001 size(4);
9002 ins_encode %{
9003 int rshift = ($src2$$constant) & 0x1f;
9004 int length = log2i_exact((juint)$src3$$constant + 1u);
9005 if (rshift + length > 32) {
9006 // if necessary, adjust mask to omit rotated bits.
9007 length = 32 - rshift;
9008 }
9009 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
9010 %}
9011 ins_pipe(pipe_class_default);
9012 %}
9013
9014 // Bitfield Extract: URShiftL + AndL
9015 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
9016 match(Set dst (AndL (URShiftL src1 src2) src3));
9017
9018 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
9019 size(4);
9020 ins_encode %{
9021 int rshift = ($src2$$constant) & 0x3f;
9022 int length = log2i_exact((julong)$src3$$constant + 1ull);
9023 if (rshift + length > 64) {
9024 // if necessary, adjust mask to omit rotated bits.
9025 length = 64 - rshift;
9026 }
9027 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
9028 %}
9029 ins_pipe(pipe_class_default);
9030 %}
9031
9032 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
9033 match(Set dst (ConvL2I (ConvI2L src)));
9034
9035 format %{ "EXTSW $dst, $src \t// int->int" %}
9036 size(4);
9037 ins_encode %{
9038 __ extsw($dst$$Register, $src$$Register);
9039 %}
9040 ins_pipe(pipe_class_default);
9041 %}
9042
9043 //----------Rotate Instructions------------------------------------------------
9044
9045 // Rotate Left by 8-bit immediate
9046 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
9047 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
9048 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9049
9050 format %{ "ROTLWI $dst, $src, $lshift" %}
9051 size(4);
9052 ins_encode %{
9053 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
9054 %}
9055 ins_pipe(pipe_class_default);
9056 %}
9057
9058 // Rotate Right by 8-bit immediate
9059 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
9060 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
9061 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9062
9063 format %{ "ROTRWI $dst, $rshift" %}
9064 size(4);
9065 ins_encode %{
9066 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
9067 %}
9068 ins_pipe(pipe_class_default);
9069 %}
9070
9071 //----------Floating Point Arithmetic Instructions-----------------------------
9072
9073 // Add float single precision
9074 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
9075 match(Set dst (AddF src1 src2));
9076
9077 format %{ "FADDS $dst, $src1, $src2" %}
9078 size(4);
9079 ins_encode %{
9080 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9081 %}
9082 ins_pipe(pipe_class_default);
9083 %}
9084
9085 // Add float double precision
9086 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
9087 match(Set dst (AddD src1 src2));
9088
9089 format %{ "FADD $dst, $src1, $src2" %}
9090 size(4);
9091 ins_encode %{
9092 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9093 %}
9094 ins_pipe(pipe_class_default);
9095 %}
9096
9097 // Sub float single precision
9098 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
9099 match(Set dst (SubF src1 src2));
9100
9101 format %{ "FSUBS $dst, $src1, $src2" %}
9102 size(4);
9103 ins_encode %{
9104 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9105 %}
9106 ins_pipe(pipe_class_default);
9107 %}
9108
9109 // Sub float double precision
9110 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
9111 match(Set dst (SubD src1 src2));
9112 format %{ "FSUB $dst, $src1, $src2" %}
9113 size(4);
9114 ins_encode %{
9115 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9116 %}
9117 ins_pipe(pipe_class_default);
9118 %}
9119
9120 // Mul float single precision
9121 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
9122 match(Set dst (MulF src1 src2));
9123 format %{ "FMULS $dst, $src1, $src2" %}
9124 size(4);
9125 ins_encode %{
9126 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9127 %}
9128 ins_pipe(pipe_class_default);
9129 %}
9130
9131 // Mul float double precision
9132 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
9133 match(Set dst (MulD src1 src2));
9134 format %{ "FMUL $dst, $src1, $src2" %}
9135 size(4);
9136 ins_encode %{
9137 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9138 %}
9139 ins_pipe(pipe_class_default);
9140 %}
9141
9142 // Div float single precision
9143 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
9144 match(Set dst (DivF src1 src2));
9145 format %{ "FDIVS $dst, $src1, $src2" %}
9146 size(4);
9147 ins_encode %{
9148 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9149 %}
9150 ins_pipe(pipe_class_default);
9151 %}
9152
9153 // Div float double precision
9154 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
9155 match(Set dst (DivD src1 src2));
9156 format %{ "FDIV $dst, $src1, $src2" %}
9157 size(4);
9158 ins_encode %{
9159 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9160 %}
9161 ins_pipe(pipe_class_default);
9162 %}
9163
9164 // Absolute float single precision
9165 instruct absF_reg(regF dst, regF src) %{
9166 match(Set dst (AbsF src));
9167 format %{ "FABS $dst, $src \t// float" %}
9168 size(4);
9169 ins_encode %{
9170 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
9171 %}
9172 ins_pipe(pipe_class_default);
9173 %}
9174
9175 // Absolute float double precision
9176 instruct absD_reg(regD dst, regD src) %{
9177 match(Set dst (AbsD src));
9178 format %{ "FABS $dst, $src \t// double" %}
9179 size(4);
9180 ins_encode %{
9181 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
9182 %}
9183 ins_pipe(pipe_class_default);
9184 %}
9185
9186 instruct negF_reg(regF dst, regF src) %{
9187 match(Set dst (NegF src));
9188 format %{ "FNEG $dst, $src \t// float" %}
9189 size(4);
9190 ins_encode %{
9191 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
9192 %}
9193 ins_pipe(pipe_class_default);
9194 %}
9195
9196 instruct negD_reg(regD dst, regD src) %{
9197 match(Set dst (NegD src));
9198 format %{ "FNEG $dst, $src \t// double" %}
9199 size(4);
9200 ins_encode %{
9201 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
9202 %}
9203 ins_pipe(pipe_class_default);
9204 %}
9205
9206 // AbsF + NegF.
9207 instruct negF_absF_reg(regF dst, regF src) %{
9208 match(Set dst (NegF (AbsF src)));
9209 format %{ "FNABS $dst, $src \t// float" %}
9210 size(4);
9211 ins_encode %{
9212 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9213 %}
9214 ins_pipe(pipe_class_default);
9215 %}
9216
9217 // AbsD + NegD.
9218 instruct negD_absD_reg(regD dst, regD src) %{
9219 match(Set dst (NegD (AbsD src)));
9220 format %{ "FNABS $dst, $src \t// double" %}
9221 size(4);
9222 ins_encode %{
9223 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9224 %}
9225 ins_pipe(pipe_class_default);
9226 %}
9227
9228 // Sqrt float double precision
9229 instruct sqrtD_reg(regD dst, regD src) %{
9230 match(Set dst (SqrtD src));
9231 format %{ "FSQRT $dst, $src" %}
9232 size(4);
9233 ins_encode %{
9234 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
9235 %}
9236 ins_pipe(pipe_class_default);
9237 %}
9238
9239 // Single-precision sqrt.
9240 instruct sqrtF_reg(regF dst, regF src) %{
9241 match(Set dst (SqrtF src));
9242 ins_cost(DEFAULT_COST);
9243
9244 format %{ "FSQRTS $dst, $src" %}
9245 size(4);
9246 ins_encode %{
9247 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
9248 %}
9249 ins_pipe(pipe_class_default);
9250 %}
9251
9252
9253 // Multiply-Accumulate
9254 // src1 * src2 + src3
9255 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9256 match(Set dst (FmaF src3 (Binary src1 src2)));
9257
9258 format %{ "FMADDS $dst, $src1, $src2, $src3" %}
9259 size(4);
9260 ins_encode %{
9261 assert(UseFMA, "Needs FMA instructions support.");
9262 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9263 %}
9264 ins_pipe(pipe_class_default);
9265 %}
9266
9267 // src1 * src2 + src3
9268 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9269 match(Set dst (FmaD src3 (Binary src1 src2)));
9270
9271 format %{ "FMADD $dst, $src1, $src2, $src3" %}
9272 size(4);
9273 ins_encode %{
9274 assert(UseFMA, "Needs FMA instructions support.");
9275 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9276 %}
9277 ins_pipe(pipe_class_default);
9278 %}
9279
9280 // src1 * (-src2) + src3 = -(src1*src2-src3)
9281 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9282 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9283 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
9284
9285 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
9286 size(4);
9287 ins_encode %{
9288 assert(UseFMA, "Needs FMA instructions support.");
9289 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9290 %}
9291 ins_pipe(pipe_class_default);
9292 %}
9293
9294 // src1 * (-src2) + src3 = -(src1*src2-src3)
9295 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9296 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9297 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
9298
9299 format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
9300 size(4);
9301 ins_encode %{
9302 assert(UseFMA, "Needs FMA instructions support.");
9303 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9304 %}
9305 ins_pipe(pipe_class_default);
9306 %}
9307
9308 // src1 * (-src2) - src3 = -(src1*src2+src3)
9309 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9310 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9311 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
9312
9313 format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
9314 size(4);
9315 ins_encode %{
9316 assert(UseFMA, "Needs FMA instructions support.");
9317 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9318 %}
9319 ins_pipe(pipe_class_default);
9320 %}
9321
9322 // src1 * (-src2) - src3 = -(src1*src2+src3)
9323 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9324 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9325 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9326
9327 format %{ "FNMADD $dst, $src1, $src2, $src3" %}
9328 size(4);
9329 ins_encode %{
9330 assert(UseFMA, "Needs FMA instructions support.");
9331 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9332 %}
9333 ins_pipe(pipe_class_default);
9334 %}
9335
9336 // src1 * src2 - src3
9337 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9338 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9339
9340 format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
9341 size(4);
9342 ins_encode %{
9343 assert(UseFMA, "Needs FMA instructions support.");
9344 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9345 %}
9346 ins_pipe(pipe_class_default);
9347 %}
9348
9349 // src1 * src2 - src3
9350 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9351 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9352
9353 format %{ "FMSUB $dst, $src1, $src2, $src3" %}
9354 size(4);
9355 ins_encode %{
9356 assert(UseFMA, "Needs FMA instructions support.");
9357 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9358 %}
9359 ins_pipe(pipe_class_default);
9360 %}
9361
9362
9363 //----------Logical Instructions-----------------------------------------------
9364
9365 // And Instructions
9366
9367 // Register And
9368 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9369 match(Set dst (AndI src1 src2));
9370 format %{ "AND $dst, $src1, $src2" %}
9371 size(4);
9372 ins_encode %{
9373 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9374 %}
9375 ins_pipe(pipe_class_default);
9376 %}
9377
9378 // Left shifted Immediate And
9379 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{
9380 match(Set dst (AndI src1 src2));
9381 effect(KILL cr0);
9382 format %{ "ANDIS $dst, $src1, $src2.hi" %}
9383 size(4);
9384 ins_encode %{
9385 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16)));
9386 %}
9387 ins_pipe(pipe_class_default);
9388 %}
9389
9390 // Immediate And
9391 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{
9392 match(Set dst (AndI src1 src2));
9393 effect(KILL cr0);
9394
9395 format %{ "ANDI $dst, $src1, $src2" %}
9396 size(4);
9397 ins_encode %{
9398 // FIXME: avoid andi_ ?
9399 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9400 %}
9401 ins_pipe(pipe_class_default);
9402 %}
9403
9404 // Immediate And where the immediate is a negative power of 2.
9405 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{
9406 match(Set dst (AndI src1 src2));
9407 format %{ "ANDWI $dst, $src1, $src2" %}
9408 size(4);
9409 ins_encode %{
9410 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant));
9411 %}
9412 ins_pipe(pipe_class_default);
9413 %}
9414
9415 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{
9416 match(Set dst (AndI src1 src2));
9417 format %{ "ANDWI $dst, $src1, $src2" %}
9418 size(4);
9419 ins_encode %{
9420 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u));
9421 %}
9422 ins_pipe(pipe_class_default);
9423 %}
9424
9425 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{
9426 match(Set dst (AndI src1 src2));
9427 predicate(UseRotateAndMaskInstructionsPPC64);
9428 format %{ "ANDWI $dst, $src1, $src2" %}
9429 size(4);
9430 ins_encode %{
9431 int bitpos = 31 - log2i_exact((juint)$src2$$constant);
9432 __ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos);
9433 %}
9434 ins_pipe(pipe_class_default);
9435 %}
9436
9437 // Register And Long
9438 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9439 match(Set dst (AndL src1 src2));
9440 ins_cost(DEFAULT_COST);
9441
9442 format %{ "AND $dst, $src1, $src2 \t// long" %}
9443 size(4);
9444 ins_encode %{
9445 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9446 %}
9447 ins_pipe(pipe_class_default);
9448 %}
9449
9450 // Immediate And long
9451 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
9452 match(Set dst (AndL src1 src2));
9453 effect(KILL cr0);
9454
9455 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9456 size(4);
9457 ins_encode %{
9458 // FIXME: avoid andi_ ?
9459 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9460 %}
9461 ins_pipe(pipe_class_default);
9462 %}
9463
9464 // Immediate And Long where the immediate is a negative power of 2.
9465 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
9466 match(Set dst (AndL src1 src2));
9467 format %{ "ANDDI $dst, $src1, $src2" %}
9468 size(4);
9469 ins_encode %{
9470 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant));
9471 %}
9472 ins_pipe(pipe_class_default);
9473 %}
9474
9475 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9476 match(Set dst (AndL src1 src2));
9477 format %{ "ANDDI $dst, $src1, $src2" %}
9478 size(4);
9479 ins_encode %{
9480 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9481 %}
9482 ins_pipe(pipe_class_default);
9483 %}
9484
9485 // AndL + ConvL2I.
9486 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9487 match(Set dst (ConvL2I (AndL src1 src2)));
9488 ins_cost(DEFAULT_COST);
9489
9490 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %}
9491 size(4);
9492 ins_encode %{
9493 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9494 %}
9495 ins_pipe(pipe_class_default);
9496 %}
9497
9498 // Or Instructions
9499
9500 // Register Or
9501 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9502 match(Set dst (OrI src1 src2));
9503 format %{ "OR $dst, $src1, $src2" %}
9504 size(4);
9505 ins_encode %{
9506 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9507 %}
9508 ins_pipe(pipe_class_default);
9509 %}
9510
9511 // Expand does not work with above instruct. (??)
9512 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9513 // no match-rule
9514 effect(DEF dst, USE src1, USE src2);
9515 format %{ "OR $dst, $src1, $src2" %}
9516 size(4);
9517 ins_encode %{
9518 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9519 %}
9520 ins_pipe(pipe_class_default);
9521 %}
9522
9523 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9524 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9525 ins_cost(DEFAULT_COST*3);
9526
9527 expand %{
9528 // FIXME: we should do this in the ideal world.
9529 iRegIdst tmp1;
9530 iRegIdst tmp2;
9531 orI_reg_reg(tmp1, src1, src2);
9532 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9533 orI_reg_reg(dst, tmp1, tmp2);
9534 %}
9535 %}
9536
9537 // Immediate Or
9538 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9539 match(Set dst (OrI src1 src2));
9540 format %{ "ORI $dst, $src1, $src2" %}
9541 size(4);
9542 ins_encode %{
9543 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9544 %}
9545 ins_pipe(pipe_class_default);
9546 %}
9547
9548 // Register Or Long
9549 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9550 match(Set dst (OrL src1 src2));
9551 ins_cost(DEFAULT_COST);
9552
9553 size(4);
9554 format %{ "OR $dst, $src1, $src2 \t// long" %}
9555 ins_encode %{
9556 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9557 %}
9558 ins_pipe(pipe_class_default);
9559 %}
9560
9561 // OrL + ConvL2I.
9562 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9563 match(Set dst (ConvL2I (OrL src1 src2)));
9564 ins_cost(DEFAULT_COST);
9565
9566 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %}
9567 size(4);
9568 ins_encode %{
9569 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9570 %}
9571 ins_pipe(pipe_class_default);
9572 %}
9573
9574 // Immediate Or long
9575 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9576 match(Set dst (OrL src1 con));
9577 ins_cost(DEFAULT_COST);
9578
9579 format %{ "ORI $dst, $src1, $con \t// long" %}
9580 size(4);
9581 ins_encode %{
9582 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9583 %}
9584 ins_pipe(pipe_class_default);
9585 %}
9586
9587 // Xor Instructions
9588
9589 // Register Xor
9590 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9591 match(Set dst (XorI src1 src2));
9592 format %{ "XOR $dst, $src1, $src2" %}
9593 size(4);
9594 ins_encode %{
9595 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9596 %}
9597 ins_pipe(pipe_class_default);
9598 %}
9599
9600 // Expand does not work with above instruct. (??)
9601 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9602 // no match-rule
9603 effect(DEF dst, USE src1, USE src2);
9604 format %{ "XOR $dst, $src1, $src2" %}
9605 size(4);
9606 ins_encode %{
9607 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9608 %}
9609 ins_pipe(pipe_class_default);
9610 %}
9611
9612 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9613 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
9614 ins_cost(DEFAULT_COST*3);
9615
9616 expand %{
9617 // FIXME: we should do this in the ideal world.
9618 iRegIdst tmp1;
9619 iRegIdst tmp2;
9620 xorI_reg_reg(tmp1, src1, src2);
9621 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
9622 xorI_reg_reg(dst, tmp1, tmp2);
9623 %}
9624 %}
9625
9626 // Immediate Xor
9627 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9628 match(Set dst (XorI src1 src2));
9629 format %{ "XORI $dst, $src1, $src2" %}
9630 size(4);
9631 ins_encode %{
9632 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9633 %}
9634 ins_pipe(pipe_class_default);
9635 %}
9636
9637 // Register Xor Long
9638 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9639 match(Set dst (XorL src1 src2));
9640 ins_cost(DEFAULT_COST);
9641
9642 format %{ "XOR $dst, $src1, $src2 \t// long" %}
9643 size(4);
9644 ins_encode %{
9645 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9646 %}
9647 ins_pipe(pipe_class_default);
9648 %}
9649
9650 // XorL + ConvL2I.
9651 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9652 match(Set dst (ConvL2I (XorL src1 src2)));
9653 ins_cost(DEFAULT_COST);
9654
9655 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %}
9656 size(4);
9657 ins_encode %{
9658 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9659 %}
9660 ins_pipe(pipe_class_default);
9661 %}
9662
9663 // Immediate Xor Long
9664 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
9665 match(Set dst (XorL src1 src2));
9666 ins_cost(DEFAULT_COST);
9667
9668 format %{ "XORI $dst, $src1, $src2 \t// long" %}
9669 size(4);
9670 ins_encode %{
9671 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9672 %}
9673 ins_pipe(pipe_class_default);
9674 %}
9675
9676 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
9677 match(Set dst (XorI src1 src2));
9678 ins_cost(DEFAULT_COST);
9679
9680 format %{ "NOT $dst, $src1 ($src2)" %}
9681 size(4);
9682 ins_encode %{
9683 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9684 %}
9685 ins_pipe(pipe_class_default);
9686 %}
9687
9688 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
9689 match(Set dst (XorL src1 src2));
9690 ins_cost(DEFAULT_COST);
9691
9692 format %{ "NOT $dst, $src1 ($src2) \t// long" %}
9693 size(4);
9694 ins_encode %{
9695 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9696 %}
9697 ins_pipe(pipe_class_default);
9698 %}
9699
9700 // And-complement
9701 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
9702 match(Set dst (AndI (XorI src1 src2) src3));
9703 ins_cost(DEFAULT_COST);
9704
9705 format %{ "ANDW $dst, xori($src1, $src2), $src3" %}
9706 size(4);
9707 ins_encode( enc_andc(dst, src3, src1) );
9708 ins_pipe(pipe_class_default);
9709 %}
9710
9711 // And-complement
9712 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9713 // no match-rule, false predicate
9714 effect(DEF dst, USE src1, USE src2);
9715 predicate(false);
9716
9717 format %{ "ANDC $dst, $src1, $src2" %}
9718 size(4);
9719 ins_encode %{
9720 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
9721 %}
9722 ins_pipe(pipe_class_default);
9723 %}
9724
9725 //----------Moves between int/long and float/double----------------------------
9726 //
9727 // The following rules move values from int/long registers/stack-locations
9728 // to float/double registers/stack-locations and vice versa, without doing any
9729 // conversions. These rules are used to implement the bit-conversion methods
9730 // of java.lang.Float etc., e.g.
9731 // int floatToIntBits(float value)
9732 // float intBitsToFloat(int bits)
9733
9734 instruct moveL2D_reg(regD dst, iRegLsrc src) %{
9735 match(Set dst (MoveL2D src));
9736
9737 format %{ "MTFPRD $dst, $src" %}
9738 size(4);
9739 ins_encode %{
9740 __ mtfprd($dst$$FloatRegister, $src$$Register);
9741 %}
9742 ins_pipe(pipe_class_default);
9743 %}
9744
9745 instruct moveI2D_reg(regD dst, iRegIsrc src) %{
9746 // no match-rule, false predicate
9747 effect(DEF dst, USE src);
9748 predicate(false);
9749
9750 format %{ "MTFPRWA $dst, $src" %}
9751 size(4);
9752 ins_encode %{
9753 __ mtfprwa($dst$$FloatRegister, $src$$Register);
9754 %}
9755 ins_pipe(pipe_class_default);
9756 %}
9757
9758 //---------- Chain stack slots between similar types --------
9759
9760 // These are needed so that the rules below can match.
9761
9762 // Load integer from stack slot
9763 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
9764 match(Set dst src);
9765 ins_cost(MEMORY_REF_COST);
9766
9767 format %{ "LWZ $dst, $src" %}
9768 size(4);
9769 ins_encode( enc_lwz(dst, src) );
9770 ins_pipe(pipe_class_memory);
9771 %}
9772
9773 // Store integer to stack slot
9774 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
9775 match(Set dst src);
9776 ins_cost(MEMORY_REF_COST);
9777
9778 format %{ "STW $src, $dst \t// stk" %}
9779 size(4);
9780 ins_encode( enc_stw(src, dst) ); // rs=rt
9781 ins_pipe(pipe_class_memory);
9782 %}
9783
9784 // Load long from stack slot
9785 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
9786 match(Set dst src);
9787 ins_cost(MEMORY_REF_COST);
9788
9789 format %{ "LD $dst, $src \t// long" %}
9790 size(4);
9791 ins_encode( enc_ld(dst, src) );
9792 ins_pipe(pipe_class_memory);
9793 %}
9794
9795 // Store long to stack slot
9796 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
9797 match(Set dst src);
9798 ins_cost(MEMORY_REF_COST);
9799
9800 format %{ "STD $src, $dst \t// long" %}
9801 size(4);
9802 ins_encode( enc_std(src, dst) ); // rs=rt
9803 ins_pipe(pipe_class_memory);
9804 %}
9805
9806 //----------Moves between int and float
9807
9808 // Move float value from float stack-location to integer register.
9809 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
9810 match(Set dst (MoveF2I src));
9811 ins_cost(MEMORY_REF_COST);
9812
9813 format %{ "LWZ $dst, $src \t// MoveF2I" %}
9814 size(4);
9815 ins_encode( enc_lwz(dst, src) );
9816 ins_pipe(pipe_class_memory);
9817 %}
9818
9819 // Move float value from float register to integer stack-location.
9820 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
9821 match(Set dst (MoveF2I src));
9822 ins_cost(MEMORY_REF_COST);
9823
9824 format %{ "STFS $src, $dst \t// MoveF2I" %}
9825 size(4);
9826 ins_encode( enc_stfs(src, dst) );
9827 ins_pipe(pipe_class_memory);
9828 %}
9829
9830 // Move integer value from integer stack-location to float register.
9831 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
9832 match(Set dst (MoveI2F src));
9833 ins_cost(MEMORY_REF_COST);
9834
9835 format %{ "LFS $dst, $src \t// MoveI2F" %}
9836 size(4);
9837 ins_encode %{
9838 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
9839 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
9840 %}
9841 ins_pipe(pipe_class_memory);
9842 %}
9843
9844 // Move integer value from integer register to float stack-location.
9845 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
9846 match(Set dst (MoveI2F src));
9847 ins_cost(MEMORY_REF_COST);
9848
9849 format %{ "STW $src, $dst \t// MoveI2F" %}
9850 size(4);
9851 ins_encode( enc_stw(src, dst) );
9852 ins_pipe(pipe_class_memory);
9853 %}
9854
9855
9856 //----------Moves between long and double
9857
9858 // Move double value from double stack-location to long register.
9859 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
9860 match(Set dst (MoveD2L src));
9861 ins_cost(MEMORY_REF_COST);
9862 size(4);
9863 format %{ "LD $dst, $src \t// MoveD2L" %}
9864 ins_encode( enc_ld(dst, src) );
9865 ins_pipe(pipe_class_memory);
9866 %}
9867
9868 // Move double value from double register to long stack-location.
9869 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
9870 match(Set dst (MoveD2L src));
9871 effect(DEF dst, USE src);
9872 ins_cost(MEMORY_REF_COST);
9873
9874 format %{ "STFD $src, $dst \t// MoveD2L" %}
9875 size(4);
9876 ins_encode( enc_stfd(src, dst) );
9877 ins_pipe(pipe_class_memory);
9878 %}
9879
9880
9881 //----------Register Move Instructions-----------------------------------------
9882
9883 // Replicate for Superword
9884
9885 instruct moveReg(iRegLdst dst, iRegIsrc src) %{
9886 predicate(false);
9887 effect(DEF dst, USE src);
9888
9889 format %{ "MR $dst, $src \t// replicate " %}
9890 // variable size, 0 or 4.
9891 ins_encode %{
9892 __ mr_if_needed($dst$$Register, $src$$Register);
9893 %}
9894 ins_pipe(pipe_class_default);
9895 %}
9896
9897 //----------Cast instructions (Java-level type cast)---------------------------
9898
9899 // Cast Long to Pointer for unsafe natives.
9900 instruct castX2P(iRegPdst dst, iRegLsrc src) %{
9901 match(Set dst (CastX2P src));
9902
9903 format %{ "MR $dst, $src \t// Long->Ptr" %}
9904 // variable size, 0 or 4.
9905 ins_encode %{
9906 __ mr_if_needed($dst$$Register, $src$$Register);
9907 %}
9908 ins_pipe(pipe_class_default);
9909 %}
9910
9911 // Cast Pointer to Long for unsafe natives.
9912 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
9913 match(Set dst (CastP2X src));
9914
9915 format %{ "MR $dst, $src \t// Ptr->Long" %}
9916 // variable size, 0 or 4.
9917 ins_encode %{
9918 __ mr_if_needed($dst$$Register, $src$$Register);
9919 %}
9920 ins_pipe(pipe_class_default);
9921 %}
9922
9923 instruct castPP(iRegPdst dst) %{
9924 match(Set dst (CastPP dst));
9925 format %{ " -- \t// castPP of $dst" %}
9926 size(0);
9927 ins_encode( /*empty*/ );
9928 ins_pipe(pipe_class_default);
9929 %}
9930
9931 instruct castII(iRegIdst dst) %{
9932 match(Set dst (CastII dst));
9933 format %{ " -- \t// castII of $dst" %}
9934 size(0);
9935 ins_encode( /*empty*/ );
9936 ins_pipe(pipe_class_default);
9937 %}
9938
9939 instruct castLL(iRegLdst dst) %{
9940 match(Set dst (CastLL dst));
9941 format %{ " -- \t// castLL of $dst" %}
9942 size(0);
9943 ins_encode( /*empty*/ );
9944 ins_pipe(pipe_class_default);
9945 %}
9946
9947 instruct castFF(regF dst) %{
9948 match(Set dst (CastFF dst));
9949 format %{ " -- \t// castFF of $dst" %}
9950 size(0);
9951 ins_encode( /*empty*/ );
9952 ins_pipe(pipe_class_default);
9953 %}
9954
9955 instruct castDD(regD dst) %{
9956 match(Set dst (CastDD dst));
9957 format %{ " -- \t// castDD of $dst" %}
9958 size(0);
9959 ins_encode( /*empty*/ );
9960 ins_pipe(pipe_class_default);
9961 %}
9962
9963 instruct castVV8(iRegLdst dst) %{
9964 match(Set dst (CastVV dst));
9965 format %{ " -- \t// castVV of $dst" %}
9966 size(0);
9967 ins_encode( /*empty*/ );
9968 ins_pipe(pipe_class_default);
9969 %}
9970
9971 instruct castVV16(vecX dst) %{
9972 match(Set dst (CastVV dst));
9973 format %{ " -- \t// castVV of $dst" %}
9974 size(0);
9975 ins_encode( /*empty*/ );
9976 ins_pipe(pipe_class_default);
9977 %}
9978
9979 instruct checkCastPP(iRegPdst dst) %{
9980 match(Set dst (CheckCastPP dst));
9981 format %{ " -- \t// checkcastPP of $dst" %}
9982 size(0);
9983 ins_encode( /*empty*/ );
9984 ins_pipe(pipe_class_default);
9985 %}
9986
9987 //----------Convert instructions-----------------------------------------------
9988
9989 // Convert to boolean.
9990
9991 // int_to_bool(src) : { 1 if src != 0
9992 // { 0 else
9993 //
9994 // strategy:
9995 // 1) Count leading zeros of 32 bit-value src,
9996 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
9997 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9998 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9999
10000 // convI2Bool
10001 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
10002 match(Set dst (Conv2B src));
10003 predicate(UseCountLeadingZerosInstructionsPPC64);
10004 ins_cost(DEFAULT_COST);
10005
10006 expand %{
10007 immI shiftAmount %{ 0x5 %}
10008 uimmI16 mask %{ 0x1 %}
10009 iRegIdst tmp1;
10010 iRegIdst tmp2;
10011 countLeadingZerosI(tmp1, src);
10012 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
10013 xorI_reg_uimm16(dst, tmp2, mask);
10014 %}
10015 %}
10016
10017 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
10018 match(Set dst (Conv2B src));
10019 effect(TEMP crx);
10020 predicate(!UseCountLeadingZerosInstructionsPPC64);
10021 ins_cost(DEFAULT_COST);
10022
10023 format %{ "CMPWI $crx, $src, #0 \t// convI2B"
10024 "LI $dst, #0\n\t"
10025 "BEQ $crx, done\n\t"
10026 "LI $dst, #1\n"
10027 "done:" %}
10028 size(16);
10029 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
10030 ins_pipe(pipe_class_compare);
10031 %}
10032
10033 // ConvI2B + XorI
10034 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
10035 match(Set dst (XorI (Conv2B src) mask));
10036 predicate(UseCountLeadingZerosInstructionsPPC64);
10037 ins_cost(DEFAULT_COST);
10038
10039 expand %{
10040 immI shiftAmount %{ 0x5 %}
10041 iRegIdst tmp1;
10042 countLeadingZerosI(tmp1, src);
10043 urShiftI_reg_imm(dst, tmp1, shiftAmount);
10044 %}
10045 %}
10046
10047 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
10048 match(Set dst (XorI (Conv2B src) mask));
10049 effect(TEMP crx);
10050 predicate(!UseCountLeadingZerosInstructionsPPC64);
10051 ins_cost(DEFAULT_COST);
10052
10053 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
10054 "LI $dst, #1\n\t"
10055 "BEQ $crx, done\n\t"
10056 "LI $dst, #0\n"
10057 "done:" %}
10058 size(16);
10059 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
10060 ins_pipe(pipe_class_compare);
10061 %}
10062
10063 // AndI 0b0..010..0 + ConvI2B
10064 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
10065 match(Set dst (Conv2B (AndI src mask)));
10066 predicate(UseRotateAndMaskInstructionsPPC64);
10067 ins_cost(DEFAULT_COST);
10068
10069 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
10070 size(4);
10071 ins_encode %{
10072 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31);
10073 %}
10074 ins_pipe(pipe_class_default);
10075 %}
10076
10077 // Convert pointer to boolean.
10078 //
10079 // ptr_to_bool(src) : { 1 if src != 0
10080 // { 0 else
10081 //
10082 // strategy:
10083 // 1) Count leading zeros of 64 bit-value src,
10084 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
10085 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
10086 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
10087
10088 // ConvP2B
10089 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
10090 match(Set dst (Conv2B src));
10091 predicate(UseCountLeadingZerosInstructionsPPC64);
10092 ins_cost(DEFAULT_COST);
10093
10094 expand %{
10095 immI shiftAmount %{ 0x6 %}
10096 uimmI16 mask %{ 0x1 %}
10097 iRegIdst tmp1;
10098 iRegIdst tmp2;
10099 countLeadingZerosP(tmp1, src);
10100 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
10101 xorI_reg_uimm16(dst, tmp2, mask);
10102 %}
10103 %}
10104
10105 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
10106 match(Set dst (Conv2B src));
10107 effect(TEMP crx);
10108 predicate(!UseCountLeadingZerosInstructionsPPC64);
10109 ins_cost(DEFAULT_COST);
10110
10111 format %{ "CMPDI $crx, $src, #0 \t// convP2B"
10112 "LI $dst, #0\n\t"
10113 "BEQ $crx, done\n\t"
10114 "LI $dst, #1\n"
10115 "done:" %}
10116 size(16);
10117 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
10118 ins_pipe(pipe_class_compare);
10119 %}
10120
10121 // ConvP2B + XorI
10122 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
10123 match(Set dst (XorI (Conv2B src) mask));
10124 predicate(UseCountLeadingZerosInstructionsPPC64);
10125 ins_cost(DEFAULT_COST);
10126
10127 expand %{
10128 immI shiftAmount %{ 0x6 %}
10129 iRegIdst tmp1;
10130 countLeadingZerosP(tmp1, src);
10131 urShiftI_reg_imm(dst, tmp1, shiftAmount);
10132 %}
10133 %}
10134
10135 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
10136 match(Set dst (XorI (Conv2B src) mask));
10137 effect(TEMP crx);
10138 predicate(!UseCountLeadingZerosInstructionsPPC64);
10139 ins_cost(DEFAULT_COST);
10140
10141 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
10142 "LI $dst, #1\n\t"
10143 "BEQ $crx, done\n\t"
10144 "LI $dst, #0\n"
10145 "done:" %}
10146 size(16);
10147 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
10148 ins_pipe(pipe_class_compare);
10149 %}
10150
10151 // if src1 < src2, return -1 else return 0
10152 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
10153 match(Set dst (CmpLTMask src1 src2));
10154 ins_cost(DEFAULT_COST*4);
10155
10156 expand %{
10157 iRegLdst src1s;
10158 iRegLdst src2s;
10159 iRegLdst diff;
10160 convI2L_reg(src1s, src1); // Ensure proper sign extension.
10161 convI2L_reg(src2s, src2); // Ensure proper sign extension.
10162 subL_reg_reg(diff, src1s, src2s);
10163 // Need to consider >=33 bit result, therefore we need signmaskL.
10164 signmask64I_regL(dst, diff);
10165 %}
10166 %}
10167
10168 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
10169 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
10170 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %}
10171 size(4);
10172 ins_encode %{
10173 __ srawi($dst$$Register, $src1$$Register, 0x1f);
10174 %}
10175 ins_pipe(pipe_class_default);
10176 %}
10177
10178 //----------Arithmetic Conversion Instructions---------------------------------
10179
10180 // Convert to Byte -- nop
10181 // Convert to Short -- nop
10182
10183 // Convert to Int
10184
10185 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
10186 match(Set dst (RShiftI (LShiftI src amount) amount));
10187 format %{ "EXTSB $dst, $src \t// byte->int" %}
10188 size(4);
10189 ins_encode %{
10190 __ extsb($dst$$Register, $src$$Register);
10191 %}
10192 ins_pipe(pipe_class_default);
10193 %}
10194
10195 instruct extsh(iRegIdst dst, iRegIsrc src) %{
10196 effect(DEF dst, USE src);
10197
10198 size(4);
10199 ins_encode %{
10200 __ extsh($dst$$Register, $src$$Register);
10201 %}
10202 ins_pipe(pipe_class_default);
10203 %}
10204
10205 // LShiftI 16 + RShiftI 16 converts short to int.
10206 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
10207 match(Set dst (RShiftI (LShiftI src amount) amount));
10208 format %{ "EXTSH $dst, $src \t// short->int" %}
10209 size(4);
10210 ins_encode %{
10211 __ extsh($dst$$Register, $src$$Register);
10212 %}
10213 ins_pipe(pipe_class_default);
10214 %}
10215
10216 // ConvL2I + ConvI2L: Sign extend int in long register.
10217 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
10218 match(Set dst (ConvI2L (ConvL2I src)));
10219
10220 format %{ "EXTSW $dst, $src \t// long->long" %}
10221 size(4);
10222 ins_encode %{
10223 __ extsw($dst$$Register, $src$$Register);
10224 %}
10225 ins_pipe(pipe_class_default);
10226 %}
10227
10228 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
10229 match(Set dst (ConvL2I src));
10230 format %{ "MR $dst, $src \t// long->int" %}
10231 // variable size, 0 or 4
10232 ins_encode %{
10233 __ mr_if_needed($dst$$Register, $src$$Register);
10234 %}
10235 ins_pipe(pipe_class_default);
10236 %}
10237
10238 instruct convD2IRaw_regD(regD dst, regD src) %{
10239 // no match-rule, false predicate
10240 effect(DEF dst, USE src);
10241 predicate(false);
10242
10243 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
10244 size(4);
10245 ins_encode %{
10246 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10247 %}
10248 ins_pipe(pipe_class_default);
10249 %}
10250
10251 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
10252 // no match-rule, false predicate
10253 effect(DEF dst, USE crx, USE src);
10254 predicate(false);
10255
10256 ins_variable_size_depending_on_alignment(true);
10257
10258 format %{ "CMOVI $crx, $dst, $src" %}
10259 size(8);
10260 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10261 ins_pipe(pipe_class_default);
10262 %}
10263
10264 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
10265 // no match-rule, false predicate
10266 effect(DEF dst, USE crx, USE src);
10267 predicate(false);
10268
10269 ins_variable_size_depending_on_alignment(true);
10270
10271 format %{ "CMOVI $crx, $dst, $src" %}
10272 size(8);
10273 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10274 ins_pipe(pipe_class_default);
10275 %}
10276
10277
10278 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{
10279 // no match-rule, false predicate
10280 effect(DEF dst, USE crx, USE src);
10281 predicate(false);
10282
10283 format %{ "CMOVI $dst, $crx, $src \t// postalloc expanded" %}
10284 postalloc_expand %{
10285 //
10286 // replaces
10287 //
10288 // region dst crx src
10289 // \ | | /
10290 // dst=cmovI_bso_reg_conLvalue0
10291 //
10292 // with
10293 //
10294 // region dst
10295 // \ /
10296 // dst=loadConI16(0)
10297 // |
10298 // ^ region dst crx src
10299 // | \ | | /
10300 // dst=cmovI_bso_reg
10301 //
10302
10303 // Create new nodes.
10304 MachNode *m1 = new loadConI16Node();
10305 MachNode *m2 = new cmovI_bso_regNode();
10306
10307 // inputs for new nodes
10308 m1->add_req(n_region);
10309 m2->add_req(n_region, n_crx, n_src);
10310
10311 // precedences for new nodes
10312 m2->add_prec(m1);
10313
10314 // operands for new nodes
10315 m1->_opnds[0] = op_dst;
10316 m1->_opnds[1] = new immI16Oper(0);
10317
10318 m2->_opnds[0] = op_dst;
10319 m2->_opnds[1] = op_crx;
10320 m2->_opnds[2] = op_src;
10321
10322 // registers for new nodes
10323 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10324 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10325
10326 // Insert new nodes.
10327 nodes->push(m1);
10328 nodes->push(m2);
10329 %}
10330 %}
10331
10332
10333 // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
10334 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
10335 match(Set dst (ConvD2I src));
10336 ins_cost(DEFAULT_COST);
10337
10338 expand %{
10339 regD tmpD;
10340 flagsReg crx;
10341 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10342 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
10343 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10344 %}
10345 %}
10346
10347 instruct convF2IRaw_regF(regF dst, regF src) %{
10348 // no match-rule, false predicate
10349 effect(DEF dst, USE src);
10350 predicate(false);
10351
10352 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
10353 size(4);
10354 ins_encode %{
10355 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10356 %}
10357 ins_pipe(pipe_class_default);
10358 %}
10359
10360
10361 // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
10362 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
10363 match(Set dst (ConvF2I src));
10364 ins_cost(DEFAULT_COST);
10365
10366 expand %{
10367 regF tmpF;
10368 flagsReg crx;
10369 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10370 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10371 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10372 %}
10373 %}
10374
10375 // Convert to Long
10376
10377 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
10378 match(Set dst (ConvI2L src));
10379 format %{ "EXTSW $dst, $src \t// int->long" %}
10380 size(4);
10381 ins_encode %{
10382 __ extsw($dst$$Register, $src$$Register);
10383 %}
10384 ins_pipe(pipe_class_default);
10385 %}
10386
10387 // Zero-extend: convert unsigned int to long (convUI2L).
10388 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
10389 match(Set dst (AndL (ConvI2L src) mask));
10390 ins_cost(DEFAULT_COST);
10391
10392 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10393 size(4);
10394 ins_encode %{
10395 __ clrldi($dst$$Register, $src$$Register, 32);
10396 %}
10397 ins_pipe(pipe_class_default);
10398 %}
10399
10400 // Zero-extend: convert unsigned int to long in long register.
10401 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
10402 match(Set dst (AndL src mask));
10403 ins_cost(DEFAULT_COST);
10404
10405 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10406 size(4);
10407 ins_encode %{
10408 __ clrldi($dst$$Register, $src$$Register, 32);
10409 %}
10410 ins_pipe(pipe_class_default);
10411 %}
10412
10413 instruct convF2LRaw_regF(regF dst, regF src) %{
10414 // no match-rule, false predicate
10415 effect(DEF dst, USE src);
10416 predicate(false);
10417
10418 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10419 size(4);
10420 ins_encode %{
10421 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10422 %}
10423 ins_pipe(pipe_class_default);
10424 %}
10425
10426 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
10427 // no match-rule, false predicate
10428 effect(DEF dst, USE crx, USE src);
10429 predicate(false);
10430
10431 ins_variable_size_depending_on_alignment(true);
10432
10433 format %{ "CMOVL $crx, $dst, $src" %}
10434 size(8);
10435 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10436 ins_pipe(pipe_class_default);
10437 %}
10438
10439 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
10440 // no match-rule, false predicate
10441 effect(DEF dst, USE crx, USE src);
10442 predicate(false);
10443
10444 ins_variable_size_depending_on_alignment(true);
10445
10446 format %{ "CMOVL $crx, $dst, $src" %}
10447 size(8);
10448 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10449 ins_pipe(pipe_class_default);
10450 %}
10451
10452
10453 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{
10454 // no match-rule, false predicate
10455 effect(DEF dst, USE crx, USE src);
10456 predicate(false);
10457
10458 format %{ "CMOVL $dst, $crx, $src \t// postalloc expanded" %}
10459 postalloc_expand %{
10460 //
10461 // replaces
10462 //
10463 // region dst crx src
10464 // \ | | /
10465 // dst=cmovL_bso_reg_conLvalue0
10466 //
10467 // with
10468 //
10469 // region dst
10470 // \ /
10471 // dst=loadConL16(0)
10472 // |
10473 // ^ region dst crx src
10474 // | \ | | /
10475 // dst=cmovL_bso_reg
10476 //
10477
10478 // Create new nodes.
10479 MachNode *m1 = new loadConL16Node();
10480 MachNode *m2 = new cmovL_bso_regNode();
10481
10482 // inputs for new nodes
10483 m1->add_req(n_region);
10484 m2->add_req(n_region, n_crx, n_src);
10485 m2->add_prec(m1);
10486
10487 // operands for new nodes
10488 m1->_opnds[0] = op_dst;
10489 m1->_opnds[1] = new immL16Oper(0);
10490 m2->_opnds[0] = op_dst;
10491 m2->_opnds[1] = op_crx;
10492 m2->_opnds[2] = op_src;
10493
10494 // registers for new nodes
10495 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10496 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10497
10498 // Insert new nodes.
10499 nodes->push(m1);
10500 nodes->push(m2);
10501 %}
10502 %}
10503
10504
10505 // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
10506 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
10507 match(Set dst (ConvF2L src));
10508 ins_cost(DEFAULT_COST);
10509
10510 expand %{
10511 regF tmpF;
10512 flagsReg crx;
10513 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10514 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
10515 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10516 %}
10517 %}
10518
10519 instruct convD2LRaw_regD(regD dst, regD src) %{
10520 // no match-rule, false predicate
10521 effect(DEF dst, USE src);
10522 predicate(false);
10523
10524 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
10525 size(4);
10526 ins_encode %{
10527 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10528 %}
10529 ins_pipe(pipe_class_default);
10530 %}
10531
10532
10533 // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
10534 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
10535 match(Set dst (ConvD2L src));
10536 ins_cost(DEFAULT_COST);
10537
10538 expand %{
10539 regD tmpD;
10540 flagsReg crx;
10541 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10542 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
10543 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10544 %}
10545 %}
10546
10547 // Convert to Float
10548
10549 // Placed here as needed in expand.
10550 instruct convL2DRaw_regD(regD dst, regD src) %{
10551 // no match-rule, false predicate
10552 effect(DEF dst, USE src);
10553 predicate(false);
10554
10555 format %{ "FCFID $dst, $src \t// convL2D" %}
10556 size(4);
10557 ins_encode %{
10558 __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
10559 %}
10560 ins_pipe(pipe_class_default);
10561 %}
10562
10563 // Placed here as needed in expand.
10564 instruct convD2F_reg(regF dst, regD src) %{
10565 match(Set dst (ConvD2F src));
10566 format %{ "FRSP $dst, $src \t// convD2F" %}
10567 size(4);
10568 ins_encode %{
10569 __ frsp($dst$$FloatRegister, $src$$FloatRegister);
10570 %}
10571 ins_pipe(pipe_class_default);
10572 %}
10573
10574 instruct convL2FRaw_regF(regF dst, regD src) %{
10575 // no match-rule, false predicate
10576 effect(DEF dst, USE src);
10577 predicate(false);
10578
10579 format %{ "FCFIDS $dst, $src \t// convL2F" %}
10580 size(4);
10581 ins_encode %{
10582 __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
10583 %}
10584 ins_pipe(pipe_class_default);
10585 %}
10586
10587
10588 // Integer to Float conversion. Special version for Power8.
10589 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
10590 match(Set dst (ConvI2F src));
10591 ins_cost(DEFAULT_COST);
10592
10593 expand %{
10594 regD tmpD;
10595 moveI2D_reg(tmpD, src);
10596 convL2FRaw_regF(dst, tmpD); // Convert to float.
10597 %}
10598 %}
10599
10600
10601 // L2F to avoid runtime call. Special version for Power8.
10602 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
10603 match(Set dst (ConvL2F src));
10604 ins_cost(DEFAULT_COST);
10605
10606 expand %{
10607 regD tmpD;
10608 moveL2D_reg(tmpD, src);
10609 convL2FRaw_regF(dst, tmpD); // Convert to float.
10610 %}
10611 %}
10612
10613 // Moved up as used in expand.
10614 //instruct convD2F_reg(regF dst, regD src) %{%}
10615
10616 // Convert to Double
10617
10618
10619 // Integer to Double conversion. Special version for Power8.
10620 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
10621 match(Set dst (ConvI2D src));
10622 ins_cost(DEFAULT_COST);
10623
10624 expand %{
10625 regD tmpD;
10626 moveI2D_reg(tmpD, src);
10627 convL2DRaw_regD(dst, tmpD); // Convert to double.
10628 %}
10629 %}
10630
10631
10632 // Long to Double conversion. Special version for Power8.
10633 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
10634 match(Set dst (ConvL2D src));
10635 ins_cost(DEFAULT_COST);
10636
10637 expand %{
10638 regD tmpD;
10639 moveL2D_reg(tmpD, src);
10640 convL2DRaw_regD(dst, tmpD); // Convert to double.
10641 %}
10642 %}
10643
10644 instruct convF2D_reg(regD dst, regF src) %{
10645 match(Set dst (ConvF2D src));
10646 format %{ "FMR $dst, $src \t// float->double" %}
10647 // variable size, 0 or 4
10648 ins_encode %{
10649 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
10650 %}
10651 ins_pipe(pipe_class_default);
10652 %}
10653
10654 instruct convF2HF_reg_reg(iRegIdst dst, regF src, regF tmp) %{
10655 match(Set dst (ConvF2HF src));
10656 effect(TEMP tmp);
10657 ins_cost(3 * DEFAULT_COST);
10658 size(12);
10659 format %{ "XSCVDPHP $tmp, $src\t# convert to half precision\n\t"
10660 "MFFPRD $dst, $tmp\t# move result from $tmp to $dst\n\t"
10661 "EXTSH $dst, $dst\t# make it a proper short"
10662 %}
10663 ins_encode %{
10664 __ f2hf($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
10665 %}
10666 ins_pipe(pipe_class_default);
10667 %}
10668
10669 instruct convHF2F_reg_reg(regF dst, iRegIsrc src) %{
10670 match(Set dst (ConvHF2F src));
10671 ins_cost(2 * DEFAULT_COST);
10672 size(8);
10673 format %{ "MTFPRD $dst, $src\t# move source from $src to $dst\n\t"
10674 "XSCVHPDP $dst, $dst\t# convert from half precision"
10675 %}
10676 ins_encode %{
10677 __ hf2f($dst$$FloatRegister, $src$$Register);
10678 %}
10679 ins_pipe(pipe_class_default);
10680 %}
10681
10682 //----------Control Flow Instructions------------------------------------------
10683 // Compare Instructions
10684
10685 // Compare Integers
10686 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10687 match(Set crx (CmpI src1 src2));
10688 size(4);
10689 format %{ "CMPW $crx, $src1, $src2" %}
10690 ins_encode %{
10691 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10692 %}
10693 ins_pipe(pipe_class_compare);
10694 %}
10695
10696 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
10697 match(Set crx (CmpI src1 src2));
10698 format %{ "CMPWI $crx, $src1, $src2" %}
10699 size(4);
10700 ins_encode %{
10701 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10702 %}
10703 ins_pipe(pipe_class_compare);
10704 %}
10705
10706 // (src1 & src2) == 0?
10707 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
10708 match(Set cr0 (CmpI (AndI src1 src2) zero));
10709 // r0 is killed
10710 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
10711 size(4);
10712 ins_encode %{
10713 __ andi_(R0, $src1$$Register, $src2$$constant);
10714 %}
10715 ins_pipe(pipe_class_compare);
10716 %}
10717
10718 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10719 match(Set crx (CmpL src1 src2));
10720 format %{ "CMPD $crx, $src1, $src2" %}
10721 size(4);
10722 ins_encode %{
10723 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
10724 %}
10725 ins_pipe(pipe_class_compare);
10726 %}
10727
10728 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
10729 match(Set crx (CmpL src1 src2));
10730 format %{ "CMPDI $crx, $src1, $src2" %}
10731 size(4);
10732 ins_encode %{
10733 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10734 %}
10735 ins_pipe(pipe_class_compare);
10736 %}
10737
10738 // Added CmpUL for LoopPredicate.
10739 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10740 match(Set crx (CmpUL src1 src2));
10741 format %{ "CMPLD $crx, $src1, $src2" %}
10742 size(4);
10743 ins_encode %{
10744 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10745 %}
10746 ins_pipe(pipe_class_compare);
10747 %}
10748
10749 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
10750 match(Set crx (CmpUL src1 src2));
10751 format %{ "CMPLDI $crx, $src1, $src2" %}
10752 size(4);
10753 ins_encode %{
10754 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10755 %}
10756 ins_pipe(pipe_class_compare);
10757 %}
10758
10759 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
10760 match(Set cr0 (CmpL (AndL src1 src2) zero));
10761 // r0 is killed
10762 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
10763 size(4);
10764 ins_encode %{
10765 __ and_(R0, $src1$$Register, $src2$$Register);
10766 %}
10767 ins_pipe(pipe_class_compare);
10768 %}
10769
10770 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
10771 match(Set cr0 (CmpL (AndL src1 src2) zero));
10772 // r0 is killed
10773 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
10774 size(4);
10775 ins_encode %{
10776 __ andi_(R0, $src1$$Register, $src2$$constant);
10777 %}
10778 ins_pipe(pipe_class_compare);
10779 %}
10780
10781 // Manifest a CmpL3 result in an integer register.
10782 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10783 match(Set dst (CmpL3 src1 src2));
10784 effect(KILL cr0);
10785 ins_cost(DEFAULT_COST * 5);
10786 size((VM_Version::has_brw() ? 16 : 20));
10787
10788 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %}
10789
10790 ins_encode %{
10791 __ cmpd(CR0, $src1$$Register, $src2$$Register);
10792 __ set_cmp3($dst$$Register);
10793 %}
10794 ins_pipe(pipe_class_default);
10795 %}
10796
10797 instruct cmpU3_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
10798 match(Set dst (CmpU3 src1 src2));
10799 effect(KILL cr0);
10800 ins_cost(DEFAULT_COST * 5);
10801 size((VM_Version::has_brw() ? 16 : 20));
10802
10803 format %{ "cmpU3_reg_reg $dst, $src1, $src2" %}
10804
10805 ins_encode %{
10806 __ cmplw(CR0, $src1$$Register, $src2$$Register);
10807 __ set_cmp3($dst$$Register);
10808 %}
10809 ins_pipe(pipe_class_default);
10810 %}
10811
10812 instruct cmpUL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10813 match(Set dst (CmpUL3 src1 src2));
10814 effect(KILL cr0);
10815 ins_cost(DEFAULT_COST * 5);
10816 size((VM_Version::has_brw() ? 16 : 20));
10817
10818 format %{ "cmpUL3_reg_reg $dst, $src1, $src2" %}
10819
10820 ins_encode %{
10821 __ cmpld(CR0, $src1$$Register, $src2$$Register);
10822 __ set_cmp3($dst$$Register);
10823 %}
10824 ins_pipe(pipe_class_default);
10825 %}
10826
10827 // Implicit range checks.
10828 // A range check in the ideal world has one of the following shapes:
10829 // - (If le (CmpU length index)), (IfTrue throw exception)
10830 // - (If lt (CmpU index length)), (IfFalse throw exception)
10831 //
10832 // Match range check 'If le (CmpU length index)'.
10833 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
10834 match(If cmp (CmpU src_length index));
10835 effect(USE labl);
10836 predicate(TrapBasedRangeChecks &&
10837 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
10838 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
10839 (Matcher::branches_to_uncommon_trap(_leaf)));
10840
10841 ins_is_TrapBasedCheckNode(true);
10842
10843 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %}
10844 size(4);
10845 ins_encode %{
10846 if ($cmp$$cmpcode == 0x1 /* less_equal */) {
10847 __ trap_range_check_le($src_length$$Register, $index$$constant);
10848 } else {
10849 // Both successors are uncommon traps, probability is 0.
10850 // Node got flipped during fixup flow.
10851 assert($cmp$$cmpcode == 0x9, "must be greater");
10852 __ trap_range_check_g($src_length$$Register, $index$$constant);
10853 }
10854 %}
10855 ins_pipe(pipe_class_trap);
10856 %}
10857
10858 // Match range check 'If lt (CmpU index length)'.
10859 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
10860 match(If cmp (CmpU src_index src_length));
10861 effect(USE labl);
10862 predicate(TrapBasedRangeChecks &&
10863 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10864 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10865 (Matcher::branches_to_uncommon_trap(_leaf)));
10866
10867 ins_is_TrapBasedCheckNode(true);
10868
10869 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
10870 size(4);
10871 ins_encode %{
10872 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10873 __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
10874 } else {
10875 // Both successors are uncommon traps, probability is 0.
10876 // Node got flipped during fixup flow.
10877 assert($cmp$$cmpcode == 0x8, "must be less");
10878 __ trap_range_check_l($src_index$$Register, $src_length$$Register);
10879 }
10880 %}
10881 ins_pipe(pipe_class_trap);
10882 %}
10883
10884 // Match range check 'If lt (CmpU index length)'.
10885 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
10886 match(If cmp (CmpU src_index length));
10887 effect(USE labl);
10888 predicate(TrapBasedRangeChecks &&
10889 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10890 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10891 (Matcher::branches_to_uncommon_trap(_leaf)));
10892
10893 ins_is_TrapBasedCheckNode(true);
10894
10895 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %}
10896 size(4);
10897 ins_encode %{
10898 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10899 __ trap_range_check_ge($src_index$$Register, $length$$constant);
10900 } else {
10901 // Both successors are uncommon traps, probability is 0.
10902 // Node got flipped during fixup flow.
10903 assert($cmp$$cmpcode == 0x8, "must be less");
10904 __ trap_range_check_l($src_index$$Register, $length$$constant);
10905 }
10906 %}
10907 ins_pipe(pipe_class_trap);
10908 %}
10909
10910 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10911 match(Set crx (CmpU src1 src2));
10912 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %}
10913 size(4);
10914 ins_encode %{
10915 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10916 %}
10917 ins_pipe(pipe_class_compare);
10918 %}
10919
10920 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
10921 match(Set crx (CmpU src1 src2));
10922 size(4);
10923 format %{ "CMPLWI $crx, $src1, $src2" %}
10924 ins_encode %{
10925 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10926 %}
10927 ins_pipe(pipe_class_compare);
10928 %}
10929
10930 // Implicit zero checks (more implicit null checks).
10931 // No constant pool entries required.
10932 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
10933 match(If cmp (CmpN value zero));
10934 effect(USE labl);
10935 predicate(TrapBasedNullChecks &&
10936 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10937 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10938 Matcher::branches_to_uncommon_trap(_leaf));
10939 ins_cost(1);
10940
10941 ins_is_TrapBasedCheckNode(true);
10942
10943 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
10944 size(4);
10945 ins_encode %{
10946 if ($cmp$$cmpcode == 0xA) {
10947 __ trap_null_check($value$$Register);
10948 } else {
10949 // Both successors are uncommon traps, probability is 0.
10950 // Node got flipped during fixup flow.
10951 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10952 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10953 }
10954 %}
10955 ins_pipe(pipe_class_trap);
10956 %}
10957
10958 // Compare narrow oops.
10959 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
10960 match(Set crx (CmpN src1 src2));
10961
10962 size(4);
10963 ins_cost(2);
10964 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %}
10965 ins_encode %{
10966 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10967 %}
10968 ins_pipe(pipe_class_compare);
10969 %}
10970
10971 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
10972 match(Set crx (CmpN src1 src2));
10973 // Make this more expensive than zeroCheckN_iReg_imm0.
10974 ins_cost(2);
10975
10976 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %}
10977 size(4);
10978 ins_encode %{
10979 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10980 %}
10981 ins_pipe(pipe_class_compare);
10982 %}
10983
10984 // Implicit zero checks (more implicit null checks).
10985 // No constant pool entries required.
10986 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
10987 match(If cmp (CmpP value zero));
10988 effect(USE labl);
10989 predicate(TrapBasedNullChecks &&
10990 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10991 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10992 Matcher::branches_to_uncommon_trap(_leaf));
10993 ins_cost(1); // Should not be cheaper than zeroCheckN.
10994
10995 ins_is_TrapBasedCheckNode(true);
10996
10997 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
10998 size(4);
10999 ins_encode %{
11000 if ($cmp$$cmpcode == 0xA) {
11001 __ trap_null_check($value$$Register);
11002 } else {
11003 // Both successors are uncommon traps, probability is 0.
11004 // Node got flipped during fixup flow.
11005 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
11006 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
11007 }
11008 %}
11009 ins_pipe(pipe_class_trap);
11010 %}
11011
11012 // Compare Pointers
11013 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
11014 match(Set crx (CmpP src1 src2));
11015 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %}
11016 size(4);
11017 ins_encode %{
11018 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
11019 %}
11020 ins_pipe(pipe_class_compare);
11021 %}
11022
11023 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
11024 match(Set crx (CmpP src1 src2));
11025 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %}
11026 size(4);
11027 ins_encode %{
11028 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
11029 %}
11030 ins_pipe(pipe_class_compare);
11031 %}
11032
11033 // Used in postalloc expand.
11034 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
11035 // This match rule prevents reordering of node before a safepoint.
11036 // This only makes sense if this instructions is used exclusively
11037 // for the expansion of EncodeP!
11038 match(Set crx (CmpP src1 src2));
11039 predicate(false);
11040
11041 format %{ "CMPDI $crx, $src1, $src2" %}
11042 size(4);
11043 ins_encode %{
11044 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11045 %}
11046 ins_pipe(pipe_class_compare);
11047 %}
11048
11049 //----------Float Compares----------------------------------------------------
11050
11051 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
11052 // Needs matchrule, see cmpDUnordered.
11053 match(Set crx (CmpF src1 src2));
11054 // no match-rule, false predicate
11055 predicate(false);
11056
11057 format %{ "cmpFUrd $crx, $src1, $src2" %}
11058 size(4);
11059 ins_encode %{
11060 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11061 %}
11062 ins_pipe(pipe_class_default);
11063 %}
11064
11065 instruct cmov_bns_less(flagsReg crx) %{
11066 // no match-rule, false predicate
11067 effect(DEF crx);
11068 predicate(false);
11069
11070 ins_variable_size_depending_on_alignment(true);
11071
11072 format %{ "CMOV $crx" %}
11073 size(12);
11074 ins_encode %{
11075 Label done;
11076 __ bns($crx$$CondRegister, done); // not unordered -> keep crx
11077 __ li(R0, 0);
11078 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less'
11079 __ bind(done);
11080 %}
11081 ins_pipe(pipe_class_default);
11082 %}
11083
11084 // Compare floating, generate condition code.
11085 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{
11086 // FIXME: should we match 'If cmp (CmpF src1 src2))' ??
11087 //
11088 // The following code sequence occurs a lot in mpegaudio:
11089 //
11090 // block BXX:
11091 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0):
11092 // cmpFUrd CR6, F11, F9
11093 // 4: instruct cmov_bns_less (cmpF_reg_reg-1):
11094 // cmov CR6
11095 // 8: instruct branchConSched:
11096 // B_FARle CR6, B56 P=0.500000 C=-1.000000
11097 match(Set crx (CmpF src1 src2));
11098 ins_cost(DEFAULT_COST+BRANCH_COST);
11099
11100 format %{ "CMPF $crx, $src1, $src2 \t// postalloc expanded" %}
11101 postalloc_expand %{
11102 //
11103 // replaces
11104 //
11105 // region src1 src2
11106 // \ | |
11107 // crx=cmpF_reg_reg
11108 //
11109 // with
11110 //
11111 // region src1 src2
11112 // \ | |
11113 // crx=cmpFUnordered_reg_reg
11114 // |
11115 // ^ region
11116 // | \
11117 // crx=cmov_bns_less
11118 //
11119
11120 // Create new nodes.
11121 MachNode *m1 = new cmpFUnordered_reg_regNode();
11122 MachNode *m2 = new cmov_bns_lessNode();
11123
11124 // inputs for new nodes
11125 m1->add_req(n_region, n_src1, n_src2);
11126 m2->add_req(n_region);
11127 m2->add_prec(m1);
11128
11129 // operands for new nodes
11130 m1->_opnds[0] = op_crx;
11131 m1->_opnds[1] = op_src1;
11132 m1->_opnds[2] = op_src2;
11133 m2->_opnds[0] = op_crx;
11134
11135 // registers for new nodes
11136 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11137 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11138
11139 // Insert new nodes.
11140 nodes->push(m1);
11141 nodes->push(m2);
11142 %}
11143 %}
11144
11145 // Compare float, generate -1,0,1
11146 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{
11147 match(Set dst (CmpF3 src1 src2));
11148 effect(KILL cr0);
11149 ins_cost(DEFAULT_COST * 6);
11150 size((VM_Version::has_brw() ? 20 : 24));
11151
11152 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %}
11153
11154 ins_encode %{
11155 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
11156 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11157 %}
11158 ins_pipe(pipe_class_default);
11159 %}
11160
11161 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
11162 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
11163 // node right before the conditional move using it.
11164 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
11165 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
11166 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
11167 // conditional move was supposed to be spilled.
11168 match(Set crx (CmpD src1 src2));
11169 // False predicate, shall not be matched.
11170 predicate(false);
11171
11172 format %{ "cmpFUrd $crx, $src1, $src2" %}
11173 size(4);
11174 ins_encode %{
11175 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11176 %}
11177 ins_pipe(pipe_class_default);
11178 %}
11179
11180 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{
11181 match(Set crx (CmpD src1 src2));
11182 ins_cost(DEFAULT_COST+BRANCH_COST);
11183
11184 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %}
11185 postalloc_expand %{
11186 //
11187 // replaces
11188 //
11189 // region src1 src2
11190 // \ | |
11191 // crx=cmpD_reg_reg
11192 //
11193 // with
11194 //
11195 // region src1 src2
11196 // \ | |
11197 // crx=cmpDUnordered_reg_reg
11198 // |
11199 // ^ region
11200 // | \
11201 // crx=cmov_bns_less
11202 //
11203
11204 // create new nodes
11205 MachNode *m1 = new cmpDUnordered_reg_regNode();
11206 MachNode *m2 = new cmov_bns_lessNode();
11207
11208 // inputs for new nodes
11209 m1->add_req(n_region, n_src1, n_src2);
11210 m2->add_req(n_region);
11211 m2->add_prec(m1);
11212
11213 // operands for new nodes
11214 m1->_opnds[0] = op_crx;
11215 m1->_opnds[1] = op_src1;
11216 m1->_opnds[2] = op_src2;
11217 m2->_opnds[0] = op_crx;
11218
11219 // registers for new nodes
11220 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11221 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11222
11223 // Insert new nodes.
11224 nodes->push(m1);
11225 nodes->push(m2);
11226 %}
11227 %}
11228
11229 // Compare double, generate -1,0,1
11230 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{
11231 match(Set dst (CmpD3 src1 src2));
11232 effect(KILL cr0);
11233 ins_cost(DEFAULT_COST * 6);
11234 size((VM_Version::has_brw() ? 20 : 24));
11235
11236 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %}
11237
11238 ins_encode %{
11239 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
11240 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11241 %}
11242 ins_pipe(pipe_class_default);
11243 %}
11244
11245 // Compare char
11246 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11247 match(Set dst (Digit src1));
11248 effect(TEMP src2, TEMP crx);
11249 ins_cost(3 * DEFAULT_COST);
11250
11251 format %{ "LI $src2, 0x3930\n\t"
11252 "CMPRB $crx, 0, $src1, $src2\n\t"
11253 "SETB $dst, $crx" %}
11254 size(12);
11255 ins_encode %{
11256 // 0x30: 0, 0x39: 9
11257 __ li($src2$$Register, 0x3930);
11258 // compare src1 with ranges 0x30 to 0x39
11259 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11260 __ setb($dst$$Register, $crx$$CondRegister);
11261 %}
11262 ins_pipe(pipe_class_default);
11263 %}
11264
11265 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11266 match(Set dst (LowerCase src1));
11267 effect(TEMP src2, TEMP crx);
11268 ins_cost(12 * DEFAULT_COST);
11269
11270 format %{ "LI $src2, 0x7A61\n\t"
11271 "CMPRB $crx, 0, $src1, $src2\n\t"
11272 "BGT $crx, done\n\t"
11273 "LIS $src2, (signed short)0xF6DF\n\t"
11274 "ORI $src2, $src2, 0xFFF8\n\t"
11275 "CMPRB $crx, 1, $src1, $src2\n\t"
11276 "BGT $crx, done\n\t"
11277 "LIS $src2, (signed short)0xAAB5\n\t"
11278 "ORI $src2, $src2, 0xBABA\n\t"
11279 "INSRDI $src2, $src2, 32, 0\n\t"
11280 "CMPEQB $crx, 1, $src1, $src2\n"
11281 "done:\n\t"
11282 "SETB $dst, $crx" %}
11283
11284 size(48);
11285 ins_encode %{
11286 Label done;
11287 // 0x61: a, 0x7A: z
11288 __ li($src2$$Register, 0x7A61);
11289 // compare src1 with ranges 0x61 to 0x7A
11290 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11291 __ bgt($crx$$CondRegister, done);
11292
11293 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
11294 __ lis($src2$$Register, (signed short)0xF6DF);
11295 __ ori($src2$$Register, $src2$$Register, 0xFFF8);
11296 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
11297 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11298 __ bgt($crx$$CondRegister, done);
11299
11300 // 0xAA: feminine ordinal indicator
11301 // 0xB5: micro sign
11302 // 0xBA: masculine ordinal indicator
11303 __ lis($src2$$Register, (signed short)0xAAB5);
11304 __ ori($src2$$Register, $src2$$Register, 0xBABA);
11305 __ insrdi($src2$$Register, $src2$$Register, 32, 0);
11306 // compare src1 with 0xAA, 0xB5, and 0xBA
11307 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
11308
11309 __ bind(done);
11310 __ setb($dst$$Register, $crx$$CondRegister);
11311 %}
11312 ins_pipe(pipe_class_default);
11313 %}
11314
11315 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11316 match(Set dst (UpperCase src1));
11317 effect(TEMP src2, TEMP crx);
11318 ins_cost(7 * DEFAULT_COST);
11319
11320 format %{ "LI $src2, 0x5A41\n\t"
11321 "CMPRB $crx, 0, $src1, $src2\n\t"
11322 "BGT $crx, done\n\t"
11323 "LIS $src2, (signed short)0xD6C0\n\t"
11324 "ORI $src2, $src2, 0xDED8\n\t"
11325 "CMPRB $crx, 1, $src1, $src2\n"
11326 "done:\n\t"
11327 "SETB $dst, $crx" %}
11328
11329 size(28);
11330 ins_encode %{
11331 Label done;
11332 // 0x41: A, 0x5A: Z
11333 __ li($src2$$Register, 0x5A41);
11334 // compare src1 with a range 0x41 to 0x5A
11335 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11336 __ bgt($crx$$CondRegister, done);
11337
11338 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
11339 __ lis($src2$$Register, (signed short)0xD6C0);
11340 __ ori($src2$$Register, $src2$$Register, 0xDED8);
11341 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
11342 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11343
11344 __ bind(done);
11345 __ setb($dst$$Register, $crx$$CondRegister);
11346 %}
11347 ins_pipe(pipe_class_default);
11348 %}
11349
11350 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11351 match(Set dst (Whitespace src1));
11352 predicate(PowerArchitecturePPC64 <= 9);
11353 effect(TEMP src2, TEMP crx);
11354 ins_cost(4 * DEFAULT_COST);
11355
11356 format %{ "LI $src2, 0x0D09\n\t"
11357 "ADDIS $src2, 0x201C\n\t"
11358 "CMPRB $crx, 1, $src1, $src2\n\t"
11359 "SETB $dst, $crx" %}
11360 size(16);
11361 ins_encode %{
11362 // 0x09 to 0x0D, 0x1C to 0x20
11363 __ li($src2$$Register, 0x0D09);
11364 __ addis($src2$$Register, $src2$$Register, 0x0201C);
11365 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11366 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11367 __ setb($dst$$Register, $crx$$CondRegister);
11368 %}
11369 ins_pipe(pipe_class_default);
11370 %}
11371
11372 // Power 10 version, using prefixed addi to load 32-bit constant
11373 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11374 match(Set dst (Whitespace src1));
11375 predicate(PowerArchitecturePPC64 >= 10);
11376 effect(TEMP src2, TEMP crx);
11377 ins_cost(3 * DEFAULT_COST);
11378
11379 format %{ "PLI $src2, 0x201C0D09\n\t"
11380 "CMPRB $crx, 1, $src1, $src2\n\t"
11381 "SETB $dst, $crx" %}
11382 size(16);
11383 ins_encode %{
11384 // 0x09 to 0x0D, 0x1C to 0x20
11385 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
11386 __ pli($src2$$Register, 0x201C0D09);
11387 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11388 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11389 __ setb($dst$$Register, $crx$$CondRegister);
11390 %}
11391 ins_pipe(pipe_class_default);
11392 ins_alignment(2);
11393 %}
11394
11395 //----------Branches---------------------------------------------------------
11396 // Jump
11397
11398 // Direct Branch.
11399 instruct branch(label labl) %{
11400 match(Goto);
11401 effect(USE labl);
11402 ins_cost(BRANCH_COST);
11403
11404 format %{ "B $labl" %}
11405 size(4);
11406 ins_encode %{
11407 Label d; // dummy
11408 __ bind(d);
11409 Label* p = $labl$$label;
11410 // `p' is `nullptr' when this encoding class is used only to
11411 // determine the size of the encoded instruction.
11412 Label& l = (nullptr == p)? d : *(p);
11413 __ b(l);
11414 %}
11415 ins_pipe(pipe_class_default);
11416 %}
11417
11418 // Conditional Near Branch
11419 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11420 // Same match rule as `branchConFar'.
11421 match(If cmp crx);
11422 effect(USE lbl);
11423 ins_cost(BRANCH_COST);
11424
11425 // If set to 1 this indicates that the current instruction is a
11426 // short variant of a long branch. This avoids using this
11427 // instruction in first-pass matching. It will then only be used in
11428 // the `Shorten_branches' pass.
11429 ins_short_branch(1);
11430
11431 format %{ "B$cmp $crx, $lbl" %}
11432 size(4);
11433 ins_encode( enc_bc(crx, cmp, lbl) );
11434 ins_pipe(pipe_class_default);
11435 %}
11436
11437 // This is for cases when the ppc64 `bc' instruction does not
11438 // reach far enough. So we emit a far branch here, which is more
11439 // expensive.
11440 //
11441 // Conditional Far Branch
11442 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11443 // Same match rule as `branchCon'.
11444 match(If cmp crx);
11445 effect(USE crx, USE lbl);
11446 // Higher cost than `branchCon'.
11447 ins_cost(5*BRANCH_COST);
11448
11449 // This is not a short variant of a branch, but the long variant.
11450 ins_short_branch(0);
11451
11452 format %{ "B_FAR$cmp $crx, $lbl" %}
11453 size(8);
11454 ins_encode( enc_bc_far(crx, cmp, lbl) );
11455 ins_pipe(pipe_class_default);
11456 %}
11457
11458 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
11459 match(CountedLoopEnd cmp crx);
11460 effect(USE labl);
11461 ins_cost(BRANCH_COST);
11462
11463 // short variant.
11464 ins_short_branch(1);
11465
11466 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
11467 size(4);
11468 ins_encode( enc_bc(crx, cmp, labl) );
11469 ins_pipe(pipe_class_default);
11470 %}
11471
11472 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
11473 match(CountedLoopEnd cmp crx);
11474 effect(USE labl);
11475 ins_cost(BRANCH_COST);
11476
11477 // Long variant.
11478 ins_short_branch(0);
11479
11480 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
11481 size(8);
11482 ins_encode( enc_bc_far(crx, cmp, labl) );
11483 ins_pipe(pipe_class_default);
11484 %}
11485
11486 // ============================================================================
11487 // Java runtime operations, intrinsics and other complex operations.
11488
11489 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
11490 // array for an instance of the superklass. Set a hidden internal cache on a
11491 // hit (cache is checked with exposed code in gen_subtype_check()). Return
11492 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
11493 //
11494 // GL TODO: Improve this.
11495 // - result should not be a TEMP
11496 // - Add match rule as on sparc avoiding additional Cmp.
11497 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
11498 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
11499 match(Set result (PartialSubtypeCheck subklass superklass));
11500 predicate(!UseSecondarySupersTable);
11501 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
11502 ins_cost(DEFAULT_COST*10);
11503
11504 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
11505 ins_encode %{
11506 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
11507 $tmp_klass$$Register, nullptr, $result$$Register);
11508 %}
11509 ins_pipe(pipe_class_default);
11510 %}
11511
11512 // Two versions of partialSubtypeCheck, both used when we need to
11513 // search for a super class in the secondary supers array. The first
11514 // is used when we don't know _a priori_ the class being searched
11515 // for. The second, far more common, is used when we do know: this is
11516 // used for instanceof, checkcast, and any case where C2 can determine
11517 // it by constant propagation.
11518 instruct partialSubtypeCheckVarSuper(iRegPsrc sub, iRegPsrc super, iRegPdst result,
11519 iRegPdst tempR1, iRegPdst tempR2, iRegPdst tempR3, iRegPdst tempR4,
11520 flagsRegCR0 cr0, regCTR ctr)
11521 %{
11522 match(Set result (PartialSubtypeCheck sub super));
11523 predicate(UseSecondarySupersTable);
11524 effect(KILL cr0, KILL ctr, TEMP_DEF result, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11525
11526 ins_cost(DEFAULT_COST * 10); // slightly larger than the next version
11527 format %{ "partialSubtypeCheck $result, $sub, $super" %}
11528 ins_encode %{
11529 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register,
11530 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11531 $result$$Register);
11532 %}
11533 ins_pipe(pipe_class_memory);
11534 %}
11535
11536 instruct partialSubtypeCheckConstSuper(rarg3RegP sub, rarg2RegP super_reg, immP super_con, rarg6RegP result,
11537 rarg1RegP tempR1, rarg5RegP tempR2, rarg4RegP tempR3, rscratch1RegP tempR4,
11538 flagsRegCR0 cr0, regCTR ctr)
11539 %{
11540 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
11541 predicate(UseSecondarySupersTable);
11542 effect(KILL cr0, KILL ctr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11543
11544 ins_cost(DEFAULT_COST*8); // smaller than the other version
11545 format %{ "partialSubtypeCheck $result, $sub, $super_reg" %}
11546
11547 ins_encode %{
11548 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
11549 if (InlineSecondarySupersTest) {
11550 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register,
11551 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11552 $result$$Register, super_klass_slot);
11553 } else {
11554 address stub = StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot);
11555 Register r_stub_addr = $tempR1$$Register;
11556 __ add_const_optimized(r_stub_addr, R29_TOC, MacroAssembler::offset_to_global_toc(stub), R0);
11557 __ mtctr(r_stub_addr);
11558 __ bctrl();
11559 }
11560 %}
11561
11562 ins_pipe(pipe_class_memory);
11563 %}
11564
11565 // inlined locking and unlocking
11566
11567 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
11568 predicate(!UseObjectMonitorTable);
11569 match(Set crx (FastLock oop box));
11570 effect(TEMP tmp1, TEMP tmp2);
11571
11572 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %}
11573 ins_encode %{
11574 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11575 $tmp1$$Register, $tmp2$$Register, noreg /*tmp3*/);
11576 // If locking was successful, crx should indicate 'EQ'.
11577 // The compiler generates a branch to the runtime call to
11578 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11579 %}
11580 ins_pipe(pipe_class_compare);
11581 %}
11582
11583 instruct cmpFastLockMonitorTable(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, flagsRegCR1 cr1) %{
11584 predicate(UseObjectMonitorTable);
11585 match(Set crx (FastLock oop box));
11586 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr1);
11587
11588 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3" %}
11589 ins_encode %{
11590 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11591 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11592 // If locking was successful, crx should indicate 'EQ'.
11593 // The compiler generates a branch to the runtime call to
11594 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11595 %}
11596 ins_pipe(pipe_class_compare);
11597 %}
11598
11599 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11600 match(Set crx (FastUnlock oop box));
11601 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11602
11603 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
11604 ins_encode %{
11605 __ fast_unlock($crx$$CondRegister, $oop$$Register, $box$$Register,
11606 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11607 // If unlocking was successful, crx should indicate 'EQ'.
11608 // The compiler generates a branch to the runtime call to
11609 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11610 %}
11611 ins_pipe(pipe_class_compare);
11612 %}
11613
11614 // Align address.
11615 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11616 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11617
11618 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
11619 size(4);
11620 ins_encode %{
11621 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant));
11622 %}
11623 ins_pipe(pipe_class_default);
11624 %}
11625
11626 // Array size computation.
11627 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11628 match(Set dst (SubL (CastP2X end) (CastP2X start)));
11629
11630 format %{ "SUB $dst, $end, $start \t// array size in bytes" %}
11631 size(4);
11632 ins_encode %{
11633 __ subf($dst$$Register, $start$$Register, $end$$Register);
11634 %}
11635 ins_pipe(pipe_class_default);
11636 %}
11637
11638 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
11639 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11640 match(Set dummy (ClearArray cnt base));
11641 effect(USE_KILL base, KILL ctr);
11642 ins_cost(2 * MEMORY_REF_COST);
11643
11644 format %{ "ClearArray $cnt, $base" %}
11645 ins_encode %{
11646 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
11647 %}
11648 ins_pipe(pipe_class_default);
11649 %}
11650
11651 // Clear-array with constant large array length.
11652 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{
11653 match(Set dummy (ClearArray cnt base));
11654 effect(USE_KILL base, TEMP tmp, KILL ctr);
11655 ins_cost(3 * MEMORY_REF_COST);
11656
11657 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
11658 ins_encode %{
11659 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
11660 %}
11661 ins_pipe(pipe_class_default);
11662 %}
11663
11664 // Clear-array with dynamic array length.
11665 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11666 match(Set dummy (ClearArray cnt base));
11667 effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11668 ins_cost(4 * MEMORY_REF_COST);
11669
11670 format %{ "ClearArray $cnt, $base" %}
11671 ins_encode %{
11672 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
11673 %}
11674 ins_pipe(pipe_class_default);
11675 %}
11676
11677 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11678 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11679 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11680 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11681 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11682 ins_cost(300);
11683 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11684 ins_encode %{
11685 __ string_compare($str1$$Register, $str2$$Register,
11686 $cnt1$$Register, $cnt2$$Register,
11687 $tmp$$Register,
11688 $result$$Register, StrIntrinsicNode::LL);
11689 %}
11690 ins_pipe(pipe_class_default);
11691 %}
11692
11693 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11694 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11695 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11696 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11697 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11698 ins_cost(300);
11699 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11700 ins_encode %{
11701 __ string_compare($str1$$Register, $str2$$Register,
11702 $cnt1$$Register, $cnt2$$Register,
11703 $tmp$$Register,
11704 $result$$Register, StrIntrinsicNode::UU);
11705 %}
11706 ins_pipe(pipe_class_default);
11707 %}
11708
11709 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11710 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11711 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11712 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11713 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11714 ins_cost(300);
11715 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11716 ins_encode %{
11717 __ string_compare($str1$$Register, $str2$$Register,
11718 $cnt1$$Register, $cnt2$$Register,
11719 $tmp$$Register,
11720 $result$$Register, StrIntrinsicNode::LU);
11721 %}
11722 ins_pipe(pipe_class_default);
11723 %}
11724
11725 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11726 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11727 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11728 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11729 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11730 ins_cost(300);
11731 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11732 ins_encode %{
11733 __ string_compare($str2$$Register, $str1$$Register,
11734 $cnt2$$Register, $cnt1$$Register,
11735 $tmp$$Register,
11736 $result$$Register, StrIntrinsicNode::UL);
11737 %}
11738 ins_pipe(pipe_class_default);
11739 %}
11740
11741 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11742 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11743 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11744 match(Set result (StrEquals (Binary str1 str2) cnt));
11745 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11746 ins_cost(300);
11747 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11748 ins_encode %{
11749 __ array_equals(false, $str1$$Register, $str2$$Register,
11750 $cnt$$Register, $tmp$$Register,
11751 $result$$Register, true /* byte */);
11752 %}
11753 ins_pipe(pipe_class_default);
11754 %}
11755
11756 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11757 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11758 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11759 match(Set result (AryEq ary1 ary2));
11760 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11761 ins_cost(300);
11762 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11763 ins_encode %{
11764 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11765 $tmp1$$Register, $tmp2$$Register,
11766 $result$$Register, true /* byte */);
11767 %}
11768 ins_pipe(pipe_class_default);
11769 %}
11770
11771 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11772 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11773 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11774 match(Set result (AryEq ary1 ary2));
11775 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11776 ins_cost(300);
11777 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11778 ins_encode %{
11779 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11780 $tmp1$$Register, $tmp2$$Register,
11781 $result$$Register, false /* byte */);
11782 %}
11783 ins_pipe(pipe_class_default);
11784 %}
11785
11786 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11787 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11788 iRegIdst tmp1, iRegIdst tmp2,
11789 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11790 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11791 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11792 // Required for EA: check if it is still a type_array.
11793 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11794 ins_cost(150);
11795
11796 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11797 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11798
11799 ins_encode %{
11800 immPOper *needleOper = (immPOper *)$needleImm;
11801 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11802 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11803 jchar chr;
11804 #ifdef VM_LITTLE_ENDIAN
11805 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11806 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11807 #else
11808 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11809 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11810 #endif
11811 __ string_indexof_char($result$$Register,
11812 $haystack$$Register, $haycnt$$Register,
11813 R0, chr,
11814 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11815 %}
11816 ins_pipe(pipe_class_compare);
11817 %}
11818
11819 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11820 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11821 iRegIdst tmp1, iRegIdst tmp2,
11822 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11823 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11824 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11825 // Required for EA: check if it is still a type_array.
11826 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11827 ins_cost(150);
11828
11829 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11830 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11831
11832 ins_encode %{
11833 immPOper *needleOper = (immPOper *)$needleImm;
11834 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11835 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11836 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11837 __ string_indexof_char($result$$Register,
11838 $haystack$$Register, $haycnt$$Register,
11839 R0, chr,
11840 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11841 %}
11842 ins_pipe(pipe_class_compare);
11843 %}
11844
11845 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11846 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11847 iRegIdst tmp1, iRegIdst tmp2,
11848 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11849 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11850 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11851 // Required for EA: check if it is still a type_array.
11852 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11853 ins_cost(150);
11854
11855 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11856 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11857
11858 ins_encode %{
11859 immPOper *needleOper = (immPOper *)$needleImm;
11860 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11861 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11862 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11863 __ string_indexof_char($result$$Register,
11864 $haystack$$Register, $haycnt$$Register,
11865 R0, chr,
11866 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11867 %}
11868 ins_pipe(pipe_class_compare);
11869 %}
11870
11871 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11872 rscratch2RegP needle, immI_1 needlecntImm,
11873 iRegIdst tmp1, iRegIdst tmp2,
11874 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11875 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11876 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11877 // Required for EA: check if it is still a type_array.
11878 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11879 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11880 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11881 ins_cost(180);
11882
11883 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11884 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11885 ins_encode %{
11886 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11887 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11888 guarantee(needle_values, "sanity");
11889 jchar chr;
11890 #ifdef VM_LITTLE_ENDIAN
11891 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11892 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11893 #else
11894 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11895 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11896 #endif
11897 __ string_indexof_char($result$$Register,
11898 $haystack$$Register, $haycnt$$Register,
11899 R0, chr,
11900 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11901 %}
11902 ins_pipe(pipe_class_compare);
11903 %}
11904
11905 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11906 rscratch2RegP needle, immI_1 needlecntImm,
11907 iRegIdst tmp1, iRegIdst tmp2,
11908 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11909 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11910 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11911 // Required for EA: check if it is still a type_array.
11912 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11913 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11914 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11915 ins_cost(180);
11916
11917 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11918 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11919 ins_encode %{
11920 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11921 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11922 guarantee(needle_values, "sanity");
11923 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11924 __ string_indexof_char($result$$Register,
11925 $haystack$$Register, $haycnt$$Register,
11926 R0, chr,
11927 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11928 %}
11929 ins_pipe(pipe_class_compare);
11930 %}
11931
11932 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11933 rscratch2RegP needle, immI_1 needlecntImm,
11934 iRegIdst tmp1, iRegIdst tmp2,
11935 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11936 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11937 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11938 // Required for EA: check if it is still a type_array.
11939 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11940 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11941 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11942 ins_cost(180);
11943
11944 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11945 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11946 ins_encode %{
11947 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11948 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11949 guarantee(needle_values, "sanity");
11950 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11951 __ string_indexof_char($result$$Register,
11952 $haystack$$Register, $haycnt$$Register,
11953 R0, chr,
11954 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11955 %}
11956 ins_pipe(pipe_class_compare);
11957 %}
11958
11959 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11960 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11961 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11962 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11963 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11964 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
11965 ins_cost(180);
11966
11967 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch"
11968 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11969 ins_encode %{
11970 __ string_indexof_char($result$$Register,
11971 $haystack$$Register, $haycnt$$Register,
11972 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11973 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11974 %}
11975 ins_pipe(pipe_class_compare);
11976 %}
11977
11978 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11979 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11980 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11981 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11982 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11983 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
11984 ins_cost(180);
11985
11986 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch"
11987 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11988 ins_encode %{
11989 __ string_indexof_char($result$$Register,
11990 $haystack$$Register, $haycnt$$Register,
11991 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11992 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11993 %}
11994 ins_pipe(pipe_class_compare);
11995 %}
11996
11997 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11998 iRegPsrc needle, uimmI15 needlecntImm,
11999 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12000 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12001 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12002 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12003 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12004 // Required for EA: check if it is still a type_array.
12005 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
12006 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12007 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12008 ins_cost(250);
12009
12010 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12011 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12012 ins_encode %{
12013 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12014 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12015
12016 __ string_indexof($result$$Register,
12017 $haystack$$Register, $haycnt$$Register,
12018 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12019 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
12020 %}
12021 ins_pipe(pipe_class_compare);
12022 %}
12023
12024 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12025 iRegPsrc needle, uimmI15 needlecntImm,
12026 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12027 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12028 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12029 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12030 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12031 // Required for EA: check if it is still a type_array.
12032 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
12033 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12034 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12035 ins_cost(250);
12036
12037 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12038 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12039 ins_encode %{
12040 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12041 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12042
12043 __ string_indexof($result$$Register,
12044 $haystack$$Register, $haycnt$$Register,
12045 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12046 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
12047 %}
12048 ins_pipe(pipe_class_compare);
12049 %}
12050
12051 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12052 iRegPsrc needle, uimmI15 needlecntImm,
12053 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12054 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12055 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12056 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12057 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12058 // Required for EA: check if it is still a type_array.
12059 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
12060 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12061 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12062 ins_cost(250);
12063
12064 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12065 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12066 ins_encode %{
12067 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12068 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12069
12070 __ string_indexof($result$$Register,
12071 $haystack$$Register, $haycnt$$Register,
12072 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12073 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
12074 %}
12075 ins_pipe(pipe_class_compare);
12076 %}
12077
12078 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12079 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12080 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12081 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12082 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12083 TEMP_DEF result,
12084 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12085 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
12086 ins_cost(300);
12087
12088 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12089 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12090 ins_encode %{
12091 __ string_indexof($result$$Register,
12092 $haystack$$Register, $haycnt$$Register,
12093 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
12094 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
12095 %}
12096 ins_pipe(pipe_class_compare);
12097 %}
12098
12099 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12100 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12101 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12102 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12103 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12104 TEMP_DEF result,
12105 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12106 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
12107 ins_cost(300);
12108
12109 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12110 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12111 ins_encode %{
12112 __ string_indexof($result$$Register,
12113 $haystack$$Register, $haycnt$$Register,
12114 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
12115 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
12116 %}
12117 ins_pipe(pipe_class_compare);
12118 %}
12119
12120 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12121 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12122 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12123 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12124 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12125 TEMP_DEF result,
12126 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12127 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
12128 ins_cost(300);
12129
12130 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12131 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12132 ins_encode %{
12133 __ string_indexof($result$$Register,
12134 $haystack$$Register, $haycnt$$Register,
12135 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
12136 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
12137 %}
12138 ins_pipe(pipe_class_compare);
12139 %}
12140
12141 // char[] to byte[] compression
12142 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12143 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12144 match(Set result (StrCompressedCopy src (Binary dst len)));
12145 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12146 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12147 ins_cost(300);
12148 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12149 ins_encode %{
12150 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12151 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
12152 %}
12153 ins_pipe(pipe_class_default);
12154 %}
12155
12156 // byte[] to char[] inflation
12157 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
12158 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12159 match(Set dummy (StrInflatedCopy src (Binary dst len)));
12160 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12161 ins_cost(300);
12162 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12163 ins_encode %{
12164 Label Ldone;
12165 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
12166 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
12167 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
12168 __ beq(CR0, Ldone);
12169 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
12170 __ bind(Ldone);
12171 %}
12172 ins_pipe(pipe_class_default);
12173 %}
12174
12175 // StringCoding.java intrinsics
12176 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
12177 regCTR ctr, flagsRegCR0 cr0)
12178 %{
12179 match(Set result (CountPositives ary1 len));
12180 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
12181 ins_cost(300);
12182 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
12183 ins_encode %{
12184 __ count_positives($ary1$$Register, $len$$Register, $result$$Register,
12185 $tmp1$$Register, $tmp2$$Register);
12186 %}
12187 ins_pipe(pipe_class_default);
12188 %}
12189
12190 // encode char[] to byte[] in ISO_8859_1
12191 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12192 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12193 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
12194 match(Set result (EncodeISOArray src (Binary dst len)));
12195 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12196 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12197 ins_cost(300);
12198 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12199 ins_encode %{
12200 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12201 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
12202 %}
12203 ins_pipe(pipe_class_default);
12204 %}
12205
12206 // encode char[] to byte[] in ASCII
12207 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12208 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12209 predicate(((EncodeISOArrayNode*)n)->is_ascii());
12210 match(Set result (EncodeISOArray src (Binary dst len)));
12211 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12212 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12213 ins_cost(300);
12214 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12215 ins_encode %{
12216 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12217 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
12218 %}
12219 ins_pipe(pipe_class_default);
12220 %}
12221
12222
12223 //---------- Min/Max Instructions ---------------------------------------------
12224
12225
12226 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12227 match(Set dst (MinI src1 src2));
12228 effect(KILL cr0);
12229 ins_cost(DEFAULT_COST*2);
12230
12231 size(8);
12232 ins_encode %{
12233 __ cmpw(CR0, $src1$$Register, $src2$$Register);
12234 __ isel($dst$$Register, CR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
12235 %}
12236 ins_pipe(pipe_class_default);
12237 %}
12238
12239
12240 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12241 match(Set dst (MaxI src1 src2));
12242 effect(KILL cr0);
12243 ins_cost(DEFAULT_COST*2);
12244
12245 size(8);
12246 ins_encode %{
12247 __ cmpw(CR0, $src1$$Register, $src2$$Register);
12248 __ isel($dst$$Register, CR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
12249 %}
12250 ins_pipe(pipe_class_default);
12251 %}
12252
12253 instruct minF(regF dst, regF src1, regF src2) %{
12254 match(Set dst (MinF src1 src2));
12255 predicate(PowerArchitecturePPC64 >= 9);
12256 ins_cost(DEFAULT_COST);
12257
12258 format %{ "XSMINJDP $dst, $src1, $src2\t// MinF" %}
12259 size(4);
12260 ins_encode %{
12261 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12262 %}
12263 ins_pipe(pipe_class_default);
12264 %}
12265
12266 instruct minD(regD dst, regD src1, regD src2) %{
12267 match(Set dst (MinD src1 src2));
12268 predicate(PowerArchitecturePPC64 >= 9);
12269 ins_cost(DEFAULT_COST);
12270
12271 format %{ "XSMINJDP $dst, $src1, $src2\t// MinD" %}
12272 size(4);
12273 ins_encode %{
12274 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12275 %}
12276 ins_pipe(pipe_class_default);
12277 %}
12278
12279 instruct maxF(regF dst, regF src1, regF src2) %{
12280 match(Set dst (MaxF src1 src2));
12281 predicate(PowerArchitecturePPC64 >= 9);
12282 ins_cost(DEFAULT_COST);
12283
12284 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxF" %}
12285 size(4);
12286 ins_encode %{
12287 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12288 %}
12289 ins_pipe(pipe_class_default);
12290 %}
12291
12292 instruct maxD(regD dst, regD src1, regD src2) %{
12293 match(Set dst (MaxD src1 src2));
12294 predicate(PowerArchitecturePPC64 >= 9);
12295 ins_cost(DEFAULT_COST);
12296
12297 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxD" %}
12298 size(4);
12299 ins_encode %{
12300 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
12301 %}
12302 ins_pipe(pipe_class_default);
12303 %}
12304
12305 //---------- Population Count Instructions ------------------------------------
12306
12307 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
12308 match(Set dst (PopCountI src));
12309 predicate(UsePopCountInstruction);
12310 ins_cost(DEFAULT_COST);
12311
12312 format %{ "POPCNTW $dst, $src" %}
12313 size(4);
12314 ins_encode %{
12315 __ popcntw($dst$$Register, $src$$Register);
12316 %}
12317 ins_pipe(pipe_class_default);
12318 %}
12319
12320 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
12321 predicate(UsePopCountInstruction);
12322 match(Set dst (PopCountL src));
12323 ins_cost(DEFAULT_COST);
12324
12325 format %{ "POPCNTD $dst, $src" %}
12326 size(4);
12327 ins_encode %{
12328 __ popcntd($dst$$Register, $src$$Register);
12329 %}
12330 ins_pipe(pipe_class_default);
12331 %}
12332
12333 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
12334 match(Set dst (CountLeadingZerosI src));
12335 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12336 ins_cost(DEFAULT_COST);
12337
12338 format %{ "CNTLZW $dst, $src" %}
12339 size(4);
12340 ins_encode %{
12341 __ cntlzw($dst$$Register, $src$$Register);
12342 %}
12343 ins_pipe(pipe_class_default);
12344 %}
12345
12346 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
12347 match(Set dst (CountLeadingZerosL src));
12348 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12349 ins_cost(DEFAULT_COST);
12350
12351 format %{ "CNTLZD $dst, $src" %}
12352 size(4);
12353 ins_encode %{
12354 __ cntlzd($dst$$Register, $src$$Register);
12355 %}
12356 ins_pipe(pipe_class_default);
12357 %}
12358
12359 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
12360 // no match-rule, false predicate
12361 effect(DEF dst, USE src);
12362 predicate(false);
12363
12364 format %{ "CNTLZD $dst, $src" %}
12365 size(4);
12366 ins_encode %{
12367 __ cntlzd($dst$$Register, $src$$Register);
12368 %}
12369 ins_pipe(pipe_class_default);
12370 %}
12371
12372 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
12373 match(Set dst (CountTrailingZerosI src));
12374 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12375 ins_cost(DEFAULT_COST);
12376
12377 expand %{
12378 immI16 imm1 %{ (int)-1 %}
12379 immI16 imm2 %{ (int)32 %}
12380 immI_minus1 m1 %{ -1 %}
12381 iRegIdst tmpI1;
12382 iRegIdst tmpI2;
12383 iRegIdst tmpI3;
12384 addI_reg_imm16(tmpI1, src, imm1);
12385 andcI_reg_reg(tmpI2, src, m1, tmpI1);
12386 countLeadingZerosI(tmpI3, tmpI2);
12387 subI_imm16_reg(dst, imm2, tmpI3);
12388 %}
12389 %}
12390
12391 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{
12392 match(Set dst (CountTrailingZerosI src));
12393 predicate(UseCountTrailingZerosInstructionsPPC64);
12394 ins_cost(DEFAULT_COST);
12395
12396 format %{ "CNTTZW $dst, $src" %}
12397 size(4);
12398 ins_encode %{
12399 __ cnttzw($dst$$Register, $src$$Register);
12400 %}
12401 ins_pipe(pipe_class_default);
12402 %}
12403
12404 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
12405 match(Set dst (CountTrailingZerosL src));
12406 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12407 ins_cost(DEFAULT_COST);
12408
12409 expand %{
12410 immL16 imm1 %{ (long)-1 %}
12411 immI16 imm2 %{ (int)64 %}
12412 iRegLdst tmpL1;
12413 iRegLdst tmpL2;
12414 iRegIdst tmpL3;
12415 addL_reg_imm16(tmpL1, src, imm1);
12416 andcL_reg_reg(tmpL2, tmpL1, src);
12417 countLeadingZerosL(tmpL3, tmpL2);
12418 subI_imm16_reg(dst, imm2, tmpL3);
12419 %}
12420 %}
12421
12422 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{
12423 match(Set dst (CountTrailingZerosL src));
12424 predicate(UseCountTrailingZerosInstructionsPPC64);
12425 ins_cost(DEFAULT_COST);
12426
12427 format %{ "CNTTZD $dst, $src" %}
12428 size(4);
12429 ins_encode %{
12430 __ cnttzd($dst$$Register, $src$$Register);
12431 %}
12432 ins_pipe(pipe_class_default);
12433 %}
12434
12435 // Expand nodes for byte_reverse_int/ushort/short.
12436 instruct rlwinm(iRegIdst dst, iRegIsrc src, immI16 shift, immI16 mb, immI16 me) %{
12437 effect(DEF dst, USE src, USE shift, USE mb, USE me);
12438 predicate(false);
12439
12440 format %{ "RLWINM $dst, $src, $shift, $mb, $me" %}
12441 size(4);
12442 ins_encode %{
12443 __ rlwinm($dst$$Register, $src$$Register, $shift$$constant, $mb$$constant, $me$$constant);
12444 %}
12445 ins_pipe(pipe_class_default);
12446 %}
12447
12448 // Expand nodes for byte_reverse_int.
12449 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
12450 effect(DEF dst, USE src, USE n, USE b);
12451 predicate(false);
12452
12453 format %{ "INSRWI $dst, $src, $n, $b" %}
12454 size(4);
12455 ins_encode %{
12456 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
12457 %}
12458 ins_pipe(pipe_class_default);
12459 %}
12460
12461 // As insrwi_a, but with USE_DEF.
12462 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
12463 effect(USE_DEF dst, USE src, USE n, USE b);
12464 predicate(false);
12465
12466 format %{ "INSRWI $dst, $src, $n, $b" %}
12467 size(4);
12468 ins_encode %{
12469 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
12470 %}
12471 ins_pipe(pipe_class_default);
12472 %}
12473
12474 // Just slightly faster than java implementation.
12475 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
12476 match(Set dst (ReverseBytesI src));
12477 predicate(!UseByteReverseInstructions);
12478 ins_cost(7*DEFAULT_COST);
12479
12480 expand %{
12481 immI16 imm24 %{ (int) 24 %}
12482 immI16 imm16 %{ (int) 16 %}
12483 immI16 imm8 %{ (int) 8 %}
12484 immI16 imm4 %{ (int) 4 %}
12485 immI16 imm0 %{ (int) 0 %}
12486 iRegLdst tmpI1;
12487 iRegLdst tmpI2;
12488 iRegLdst tmpI3;
12489
12490 urShiftI_reg_imm(tmpI1, src, imm24);
12491 insrwi_a(dst, tmpI1, imm8, imm24);
12492 urShiftI_reg_imm(tmpI2, src, imm16);
12493 insrwi(dst, tmpI2, imm16, imm8);
12494 urShiftI_reg_imm(tmpI3, src, imm8);
12495 insrwi(dst, tmpI3, imm8, imm8);
12496 insrwi(dst, src, imm8, imm0);
12497 %}
12498 %}
12499
12500 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{
12501 match(Set dst (ReverseBytesI src));
12502 predicate(UseVectorByteReverseInstructionsPPC64);
12503 effect(TEMP tmpV);
12504 ins_cost(DEFAULT_COST*3);
12505 size(12);
12506 format %{ "MTVSRWZ $tmpV, $src\n"
12507 "\tXXBRW $tmpV, $tmpV\n"
12508 "\tMFVSRWZ $dst, $tmpV" %}
12509
12510 ins_encode %{
12511 __ mtvsrwz($tmpV$$VectorRegister.to_vsr(), $src$$Register);
12512 __ xxbrw($tmpV$$VectorRegister.to_vsr(), $tmpV$$VectorRegister->to_vsr());
12513 __ mfvsrwz($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12514 %}
12515 ins_pipe(pipe_class_default);
12516 %}
12517
12518 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{
12519 match(Set dst (ReverseBytesI src));
12520 predicate(UseByteReverseInstructions);
12521 ins_cost(DEFAULT_COST);
12522 size(4);
12523
12524 format %{ "BRW $dst, $src" %}
12525
12526 ins_encode %{
12527 __ brw($dst$$Register, $src$$Register);
12528 %}
12529 ins_pipe(pipe_class_default);
12530 %}
12531
12532 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
12533 match(Set dst (ReverseBytesL src));
12534 predicate(!UseByteReverseInstructions);
12535 ins_cost(15*DEFAULT_COST);
12536
12537 expand %{
12538 immI16 imm56 %{ (int) 56 %}
12539 immI16 imm48 %{ (int) 48 %}
12540 immI16 imm40 %{ (int) 40 %}
12541 immI16 imm32 %{ (int) 32 %}
12542 immI16 imm24 %{ (int) 24 %}
12543 immI16 imm16 %{ (int) 16 %}
12544 immI16 imm8 %{ (int) 8 %}
12545 immI16 imm0 %{ (int) 0 %}
12546 iRegLdst tmpL1;
12547 iRegLdst tmpL2;
12548 iRegLdst tmpL3;
12549 iRegLdst tmpL4;
12550 iRegLdst tmpL5;
12551 iRegLdst tmpL6;
12552
12553 // src : |a|b|c|d|e|f|g|h|
12554 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
12555 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
12556 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
12557 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
12558 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
12559 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
12560 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
12561 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
12562 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
12563 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
12564 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
12565 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
12566 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
12567 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
12568 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
12569 %}
12570 %}
12571
12572 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{
12573 match(Set dst (ReverseBytesL src));
12574 predicate(UseVectorByteReverseInstructionsPPC64);
12575 effect(TEMP tmpV);
12576 ins_cost(DEFAULT_COST*3);
12577 size(12);
12578 format %{ "MTVSRD $tmpV, $src\n"
12579 "\tXXBRD $tmpV, $tmpV\n"
12580 "\tMFVSRD $dst, $tmpV" %}
12581
12582 ins_encode %{
12583 __ mtvsrd($tmpV$$VectorRegister->to_vsr(), $src$$Register);
12584 __ xxbrd($tmpV$$VectorRegister->to_vsr(), $tmpV$$VectorRegister->to_vsr());
12585 __ mfvsrd($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12586 %}
12587 ins_pipe(pipe_class_default);
12588 %}
12589
12590 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{
12591 match(Set dst (ReverseBytesL src));
12592 predicate(UseByteReverseInstructions);
12593 ins_cost(DEFAULT_COST);
12594 size(4);
12595
12596 format %{ "BRD $dst, $src" %}
12597
12598 ins_encode %{
12599 __ brd($dst$$Register, $src$$Register);
12600 %}
12601 ins_pipe(pipe_class_default);
12602 %}
12603
12604 // Need zero extend. Must not use brh only.
12605 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
12606 match(Set dst (ReverseBytesUS src));
12607 ins_cost(2*DEFAULT_COST);
12608
12609 expand %{
12610 immI16 imm31 %{ (int) 31 %}
12611 immI16 imm24 %{ (int) 24 %}
12612 immI16 imm16 %{ (int) 16 %}
12613 immI16 imm8 %{ (int) 8 %}
12614
12615 rlwinm(dst, src, imm24, imm24, imm31);
12616 insrwi(dst, src, imm8, imm16);
12617 %}
12618 %}
12619
12620 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
12621 match(Set dst (ReverseBytesS src));
12622 predicate(!UseByteReverseInstructions);
12623 ins_cost(3*DEFAULT_COST);
12624
12625 expand %{
12626 immI16 imm16 %{ (int) 16 %}
12627 immI16 imm8 %{ (int) 8 %}
12628 iRegLdst tmpI1;
12629
12630 urShiftI_reg_imm(tmpI1, src, imm8);
12631 insrwi(tmpI1, src, imm8, imm16);
12632 extsh(dst, tmpI1);
12633 %}
12634 %}
12635
12636 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{
12637 match(Set dst (ReverseBytesS src));
12638 predicate(UseByteReverseInstructions);
12639 ins_cost(DEFAULT_COST);
12640 size(8);
12641
12642 format %{ "BRH $dst, $src\n\t"
12643 "EXTSH $dst, $dst" %}
12644
12645 ins_encode %{
12646 __ brh($dst$$Register, $src$$Register);
12647 __ extsh($dst$$Register, $dst$$Register);
12648 %}
12649 ins_pipe(pipe_class_default);
12650 %}
12651
12652 // Load Integer reversed byte order
12653 instruct loadI_reversed(iRegIdst dst, indirect mem) %{
12654 match(Set dst (ReverseBytesI (LoadI mem)));
12655 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12656 ins_cost(MEMORY_REF_COST);
12657
12658 size(4);
12659 ins_encode %{
12660 __ lwbrx($dst$$Register, $mem$$Register);
12661 %}
12662 ins_pipe(pipe_class_default);
12663 %}
12664
12665 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{
12666 match(Set dst (ReverseBytesI (LoadI mem)));
12667 ins_cost(2 * MEMORY_REF_COST);
12668
12669 size(12);
12670 ins_encode %{
12671 __ lwbrx($dst$$Register, $mem$$Register);
12672 __ twi_0($dst$$Register);
12673 __ isync();
12674 %}
12675 ins_pipe(pipe_class_default);
12676 %}
12677
12678 // Load Long - aligned and reversed
12679 instruct loadL_reversed(iRegLdst dst, indirect mem) %{
12680 match(Set dst (ReverseBytesL (LoadL mem)));
12681 predicate((n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))));
12682 ins_cost(MEMORY_REF_COST);
12683
12684 size(4);
12685 ins_encode %{
12686 __ ldbrx($dst$$Register, $mem$$Register);
12687 %}
12688 ins_pipe(pipe_class_default);
12689 %}
12690
12691 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{
12692 match(Set dst (ReverseBytesL (LoadL mem)));
12693 ins_cost(2 * MEMORY_REF_COST);
12694
12695 size(12);
12696 ins_encode %{
12697 __ ldbrx($dst$$Register, $mem$$Register);
12698 __ twi_0($dst$$Register);
12699 __ isync();
12700 %}
12701 ins_pipe(pipe_class_default);
12702 %}
12703
12704 // Load unsigned short / char reversed byte order
12705 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
12706 match(Set dst (ReverseBytesUS (LoadUS mem)));
12707 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12708 ins_cost(MEMORY_REF_COST);
12709
12710 size(4);
12711 ins_encode %{
12712 __ lhbrx($dst$$Register, $mem$$Register);
12713 %}
12714 ins_pipe(pipe_class_default);
12715 %}
12716
12717 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{
12718 match(Set dst (ReverseBytesUS (LoadUS mem)));
12719 ins_cost(2 * MEMORY_REF_COST);
12720
12721 size(12);
12722 ins_encode %{
12723 __ lhbrx($dst$$Register, $mem$$Register);
12724 __ twi_0($dst$$Register);
12725 __ isync();
12726 %}
12727 ins_pipe(pipe_class_default);
12728 %}
12729
12730 // Load short reversed byte order
12731 instruct loadS_reversed(iRegIdst dst, indirect mem) %{
12732 match(Set dst (ReverseBytesS (LoadS mem)));
12733 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12734 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
12735
12736 size(8);
12737 ins_encode %{
12738 __ lhbrx($dst$$Register, $mem$$Register);
12739 __ extsh($dst$$Register, $dst$$Register);
12740 %}
12741 ins_pipe(pipe_class_default);
12742 %}
12743
12744 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{
12745 match(Set dst (ReverseBytesS (LoadS mem)));
12746 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12747
12748 size(16);
12749 ins_encode %{
12750 __ lhbrx($dst$$Register, $mem$$Register);
12751 __ twi_0($dst$$Register);
12752 __ extsh($dst$$Register, $dst$$Register);
12753 __ isync();
12754 %}
12755 ins_pipe(pipe_class_default);
12756 %}
12757
12758 // Store Integer reversed byte order
12759 instruct storeI_reversed(iRegIsrc src, indirect mem) %{
12760 match(Set mem (StoreI mem (ReverseBytesI src)));
12761 ins_cost(MEMORY_REF_COST);
12762
12763 size(4);
12764 ins_encode %{
12765 __ stwbrx($src$$Register, $mem$$Register);
12766 %}
12767 ins_pipe(pipe_class_default);
12768 %}
12769
12770 // Store Long reversed byte order
12771 instruct storeL_reversed(iRegLsrc src, indirect mem) %{
12772 match(Set mem (StoreL mem (ReverseBytesL src)));
12773 ins_cost(MEMORY_REF_COST);
12774
12775 size(4);
12776 ins_encode %{
12777 __ stdbrx($src$$Register, $mem$$Register);
12778 %}
12779 ins_pipe(pipe_class_default);
12780 %}
12781
12782 // Store unsigned short / char reversed byte order
12783 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
12784 match(Set mem (StoreC mem (ReverseBytesUS src)));
12785 ins_cost(MEMORY_REF_COST);
12786
12787 size(4);
12788 ins_encode %{
12789 __ sthbrx($src$$Register, $mem$$Register);
12790 %}
12791 ins_pipe(pipe_class_default);
12792 %}
12793
12794 // Store short reversed byte order
12795 instruct storeS_reversed(iRegIsrc src, indirect mem) %{
12796 match(Set mem (StoreC mem (ReverseBytesS src)));
12797 ins_cost(MEMORY_REF_COST);
12798
12799 size(4);
12800 ins_encode %{
12801 __ sthbrx($src$$Register, $mem$$Register);
12802 %}
12803 ins_pipe(pipe_class_default);
12804 %}
12805
12806 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
12807 effect(DEF temp1, USE src);
12808
12809 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %}
12810 size(4);
12811 ins_encode %{
12812 __ mtvsrwz($temp1$$VectorRegister->to_vsr(), $src$$Register);
12813 %}
12814 ins_pipe(pipe_class_default);
12815 %}
12816
12817 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{
12818 effect(DEF dst, USE src, USE imm1);
12819
12820 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %}
12821 size(4);
12822 ins_encode %{
12823 __ xxspltw($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $imm1$$constant);
12824 %}
12825 ins_pipe(pipe_class_default);
12826 %}
12827
12828 instruct xscvdpspn_regF(vecX dst, regF src) %{
12829 effect(DEF dst, USE src);
12830
12831 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %}
12832 size(4);
12833 ins_encode %{
12834 __ xscvdpspn($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr());
12835 %}
12836 ins_pipe(pipe_class_default);
12837 %}
12838
12839 //---------- Replicate Vector Instructions ------------------------------------
12840
12841 // Insrdi does replicate if src == dst.
12842 instruct repl32(iRegLdst dst) %{
12843 predicate(false);
12844 effect(USE_DEF dst);
12845
12846 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %}
12847 size(4);
12848 ins_encode %{
12849 __ insrdi($dst$$Register, $dst$$Register, 32, 0);
12850 %}
12851 ins_pipe(pipe_class_default);
12852 %}
12853
12854 // Insrdi does replicate if src == dst.
12855 instruct repl48(iRegLdst dst) %{
12856 predicate(false);
12857 effect(USE_DEF dst);
12858
12859 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %}
12860 size(4);
12861 ins_encode %{
12862 __ insrdi($dst$$Register, $dst$$Register, 48, 0);
12863 %}
12864 ins_pipe(pipe_class_default);
12865 %}
12866
12867 // Insrdi does replicate if src == dst.
12868 instruct repl56(iRegLdst dst) %{
12869 predicate(false);
12870 effect(USE_DEF dst);
12871
12872 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %}
12873 size(4);
12874 ins_encode %{
12875 __ insrdi($dst$$Register, $dst$$Register, 56, 0);
12876 %}
12877 ins_pipe(pipe_class_default);
12878 %}
12879
12880 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12881 match(Set dst (Replicate src));
12882 predicate(n->as_Vector()->length() == 8 &&
12883 Matcher::vector_element_basic_type(n) == T_BYTE);
12884 expand %{
12885 moveReg(dst, src);
12886 repl56(dst);
12887 repl48(dst);
12888 repl32(dst);
12889 %}
12890 %}
12891
12892 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
12893 match(Set dst (Replicate zero));
12894 predicate(n->as_Vector()->length() == 8 &&
12895 Matcher::vector_element_basic_type(n) == T_BYTE);
12896 format %{ "LI $dst, #0 \t// replicate8B" %}
12897 size(4);
12898 ins_encode %{
12899 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12900 %}
12901 ins_pipe(pipe_class_default);
12902 %}
12903
12904 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
12905 match(Set dst (Replicate src));
12906 predicate(n->as_Vector()->length() == 8 &&
12907 Matcher::vector_element_basic_type(n) == T_BYTE);
12908 format %{ "LI $dst, #-1 \t// replicate8B" %}
12909 size(4);
12910 ins_encode %{
12911 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12912 %}
12913 ins_pipe(pipe_class_default);
12914 %}
12915
12916 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{
12917 match(Set dst (Replicate src));
12918 predicate(n->as_Vector()->length() == 16 &&
12919 Matcher::vector_element_basic_type(n) == T_BYTE);
12920
12921 expand %{
12922 iRegLdst tmpL;
12923 vecX tmpV;
12924 immI8 imm1 %{ (int) 1 %}
12925 moveReg(tmpL, src);
12926 repl56(tmpL);
12927 repl48(tmpL);
12928 mtvsrwz(tmpV, tmpL);
12929 xxspltw(dst, tmpV, imm1);
12930 %}
12931 %}
12932
12933 instruct repl16B_immI0(vecX dst, immI_0 zero) %{
12934 match(Set dst (Replicate zero));
12935 predicate(n->as_Vector()->length() == 16 &&
12936 Matcher::vector_element_basic_type(n) == T_BYTE);
12937
12938 format %{ "XXLXOR $dst, $zero \t// replicate16B" %}
12939 size(4);
12940 ins_encode %{
12941 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12942 %}
12943 ins_pipe(pipe_class_default);
12944 %}
12945
12946 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{
12947 match(Set dst (Replicate src));
12948 predicate(n->as_Vector()->length() == 16 &&
12949 Matcher::vector_element_basic_type(n) == T_BYTE);
12950
12951 format %{ "XXLEQV $dst, $src \t// replicate16B" %}
12952 size(4);
12953 ins_encode %{
12954 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12955 %}
12956 ins_pipe(pipe_class_default);
12957 %}
12958
12959 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12960 match(Set dst (Replicate src));
12961 predicate(n->as_Vector()->length() == 4 &&
12962 Matcher::vector_element_basic_type(n) == T_SHORT);
12963 expand %{
12964 moveReg(dst, src);
12965 repl48(dst);
12966 repl32(dst);
12967 %}
12968 %}
12969
12970 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
12971 match(Set dst (Replicate zero));
12972 predicate(n->as_Vector()->length() == 4 &&
12973 Matcher::vector_element_basic_type(n) == T_SHORT);
12974 format %{ "LI $dst, #0 \t// replicate4S" %}
12975 size(4);
12976 ins_encode %{
12977 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12978 %}
12979 ins_pipe(pipe_class_default);
12980 %}
12981
12982 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
12983 match(Set dst (Replicate src));
12984 predicate(n->as_Vector()->length() == 4 &&
12985 Matcher::vector_element_basic_type(n) == T_SHORT);
12986 format %{ "LI $dst, -1 \t// replicate4S" %}
12987 size(4);
12988 ins_encode %{
12989 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12990 %}
12991 ins_pipe(pipe_class_default);
12992 %}
12993
12994 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{
12995 match(Set dst (Replicate src));
12996 predicate(n->as_Vector()->length() == 8 &&
12997 Matcher::vector_element_basic_type(n) == T_SHORT);
12998
12999 expand %{
13000 iRegLdst tmpL;
13001 vecX tmpV;
13002 immI8 zero %{ (int) 0 %}
13003 moveReg(tmpL, src);
13004 repl48(tmpL);
13005 repl32(tmpL);
13006 mtvsrd(tmpV, tmpL);
13007 xxpermdi(dst, tmpV, tmpV, zero);
13008 %}
13009 %}
13010
13011 instruct repl8S_immI0(vecX dst, immI_0 zero) %{
13012 match(Set dst (Replicate zero));
13013 predicate(n->as_Vector()->length() == 8 &&
13014 Matcher::vector_element_basic_type(n) == T_SHORT);
13015
13016 format %{ "XXLXOR $dst, $zero \t// replicate8S" %}
13017 size(4);
13018 ins_encode %{
13019 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13020 %}
13021 ins_pipe(pipe_class_default);
13022 %}
13023
13024 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{
13025 match(Set dst (Replicate src));
13026 predicate(n->as_Vector()->length() == 8 &&
13027 Matcher::vector_element_basic_type(n) == T_SHORT);
13028
13029 format %{ "XXLEQV $dst, $src \t// replicate8S" %}
13030 size(4);
13031 ins_encode %{
13032 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13033 %}
13034 ins_pipe(pipe_class_default);
13035 %}
13036
13037 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
13038 match(Set dst (Replicate src));
13039 predicate(n->as_Vector()->length() == 2 &&
13040 Matcher::vector_element_basic_type(n) == T_INT);
13041 ins_cost(2 * DEFAULT_COST);
13042 expand %{
13043 moveReg(dst, src);
13044 repl32(dst);
13045 %}
13046 %}
13047
13048 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
13049 match(Set dst (Replicate zero));
13050 predicate(n->as_Vector()->length() == 2 &&
13051 Matcher::vector_element_basic_type(n) == T_INT);
13052 format %{ "LI $dst, #0 \t// replicate2I" %}
13053 size(4);
13054 ins_encode %{
13055 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
13056 %}
13057 ins_pipe(pipe_class_default);
13058 %}
13059
13060 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
13061 match(Set dst (Replicate src));
13062 predicate(n->as_Vector()->length() == 2 &&
13063 Matcher::vector_element_basic_type(n) == T_INT);
13064 format %{ "LI $dst, -1 \t// replicate2I" %}
13065 size(4);
13066 ins_encode %{
13067 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
13068 %}
13069 ins_pipe(pipe_class_default);
13070 %}
13071
13072 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{
13073 match(Set dst (Replicate src));
13074 predicate(n->as_Vector()->length() == 4 &&
13075 Matcher::vector_element_basic_type(n) == T_INT);
13076 ins_cost(2 * DEFAULT_COST);
13077
13078 expand %{
13079 iRegLdst tmpL;
13080 vecX tmpV;
13081 immI8 zero %{ (int) 0 %}
13082 moveReg(tmpL, src);
13083 repl32(tmpL);
13084 mtvsrd(tmpV, tmpL);
13085 xxpermdi(dst, tmpV, tmpV, zero);
13086 %}
13087 %}
13088
13089 instruct repl4I_immI0(vecX dst, immI_0 zero) %{
13090 match(Set dst (Replicate zero));
13091 predicate(n->as_Vector()->length() == 4 &&
13092 Matcher::vector_element_basic_type(n) == T_INT);
13093
13094 format %{ "XXLXOR $dst, $zero \t// replicate4I" %}
13095 size(4);
13096 ins_encode %{
13097 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13098 %}
13099 ins_pipe(pipe_class_default);
13100 %}
13101
13102 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{
13103 match(Set dst (Replicate src));
13104 predicate(n->as_Vector()->length() == 4 &&
13105 Matcher::vector_element_basic_type(n) == T_INT);
13106
13107 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %}
13108 size(4);
13109 ins_encode %{
13110 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13111 %}
13112 ins_pipe(pipe_class_default);
13113 %}
13114
13115 // Move float to int register via stack, replicate.
13116 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
13117 match(Set dst (Replicate src));
13118 predicate(n->as_Vector()->length() == 2 &&
13119 Matcher::vector_element_basic_type(n) == T_FLOAT);
13120 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
13121 expand %{
13122 stackSlotL tmpS;
13123 iRegIdst tmpI;
13124 moveF2I_reg_stack(tmpS, src); // Move float to stack.
13125 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
13126 moveReg(dst, tmpI); // Move int to long reg.
13127 repl32(dst); // Replicate bitpattern.
13128 %}
13129 %}
13130
13131 // Replicate scalar constant to packed float values in Double register
13132 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
13133 match(Set dst (Replicate src));
13134 predicate(n->as_Vector()->length() == 2 &&
13135 Matcher::vector_element_basic_type(n) == T_FLOAT);
13136 ins_cost(5 * DEFAULT_COST);
13137
13138 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
13139 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
13140 %}
13141
13142 // Replicate scalar zero constant to packed float values in Double register
13143 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
13144 match(Set dst (Replicate zero));
13145 predicate(n->as_Vector()->length() == 2 &&
13146 Matcher::vector_element_basic_type(n) == T_FLOAT);
13147
13148 format %{ "LI $dst, #0 \t// replicate2F" %}
13149 size(4);
13150 ins_encode %{
13151 __ li($dst$$Register, 0x0);
13152 %}
13153 ins_pipe(pipe_class_default);
13154 %}
13155
13156
13157 //----------Vector Arithmetic Instructions--------------------------------------
13158
13159 // Vector Addition Instructions
13160
13161 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
13162 match(Set dst (AddVB src1 src2));
13163 predicate(n->as_Vector()->length() == 16);
13164 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %}
13165 size(4);
13166 ins_encode %{
13167 __ vaddubm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13168 %}
13169 ins_pipe(pipe_class_default);
13170 %}
13171
13172 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
13173 match(Set dst (AddVS src1 src2));
13174 predicate(n->as_Vector()->length() == 8);
13175 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %}
13176 size(4);
13177 ins_encode %{
13178 __ vadduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13179 %}
13180 ins_pipe(pipe_class_default);
13181 %}
13182
13183 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
13184 match(Set dst (AddVI src1 src2));
13185 predicate(n->as_Vector()->length() == 4);
13186 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %}
13187 size(4);
13188 ins_encode %{
13189 __ vadduwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13190 %}
13191 ins_pipe(pipe_class_default);
13192 %}
13193
13194 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
13195 match(Set dst (AddVF src1 src2));
13196 predicate(n->as_Vector()->length() == 4);
13197 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %}
13198 size(4);
13199 ins_encode %{
13200 __ vaddfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13201 %}
13202 ins_pipe(pipe_class_default);
13203 %}
13204
13205 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
13206 match(Set dst (AddVL src1 src2));
13207 predicate(n->as_Vector()->length() == 2);
13208 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %}
13209 size(4);
13210 ins_encode %{
13211 __ vaddudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13212 %}
13213 ins_pipe(pipe_class_default);
13214 %}
13215
13216 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
13217 match(Set dst (AddVD src1 src2));
13218 predicate(n->as_Vector()->length() == 2);
13219 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %}
13220 size(4);
13221 ins_encode %{
13222 __ xvadddp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13223 %}
13224 ins_pipe(pipe_class_default);
13225 %}
13226
13227 // Vector Subtraction Instructions
13228
13229 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
13230 match(Set dst (SubVB src1 src2));
13231 predicate(n->as_Vector()->length() == 16);
13232 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %}
13233 size(4);
13234 ins_encode %{
13235 __ vsububm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13236 %}
13237 ins_pipe(pipe_class_default);
13238 %}
13239
13240 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
13241 match(Set dst (SubVS src1 src2));
13242 predicate(n->as_Vector()->length() == 8);
13243 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %}
13244 size(4);
13245 ins_encode %{
13246 __ vsubuhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13247 %}
13248 ins_pipe(pipe_class_default);
13249 %}
13250
13251 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
13252 match(Set dst (SubVI src1 src2));
13253 predicate(n->as_Vector()->length() == 4);
13254 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %}
13255 size(4);
13256 ins_encode %{
13257 __ vsubuwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13258 %}
13259 ins_pipe(pipe_class_default);
13260 %}
13261
13262 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
13263 match(Set dst (SubVF src1 src2));
13264 predicate(n->as_Vector()->length() == 4);
13265 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %}
13266 size(4);
13267 ins_encode %{
13268 __ vsubfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13269 %}
13270 ins_pipe(pipe_class_default);
13271 %}
13272
13273 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
13274 match(Set dst (SubVL src1 src2));
13275 predicate(n->as_Vector()->length() == 2);
13276 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %}
13277 size(4);
13278 ins_encode %{
13279 __ vsubudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13280 %}
13281 ins_pipe(pipe_class_default);
13282 %}
13283
13284 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
13285 match(Set dst (SubVD src1 src2));
13286 predicate(n->as_Vector()->length() == 2);
13287 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %}
13288 size(4);
13289 ins_encode %{
13290 __ xvsubdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13291 %}
13292 ins_pipe(pipe_class_default);
13293 %}
13294
13295 // Vector Multiplication Instructions
13296
13297 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
13298 match(Set dst (MulVS src1 src2));
13299 predicate(n->as_Vector()->length() == 8);
13300 effect(TEMP tmp);
13301 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %}
13302 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %}
13303 size(8);
13304 ins_encode %{
13305 __ vspltish($tmp$$VectorRegister, 0);
13306 __ vmladduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister, $tmp$$VectorRegister);
13307 %}
13308 ins_pipe(pipe_class_default);
13309 %}
13310
13311 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
13312 match(Set dst (MulVI src1 src2));
13313 predicate(n->as_Vector()->length() == 4);
13314 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %}
13315 size(4);
13316 ins_encode %{
13317 __ vmuluwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13318 %}
13319 ins_pipe(pipe_class_default);
13320 %}
13321
13322 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
13323 match(Set dst (MulVF src1 src2));
13324 predicate(n->as_Vector()->length() == 4);
13325 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %}
13326 size(4);
13327 ins_encode %{
13328 __ xvmulsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13329 %}
13330 ins_pipe(pipe_class_default);
13331 %}
13332
13333 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
13334 match(Set dst (MulVD src1 src2));
13335 predicate(n->as_Vector()->length() == 2);
13336 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %}
13337 size(4);
13338 ins_encode %{
13339 __ xvmuldp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13340 %}
13341 ins_pipe(pipe_class_default);
13342 %}
13343
13344 // Vector Division Instructions
13345
13346 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
13347 match(Set dst (DivVF src1 src2));
13348 predicate(n->as_Vector()->length() == 4);
13349 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %}
13350 size(4);
13351 ins_encode %{
13352 __ xvdivsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13353 %}
13354 ins_pipe(pipe_class_default);
13355 %}
13356
13357 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
13358 match(Set dst (DivVD src1 src2));
13359 predicate(n->as_Vector()->length() == 2);
13360 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %}
13361 size(4);
13362 ins_encode %{
13363 __ xvdivdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13364 %}
13365 ins_pipe(pipe_class_default);
13366 %}
13367
13368 // Vector Min / Max Instructions
13369
13370 instruct vmin_reg(vecX dst, vecX src1, vecX src2) %{
13371 match(Set dst (MinV src1 src2));
13372 format %{ "VMIN $dst,$src1,$src2\t// vector min" %}
13373 size(4);
13374 ins_encode %{
13375 BasicType bt = Matcher::vector_element_basic_type(this);
13376 switch (bt) {
13377 case T_INT:
13378 __ vminsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13379 break;
13380 case T_LONG:
13381 __ vminsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13382 break;
13383 default:
13384 ShouldNotReachHere();
13385 }
13386 %}
13387 ins_pipe(pipe_class_default);
13388 %}
13389
13390 instruct vmax_reg(vecX dst, vecX src1, vecX src2) %{
13391 match(Set dst (MaxV src1 src2));
13392 format %{ "VMAX $dst,$src1,$src2\t// vector max" %}
13393 size(4);
13394 ins_encode %{
13395 BasicType bt = Matcher::vector_element_basic_type(this);
13396 switch (bt) {
13397 case T_INT:
13398 __ vmaxsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13399 break;
13400 case T_LONG:
13401 __ vmaxsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13402 break;
13403 default:
13404 ShouldNotReachHere();
13405 }
13406 %}
13407 ins_pipe(pipe_class_default);
13408 %}
13409
13410 instruct vminu_reg(vecX dst, vecX src1, vecX src2) %{
13411 match(Set dst (UMinV src1 src2));
13412 format %{ "VMINU $dst,$src1,$src2\t// vector unsigned min" %}
13413 size(4);
13414 ins_encode %{
13415 BasicType bt = Matcher::vector_element_basic_type(this);
13416 switch (bt) {
13417 case T_INT:
13418 __ vminuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13419 break;
13420 case T_LONG:
13421 __ vminud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13422 break;
13423 default:
13424 ShouldNotReachHere();
13425 }
13426 %}
13427 ins_pipe(pipe_class_default);
13428 %}
13429
13430 instruct vmaxu_reg(vecX dst, vecX src1, vecX src2) %{
13431 match(Set dst (UMaxV src1 src2));
13432 format %{ "VMAXU $dst,$src1,$src2\t// vector unsigned max" %}
13433 size(4);
13434 ins_encode %{
13435 BasicType bt = Matcher::vector_element_basic_type(this);
13436 switch (bt) {
13437 case T_INT:
13438 __ vmaxuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13439 break;
13440 case T_LONG:
13441 __ vmaxud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13442 break;
13443 default:
13444 ShouldNotReachHere();
13445 }
13446 %}
13447 ins_pipe(pipe_class_default);
13448 %}
13449
13450 instruct vand(vecX dst, vecX src1, vecX src2) %{
13451 match(Set dst (AndV src1 src2));
13452 size(4);
13453 format %{ "VAND $dst,$src1,$src2\t// and vectors" %}
13454 ins_encode %{
13455 __ vand($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13456 %}
13457 ins_pipe(pipe_class_default);
13458 %}
13459
13460 instruct vor(vecX dst, vecX src1, vecX src2) %{
13461 match(Set dst (OrV src1 src2));
13462 size(4);
13463 format %{ "VOR $dst,$src1,$src2\t// or vectors" %}
13464 ins_encode %{
13465 __ vor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13466 %}
13467 ins_pipe(pipe_class_default);
13468 %}
13469
13470 instruct vxor(vecX dst, vecX src1, vecX src2) %{
13471 match(Set dst (XorV src1 src2));
13472 size(4);
13473 format %{ "VXOR $dst,$src1,$src2\t// xor vectors" %}
13474 ins_encode %{
13475 __ vxor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13476 %}
13477 ins_pipe(pipe_class_default);
13478 %}
13479
13480 instruct reductionI_arith_logic(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2) %{
13481 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13482 match(Set dst (AddReductionVI srcInt srcVec));
13483 match(Set dst (MulReductionVI srcInt srcVec));
13484 match(Set dst (AndReductionV srcInt srcVec));
13485 match(Set dst ( OrReductionV srcInt srcVec));
13486 match(Set dst (XorReductionV srcInt srcVec));
13487 effect(TEMP tmp1, TEMP tmp2);
13488 ins_cost(DEFAULT_COST * 6);
13489 format %{ "REDUCEI_ARITH_LOGIC // $dst,$srcInt,$srcVec,$tmp1,$tmp2\t// reduce vector int add/mul/and/or/xor" %}
13490 size(24);
13491 ins_encode %{
13492 int opcode = this->ideal_Opcode();
13493 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13494 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13495 %}
13496 ins_pipe(pipe_class_default);
13497 %}
13498
13499 instruct reductionI_min_max(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2, flagsRegCR0 cr0) %{
13500 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13501 match(Set dst (MinReductionV srcInt srcVec));
13502 match(Set dst (MaxReductionV srcInt srcVec));
13503 effect(TEMP tmp1, TEMP tmp2, KILL cr0);
13504 ins_cost(DEFAULT_COST * 7);
13505 format %{ "REDUCEI_MINMAX // $dst,$srcInt,$srcVec,$tmp1,$tmp2,cr0\t// reduce vector int min/max" %}
13506 size(28);
13507 ins_encode %{
13508 int opcode = this->ideal_Opcode();
13509 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13510 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13511 %}
13512 ins_pipe(pipe_class_default);
13513 %}
13514
13515 // Vector Absolute Instructions
13516
13517 instruct vabs4F_reg(vecX dst, vecX src) %{
13518 match(Set dst (AbsVF src));
13519 predicate(n->as_Vector()->length() == 4);
13520 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
13521 size(4);
13522 ins_encode %{
13523 __ xvabssp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13524 %}
13525 ins_pipe(pipe_class_default);
13526 %}
13527
13528 instruct vabs2D_reg(vecX dst, vecX src) %{
13529 match(Set dst (AbsVD src));
13530 predicate(n->as_Vector()->length() == 2);
13531 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
13532 size(4);
13533 ins_encode %{
13534 __ xvabsdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13535 %}
13536 ins_pipe(pipe_class_default);
13537 %}
13538
13539 // Round Instructions
13540 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{
13541 match(Set dst (RoundDoubleMode src rmode));
13542 format %{ "RoundDoubleMode $src,$rmode" %}
13543 size(4);
13544 ins_encode %{
13545 switch ($rmode$$constant) {
13546 case RoundDoubleModeNode::rmode_rint:
13547 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr());
13548 break;
13549 case RoundDoubleModeNode::rmode_floor:
13550 __ frim($dst$$FloatRegister, $src$$FloatRegister);
13551 break;
13552 case RoundDoubleModeNode::rmode_ceil:
13553 __ frip($dst$$FloatRegister, $src$$FloatRegister);
13554 break;
13555 default:
13556 ShouldNotReachHere();
13557 }
13558 %}
13559 ins_pipe(pipe_class_default);
13560 %}
13561
13562 // Vector Round Instructions
13563 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
13564 match(Set dst (RoundDoubleModeV src rmode));
13565 predicate(n->as_Vector()->length() == 2);
13566 format %{ "RoundDoubleModeV $src,$rmode" %}
13567 size(4);
13568 ins_encode %{
13569 switch ($rmode$$constant) {
13570 case RoundDoubleModeNode::rmode_rint:
13571 __ xvrdpic($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13572 break;
13573 case RoundDoubleModeNode::rmode_floor:
13574 __ xvrdpim($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13575 break;
13576 case RoundDoubleModeNode::rmode_ceil:
13577 __ xvrdpip($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13578 break;
13579 default:
13580 ShouldNotReachHere();
13581 }
13582 %}
13583 ins_pipe(pipe_class_default);
13584 %}
13585
13586 // Vector Negate Instructions
13587
13588 instruct vneg4F_reg(vecX dst, vecX src) %{
13589 match(Set dst (NegVF src));
13590 predicate(n->as_Vector()->length() == 4);
13591 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
13592 size(4);
13593 ins_encode %{
13594 __ xvnegsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13595 %}
13596 ins_pipe(pipe_class_default);
13597 %}
13598
13599 instruct vneg2D_reg(vecX dst, vecX src) %{
13600 match(Set dst (NegVD src));
13601 predicate(n->as_Vector()->length() == 2);
13602 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
13603 size(4);
13604 ins_encode %{
13605 __ xvnegdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13606 %}
13607 ins_pipe(pipe_class_default);
13608 %}
13609
13610 instruct vneg4I_reg(vecX dst, vecX src) %{
13611 match(Set dst (NegVI src));
13612 predicate(Matcher::vector_element_basic_type(n) == T_INT);
13613 format %{ "VNEGW $dst,$src\t// negate int vector" %}
13614 size(4);
13615 ins_encode %{
13616 __ vnegw($dst$$VectorRegister, $src$$VectorRegister);
13617 %}
13618 ins_pipe(pipe_class_default);
13619 %}
13620
13621 // Vector Square Root Instructions
13622
13623 instruct vsqrt4F_reg(vecX dst, vecX src) %{
13624 match(Set dst (SqrtVF src));
13625 predicate(n->as_Vector()->length() == 4);
13626 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
13627 size(4);
13628 ins_encode %{
13629 __ xvsqrtsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13630 %}
13631 ins_pipe(pipe_class_default);
13632 %}
13633
13634 instruct vsqrt2D_reg(vecX dst, vecX src) %{
13635 match(Set dst (SqrtVD src));
13636 predicate(n->as_Vector()->length() == 2);
13637 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %}
13638 size(4);
13639 ins_encode %{
13640 __ xvsqrtdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13641 %}
13642 ins_pipe(pipe_class_default);
13643 %}
13644
13645 // Vector Population Count and Zeros Count Instructions
13646
13647 instruct vpopcnt_reg(vecX dst, vecX src) %{
13648 match(Set dst (PopCountVI src));
13649 match(Set dst (PopCountVL src));
13650 format %{ "VPOPCNT $dst,$src\t// pop count packed" %}
13651 size(4);
13652 ins_encode %{
13653 BasicType bt = Matcher::vector_element_basic_type(this);
13654 switch (bt) {
13655 case T_BYTE:
13656 __ vpopcntb($dst$$VectorRegister, $src$$VectorRegister);
13657 break;
13658 case T_SHORT:
13659 __ vpopcnth($dst$$VectorRegister, $src$$VectorRegister);
13660 break;
13661 case T_INT:
13662 __ vpopcntw($dst$$VectorRegister, $src$$VectorRegister);
13663 break;
13664 case T_LONG:
13665 __ vpopcntd($dst$$VectorRegister, $src$$VectorRegister);
13666 break;
13667 default:
13668 ShouldNotReachHere();
13669 }
13670 %}
13671 ins_pipe(pipe_class_default);
13672 %}
13673
13674 instruct vcount_leading_zeros_reg(vecX dst, vecX src) %{
13675 match(Set dst (CountLeadingZerosV src));
13676 format %{ "VCLZ $dst,$src\t// leading zeros count packed" %}
13677 size(4);
13678 ins_encode %{
13679 BasicType bt = Matcher::vector_element_basic_type(this);
13680 switch (bt) {
13681 case T_BYTE:
13682 __ vclzb($dst$$VectorRegister, $src$$VectorRegister);
13683 break;
13684 case T_SHORT:
13685 __ vclzh($dst$$VectorRegister, $src$$VectorRegister);
13686 break;
13687 case T_INT:
13688 __ vclzw($dst$$VectorRegister, $src$$VectorRegister);
13689 break;
13690 case T_LONG:
13691 __ vclzd($dst$$VectorRegister, $src$$VectorRegister);
13692 break;
13693 default:
13694 ShouldNotReachHere();
13695 }
13696 %}
13697 ins_pipe(pipe_class_default);
13698 %}
13699
13700 instruct vcount_trailing_zeros_reg(vecX dst, vecX src) %{
13701 match(Set dst (CountTrailingZerosV src));
13702 format %{ "VCTZ $dst,$src\t// trailing zeros count packed" %}
13703 size(4);
13704 ins_encode %{
13705 BasicType bt = Matcher::vector_element_basic_type(this);
13706 switch (bt) {
13707 case T_BYTE:
13708 __ vctzb($dst$$VectorRegister, $src$$VectorRegister);
13709 break;
13710 case T_SHORT:
13711 __ vctzh($dst$$VectorRegister, $src$$VectorRegister);
13712 break;
13713 case T_INT:
13714 __ vctzw($dst$$VectorRegister, $src$$VectorRegister);
13715 break;
13716 case T_LONG:
13717 __ vctzd($dst$$VectorRegister, $src$$VectorRegister);
13718 break;
13719 default:
13720 ShouldNotReachHere();
13721 }
13722 %}
13723 ins_pipe(pipe_class_default);
13724 %}
13725
13726 // --------------------------------- FMA --------------------------------------
13727 // src1 * src2 + dst
13728 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{
13729 match(Set dst (FmaVF dst (Binary src1 src2)));
13730 predicate(n->as_Vector()->length() == 4);
13731
13732 format %{ "XVMADDASP $dst, $src1, $src2" %}
13733
13734 size(4);
13735 ins_encode %{
13736 assert(UseFMA, "Needs FMA instructions support.");
13737 __ xvmaddasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13738 %}
13739 ins_pipe(pipe_class_default);
13740 %}
13741
13742 // src1 * (-src2) + dst
13743 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13744 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{
13745 match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
13746 predicate(n->as_Vector()->length() == 4);
13747
13748 format %{ "XVNMSUBASP $dst, $src1, $src2" %}
13749
13750 size(4);
13751 ins_encode %{
13752 assert(UseFMA, "Needs FMA instructions support.");
13753 __ xvnmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13754 %}
13755 ins_pipe(pipe_class_default);
13756 %}
13757
13758 // src1 * src2 - dst
13759 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{
13760 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2)));
13761 predicate(n->as_Vector()->length() == 4);
13762
13763 format %{ "XVMSUBASP $dst, $src1, $src2" %}
13764
13765 size(4);
13766 ins_encode %{
13767 assert(UseFMA, "Needs FMA instructions support.");
13768 __ xvmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13769 %}
13770 ins_pipe(pipe_class_default);
13771 %}
13772
13773 // src1 * src2 + dst
13774 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{
13775 match(Set dst (FmaVD dst (Binary src1 src2)));
13776 predicate(n->as_Vector()->length() == 2);
13777
13778 format %{ "XVMADDADP $dst, $src1, $src2" %}
13779
13780 size(4);
13781 ins_encode %{
13782 assert(UseFMA, "Needs FMA instructions support.");
13783 __ xvmaddadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13784 %}
13785 ins_pipe(pipe_class_default);
13786 %}
13787
13788 // src1 * (-src2) + dst
13789 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13790 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{
13791 match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
13792 predicate(n->as_Vector()->length() == 2);
13793
13794 format %{ "XVNMSUBADP $dst, $src1, $src2" %}
13795
13796 size(4);
13797 ins_encode %{
13798 assert(UseFMA, "Needs FMA instructions support.");
13799 __ xvnmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13800 %}
13801 ins_pipe(pipe_class_default);
13802 %}
13803
13804 // src1 * src2 - dst
13805 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
13806 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2)));
13807 predicate(n->as_Vector()->length() == 2);
13808
13809 format %{ "XVMSUBADP $dst, $src1, $src2" %}
13810
13811 size(4);
13812 ins_encode %{
13813 assert(UseFMA, "Needs FMA instructions support.");
13814 __ xvmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13815 %}
13816 ins_pipe(pipe_class_default);
13817 %}
13818
13819 //----------Overflow Math Instructions-----------------------------------------
13820
13821 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
13822 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
13823 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
13824
13825 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13826 match(Set cr0 (OverflowAddL op1 op2));
13827
13828 format %{ "ADD_ $op1, $op2\t# overflow check long" %}
13829 size(12);
13830 ins_encode %{
13831 __ li(R0, 0);
13832 __ mtxer(R0); // clear XER.SO
13833 __ addo_(R0, $op1$$Register, $op2$$Register);
13834 %}
13835 ins_pipe(pipe_class_default);
13836 %}
13837
13838 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13839 match(Set cr0 (OverflowSubL op1 op2));
13840
13841 format %{ "SUBFO_ R0, $op2, $op1\t# overflow check long" %}
13842 size(12);
13843 ins_encode %{
13844 __ li(R0, 0);
13845 __ mtxer(R0); // clear XER.SO
13846 __ subfo_(R0, $op2$$Register, $op1$$Register);
13847 %}
13848 ins_pipe(pipe_class_default);
13849 %}
13850
13851 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
13852 match(Set cr0 (OverflowSubL zero op2));
13853
13854 format %{ "NEGO_ R0, $op2\t# overflow check long" %}
13855 size(12);
13856 ins_encode %{
13857 __ li(R0, 0);
13858 __ mtxer(R0); // clear XER.SO
13859 __ nego_(R0, $op2$$Register);
13860 %}
13861 ins_pipe(pipe_class_default);
13862 %}
13863
13864 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13865 match(Set cr0 (OverflowMulL op1 op2));
13866
13867 format %{ "MULLDO_ R0, $op1, $op2\t# overflow check long" %}
13868 size(12);
13869 ins_encode %{
13870 __ li(R0, 0);
13871 __ mtxer(R0); // clear XER.SO
13872 __ mulldo_(R0, $op1$$Register, $op2$$Register);
13873 %}
13874 ins_pipe(pipe_class_default);
13875 %}
13876
13877 instruct repl4F_reg_Ex(vecX dst, regF src) %{
13878 match(Set dst (Replicate src));
13879 predicate(n->as_Vector()->length() == 4 &&
13880 Matcher::vector_element_basic_type(n) == T_FLOAT);
13881 ins_cost(DEFAULT_COST);
13882 expand %{
13883 vecX tmpV;
13884 immI8 zero %{ (int) 0 %}
13885
13886 xscvdpspn_regF(tmpV, src);
13887 xxspltw(dst, tmpV, zero);
13888 %}
13889 %}
13890
13891 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{
13892 match(Set dst (Replicate src));
13893 predicate(n->as_Vector()->length() == 4 &&
13894 Matcher::vector_element_basic_type(n) == T_FLOAT);
13895 effect(TEMP tmp);
13896 ins_cost(10 * DEFAULT_COST);
13897
13898 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) );
13899 %}
13900
13901 instruct repl4F_immF0(vecX dst, immF_0 zero) %{
13902 match(Set dst (Replicate zero));
13903 predicate(n->as_Vector()->length() == 4 &&
13904 Matcher::vector_element_basic_type(n) == T_FLOAT);
13905
13906 format %{ "XXLXOR $dst, $zero \t// replicate4F" %}
13907 size(4);
13908 ins_encode %{
13909 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13910 %}
13911 ins_pipe(pipe_class_default);
13912 %}
13913
13914 instruct repl2D_reg_Ex(vecX dst, regD src) %{
13915 match(Set dst (Replicate src));
13916 predicate(n->as_Vector()->length() == 2 &&
13917 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13918
13919 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %}
13920 size(4);
13921 ins_encode %{
13922 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0);
13923 %}
13924 ins_pipe(pipe_class_default);
13925 %}
13926
13927 instruct repl2D_immD0(vecX dst, immD_0 zero) %{
13928 match(Set dst (Replicate zero));
13929 predicate(n->as_Vector()->length() == 2 &&
13930 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13931
13932 format %{ "XXLXOR $dst, $zero \t// replicate2D" %}
13933 size(4);
13934 ins_encode %{
13935 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13936 %}
13937 ins_pipe(pipe_class_default);
13938 %}
13939
13940 instruct mtvsrd(vecX dst, iRegLsrc src) %{
13941 predicate(false);
13942 effect(DEF dst, USE src);
13943
13944 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %}
13945 size(4);
13946 ins_encode %{
13947 __ mtvsrd($dst$$VectorRegister->to_vsr(), $src$$Register);
13948 %}
13949 ins_pipe(pipe_class_default);
13950 %}
13951
13952 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{
13953 effect(DEF dst, USE src, USE zero);
13954
13955 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %}
13956 size(4);
13957 ins_encode %{
13958 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $zero$$constant);
13959 %}
13960 ins_pipe(pipe_class_default);
13961 %}
13962
13963 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{
13964 effect(DEF dst, USE src1, USE src2, USE zero);
13965
13966 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %}
13967 size(4);
13968 ins_encode %{
13969 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr(), $zero$$constant);
13970 %}
13971 ins_pipe(pipe_class_default);
13972 %}
13973
13974 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{
13975 predicate(Matcher::vector_element_basic_type(n) == T_LONG);
13976 match(Set dst (Replicate src));
13977 predicate(n->as_Vector()->length() == 2);
13978 expand %{
13979 vecX tmpV;
13980 immI8 zero %{ (int) 0 %}
13981 mtvsrd(tmpV, src);
13982 xxpermdi(dst, tmpV, tmpV, zero);
13983 %}
13984 %}
13985
13986 instruct repl2L_immI0(vecX dst, immI_0 zero) %{
13987 match(Set dst (Replicate zero));
13988 predicate(n->as_Vector()->length() == 2 &&
13989 Matcher::vector_element_basic_type(n) == T_LONG);
13990
13991 format %{ "XXLXOR $dst, $zero \t// replicate2L" %}
13992 size(4);
13993 ins_encode %{
13994 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13995 %}
13996 ins_pipe(pipe_class_default);
13997 %}
13998
13999 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{
14000 match(Set dst (Replicate src));
14001 predicate(n->as_Vector()->length() == 2 &&
14002 Matcher::vector_element_basic_type(n) == T_LONG);
14003
14004 format %{ "XXLEQV $dst, $src \t// replicate2L" %}
14005 size(4);
14006 ins_encode %{
14007 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
14008 %}
14009 ins_pipe(pipe_class_default);
14010 %}
14011
14012 // ============================================================================
14013 // Safepoint Instruction
14014
14015 instruct safePoint_poll(iRegPdst poll) %{
14016 match(SafePoint poll);
14017
14018 // It caused problems to add the effect that r0 is killed, but this
14019 // effect no longer needs to be mentioned, since r0 is not contained
14020 // in a reg_class.
14021
14022 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
14023 size(4);
14024 ins_encode( enc_poll(0x0, poll) );
14025 ins_pipe(pipe_class_default);
14026 %}
14027
14028 // ============================================================================
14029 // Call Instructions
14030
14031 // Call Java Static Instruction
14032
14033 source %{
14034
14035 #include "runtime/continuation.hpp"
14036
14037 %}
14038
14039 // Schedulable version of call static node.
14040 instruct CallStaticJavaDirect(method meth) %{
14041 match(CallStaticJava);
14042 effect(USE meth);
14043 ins_cost(CALL_COST);
14044
14045 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
14046
14047 format %{ "CALL,static $meth \t// ==> " %}
14048 size((Continuations::enabled() ? 8 : 4));
14049 ins_encode( enc_java_static_call(meth) );
14050 ins_pipe(pipe_class_call);
14051 %}
14052
14053 // Call Java Dynamic Instruction
14054
14055 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call).
14056 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable
14057 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node.
14058 // The call destination must still be placed in the constant pool.
14059 instruct CallDynamicJavaDirectSched(method meth) %{
14060 match(CallDynamicJava); // To get all the data fields we need ...
14061 effect(USE meth);
14062 predicate(false); // ... but never match.
14063
14064 ins_field_load_ic_hi_node(loadConL_hiNode*);
14065 ins_field_load_ic_node(loadConLNode*);
14066 ins_num_consts(1 /* 1 patchable constant: call destination */);
14067
14068 format %{ "BL \t// dynamic $meth ==> " %}
14069 size((Continuations::enabled() ? 8 : 4));
14070 ins_encode( enc_java_dynamic_call_sched(meth) );
14071 ins_pipe(pipe_class_call);
14072 %}
14073
14074 // Schedulable (i.e. postalloc expanded) version of call dynamic java.
14075 // We use postalloc expanded calls if we use inline caches
14076 // and do not update method data.
14077 //
14078 // This instruction has two constants: inline cache (IC) and call destination.
14079 // Loading the inline cache will be postalloc expanded, thus leaving a call with
14080 // one constant.
14081 instruct CallDynamicJavaDirectSched_Ex(method meth) %{
14082 match(CallDynamicJava);
14083 effect(USE meth);
14084 predicate(UseInlineCaches);
14085 ins_cost(CALL_COST);
14086
14087 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */);
14088
14089 format %{ "CALL,dynamic $meth \t// postalloc expanded" %}
14090 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) );
14091 %}
14092
14093 // Compound version of call dynamic java
14094 // We use postalloc expanded calls if we use inline caches
14095 // and do not update method data.
14096 instruct CallDynamicJavaDirect(method meth) %{
14097 match(CallDynamicJava);
14098 effect(USE meth);
14099 predicate(!UseInlineCaches);
14100 ins_cost(CALL_COST);
14101
14102 // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
14103 ins_num_consts(4);
14104
14105 format %{ "CALL,dynamic $meth \t// ==> " %}
14106 ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
14107 ins_pipe(pipe_class_call);
14108 %}
14109
14110 // Call Runtime Instruction
14111
14112 instruct CallRuntimeDirect(method meth) %{
14113 match(CallRuntime);
14114 effect(USE meth);
14115 ins_cost(CALL_COST);
14116
14117 // Enc_java_to_runtime_call needs up to 3 constants: call target,
14118 // env for callee, C-toc.
14119 ins_num_consts(3);
14120
14121 format %{ "CALL,runtime" %}
14122 ins_encode( enc_java_to_runtime_call(meth) );
14123 ins_pipe(pipe_class_call);
14124 %}
14125
14126 // Call Leaf
14127
14128 // Used by postalloc expand of CallLeafDirect_Ex (mtctr).
14129 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
14130 effect(DEF dst, USE src);
14131
14132 ins_num_consts(1);
14133
14134 format %{ "MTCTR $src" %}
14135 size(4);
14136 ins_encode( enc_leaf_call_mtctr(src) );
14137 ins_pipe(pipe_class_default);
14138 %}
14139
14140 // Used by postalloc expand of CallLeafDirect_Ex (actual call).
14141 instruct CallLeafDirect(method meth) %{
14142 match(CallLeaf); // To get the data all the data fields we need ...
14143 effect(USE meth);
14144 predicate(false); // but never match.
14145
14146 format %{ "BCTRL \t// leaf call $meth ==> " %}
14147 size((Continuations::enabled() ? 8 : 4));
14148 ins_encode %{
14149 __ bctrl();
14150 __ post_call_nop();
14151 %}
14152 ins_pipe(pipe_class_call);
14153 %}
14154
14155 // postalloc expand of CallLeafDirect.
14156 // Load address to call from TOC, then bl to it.
14157 instruct CallLeafDirect_Ex(method meth) %{
14158 match(CallLeaf);
14159 effect(USE meth);
14160 ins_cost(CALL_COST);
14161
14162 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
14163 // env for callee, C-toc.
14164 ins_num_consts(3);
14165
14166 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
14167 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
14168 %}
14169
14170 // Call runtime without safepoint - same as CallLeaf.
14171 // postalloc expand of CallLeafNoFPDirect.
14172 // Load address to call from TOC, then bl to it.
14173 instruct CallLeafNoFPDirect_Ex(method meth) %{
14174 match(CallLeafNoFP);
14175 effect(USE meth);
14176 ins_cost(CALL_COST);
14177
14178 // Enc_java_to_runtime_call needs up to 3 constants: call target,
14179 // env for callee, C-toc.
14180 ins_num_consts(3);
14181
14182 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
14183 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
14184 %}
14185
14186 // Tail Call; Jump from runtime stub to Java code.
14187 // Also known as an 'interprocedural jump'.
14188 // Target of jump will eventually return to caller.
14189 // TailJump below removes the return address.
14190 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{
14191 match(TailCall jump_target method_ptr);
14192 ins_cost(CALL_COST);
14193
14194 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t"
14195 "BCTR \t// tail call" %}
14196 size(8);
14197 ins_encode %{
14198 __ mtctr($jump_target$$Register);
14199 __ bctr();
14200 %}
14201 ins_pipe(pipe_class_call);
14202 %}
14203
14204 // Return Instruction
14205 instruct Ret() %{
14206 match(Return);
14207 format %{ "BLR \t// branch to link register" %}
14208 size(4);
14209 ins_encode %{
14210 // LR is restored in MachEpilogNode. Just do the RET here.
14211 __ blr();
14212 %}
14213 ins_pipe(pipe_class_default);
14214 %}
14215
14216 // Tail Jump; remove the return address; jump to target.
14217 // TailCall above leaves the return address around.
14218 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
14219 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
14220 // "restore" before this instruction (in Epilogue), we need to materialize it
14221 // in %i0.
14222 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
14223 match(TailJump jump_target ex_oop);
14224 ins_cost(CALL_COST);
14225
14226 format %{ "LD R4_ARG2 = LR\n\t"
14227 "MTCTR $jump_target\n\t"
14228 "BCTR \t// TailJump, exception oop: $ex_oop" %}
14229 size(12);
14230 ins_encode %{
14231 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP);
14232 __ mtctr($jump_target$$Register);
14233 __ bctr();
14234 %}
14235 ins_pipe(pipe_class_call);
14236 %}
14237
14238 // Forward exception.
14239 instruct ForwardExceptionjmp()
14240 %{
14241 match(ForwardException);
14242 ins_cost(CALL_COST);
14243
14244 format %{ "JMP forward_exception_stub" %}
14245 ins_encode %{
14246 __ set_inst_mark();
14247 __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
14248 __ clear_inst_mark();
14249 %}
14250 ins_pipe(pipe_class_call);
14251 %}
14252
14253 // Create exception oop: created by stack-crawling runtime code.
14254 // Created exception is now available to this handler, and is setup
14255 // just prior to jumping to this handler. No code emitted.
14256 instruct CreateException(rarg1RegP ex_oop) %{
14257 match(Set ex_oop (CreateEx));
14258 ins_cost(0);
14259
14260 format %{ " -- \t// exception oop; no code emitted" %}
14261 size(0);
14262 ins_encode( /*empty*/ );
14263 ins_pipe(pipe_class_default);
14264 %}
14265
14266 // Rethrow exception: The exception oop will come in the first
14267 // argument position. Then JUMP (not call) to the rethrow stub code.
14268 instruct RethrowException() %{
14269 match(Rethrow);
14270 ins_cost(CALL_COST);
14271
14272 format %{ "JMP rethrow_stub" %}
14273 ins_encode %{
14274 __ set_inst_mark();
14275 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
14276 __ clear_inst_mark();
14277 %}
14278 ins_pipe(pipe_class_call);
14279 %}
14280
14281 // Die now.
14282 instruct ShouldNotReachHere() %{
14283 match(Halt);
14284 ins_cost(CALL_COST);
14285
14286 format %{ "ShouldNotReachHere" %}
14287 ins_encode %{
14288 if (is_reachable()) {
14289 const char* str = __ code_string(_halt_reason);
14290 __ stop(str);
14291 }
14292 %}
14293 ins_pipe(pipe_class_default);
14294 %}
14295
14296 // This name is KNOWN by the ADLC and cannot be changed. The ADLC
14297 // forces a 'TypeRawPtr::BOTTOM' output type for this guy.
14298 // Get a DEF on threadRegP, no costs, no encoding, use
14299 // 'ins_should_rematerialize(true)' to avoid spilling.
14300 instruct tlsLoadP(threadRegP dst) %{
14301 match(Set dst (ThreadLocal));
14302 ins_cost(0);
14303
14304 ins_should_rematerialize(true);
14305
14306 format %{ " -- \t// $dst=Thread::current(), empty" %}
14307 size(0);
14308 ins_encode( /*empty*/ );
14309 ins_pipe(pipe_class_empty);
14310 %}
14311
14312 //---Some PPC specific nodes---------------------------------------------------
14313
14314 // Nop instructions
14315
14316 instruct fxNop() %{
14317 ins_cost(0);
14318
14319 ins_is_nop(true);
14320
14321 format %{ "fxNop" %}
14322 size(4);
14323 ins_encode %{
14324 __ nop();
14325 %}
14326 ins_pipe(pipe_class_default);
14327 %}
14328
14329 instruct fpNop0() %{
14330 ins_cost(0);
14331
14332 ins_is_nop(true);
14333
14334 format %{ "fpNop0" %}
14335 size(4);
14336 ins_encode %{
14337 __ fpnop0();
14338 %}
14339 ins_pipe(pipe_class_default);
14340 %}
14341
14342 instruct fpNop1() %{
14343 ins_cost(0);
14344
14345 ins_is_nop(true);
14346
14347 format %{ "fpNop1" %}
14348 size(4);
14349 ins_encode %{
14350 __ fpnop1();
14351 %}
14352 ins_pipe(pipe_class_default);
14353 %}
14354
14355 instruct brNop0() %{
14356 ins_cost(0);
14357 size(4);
14358 format %{ "brNop0" %}
14359 ins_encode %{
14360 __ brnop0();
14361 %}
14362 ins_is_nop(true);
14363 ins_pipe(pipe_class_default);
14364 %}
14365
14366 instruct brNop1() %{
14367 ins_cost(0);
14368
14369 ins_is_nop(true);
14370
14371 format %{ "brNop1" %}
14372 size(4);
14373 ins_encode %{
14374 __ brnop1();
14375 %}
14376 ins_pipe(pipe_class_default);
14377 %}
14378
14379 instruct brNop2() %{
14380 ins_cost(0);
14381
14382 ins_is_nop(true);
14383
14384 format %{ "brNop2" %}
14385 size(4);
14386 ins_encode %{
14387 __ brnop2();
14388 %}
14389 ins_pipe(pipe_class_default);
14390 %}
14391
14392 instruct cacheWB(indirect addr)
14393 %{
14394 match(CacheWB addr);
14395
14396 ins_cost(100);
14397 format %{ "cache writeback, address = $addr" %}
14398 ins_encode %{
14399 assert($addr->index_position() < 0, "should be");
14400 assert($addr$$disp == 0, "should be");
14401 __ cache_wb(Address($addr$$base$$Register));
14402 %}
14403 ins_pipe(pipe_class_default);
14404 %}
14405
14406 instruct cacheWBPreSync()
14407 %{
14408 match(CacheWBPreSync);
14409
14410 ins_cost(0);
14411 format %{ "cache writeback presync" %}
14412 ins_encode %{
14413 __ cache_wbsync(true);
14414 %}
14415 ins_pipe(pipe_class_default);
14416 %}
14417
14418 instruct cacheWBPostSync()
14419 %{
14420 match(CacheWBPostSync);
14421
14422 ins_cost(100);
14423 format %{ "cache writeback postsync" %}
14424 ins_encode %{
14425 __ cache_wbsync(false);
14426 %}
14427 ins_pipe(pipe_class_default);
14428 %}
14429
14430 //----------PEEPHOLE RULES-----------------------------------------------------
14431 // These must follow all instruction definitions as they use the names
14432 // defined in the instructions definitions.
14433 //
14434 // peepmatch ( root_instr_name [preceeding_instruction]* );
14435 //
14436 // peepconstraint %{
14437 // (instruction_number.operand_name relational_op instruction_number.operand_name
14438 // [, ...] );
14439 // // instruction numbers are zero-based using left to right order in peepmatch
14440 //
14441 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14442 // // provide an instruction_number.operand_name for each operand that appears
14443 // // in the replacement instruction's match rule
14444 //
14445 // ---------VM FLAGS---------------------------------------------------------
14446 //
14447 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14448 //
14449 // Each peephole rule is given an identifying number starting with zero and
14450 // increasing by one in the order seen by the parser. An individual peephole
14451 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14452 // on the command-line.
14453 //
14454 // ---------CURRENT LIMITATIONS----------------------------------------------
14455 //
14456 // Only match adjacent instructions in same basic block
14457 // Only equality constraints
14458 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14459 // Only one replacement instruction
14460 //
14461 // ---------EXAMPLE----------------------------------------------------------
14462 //
14463 // // pertinent parts of existing instructions in architecture description
14464 // instruct movI(eRegI dst, eRegI src) %{
14465 // match(Set dst (CopyI src));
14466 // %}
14467 //
14468 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14469 // match(Set dst (AddI dst src));
14470 // effect(KILL cr);
14471 // %}
14472 //
14473 // // Change (inc mov) to lea
14474 // peephole %{
14475 // // increment preceded by register-register move
14476 // peepmatch ( incI_eReg movI );
14477 // // require that the destination register of the increment
14478 // // match the destination register of the move
14479 // peepconstraint ( 0.dst == 1.dst );
14480 // // construct a replacement instruction that sets
14481 // // the destination to ( move's source register + one )
14482 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14483 // %}
14484 //
14485 // Implementation no longer uses movX instructions since
14486 // machine-independent system no longer uses CopyX nodes.
14487 //
14488 // peephole %{
14489 // peepmatch ( incI_eReg movI );
14490 // peepconstraint ( 0.dst == 1.dst );
14491 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14492 // %}
14493 //
14494 // peephole %{
14495 // peepmatch ( decI_eReg movI );
14496 // peepconstraint ( 0.dst == 1.dst );
14497 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14498 // %}
14499 //
14500 // peephole %{
14501 // peepmatch ( addI_eReg_imm movI );
14502 // peepconstraint ( 0.dst == 1.dst );
14503 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14504 // %}
14505 //
14506 // peephole %{
14507 // peepmatch ( addP_eReg_imm movP );
14508 // peepconstraint ( 0.dst == 1.dst );
14509 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
14510 // %}
14511
14512 // // Change load of spilled value to only a spill
14513 // instruct storeI(memory mem, eRegI src) %{
14514 // match(Set mem (StoreI mem src));
14515 // %}
14516 //
14517 // instruct loadI(eRegI dst, memory mem) %{
14518 // match(Set dst (LoadI mem));
14519 // %}
14520 //
14521 peephole %{
14522 peepmatch ( loadI storeI );
14523 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14524 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14525 %}
14526
14527 peephole %{
14528 peepmatch ( loadL storeL );
14529 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14530 peepreplace ( storeL( 1.mem 1.mem 1.src ) );
14531 %}
14532
14533 peephole %{
14534 peepmatch ( loadP storeP );
14535 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
14536 peepreplace ( storeP( 1.dst 1.dst 1.src ) );
14537 %}
14538
14539 //----------SMARTSPILL RULES---------------------------------------------------
14540 // These must follow all instruction definitions as they use the names
14541 // defined in the instructions definitions.