1 //
2 // Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved.
3 // Copyright (c) 2012, 2026 SAP SE. All rights reserved.
4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 //
6 // This code is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License version 2 only, as
8 // published by the Free Software Foundation.
9 //
10 // This code is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // version 2 for more details (a copy is included in the LICENSE file that
14 // accompanied this code).
15 //
16 // You should have received a copy of the GNU General Public License version
17 // 2 along with this work; if not, write to the Free Software Foundation,
18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 // or visit www.oracle.com if you need additional information or have any
22 // questions.
23 //
24 //
25
26 //
27 // PPC64 Architecture Description File
28 //
29
30 //----------REGISTER DEFINITION BLOCK------------------------------------------
31 // This information is used by the matcher and the register allocator to
32 // describe individual registers and classes of registers within the target
33 // architecture.
34 register %{
35 //----------Architecture Description Register Definitions----------------------
36 // General Registers
37 // "reg_def" name (register save type, C convention save type,
38 // ideal register type, encoding);
39 //
40 // Register Save Types:
41 //
42 // NS = No-Save: The register allocator assumes that these registers
43 // can be used without saving upon entry to the method, &
44 // that they do not need to be saved at call sites.
45 //
46 // SOC = Save-On-Call: The register allocator assumes that these registers
47 // can be used without saving upon entry to the method,
48 // but that they must be saved at call sites.
49 // These are called "volatiles" on ppc.
50 //
51 // SOE = Save-On-Entry: The register allocator assumes that these registers
52 // must be saved before using them upon entry to the
53 // method, but they do not need to be saved at call
54 // sites.
55 // These are called "nonvolatiles" on ppc.
56 //
57 // AS = Always-Save: The register allocator assumes that these registers
58 // must be saved before using them upon entry to the
59 // method, & that they must be saved at call sites.
60 //
61 // Ideal Register Type is used to determine how to save & restore a
62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
64 //
65 // The encoding number is the actual bit-pattern placed into the opcodes.
66 //
67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI
68 // Supplement Version 1.7 as of 2003-10-29.
69 //
70 // For each 64-bit register we must define two registers: the register
71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half',
72 // e.g. R3_H, which is needed by the allocator, but is not used
73 // for stores, loads, etc.
74
75 // ----------------------------
76 // Integer/Long Registers
77 // ----------------------------
78
79 // PPC64 has 32 64-bit integer registers.
80
81 // types: v = volatile, nv = non-volatile, s = system
82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs
83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() );
84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP
85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() );
86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC
87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() );
88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret
89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() );
90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2
91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() );
92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3
93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() );
94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4
95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() );
96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5
97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() );
98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6
99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() );
100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7
101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() );
102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8
103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next());
104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch
105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next());
106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch
107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next());
108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id
109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next());
110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv
111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next());
112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv
113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next());
114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv
115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next());
116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv
117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next());
118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv
119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next());
120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv
121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next());
122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv
123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next());
124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv
125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next());
126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv
127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next());
128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv
129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next());
130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv
131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next());
132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv
133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next());
134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv
135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next());
136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv
137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next());
138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv
139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next());
140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv
141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next());
142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv
143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next());
144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv
145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next());
146
147
148 // ----------------------------
149 // Float/Double Registers
150 // ----------------------------
151
152 // Double Registers
153 // The rules of ADL require that double registers be defined in pairs.
154 // Each pair must be two 32-bit values, but not necessarily a pair of
155 // single float registers. In each pair, ADLC-assigned register numbers
156 // must be adjacent, with the lower number even. Finally, when the
157 // CPU stores such a register pair to memory, the word associated with
158 // the lower ADLC-assigned number must be stored to the lower address.
159
160 // PPC64 has 32 64-bit floating-point registers. Each can store a single
161 // or double precision floating-point value.
162
163 // types: v = volatile, nv = non-volatile, s = system
164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch
165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() );
166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret
167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() );
168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2
169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() );
170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3
171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() );
172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4
173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() );
174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5
175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() );
176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6
177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() );
178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7
179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() );
180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8
181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() );
182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9
183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() );
184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10
185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next());
186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11
187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next());
188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12
189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next());
190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13
191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next());
192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv
193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next());
194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv
195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next());
196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv
197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next());
198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv
199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next());
200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv
201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next());
202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv
203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next());
204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv
205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next());
206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv
207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next());
208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv
209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next());
210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv
211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next());
212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv
213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next());
214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv
215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next());
216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv
217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next());
218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv
219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next());
220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv
221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next());
222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv
223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next());
224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv
225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next());
226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv
227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next());
228
229 // ----------------------------
230 // Special Registers
231 // ----------------------------
232
233 // Condition Codes Flag Registers
234
235 // PPC64 has 8 condition code "registers" which are all contained
236 // in the CR register.
237
238 // types: v = volatile, nv = non-volatile, s = system
239 reg_def CR0(SOC, SOC, Op_RegFlags, 0, CR0->as_VMReg()); // v
240 reg_def CR1(SOC, SOC, Op_RegFlags, 1, CR1->as_VMReg()); // v
241 reg_def CR2(SOC, SOC, Op_RegFlags, 2, CR2->as_VMReg()); // nv
242 reg_def CR3(SOC, SOC, Op_RegFlags, 3, CR3->as_VMReg()); // nv
243 reg_def CR4(SOC, SOC, Op_RegFlags, 4, CR4->as_VMReg()); // nv
244 reg_def CR5(SOC, SOC, Op_RegFlags, 5, CR5->as_VMReg()); // v
245 reg_def CR6(SOC, SOC, Op_RegFlags, 6, CR6->as_VMReg()); // v
246 reg_def CR7(SOC, SOC, Op_RegFlags, 7, CR7->as_VMReg()); // v
247
248 // Special registers of PPC64
249
250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v
251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v
252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v
253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v
254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v
255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v
256
257 // ----------------------------
258 // Vector Registers
259 // ----------------------------
260
261 reg_def VR0 (SOC, SOC, Op_RegF, 0, VR0->as_VMReg() );
262 reg_def VR0_H(SOC, SOC, Op_RegF, 0, VR0->as_VMReg()->next() );
263 reg_def VR0_J(SOC, SOC, Op_RegF, 0, VR0->as_VMReg()->next(2));
264 reg_def VR0_K(SOC, SOC, Op_RegF, 0, VR0->as_VMReg()->next(3));
265
266 reg_def VR1 (SOC, SOC, Op_RegF, 1, VR1->as_VMReg() );
267 reg_def VR1_H(SOC, SOC, Op_RegF, 1, VR1->as_VMReg()->next() );
268 reg_def VR1_J(SOC, SOC, Op_RegF, 1, VR1->as_VMReg()->next(2));
269 reg_def VR1_K(SOC, SOC, Op_RegF, 1, VR1->as_VMReg()->next(3));
270
271 reg_def VR2 (SOC, SOC, Op_RegF, 2, VR2->as_VMReg() );
272 reg_def VR2_H(SOC, SOC, Op_RegF, 2, VR2->as_VMReg()->next() );
273 reg_def VR2_J(SOC, SOC, Op_RegF, 2, VR2->as_VMReg()->next(2));
274 reg_def VR2_K(SOC, SOC, Op_RegF, 2, VR2->as_VMReg()->next(3));
275
276 reg_def VR3 (SOC, SOC, Op_RegF, 3, VR3->as_VMReg() );
277 reg_def VR3_H(SOC, SOC, Op_RegF, 3, VR3->as_VMReg()->next() );
278 reg_def VR3_J(SOC, SOC, Op_RegF, 3, VR3->as_VMReg()->next(2));
279 reg_def VR3_K(SOC, SOC, Op_RegF, 3, VR3->as_VMReg()->next(3));
280
281 reg_def VR4 (SOC, SOC, Op_RegF, 4, VR4->as_VMReg() );
282 reg_def VR4_H(SOC, SOC, Op_RegF, 4, VR4->as_VMReg()->next() );
283 reg_def VR4_J(SOC, SOC, Op_RegF, 4, VR4->as_VMReg()->next(2));
284 reg_def VR4_K(SOC, SOC, Op_RegF, 4, VR4->as_VMReg()->next(3));
285
286 reg_def VR5 (SOC, SOC, Op_RegF, 5, VR5->as_VMReg() );
287 reg_def VR5_H(SOC, SOC, Op_RegF, 5, VR5->as_VMReg()->next() );
288 reg_def VR5_J(SOC, SOC, Op_RegF, 5, VR5->as_VMReg()->next(2));
289 reg_def VR5_K(SOC, SOC, Op_RegF, 5, VR5->as_VMReg()->next(3));
290
291 reg_def VR6 (SOC, SOC, Op_RegF, 6, VR6->as_VMReg() );
292 reg_def VR6_H(SOC, SOC, Op_RegF, 6, VR6->as_VMReg()->next() );
293 reg_def VR6_J(SOC, SOC, Op_RegF, 6, VR6->as_VMReg()->next(2));
294 reg_def VR6_K(SOC, SOC, Op_RegF, 6, VR6->as_VMReg()->next(3));
295
296 reg_def VR7 (SOC, SOC, Op_RegF, 7, VR7->as_VMReg() );
297 reg_def VR7_H(SOC, SOC, Op_RegF, 7, VR7->as_VMReg()->next() );
298 reg_def VR7_J(SOC, SOC, Op_RegF, 7, VR7->as_VMReg()->next(2));
299 reg_def VR7_K(SOC, SOC, Op_RegF, 7, VR7->as_VMReg()->next(3));
300
301 reg_def VR8 (SOC, SOC, Op_RegF, 8, VR8->as_VMReg() );
302 reg_def VR8_H(SOC, SOC, Op_RegF, 8, VR8->as_VMReg()->next() );
303 reg_def VR8_J(SOC, SOC, Op_RegF, 8, VR8->as_VMReg()->next(2));
304 reg_def VR8_K(SOC, SOC, Op_RegF, 8, VR8->as_VMReg()->next(3));
305
306 reg_def VR9 (SOC, SOC, Op_RegF, 9, VR9->as_VMReg() );
307 reg_def VR9_H(SOC, SOC, Op_RegF, 9, VR9->as_VMReg()->next() );
308 reg_def VR9_J(SOC, SOC, Op_RegF, 9, VR9->as_VMReg()->next(2));
309 reg_def VR9_K(SOC, SOC, Op_RegF, 9, VR9->as_VMReg()->next(3));
310
311 reg_def VR10 (SOC, SOC, Op_RegF, 10, VR10->as_VMReg() );
312 reg_def VR10_H(SOC, SOC, Op_RegF, 10, VR10->as_VMReg()->next() );
313 reg_def VR10_J(SOC, SOC, Op_RegF, 10, VR10->as_VMReg()->next(2));
314 reg_def VR10_K(SOC, SOC, Op_RegF, 10, VR10->as_VMReg()->next(3));
315
316 reg_def VR11 (SOC, SOC, Op_RegF, 11, VR11->as_VMReg() );
317 reg_def VR11_H(SOC, SOC, Op_RegF, 11, VR11->as_VMReg()->next() );
318 reg_def VR11_J(SOC, SOC, Op_RegF, 11, VR11->as_VMReg()->next(2));
319 reg_def VR11_K(SOC, SOC, Op_RegF, 11, VR11->as_VMReg()->next(3));
320
321 reg_def VR12 (SOC, SOC, Op_RegF, 12, VR12->as_VMReg() );
322 reg_def VR12_H(SOC, SOC, Op_RegF, 12, VR12->as_VMReg()->next() );
323 reg_def VR12_J(SOC, SOC, Op_RegF, 12, VR12->as_VMReg()->next(2));
324 reg_def VR12_K(SOC, SOC, Op_RegF, 12, VR12->as_VMReg()->next(3));
325
326 reg_def VR13 (SOC, SOC, Op_RegF, 13, VR13->as_VMReg() );
327 reg_def VR13_H(SOC, SOC, Op_RegF, 13, VR13->as_VMReg()->next() );
328 reg_def VR13_J(SOC, SOC, Op_RegF, 13, VR13->as_VMReg()->next(2));
329 reg_def VR13_K(SOC, SOC, Op_RegF, 13, VR13->as_VMReg()->next(3));
330
331 reg_def VR14 (SOC, SOC, Op_RegF, 14, VR14->as_VMReg() );
332 reg_def VR14_H(SOC, SOC, Op_RegF, 14, VR14->as_VMReg()->next() );
333 reg_def VR14_J(SOC, SOC, Op_RegF, 14, VR14->as_VMReg()->next(2));
334 reg_def VR14_K(SOC, SOC, Op_RegF, 14, VR14->as_VMReg()->next(3));
335
336 reg_def VR15 (SOC, SOC, Op_RegF, 15, VR15->as_VMReg() );
337 reg_def VR15_H(SOC, SOC, Op_RegF, 15, VR15->as_VMReg()->next() );
338 reg_def VR15_J(SOC, SOC, Op_RegF, 15, VR15->as_VMReg()->next(2));
339 reg_def VR15_K(SOC, SOC, Op_RegF, 15, VR15->as_VMReg()->next(3));
340
341 reg_def VR16 (SOC, SOC, Op_RegF, 16, VR16->as_VMReg() );
342 reg_def VR16_H(SOC, SOC, Op_RegF, 16, VR16->as_VMReg()->next() );
343 reg_def VR16_J(SOC, SOC, Op_RegF, 16, VR16->as_VMReg()->next(2));
344 reg_def VR16_K(SOC, SOC, Op_RegF, 16, VR16->as_VMReg()->next(3));
345
346 reg_def VR17 (SOC, SOC, Op_RegF, 17, VR17->as_VMReg() );
347 reg_def VR17_H(SOC, SOC, Op_RegF, 17, VR17->as_VMReg()->next() );
348 reg_def VR17_J(SOC, SOC, Op_RegF, 17, VR17->as_VMReg()->next(2));
349 reg_def VR17_K(SOC, SOC, Op_RegF, 17, VR17->as_VMReg()->next(3));
350
351 reg_def VR18 (SOC, SOC, Op_RegF, 18, VR18->as_VMReg() );
352 reg_def VR18_H(SOC, SOC, Op_RegF, 18, VR18->as_VMReg()->next() );
353 reg_def VR18_J(SOC, SOC, Op_RegF, 18, VR18->as_VMReg()->next(2));
354 reg_def VR18_K(SOC, SOC, Op_RegF, 18, VR18->as_VMReg()->next(3));
355
356 reg_def VR19 (SOC, SOC, Op_RegF, 19, VR19->as_VMReg() );
357 reg_def VR19_H(SOC, SOC, Op_RegF, 19, VR19->as_VMReg()->next() );
358 reg_def VR19_J(SOC, SOC, Op_RegF, 19, VR19->as_VMReg()->next(2));
359 reg_def VR19_K(SOC, SOC, Op_RegF, 19, VR19->as_VMReg()->next(3));
360
361 reg_def VR20 (SOC, SOE, Op_RegF, 20, VR20->as_VMReg() );
362 reg_def VR20_H(SOC, SOE, Op_RegF, 20, VR20->as_VMReg()->next() );
363 reg_def VR20_J(SOC, SOE, Op_RegF, 20, VR20->as_VMReg()->next(2));
364 reg_def VR20_K(SOC, SOE, Op_RegF, 20, VR20->as_VMReg()->next(3));
365
366 reg_def VR21 (SOC, SOE, Op_RegF, 21, VR21->as_VMReg() );
367 reg_def VR21_H(SOC, SOE, Op_RegF, 21, VR21->as_VMReg()->next() );
368 reg_def VR21_J(SOC, SOE, Op_RegF, 21, VR21->as_VMReg()->next(2));
369 reg_def VR21_K(SOC, SOE, Op_RegF, 21, VR21->as_VMReg()->next(3));
370
371 reg_def VR22 (SOC, SOE, Op_RegF, 22, VR22->as_VMReg() );
372 reg_def VR22_H(SOC, SOE, Op_RegF, 22, VR22->as_VMReg()->next() );
373 reg_def VR22_J(SOC, SOE, Op_RegF, 22, VR22->as_VMReg()->next(2));
374 reg_def VR22_K(SOC, SOE, Op_RegF, 22, VR22->as_VMReg()->next(3));
375
376 reg_def VR23 (SOC, SOE, Op_RegF, 23, VR23->as_VMReg() );
377 reg_def VR23_H(SOC, SOE, Op_RegF, 23, VR23->as_VMReg()->next() );
378 reg_def VR23_J(SOC, SOE, Op_RegF, 23, VR23->as_VMReg()->next(2));
379 reg_def VR23_K(SOC, SOE, Op_RegF, 23, VR23->as_VMReg()->next(3));
380
381 reg_def VR24 (SOC, SOE, Op_RegF, 24, VR24->as_VMReg() );
382 reg_def VR24_H(SOC, SOE, Op_RegF, 24, VR24->as_VMReg()->next() );
383 reg_def VR24_J(SOC, SOE, Op_RegF, 24, VR24->as_VMReg()->next(2));
384 reg_def VR24_K(SOC, SOE, Op_RegF, 24, VR24->as_VMReg()->next(3));
385
386 reg_def VR25 (SOC, SOE, Op_RegF, 25, VR25->as_VMReg() );
387 reg_def VR25_H(SOC, SOE, Op_RegF, 25, VR25->as_VMReg()->next() );
388 reg_def VR25_J(SOC, SOE, Op_RegF, 25, VR25->as_VMReg()->next(2));
389 reg_def VR25_K(SOC, SOE, Op_RegF, 25, VR25->as_VMReg()->next(3));
390
391 reg_def VR26 (SOC, SOE, Op_RegF, 26, VR26->as_VMReg() );
392 reg_def VR26_H(SOC, SOE, Op_RegF, 26, VR26->as_VMReg()->next() );
393 reg_def VR26_J(SOC, SOE, Op_RegF, 26, VR26->as_VMReg()->next(2));
394 reg_def VR26_K(SOC, SOE, Op_RegF, 26, VR26->as_VMReg()->next(3));
395
396 reg_def VR27 (SOC, SOE, Op_RegF, 27, VR27->as_VMReg() );
397 reg_def VR27_H(SOC, SOE, Op_RegF, 27, VR27->as_VMReg()->next() );
398 reg_def VR27_J(SOC, SOE, Op_RegF, 27, VR27->as_VMReg()->next(2));
399 reg_def VR27_K(SOC, SOE, Op_RegF, 27, VR27->as_VMReg()->next(3));
400
401 reg_def VR28 (SOC, SOE, Op_RegF, 28, VR28->as_VMReg() );
402 reg_def VR28_H(SOC, SOE, Op_RegF, 28, VR28->as_VMReg()->next() );
403 reg_def VR28_J(SOC, SOE, Op_RegF, 28, VR28->as_VMReg()->next(2));
404 reg_def VR28_K(SOC, SOE, Op_RegF, 28, VR28->as_VMReg()->next(3));
405
406 reg_def VR29 (SOC, SOE, Op_RegF, 29, VR29->as_VMReg() );
407 reg_def VR29_H(SOC, SOE, Op_RegF, 29, VR29->as_VMReg()->next() );
408 reg_def VR29_J(SOC, SOE, Op_RegF, 29, VR29->as_VMReg()->next(2));
409 reg_def VR29_K(SOC, SOE, Op_RegF, 29, VR29->as_VMReg()->next(3));
410
411 reg_def VR30 (SOC, SOE, Op_RegF, 30, VR30->as_VMReg() );
412 reg_def VR30_H(SOC, SOE, Op_RegF, 30, VR30->as_VMReg()->next() );
413 reg_def VR30_J(SOC, SOE, Op_RegF, 30, VR30->as_VMReg()->next(2));
414 reg_def VR30_K(SOC, SOE, Op_RegF, 30, VR30->as_VMReg()->next(3));
415
416 reg_def VR31 (SOC, SOE, Op_RegF, 31, VR31->as_VMReg() );
417 reg_def VR31_H(SOC, SOE, Op_RegF, 31, VR31->as_VMReg()->next() );
418 reg_def VR31_J(SOC, SOE, Op_RegF, 31, VR31->as_VMReg()->next(2));
419 reg_def VR31_K(SOC, SOE, Op_RegF, 31, VR31->as_VMReg()->next(3));
420
421 // ----------------------------
422 // Specify priority of register selection within phases of register
423 // allocation. Highest priority is first. A useful heuristic is to
424 // give registers a low priority when they are required by machine
425 // instructions, like EAX and EDX on I486, and choose no-save registers
426 // before save-on-call, & save-on-call before save-on-entry. Registers
427 // which participate in fixed calling sequences should come last.
428 // Registers which are used as pairs must fall on an even boundary.
429
430 // It's worth about 1% on SPEC geomean to get this right.
431
432 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration
433 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g.
434 // R3_num. Therefore, R3_num may not be (and in reality is not)
435 // the same as R3->encoding()! Furthermore, we cannot make any
436 // assumptions on ordering, e.g. R3_num may be less than R2_num.
437 // Additionally, the function
438 // static enum RC rc_class(OptoReg::Name reg )
439 // maps a given <register>_num value to its chunk type (except for flags)
440 // and its current implementation relies on chunk0 and chunk1 having a
441 // size of 64 each.
442
443 // If you change this allocation class, please have a look at the
444 // default values for the parameters RoundRobinIntegerRegIntervalStart
445 // and RoundRobinFloatRegIntervalStart
446
447 alloc_class chunk0 (
448 // Chunk0 contains *all* 64 integer registers halves.
449
450 // "non-volatile" registers
451 R14, R14_H,
452 R15, R15_H,
453 R17, R17_H,
454 R18, R18_H,
455 R19, R19_H,
456 R20, R20_H,
457 R21, R21_H,
458 R22, R22_H,
459 R23, R23_H,
460 R24, R24_H,
461 R25, R25_H,
462 R26, R26_H,
463 R27, R27_H,
464 R28, R28_H,
465 R29, R29_H,
466 R30, R30_H,
467 R31, R31_H,
468
469 // scratch/special registers
470 R11, R11_H,
471 R12, R12_H,
472
473 // argument registers
474 R10, R10_H,
475 R9, R9_H,
476 R8, R8_H,
477 R7, R7_H,
478 R6, R6_H,
479 R5, R5_H,
480 R4, R4_H,
481 R3, R3_H,
482
483 // special registers, not available for allocation
484 R16, R16_H, // R16_thread
485 R13, R13_H, // system thread id
486 R2, R2_H, // may be used for TOC
487 R1, R1_H, // SP
488 R0, R0_H // R0 (scratch)
489 );
490
491 // If you change this allocation class, please have a look at the
492 // default values for the parameters RoundRobinIntegerRegIntervalStart
493 // and RoundRobinFloatRegIntervalStart
494
495 alloc_class chunk1 (
496 // Chunk1 contains *all* 64 floating-point registers halves.
497
498 // scratch register
499 F0, F0_H,
500
501 // argument registers
502 F13, F13_H,
503 F12, F12_H,
504 F11, F11_H,
505 F10, F10_H,
506 F9, F9_H,
507 F8, F8_H,
508 F7, F7_H,
509 F6, F6_H,
510 F5, F5_H,
511 F4, F4_H,
512 F3, F3_H,
513 F2, F2_H,
514 F1, F1_H,
515
516 // non-volatile registers
517 F14, F14_H,
518 F15, F15_H,
519 F16, F16_H,
520 F17, F17_H,
521 F18, F18_H,
522 F19, F19_H,
523 F20, F20_H,
524 F21, F21_H,
525 F22, F22_H,
526 F23, F23_H,
527 F24, F24_H,
528 F25, F25_H,
529 F26, F26_H,
530 F27, F27_H,
531 F28, F28_H,
532 F29, F29_H,
533 F30, F30_H,
534 F31, F31_H
535 );
536
537 alloc_class chunk2 (
538 VR0 , VR0_H , VR0_J , VR0_K ,
539 VR1 , VR1_H , VR1_J , VR1_K ,
540 VR2 , VR2_H , VR2_J , VR2_K ,
541 VR3 , VR3_H , VR3_J , VR3_K ,
542 VR4 , VR4_H , VR4_J , VR4_K ,
543 VR5 , VR5_H , VR5_J , VR5_K ,
544 VR6 , VR6_H , VR6_J , VR6_K ,
545 VR7 , VR7_H , VR7_J , VR7_K ,
546 VR8 , VR8_H , VR8_J , VR8_K ,
547 VR9 , VR9_H , VR9_J , VR9_K ,
548 VR10, VR10_H, VR10_J, VR10_K,
549 VR11, VR11_H, VR11_J, VR11_K,
550 VR12, VR12_H, VR12_J, VR12_K,
551 VR13, VR13_H, VR13_J, VR13_K,
552 VR14, VR14_H, VR14_J, VR14_K,
553 VR15, VR15_H, VR15_J, VR15_K,
554 VR16, VR16_H, VR16_J, VR16_K,
555 VR17, VR17_H, VR17_J, VR17_K,
556 VR18, VR18_H, VR18_J, VR18_K,
557 VR19, VR19_H, VR19_J, VR19_K,
558 VR20, VR20_H, VR20_J, VR20_K,
559 VR21, VR21_H, VR21_J, VR21_K,
560 VR22, VR22_H, VR22_J, VR22_K,
561 VR23, VR23_H, VR23_J, VR23_K,
562 VR24, VR24_H, VR24_J, VR24_K,
563 VR25, VR25_H, VR25_J, VR25_K,
564 VR26, VR26_H, VR26_J, VR26_K,
565 VR27, VR27_H, VR27_J, VR27_K,
566 VR28, VR28_H, VR28_J, VR28_K,
567 VR29, VR29_H, VR29_J, VR29_K,
568 VR30, VR30_H, VR30_J, VR30_K,
569 VR31, VR31_H, VR31_J, VR31_K
570 );
571
572 alloc_class chunk3 (
573 // Chunk2 contains *all* 8 condition code registers.
574 CR0,
575 CR1,
576 CR2,
577 CR3,
578 CR4,
579 CR5,
580 CR6,
581 CR7
582 );
583
584 alloc_class chunk4 (
585 // special registers
586 // These registers are not allocated, but used for nodes generated by postalloc expand.
587 SR_XER,
588 SR_LR,
589 SR_CTR,
590 SR_VRSAVE,
591 SR_SPEFSCR,
592 SR_PPR
593 );
594
595 //-------Architecture Description Register Classes-----------------------
596
597 // Several register classes are automatically defined based upon
598 // information in this architecture description.
599
600 // 1) reg_class inline_cache_reg ( as defined in frame section )
601 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
602 //
603
604 // ----------------------------
605 // 32 Bit Register Classes
606 // ----------------------------
607
608 // We specify registers twice, once as read/write, and once read-only.
609 // We use the read-only registers for source operands. With this, we
610 // can include preset read only registers in this class, as a hard-coded
611 // '0'-register. (We used to simulate this on ppc.)
612
613 // 32 bit registers that can be read and written i.e. these registers
614 // can be dest (or src) of normal instructions.
615 reg_class bits32_reg_rw(
616 /*R0*/ // R0
617 /*R1*/ // SP
618 R2, // TOC
619 R3,
620 R4,
621 R5,
622 R6,
623 R7,
624 R8,
625 R9,
626 R10,
627 R11,
628 R12,
629 /*R13*/ // system thread id
630 R14,
631 R15,
632 /*R16*/ // R16_thread
633 R17,
634 R18,
635 R19,
636 R20,
637 R21,
638 R22,
639 R23,
640 R24,
641 R25,
642 R26,
643 R27,
644 R28,
645 /*R29,*/ // global TOC
646 R30,
647 R31
648 );
649
650 // 32 bit registers that can only be read i.e. these registers can
651 // only be src of all instructions.
652 reg_class bits32_reg_ro(
653 /*R0*/ // R0
654 /*R1*/ // SP
655 R2 // TOC
656 R3,
657 R4,
658 R5,
659 R6,
660 R7,
661 R8,
662 R9,
663 R10,
664 R11,
665 R12,
666 /*R13*/ // system thread id
667 R14,
668 R15,
669 /*R16*/ // R16_thread
670 R17,
671 R18,
672 R19,
673 R20,
674 R21,
675 R22,
676 R23,
677 R24,
678 R25,
679 R26,
680 R27,
681 R28,
682 /*R29,*/
683 R30,
684 R31
685 );
686
687 reg_class rscratch1_bits32_reg(R11);
688 reg_class rscratch2_bits32_reg(R12);
689 reg_class rarg1_bits32_reg(R3);
690 reg_class rarg2_bits32_reg(R4);
691 reg_class rarg3_bits32_reg(R5);
692 reg_class rarg4_bits32_reg(R6);
693
694 // ----------------------------
695 // 64 Bit Register Classes
696 // ----------------------------
697 // 64-bit build means 64-bit pointers means hi/lo pairs
698
699 reg_class rscratch1_bits64_reg(R11_H, R11);
700 reg_class rscratch2_bits64_reg(R12_H, R12);
701 reg_class rarg1_bits64_reg(R3_H, R3);
702 reg_class rarg2_bits64_reg(R4_H, R4);
703 reg_class rarg3_bits64_reg(R5_H, R5);
704 reg_class rarg4_bits64_reg(R6_H, R6);
705 reg_class rarg5_bits64_reg(R7_H, R7);
706 reg_class rarg6_bits64_reg(R8_H, R8);
707 // Thread register, 'written' by tlsLoadP, see there.
708 reg_class thread_bits64_reg(R16_H, R16);
709
710 reg_class r19_bits64_reg(R19_H, R19);
711
712 // 64 bit registers that can be read and written i.e. these registers
713 // can be dest (or src) of normal instructions.
714 reg_class bits64_reg_rw(
715 /*R0_H, R0*/ // R0
716 /*R1_H, R1*/ // SP
717 R2_H, R2, // TOC
718 R3_H, R3,
719 R4_H, R4,
720 R5_H, R5,
721 R6_H, R6,
722 R7_H, R7,
723 R8_H, R8,
724 R9_H, R9,
725 R10_H, R10,
726 R11_H, R11,
727 R12_H, R12,
728 /*R13_H, R13*/ // system thread id
729 R14_H, R14,
730 R15_H, R15,
731 /*R16_H, R16*/ // R16_thread
732 R17_H, R17,
733 R18_H, R18,
734 R19_H, R19,
735 R20_H, R20,
736 R21_H, R21,
737 R22_H, R22,
738 R23_H, R23,
739 R24_H, R24,
740 R25_H, R25,
741 R26_H, R26,
742 R27_H, R27,
743 R28_H, R28,
744 /*R29_H, R29,*/
745 R30_H, R30,
746 R31_H, R31
747 );
748
749 // 64 bit registers used excluding r2, r11 and r12
750 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses
751 // r2, r11 and r12 internally.
752 reg_class bits64_reg_leaf_call(
753 /*R0_H, R0*/ // R0
754 /*R1_H, R1*/ // SP
755 /*R2_H, R2*/ // TOC
756 R3_H, R3,
757 R4_H, R4,
758 R5_H, R5,
759 R6_H, R6,
760 R7_H, R7,
761 R8_H, R8,
762 R9_H, R9,
763 R10_H, R10,
764 /*R11_H, R11*/
765 /*R12_H, R12*/
766 /*R13_H, R13*/ // system thread id
767 R14_H, R14,
768 R15_H, R15,
769 /*R16_H, R16*/ // R16_thread
770 R17_H, R17,
771 R18_H, R18,
772 R19_H, R19,
773 R20_H, R20,
774 R21_H, R21,
775 R22_H, R22,
776 R23_H, R23,
777 R24_H, R24,
778 R25_H, R25,
779 R26_H, R26,
780 R27_H, R27,
781 R28_H, R28,
782 /*R29_H, R29,*/
783 R30_H, R30,
784 R31_H, R31
785 );
786
787 // Used to hold the TOC to avoid collisions with expanded DynamicCall
788 // which uses r19 as inline cache internally and expanded LeafCall which uses
789 // r2, r11 and r12 internally.
790 reg_class bits64_constant_table_base(
791 /*R0_H, R0*/ // R0
792 /*R1_H, R1*/ // SP
793 /*R2_H, R2*/ // TOC
794 R3_H, R3,
795 R4_H, R4,
796 R5_H, R5,
797 R6_H, R6,
798 R7_H, R7,
799 R8_H, R8,
800 R9_H, R9,
801 R10_H, R10,
802 /*R11_H, R11*/
803 /*R12_H, R12*/
804 /*R13_H, R13*/ // system thread id
805 R14_H, R14,
806 R15_H, R15,
807 /*R16_H, R16*/ // R16_thread
808 R17_H, R17,
809 R18_H, R18,
810 /*R19_H, R19*/
811 R20_H, R20,
812 R21_H, R21,
813 R22_H, R22,
814 R23_H, R23,
815 R24_H, R24,
816 R25_H, R25,
817 R26_H, R26,
818 R27_H, R27,
819 R28_H, R28,
820 /*R29_H, R29,*/
821 R30_H, R30,
822 R31_H, R31
823 );
824
825 // 64 bit registers that can only be read i.e. these registers can
826 // only be src of all instructions.
827 reg_class bits64_reg_ro(
828 /*R0_H, R0*/ // R0
829 R1_H, R1,
830 R2_H, R2, // TOC
831 R3_H, R3,
832 R4_H, R4,
833 R5_H, R5,
834 R6_H, R6,
835 R7_H, R7,
836 R8_H, R8,
837 R9_H, R9,
838 R10_H, R10,
839 R11_H, R11,
840 R12_H, R12,
841 /*R13_H, R13*/ // system thread id
842 R14_H, R14,
843 R15_H, R15,
844 R16_H, R16, // R16_thread
845 R17_H, R17,
846 R18_H, R18,
847 R19_H, R19,
848 R20_H, R20,
849 R21_H, R21,
850 R22_H, R22,
851 R23_H, R23,
852 R24_H, R24,
853 R25_H, R25,
854 R26_H, R26,
855 R27_H, R27,
856 R28_H, R28,
857 /*R29_H, R29,*/ // TODO: let allocator handle TOC!!
858 R30_H, R30,
859 R31_H, R31
860 );
861
862
863 // ----------------------------
864 // Special Class for Condition Code Flags Register
865
866 reg_class int_flags(
867 /*CR0*/ // scratch
868 /*CR1*/ // scratch
869 /*CR2*/ // nv!
870 /*CR3*/ // nv!
871 /*CR4*/ // nv!
872 CR5,
873 CR6,
874 CR7
875 );
876
877 reg_class int_flags_ro(
878 CR0,
879 CR1,
880 CR2,
881 CR3,
882 CR4,
883 CR5,
884 CR6,
885 CR7
886 );
887
888 reg_class int_flags_CR0(CR0);
889 reg_class int_flags_CR1(CR1);
890 reg_class int_flags_CR6(CR6);
891 reg_class ctr_reg(SR_CTR);
892
893 // ----------------------------
894 // Float Register Classes
895 // ----------------------------
896
897 reg_class flt_reg(
898 F0,
899 F1,
900 F2,
901 F3,
902 F4,
903 F5,
904 F6,
905 F7,
906 F8,
907 F9,
908 F10,
909 F11,
910 F12,
911 F13,
912 F14, // nv!
913 F15, // nv!
914 F16, // nv!
915 F17, // nv!
916 F18, // nv!
917 F19, // nv!
918 F20, // nv!
919 F21, // nv!
920 F22, // nv!
921 F23, // nv!
922 F24, // nv!
923 F25, // nv!
924 F26, // nv!
925 F27, // nv!
926 F28, // nv!
927 F29, // nv!
928 F30, // nv!
929 F31 // nv!
930 );
931
932 // Double precision float registers have virtual `high halves' that
933 // are needed by the allocator.
934 reg_class dbl_reg(
935 F0, F0_H,
936 F1, F1_H,
937 F2, F2_H,
938 F3, F3_H,
939 F4, F4_H,
940 F5, F5_H,
941 F6, F6_H,
942 F7, F7_H,
943 F8, F8_H,
944 F9, F9_H,
945 F10, F10_H,
946 F11, F11_H,
947 F12, F12_H,
948 F13, F13_H,
949 F14, F14_H, // nv!
950 F15, F15_H, // nv!
951 F16, F16_H, // nv!
952 F17, F17_H, // nv!
953 F18, F18_H, // nv!
954 F19, F19_H, // nv!
955 F20, F20_H, // nv!
956 F21, F21_H, // nv!
957 F22, F22_H, // nv!
958 F23, F23_H, // nv!
959 F24, F24_H, // nv!
960 F25, F25_H, // nv!
961 F26, F26_H, // nv!
962 F27, F27_H, // nv!
963 F28, F28_H, // nv!
964 F29, F29_H, // nv!
965 F30, F30_H, // nv!
966 F31, F31_H // nv!
967 );
968
969 // ----------------------------
970 // Vector-Scalar Register Class
971 // ----------------------------
972
973 reg_class v_reg(
974 VR0 , VR0_H , VR0_J , VR0_K ,
975 VR1 , VR1_H , VR1_J , VR1_K ,
976 VR2 , VR2_H , VR2_J , VR2_K ,
977 VR3 , VR3_H , VR3_J , VR3_K ,
978 VR4 , VR4_H , VR4_J , VR4_K ,
979 VR5 , VR5_H , VR5_J , VR5_K ,
980 VR6 , VR6_H , VR6_J , VR6_K ,
981 VR7 , VR7_H , VR7_J , VR7_K ,
982 VR8 , VR8_H , VR8_J , VR8_K ,
983 VR9 , VR9_H , VR9_J , VR9_K ,
984 VR10, VR10_H, VR10_J, VR10_K,
985 VR11, VR11_H, VR11_J, VR11_K,
986 VR12, VR12_H, VR12_J, VR12_K,
987 VR13, VR13_H, VR13_J, VR13_K,
988 VR14, VR14_H, VR14_J, VR14_K,
989 VR15, VR15_H, VR15_J, VR15_K,
990 VR16, VR16_H, VR16_J, VR16_K,
991 VR17, VR17_H, VR17_J, VR17_K,
992 VR18, VR18_H, VR18_J, VR18_K,
993 VR19, VR19_H, VR19_J, VR19_K,
994 VR20, VR20_H, VR20_J, VR20_K,
995 VR21, VR21_H, VR21_J, VR21_K,
996 VR22, VR22_H, VR22_J, VR22_K,
997 VR23, VR23_H, VR23_J, VR23_K,
998 VR24, VR24_H, VR24_J, VR24_K,
999 VR25, VR25_H, VR25_J, VR25_K,
1000 VR26, VR26_H, VR26_J, VR26_K,
1001 VR27, VR27_H, VR27_J, VR27_K,
1002 VR28, VR28_H, VR28_J, VR28_K,
1003 VR29, VR29_H, VR29_J, VR29_K,
1004 VR30, VR30_H, VR30_J, VR30_K,
1005 VR31, VR31_H, VR31_J, VR31_K
1006 );
1007
1008 %}
1009
1010 //----------DEFINITION BLOCK---------------------------------------------------
1011 // Define name --> value mappings to inform the ADLC of an integer valued name
1012 // Current support includes integer values in the range [0, 0x7FFFFFFF]
1013 // Format:
1014 // int_def <name> ( <int_value>, <expression>);
1015 // Generated Code in ad_<arch>.hpp
1016 // #define <name> (<expression>)
1017 // // value == <int_value>
1018 // Generated code in ad_<arch>.cpp adlc_verification()
1019 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
1020 //
1021 definitions %{
1022 // The default cost (of an ALU instruction).
1023 int_def DEFAULT_COST_LOW ( 30, 30);
1024 int_def DEFAULT_COST ( 100, 100);
1025 int_def HUGE_COST (1000000, 1000000);
1026
1027 // Memory refs
1028 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2);
1029 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3);
1030
1031 // Branches are even more expensive.
1032 int_def BRANCH_COST ( 900, DEFAULT_COST * 9);
1033 int_def CALL_COST ( 1300, DEFAULT_COST * 13);
1034 %}
1035
1036
1037 //----------SOURCE BLOCK-------------------------------------------------------
1038 // This is a block of C++ code which provides values, functions, and
1039 // definitions necessary in the rest of the architecture description.
1040 source_hpp %{
1041 // Header information of the source block.
1042 // Method declarations/definitions which are used outside
1043 // the ad-scope can conveniently be defined here.
1044 //
1045 // To keep related declarations/definitions/uses close together,
1046 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
1047
1048 #include "opto/convertnode.hpp"
1049
1050 // Returns true if Node n is followed by a MemBar node that
1051 // will do an acquire. If so, this node must not do the acquire
1052 // operation.
1053 bool followed_by_acquire(const Node *n);
1054 %}
1055
1056 source %{
1057
1058 #include "opto/c2_CodeStubs.hpp"
1059 #include "oops/klass.inline.hpp"
1060
1061 void PhaseOutput::pd_perform_mach_node_analysis() {
1062 }
1063
1064 int MachNode::pd_alignment_required() const {
1065 return 1;
1066 }
1067
1068 int MachNode::compute_padding(int current_offset) const {
1069 return 0;
1070 }
1071
1072 // Should the matcher clone input 'm' of node 'n'?
1073 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
1074 if (is_encode_and_store_pattern(n, m)) {
1075 mstack.push(m, Visit);
1076 return true;
1077 }
1078 return false;
1079 }
1080
1081 // Should the Matcher clone shifts on addressing modes, expecting them
1082 // to be subsumed into complex addressing expressions or compute them
1083 // into registers?
1084 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
1085 return clone_base_plus_offset_address(m, mstack, address_visited);
1086 }
1087
1088 // Optimize load-acquire.
1089 //
1090 // Check if acquire is unnecessary due to following operation that does
1091 // acquire anyways.
1092 // Walk the pattern:
1093 //
1094 // n: Load.acq
1095 // |
1096 // MemBarAcquire
1097 // | |
1098 // Proj(ctrl) Proj(mem)
1099 // | |
1100 // MemBarRelease/Volatile
1101 //
1102 bool followed_by_acquire(const Node *load) {
1103 assert(load->is_Load(), "So far implemented only for loads.");
1104
1105 // Find MemBarAcquire.
1106 const Node *mba = nullptr;
1107 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) {
1108 const Node *out = load->fast_out(i);
1109 if (out->Opcode() == Op_MemBarAcquire) {
1110 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge.
1111 mba = out;
1112 break;
1113 }
1114 }
1115 if (!mba) return false;
1116
1117 // Find following MemBar node.
1118 //
1119 // The following node must be reachable by control AND memory
1120 // edge to assure no other operations are in between the two nodes.
1121 //
1122 // So first get the Proj node, mem_proj, to use it to iterate forward.
1123 Node *mem_proj = nullptr;
1124 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) {
1125 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found.
1126 assert(mem_proj->is_Proj(), "only projections here");
1127 ProjNode *proj = mem_proj->as_Proj();
1128 if (proj->_con == TypeFunc::Memory &&
1129 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only
1130 break;
1131 }
1132 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken");
1133
1134 // Search MemBar behind Proj. If there are other memory operations
1135 // behind the Proj we lost.
1136 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) {
1137 Node *x = mem_proj->fast_out(j);
1138 // Proj might have an edge to a store or load node which precedes the membar.
1139 if (x->is_Mem()) return false;
1140
1141 // On PPC64 release and volatile are implemented by an instruction
1142 // that also has acquire semantics. I.e. there is no need for an
1143 // acquire before these.
1144 int xop = x->Opcode();
1145 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) {
1146 // Make sure we're not missing Call/Phi/MergeMem by checking
1147 // control edges. The control edge must directly lead back
1148 // to the MemBarAcquire
1149 Node *ctrl_proj = x->in(0);
1150 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) {
1151 return true;
1152 }
1153 }
1154 }
1155
1156 return false;
1157 }
1158
1159 #define __ masm->
1160
1161 // Tertiary op of a LoadP or StoreP encoding.
1162 #define REGP_OP true
1163
1164 // ****************************************************************************
1165
1166 // REQUIRED FUNCTIONALITY
1167
1168 // !!!!! Special hack to get all type of calls to specify the byte offset
1169 // from the start of the call to the point where the return address
1170 // will point.
1171
1172 // PPC port: Removed use of lazy constant construct.
1173
1174 int MachCallStaticJavaNode::ret_addr_offset() {
1175 // It's only a single branch-and-link instruction.
1176 return 4;
1177 }
1178
1179 int MachCallDynamicJavaNode::ret_addr_offset() {
1180 return 12;
1181 }
1182
1183 int MachCallRuntimeNode::ret_addr_offset() {
1184 if (rule() == CallRuntimeDirect_rule) {
1185 // CallRuntimeDirectNode uses call_c.
1186 #if defined(ABI_ELFv2)
1187 return 28;
1188 #else
1189 return 40;
1190 #endif
1191 }
1192 assert(rule() == CallLeafDirect_rule, "unexpected node with rule %u", rule());
1193 // CallLeafDirectNode uses bl.
1194 return 4;
1195 }
1196
1197 //=============================================================================
1198
1199 // condition code conversions
1200
1201 static int cc_to_boint(int cc) {
1202 return Assembler::bcondCRbiIs0 | (cc & 8);
1203 }
1204
1205 static int cc_to_inverse_boint(int cc) {
1206 return Assembler::bcondCRbiIs0 | (8-(cc & 8));
1207 }
1208
1209 static int cc_to_biint(int cc, int flags_reg) {
1210 return (flags_reg << 2) | (cc & 3);
1211 }
1212
1213 //=============================================================================
1214
1215 // Compute padding required for nodes which need alignment. The padding
1216 // is the number of bytes (not instructions) which will be inserted before
1217 // the instruction. The padding must match the size of a NOP instruction.
1218
1219 // Add nop if a prefixed (two-word) instruction is going to cross a 64-byte boundary.
1220 // (See Section 1.6 of Power ISA Version 3.1)
1221 static int compute_prefix_padding(int current_offset) {
1222 assert(PowerArchitecturePPC64 >= 10 && (CodeEntryAlignment & 63) == 0,
1223 "Code buffer must be aligned to a multiple of 64 bytes");
1224 if (is_aligned(current_offset + BytesPerInstWord, 64)) {
1225 return BytesPerInstWord;
1226 }
1227 return 0;
1228 }
1229
1230 int loadConI32Node::compute_padding(int current_offset) const {
1231 return compute_prefix_padding(current_offset);
1232 }
1233
1234 int loadConL34Node::compute_padding(int current_offset) const {
1235 return compute_prefix_padding(current_offset);
1236 }
1237
1238 int addI_reg_imm32Node::compute_padding(int current_offset) const {
1239 return compute_prefix_padding(current_offset);
1240 }
1241
1242 int addL_reg_imm34Node::compute_padding(int current_offset) const {
1243 return compute_prefix_padding(current_offset);
1244 }
1245
1246 int addP_reg_imm34Node::compute_padding(int current_offset) const {
1247 return compute_prefix_padding(current_offset);
1248 }
1249
1250 int cmprb_Whitespace_reg_reg_prefixedNode::compute_padding(int current_offset) const {
1251 return compute_prefix_padding(current_offset);
1252 }
1253
1254
1255 //=============================================================================
1256
1257 // Emit an interrupt that is caught by the debugger (for debugging compiler).
1258 void emit_break(C2_MacroAssembler *masm) {
1259 __ illtrap();
1260 }
1261
1262 #ifndef PRODUCT
1263 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1264 st->print("BREAKPOINT");
1265 }
1266 #endif
1267
1268 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1269 emit_break(masm);
1270 }
1271
1272 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1273 return MachNode::size(ra_);
1274 }
1275
1276 //=============================================================================
1277
1278 void emit_nop(C2_MacroAssembler *masm) {
1279 __ nop();
1280 }
1281
1282 static inline void emit_long(C2_MacroAssembler *masm, int value) {
1283 *((int*)(__ pc())) = value;
1284 __ set_inst_end(__ pc() + BytesPerInstWord);
1285 }
1286
1287 //=============================================================================
1288
1289 %} // interrupt source
1290
1291 source_hpp %{ // Header information of the source block.
1292
1293 //--------------------------------------------------------------
1294 //---< Used for optimization in Compile::Shorten_branches >---
1295 //--------------------------------------------------------------
1296
1297 class C2_MacroAssembler;
1298
1299 class CallStubImpl {
1300
1301 public:
1302
1303 // Size of call trampoline stub.
1304 // This doesn't need to be accurate to the byte, but it
1305 // must be larger than or equal to the real size of the stub.
1306 static uint size_call_trampoline() {
1307 return MacroAssembler::trampoline_stub_size;
1308 }
1309
1310 // number of relocations needed by a call trampoline stub
1311 static uint reloc_call_trampoline() {
1312 return 5;
1313 }
1314
1315 };
1316
1317 %} // end source_hpp
1318
1319 source %{
1320
1321 // Factory for creating loadConL* nodes for large/small constant pool.
1322
1323 static inline jlong replicate_immF(float con) {
1324 // Replicate float con 2 times and pack into vector.
1325 int val = *((int*)&con);
1326 jlong lval = val;
1327 lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1328 return lval;
1329 }
1330
1331 //=============================================================================
1332
1333 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1334 int ConstantTable::calculate_table_base_offset() const {
1335 return 0; // absolute addressing, no offset
1336 }
1337
1338 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1339 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1340 iRegLdstOper *op_dst = new iRegLdstOper();
1341 MachNode *m1 = new loadToc_hiNode();
1342 MachNode *m2 = new loadToc_loNode();
1343
1344 m1->add_req(nullptr);
1345 m2->add_req(nullptr, m1);
1346 m1->_opnds[0] = op_dst;
1347 m2->_opnds[0] = op_dst;
1348 m2->_opnds[1] = op_dst;
1349 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1350 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1351 nodes->push(m1);
1352 nodes->push(m2);
1353 }
1354
1355 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const {
1356 // Is postalloc expanded.
1357 ShouldNotReachHere();
1358 }
1359
1360 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1361 return 0;
1362 }
1363
1364 #ifndef PRODUCT
1365 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1366 st->print("-- \t// MachConstantBaseNode (empty encoding)");
1367 }
1368 #endif
1369
1370 //=============================================================================
1371
1372 #ifndef PRODUCT
1373 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1374 Compile* C = ra_->C;
1375 const long framesize = C->output()->frame_slots() << LogBytesPerInt;
1376
1377 st->print("PROLOG\n\t");
1378 if (C->output()->need_stack_bang(framesize)) {
1379 st->print("stack_overflow_check\n\t");
1380 }
1381
1382 if (!false /* TODO: PPC port C->is_frameless_method()*/) {
1383 st->print("save return pc\n\t");
1384 st->print("push frame %ld\n\t", -framesize);
1385 }
1386
1387 if (C->stub_function() == nullptr) {
1388 st->print("nmethod entry barrier\n\t");
1389 }
1390 }
1391 #endif
1392
1393 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1394 Compile* C = ra_->C;
1395
1396 const long framesize = C->output()->frame_size_in_bytes();
1397 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment");
1398
1399 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1400
1401 const Register return_pc = R20; // Must match return_addr() in frame section.
1402 const Register callers_sp = R21;
1403 const Register push_frame_temp = R22;
1404 const Register toc_temp = R23;
1405 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp);
1406
1407 if (!method_is_frameless) {
1408 // Get return pc.
1409 __ mflr(return_pc);
1410 }
1411
1412 if (C->clinit_barrier_on_entry()) {
1413 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
1414
1415 Label L_skip_barrier;
1416 Register klass = toc_temp;
1417
1418 // Notify OOP recorder (don't need the relocation)
1419 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding());
1420 __ load_const_optimized(klass, md.value(), R0);
1421 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/);
1422
1423 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0);
1424 __ mtctr(klass);
1425 __ bctr();
1426
1427 __ bind(L_skip_barrier);
1428 }
1429
1430 // Calls to C2R adapters often do not accept exceptional returns.
1431 // We require that their callers must bang for them. But be
1432 // careful, because some VM calls (such as call site linkage) can
1433 // use several kilobytes of stack. But the stack safety zone should
1434 // account for that. See bugs 4446381, 4468289, 4497237.
1435
1436 int bangsize = C->output()->bang_size_in_bytes();
1437 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect");
1438 if (C->output()->need_stack_bang(bangsize)) {
1439 // Unfortunately we cannot use the function provided in
1440 // assembler.cpp as we have to emulate the pipes. So I had to
1441 // insert the code of generate_stack_overflow_check(), see
1442 // assembler.cpp for some illuminative comments.
1443 const int page_size = os::vm_page_size();
1444 int bang_end = StackOverflow::stack_shadow_zone_size();
1445
1446 // This is how far the previous frame's stack banging extended.
1447 const int bang_end_safe = bang_end;
1448
1449 if (bangsize > page_size) {
1450 bang_end += bangsize;
1451 }
1452
1453 int bang_offset = bang_end_safe;
1454
1455 while (bang_offset <= bang_end) {
1456 // Need at least one stack bang at end of shadow zone.
1457
1458 // Again I had to copy code, this time from assembler_ppc.cpp,
1459 // bang_stack_with_offset - see there for comments.
1460
1461 // Stack grows down, caller passes positive offset.
1462 assert(bang_offset > 0, "must bang with positive offset");
1463
1464 long stdoffset = -bang_offset;
1465
1466 if (Assembler::is_simm(stdoffset, 16)) {
1467 // Signed 16 bit offset, a simple std is ok.
1468 if (UseLoadInstructionsForStackBangingPPC64) {
1469 __ ld(R0, (int)(signed short)stdoffset, R1_SP);
1470 } else {
1471 __ std(R0, (int)(signed short)stdoffset, R1_SP);
1472 }
1473 } else if (Assembler::is_simm(stdoffset, 31)) {
1474 // Use largeoffset calculations for addis & ld/std.
1475 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset);
1476 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset);
1477
1478 Register tmp = R11;
1479 __ addis(tmp, R1_SP, hi);
1480 if (UseLoadInstructionsForStackBangingPPC64) {
1481 __ ld(R0, lo, tmp);
1482 } else {
1483 __ std(R0, lo, tmp);
1484 }
1485 } else {
1486 ShouldNotReachHere();
1487 }
1488
1489 bang_offset += page_size;
1490 }
1491 // R11 trashed
1492 } // C->output()->need_stack_bang(framesize)
1493
1494 unsigned int bytes = (unsigned int)framesize;
1495 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
1496 ciMethod *currMethod = C->method();
1497
1498 if (!method_is_frameless) {
1499 // Get callers sp.
1500 __ mr(callers_sp, R1_SP);
1501
1502 // Push method's frame, modifies SP.
1503 assert(Assembler::is_uimm(framesize, 32U), "wrong type");
1504 // The ABI is already accounted for in 'framesize' via the
1505 // 'out_preserve' area.
1506 Register tmp = push_frame_temp;
1507 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp).
1508 if (Assembler::is_simm(-offset, 16)) {
1509 __ stdu(R1_SP, -offset, R1_SP);
1510 } else {
1511 long x = -offset;
1512 // Had to insert load_const(tmp, -offset).
1513 __ lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16)));
1514 __ ori( tmp, tmp, ((x >> 32) & 0x0000ffff));
1515 __ sldi(tmp, tmp, 32);
1516 __ oris(tmp, tmp, (x & 0xffff0000) >> 16);
1517 __ ori( tmp, tmp, (x & 0x0000ffff));
1518
1519 __ stdux(R1_SP, R1_SP, tmp);
1520 }
1521 }
1522 #if 0 // TODO: PPC port
1523 // For testing large constant pools, emit a lot of constants to constant pool.
1524 // "Randomize" const_size.
1525 if (ConstantsALot) {
1526 const int num_consts = const_size();
1527 for (int i = 0; i < num_consts; i++) {
1528 __ long_constant(0xB0B5B00BBABE);
1529 }
1530 }
1531 #endif
1532 if (!method_is_frameless) {
1533 // Save return pc.
1534 __ std(return_pc, _abi0(lr), callers_sp);
1535 }
1536
1537 if (C->stub_function() == nullptr) {
1538 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
1539 bs->nmethod_entry_barrier(masm, push_frame_temp);
1540 }
1541
1542 C->output()->set_frame_complete(__ offset());
1543 }
1544
1545 int MachPrologNode::reloc() const {
1546 // Return number of relocatable values contained in this instruction.
1547 return 1; // 1 reloc entry for load_const(toc).
1548 }
1549
1550 //=============================================================================
1551
1552 #ifndef PRODUCT
1553 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1554 Compile* C = ra_->C;
1555
1556 st->print("EPILOG\n\t");
1557 st->print("restore return pc\n\t");
1558 st->print("pop frame\n\t");
1559
1560 if (do_polling() && C->is_method_compilation()) {
1561 st->print("safepoint poll\n\t");
1562 }
1563 }
1564 #endif
1565
1566 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1567 Compile* C = ra_->C;
1568
1569 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt;
1570 assert(framesize >= 0, "negative frame-size?");
1571
1572 const bool method_needs_polling = do_polling() && C->is_method_compilation();
1573 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1574 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
1575 const Register temp = R12;
1576
1577 if (!method_is_frameless) {
1578 // Restore return pc relative to callers' sp.
1579 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP);
1580 // Move return pc to LR.
1581 __ mtlr(return_pc);
1582 // Pop frame (fixed frame-size).
1583 __ addi(R1_SP, R1_SP, (int)framesize);
1584 }
1585
1586 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1587 __ reserved_stack_check(return_pc);
1588 }
1589
1590 if (method_needs_polling) {
1591 Label dummy_label;
1592 Label* code_stub = &dummy_label;
1593 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) {
1594 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1595 C->output()->add_stub(stub);
1596 code_stub = &stub->entry();
1597 __ relocate(relocInfo::poll_return_type);
1598 }
1599 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */);
1600 }
1601 }
1602
1603 int MachEpilogNode::reloc() const {
1604 // Return number of relocatable values contained in this instruction.
1605 return 1; // 1 for load_from_polling_page.
1606 }
1607
1608 const Pipeline * MachEpilogNode::pipeline() const {
1609 return MachNode::pipeline_class();
1610 }
1611
1612 // =============================================================================
1613
1614 // Figure out which register class each belongs in: rc_int, rc_float, rc_vec or
1615 // rc_stack.
1616 enum RC { rc_bad, rc_int, rc_float, rc_vec, rc_stack };
1617
1618 static enum RC rc_class(OptoReg::Name reg) {
1619 // Return the register class for the given register. The given register
1620 // reg is a <register>_num value, which is an index into the MachRegisterNumbers
1621 // enumeration in adGlobals_ppc.hpp.
1622
1623 if (reg == OptoReg::Bad) return rc_bad;
1624
1625 // We have 64 integer register halves, starting at index 0.
1626 STATIC_ASSERT((int)ConcreteRegisterImpl::max_gpr == (int)MachRegisterNumbers::F0_num);
1627 if (reg < ConcreteRegisterImpl::max_gpr) return rc_int;
1628
1629 // We have 64 floating-point register halves, starting at index 64.
1630 STATIC_ASSERT((int)ConcreteRegisterImpl::max_fpr == (int)MachRegisterNumbers::VR0_num);
1631 if (reg < ConcreteRegisterImpl::max_fpr) return rc_float;
1632
1633 // We have 64 vector-scalar registers, starting at index 128.
1634 STATIC_ASSERT((int)ConcreteRegisterImpl::max_vr == (int)MachRegisterNumbers::CR0_num);
1635 if (reg < ConcreteRegisterImpl::max_vr) return rc_vec;
1636
1637 // Condition and special purpose registers are not allocated. We only accept stack from here.
1638 assert(OptoReg::is_stack(reg), "what else is it?");
1639 return rc_stack;
1640 }
1641
1642 static int ld_st_helper(C2_MacroAssembler *masm, const char *op_str, uint opcode, int reg, int offset,
1643 bool do_print, Compile* C, outputStream *st) {
1644
1645 assert(opcode == Assembler::LD_OPCODE ||
1646 opcode == Assembler::STD_OPCODE ||
1647 opcode == Assembler::LWZ_OPCODE ||
1648 opcode == Assembler::STW_OPCODE ||
1649 opcode == Assembler::LFD_OPCODE ||
1650 opcode == Assembler::STFD_OPCODE ||
1651 opcode == Assembler::LFS_OPCODE ||
1652 opcode == Assembler::STFS_OPCODE,
1653 "opcode not supported");
1654
1655 if (masm) {
1656 int d =
1657 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ?
1658 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/)
1659 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build.
1660 emit_long(masm, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP));
1661 }
1662 #ifndef PRODUCT
1663 else if (do_print) {
1664 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy",
1665 op_str,
1666 Matcher::regName[reg],
1667 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/);
1668 }
1669 #endif
1670 return 4; // size
1671 }
1672
1673 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1674 Compile* C = ra_->C;
1675
1676 // Get registers to move.
1677 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1678 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1679 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1680 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1681
1682 enum RC src_hi_rc = rc_class(src_hi);
1683 enum RC src_lo_rc = rc_class(src_lo);
1684 enum RC dst_hi_rc = rc_class(dst_hi);
1685 enum RC dst_lo_rc = rc_class(dst_lo);
1686
1687 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1688 if (src_hi != OptoReg::Bad)
1689 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1690 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1691 "expected aligned-adjacent pairs");
1692 // Generate spill code!
1693 int size = 0;
1694
1695 if (src_lo == dst_lo && src_hi == dst_hi)
1696 return size; // Self copy, no move.
1697
1698 if (bottom_type()->isa_vect() != nullptr && ideal_reg() == Op_VecX) {
1699 int src_offset = ra_->reg2offset(src_lo);
1700 int dst_offset = ra_->reg2offset(dst_lo);
1701 DEBUG_ONLY(int algm = MIN2(RegMask::num_registers(ideal_reg()), (int)Matcher::stack_alignment_in_slots()) * VMRegImpl::stack_slot_size);
1702 assert((src_lo_rc != rc_stack) || is_aligned(src_offset, algm), "unaligned vector spill sp offset %d (src)", src_offset);
1703 assert((dst_lo_rc != rc_stack) || is_aligned(dst_offset, algm), "unaligned vector spill sp offset %d (dst)", dst_offset);
1704 // Memory->Memory Spill.
1705 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1706 if (masm) {
1707 __ ld(R0, src_offset, R1_SP);
1708 __ std(R0, dst_offset, R1_SP);
1709 __ ld(R0, src_offset+8, R1_SP);
1710 __ std(R0, dst_offset+8, R1_SP);
1711 }
1712 size += 16;
1713 #ifndef PRODUCT
1714 if (st != nullptr) {
1715 st->print("%-7s [R1_SP + #%d] -> [R1_SP + #%d] \t// vector spill copy", "SPILL", src_offset, dst_offset);
1716 }
1717 #endif // !PRODUCT
1718 }
1719 // VectorRegister->Memory Spill.
1720 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_stack) {
1721 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1722 if (masm) {
1723 __ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16
1724 }
1725 size += 4;
1726 #ifndef PRODUCT
1727 if (st != nullptr) {
1728 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "STXV", Matcher::regName[src_lo], dst_offset);
1729 }
1730 #endif // !PRODUCT
1731 }
1732 // Memory->VectorRegister Spill.
1733 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vec) {
1734 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1735 if (masm) {
1736 __ lxv(Rdst, src_offset, R1_SP);
1737 }
1738 size += 4;
1739 #ifndef PRODUCT
1740 if (st != nullptr) {
1741 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "LXV", Matcher::regName[dst_lo], src_offset);
1742 }
1743 #endif // !PRODUCT
1744 }
1745 // VectorRegister->VectorRegister.
1746 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_vec) {
1747 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1748 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1749 if (masm) {
1750 __ xxlor(Rdst, Rsrc, Rsrc);
1751 }
1752 size += 4;
1753 #ifndef PRODUCT
1754 if (st != nullptr) {
1755 st->print("%-7s %s, %s, %s\t// vector spill copy",
1756 "XXLOR", Matcher::regName[dst_lo], Matcher::regName[src_lo], Matcher::regName[src_lo]);
1757 }
1758 #endif // !PRODUCT
1759 }
1760 else {
1761 ShouldNotReachHere(); // No VR spill.
1762 }
1763 return size;
1764 }
1765
1766 // --------------------------------------
1767 // Memory->Memory Spill. Use R0 to hold the value.
1768 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1769 int src_offset = ra_->reg2offset(src_lo);
1770 int dst_offset = ra_->reg2offset(dst_lo);
1771 if (src_hi != OptoReg::Bad) {
1772 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack,
1773 "expected same type of move for high parts");
1774 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st);
1775 if (!masm && !do_size) st->print("\n\t");
1776 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st);
1777 } else {
1778 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st);
1779 if (!masm && !do_size) st->print("\n\t");
1780 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st);
1781 }
1782 return size;
1783 }
1784
1785 // --------------------------------------
1786 // Check for float->int copy; requires a trip through memory.
1787 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1788 Unimplemented();
1789 }
1790
1791 // --------------------------------------
1792 // Check for integer reg-reg copy.
1793 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1794 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1795 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1796 size = (Rsrc != Rdst) ? 4 : 0;
1797
1798 if (masm) {
1799 if (size) {
1800 __ mr(Rdst, Rsrc);
1801 }
1802 }
1803 #ifndef PRODUCT
1804 else if (!do_size) {
1805 if (size) {
1806 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1807 } else {
1808 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1809 }
1810 }
1811 #endif
1812 return size;
1813 }
1814
1815 // Check for integer store.
1816 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1817 int dst_offset = ra_->reg2offset(dst_lo);
1818 if (src_hi != OptoReg::Bad) {
1819 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack,
1820 "expected same type of move for high parts");
1821 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1822 } else {
1823 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st);
1824 }
1825 return size;
1826 }
1827
1828 // Check for integer load.
1829 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1830 int src_offset = ra_->reg2offset(src_lo);
1831 if (src_hi != OptoReg::Bad) {
1832 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack,
1833 "expected same type of move for high parts");
1834 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1835 } else {
1836 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st);
1837 }
1838 return size;
1839 }
1840
1841 // Check for float reg-reg copy.
1842 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1843 if (masm) {
1844 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]);
1845 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]);
1846 __ fmr(Rdst, Rsrc);
1847 }
1848 #ifndef PRODUCT
1849 else if (!do_size) {
1850 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1851 }
1852 #endif
1853 return 4;
1854 }
1855
1856 // Check for float store.
1857 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1858 int dst_offset = ra_->reg2offset(dst_lo);
1859 if (src_hi != OptoReg::Bad) {
1860 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack,
1861 "expected same type of move for high parts");
1862 size += ld_st_helper(masm, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1863 } else {
1864 size += ld_st_helper(masm, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st);
1865 }
1866 return size;
1867 }
1868
1869 // Check for float load.
1870 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1871 int src_offset = ra_->reg2offset(src_lo);
1872 if (src_hi != OptoReg::Bad) {
1873 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack,
1874 "expected same type of move for high parts");
1875 size += ld_st_helper(masm, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1876 } else {
1877 size += ld_st_helper(masm, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st);
1878 }
1879 return size;
1880 }
1881
1882 // --------------------------------------------------------------------
1883 // Check for hi bits still needing moving. Only happens for misaligned
1884 // arguments to native calls.
1885 if (src_hi == dst_hi)
1886 return size; // Self copy; no move.
1887
1888 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad");
1889 ShouldNotReachHere(); // Unimplemented
1890 return 0;
1891 }
1892
1893 #ifndef PRODUCT
1894 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1895 if (!ra_)
1896 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1897 else
1898 implementation(nullptr, ra_, false, st);
1899 }
1900 #endif
1901
1902 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1903 implementation(masm, ra_, false, nullptr);
1904 }
1905
1906 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1907 return implementation(nullptr, ra_, true, nullptr);
1908 }
1909
1910 #ifndef PRODUCT
1911 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1912 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count);
1913 }
1914 #endif
1915
1916 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *) const {
1917 // _count contains the number of nops needed for padding.
1918 for (int i = 0; i < _count; i++) {
1919 __ nop();
1920 }
1921 }
1922
1923 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
1924 return _count * 4;
1925 }
1926
1927 #ifndef PRODUCT
1928 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1929 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1930 char reg_str[128];
1931 ra_->dump_register(this, reg_str, sizeof(reg_str));
1932 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset);
1933 }
1934 #endif
1935
1936 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1937 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1938 int reg = ra_->get_encode(this);
1939
1940 if (Assembler::is_simm(offset, 16)) {
1941 __ addi(as_Register(reg), R1, offset);
1942 } else {
1943 ShouldNotReachHere();
1944 }
1945 }
1946
1947 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1948 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1949 return 4;
1950 }
1951
1952 #ifndef PRODUCT
1953 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1954 {
1955 Unimplemented();
1956 }
1957 #endif
1958
1959 void MachVEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc* ra_) const
1960 {
1961 Unimplemented();
1962 }
1963
1964 #ifndef PRODUCT
1965 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1966 st->print_cr("---- MachUEPNode ----");
1967 st->print_cr("...");
1968 }
1969 #endif
1970
1971 void MachUEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1972 // This is the unverified entry point.
1973 __ ic_check(CodeEntryAlignment);
1974 // Argument is valid and klass is as expected, continue.
1975 }
1976
1977 //=============================================================================
1978
1979 %} // interrupt source
1980
1981 source_hpp %{ // Header information of the source block.
1982
1983 class HandlerImpl {
1984
1985 public:
1986
1987 static int emit_deopt_handler(C2_MacroAssembler* masm);
1988
1989 static uint size_deopt_handler() {
1990 // The deopt_handler is a bl64_patchable.
1991 return MacroAssembler::bl64_patchable_size + BytesPerInstWord;
1992 }
1993
1994 };
1995
1996 class Node::PD {
1997 public:
1998 enum NodeFlags {
1999 _last_flag = Node::_last_flag
2000 };
2001 };
2002
2003 %} // end source_hpp
2004
2005 source %{
2006
2007 // The deopt_handler is like the exception handler, but it calls to
2008 // the deoptimization blob instead of jumping to the exception blob.
2009 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
2010 address base = __ start_a_stub(size_deopt_handler());
2011 if (base == nullptr) {
2012 ciEnv::current()->record_failure("CodeCache is full");
2013 return 0; // CodeBuffer::expand failed
2014 }
2015
2016 int offset = __ offset();
2017
2018 Label start;
2019 __ bind(start);
2020
2021 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
2022 relocInfo::runtime_call_type);
2023
2024 int entry_offset = __ offset();
2025
2026 __ b(start);
2027
2028 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
2029 assert(__ offset() - entry_offset >= NativePostCallNop::first_check_size,
2030 "out of bounds read in post-call NOP check");
2031 __ end_a_stub();
2032
2033 return entry_offset;
2034 }
2035
2036 //=============================================================================
2037
2038 // Use a frame slots bias for frameless methods if accessing the stack.
2039 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) {
2040 if (as_Register(reg_enc) == R1_SP) {
2041 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes();
2042 }
2043 return 0;
2044 }
2045
2046 bool Matcher::match_rule_supported(int opcode) {
2047 if (!has_match_rule(opcode)) {
2048 return false; // no match rule present
2049 }
2050
2051 switch (opcode) {
2052 case Op_CountLeadingZerosI:
2053 case Op_CountLeadingZerosL:
2054 return UseCountLeadingZerosInstructionsPPC64;
2055 case Op_CountTrailingZerosI:
2056 case Op_CountTrailingZerosL:
2057 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64);
2058 case Op_PopCountI:
2059 case Op_PopCountL:
2060 return UsePopCountInstruction;
2061 case Op_ConvF2HF:
2062 case Op_ConvHF2F:
2063 return VM_Version::supports_float16();
2064 case Op_AddVB:
2065 case Op_AddVS:
2066 case Op_AddVI:
2067 case Op_AddVF:
2068 case Op_AddVD:
2069 case Op_SubVB:
2070 case Op_SubVS:
2071 case Op_SubVI:
2072 case Op_SubVF:
2073 case Op_SubVD:
2074 case Op_MulVS:
2075 case Op_MulVF:
2076 case Op_MulVD:
2077 case Op_DivVF:
2078 case Op_DivVD:
2079 case Op_AbsVF:
2080 case Op_AbsVD:
2081 case Op_NegVI:
2082 case Op_NegVF:
2083 case Op_NegVD:
2084 case Op_SqrtVF:
2085 case Op_SqrtVD:
2086 case Op_AddVL:
2087 case Op_SubVL:
2088 case Op_MulVI:
2089 case Op_RoundDoubleModeV:
2090 case Op_MinV:
2091 case Op_MaxV:
2092 case Op_UMinV:
2093 case Op_UMaxV:
2094 case Op_AndV:
2095 case Op_OrV:
2096 case Op_XorV:
2097 case Op_AddReductionVI:
2098 case Op_MulReductionVI:
2099 case Op_AndReductionV:
2100 case Op_OrReductionV:
2101 case Op_XorReductionV:
2102 case Op_MinReductionV:
2103 case Op_MaxReductionV:
2104 return SuperwordUseVSX;
2105 case Op_PopCountVI:
2106 case Op_PopCountVL:
2107 return (SuperwordUseVSX && UsePopCountInstruction);
2108 case Op_CountLeadingZerosV:
2109 return SuperwordUseVSX && UseCountLeadingZerosInstructionsPPC64;
2110 case Op_CountTrailingZerosV:
2111 return SuperwordUseVSX && UseCountTrailingZerosInstructionsPPC64;
2112 case Op_FmaF:
2113 case Op_FmaD:
2114 return UseFMA;
2115 case Op_FmaVF:
2116 case Op_FmaVD:
2117 return (SuperwordUseVSX && UseFMA);
2118
2119 case Op_MinF:
2120 case Op_MaxF:
2121 case Op_MinD:
2122 case Op_MaxD:
2123 return (PowerArchitecturePPC64 >= 9);
2124
2125 case Op_Digit:
2126 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit);
2127 case Op_LowerCase:
2128 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase);
2129 case Op_UpperCase:
2130 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase);
2131 case Op_Whitespace:
2132 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace);
2133
2134 case Op_CacheWB:
2135 case Op_CacheWBPreSync:
2136 case Op_CacheWBPostSync:
2137 return VM_Version::supports_data_cache_line_flush();
2138
2139 case Op_OnSpinWait:
2140 return VM_Version::supports_on_spin_wait();
2141 }
2142
2143 return true; // Per default match rules are supported.
2144 }
2145
2146 bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
2147 return match_rule_supported_vector(opcode, vlen, bt);
2148 }
2149
2150 bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
2151 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
2152 return false;
2153 }
2154 // Special cases
2155 switch (opcode) {
2156 // Reductions only support INT at the moment.
2157 case Op_AddReductionVI:
2158 case Op_MulReductionVI:
2159 case Op_AndReductionV:
2160 case Op_OrReductionV:
2161 case Op_XorReductionV:
2162 case Op_MinReductionV:
2163 case Op_MaxReductionV:
2164 return bt == T_INT;
2165 // MaxV, MinV need types == INT || LONG.
2166 case Op_MaxV:
2167 case Op_MinV:
2168 case Op_UMinV:
2169 case Op_UMaxV:
2170 return bt == T_INT || bt == T_LONG;
2171 case Op_NegVI:
2172 return bt == T_INT;
2173 }
2174 return true; // Per default match rules are supported.
2175 }
2176
2177 bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
2178 return false;
2179 }
2180
2181 bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
2182 return false;
2183 }
2184
2185 bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
2186 return false;
2187 }
2188
2189 bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
2190 return false;
2191 }
2192
2193 const RegMask* Matcher::predicate_reg_mask(void) {
2194 return nullptr;
2195 }
2196
2197 // Vector calling convention not yet implemented.
2198 bool Matcher::supports_vector_calling_convention(void) {
2199 return false;
2200 }
2201
2202 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2203 Unimplemented();
2204 return OptoRegPair(0, 0);
2205 }
2206
2207 // Vector width in bytes.
2208 int Matcher::vector_width_in_bytes(BasicType bt) {
2209 if (SuperwordUseVSX) {
2210 assert(MaxVectorSize == 16,
2211 "SuperwordUseVSX requires MaxVectorSize 16, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2212 return 16;
2213 } else {
2214 assert(MaxVectorSize == 8,
2215 "expected MaxVectorSize 8, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2216 return 8;
2217 }
2218 }
2219
2220 // Vector ideal reg.
2221 uint Matcher::vector_ideal_reg(int size) {
2222 if (SuperwordUseVSX) {
2223 assert(MaxVectorSize == 16 && size == 16,
2224 "SuperwordUseVSX requires MaxVectorSize 16 and size 16, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2225 (int64_t)MaxVectorSize, size);
2226 return Op_VecX;
2227 } else {
2228 assert(MaxVectorSize == 8 && size == 8,
2229 "expected MaxVectorSize 8 and size 8, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2230 (int64_t)MaxVectorSize, size);
2231 return Op_RegL;
2232 }
2233 }
2234
2235 // Limits on vector size (number of elements) loaded into vector.
2236 int Matcher::max_vector_size(const BasicType bt) {
2237 assert(is_java_primitive(bt), "only primitive type vectors");
2238 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2239 }
2240
2241 int Matcher::min_vector_size(const BasicType bt) {
2242 return max_vector_size(bt); // Same as max.
2243 }
2244
2245 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
2246 return Matcher::max_vector_size(bt);
2247 }
2248
2249 int Matcher::scalable_vector_reg_size(const BasicType bt) {
2250 return -1;
2251 }
2252
2253 // RETURNS: whether this branch offset is short enough that a short
2254 // branch can be used.
2255 //
2256 // If the platform does not provide any short branch variants, then
2257 // this method should return `false' for offset 0.
2258 //
2259 // `Compile::Fill_buffer' will decide on basis of this information
2260 // whether to do the pass `Compile::Shorten_branches' at all.
2261 //
2262 // And `Compile::Shorten_branches' will decide on basis of this
2263 // information whether to replace particular branch sites by short
2264 // ones.
2265 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2266 // Is the offset within the range of a ppc64 pc relative branch?
2267 bool b;
2268
2269 const int safety_zone = 3 * BytesPerInstWord;
2270 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2271 29 - 16 + 1 + 2);
2272 return b;
2273 }
2274
2275 /* TODO: PPC port
2276 // Make a new machine dependent decode node (with its operands).
2277 MachTypeNode *Matcher::make_decode_node() {
2278 assert(CompressedOops::base() == nullptr && CompressedOops::shift() == 0,
2279 "This method is only implemented for unscaled cOops mode so far");
2280 MachTypeNode *decode = new decodeN_unscaledNode();
2281 decode->set_opnd_array(0, new iRegPdstOper());
2282 decode->set_opnd_array(1, new iRegNsrcOper());
2283 return decode;
2284 }
2285 */
2286
2287 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
2288 ShouldNotReachHere(); // generic vector operands not supported
2289 return nullptr;
2290 }
2291
2292 bool Matcher::is_reg2reg_move(MachNode* m) {
2293 ShouldNotReachHere(); // generic vector operands not supported
2294 return false;
2295 }
2296
2297 bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
2298 return false;
2299 }
2300
2301 bool Matcher::is_generic_vector(MachOper* opnd) {
2302 ShouldNotReachHere(); // generic vector operands not supported
2303 return false;
2304 }
2305
2306 #ifdef ASSERT
2307 // Return whether or not this register is ever used as an argument.
2308 bool Matcher::can_be_java_arg(int reg) {
2309 // We must include the virtual halves in order to get STDs and LDs
2310 // instead of STWs and LWs in the trampoline stubs.
2311
2312 if ( reg == R3_num || reg == R3_H_num
2313 || reg == R4_num || reg == R4_H_num
2314 || reg == R5_num || reg == R5_H_num
2315 || reg == R6_num || reg == R6_H_num
2316 || reg == R7_num || reg == R7_H_num
2317 || reg == R8_num || reg == R8_H_num
2318 || reg == R9_num || reg == R9_H_num
2319 || reg == R10_num || reg == R10_H_num)
2320 return true;
2321
2322 if ( reg == F1_num || reg == F1_H_num
2323 || reg == F2_num || reg == F2_H_num
2324 || reg == F3_num || reg == F3_H_num
2325 || reg == F4_num || reg == F4_H_num
2326 || reg == F5_num || reg == F5_H_num
2327 || reg == F6_num || reg == F6_H_num
2328 || reg == F7_num || reg == F7_H_num
2329 || reg == F8_num || reg == F8_H_num
2330 || reg == F9_num || reg == F9_H_num
2331 || reg == F10_num || reg == F10_H_num
2332 || reg == F11_num || reg == F11_H_num
2333 || reg == F12_num || reg == F12_H_num
2334 || reg == F13_num || reg == F13_H_num)
2335 return true;
2336
2337 return false;
2338 }
2339 #endif
2340
2341 uint Matcher::int_pressure_limit()
2342 {
2343 return (INTPRESSURE == -1) ? 26 : INTPRESSURE;
2344 }
2345
2346 uint Matcher::float_pressure_limit()
2347 {
2348 return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE;
2349 }
2350
2351 // Register for the first projection of an int pair
2352 const RegMask& Matcher::firstI_proj_mask() {
2353 ShouldNotReachHere();
2354 return RegMask::EMPTY;
2355 }
2356
2357 // Register for the second projection of an int pair
2358 const RegMask& Matcher::secondI_proj_mask() {
2359 ShouldNotReachHere();
2360 return RegMask::EMPTY;
2361 }
2362
2363 // Register for the first projection of a long pair
2364 const RegMask& Matcher::firstL_proj_mask() {
2365 ShouldNotReachHere();
2366 return RegMask::EMPTY;
2367 }
2368
2369 // Register for the second projection of a long pair
2370 const RegMask& Matcher::secondL_proj_mask() {
2371 ShouldNotReachHere();
2372 return RegMask::EMPTY;
2373 }
2374
2375 %}
2376
2377 //----------ENCODING BLOCK-----------------------------------------------------
2378 // This block specifies the encoding classes used by the compiler to output
2379 // byte streams. Encoding classes are parameterized macros used by
2380 // Machine Instruction Nodes in order to generate the bit encoding of the
2381 // instruction. Operands specify their base encoding interface with the
2382 // interface keyword. There are currently supported four interfaces,
2383 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
2384 // operand to generate a function which returns its register number when
2385 // queried. CONST_INTER causes an operand to generate a function which
2386 // returns the value of the constant when queried. MEMORY_INTER causes an
2387 // operand to generate four functions which return the Base Register, the
2388 // Index Register, the Scale Value, and the Offset Value of the operand when
2389 // queried. COND_INTER causes an operand to generate six functions which
2390 // return the encoding code (ie - encoding bits for the instruction)
2391 // associated with each basic boolean condition for a conditional instruction.
2392 //
2393 // Instructions specify two basic values for encoding. Again, a function
2394 // is available to check if the constant displacement is an oop. They use the
2395 // ins_encode keyword to specify their encoding classes (which must be
2396 // a sequence of enc_class names, and their parameters, specified in
2397 // the encoding block), and they use the
2398 // opcode keyword to specify, in order, their primary, secondary, and
2399 // tertiary opcode. Only the opcode sections which a particular instruction
2400 // needs for encoding need to be specified.
2401 encode %{
2402 enc_class enc_unimplemented %{
2403 __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
2404 %}
2405
2406 enc_class enc_untested %{
2407 #ifdef ASSERT
2408 __ untested("Untested mach node encoding in AD file.");
2409 #else
2410 #endif
2411 %}
2412
2413 enc_class enc_lbz(iRegIdst dst, memory mem) %{
2414 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2415 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2416 %}
2417
2418 // Load acquire.
2419 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
2420 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2421 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2422 __ twi_0($dst$$Register);
2423 __ isync();
2424 %}
2425
2426 enc_class enc_lhz(iRegIdst dst, memory mem) %{
2427 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2428 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2429 %}
2430
2431 // Load acquire.
2432 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
2433 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2434 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2435 __ twi_0($dst$$Register);
2436 __ isync();
2437 %}
2438
2439 enc_class enc_lwz(iRegIdst dst, memory mem) %{
2440 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2441 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2442 %}
2443
2444 // Load acquire.
2445 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
2446 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2447 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2448 __ twi_0($dst$$Register);
2449 __ isync();
2450 %}
2451
2452 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
2453 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2454 // Operand 'ds' requires 4-alignment.
2455 assert((Idisp & 0x3) == 0, "unaligned offset");
2456 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2457 %}
2458
2459 // Load acquire.
2460 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
2461 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2462 // Operand 'ds' requires 4-alignment.
2463 assert((Idisp & 0x3) == 0, "unaligned offset");
2464 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2465 __ twi_0($dst$$Register);
2466 __ isync();
2467 %}
2468
2469 enc_class enc_lfd(RegF dst, memory mem) %{
2470 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2471 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2472 %}
2473
2474 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2475 int toc_offset = 0;
2476
2477 address const_toc_addr;
2478 // Create a non-oop constant, no relocation needed.
2479 // If it is an IC, it has a virtual_call_Relocation.
2480 const_toc_addr = __ long_constant((jlong)$src$$constant);
2481 if (const_toc_addr == nullptr) {
2482 ciEnv::current()->record_out_of_memory_failure();
2483 return;
2484 }
2485
2486 // Get the constant's TOC offset.
2487 toc_offset = __ offset_to_method_toc(const_toc_addr);
2488
2489 // Keep the current instruction offset in mind.
2490 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2491
2492 __ ld($dst$$Register, toc_offset, $toc$$Register);
2493 %}
2494
2495 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2496 if (!ra_->C->output()->in_scratch_emit_size()) {
2497 address const_toc_addr;
2498 // Create a non-oop constant, no relocation needed.
2499 // If it is an IC, it has a virtual_call_Relocation.
2500 const_toc_addr = __ long_constant((jlong)$src$$constant);
2501 if (const_toc_addr == nullptr) {
2502 ciEnv::current()->record_out_of_memory_failure();
2503 return;
2504 }
2505
2506 // Get the constant's TOC offset.
2507 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2508 // Store the toc offset of the constant.
2509 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2510
2511 // Also keep the current instruction offset in mind.
2512 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2513 }
2514
2515 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2516 %}
2517
2518 %} // encode
2519
2520 source %{
2521
2522 typedef struct {
2523 loadConL_hiNode *_large_hi;
2524 loadConL_loNode *_large_lo;
2525 loadConLNode *_small;
2526 MachNode *_last;
2527 } loadConLNodesTuple;
2528
2529 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2530 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2531 loadConLNodesTuple nodes;
2532
2533 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2534 if (large_constant_pool) {
2535 // Create new nodes.
2536 loadConL_hiNode *m1 = new loadConL_hiNode();
2537 loadConL_loNode *m2 = new loadConL_loNode();
2538
2539 // inputs for new nodes
2540 m1->add_req(nullptr, toc);
2541 m2->add_req(nullptr, m1);
2542
2543 // operands for new nodes
2544 m1->_opnds[0] = new iRegLdstOper(); // dst
2545 m1->_opnds[1] = immSrc; // src
2546 m1->_opnds[2] = new iRegLdstOper(); // toc
2547 m2->_opnds[0] = new iRegLdstOper(); // dst
2548 m2->_opnds[1] = immSrc; // src
2549 m2->_opnds[2] = new iRegLdstOper(); // base
2550
2551 // Initialize ins_attrib TOC fields.
2552 m1->_const_toc_offset = -1;
2553 m2->_const_toc_offset_hi_node = m1;
2554
2555 // Initialize ins_attrib instruction offset.
2556 m1->_cbuf_insts_offset = -1;
2557
2558 // register allocation for new nodes
2559 ra_->set_pair(m1->_idx, reg_second, reg_first);
2560 ra_->set_pair(m2->_idx, reg_second, reg_first);
2561
2562 // Create result.
2563 nodes._large_hi = m1;
2564 nodes._large_lo = m2;
2565 nodes._small = nullptr;
2566 nodes._last = nodes._large_lo;
2567 assert(m2->bottom_type()->isa_long(), "must be long");
2568 } else {
2569 loadConLNode *m2 = new loadConLNode();
2570
2571 // inputs for new nodes
2572 m2->add_req(nullptr, toc);
2573
2574 // operands for new nodes
2575 m2->_opnds[0] = new iRegLdstOper(); // dst
2576 m2->_opnds[1] = immSrc; // src
2577 m2->_opnds[2] = new iRegLdstOper(); // toc
2578
2579 // Initialize ins_attrib instruction offset.
2580 m2->_cbuf_insts_offset = -1;
2581
2582 // register allocation for new nodes
2583 ra_->set_pair(m2->_idx, reg_second, reg_first);
2584
2585 // Create result.
2586 nodes._large_hi = nullptr;
2587 nodes._large_lo = nullptr;
2588 nodes._small = m2;
2589 nodes._last = nodes._small;
2590 assert(m2->bottom_type()->isa_long(), "must be long");
2591 }
2592
2593 return nodes;
2594 }
2595
2596 typedef struct {
2597 loadConL_hiNode *_large_hi;
2598 loadConL_loNode *_large_lo;
2599 mtvsrdNode *_moved;
2600 xxspltdNode *_replicated;
2601 loadConLNode *_small;
2602 MachNode *_last;
2603 } loadConLReplicatedNodesTuple;
2604
2605 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2606 vecXOper *dst, immI_0Oper *zero,
2607 OptoReg::Name reg_second, OptoReg::Name reg_first,
2608 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) {
2609 loadConLReplicatedNodesTuple nodes;
2610
2611 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2612 if (large_constant_pool) {
2613 // Create new nodes.
2614 loadConL_hiNode *m1 = new loadConL_hiNode();
2615 loadConL_loNode *m2 = new loadConL_loNode();
2616 mtvsrdNode *m3 = new mtvsrdNode();
2617 xxspltdNode *m4 = new xxspltdNode();
2618
2619 // inputs for new nodes
2620 m1->add_req(nullptr, toc);
2621 m2->add_req(nullptr, m1);
2622 m3->add_req(nullptr, m2);
2623 m4->add_req(nullptr, m3);
2624
2625 // operands for new nodes
2626 m1->_opnds[0] = new iRegLdstOper(); // dst
2627 m1->_opnds[1] = immSrc; // src
2628 m1->_opnds[2] = new iRegLdstOper(); // toc
2629
2630 m2->_opnds[0] = new iRegLdstOper(); // dst
2631 m2->_opnds[1] = immSrc; // src
2632 m2->_opnds[2] = new iRegLdstOper(); // base
2633
2634 m3->_opnds[0] = new vecXOper(); // dst
2635 m3->_opnds[1] = new iRegLdstOper(); // src
2636
2637 m4->_opnds[0] = new vecXOper(); // dst
2638 m4->_opnds[1] = new vecXOper(); // src
2639 m4->_opnds[2] = zero;
2640
2641 // Initialize ins_attrib TOC fields.
2642 m1->_const_toc_offset = -1;
2643 m2->_const_toc_offset_hi_node = m1;
2644
2645 // Initialize ins_attrib instruction offset.
2646 m1->_cbuf_insts_offset = -1;
2647
2648 // register allocation for new nodes
2649 ra_->set_pair(m1->_idx, reg_second, reg_first);
2650 ra_->set_pair(m2->_idx, reg_second, reg_first);
2651 ra_->set1(m3->_idx, reg_second);
2652 ra_->set2(m3->_idx, reg_vec_first);
2653 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2654
2655 // Create result.
2656 nodes._large_hi = m1;
2657 nodes._large_lo = m2;
2658 nodes._moved = m3;
2659 nodes._replicated = m4;
2660 nodes._small = nullptr;
2661 nodes._last = nodes._replicated;
2662 assert(m2->bottom_type()->isa_long(), "must be long");
2663 } else {
2664 loadConLNode *m2 = new loadConLNode();
2665 mtvsrdNode *m3 = new mtvsrdNode();
2666 xxspltdNode *m4 = new xxspltdNode();
2667
2668 // inputs for new nodes
2669 m2->add_req(nullptr, toc);
2670
2671 // operands for new nodes
2672 m2->_opnds[0] = new iRegLdstOper(); // dst
2673 m2->_opnds[1] = immSrc; // src
2674 m2->_opnds[2] = new iRegLdstOper(); // toc
2675
2676 m3->_opnds[0] = new vecXOper(); // dst
2677 m3->_opnds[1] = new iRegLdstOper(); // src
2678
2679 m4->_opnds[0] = new vecXOper(); // dst
2680 m4->_opnds[1] = new vecXOper(); // src
2681 m4->_opnds[2] = zero;
2682
2683 // Initialize ins_attrib instruction offset.
2684 m2->_cbuf_insts_offset = -1;
2685 ra_->set1(m3->_idx, reg_second);
2686 ra_->set2(m3->_idx, reg_vec_first);
2687 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2688
2689 // register allocation for new nodes
2690 ra_->set_pair(m2->_idx, reg_second, reg_first);
2691
2692 // Create result.
2693 nodes._large_hi = nullptr;
2694 nodes._large_lo = nullptr;
2695 nodes._small = m2;
2696 nodes._moved = m3;
2697 nodes._replicated = m4;
2698 nodes._last = nodes._replicated;
2699 assert(m2->bottom_type()->isa_long(), "must be long");
2700 }
2701
2702 return nodes;
2703 }
2704
2705 %} // source
2706
2707 encode %{
2708 // Postalloc expand emitter for loading a long constant from the method's TOC.
2709 // Enc_class needed as consttanttablebase is not supported by postalloc
2710 // expand.
2711 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2712 // Create new nodes.
2713 loadConLNodesTuple loadConLNodes =
2714 loadConLNodesTuple_create(ra_, n_toc, op_src,
2715 ra_->get_reg_second(this), ra_->get_reg_first(this));
2716
2717 // Push new nodes.
2718 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2719 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2720
2721 // some asserts
2722 assert(nodes->length() >= 1, "must have created at least 1 node");
2723 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2724 %}
2725
2726 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2727 int toc_offset = 0;
2728
2729 intptr_t val = $src$$constant;
2730 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2731 address const_toc_addr;
2732 RelocationHolder r; // Initializes type to none.
2733 if (constant_reloc == relocInfo::oop_type) {
2734 // Create an oop constant and a corresponding relocation.
2735 AddressLiteral a = __ constant_oop_address((jobject)val);
2736 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2737 r = a.rspec();
2738 } else if (constant_reloc == relocInfo::metadata_type) {
2739 // Notify OOP recorder (don't need the relocation)
2740 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2741 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2742 } else {
2743 // Create a non-oop constant, no relocation needed.
2744 const_toc_addr = __ long_constant((jlong)$src$$constant);
2745 }
2746
2747 if (const_toc_addr == nullptr) {
2748 ciEnv::current()->record_out_of_memory_failure();
2749 return;
2750 }
2751 __ relocate(r); // If set above.
2752 // Get the constant's TOC offset.
2753 toc_offset = __ offset_to_method_toc(const_toc_addr);
2754
2755 __ ld($dst$$Register, toc_offset, $toc$$Register);
2756 %}
2757
2758 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2759 if (!ra_->C->output()->in_scratch_emit_size()) {
2760 intptr_t val = $src$$constant;
2761 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2762 address const_toc_addr;
2763 RelocationHolder r; // Initializes type to none.
2764 if (constant_reloc == relocInfo::oop_type) {
2765 // Create an oop constant and a corresponding relocation.
2766 AddressLiteral a = __ constant_oop_address((jobject)val);
2767 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2768 r = a.rspec();
2769 } else if (constant_reloc == relocInfo::metadata_type) {
2770 // Notify OOP recorder (don't need the relocation)
2771 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2772 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2773 } else { // non-oop pointers, e.g. card mark base, heap top
2774 // Create a non-oop constant, no relocation needed.
2775 const_toc_addr = __ long_constant((jlong)$src$$constant);
2776 }
2777
2778 if (const_toc_addr == nullptr) {
2779 ciEnv::current()->record_out_of_memory_failure();
2780 return;
2781 }
2782 __ relocate(r); // If set above.
2783 // Get the constant's TOC offset.
2784 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2785 // Store the toc offset of the constant.
2786 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2787 }
2788
2789 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2790 %}
2791
2792 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2793 // Enc_class needed as consttanttablebase is not supported by postalloc
2794 // expand.
2795 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2796 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2797 if (large_constant_pool) {
2798 // Create new nodes.
2799 loadConP_hiNode *m1 = new loadConP_hiNode();
2800 loadConP_loNode *m2 = new loadConP_loNode();
2801
2802 // If this is an oop, both m1 and m2 must be consider oops so postalloc scheduling does not
2803 // put a safepoint between them
2804 m1->_bottom_type = bottom_type();
2805 m2->_bottom_type = bottom_type();
2806
2807 // inputs for new nodes
2808 m1->add_req(nullptr, n_toc);
2809 m2->add_req(nullptr, m1);
2810
2811 // operands for new nodes
2812 m1->_opnds[0] = new iRegPdstOper(); // dst
2813 m1->_opnds[1] = op_src; // src
2814 m1->_opnds[2] = new iRegLdstOper(); // toc
2815
2816 m2->_opnds[0] = new iRegPdstOper(); // dst
2817 m2->_opnds[1] = op_src; // src
2818 m2->_opnds[2] = new iRegLdstOper(); // base
2819
2820 // Initialize ins_attrib TOC fields.
2821 m1->_const_toc_offset = -1;
2822 m2->_const_toc_offset_hi_node = m1;
2823
2824 // Register allocation for new nodes.
2825 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2826 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2827
2828 nodes->push(m1);
2829 nodes->push(m2);
2830 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2831 } else {
2832 loadConPNode *m2 = new loadConPNode();
2833
2834 // inputs for new nodes
2835 m2->add_req(nullptr, n_toc);
2836
2837 // operands for new nodes
2838 m2->_opnds[0] = new iRegPdstOper(); // dst
2839 m2->_opnds[1] = op_src; // src
2840 m2->_opnds[2] = new iRegLdstOper(); // toc
2841
2842 // Register allocation for new nodes.
2843 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2844
2845 nodes->push(m2);
2846 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2847 }
2848 %}
2849
2850 // Enc_class needed as consttanttablebase is not supported by postalloc
2851 // expand.
2852 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2853 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2854
2855 MachNode *m2;
2856 if (large_constant_pool) {
2857 m2 = new loadConFCompNode();
2858 } else {
2859 m2 = new loadConFNode();
2860 }
2861 // inputs for new nodes
2862 m2->add_req(nullptr, n_toc);
2863
2864 // operands for new nodes
2865 m2->_opnds[0] = op_dst;
2866 m2->_opnds[1] = op_src;
2867 m2->_opnds[2] = new iRegLdstOper(); // constanttablebase
2868
2869 // register allocation for new nodes
2870 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2871 nodes->push(m2);
2872 %}
2873
2874 // Enc_class needed as consttanttablebase is not supported by postalloc
2875 // expand.
2876 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2877 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2878
2879 MachNode *m2;
2880 if (large_constant_pool) {
2881 m2 = new loadConDCompNode();
2882 } else {
2883 m2 = new loadConDNode();
2884 }
2885 // inputs for new nodes
2886 m2->add_req(nullptr, n_toc);
2887
2888 // operands for new nodes
2889 m2->_opnds[0] = op_dst;
2890 m2->_opnds[1] = op_src;
2891 m2->_opnds[2] = new iRegLdstOper(); // constanttablebase
2892
2893 // register allocation for new nodes
2894 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2895 nodes->push(m2);
2896 %}
2897
2898 enc_class enc_stw(iRegIsrc src, memory mem) %{
2899 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2900 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2901 %}
2902
2903 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2904 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2905 // Operand 'ds' requires 4-alignment.
2906 assert((Idisp & 0x3) == 0, "unaligned offset");
2907 __ std($src$$Register, Idisp, $mem$$base$$Register);
2908 %}
2909
2910 enc_class enc_stfs(RegF src, memory mem) %{
2911 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2912 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2913 %}
2914
2915 enc_class enc_stfd(RegF src, memory mem) %{
2916 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2917 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2918 %}
2919
2920 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2921 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
2922 encodeP_subNode *n_sub_base = new encodeP_subNode();
2923 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
2924 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode();
2925
2926 n_compare->add_req(n_region, n_src);
2927 n_compare->_opnds[0] = op_crx;
2928 n_compare->_opnds[1] = op_src;
2929 n_compare->_opnds[2] = new immL16Oper(0);
2930
2931 n_sub_base->add_req(n_region, n_src);
2932 n_sub_base->_opnds[0] = op_dst;
2933 n_sub_base->_opnds[1] = op_src;
2934 n_sub_base->_bottom_type = _bottom_type;
2935
2936 n_shift->add_req(n_region, n_sub_base);
2937 n_shift->_opnds[0] = op_dst;
2938 n_shift->_opnds[1] = op_dst;
2939 n_shift->_bottom_type = _bottom_type;
2940
2941 n_cond_set->add_req(n_region, n_compare, n_shift);
2942 n_cond_set->_opnds[0] = op_dst;
2943 n_cond_set->_opnds[1] = op_crx;
2944 n_cond_set->_opnds[2] = op_dst;
2945 n_cond_set->_bottom_type = _bottom_type;
2946
2947 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2948 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2949 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2950 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2951
2952 nodes->push(n_compare);
2953 nodes->push(n_sub_base);
2954 nodes->push(n_shift);
2955 nodes->push(n_cond_set);
2956
2957 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2958 %}
2959
2960 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
2961
2962 encodeP_subNode *n1 = new encodeP_subNode();
2963 n1->add_req(n_region, n_src);
2964 n1->_opnds[0] = op_dst;
2965 n1->_opnds[1] = op_src;
2966 n1->_bottom_type = _bottom_type;
2967
2968 encodeP_shiftNode *n2 = new encodeP_shiftNode();
2969 n2->add_req(n_region, n1);
2970 n2->_opnds[0] = op_dst;
2971 n2->_opnds[1] = op_dst;
2972 n2->_bottom_type = _bottom_type;
2973 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2974 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2975
2976 nodes->push(n1);
2977 nodes->push(n2);
2978 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2979 %}
2980
2981 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
2982 decodeN_shiftNode *n_shift = new decodeN_shiftNode();
2983 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
2984
2985 n_compare->add_req(n_region, n_src);
2986 n_compare->_opnds[0] = op_crx;
2987 n_compare->_opnds[1] = op_src;
2988 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
2989
2990 n_shift->add_req(n_region, n_src);
2991 n_shift->_opnds[0] = op_dst;
2992 n_shift->_opnds[1] = op_src;
2993 n_shift->_bottom_type = _bottom_type;
2994
2995 decodeN_addNode *n_add_base = new decodeN_addNode();
2996 n_add_base->add_req(n_region, n_shift);
2997 n_add_base->_opnds[0] = op_dst;
2998 n_add_base->_opnds[1] = op_dst;
2999 n_add_base->_bottom_type = _bottom_type;
3000
3001 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
3002 n_cond_set->add_req(n_region, n_compare, n_add_base);
3003 n_cond_set->_opnds[0] = op_dst;
3004 n_cond_set->_opnds[1] = op_crx;
3005 n_cond_set->_opnds[2] = op_dst;
3006 n_cond_set->_bottom_type = _bottom_type;
3007
3008 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3009 ra_->set_oop(n_cond_set, true);
3010
3011 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3012 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3013 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3014 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3015
3016 nodes->push(n_compare);
3017 nodes->push(n_shift);
3018 nodes->push(n_add_base);
3019 nodes->push(n_cond_set);
3020
3021 %}
3022
3023 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3024 decodeN_shiftNode *n1 = new decodeN_shiftNode();
3025 n1->add_req(n_region, n_src);
3026 n1->_opnds[0] = op_dst;
3027 n1->_opnds[1] = op_src;
3028 n1->_bottom_type = _bottom_type;
3029
3030 decodeN_addNode *n2 = new decodeN_addNode();
3031 n2->add_req(n_region, n1);
3032 n2->_opnds[0] = op_dst;
3033 n2->_opnds[1] = op_dst;
3034 n2->_bottom_type = _bottom_type;
3035 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3036 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3037
3038 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3039 ra_->set_oop(n2, true);
3040
3041 nodes->push(n1);
3042 nodes->push(n2);
3043 %}
3044
3045
3046 // This enc_class is needed so that scheduler gets proper
3047 // input mapping for latency computation.
3048 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
3049 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
3050 %}
3051
3052 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3053 Label done;
3054 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3055 __ li($dst$$Register, $zero$$constant);
3056 __ beq($crx$$CondRegister, done);
3057 __ li($dst$$Register, $notzero$$constant);
3058 __ bind(done);
3059 %}
3060
3061 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3062 Label done;
3063 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3064 __ li($dst$$Register, $zero$$constant);
3065 __ beq($crx$$CondRegister, done);
3066 __ li($dst$$Register, $notzero$$constant);
3067 __ bind(done);
3068 %}
3069
3070 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3071 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3072 Label done;
3073 __ bso($crx$$CondRegister, done);
3074 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3075 __ bind(done);
3076 %}
3077
3078 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3079 Label d; // dummy
3080 __ bind(d);
3081 Label* p = ($lbl$$label);
3082 // `p' is `nullptr' when this encoding class is used only to
3083 // determine the size of the encoded instruction.
3084 Label& l = (nullptr == p)? d : *(p);
3085 int cc = $cmp$$cmpcode;
3086 int flags_reg = $crx$$reg;
3087 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3088 int bhint = Assembler::bhintNoHint;
3089
3090 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3091 if (_prob <= PROB_NEVER) {
3092 bhint = Assembler::bhintIsNotTaken;
3093 } else if (_prob >= PROB_ALWAYS) {
3094 bhint = Assembler::bhintIsTaken;
3095 }
3096 }
3097
3098 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3099 cc_to_biint(cc, flags_reg),
3100 l);
3101 %}
3102
3103 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3104 // The scheduler doesn't know about branch shortening, so we set the opcode
3105 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3106 Label d; // dummy
3107 __ bind(d);
3108 Label* p = ($lbl$$label);
3109 // `p' is `nullptr' when this encoding class is used only to
3110 // determine the size of the encoded instruction.
3111 Label& l = (nullptr == p)? d : *(p);
3112 int cc = $cmp$$cmpcode;
3113 int flags_reg = $crx$$reg;
3114 int bhint = Assembler::bhintNoHint;
3115
3116 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3117 if (_prob <= PROB_NEVER) {
3118 bhint = Assembler::bhintIsNotTaken;
3119 } else if (_prob >= PROB_ALWAYS) {
3120 bhint = Assembler::bhintIsTaken;
3121 }
3122 }
3123
3124 // Tell the conditional far branch to optimize itself when being relocated.
3125 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3126 cc_to_biint(cc, flags_reg),
3127 l,
3128 MacroAssembler::bc_far_optimize_on_relocate);
3129 %}
3130
3131 // Postalloc expand emitter for loading a replicatef float constant from
3132 // the method's TOC.
3133 // Enc_class needed as consttanttablebase is not supported by postalloc
3134 // expand.
3135 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3136 // Create new nodes.
3137
3138 // Make an operand with the bit pattern to load as float.
3139 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3140
3141 loadConLNodesTuple loadConLNodes =
3142 loadConLNodesTuple_create(ra_, n_toc, op_repl,
3143 ra_->get_reg_second(this), ra_->get_reg_first(this));
3144
3145 // Push new nodes.
3146 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3147 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3148
3149 assert(nodes->length() >= 1, "must have created at least 1 node");
3150 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3151 %}
3152
3153 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{
3154 // Create new nodes.
3155
3156 // Make an operand with the bit pattern to load as float.
3157 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3158 immI_0Oper *op_zero = new immI_0Oper(0);
3159
3160 loadConLReplicatedNodesTuple loadConLNodes =
3161 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero,
3162 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp),
3163 ra_->get_reg_second(this), ra_->get_reg_first(this));
3164
3165 // Push new nodes.
3166 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); }
3167 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); }
3168 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); }
3169 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); }
3170
3171 assert(nodes->length() >= 1, "must have created at least 1 node");
3172 %}
3173
3174 // This enc_class is needed so that scheduler gets proper
3175 // input mapping for latency computation.
3176 enc_class enc_poll(immI dst, iRegLdst poll) %{
3177 // Fake operand dst needed for PPC scheduler.
3178 assert($dst$$constant == 0x0, "dst must be 0x0");
3179
3180 // Mark the code position where the load from the safepoint
3181 // polling page was emitted as relocInfo::poll_type.
3182 __ relocate(relocInfo::poll_type);
3183 __ load_from_polling_page($poll$$Register);
3184 %}
3185
3186 // A Java static call or a runtime call.
3187 //
3188 // Branch-and-link relative to a trampoline.
3189 // The trampoline loads the target address and does a long branch to there.
3190 // In case we call java, the trampoline branches to a interpreter_stub
3191 // which loads the inline cache and the real call target from the constant pool.
3192 //
3193 // This basically looks like this:
3194 //
3195 // >>>> consts -+ -+
3196 // | |- offset1
3197 // [call target1] | <-+
3198 // [IC cache] |- offset2
3199 // [call target2] <--+
3200 //
3201 // <<<< consts
3202 // >>>> insts
3203 //
3204 // bl offset16 -+ -+ ??? // How many bits available?
3205 // | |
3206 // <<<< insts | |
3207 // >>>> stubs | |
3208 // | |- trampoline_stub_Reloc
3209 // trampoline stub: | <-+
3210 // r2 = toc |
3211 // r2 = [r2 + offset1] | // Load call target1 from const section
3212 // mtctr r2 |
3213 // bctr |- static_stub_Reloc
3214 // comp_to_interp_stub: <---+
3215 // r1 = toc
3216 // ICreg = [r1 + IC_offset] // Load IC from const section
3217 // r1 = [r1 + offset2] // Load call target2 from const section
3218 // mtctr r1
3219 // bctr
3220 //
3221 // <<<< stubs
3222 //
3223 // The call instruction in the code either
3224 // - Branches directly to a compiled method if the offset is encodable in instruction.
3225 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3226 // - Branches to the compiled_to_interp stub if the target is interpreted.
3227 //
3228 // Further there are three relocations from the loads to the constants in
3229 // the constant section.
3230 //
3231 // Usage of r1 and r2 in the stubs allows to distinguish them.
3232 enc_class enc_java_static_call(method meth) %{
3233 address entry_point = (address)$meth$$method;
3234 address call_pc;
3235
3236 if (!_method) {
3237 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3238 call_pc = __ trampoline_call(AddressLiteral(entry_point, relocInfo::runtime_call_type));
3239 if (call_pc == nullptr) {
3240 ciEnv::current()->record_failure("CodeCache is full");
3241 return;
3242 }
3243 } else {
3244 int method_index = resolved_method_index(masm);
3245 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3246 : static_call_Relocation::spec(method_index);
3247 call_pc = __ trampoline_call(AddressLiteral(entry_point, rspec));
3248 if (call_pc == nullptr) {
3249 ciEnv::current()->record_failure("CodeCache is full");
3250 return;
3251 }
3252
3253 // Emit stub for static call
3254 address stub = CompiledDirectCall::emit_to_interp_stub(masm, call_pc);
3255 if (stub == nullptr) {
3256 ciEnv::current()->record_failure("CodeCache is full");
3257 return;
3258 }
3259 }
3260 __ post_call_nop();
3261 %}
3262
3263 // Compound version of call dynamic
3264 // Toc is only passed so that it can be used in ins_encode statement.
3265 // In the code we have to use $constanttablebase.
3266 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
3267 int start_offset = __ offset();
3268 int method_index = resolved_method_index(masm);
3269 bool scratch_emit = ra_ == nullptr;
3270 Register Rtoc = scratch_emit ? R2_TOC : $constanttablebase;
3271 bool success = __ ic_call(Rtoc, (address)$meth$$method, method_index, scratch_emit, true /*fixed_size*/);
3272 if (!success) {
3273 ciEnv::current()->record_failure("CodeCache is full");
3274 return;
3275 }
3276 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3277 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3278 __ post_call_nop();
3279 %}
3280
3281 // a runtime call
3282 enc_class enc_java_to_runtime_call (method meth) %{
3283 const address start_pc = __ pc();
3284
3285 #if defined(ABI_ELFv2)
3286 address entry= !($meth$$method) ? nullptr : (address)$meth$$method;
3287 __ call_c(entry, relocInfo::runtime_call_type);
3288 __ post_call_nop();
3289 #else
3290 // The function we're going to call.
3291 FunctionDescriptor fdtemp;
3292 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3293
3294 Register Rtoc = R12_scratch2;
3295 // Calculate the method's TOC.
3296 __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3297 // Put entry, env, toc into the constant pool, this needs up to 3 constant
3298 // pool entries; call_c_using_toc will optimize the call.
3299 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3300 if (!success) {
3301 ciEnv::current()->record_out_of_memory_failure();
3302 return;
3303 }
3304 __ post_call_nop();
3305 #endif
3306
3307 // Check the ret_addr_offset.
3308 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3309 "Fix constant in ret_addr_offset()");
3310 %}
3311
3312 // Move to ctr for leaf call.
3313 // This enc_class is needed so that scheduler gets proper
3314 // input mapping for latency computation.
3315 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3316 __ mtctr($src$$Register);
3317 %}
3318
3319 // Postalloc expand emitter for runtime leaf calls.
3320 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3321 loadConLNodesTuple loadConLNodes_Entry;
3322 #if defined(ABI_ELFv2)
3323 jlong entry_address = (jlong) this->entry_point();
3324 assert(entry_address, "need address here");
3325 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3326 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3327 #else
3328 // Get the struct that describes the function we are about to call.
3329 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3330 assert(fd, "need fd here");
3331 jlong entry_address = (jlong) fd->entry();
3332 // new nodes
3333 loadConLNodesTuple loadConLNodes_Env;
3334 loadConLNodesTuple loadConLNodes_Toc;
3335
3336 // Create nodes and operands for loading the entry point.
3337 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3338 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3339
3340
3341 // Create nodes and operands for loading the env pointer.
3342 if (fd->env() != nullptr) {
3343 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3344 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3345 } else {
3346 loadConLNodes_Env._large_hi = nullptr;
3347 loadConLNodes_Env._large_lo = nullptr;
3348 loadConLNodes_Env._small = nullptr;
3349 loadConLNodes_Env._last = new loadConL16Node();
3350 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3351 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3352 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3353 }
3354
3355 // Create nodes and operands for loading the Toc point.
3356 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3357 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3358 #endif // ABI_ELFv2
3359 // mtctr node
3360 MachNode *mtctr = new CallLeafDirect_mtctrNode();
3361
3362 assert(loadConLNodes_Entry._last != nullptr, "entry must exist");
3363 mtctr->add_req(nullptr, loadConLNodes_Entry._last);
3364
3365 mtctr->_opnds[0] = new iRegLdstOper();
3366 mtctr->_opnds[1] = new iRegLdstOper();
3367
3368 // call node
3369 MachCallLeafNode *call = new CallLeafDirectNode();
3370
3371 call->_opnds[0] = _opnds[0];
3372 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3373
3374 // Make the new call node look like the old one.
3375 call->_name = _name;
3376 call->_tf = _tf;
3377 call->_entry_point = _entry_point;
3378 call->_cnt = _cnt;
3379 call->_guaranteed_safepoint = false;
3380 call->_oop_map = _oop_map;
3381 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3382 call->_jvms = nullptr;
3383 call->_jvmadj = _jvmadj;
3384 call->_in_rms = _in_rms;
3385 call->_nesting = _nesting;
3386
3387 // New call needs all inputs of old call.
3388 // Req...
3389 for (uint i = 0; i < req(); ++i) {
3390 if (i != mach_constant_base_node_input()) {
3391 call->add_req(in(i));
3392 }
3393 }
3394
3395 // These must be reqired edges, as the registers are live up to
3396 // the call. Else the constants are handled as kills.
3397 call->add_req(mtctr);
3398 #if !defined(ABI_ELFv2)
3399 call->add_req(loadConLNodes_Env._last);
3400 call->add_req(loadConLNodes_Toc._last);
3401 #endif
3402
3403 // ...as well as prec
3404 for (uint i = req(); i < len(); ++i) {
3405 call->add_prec(in(i));
3406 }
3407
3408 // registers
3409 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3410
3411 // Insert the new nodes.
3412 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3413 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last);
3414 #if !defined(ABI_ELFv2)
3415 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi);
3416 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last);
3417 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi);
3418 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last);
3419 #endif
3420 nodes->push(mtctr);
3421 nodes->push(call);
3422 %}
3423 %}
3424
3425 //----------FRAME--------------------------------------------------------------
3426 // Definition of frame structure and management information.
3427
3428 frame %{
3429 // These two registers define part of the calling convention between
3430 // compiled code and the interpreter.
3431
3432 // Inline Cache Register or method for I2C.
3433 inline_cache_reg(R19); // R19_method
3434
3435 // Optional: name the operand used by cisc-spilling to access
3436 // [stack_pointer + offset].
3437 cisc_spilling_operand_name(indOffset);
3438
3439 // Number of stack slots consumed by a Monitor enter.
3440 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size));
3441
3442 // Compiled code's Frame Pointer.
3443 frame_pointer(R1); // R1_SP
3444
3445 stack_alignment(frame::alignment_in_bytes);
3446
3447 // Number of outgoing stack slots killed above the
3448 // out_preserve_stack_slots for calls to C. Supports the var-args
3449 // backing area for register parms.
3450 //
3451 varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3452
3453 // The after-PROLOG location of the return address. Location of
3454 // return address specifies a type (REG or STACK) and a number
3455 // representing the register number (i.e. - use a register name) or
3456 // stack slot.
3457 //
3458 // A: Link register is stored in stack slot ...
3459 // M: ... but it's in the caller's frame according to PPC-64 ABI.
3460 // J: Therefore, we make sure that the link register is also in R11_scratch1
3461 // at the end of the prolog.
3462 // B: We use R20, now.
3463 //return_addr(REG R20);
3464
3465 // G: After reading the comments made by all the luminaries on their
3466 // failure to tell the compiler where the return address really is,
3467 // I hardly dare to try myself. However, I'm convinced it's in slot
3468 // 4 what apparently works and saves us some spills.
3469 return_addr(STACK 4);
3470
3471 // Location of compiled Java return values. Same as C
3472 return_value %{
3473 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3474 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3475 "only return normal values");
3476 // enum names from opcodes.hpp
3477 static int typeToRegLo[Op_RegL+1] = {
3478 0, // Op_Node
3479 0, // Op_Set
3480 R3_num, // Op_RegN
3481 R3_num, // Op_RegI
3482 R3_num, // Op_RegP
3483 F1_num, // Op_RegF
3484 F1_num, // Op_RegD
3485 R3_num, // Op_RegL
3486 };
3487
3488 static int typeToRegHi[Op_RegL+1] = {
3489 0, // Op_Node
3490 0, // Op_Set
3491 OptoReg::Bad, // Op_RegN
3492 OptoReg::Bad, // Op_RegI
3493 R3_H_num, // Op_RegP
3494 OptoReg::Bad, // Op_RegF
3495 F1_H_num, // Op_RegD
3496 R3_H_num // Op_RegL
3497 };
3498
3499 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3500 %}
3501 %}
3502
3503
3504 //----------ATTRIBUTES---------------------------------------------------------
3505
3506 //----------Operand Attributes-------------------------------------------------
3507 op_attrib op_cost(1); // Required cost attribute.
3508
3509 //----------Instruction Attributes---------------------------------------------
3510
3511 // Cost attribute. required.
3512 ins_attrib ins_cost(DEFAULT_COST);
3513
3514 // Is this instruction a non-matching short branch variant of some
3515 // long branch? Not required.
3516 ins_attrib ins_short_branch(0);
3517
3518 ins_attrib ins_is_TrapBasedCheckNode(true);
3519
3520 // Number of constants.
3521 // This instruction uses the given number of constants
3522 // (optional attribute).
3523 // This is needed to determine in time whether the constant pool will
3524 // exceed 4000 entries. Before postalloc_expand the overall number of constants
3525 // is determined. It's also used to compute the constant pool size
3526 // in Output().
3527 ins_attrib ins_num_consts(0);
3528
3529 // Required alignment attribute (must be a power of 2) specifies the
3530 // alignment that some part of the instruction (not necessarily the
3531 // start) requires. If > 1, a compute_padding() function must be
3532 // provided for the instruction.
3533 ins_attrib ins_alignment(1);
3534
3535 // Enforce/prohibit rematerializations.
3536 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3537 // then rematerialization of that instruction is prohibited and the
3538 // instruction's value will be spilled if necessary.
3539 // Causes that MachNode::rematerialize() returns false.
3540 // - If an instruction is attributed with 'ins_should_rematerialize(true)'
3541 // then rematerialization should be enforced and a copy of the instruction
3542 // should be inserted if possible; rematerialization is not guaranteed.
3543 // Note: this may result in rematerializations in front of every use.
3544 // Causes that MachNode::rematerialize() can return true.
3545 // (optional attribute)
3546 ins_attrib ins_cannot_rematerialize(false);
3547 ins_attrib ins_should_rematerialize(false);
3548
3549 // Instruction is a nop.
3550 ins_attrib ins_is_nop(false);
3551
3552 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock).
3553 ins_attrib ins_use_mach_if_fast_lock_node(false);
3554
3555 // Field for the toc offset of a constant.
3556 //
3557 // This is needed if the toc offset is not encodable as an immediate in
3558 // the PPC load instruction. If so, the upper (hi) bits of the offset are
3559 // added to the toc, and from this a load with immediate is performed.
3560 // With postalloc expand, we get two nodes that require the same offset
3561 // but which don't know about each other. The offset is only known
3562 // when the constant is added to the constant pool during emitting.
3563 // It is generated in the 'hi'-node adding the upper bits, and saved
3564 // in this node. The 'lo'-node has a link to the 'hi'-node and reads
3565 // the offset from there when it gets encoded.
3566 ins_attrib ins_field_const_toc_offset(0);
3567 ins_attrib ins_field_const_toc_offset_hi_node(0);
3568
3569 // A field that can hold the instructions offset in the code buffer.
3570 // Set in the nodes emitter.
3571 ins_attrib ins_field_cbuf_insts_offset(-1);
3572
3573 // Fields for referencing a call's load-IC-node.
3574 // If the toc offset can not be encoded as an immediate in a load, we
3575 // use two nodes.
3576 ins_attrib ins_field_load_ic_hi_node(0);
3577 ins_attrib ins_field_load_ic_node(0);
3578
3579 // Whether this node is expanded during code emission into a sequence of
3580 // instructions and the first instruction can perform an implicit null check.
3581 ins_attrib ins_is_late_expanded_null_check_candidate(false);
3582
3583 //----------OPERANDS-----------------------------------------------------------
3584 // Operand definitions must precede instruction definitions for correct
3585 // parsing in the ADLC because operands constitute user defined types
3586 // which are used in instruction definitions.
3587 //
3588 // Formats are generated automatically for constants and base registers.
3589
3590 operand vecX() %{
3591 constraint(ALLOC_IN_RC(v_reg));
3592 match(VecX);
3593
3594 format %{ %}
3595 interface(REG_INTER);
3596 %}
3597
3598 //----------Simple Operands----------------------------------------------------
3599 // Immediate Operands
3600
3601 // Integer Immediate: 32-bit
3602 operand immI() %{
3603 match(ConI);
3604 op_cost(40);
3605 format %{ %}
3606 interface(CONST_INTER);
3607 %}
3608
3609 operand immI8() %{
3610 predicate(Assembler::is_simm(n->get_int(), 8));
3611 op_cost(0);
3612 match(ConI);
3613 format %{ %}
3614 interface(CONST_INTER);
3615 %}
3616
3617 // Integer Immediate: 16-bit
3618 operand immI16() %{
3619 predicate(Assembler::is_simm(n->get_int(), 16));
3620 op_cost(0);
3621 match(ConI);
3622 format %{ %}
3623 interface(CONST_INTER);
3624 %}
3625
3626 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000.
3627 operand immIhi16() %{
3628 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0));
3629 match(ConI);
3630 op_cost(0);
3631 format %{ %}
3632 interface(CONST_INTER);
3633 %}
3634
3635 // Integer Immediate: 32-bit immediate for prefixed addi and load/store.
3636 operand immI32() %{
3637 predicate(PowerArchitecturePPC64 >= 10);
3638 op_cost(0);
3639 match(ConI);
3640 format %{ %}
3641 interface(CONST_INTER);
3642 %}
3643
3644 operand immInegpow2() %{
3645 predicate(is_power_of_2(-(juint)(n->get_int())));
3646 match(ConI);
3647 op_cost(0);
3648 format %{ %}
3649 interface(CONST_INTER);
3650 %}
3651
3652 operand immIpow2minus1() %{
3653 predicate(is_power_of_2((juint)(n->get_int()) + 1u));
3654 match(ConI);
3655 op_cost(0);
3656 format %{ %}
3657 interface(CONST_INTER);
3658 %}
3659
3660 operand immIpowerOf2() %{
3661 predicate(is_power_of_2((juint)(n->get_int())));
3662 match(ConI);
3663 op_cost(0);
3664 format %{ %}
3665 interface(CONST_INTER);
3666 %}
3667
3668 // Unsigned Integer Immediate: the values 0-31
3669 operand uimmI5() %{
3670 predicate(Assembler::is_uimm(n->get_int(), 5));
3671 match(ConI);
3672 op_cost(0);
3673 format %{ %}
3674 interface(CONST_INTER);
3675 %}
3676
3677 // Unsigned Integer Immediate: 6-bit
3678 operand uimmI6() %{
3679 predicate(Assembler::is_uimm(n->get_int(), 6));
3680 match(ConI);
3681 op_cost(0);
3682 format %{ %}
3683 interface(CONST_INTER);
3684 %}
3685
3686 // Unsigned Integer Immediate: 6-bit int, greater than 32
3687 operand uimmI6_ge32() %{
3688 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32);
3689 match(ConI);
3690 op_cost(0);
3691 format %{ %}
3692 interface(CONST_INTER);
3693 %}
3694
3695 // Unsigned Integer Immediate: 15-bit
3696 operand uimmI15() %{
3697 predicate(Assembler::is_uimm(n->get_int(), 15));
3698 match(ConI);
3699 op_cost(0);
3700 format %{ %}
3701 interface(CONST_INTER);
3702 %}
3703
3704 // Unsigned Integer Immediate: 16-bit
3705 operand uimmI16() %{
3706 predicate(Assembler::is_uimm(n->get_int(), 16));
3707 match(ConI);
3708 op_cost(0);
3709 format %{ %}
3710 interface(CONST_INTER);
3711 %}
3712
3713 // constant 'int 0'.
3714 operand immI_0() %{
3715 predicate(n->get_int() == 0);
3716 match(ConI);
3717 op_cost(0);
3718 format %{ %}
3719 interface(CONST_INTER);
3720 %}
3721
3722 // constant 'int 1'.
3723 operand immI_1() %{
3724 predicate(n->get_int() == 1);
3725 match(ConI);
3726 op_cost(0);
3727 format %{ %}
3728 interface(CONST_INTER);
3729 %}
3730
3731 // constant 'int -1'.
3732 operand immI_minus1() %{
3733 predicate(n->get_int() == -1);
3734 match(ConI);
3735 op_cost(0);
3736 format %{ %}
3737 interface(CONST_INTER);
3738 %}
3739
3740 // int value 16.
3741 operand immI_16() %{
3742 predicate(n->get_int() == 16);
3743 match(ConI);
3744 op_cost(0);
3745 format %{ %}
3746 interface(CONST_INTER);
3747 %}
3748
3749 // int value 24.
3750 operand immI_24() %{
3751 predicate(n->get_int() == 24);
3752 match(ConI);
3753 op_cost(0);
3754 format %{ %}
3755 interface(CONST_INTER);
3756 %}
3757
3758 // Compressed oops constants
3759 // Pointer Immediate
3760 operand immN() %{
3761 match(ConN);
3762
3763 op_cost(10);
3764 format %{ %}
3765 interface(CONST_INTER);
3766 %}
3767
3768 // nullptr Pointer Immediate
3769 operand immN_0() %{
3770 predicate(n->get_narrowcon() == 0);
3771 match(ConN);
3772
3773 op_cost(0);
3774 format %{ %}
3775 interface(CONST_INTER);
3776 %}
3777
3778 // Compressed klass constants
3779 operand immNKlass() %{
3780 match(ConNKlass);
3781
3782 op_cost(0);
3783 format %{ %}
3784 interface(CONST_INTER);
3785 %}
3786
3787 // This operand can be used to avoid matching of an instruct
3788 // with chain rule.
3789 operand immNKlass_NM() %{
3790 match(ConNKlass);
3791 predicate(false);
3792 op_cost(0);
3793 format %{ %}
3794 interface(CONST_INTER);
3795 %}
3796
3797 // Pointer Immediate: 64-bit
3798 operand immP() %{
3799 match(ConP);
3800 op_cost(0);
3801 format %{ %}
3802 interface(CONST_INTER);
3803 %}
3804
3805 // Operand to avoid match of loadConP.
3806 // This operand can be used to avoid matching of an instruct
3807 // with chain rule.
3808 operand immP_NM() %{
3809 match(ConP);
3810 predicate(false);
3811 op_cost(0);
3812 format %{ %}
3813 interface(CONST_INTER);
3814 %}
3815
3816 // constant 'pointer 0'.
3817 operand immP_0() %{
3818 predicate(n->get_ptr() == 0);
3819 match(ConP);
3820 op_cost(0);
3821 format %{ %}
3822 interface(CONST_INTER);
3823 %}
3824
3825 // pointer 0x0 or 0x1
3826 operand immP_0or1() %{
3827 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
3828 match(ConP);
3829 op_cost(0);
3830 format %{ %}
3831 interface(CONST_INTER);
3832 %}
3833
3834 operand immL() %{
3835 match(ConL);
3836 op_cost(40);
3837 format %{ %}
3838 interface(CONST_INTER);
3839 %}
3840
3841 operand immLmax30() %{
3842 predicate((n->get_long() <= 30));
3843 match(ConL);
3844 op_cost(0);
3845 format %{ %}
3846 interface(CONST_INTER);
3847 %}
3848
3849 // Long Immediate: 16-bit
3850 operand immL16() %{
3851 predicate(Assembler::is_simm(n->get_long(), 16));
3852 match(ConL);
3853 op_cost(0);
3854 format %{ %}
3855 interface(CONST_INTER);
3856 %}
3857
3858 // Long Immediate: 16-bit, 4-aligned
3859 operand immL16Alg4() %{
3860 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
3861 match(ConL);
3862 op_cost(0);
3863 format %{ %}
3864 interface(CONST_INTER);
3865 %}
3866
3867 // Long Immediate: 16-bit, 16-aligned
3868 operand immL16Alg16() %{
3869 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0xf) == 0));
3870 match(ConL);
3871 op_cost(0);
3872 format %{ %}
3873 interface(CONST_INTER);
3874 %}
3875
3876 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
3877 operand immL32hi16() %{
3878 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L));
3879 match(ConL);
3880 op_cost(0);
3881 format %{ %}
3882 interface(CONST_INTER);
3883 %}
3884
3885 // Long Immediate: 32-bit
3886 operand immL32() %{
3887 predicate(Assembler::is_simm(n->get_long(), 32));
3888 match(ConL);
3889 op_cost(0);
3890 format %{ %}
3891 interface(CONST_INTER);
3892 %}
3893
3894 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store.
3895 operand immL34() %{
3896 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34));
3897 match(ConL);
3898 op_cost(0);
3899 format %{ %}
3900 interface(CONST_INTER);
3901 %}
3902
3903 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000.
3904 operand immLhighest16() %{
3905 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L);
3906 match(ConL);
3907 op_cost(0);
3908 format %{ %}
3909 interface(CONST_INTER);
3910 %}
3911
3912 operand immLnegpow2() %{
3913 predicate(is_power_of_2(-(julong)(n->get_long())));
3914 match(ConL);
3915 op_cost(0);
3916 format %{ %}
3917 interface(CONST_INTER);
3918 %}
3919
3920 operand immLpow2minus1() %{
3921 predicate(is_power_of_2((julong)(n->get_long()) + 1ull));
3922 match(ConL);
3923 op_cost(0);
3924 format %{ %}
3925 interface(CONST_INTER);
3926 %}
3927
3928 // constant 'long 0'.
3929 operand immL_0() %{
3930 predicate(n->get_long() == 0L);
3931 match(ConL);
3932 op_cost(0);
3933 format %{ %}
3934 interface(CONST_INTER);
3935 %}
3936
3937 // constat ' long -1'.
3938 operand immL_minus1() %{
3939 predicate(n->get_long() == -1L);
3940 match(ConL);
3941 op_cost(0);
3942 format %{ %}
3943 interface(CONST_INTER);
3944 %}
3945
3946 // Long Immediate: low 32-bit mask
3947 operand immL_32bits() %{
3948 predicate(n->get_long() == 0xFFFFFFFFL);
3949 match(ConL);
3950 op_cost(0);
3951 format %{ %}
3952 interface(CONST_INTER);
3953 %}
3954
3955 // Unsigned Long Immediate: 16-bit
3956 operand uimmL16() %{
3957 predicate(Assembler::is_uimm(n->get_long(), 16));
3958 match(ConL);
3959 op_cost(0);
3960 format %{ %}
3961 interface(CONST_INTER);
3962 %}
3963
3964 // Float Immediate
3965 operand immF() %{
3966 match(ConF);
3967 op_cost(40);
3968 format %{ %}
3969 interface(CONST_INTER);
3970 %}
3971
3972 // Float Immediate: +0.0f.
3973 operand immF_0() %{
3974 predicate(jint_cast(n->getf()) == 0);
3975 match(ConF);
3976
3977 op_cost(0);
3978 format %{ %}
3979 interface(CONST_INTER);
3980 %}
3981
3982 // Double Immediate
3983 operand immD() %{
3984 match(ConD);
3985 op_cost(40);
3986 format %{ %}
3987 interface(CONST_INTER);
3988 %}
3989
3990 // Double Immediate: +0.0d.
3991 operand immD_0() %{
3992 predicate(jlong_cast(n->getd()) == 0);
3993 match(ConD);
3994
3995 op_cost(0);
3996 format %{ %}
3997 interface(CONST_INTER);
3998 %}
3999
4000 // Integer Register Operands
4001 // Integer Destination Register
4002 // See definition of reg_class bits32_reg_rw.
4003 operand iRegIdst() %{
4004 constraint(ALLOC_IN_RC(bits32_reg_rw));
4005 match(RegI);
4006 match(rscratch1RegI);
4007 match(rscratch2RegI);
4008 match(rarg1RegI);
4009 match(rarg2RegI);
4010 match(rarg3RegI);
4011 match(rarg4RegI);
4012 format %{ %}
4013 interface(REG_INTER);
4014 %}
4015
4016 // Integer Source Register
4017 // See definition of reg_class bits32_reg_ro.
4018 operand iRegIsrc() %{
4019 constraint(ALLOC_IN_RC(bits32_reg_ro));
4020 match(RegI);
4021 match(rscratch1RegI);
4022 match(rscratch2RegI);
4023 match(rarg1RegI);
4024 match(rarg2RegI);
4025 match(rarg3RegI);
4026 match(rarg4RegI);
4027 format %{ %}
4028 interface(REG_INTER);
4029 %}
4030
4031 operand rscratch1RegI() %{
4032 constraint(ALLOC_IN_RC(rscratch1_bits32_reg));
4033 match(iRegIdst);
4034 format %{ %}
4035 interface(REG_INTER);
4036 %}
4037
4038 operand rscratch2RegI() %{
4039 constraint(ALLOC_IN_RC(rscratch2_bits32_reg));
4040 match(iRegIdst);
4041 format %{ %}
4042 interface(REG_INTER);
4043 %}
4044
4045 operand rarg1RegI() %{
4046 constraint(ALLOC_IN_RC(rarg1_bits32_reg));
4047 match(iRegIdst);
4048 format %{ %}
4049 interface(REG_INTER);
4050 %}
4051
4052 operand rarg2RegI() %{
4053 constraint(ALLOC_IN_RC(rarg2_bits32_reg));
4054 match(iRegIdst);
4055 format %{ %}
4056 interface(REG_INTER);
4057 %}
4058
4059 operand rarg3RegI() %{
4060 constraint(ALLOC_IN_RC(rarg3_bits32_reg));
4061 match(iRegIdst);
4062 format %{ %}
4063 interface(REG_INTER);
4064 %}
4065
4066 operand rarg4RegI() %{
4067 constraint(ALLOC_IN_RC(rarg4_bits32_reg));
4068 match(iRegIdst);
4069 format %{ %}
4070 interface(REG_INTER);
4071 %}
4072
4073 operand rarg1RegL() %{
4074 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4075 match(iRegLdst);
4076 format %{ %}
4077 interface(REG_INTER);
4078 %}
4079
4080 // Pointer Destination Register
4081 // See definition of reg_class bits64_reg_rw.
4082 operand iRegPdst() %{
4083 constraint(ALLOC_IN_RC(bits64_reg_rw));
4084 match(RegP);
4085 match(rscratch1RegP);
4086 match(rscratch2RegP);
4087 match(rarg1RegP);
4088 match(rarg2RegP);
4089 match(rarg3RegP);
4090 match(rarg4RegP);
4091 format %{ %}
4092 interface(REG_INTER);
4093 %}
4094
4095 // Pointer Destination Register
4096 // Operand not using r11 and r12 (killed in epilog).
4097 operand iRegPdstNoScratch() %{
4098 constraint(ALLOC_IN_RC(bits64_reg_leaf_call));
4099 match(RegP);
4100 match(rarg1RegP);
4101 match(rarg2RegP);
4102 match(rarg3RegP);
4103 match(rarg4RegP);
4104 format %{ %}
4105 interface(REG_INTER);
4106 %}
4107
4108 // Pointer Source Register
4109 // See definition of reg_class bits64_reg_ro.
4110 operand iRegPsrc() %{
4111 constraint(ALLOC_IN_RC(bits64_reg_ro));
4112 match(RegP);
4113 match(iRegPdst);
4114 match(rscratch1RegP);
4115 match(rscratch2RegP);
4116 match(rarg1RegP);
4117 match(rarg2RegP);
4118 match(rarg3RegP);
4119 match(rarg4RegP);
4120 match(rarg5RegP);
4121 match(rarg6RegP);
4122 match(threadRegP);
4123 format %{ %}
4124 interface(REG_INTER);
4125 %}
4126
4127 // Thread operand.
4128 operand threadRegP() %{
4129 constraint(ALLOC_IN_RC(thread_bits64_reg));
4130 match(iRegPdst);
4131 format %{ "R16" %}
4132 interface(REG_INTER);
4133 %}
4134
4135 operand rscratch1RegP() %{
4136 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4137 match(iRegPdst);
4138 format %{ "R11" %}
4139 interface(REG_INTER);
4140 %}
4141
4142 operand rscratch2RegP() %{
4143 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4144 match(iRegPdst);
4145 format %{ %}
4146 interface(REG_INTER);
4147 %}
4148
4149 operand rarg1RegP() %{
4150 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4151 match(iRegPdst);
4152 format %{ %}
4153 interface(REG_INTER);
4154 %}
4155
4156 operand rarg2RegP() %{
4157 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4158 match(iRegPdst);
4159 format %{ %}
4160 interface(REG_INTER);
4161 %}
4162
4163 operand rarg3RegP() %{
4164 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4165 match(iRegPdst);
4166 format %{ %}
4167 interface(REG_INTER);
4168 %}
4169
4170 operand rarg4RegP() %{
4171 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4172 match(iRegPdst);
4173 format %{ %}
4174 interface(REG_INTER);
4175 %}
4176
4177 operand rarg5RegP() %{
4178 constraint(ALLOC_IN_RC(rarg5_bits64_reg));
4179 match(iRegPdst);
4180 format %{ %}
4181 interface(REG_INTER);
4182 %}
4183
4184 operand rarg6RegP() %{
4185 constraint(ALLOC_IN_RC(rarg6_bits64_reg));
4186 match(iRegPdst);
4187 format %{ %}
4188 interface(REG_INTER);
4189 %}
4190
4191 operand iRegNsrc() %{
4192 constraint(ALLOC_IN_RC(bits32_reg_ro));
4193 match(RegN);
4194 match(iRegNdst);
4195
4196 format %{ %}
4197 interface(REG_INTER);
4198 %}
4199
4200 operand iRegNdst() %{
4201 constraint(ALLOC_IN_RC(bits32_reg_rw));
4202 match(RegN);
4203
4204 format %{ %}
4205 interface(REG_INTER);
4206 %}
4207
4208 // Long Destination Register
4209 // See definition of reg_class bits64_reg_rw.
4210 operand iRegLdst() %{
4211 constraint(ALLOC_IN_RC(bits64_reg_rw));
4212 match(RegL);
4213 match(rscratch1RegL);
4214 match(rscratch2RegL);
4215 format %{ %}
4216 interface(REG_INTER);
4217 %}
4218
4219 // Long Source Register
4220 // See definition of reg_class bits64_reg_ro.
4221 operand iRegLsrc() %{
4222 constraint(ALLOC_IN_RC(bits64_reg_ro));
4223 match(RegL);
4224 match(iRegLdst);
4225 match(rscratch1RegL);
4226 match(rscratch2RegL);
4227 format %{ %}
4228 interface(REG_INTER);
4229 %}
4230
4231 // Special operand for ConvL2I.
4232 operand iRegL2Isrc(iRegLsrc reg) %{
4233 constraint(ALLOC_IN_RC(bits64_reg_ro));
4234 match(ConvL2I reg);
4235 format %{ "ConvL2I($reg)" %}
4236 interface(REG_INTER)
4237 %}
4238
4239 operand rscratch1RegL() %{
4240 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4241 match(RegL);
4242 format %{ %}
4243 interface(REG_INTER);
4244 %}
4245
4246 operand rscratch2RegL() %{
4247 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4248 match(RegL);
4249 format %{ %}
4250 interface(REG_INTER);
4251 %}
4252
4253 // Condition Code Flag Registers
4254 operand flagsReg() %{
4255 constraint(ALLOC_IN_RC(int_flags));
4256 match(RegFlags);
4257 format %{ %}
4258 interface(REG_INTER);
4259 %}
4260
4261 operand flagsRegSrc() %{
4262 constraint(ALLOC_IN_RC(int_flags_ro));
4263 match(RegFlags);
4264 match(flagsReg);
4265 match(flagsRegCR0);
4266 format %{ %}
4267 interface(REG_INTER);
4268 %}
4269
4270 // Condition Code Flag Register CR0
4271 operand flagsRegCR0() %{
4272 constraint(ALLOC_IN_RC(int_flags_CR0));
4273 match(RegFlags);
4274 format %{ "CR0" %}
4275 interface(REG_INTER);
4276 %}
4277
4278 operand flagsRegCR1() %{
4279 constraint(ALLOC_IN_RC(int_flags_CR1));
4280 match(RegFlags);
4281 format %{ "CR1" %}
4282 interface(REG_INTER);
4283 %}
4284
4285 operand flagsRegCR6() %{
4286 constraint(ALLOC_IN_RC(int_flags_CR6));
4287 match(RegFlags);
4288 format %{ "CR6" %}
4289 interface(REG_INTER);
4290 %}
4291
4292 operand regCTR() %{
4293 constraint(ALLOC_IN_RC(ctr_reg));
4294 // RegFlags should work. Introducing a RegSpecial type would cause a
4295 // lot of changes.
4296 match(RegFlags);
4297 format %{"SR_CTR" %}
4298 interface(REG_INTER);
4299 %}
4300
4301 operand regD() %{
4302 constraint(ALLOC_IN_RC(dbl_reg));
4303 match(RegD);
4304 format %{ %}
4305 interface(REG_INTER);
4306 %}
4307
4308 operand regF() %{
4309 constraint(ALLOC_IN_RC(flt_reg));
4310 match(RegF);
4311 format %{ %}
4312 interface(REG_INTER);
4313 %}
4314
4315 // Special Registers
4316
4317 // Method Register
4318 operand inline_cache_regP(iRegPdst reg) %{
4319 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg
4320 match(reg);
4321 format %{ %}
4322 interface(REG_INTER);
4323 %}
4324
4325 // Operands to remove register moves in unscaled mode.
4326 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4327 operand iRegP2N(iRegPsrc reg) %{
4328 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0);
4329 constraint(ALLOC_IN_RC(bits64_reg_ro));
4330 match(EncodeP reg);
4331 format %{ "$reg" %}
4332 interface(REG_INTER)
4333 %}
4334
4335 operand iRegN2P(iRegNsrc reg) %{
4336 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4337 constraint(ALLOC_IN_RC(bits32_reg_ro));
4338 match(DecodeN reg);
4339 format %{ "$reg" %}
4340 interface(REG_INTER)
4341 %}
4342
4343 operand iRegN2P_klass(iRegNsrc reg) %{
4344 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4345 constraint(ALLOC_IN_RC(bits32_reg_ro));
4346 match(DecodeNKlass reg);
4347 format %{ "$reg" %}
4348 interface(REG_INTER)
4349 %}
4350
4351 //----------Complex Operands---------------------------------------------------
4352 // Indirect Memory Reference
4353 operand indirect(iRegPsrc reg) %{
4354 constraint(ALLOC_IN_RC(bits64_reg_ro));
4355 match(reg);
4356 op_cost(100);
4357 format %{ "[$reg]" %}
4358 interface(MEMORY_INTER) %{
4359 base($reg);
4360 index(0x0);
4361 scale(0x0);
4362 disp(0x0);
4363 %}
4364 %}
4365
4366 // Indirect with Offset
4367 operand indOffset16(iRegPsrc reg, immL16 offset) %{
4368 constraint(ALLOC_IN_RC(bits64_reg_ro));
4369 match(AddP reg offset);
4370 op_cost(100);
4371 format %{ "[$reg + $offset]" %}
4372 interface(MEMORY_INTER) %{
4373 base($reg);
4374 index(0x0);
4375 scale(0x0);
4376 disp($offset);
4377 %}
4378 %}
4379
4380 // Indirect with 4-aligned Offset
4381 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{
4382 constraint(ALLOC_IN_RC(bits64_reg_ro));
4383 match(AddP reg offset);
4384 op_cost(100);
4385 format %{ "[$reg + $offset]" %}
4386 interface(MEMORY_INTER) %{
4387 base($reg);
4388 index(0x0);
4389 scale(0x0);
4390 disp($offset);
4391 %}
4392 %}
4393
4394 // Indirect with 16-aligned Offset
4395 operand indOffset16Alg16(iRegPsrc reg, immL16Alg16 offset) %{
4396 constraint(ALLOC_IN_RC(bits64_reg_ro));
4397 match(AddP reg offset);
4398 op_cost(100);
4399 format %{ "[$reg + $offset]" %}
4400 interface(MEMORY_INTER) %{
4401 base($reg);
4402 index(0x0);
4403 scale(0x0);
4404 disp($offset);
4405 %}
4406 %}
4407
4408 //----------Complex Operands for Compressed OOPs-------------------------------
4409 // Compressed OOPs with narrow_oop_shift == 0.
4410
4411 // Indirect Memory Reference, compressed OOP
4412 operand indirectNarrow(iRegNsrc reg) %{
4413 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4414 constraint(ALLOC_IN_RC(bits64_reg_ro));
4415 match(DecodeN reg);
4416 op_cost(100);
4417 format %{ "[$reg]" %}
4418 interface(MEMORY_INTER) %{
4419 base($reg);
4420 index(0x0);
4421 scale(0x0);
4422 disp(0x0);
4423 %}
4424 %}
4425
4426 operand indirectNarrow_klass(iRegNsrc reg) %{
4427 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4428 constraint(ALLOC_IN_RC(bits64_reg_ro));
4429 match(DecodeNKlass reg);
4430 op_cost(100);
4431 format %{ "[$reg]" %}
4432 interface(MEMORY_INTER) %{
4433 base($reg);
4434 index(0x0);
4435 scale(0x0);
4436 disp(0x0);
4437 %}
4438 %}
4439
4440 // Indirect with Offset, compressed OOP
4441 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4442 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4443 constraint(ALLOC_IN_RC(bits64_reg_ro));
4444 match(AddP (DecodeN reg) offset);
4445 op_cost(100);
4446 format %{ "[$reg + $offset]" %}
4447 interface(MEMORY_INTER) %{
4448 base($reg);
4449 index(0x0);
4450 scale(0x0);
4451 disp($offset);
4452 %}
4453 %}
4454
4455 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4456 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4457 constraint(ALLOC_IN_RC(bits64_reg_ro));
4458 match(AddP (DecodeNKlass reg) offset);
4459 op_cost(100);
4460 format %{ "[$reg + $offset]" %}
4461 interface(MEMORY_INTER) %{
4462 base($reg);
4463 index(0x0);
4464 scale(0x0);
4465 disp($offset);
4466 %}
4467 %}
4468
4469 // Indirect with 4-aligned Offset, compressed OOP
4470 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4471 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4472 constraint(ALLOC_IN_RC(bits64_reg_ro));
4473 match(AddP (DecodeN reg) offset);
4474 op_cost(100);
4475 format %{ "[$reg + $offset]" %}
4476 interface(MEMORY_INTER) %{
4477 base($reg);
4478 index(0x0);
4479 scale(0x0);
4480 disp($offset);
4481 %}
4482 %}
4483
4484 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4485 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4486 constraint(ALLOC_IN_RC(bits64_reg_ro));
4487 match(AddP (DecodeNKlass reg) offset);
4488 op_cost(100);
4489 format %{ "[$reg + $offset]" %}
4490 interface(MEMORY_INTER) %{
4491 base($reg);
4492 index(0x0);
4493 scale(0x0);
4494 disp($offset);
4495 %}
4496 %}
4497
4498 //----------Special Memory Operands--------------------------------------------
4499 // Stack Slot Operand
4500 //
4501 // This operand is used for loading and storing temporary values on
4502 // the stack where a match requires a value to flow through memory.
4503 operand stackSlotI(sRegI reg) %{
4504 constraint(ALLOC_IN_RC(stack_slots));
4505 op_cost(100);
4506 //match(RegI);
4507 format %{ "[sp+$reg]" %}
4508 interface(MEMORY_INTER) %{
4509 base(0x1); // R1_SP
4510 index(0x0);
4511 scale(0x0);
4512 disp($reg); // Stack Offset
4513 %}
4514 %}
4515
4516 operand stackSlotL(sRegL reg) %{
4517 constraint(ALLOC_IN_RC(stack_slots));
4518 op_cost(100);
4519 //match(RegL);
4520 format %{ "[sp+$reg]" %}
4521 interface(MEMORY_INTER) %{
4522 base(0x1); // R1_SP
4523 index(0x0);
4524 scale(0x0);
4525 disp($reg); // Stack Offset
4526 %}
4527 %}
4528
4529 operand stackSlotP(sRegP reg) %{
4530 constraint(ALLOC_IN_RC(stack_slots));
4531 op_cost(100);
4532 //match(RegP);
4533 format %{ "[sp+$reg]" %}
4534 interface(MEMORY_INTER) %{
4535 base(0x1); // R1_SP
4536 index(0x0);
4537 scale(0x0);
4538 disp($reg); // Stack Offset
4539 %}
4540 %}
4541
4542 operand stackSlotF(sRegF reg) %{
4543 constraint(ALLOC_IN_RC(stack_slots));
4544 op_cost(100);
4545 //match(RegF);
4546 format %{ "[sp+$reg]" %}
4547 interface(MEMORY_INTER) %{
4548 base(0x1); // R1_SP
4549 index(0x0);
4550 scale(0x0);
4551 disp($reg); // Stack Offset
4552 %}
4553 %}
4554
4555 operand stackSlotD(sRegD reg) %{
4556 constraint(ALLOC_IN_RC(stack_slots));
4557 op_cost(100);
4558 //match(RegD);
4559 format %{ "[sp+$reg]" %}
4560 interface(MEMORY_INTER) %{
4561 base(0x1); // R1_SP
4562 index(0x0);
4563 scale(0x0);
4564 disp($reg); // Stack Offset
4565 %}
4566 %}
4567
4568 // Operands for expressing Control Flow
4569 // NOTE: Label is a predefined operand which should not be redefined in
4570 // the AD file. It is generically handled within the ADLC.
4571
4572 //----------Conditional Branch Operands----------------------------------------
4573 // Comparison Op
4574 //
4575 // This is the operation of the comparison, and is limited to the
4576 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE
4577 // (!=).
4578 //
4579 // Other attributes of the comparison, such as unsignedness, are specified
4580 // by the comparison instruction that sets a condition code flags register.
4581 // That result is represented by a flags operand whose subtype is appropriate
4582 // to the unsignedness (etc.) of the comparison.
4583 //
4584 // Later, the instruction which matches both the Comparison Op (a Bool) and
4585 // the flags (produced by the Cmp) specifies the coding of the comparison op
4586 // by matching a specific subtype of Bool operand below.
4587
4588 // When used for floating point comparisons: unordered same as less.
4589 operand cmpOp() %{
4590 match(Bool);
4591 format %{ "" %}
4592 interface(COND_INTER) %{
4593 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'.
4594 // BO & BI
4595 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4596 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4597 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4598 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4599 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4600 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4601 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4602 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4603 %}
4604 %}
4605
4606 //----------OPERAND CLASSES----------------------------------------------------
4607 // Operand Classes are groups of operands that are used to simplify
4608 // instruction definitions by not requiring the AD writer to specify
4609 // separate instructions for every form of operand when the
4610 // instruction accepts multiple operand types with the same basic
4611 // encoding and format. The classic case of this is memory operands.
4612 // Indirect is not included since its use is limited to Compare & Swap.
4613
4614 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4615 // Memory operand where offsets are 4-aligned. Required for ld, std.
4616 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4617 opclass memoryAlg16(indirect, indOffset16Alg16);
4618 opclass indirectMemory(indirect, indirectNarrow);
4619
4620 // Special opclass for I and ConvL2I.
4621 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4622
4623 // Operand classes to match encode and decode. iRegN_P2N is only used
4624 // for storeN. I have never seen an encode node elsewhere.
4625 opclass iRegN_P2N(iRegNsrc, iRegP2N);
4626 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4627
4628 //----------PIPELINE-----------------------------------------------------------
4629
4630 pipeline %{
4631
4632 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4633 // J. Res. & Dev., No. 1, Jan. 2002.
4634
4635 //----------ATTRIBUTES---------------------------------------------------------
4636 attributes %{
4637
4638 // Power4 instructions are of fixed length.
4639 fixed_size_instructions;
4640
4641 // TODO: if `bundle' means number of instructions fetched
4642 // per cycle, this is 8. If `bundle' means Power4 `group', that is
4643 // max instructions issued per cycle, this is 5.
4644 max_instructions_per_bundle = 8;
4645
4646 // A Power4 instruction is 4 bytes long.
4647 instruction_unit_size = 4;
4648
4649 // The Power4 processor fetches 64 bytes...
4650 instruction_fetch_unit_size = 64;
4651
4652 // ...in one line
4653 instruction_fetch_units = 1
4654 %}
4655
4656 //----------RESOURCES----------------------------------------------------------
4657 // Resources are the functional units available to the machine
4658 resources(
4659 PPC_BR, // branch unit
4660 PPC_CR, // condition unit
4661 PPC_FX1, // integer arithmetic unit 1
4662 PPC_FX2, // integer arithmetic unit 2
4663 PPC_LDST1, // load/store unit 1
4664 PPC_LDST2, // load/store unit 2
4665 PPC_FP1, // float arithmetic unit 1
4666 PPC_FP2, // float arithmetic unit 2
4667 PPC_LDST = PPC_LDST1 | PPC_LDST2,
4668 PPC_FX = PPC_FX1 | PPC_FX2,
4669 PPC_FP = PPC_FP1 | PPC_FP2
4670 );
4671
4672 //----------PIPELINE DESCRIPTION-----------------------------------------------
4673 // Pipeline Description specifies the stages in the machine's pipeline
4674 pipe_desc(
4675 // Power4 longest pipeline path
4676 PPC_IF, // instruction fetch
4677 PPC_IC,
4678 //PPC_BP, // branch prediction
4679 PPC_D0, // decode
4680 PPC_D1, // decode
4681 PPC_D2, // decode
4682 PPC_D3, // decode
4683 PPC_Xfer1,
4684 PPC_GD, // group definition
4685 PPC_MP, // map
4686 PPC_ISS, // issue
4687 PPC_RF, // resource fetch
4688 PPC_EX1, // execute (all units)
4689 PPC_EX2, // execute (FP, LDST)
4690 PPC_EX3, // execute (FP, LDST)
4691 PPC_EX4, // execute (FP)
4692 PPC_EX5, // execute (FP)
4693 PPC_EX6, // execute (FP)
4694 PPC_WB, // write back
4695 PPC_Xfer2,
4696 PPC_CP
4697 );
4698
4699 //----------PIPELINE CLASSES---------------------------------------------------
4700 // Pipeline Classes describe the stages in which input and output are
4701 // referenced by the hardware pipeline.
4702
4703 // Simple pipeline classes.
4704
4705 // Default pipeline class.
4706 pipe_class pipe_class_default() %{
4707 single_instruction;
4708 fixed_latency(2);
4709 %}
4710
4711 // Pipeline class for empty instructions.
4712 pipe_class pipe_class_empty() %{
4713 single_instruction;
4714 fixed_latency(0);
4715 %}
4716
4717 // Pipeline class for compares.
4718 pipe_class pipe_class_compare() %{
4719 single_instruction;
4720 fixed_latency(16);
4721 %}
4722
4723 // Pipeline class for traps.
4724 pipe_class pipe_class_trap() %{
4725 single_instruction;
4726 fixed_latency(100);
4727 %}
4728
4729 // Pipeline class for memory operations.
4730 pipe_class pipe_class_memory() %{
4731 single_instruction;
4732 fixed_latency(16);
4733 %}
4734
4735 // Pipeline class for call.
4736 pipe_class pipe_class_call() %{
4737 single_instruction;
4738 fixed_latency(100);
4739 %}
4740
4741 // Define the class for the Nop node.
4742 define %{
4743 MachNop = pipe_class_default;
4744 %}
4745
4746 %}
4747
4748 //----------INSTRUCTIONS-------------------------------------------------------
4749
4750 // Naming of instructions:
4751 // opA_operB / opA_operB_operC:
4752 // Operation 'op' with one or two source operands 'oper'. Result
4753 // type is A, source operand types are B and C.
4754 // Iff A == B == C, B and C are left out.
4755 //
4756 // The instructions are ordered according to the following scheme:
4757 // - loads
4758 // - load constants
4759 // - prefetch
4760 // - store
4761 // - encode/decode
4762 // - membar
4763 // - conditional moves
4764 // - compare & swap
4765 // - arithmetic and logic operations
4766 // * int: Add, Sub, Mul, Div, Mod
4767 // * int: lShift, arShift, urShift, rot
4768 // * float: Add, Sub, Mul, Div
4769 // * and, or, xor ...
4770 // - register moves: float <-> int, reg <-> stack, repl
4771 // - cast (high level type cast, XtoP, castPP, castII, not_null etc.
4772 // - conv (low level type cast requiring bit changes (sign extend etc)
4773 // - compares, range & zero checks.
4774 // - branches
4775 // - complex operations, intrinsics, min, max, replicate
4776 // - lock
4777 // - Calls
4778 //
4779 // If there are similar instructions with different types they are sorted:
4780 // int before float
4781 // small before big
4782 // signed before unsigned
4783 // e.g., loadS before loadUS before loadI before loadF.
4784
4785
4786 //----------Load/Store Instructions--------------------------------------------
4787
4788 //----------Load Instructions--------------------------------------------------
4789
4790 // Converts byte to int.
4791 // As convB2I_reg, but without match rule. The match rule of convB2I_reg
4792 // reuses the 'amount' operand, but adlc expects that operand specification
4793 // and operands in match rule are equivalent.
4794 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
4795 effect(DEF dst, USE src);
4796 format %{ "EXTSB $dst, $src \t// byte->int" %}
4797 size(4);
4798 ins_encode %{
4799 __ extsb($dst$$Register, $src$$Register);
4800 %}
4801 ins_pipe(pipe_class_default);
4802 %}
4803
4804 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{
4805 // match-rule, false predicate
4806 match(Set dst (LoadB mem));
4807 predicate(false);
4808
4809 format %{ "LBZ $dst, $mem" %}
4810 size(4);
4811 ins_encode( enc_lbz(dst, mem) );
4812 ins_pipe(pipe_class_memory);
4813 %}
4814
4815 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{
4816 // match-rule, false predicate
4817 match(Set dst (LoadB mem));
4818 predicate(false);
4819
4820 format %{ "LBZ $dst, $mem\n\t"
4821 "TWI $dst\n\t"
4822 "ISYNC" %}
4823 size(12);
4824 ins_encode( enc_lbz_ac(dst, mem) );
4825 ins_pipe(pipe_class_memory);
4826 %}
4827
4828 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
4829 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{
4830 match(Set dst (LoadB mem));
4831 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4832 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4833 expand %{
4834 iRegIdst tmp;
4835 loadUB_indirect(tmp, mem);
4836 convB2I_reg_2(dst, tmp);
4837 %}
4838 %}
4839
4840 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{
4841 match(Set dst (LoadB mem));
4842 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
4843 expand %{
4844 iRegIdst tmp;
4845 loadUB_indirect_ac(tmp, mem);
4846 convB2I_reg_2(dst, tmp);
4847 %}
4848 %}
4849
4850 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{
4851 // match-rule, false predicate
4852 match(Set dst (LoadB mem));
4853 predicate(false);
4854
4855 format %{ "LBZ $dst, $mem" %}
4856 size(4);
4857 ins_encode( enc_lbz(dst, mem) );
4858 ins_pipe(pipe_class_memory);
4859 %}
4860
4861 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{
4862 // match-rule, false predicate
4863 match(Set dst (LoadB mem));
4864 predicate(false);
4865
4866 format %{ "LBZ $dst, $mem\n\t"
4867 "TWI $dst\n\t"
4868 "ISYNC" %}
4869 size(12);
4870 ins_encode( enc_lbz_ac(dst, mem) );
4871 ins_pipe(pipe_class_memory);
4872 %}
4873
4874 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
4875 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{
4876 match(Set dst (LoadB mem));
4877 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4878 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4879
4880 expand %{
4881 iRegIdst tmp;
4882 loadUB_indOffset16(tmp, mem);
4883 convB2I_reg_2(dst, tmp);
4884 %}
4885 %}
4886
4887 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{
4888 match(Set dst (LoadB mem));
4889 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
4890
4891 expand %{
4892 iRegIdst tmp;
4893 loadUB_indOffset16_ac(tmp, mem);
4894 convB2I_reg_2(dst, tmp);
4895 %}
4896 %}
4897
4898 // Load Unsigned Byte (8bit UNsigned) into an int reg.
4899 instruct loadUB(iRegIdst dst, memory mem) %{
4900 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4901 match(Set dst (LoadUB mem));
4902 ins_cost(MEMORY_REF_COST);
4903
4904 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %}
4905 size(4);
4906 ins_encode( enc_lbz(dst, mem) );
4907 ins_pipe(pipe_class_memory);
4908 %}
4909
4910 // Load Unsigned Byte (8bit UNsigned) acquire.
4911 instruct loadUB_ac(iRegIdst dst, memory mem) %{
4912 match(Set dst (LoadUB mem));
4913 ins_cost(3*MEMORY_REF_COST);
4914
4915 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t"
4916 "TWI $dst\n\t"
4917 "ISYNC" %}
4918 size(12);
4919 ins_encode( enc_lbz_ac(dst, mem) );
4920 ins_pipe(pipe_class_memory);
4921 %}
4922
4923 // Load Unsigned Byte (8bit UNsigned) into a Long Register.
4924 instruct loadUB2L(iRegLdst dst, memory mem) %{
4925 match(Set dst (ConvI2L (LoadUB mem)));
4926 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
4927 ins_cost(MEMORY_REF_COST);
4928
4929 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %}
4930 size(4);
4931 ins_encode( enc_lbz(dst, mem) );
4932 ins_pipe(pipe_class_memory);
4933 %}
4934
4935 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{
4936 match(Set dst (ConvI2L (LoadUB mem)));
4937 ins_cost(3*MEMORY_REF_COST);
4938
4939 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t"
4940 "TWI $dst\n\t"
4941 "ISYNC" %}
4942 size(12);
4943 ins_encode( enc_lbz_ac(dst, mem) );
4944 ins_pipe(pipe_class_memory);
4945 %}
4946
4947 // Load Short (16bit signed)
4948 instruct loadS(iRegIdst dst, memory mem) %{
4949 match(Set dst (LoadS mem));
4950 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4951 ins_cost(MEMORY_REF_COST);
4952
4953 format %{ "LHA $dst, $mem" %}
4954 size(4);
4955 ins_encode %{
4956 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
4957 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
4958 %}
4959 ins_pipe(pipe_class_memory);
4960 %}
4961
4962 // Load Short (16bit signed) acquire.
4963 instruct loadS_ac(iRegIdst dst, memory mem) %{
4964 match(Set dst (LoadS mem));
4965 ins_cost(3*MEMORY_REF_COST);
4966
4967 format %{ "LHA $dst, $mem\t acquire\n\t"
4968 "TWI $dst\n\t"
4969 "ISYNC" %}
4970 size(12);
4971 ins_encode %{
4972 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
4973 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
4974 __ twi_0($dst$$Register);
4975 __ isync();
4976 %}
4977 ins_pipe(pipe_class_memory);
4978 %}
4979
4980 // Load Char (16bit unsigned)
4981 instruct loadUS(iRegIdst dst, memory mem) %{
4982 match(Set dst (LoadUS mem));
4983 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4984 ins_cost(MEMORY_REF_COST);
4985
4986 format %{ "LHZ $dst, $mem" %}
4987 size(4);
4988 ins_encode( enc_lhz(dst, mem) );
4989 ins_pipe(pipe_class_memory);
4990 %}
4991
4992 // Load Char (16bit unsigned) acquire.
4993 instruct loadUS_ac(iRegIdst dst, memory mem) %{
4994 match(Set dst (LoadUS mem));
4995 ins_cost(3*MEMORY_REF_COST);
4996
4997 format %{ "LHZ $dst, $mem \t// acquire\n\t"
4998 "TWI $dst\n\t"
4999 "ISYNC" %}
5000 size(12);
5001 ins_encode( enc_lhz_ac(dst, mem) );
5002 ins_pipe(pipe_class_memory);
5003 %}
5004
5005 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register.
5006 instruct loadUS2L(iRegLdst dst, memory mem) %{
5007 match(Set dst (ConvI2L (LoadUS mem)));
5008 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5009 ins_cost(MEMORY_REF_COST);
5010
5011 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %}
5012 size(4);
5013 ins_encode( enc_lhz(dst, mem) );
5014 ins_pipe(pipe_class_memory);
5015 %}
5016
5017 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire.
5018 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{
5019 match(Set dst (ConvI2L (LoadUS mem)));
5020 ins_cost(3*MEMORY_REF_COST);
5021
5022 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t"
5023 "TWI $dst\n\t"
5024 "ISYNC" %}
5025 size(12);
5026 ins_encode( enc_lhz_ac(dst, mem) );
5027 ins_pipe(pipe_class_memory);
5028 %}
5029
5030 // Load Integer.
5031 instruct loadI(iRegIdst dst, memory mem) %{
5032 match(Set dst (LoadI mem));
5033 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5034 ins_cost(MEMORY_REF_COST);
5035
5036 format %{ "LWZ $dst, $mem" %}
5037 size(4);
5038 ins_encode( enc_lwz(dst, mem) );
5039 ins_pipe(pipe_class_memory);
5040 %}
5041
5042 // Load Integer acquire.
5043 instruct loadI_ac(iRegIdst dst, memory mem) %{
5044 match(Set dst (LoadI mem));
5045 ins_cost(3*MEMORY_REF_COST);
5046
5047 format %{ "LWZ $dst, $mem \t// load acquire\n\t"
5048 "TWI $dst\n\t"
5049 "ISYNC" %}
5050 size(12);
5051 ins_encode( enc_lwz_ac(dst, mem) );
5052 ins_pipe(pipe_class_memory);
5053 %}
5054
5055 // Match loading integer and casting it to unsigned int in
5056 // long register.
5057 // LoadI + ConvI2L + AndL 0xffffffff.
5058 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
5059 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5060 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered());
5061 ins_cost(MEMORY_REF_COST);
5062
5063 format %{ "LWZ $dst, $mem \t// zero-extend to long" %}
5064 size(4);
5065 ins_encode( enc_lwz(dst, mem) );
5066 ins_pipe(pipe_class_memory);
5067 %}
5068
5069 // Match loading integer and casting it to long.
5070 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
5071 match(Set dst (ConvI2L (LoadI mem)));
5072 predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5073 ins_cost(MEMORY_REF_COST);
5074
5075 format %{ "LWA $dst, $mem \t// loadI2L" %}
5076 size(4);
5077 ins_encode %{
5078 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5079 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5080 %}
5081 ins_pipe(pipe_class_memory);
5082 %}
5083
5084 // Match loading integer and casting it to long - acquire.
5085 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
5086 match(Set dst (ConvI2L (LoadI mem)));
5087 ins_cost(3*MEMORY_REF_COST);
5088
5089 format %{ "LWA $dst, $mem \t// loadI2L acquire"
5090 "TWI $dst\n\t"
5091 "ISYNC" %}
5092 size(12);
5093 ins_encode %{
5094 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5095 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5096 __ twi_0($dst$$Register);
5097 __ isync();
5098 %}
5099 ins_pipe(pipe_class_memory);
5100 %}
5101
5102 // Load Long - aligned
5103 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{
5104 match(Set dst (LoadL mem));
5105 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5106 ins_cost(MEMORY_REF_COST);
5107
5108 format %{ "LD $dst, $mem \t// long" %}
5109 size(4);
5110 ins_encode( enc_ld(dst, mem) );
5111 ins_pipe(pipe_class_memory);
5112 %}
5113
5114 // Load Long - aligned acquire.
5115 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{
5116 match(Set dst (LoadL mem));
5117 ins_cost(3*MEMORY_REF_COST);
5118
5119 format %{ "LD $dst, $mem \t// long acquire\n\t"
5120 "TWI $dst\n\t"
5121 "ISYNC" %}
5122 size(12);
5123 ins_encode( enc_ld_ac(dst, mem) );
5124 ins_pipe(pipe_class_memory);
5125 %}
5126
5127 // Load Long - UNaligned
5128 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{
5129 match(Set dst (LoadL_unaligned mem));
5130 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5131 ins_cost(MEMORY_REF_COST);
5132
5133 format %{ "LD $dst, $mem \t// unaligned long" %}
5134 size(4);
5135 ins_encode( enc_ld(dst, mem) );
5136 ins_pipe(pipe_class_memory);
5137 %}
5138
5139 // Load nodes for superwords
5140
5141 // Load Aligned Packed Byte
5142 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{
5143 predicate(n->as_LoadVector()->memory_size() == 8);
5144 match(Set dst (LoadVector mem));
5145 ins_cost(MEMORY_REF_COST);
5146
5147 format %{ "LD $dst, $mem \t// load 8-byte Vector" %}
5148 size(4);
5149 ins_encode( enc_ld(dst, mem) );
5150 ins_pipe(pipe_class_memory);
5151 %}
5152
5153
5154 instruct loadV16(vecX dst, memoryAlg16 mem) %{
5155 predicate(n->as_LoadVector()->memory_size() == 16);
5156 match(Set dst (LoadVector mem));
5157 ins_cost(MEMORY_REF_COST);
5158
5159 format %{ "LXV $dst, $mem \t// load 16-byte Vector" %}
5160 size(4);
5161 ins_encode %{
5162 __ lxv($dst$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
5163 %}
5164 ins_pipe(pipe_class_default);
5165 %}
5166
5167 // Load Range, range = array length (=jint)
5168 instruct loadRange(iRegIdst dst, memory mem) %{
5169 match(Set dst (LoadRange mem));
5170 ins_cost(MEMORY_REF_COST);
5171
5172 format %{ "LWZ $dst, $mem \t// range" %}
5173 size(4);
5174 ins_encode( enc_lwz(dst, mem) );
5175 ins_pipe(pipe_class_memory);
5176 %}
5177
5178 // Load Compressed Pointer
5179 instruct loadN(iRegNdst dst, memory mem) %{
5180 match(Set dst (LoadN mem));
5181 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5182 ins_cost(MEMORY_REF_COST);
5183
5184 format %{ "LWZ $dst, $mem \t// load compressed ptr" %}
5185 size(4);
5186 ins_encode( enc_lwz(dst, mem) );
5187 ins_pipe(pipe_class_memory);
5188 %}
5189
5190 // Load Compressed Pointer acquire.
5191 instruct loadN_ac(iRegNdst dst, memory mem) %{
5192 match(Set dst (LoadN mem));
5193 predicate(n->as_Load()->barrier_data() == 0);
5194 ins_cost(3*MEMORY_REF_COST);
5195
5196 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5197 "TWI $dst\n\t"
5198 "ISYNC" %}
5199 size(12);
5200 ins_encode( enc_lwz_ac(dst, mem) );
5201 ins_pipe(pipe_class_memory);
5202 %}
5203
5204 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5205 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5206 match(Set dst (DecodeN (LoadN mem)));
5207 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0 && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5208 ins_cost(MEMORY_REF_COST);
5209
5210 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5211 size(4);
5212 ins_encode( enc_lwz(dst, mem) );
5213 ins_pipe(pipe_class_memory);
5214 %}
5215
5216 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5217 match(Set dst (DecodeNKlass (LoadNKlass mem)));
5218 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0 &&
5219 _kids[0]->_leaf->as_Load()->is_unordered());
5220 ins_cost(MEMORY_REF_COST);
5221
5222 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5223 size(4);
5224 ins_encode( enc_lwz(dst, mem) );
5225 ins_pipe(pipe_class_memory);
5226 %}
5227
5228 // Load Pointer
5229 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5230 match(Set dst (LoadP mem));
5231 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5232 ins_cost(MEMORY_REF_COST);
5233
5234 format %{ "LD $dst, $mem \t// ptr" %}
5235 size(4);
5236 ins_encode( enc_ld(dst, mem) );
5237 ins_pipe(pipe_class_memory);
5238 %}
5239
5240 // Load Pointer acquire.
5241 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5242 match(Set dst (LoadP mem));
5243 ins_cost(3*MEMORY_REF_COST);
5244
5245 predicate(n->as_Load()->barrier_data() == 0);
5246
5247 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5248 "TWI $dst\n\t"
5249 "ISYNC" %}
5250 size(12);
5251 ins_encode( enc_ld_ac(dst, mem) );
5252 ins_pipe(pipe_class_memory);
5253 %}
5254
5255 // LoadP + CastP2L
5256 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
5257 match(Set dst (CastP2X (LoadP mem)));
5258 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5259 ins_cost(MEMORY_REF_COST);
5260
5261 format %{ "LD $dst, $mem \t// ptr + p2x" %}
5262 size(4);
5263 ins_encode( enc_ld(dst, mem) );
5264 ins_pipe(pipe_class_memory);
5265 %}
5266
5267 // Load compressed klass pointer.
5268 instruct loadNKlass(iRegNdst dst, memory mem) %{
5269 match(Set dst (LoadNKlass mem));
5270 predicate(!UseCompactObjectHeaders);
5271 ins_cost(MEMORY_REF_COST);
5272
5273 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %}
5274 size(4);
5275 ins_encode( enc_lwz(dst, mem) );
5276 ins_pipe(pipe_class_memory);
5277 %}
5278
5279 instruct loadNKlassCompactHeaders(iRegNdst dst, memory mem) %{
5280 match(Set dst (LoadNKlass mem));
5281 predicate(UseCompactObjectHeaders);
5282 ins_cost(MEMORY_REF_COST);
5283
5284 format %{ "load_narrow_klass_compact $dst, $mem \t// compressed class ptr" %}
5285 size(8);
5286 ins_encode %{
5287 assert($mem$$index$$Register == R0, "must not have indexed address: %s[%s]", $mem$$base$$Register.name(), $mem$$index$$Register.name());
5288 __ load_narrow_klass_compact_c2($dst$$Register, $mem$$base$$Register, $mem$$disp);
5289 %}
5290 ins_pipe(pipe_class_memory);
5291 %}
5292
5293 // Load Klass Pointer
5294 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
5295 match(Set dst (LoadKlass mem));
5296 ins_cost(MEMORY_REF_COST);
5297
5298 format %{ "LD $dst, $mem \t// klass ptr" %}
5299 size(4);
5300 ins_encode( enc_ld(dst, mem) );
5301 ins_pipe(pipe_class_memory);
5302 %}
5303
5304 // Load Float
5305 instruct loadF(regF dst, memory mem) %{
5306 match(Set dst (LoadF mem));
5307 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5308 ins_cost(MEMORY_REF_COST);
5309
5310 format %{ "LFS $dst, $mem" %}
5311 size(4);
5312 ins_encode %{
5313 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5314 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5315 %}
5316 ins_pipe(pipe_class_memory);
5317 %}
5318
5319 // Load Float acquire.
5320 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5321 match(Set dst (LoadF mem));
5322 effect(TEMP cr0);
5323 ins_cost(3*MEMORY_REF_COST);
5324
5325 format %{ "LFS $dst, $mem \t// acquire\n\t"
5326 "FCMPU cr0, $dst, $dst\n\t"
5327 "BNE cr0, next\n"
5328 "next:\n\t"
5329 "ISYNC" %}
5330 size(16);
5331 ins_encode %{
5332 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5333 Label next;
5334 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5335 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5336 __ bne(CR0, next);
5337 __ bind(next);
5338 __ isync();
5339 %}
5340 ins_pipe(pipe_class_memory);
5341 %}
5342
5343 // Load Double - aligned
5344 instruct loadD(regD dst, memory mem) %{
5345 match(Set dst (LoadD mem));
5346 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5347 ins_cost(MEMORY_REF_COST);
5348
5349 format %{ "LFD $dst, $mem" %}
5350 size(4);
5351 ins_encode( enc_lfd(dst, mem) );
5352 ins_pipe(pipe_class_memory);
5353 %}
5354
5355 // Load Double - aligned acquire.
5356 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5357 match(Set dst (LoadD mem));
5358 effect(TEMP cr0);
5359 ins_cost(3*MEMORY_REF_COST);
5360
5361 format %{ "LFD $dst, $mem \t// acquire\n\t"
5362 "FCMPU cr0, $dst, $dst\n\t"
5363 "BNE cr0, next\n"
5364 "next:\n\t"
5365 "ISYNC" %}
5366 size(16);
5367 ins_encode %{
5368 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5369 Label next;
5370 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5371 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5372 __ bne(CR0, next);
5373 __ bind(next);
5374 __ isync();
5375 %}
5376 ins_pipe(pipe_class_memory);
5377 %}
5378
5379 // Load Double - UNaligned
5380 instruct loadD_unaligned(regD dst, memory mem) %{
5381 match(Set dst (LoadD_unaligned mem));
5382 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5383 ins_cost(MEMORY_REF_COST);
5384
5385 format %{ "LFD $dst, $mem" %}
5386 size(4);
5387 ins_encode( enc_lfd(dst, mem) );
5388 ins_pipe(pipe_class_memory);
5389 %}
5390
5391 //----------Constants--------------------------------------------------------
5392
5393 // Load MachConstantTableBase: add hi offset to global toc.
5394 // TODO: Handle hidden register r29 in bundler!
5395 instruct loadToc_hi(iRegLdst dst) %{
5396 effect(DEF dst);
5397 ins_cost(DEFAULT_COST);
5398
5399 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %}
5400 size(4);
5401 ins_encode %{
5402 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
5403 %}
5404 ins_pipe(pipe_class_default);
5405 %}
5406
5407 // Load MachConstantTableBase: add lo offset to global toc.
5408 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
5409 effect(DEF dst, USE src);
5410 ins_cost(DEFAULT_COST);
5411
5412 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %}
5413 size(4);
5414 ins_encode %{
5415 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
5416 %}
5417 ins_pipe(pipe_class_default);
5418 %}
5419
5420 // Load 16-bit integer constant 0xssss????
5421 instruct loadConI16(iRegIdst dst, immI16 src) %{
5422 match(Set dst src);
5423
5424 format %{ "LI $dst, $src" %}
5425 size(4);
5426 ins_encode %{
5427 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5428 %}
5429 ins_pipe(pipe_class_default);
5430 %}
5431
5432 // Load integer constant 0x????0000
5433 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
5434 match(Set dst src);
5435 ins_cost(DEFAULT_COST);
5436
5437 format %{ "LIS $dst, $src.hi" %}
5438 size(4);
5439 ins_encode %{
5440 // Lis sign extends 16-bit src then shifts it 16 bit to the left.
5441 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5442 %}
5443 ins_pipe(pipe_class_default);
5444 %}
5445
5446 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted
5447 // and sign extended), this adds the low 16 bits.
5448 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
5449 // no match-rule, false predicate
5450 effect(DEF dst, USE src1, USE src2);
5451 predicate(false);
5452
5453 format %{ "ORI $dst, $src1.hi, $src2.lo" %}
5454 size(4);
5455 ins_encode %{
5456 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5457 %}
5458 ins_pipe(pipe_class_default);
5459 %}
5460
5461 instruct loadConI32(iRegIdst dst, immI32 src) %{
5462 match(Set dst src);
5463 // This macro is valid only in Power 10 and up, but adding the following predicate here
5464 // caused a build error, so we comment it out for now.
5465 // predicate(PowerArchitecturePPC64 >= 10);
5466 ins_cost(DEFAULT_COST+1);
5467
5468 format %{ "PLI $dst, $src" %}
5469 size(8);
5470 ins_encode %{
5471 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5472 __ pli($dst$$Register, $src$$constant);
5473 %}
5474 ins_pipe(pipe_class_default);
5475 ins_alignment(2);
5476 %}
5477
5478 instruct loadConI_Ex(iRegIdst dst, immI src) %{
5479 match(Set dst src);
5480 ins_cost(DEFAULT_COST*2);
5481
5482 expand %{
5483 // Would like to use $src$$constant.
5484 immI16 srcLo %{ _opnds[1]->constant() %}
5485 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5486 immIhi16 srcHi %{ _opnds[1]->constant() %}
5487 iRegIdst tmpI;
5488 loadConIhi16(tmpI, srcHi);
5489 loadConI32_lo16(dst, tmpI, srcLo);
5490 %}
5491 %}
5492
5493 // No constant pool entries required.
5494 instruct loadConL16(iRegLdst dst, immL16 src) %{
5495 match(Set dst src);
5496
5497 format %{ "LI $dst, $src \t// long" %}
5498 size(4);
5499 ins_encode %{
5500 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
5501 %}
5502 ins_pipe(pipe_class_default);
5503 %}
5504
5505 // Load long constant 0xssssssss????0000
5506 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
5507 match(Set dst src);
5508 ins_cost(DEFAULT_COST);
5509
5510 format %{ "LIS $dst, $src.hi \t// long" %}
5511 size(4);
5512 ins_encode %{
5513 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5514 %}
5515 ins_pipe(pipe_class_default);
5516 %}
5517
5518 // To load a 32 bit constant: merge lower 16 bits into already loaded
5519 // high 16 bits.
5520 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
5521 // no match-rule, false predicate
5522 effect(DEF dst, USE src1, USE src2);
5523 predicate(false);
5524
5525 format %{ "ORI $dst, $src1, $src2.lo" %}
5526 size(4);
5527 ins_encode %{
5528 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5529 %}
5530 ins_pipe(pipe_class_default);
5531 %}
5532
5533 // Load 32-bit long constant
5534 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{
5535 match(Set dst src);
5536 ins_cost(DEFAULT_COST*2);
5537
5538 expand %{
5539 // Would like to use $src$$constant.
5540 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%}
5541 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5542 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%}
5543 iRegLdst tmpL;
5544 loadConL32hi16(tmpL, srcHi);
5545 loadConL32_lo16(dst, tmpL, srcLo);
5546 %}
5547 %}
5548
5549 // Load 34-bit long constant using prefixed addi. No constant pool entries required.
5550 instruct loadConL34(iRegLdst dst, immL34 src) %{
5551 match(Set dst src);
5552 // This macro is valid only in Power 10 and up, but adding the following predicate here
5553 // caused a build error, so we comment it out for now.
5554 // predicate(PowerArchitecturePPC64 >= 10);
5555 ins_cost(DEFAULT_COST+1);
5556
5557 format %{ "PLI $dst, $src \t// long" %}
5558 size(8);
5559 ins_encode %{
5560 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5561 __ pli($dst$$Register, $src$$constant);
5562 %}
5563 ins_pipe(pipe_class_default);
5564 ins_alignment(2);
5565 %}
5566
5567 // Load long constant 0x????000000000000.
5568 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{
5569 match(Set dst src);
5570 ins_cost(DEFAULT_COST);
5571
5572 expand %{
5573 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%}
5574 immI shift32 %{ 32 %}
5575 iRegLdst tmpL;
5576 loadConL32hi16(tmpL, srcHi);
5577 lshiftL_regL_immI(dst, tmpL, shift32);
5578 %}
5579 %}
5580
5581 // Expand node for constant pool load: small offset.
5582 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{
5583 effect(DEF dst, USE src, USE toc);
5584 ins_cost(MEMORY_REF_COST);
5585
5586 ins_num_consts(1);
5587 // Needed so that CallDynamicJavaDirect can compute the address of this
5588 // instruction for relocation.
5589 ins_field_cbuf_insts_offset(int);
5590
5591 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %}
5592 size(4);
5593 ins_encode( enc_load_long_constL(dst, src, toc) );
5594 ins_pipe(pipe_class_memory);
5595 %}
5596
5597 // Expand node for constant pool load: large offset.
5598 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{
5599 effect(DEF dst, USE src, USE toc);
5600 predicate(false);
5601
5602 ins_num_consts(1);
5603 ins_field_const_toc_offset(int);
5604 // Needed so that CallDynamicJavaDirect can compute the address of this
5605 // instruction for relocation.
5606 ins_field_cbuf_insts_offset(int);
5607
5608 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %}
5609 size(4);
5610 ins_encode( enc_load_long_constL_hi(dst, toc, src) );
5611 ins_pipe(pipe_class_default);
5612 %}
5613
5614 // Expand node for constant pool load: large offset.
5615 // No constant pool entries required.
5616 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
5617 effect(DEF dst, USE src, USE base);
5618 predicate(false);
5619
5620 ins_field_const_toc_offset_hi_node(loadConL_hiNode*);
5621
5622 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %}
5623 size(4);
5624 ins_encode %{
5625 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5626 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5627 %}
5628 ins_pipe(pipe_class_memory);
5629 %}
5630
5631 // Load long constant from constant table. Expand in case of
5632 // offset > 16 bit is needed.
5633 // Adlc adds toc node MachConstantTableBase.
5634 instruct loadConL_Ex(iRegLdst dst, immL src) %{
5635 match(Set dst src);
5636 ins_cost(MEMORY_REF_COST);
5637
5638 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %}
5639 // We can not inline the enc_class for the expand as that does not support constanttablebase.
5640 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) );
5641 %}
5642
5643 // Load nullptr as compressed oop.
5644 instruct loadConN0(iRegNdst dst, immN_0 src) %{
5645 match(Set dst src);
5646 ins_cost(DEFAULT_COST);
5647
5648 format %{ "LI $dst, $src \t// compressed ptr" %}
5649 size(4);
5650 ins_encode %{
5651 __ li($dst$$Register, 0);
5652 %}
5653 ins_pipe(pipe_class_default);
5654 %}
5655
5656 // Load hi part of compressed oop constant.
5657 instruct loadConN_hi(iRegNdst dst, immN src) %{
5658 effect(DEF dst, USE src);
5659 ins_cost(DEFAULT_COST);
5660
5661 format %{ "LIS $dst, $src \t// narrow oop hi" %}
5662 size(4);
5663 ins_encode %{
5664 __ lis($dst$$Register, 0); // Will get patched.
5665 %}
5666 ins_pipe(pipe_class_default);
5667 %}
5668
5669 // Add lo part of compressed oop constant to already loaded hi part.
5670 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
5671 effect(DEF dst, USE src1, USE src2);
5672 ins_cost(DEFAULT_COST);
5673
5674 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %}
5675 size(4);
5676 ins_encode %{
5677 AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant);
5678 __ relocate(addrlit.rspec(), /*compressed format*/ 1);
5679 __ ori($dst$$Register, $src1$$Register, 0); // Will get patched.
5680 %}
5681 ins_pipe(pipe_class_default);
5682 %}
5683
5684 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
5685 effect(DEF dst, USE src, USE shift, USE mask_begin);
5686
5687 size(4);
5688 ins_encode %{
5689 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
5690 %}
5691 ins_pipe(pipe_class_default);
5692 %}
5693
5694 // Needed to postalloc expand loadConN: ConN is loaded as ConI
5695 // leaving the upper 32 bits with sign-extension bits.
5696 // This clears these bits: dst = src & 0xFFFFFFFF.
5697 // TODO: Eventually call this maskN_regN_FFFFFFFF.
5698 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
5699 effect(DEF dst, USE src);
5700 predicate(false);
5701
5702 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
5703 size(4);
5704 ins_encode %{
5705 __ clrldi($dst$$Register, $src$$Register, 0x20);
5706 %}
5707 ins_pipe(pipe_class_default);
5708 %}
5709
5710 // Optimize DecodeN for disjoint base.
5711 // Load base of compressed oops into a register
5712 instruct loadBase(iRegLdst dst) %{
5713 effect(DEF dst);
5714
5715 format %{ "LoadConst $dst, heapbase" %}
5716 ins_encode %{
5717 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0);
5718 %}
5719 ins_pipe(pipe_class_default);
5720 %}
5721
5722 // Loading ConN must be postalloc expanded so that edges between
5723 // the nodes are safe. They may not interfere with a safepoint.
5724 // GL TODO: This needs three instructions: better put this into the constant pool.
5725 instruct loadConN_Ex(iRegNdst dst, immN src) %{
5726 match(Set dst src);
5727 ins_cost(DEFAULT_COST*2);
5728
5729 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5730 postalloc_expand %{
5731 MachNode *m1 = new loadConN_hiNode();
5732 MachNode *m2 = new loadConN_loNode();
5733 MachNode *m3 = new clearMs32bNode();
5734 m1->_bottom_type = bottom_type();
5735 m2->_bottom_type = bottom_type();
5736 m3->_bottom_type = bottom_type();
5737 m1->add_req(nullptr);
5738 m2->add_req(nullptr, m1);
5739 m3->add_req(nullptr, m2);
5740 m1->_opnds[0] = op_dst;
5741 m1->_opnds[1] = op_src;
5742 m2->_opnds[0] = op_dst;
5743 m2->_opnds[1] = op_dst;
5744 m2->_opnds[2] = op_src;
5745 m3->_opnds[0] = op_dst;
5746 m3->_opnds[1] = op_dst;
5747 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5748 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5749 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5750 nodes->push(m1);
5751 nodes->push(m2);
5752 nodes->push(m3);
5753 %}
5754 %}
5755
5756 // We have seen a safepoint between the hi and lo parts, and this node was handled
5757 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is
5758 // not a narrow oop.
5759 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
5760 match(Set dst src);
5761 effect(DEF dst, USE src);
5762 ins_cost(DEFAULT_COST);
5763
5764 format %{ "LIS $dst, $src \t// narrow klass hi" %}
5765 size(4);
5766 ins_encode %{
5767 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant);
5768 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
5769 %}
5770 ins_pipe(pipe_class_default);
5771 %}
5772
5773 // As loadConNKlass_hi this must be recognized as narrow klass, not oop!
5774 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5775 match(Set dst src1);
5776 effect(TEMP src2);
5777 ins_cost(DEFAULT_COST);
5778
5779 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
5780 size(4);
5781 ins_encode %{
5782 __ clrldi($dst$$Register, $src2$$Register, 0x20);
5783 %}
5784 ins_pipe(pipe_class_default);
5785 %}
5786
5787 // This needs a match rule so that build_oop_map knows this is
5788 // not a narrow oop.
5789 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5790 match(Set dst src1);
5791 effect(TEMP src2);
5792 ins_cost(DEFAULT_COST);
5793
5794 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
5795 size(4);
5796 ins_encode %{
5797 // Notify OOP recorder (don't need the relocation)
5798 AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant);
5799 intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value());
5800 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
5801 %}
5802 ins_pipe(pipe_class_default);
5803 %}
5804
5805 // Loading ConNKlass must be postalloc expanded so that edges between
5806 // the nodes are safe. They may not interfere with a safepoint.
5807 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
5808 match(Set dst src);
5809 ins_cost(DEFAULT_COST*2);
5810
5811 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5812 postalloc_expand %{
5813 // Load high bits into register. Sign extended.
5814 MachNode *m1 = new loadConNKlass_hiNode();
5815 m1->_bottom_type = bottom_type();
5816 m1->add_req(nullptr);
5817 m1->_opnds[0] = op_dst;
5818 m1->_opnds[1] = op_src;
5819 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5820 nodes->push(m1);
5821
5822 MachNode *m2 = m1;
5823 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) {
5824 // Value might be 1-extended. Mask out these bits.
5825 m2 = new loadConNKlass_maskNode();
5826 m2->_bottom_type = bottom_type();
5827 m2->add_req(nullptr, m1);
5828 m2->_opnds[0] = op_dst;
5829 m2->_opnds[1] = op_src;
5830 m2->_opnds[2] = op_dst;
5831 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5832 nodes->push(m2);
5833 }
5834
5835 MachNode *m3 = new loadConNKlass_loNode();
5836 m3->_bottom_type = bottom_type();
5837 m3->add_req(nullptr, m2);
5838 m3->_opnds[0] = op_dst;
5839 m3->_opnds[1] = op_src;
5840 m3->_opnds[2] = op_dst;
5841 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5842 nodes->push(m3);
5843 %}
5844 %}
5845
5846 // 0x1 is used in object initialization (initial object header).
5847 // No constant pool entries required.
5848 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
5849 match(Set dst src);
5850
5851 format %{ "LI $dst, $src \t// ptr" %}
5852 size(4);
5853 ins_encode %{
5854 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5855 %}
5856 ins_pipe(pipe_class_default);
5857 %}
5858
5859 // Expand node for constant pool load: small offset.
5860 // The match rule is needed to generate the correct bottom_type(),
5861 // however this node should never match. The use of predicate is not
5862 // possible since ADLC forbids predicates for chain rules. The higher
5863 // costs do not prevent matching in this case. For that reason the
5864 // operand immP_NM with predicate(false) is used.
5865 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{
5866 match(Set dst src);
5867 effect(TEMP toc);
5868
5869 ins_num_consts(1);
5870
5871 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %}
5872 size(4);
5873 ins_encode( enc_load_long_constP(dst, src, toc) );
5874 ins_pipe(pipe_class_memory);
5875 %}
5876
5877 // Expand node for constant pool load: large offset.
5878 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{
5879 effect(DEF dst, USE src, USE toc);
5880 predicate(false);
5881
5882 ins_num_consts(1);
5883 ins_field_const_toc_offset(int);
5884
5885 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %}
5886 size(4);
5887 ins_encode( enc_load_long_constP_hi(dst, src, toc) );
5888 ins_pipe(pipe_class_default);
5889 %}
5890
5891 // Expand node for constant pool load: large offset.
5892 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
5893 match(Set dst src);
5894 effect(TEMP base);
5895
5896 ins_field_const_toc_offset_hi_node(loadConP_hiNode*);
5897
5898 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
5899 size(4);
5900 ins_encode %{
5901 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5902 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5903 %}
5904 ins_pipe(pipe_class_memory);
5905 %}
5906
5907 // Load pointer constant from constant table. Expand in case an
5908 // offset > 16 bit is needed.
5909 // Adlc adds toc node MachConstantTableBase.
5910 instruct loadConP_Ex(iRegPdst dst, immP src) %{
5911 match(Set dst src);
5912 ins_cost(MEMORY_REF_COST);
5913
5914 // This rule does not use "expand" because then
5915 // the result type is not known to be an Oop. An ADLC
5916 // enhancement will be needed to make that work - not worth it!
5917
5918 // If this instruction rematerializes, it prolongs the live range
5919 // of the toc node, causing illegal graphs.
5920 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule().
5921 ins_cannot_rematerialize(true);
5922
5923 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %}
5924 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) );
5925 %}
5926
5927 // Expand node for constant pool load: small offset.
5928 instruct loadConF(regF dst, immF src, iRegLdst toc) %{
5929 effect(DEF dst, USE src, USE toc);
5930 ins_cost(MEMORY_REF_COST);
5931
5932 ins_num_consts(1);
5933
5934 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %}
5935 size(4);
5936 ins_encode %{
5937 address float_address = __ float_constant($src$$constant);
5938 if (float_address == nullptr) {
5939 ciEnv::current()->record_out_of_memory_failure();
5940 return;
5941 }
5942 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register);
5943 %}
5944 ins_pipe(pipe_class_memory);
5945 %}
5946
5947 // Expand node for constant pool load: large offset.
5948 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
5949 effect(DEF dst, USE src, USE toc);
5950 ins_cost(MEMORY_REF_COST);
5951
5952 ins_num_consts(1);
5953
5954 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
5955 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t"
5956 "ADDIS $toc, $toc, -offset_hi"%}
5957 size(12);
5958 ins_encode %{
5959 FloatRegister Rdst = $dst$$FloatRegister;
5960 Register Rtoc = $toc$$Register;
5961 address float_address = __ float_constant($src$$constant);
5962 if (float_address == nullptr) {
5963 ciEnv::current()->record_out_of_memory_failure();
5964 return;
5965 }
5966 int offset = __ offset_to_method_toc(float_address);
5967 int hi = (offset + (1<<15))>>16;
5968 int lo = offset - hi * (1<<16);
5969
5970 __ addis(Rtoc, Rtoc, hi);
5971 __ lfs(Rdst, lo, Rtoc);
5972 __ addis(Rtoc, Rtoc, -hi);
5973 %}
5974 ins_pipe(pipe_class_memory);
5975 %}
5976
5977 // Adlc adds toc node MachConstantTableBase.
5978 instruct loadConF_Ex(regF dst, immF src) %{
5979 match(Set dst src);
5980 ins_cost(MEMORY_REF_COST);
5981
5982 // See loadConP.
5983 ins_cannot_rematerialize(true);
5984
5985 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
5986 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) );
5987 %}
5988
5989 // Expand node for constant pool load: small offset.
5990 instruct loadConD(regD dst, immD src, iRegLdst toc) %{
5991 effect(DEF dst, USE src, USE toc);
5992 ins_cost(MEMORY_REF_COST);
5993
5994 ins_num_consts(1);
5995
5996 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %}
5997 size(4);
5998 ins_encode %{
5999 address float_address = __ double_constant($src$$constant);
6000 if (float_address == nullptr) {
6001 ciEnv::current()->record_out_of_memory_failure();
6002 return;
6003 }
6004 int offset = __ offset_to_method_toc(float_address);
6005 __ lfd($dst$$FloatRegister, offset, $toc$$Register);
6006 %}
6007 ins_pipe(pipe_class_memory);
6008 %}
6009
6010 // Expand node for constant pool load: large offset.
6011 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
6012 effect(DEF dst, USE src, USE toc);
6013 ins_cost(MEMORY_REF_COST);
6014
6015 ins_num_consts(1);
6016
6017 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6018 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t"
6019 "ADDIS $toc, $toc, -offset_hi" %}
6020 size(12);
6021 ins_encode %{
6022 FloatRegister Rdst = $dst$$FloatRegister;
6023 Register Rtoc = $toc$$Register;
6024 address float_address = __ double_constant($src$$constant);
6025 if (float_address == nullptr) {
6026 ciEnv::current()->record_out_of_memory_failure();
6027 return;
6028 }
6029 int offset = __ offset_to_method_toc(float_address);
6030 int hi = (offset + (1<<15))>>16;
6031 int lo = offset - hi * (1<<16);
6032
6033 __ addis(Rtoc, Rtoc, hi);
6034 __ lfd(Rdst, lo, Rtoc);
6035 __ addis(Rtoc, Rtoc, -hi);
6036 %}
6037 ins_pipe(pipe_class_memory);
6038 %}
6039
6040 // Adlc adds toc node MachConstantTableBase.
6041 instruct loadConD_Ex(regD dst, immD src) %{
6042 match(Set dst src);
6043 ins_cost(MEMORY_REF_COST);
6044
6045 // See loadConP.
6046 ins_cannot_rematerialize(true);
6047
6048 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6049 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) );
6050 %}
6051
6052 // Prefetch instructions.
6053 // Must be safe to execute with invalid address (cannot fault).
6054
6055 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
6056 match(PrefetchAllocation (AddP mem src));
6057 ins_cost(MEMORY_REF_COST);
6058
6059 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
6060 size(4);
6061 ins_encode %{
6062 __ dcbtst($src$$Register, $mem$$base$$Register);
6063 %}
6064 ins_pipe(pipe_class_memory);
6065 %}
6066
6067 instruct prefetch_alloc_no_offset(indirectMemory mem) %{
6068 match(PrefetchAllocation mem);
6069 ins_cost(MEMORY_REF_COST);
6070
6071 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
6072 size(4);
6073 ins_encode %{
6074 __ dcbtst($mem$$base$$Register);
6075 %}
6076 ins_pipe(pipe_class_memory);
6077 %}
6078
6079 //----------Store Instructions-------------------------------------------------
6080
6081 // Store Byte
6082 instruct storeB(memory mem, iRegIsrc src) %{
6083 match(Set mem (StoreB mem src));
6084 ins_cost(MEMORY_REF_COST);
6085
6086 format %{ "STB $src, $mem \t// byte" %}
6087 size(4);
6088 ins_encode %{
6089 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6090 __ stb($src$$Register, Idisp, $mem$$base$$Register);
6091 %}
6092 ins_pipe(pipe_class_memory);
6093 %}
6094
6095 // Store Char/Short
6096 instruct storeC(memory mem, iRegIsrc src) %{
6097 match(Set mem (StoreC mem src));
6098 ins_cost(MEMORY_REF_COST);
6099
6100 format %{ "STH $src, $mem \t// short" %}
6101 size(4);
6102 ins_encode %{
6103 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6104 __ sth($src$$Register, Idisp, $mem$$base$$Register);
6105 %}
6106 ins_pipe(pipe_class_memory);
6107 %}
6108
6109 // Store Integer
6110 instruct storeI(memory mem, iRegIsrc src) %{
6111 match(Set mem (StoreI mem src));
6112 ins_cost(MEMORY_REF_COST);
6113
6114 format %{ "STW $src, $mem" %}
6115 size(4);
6116 ins_encode( enc_stw(src, mem) );
6117 ins_pipe(pipe_class_memory);
6118 %}
6119
6120 // ConvL2I + StoreI.
6121 instruct storeI_convL2I(memory mem, iRegLsrc src) %{
6122 match(Set mem (StoreI mem (ConvL2I src)));
6123 ins_cost(MEMORY_REF_COST);
6124
6125 format %{ "STW l2i($src), $mem" %}
6126 size(4);
6127 ins_encode( enc_stw(src, mem) );
6128 ins_pipe(pipe_class_memory);
6129 %}
6130
6131 // Store Long
6132 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{
6133 match(Set mem (StoreL mem src));
6134 ins_cost(MEMORY_REF_COST);
6135
6136 format %{ "STD $src, $mem \t// long" %}
6137 size(4);
6138 ins_encode( enc_std(src, mem) );
6139 ins_pipe(pipe_class_memory);
6140 %}
6141
6142 // Store super word nodes.
6143
6144 // Store Aligned Packed Byte long register to memory
6145 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{
6146 predicate(n->as_StoreVector()->memory_size() == 8);
6147 match(Set mem (StoreVector mem src));
6148 ins_cost(MEMORY_REF_COST);
6149
6150 format %{ "STD $mem, $src \t// packed8B" %}
6151 size(4);
6152 ins_encode( enc_std(src, mem) );
6153 ins_pipe(pipe_class_memory);
6154 %}
6155
6156
6157 instruct storeV16(memoryAlg16 mem, vecX src) %{
6158 predicate(n->as_StoreVector()->memory_size() == 16);
6159 match(Set mem (StoreVector mem src));
6160 ins_cost(MEMORY_REF_COST);
6161
6162 format %{ "STXV $mem, $src \t// store 16-byte Vector" %}
6163 size(4);
6164 ins_encode %{
6165 __ stxv($src$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
6166 %}
6167 ins_pipe(pipe_class_default);
6168 %}
6169
6170 // Reinterpret: only one vector size used: either L or X
6171 instruct reinterpretL(iRegLdst dst) %{
6172 match(Set dst (VectorReinterpret dst));
6173 ins_cost(0);
6174 format %{ "reinterpret $dst" %}
6175 size(0);
6176 ins_encode( /*empty*/ );
6177 ins_pipe(pipe_class_empty);
6178 %}
6179
6180 instruct reinterpretX(vecX dst) %{
6181 match(Set dst (VectorReinterpret dst));
6182 ins_cost(0);
6183 format %{ "reinterpret $dst" %}
6184 size(0);
6185 ins_encode( /*empty*/ );
6186 ins_pipe(pipe_class_empty);
6187 %}
6188
6189 // Store Compressed Oop
6190 instruct storeN(memory dst, iRegN_P2N src) %{
6191 match(Set dst (StoreN dst src));
6192 predicate(n->as_Store()->barrier_data() == 0);
6193 ins_cost(MEMORY_REF_COST);
6194
6195 format %{ "STW $src, $dst \t// compressed oop" %}
6196 size(4);
6197 ins_encode( enc_stw(src, dst) );
6198 ins_pipe(pipe_class_memory);
6199 %}
6200
6201 // Store Compressed KLass
6202 instruct storeNKlass(memory dst, iRegN_P2N src) %{
6203 match(Set dst (StoreNKlass dst src));
6204 ins_cost(MEMORY_REF_COST);
6205
6206 format %{ "STW $src, $dst \t// compressed klass" %}
6207 size(4);
6208 ins_encode( enc_stw(src, dst) );
6209 ins_pipe(pipe_class_memory);
6210 %}
6211
6212 // Store Pointer
6213 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{
6214 match(Set dst (StoreP dst src));
6215 predicate(n->as_Store()->barrier_data() == 0);
6216 ins_cost(MEMORY_REF_COST);
6217
6218 format %{ "STD $src, $dst \t// ptr" %}
6219 size(4);
6220 ins_encode( enc_std(src, dst) );
6221 ins_pipe(pipe_class_memory);
6222 %}
6223
6224 // Store Float
6225 instruct storeF(memory mem, regF src) %{
6226 match(Set mem (StoreF mem src));
6227 ins_cost(MEMORY_REF_COST);
6228
6229 format %{ "STFS $src, $mem" %}
6230 size(4);
6231 ins_encode( enc_stfs(src, mem) );
6232 ins_pipe(pipe_class_memory);
6233 %}
6234
6235 // Store Double
6236 instruct storeD(memory mem, regD src) %{
6237 match(Set mem (StoreD mem src));
6238 ins_cost(MEMORY_REF_COST);
6239
6240 format %{ "STFD $src, $mem" %}
6241 size(4);
6242 ins_encode( enc_stfd(src, mem) );
6243 ins_pipe(pipe_class_memory);
6244 %}
6245
6246 // Convert oop pointer into compressed form.
6247
6248 // Nodes for postalloc expand.
6249
6250 // Shift node for expand.
6251 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
6252 // The match rule is needed to make it a 'MachTypeNode'!
6253 match(Set dst (EncodeP src));
6254 predicate(false);
6255
6256 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6257 size(4);
6258 ins_encode %{
6259 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6260 %}
6261 ins_pipe(pipe_class_default);
6262 %}
6263
6264 // Add node for expand.
6265 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6266 // The match rule is needed to make it a 'MachTypeNode'!
6267 match(Set dst (EncodeP src));
6268 predicate(false);
6269
6270 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6271 ins_encode %{
6272 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6273 %}
6274 ins_pipe(pipe_class_default);
6275 %}
6276
6277 // Conditional sub base.
6278 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6279 // The match rule is needed to make it a 'MachTypeNode'!
6280 match(Set dst (EncodeP (Binary crx src1)));
6281 predicate(false);
6282
6283 format %{ "BEQ $crx, done\n\t"
6284 "SUB $dst, $src1, heapbase \t// encode: subtract base if != nullptr\n"
6285 "done:" %}
6286 ins_encode %{
6287 Label done;
6288 __ beq($crx$$CondRegister, done);
6289 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0);
6290 __ bind(done);
6291 %}
6292 ins_pipe(pipe_class_default);
6293 %}
6294
6295 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6296 // The match rule is needed to make it a 'MachTypeNode'!
6297 match(Set dst (EncodeP (Binary crx src1)));
6298 predicate(false);
6299
6300 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6301 size(4);
6302 ins_encode %{
6303 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6304 %}
6305 ins_pipe(pipe_class_default);
6306 %}
6307
6308 // Disjoint narrow oop base.
6309 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6310 match(Set dst (EncodeP src));
6311 predicate(CompressedOops::base_disjoint());
6312
6313 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6314 size(4);
6315 ins_encode %{
6316 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32);
6317 %}
6318 ins_pipe(pipe_class_default);
6319 %}
6320
6321 // shift != 0, base != 0
6322 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6323 match(Set dst (EncodeP src));
6324 effect(TEMP crx);
6325 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6326 CompressedOops::shift() != 0 &&
6327 CompressedOops::base_overlaps());
6328
6329 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6330 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6331 %}
6332
6333 // shift != 0, base != 0
6334 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6335 match(Set dst (EncodeP src));
6336 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6337 CompressedOops::shift() != 0 &&
6338 CompressedOops::base_overlaps());
6339
6340 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6341 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6342 %}
6343
6344 // shift != 0, base == 0
6345 // TODO: This is the same as encodeP_shift. Merge!
6346 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6347 match(Set dst (EncodeP src));
6348 predicate(CompressedOops::shift() != 0 &&
6349 CompressedOops::base() == nullptr);
6350
6351 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != nullptr" %}
6352 size(4);
6353 ins_encode %{
6354 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6355 %}
6356 ins_pipe(pipe_class_default);
6357 %}
6358
6359 // Compressed OOPs with narrow_oop_shift == 0.
6360 // shift == 0, base == 0
6361 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
6362 match(Set dst (EncodeP src));
6363 predicate(CompressedOops::shift() == 0);
6364
6365 format %{ "MR $dst, $src \t// Ptr->Narrow" %}
6366 // variable size, 0 or 4.
6367 ins_encode %{
6368 __ mr_if_needed($dst$$Register, $src$$Register);
6369 %}
6370 ins_pipe(pipe_class_default);
6371 %}
6372
6373 // Decode nodes.
6374
6375 // Shift node for expand.
6376 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6377 // The match rule is needed to make it a 'MachTypeNode'!
6378 match(Set dst (DecodeN src));
6379 predicate(false);
6380
6381 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6382 size(4);
6383 ins_encode %{
6384 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6385 %}
6386 ins_pipe(pipe_class_default);
6387 %}
6388
6389 // Add node for expand.
6390 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6391 // The match rule is needed to make it a 'MachTypeNode'!
6392 match(Set dst (DecodeN src));
6393 predicate(false);
6394
6395 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %}
6396 ins_encode %{
6397 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6398 %}
6399 ins_pipe(pipe_class_default);
6400 %}
6401
6402 // conditianal add base for expand
6403 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6404 // The match rule is needed to make it a 'MachTypeNode'!
6405 // NOTICE that the rule is nonsense - we just have to make sure that:
6406 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6407 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6408 match(Set dst (DecodeN (Binary crx src)));
6409 predicate(false);
6410
6411 format %{ "BEQ $crx, done\n\t"
6412 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != nullptr\n"
6413 "done:" %}
6414 ins_encode %{
6415 Label done;
6416 __ beq($crx$$CondRegister, done);
6417 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6418 __ bind(done);
6419 %}
6420 ins_pipe(pipe_class_default);
6421 %}
6422
6423 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6424 // The match rule is needed to make it a 'MachTypeNode'!
6425 // NOTICE that the rule is nonsense - we just have to make sure that:
6426 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6427 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6428 match(Set dst (DecodeN (Binary crx src1)));
6429 predicate(false);
6430
6431 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6432 size(4);
6433 ins_encode %{
6434 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6435 %}
6436 ins_pipe(pipe_class_default);
6437 %}
6438
6439 // shift != 0, base != 0
6440 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6441 match(Set dst (DecodeN src));
6442 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6443 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6444 CompressedOops::shift() != 0 &&
6445 CompressedOops::base() != nullptr);
6446 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6447 effect(TEMP crx);
6448
6449 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6450 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6451 %}
6452
6453 // shift != 0, base == 0
6454 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6455 match(Set dst (DecodeN src));
6456 predicate(CompressedOops::shift() != 0 &&
6457 CompressedOops::base() == nullptr);
6458
6459 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %}
6460 size(4);
6461 ins_encode %{
6462 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6463 %}
6464 ins_pipe(pipe_class_default);
6465 %}
6466
6467 // Optimize DecodeN for disjoint base.
6468 // Shift narrow oop and or it into register that already contains the heap base.
6469 // Base == dst must hold, and is assured by construction in postaloc_expand.
6470 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6471 match(Set dst (DecodeN src));
6472 effect(TEMP base);
6473 predicate(false);
6474
6475 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6476 size(4);
6477 ins_encode %{
6478 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift());
6479 %}
6480 ins_pipe(pipe_class_default);
6481 %}
6482
6483 // Optimize DecodeN for disjoint base.
6484 // This node requires only one cycle on the critical path.
6485 // We must postalloc_expand as we can not express use_def effects where
6486 // the used register is L and the def'ed register P.
6487 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6488 match(Set dst (DecodeN src));
6489 effect(TEMP_DEF dst);
6490 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6491 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6492 CompressedOops::base_disjoint());
6493 ins_cost(DEFAULT_COST);
6494
6495 format %{ "MOV $dst, heapbase \t\n"
6496 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6497 postalloc_expand %{
6498 loadBaseNode *n1 = new loadBaseNode();
6499 n1->add_req(nullptr);
6500 n1->_opnds[0] = op_dst;
6501
6502 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6503 n2->add_req(n_region, n_src, n1);
6504 n2->_opnds[0] = op_dst;
6505 n2->_opnds[1] = op_src;
6506 n2->_opnds[2] = op_dst;
6507 n2->_bottom_type = _bottom_type;
6508
6509 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6510 ra_->set_oop(n2, true);
6511
6512 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6513 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6514
6515 nodes->push(n1);
6516 nodes->push(n2);
6517 %}
6518 %}
6519
6520 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6521 match(Set dst (DecodeN src));
6522 effect(TEMP_DEF dst, TEMP crx);
6523 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6524 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6525 CompressedOops::base_disjoint());
6526 ins_cost(3 * DEFAULT_COST);
6527
6528 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %}
6529 postalloc_expand %{
6530 loadBaseNode *n1 = new loadBaseNode();
6531 n1->add_req(nullptr);
6532 n1->_opnds[0] = op_dst;
6533
6534 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
6535 n_compare->add_req(n_region, n_src);
6536 n_compare->_opnds[0] = op_crx;
6537 n_compare->_opnds[1] = op_src;
6538 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6539
6540 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6541 n2->add_req(n_region, n_src, n1);
6542 n2->_opnds[0] = op_dst;
6543 n2->_opnds[1] = op_src;
6544 n2->_opnds[2] = op_dst;
6545 n2->_bottom_type = _bottom_type;
6546
6547 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6548 n_cond_set->add_req(n_region, n_compare, n2);
6549 n_cond_set->_opnds[0] = op_dst;
6550 n_cond_set->_opnds[1] = op_crx;
6551 n_cond_set->_opnds[2] = op_dst;
6552 n_cond_set->_bottom_type = _bottom_type;
6553
6554 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6555 ra_->set_oop(n_cond_set, true);
6556
6557 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6558 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
6559 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6560 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6561
6562 nodes->push(n1);
6563 nodes->push(n_compare);
6564 nodes->push(n2);
6565 nodes->push(n_cond_set);
6566 %}
6567 %}
6568
6569 // src != 0, shift != 0, base != 0
6570 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6571 match(Set dst (DecodeN src));
6572 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6573 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6574 CompressedOops::shift() != 0 &&
6575 CompressedOops::base() != nullptr);
6576 ins_cost(2 * DEFAULT_COST);
6577
6578 format %{ "DecodeN $dst, $src \t// $src != nullptr, postalloc expanded" %}
6579 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6580 %}
6581
6582 // Compressed OOPs with narrow_oop_shift == 0.
6583 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6584 match(Set dst (DecodeN src));
6585 predicate(CompressedOops::shift() == 0);
6586 ins_cost(DEFAULT_COST);
6587
6588 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %}
6589 // variable size, 0 or 4.
6590 ins_encode %{
6591 __ mr_if_needed($dst$$Register, $src$$Register);
6592 %}
6593 ins_pipe(pipe_class_default);
6594 %}
6595
6596 // Convert compressed oop into int for vectors alignment masking.
6597 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
6598 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6599 predicate(CompressedOops::shift() == 0);
6600 ins_cost(DEFAULT_COST);
6601
6602 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %}
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 // Convert klass pointer into compressed form.
6611
6612 // Nodes for postalloc expand.
6613
6614 // Shift node for expand.
6615 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
6616 // The match rule is needed to make it a 'MachTypeNode'!
6617 match(Set dst (EncodePKlass src));
6618 predicate(false);
6619
6620 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6621 size(4);
6622 ins_encode %{
6623 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6624 %}
6625 ins_pipe(pipe_class_default);
6626 %}
6627
6628 // Add node for expand.
6629 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6630 // The match rule is needed to make it a 'MachTypeNode'!
6631 match(Set dst (EncodePKlass (Binary base src)));
6632 predicate(false);
6633
6634 format %{ "SUB $dst, $base, $src \t// encode" %}
6635 size(4);
6636 ins_encode %{
6637 __ subf($dst$$Register, $base$$Register, $src$$Register);
6638 %}
6639 ins_pipe(pipe_class_default);
6640 %}
6641
6642 // Disjoint narrow oop base.
6643 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
6644 match(Set dst (EncodePKlass src));
6645 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/);
6646
6647 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6648 size(4);
6649 ins_encode %{
6650 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
6651 %}
6652 ins_pipe(pipe_class_default);
6653 %}
6654
6655 // shift != 0, base != 0
6656 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6657 match(Set dst (EncodePKlass (Binary base src)));
6658 predicate(false);
6659
6660 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6661 postalloc_expand %{
6662 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
6663 n1->add_req(n_region, n_base, n_src);
6664 n1->_opnds[0] = op_dst;
6665 n1->_opnds[1] = op_base;
6666 n1->_opnds[2] = op_src;
6667 n1->_bottom_type = _bottom_type;
6668
6669 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode();
6670 n2->add_req(n_region, n1);
6671 n2->_opnds[0] = op_dst;
6672 n2->_opnds[1] = op_dst;
6673 n2->_bottom_type = _bottom_type;
6674 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6675 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6676
6677 nodes->push(n1);
6678 nodes->push(n2);
6679 %}
6680 %}
6681
6682 // shift != 0, base != 0
6683 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
6684 match(Set dst (EncodePKlass src));
6685 //predicate(CompressedKlassPointers::shift() != 0 &&
6686 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/);
6687
6688 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6689 ins_cost(DEFAULT_COST*2); // Don't count constant.
6690 expand %{
6691 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %}
6692 iRegLdst base;
6693 loadConL_Ex(base, baseImm);
6694 encodePKlass_not_null_Ex(dst, base, src);
6695 %}
6696 %}
6697
6698 // Decode nodes.
6699
6700 // Shift node for expand.
6701 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
6702 // The match rule is needed to make it a 'MachTypeNode'!
6703 match(Set dst (DecodeNKlass src));
6704 predicate(false);
6705
6706 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %}
6707 size(4);
6708 ins_encode %{
6709 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6710 %}
6711 ins_pipe(pipe_class_default);
6712 %}
6713
6714 // Add node for expand.
6715
6716 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6717 // The match rule is needed to make it a 'MachTypeNode'!
6718 match(Set dst (DecodeNKlass (Binary base src)));
6719 predicate(false);
6720
6721 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
6722 size(4);
6723 ins_encode %{
6724 __ add($dst$$Register, $base$$Register, $src$$Register);
6725 %}
6726 ins_pipe(pipe_class_default);
6727 %}
6728
6729 // src != 0, shift != 0, base != 0
6730 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
6731 match(Set dst (DecodeNKlass (Binary base src)));
6732 //effect(kill src); // We need a register for the immediate result after shifting.
6733 predicate(false);
6734
6735 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != nullptr, postalloc expanded" %}
6736 postalloc_expand %{
6737 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode();
6738 n1->add_req(n_region, n_base, n_src);
6739 n1->_opnds[0] = op_dst;
6740 n1->_opnds[1] = op_base;
6741 n1->_opnds[2] = op_src;
6742 n1->_bottom_type = _bottom_type;
6743
6744 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode();
6745 n2->add_req(n_region, n1);
6746 n2->_opnds[0] = op_dst;
6747 n2->_opnds[1] = op_dst;
6748 n2->_bottom_type = _bottom_type;
6749
6750 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6751 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6752
6753 nodes->push(n1);
6754 nodes->push(n2);
6755 %}
6756 %}
6757
6758 // src != 0, shift != 0, base != 0
6759 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
6760 match(Set dst (DecodeNKlass src));
6761 // predicate(CompressedKlassPointers::shift() != 0 &&
6762 // CompressedKlassPointers::base() != 0);
6763
6764 //format %{ "DecodeNKlass $dst, $src \t// $src != nullptr, expanded" %}
6765
6766 ins_cost(DEFAULT_COST*2); // Don't count constant.
6767 expand %{
6768 // We add first, then we shift. Like this, we can get along with one register less.
6769 // But we have to load the base pre-shifted.
6770 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %}
6771 iRegLdst base;
6772 loadConL_Ex(base, baseImm);
6773 decodeNKlass_notNull_addBase_Ex(dst, base, src);
6774 %}
6775 %}
6776
6777 //----------MemBar Instructions-----------------------------------------------
6778 // Memory barrier flavors
6779
6780 instruct membar_acquire() %{
6781 match(LoadFence);
6782 ins_cost(4*MEMORY_REF_COST);
6783
6784 format %{ "MEMBAR-acquire" %}
6785 size(4);
6786 ins_encode %{
6787 __ acquire();
6788 %}
6789 ins_pipe(pipe_class_default);
6790 %}
6791
6792 instruct unnecessary_membar_acquire() %{
6793 match(MemBarAcquire);
6794 ins_cost(0);
6795
6796 format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
6797 size(0);
6798 ins_encode( /*empty*/ );
6799 ins_pipe(pipe_class_default);
6800 %}
6801
6802 instruct membar_acquire_lock() %{
6803 match(MemBarAcquireLock);
6804 ins_cost(0);
6805
6806 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
6807 size(0);
6808 ins_encode( /*empty*/ );
6809 ins_pipe(pipe_class_default);
6810 %}
6811
6812 instruct membar_release() %{
6813 match(MemBarRelease);
6814 match(StoreFence);
6815 ins_cost(4*MEMORY_REF_COST);
6816
6817 format %{ "MEMBAR-release" %}
6818 size(4);
6819 ins_encode %{
6820 __ release();
6821 %}
6822 ins_pipe(pipe_class_default);
6823 %}
6824
6825 instruct membar_storestore() %{
6826 match(MemBarStoreStore);
6827 match(StoreStoreFence);
6828 ins_cost(4*MEMORY_REF_COST);
6829
6830 format %{ "MEMBAR-store-store" %}
6831 size(4);
6832 ins_encode %{
6833 __ membar(Assembler::StoreStore);
6834 %}
6835 ins_pipe(pipe_class_default);
6836 %}
6837
6838 instruct membar_release_lock() %{
6839 match(MemBarReleaseLock);
6840 ins_cost(0);
6841
6842 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
6843 size(0);
6844 ins_encode( /*empty*/ );
6845 ins_pipe(pipe_class_default);
6846 %}
6847
6848 instruct membar_storeload() %{
6849 match(MemBarStoreLoad);
6850 ins_cost(4*MEMORY_REF_COST);
6851
6852 format %{ "MEMBAR-store-load" %}
6853 size(4);
6854 ins_encode %{
6855 __ fence();
6856 %}
6857 ins_pipe(pipe_class_default);
6858 %}
6859
6860 instruct membar_volatile() %{
6861 match(MemBarVolatile);
6862 ins_cost(4*MEMORY_REF_COST);
6863
6864 format %{ "MEMBAR-volatile" %}
6865 size(4);
6866 ins_encode %{
6867 __ fence();
6868 %}
6869 ins_pipe(pipe_class_default);
6870 %}
6871
6872 // This optimization is wrong on PPC. The following pattern is not supported:
6873 // MemBarVolatile
6874 // ^ ^
6875 // | |
6876 // CtrlProj MemProj
6877 // ^ ^
6878 // | |
6879 // | Load
6880 // |
6881 // MemBarVolatile
6882 //
6883 // The first MemBarVolatile could get optimized out! According to
6884 // Vladimir, this pattern can not occur on Oracle platforms.
6885 // However, it does occur on PPC64 (because of membars in
6886 // inline_unsafe_load_store).
6887 //
6888 // Add this node again if we found a good solution for inline_unsafe_load_store().
6889 // Don't forget to look at the implementation of post_store_load_barrier again,
6890 // we did other fixes in that method.
6891 //instruct unnecessary_membar_volatile() %{
6892 // match(MemBarVolatile);
6893 // predicate(Matcher::post_store_load_barrier(n));
6894 // ins_cost(0);
6895 //
6896 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
6897 // size(0);
6898 // ins_encode( /*empty*/ );
6899 // ins_pipe(pipe_class_default);
6900 //%}
6901
6902 instruct membar_full() %{
6903 match(MemBarFull);
6904 ins_cost(4*MEMORY_REF_COST);
6905
6906 format %{ "MEMBAR-full" %}
6907 size(4);
6908 ins_encode %{
6909 __ fence();
6910 %}
6911 ins_pipe(pipe_class_default);
6912 %}
6913
6914 instruct membar_CPUOrder() %{
6915 match(MemBarCPUOrder);
6916 ins_cost(0);
6917
6918 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
6919 size(0);
6920 ins_encode( /*empty*/ );
6921 ins_pipe(pipe_class_default);
6922 %}
6923
6924 instruct onspinwait() %{
6925 match(OnSpinWait);
6926 ins_cost(DEFAULT_COST);
6927
6928 format %{ "OnSpinWait (smt_prio_low ; smt_prio_medium)" %}
6929 size(8);
6930 ins_encode %{
6931 __ block_comment("spin_wait {");
6932 __ smt_prio_low();
6933 __ smt_prio_medium();
6934 __ block_comment("}");
6935 %}
6936 ins_pipe(pipe_class_default);
6937 %}
6938
6939 //----------Conditional Move---------------------------------------------------
6940
6941 // Cmove using isel.
6942 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
6943 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
6944 ins_cost(DEFAULT_COST);
6945
6946 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6947 size(4);
6948 ins_encode %{
6949 int cc = $cmp$$cmpcode;
6950 __ isel($dst$$Register, $crx$$CondRegister,
6951 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6952 %}
6953 ins_pipe(pipe_class_default);
6954 %}
6955
6956 // Cmove using isel.
6957 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
6958 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
6959 ins_cost(DEFAULT_COST);
6960
6961 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6962 size(4);
6963 ins_encode %{
6964 int cc = $cmp$$cmpcode;
6965 __ isel($dst$$Register, $crx$$CondRegister,
6966 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6967 %}
6968 ins_pipe(pipe_class_default);
6969 %}
6970
6971 // Cmove using isel.
6972 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
6973 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
6974 ins_cost(DEFAULT_COST);
6975
6976 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6977 size(4);
6978 ins_encode %{
6979 int cc = $cmp$$cmpcode;
6980 __ isel($dst$$Register, $crx$$CondRegister,
6981 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6982 %}
6983 ins_pipe(pipe_class_default);
6984 %}
6985
6986 // Cmove using isel.
6987 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
6988 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
6989 ins_cost(DEFAULT_COST);
6990
6991 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6992 size(4);
6993 ins_encode %{
6994 int cc = $cmp$$cmpcode;
6995 __ isel($dst$$Register, $crx$$CondRegister,
6996 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6997 %}
6998 ins_pipe(pipe_class_default);
6999 %}
7000
7001 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
7002 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
7003 ins_cost(DEFAULT_COST+BRANCH_COST);
7004
7005 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7006 size(8);
7007 ins_encode %{
7008 Label done;
7009 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7010 // Branch if not (cmp crx).
7011 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7012 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7013 __ bind(done);
7014 %}
7015 ins_pipe(pipe_class_default);
7016 %}
7017
7018 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7019 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7020 ins_cost(DEFAULT_COST+BRANCH_COST);
7021
7022 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7023 size(8);
7024 ins_encode %{
7025 Label done;
7026 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7027 // Branch if not (cmp crx).
7028 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7029 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7030 __ bind(done);
7031 %}
7032 ins_pipe(pipe_class_default);
7033 %}
7034
7035 instruct cmovF_cmpF(cmpOp cop, regF op1, regF op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7036 match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7037 predicate(PowerArchitecturePPC64 >= 9);
7038 effect(TEMP tmp);
7039 ins_cost(2*DEFAULT_COST);
7040 format %{ "cmovF_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7041 size(8);
7042 ins_encode %{
7043 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7044 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7045 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7046 $tmp$$FloatRegister->to_vsr());
7047 %}
7048 ins_pipe(pipe_class_default);
7049 %}
7050
7051 instruct cmovF_cmpD(cmpOp cop, regD op1, regD op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7052 match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7053 predicate(PowerArchitecturePPC64 >= 9);
7054 effect(TEMP tmp);
7055 ins_cost(2*DEFAULT_COST);
7056 format %{ "cmovF_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7057 size(8);
7058 ins_encode %{
7059 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7060 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7061 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7062 $tmp$$FloatRegister->to_vsr());
7063 %}
7064 ins_pipe(pipe_class_default);
7065 %}
7066
7067 instruct cmovD_cmpD(cmpOp cop, regD op1, regD op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7068 match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7069 predicate(PowerArchitecturePPC64 >= 9);
7070 effect(TEMP tmp);
7071 ins_cost(2*DEFAULT_COST);
7072 format %{ "cmovD_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7073 size(8);
7074 ins_encode %{
7075 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7076 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7077 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7078 $tmp$$FloatRegister->to_vsr());
7079 %}
7080 ins_pipe(pipe_class_default);
7081 %}
7082
7083 instruct cmovD_cmpF(cmpOp cop, regF op1, regF op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7084 match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7085 predicate(PowerArchitecturePPC64 >= 9);
7086 effect(TEMP tmp);
7087 ins_cost(2*DEFAULT_COST);
7088 format %{ "cmovD_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7089 size(8);
7090 ins_encode %{
7091 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7092 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7093 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7094 $tmp$$FloatRegister->to_vsr());
7095 %}
7096 ins_pipe(pipe_class_default);
7097 %}
7098
7099 //----------Compare-And-Swap---------------------------------------------------
7100
7101 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7102 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7103 // matched.
7104
7105 // Strong versions:
7106
7107 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7108 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7109 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7110 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7111 ins_encode %{
7112 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7113 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7114 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7115 $res$$Register, nullptr, true);
7116 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7117 __ isync();
7118 } else {
7119 __ sync();
7120 }
7121 %}
7122 ins_pipe(pipe_class_default);
7123 %}
7124
7125 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7126 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7127 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7128 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7129 ins_encode %{
7130 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7131 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7132 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7133 $res$$Register, nullptr, true);
7134 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7135 __ isync();
7136 } else {
7137 __ sync();
7138 }
7139 %}
7140 ins_pipe(pipe_class_default);
7141 %}
7142
7143 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7144 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7145 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7146 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7147 ins_encode %{
7148 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7149 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7150 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7151 $res$$Register, nullptr, true);
7152 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7153 __ isync();
7154 } else {
7155 __ sync();
7156 }
7157 %}
7158 ins_pipe(pipe_class_default);
7159 %}
7160
7161 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7162 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7163 predicate(n->as_LoadStore()->barrier_data() == 0);
7164 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7165 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7166 ins_encode %{
7167 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7168 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7169 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7170 $res$$Register, nullptr, true);
7171 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7172 __ isync();
7173 } else {
7174 __ sync();
7175 }
7176 %}
7177 ins_pipe(pipe_class_default);
7178 %}
7179
7180 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7181 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7182 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7183 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7184 ins_encode %{
7185 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7186 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7187 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7188 $res$$Register, nullptr, true);
7189 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7190 __ isync();
7191 } else {
7192 __ sync();
7193 }
7194 %}
7195 ins_pipe(pipe_class_default);
7196 %}
7197
7198 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7199 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7200 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7201 predicate(n->as_LoadStore()->barrier_data() == 0);
7202 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7203 ins_encode %{
7204 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7205 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7206 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7207 $res$$Register, nullptr, true);
7208 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7209 __ isync();
7210 } else {
7211 __ sync();
7212 }
7213 %}
7214 ins_pipe(pipe_class_default);
7215 %}
7216
7217 // Weak versions:
7218
7219 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7220 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7221 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7222 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7223 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7224 ins_encode %{
7225 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7226 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7227 MacroAssembler::MemBarNone,
7228 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7229 %}
7230 ins_pipe(pipe_class_default);
7231 %}
7232
7233 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7234 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7235 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) );
7236 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7237 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7238 ins_encode %{
7239 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7240 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7241 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7242 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7243 %}
7244 ins_pipe(pipe_class_default);
7245 %}
7246
7247 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7248 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7249 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7250 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7251 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7252 ins_encode %{
7253 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7254 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7255 MacroAssembler::MemBarNone,
7256 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7257 %}
7258 ins_pipe(pipe_class_default);
7259 %}
7260
7261 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7262 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7263 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7264 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7265 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7266 ins_encode %{
7267 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7268 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7269 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7270 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7271 %}
7272 ins_pipe(pipe_class_default);
7273 %}
7274
7275 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7276 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7277 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7278 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7279 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7280 ins_encode %{
7281 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7282 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7283 MacroAssembler::MemBarNone,
7284 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7285 %}
7286 ins_pipe(pipe_class_default);
7287 %}
7288
7289 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7290 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7291 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7292 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7293 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7294 ins_encode %{
7295 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7296 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7297 // value is never passed to caller.
7298 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7299 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7300 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7301 %}
7302 ins_pipe(pipe_class_default);
7303 %}
7304
7305 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7306 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7307 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7308 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7309 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7310 ins_encode %{
7311 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7312 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7313 MacroAssembler::MemBarNone,
7314 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7315 %}
7316 ins_pipe(pipe_class_default);
7317 %}
7318
7319 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7320 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7321 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7322 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7323 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7324 ins_encode %{
7325 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7326 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7327 // value is never passed to caller.
7328 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7329 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7330 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7331 %}
7332 ins_pipe(pipe_class_default);
7333 %}
7334
7335 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7336 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7337 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7338 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7339 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7340 ins_encode %{
7341 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7342 // value is never passed to caller.
7343 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7344 MacroAssembler::MemBarNone,
7345 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7346 %}
7347 ins_pipe(pipe_class_default);
7348 %}
7349
7350 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7351 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7352 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7353 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7354 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7355 ins_encode %{
7356 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7357 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7358 // value is never passed to caller.
7359 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7360 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7361 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7362 %}
7363 ins_pipe(pipe_class_default);
7364 %}
7365
7366 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7367 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7368 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7369 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7370 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7371 ins_encode %{
7372 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7373 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7374 MacroAssembler::MemBarNone,
7375 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7376 %}
7377 ins_pipe(pipe_class_default);
7378 %}
7379
7380 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7381 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7382 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7383 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7384 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7385 ins_encode %{
7386 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7387 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7388 // value is never passed to caller.
7389 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7390 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7391 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7392 %}
7393 ins_pipe(pipe_class_default);
7394 %}
7395
7396 // CompareAndExchange
7397
7398 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7399 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7400 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7401 effect(TEMP_DEF res, TEMP cr0);
7402 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7403 ins_encode %{
7404 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7405 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7406 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7407 noreg, nullptr, true);
7408 %}
7409 ins_pipe(pipe_class_default);
7410 %}
7411
7412 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7413 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7414 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7415 effect(TEMP_DEF res, TEMP cr0);
7416 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7417 ins_encode %{
7418 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7419 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7420 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7421 noreg, nullptr, true);
7422 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7423 __ isync();
7424 } else {
7425 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7426 __ sync();
7427 }
7428 %}
7429 ins_pipe(pipe_class_default);
7430 %}
7431
7432
7433 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7434 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7435 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7436 effect(TEMP_DEF res, TEMP cr0);
7437 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7438 ins_encode %{
7439 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7440 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7441 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7442 noreg, nullptr, true);
7443 %}
7444 ins_pipe(pipe_class_default);
7445 %}
7446
7447 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7448 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7449 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7450 effect(TEMP_DEF res, TEMP cr0);
7451 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7452 ins_encode %{
7453 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7454 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7455 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7456 noreg, nullptr, true);
7457 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7458 __ isync();
7459 } else {
7460 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7461 __ sync();
7462 }
7463 %}
7464 ins_pipe(pipe_class_default);
7465 %}
7466
7467 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7468 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7469 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7470 effect(TEMP_DEF res, TEMP cr0);
7471 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
7472 ins_encode %{
7473 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7474 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7475 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7476 noreg, nullptr, true);
7477 %}
7478 ins_pipe(pipe_class_default);
7479 %}
7480
7481 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7482 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7483 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7484 effect(TEMP_DEF res, TEMP cr0);
7485 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
7486 ins_encode %{
7487 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7488 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7489 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7490 noreg, nullptr, true);
7491 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7492 __ isync();
7493 } else {
7494 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7495 __ sync();
7496 }
7497 %}
7498 ins_pipe(pipe_class_default);
7499 %}
7500
7501 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7502 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7503 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7504 effect(TEMP_DEF res, TEMP cr0);
7505 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7506 ins_encode %{
7507 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7508 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7509 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7510 noreg, nullptr, true);
7511 %}
7512 ins_pipe(pipe_class_default);
7513 %}
7514
7515 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7516 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7517 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7518 effect(TEMP_DEF res, TEMP cr0);
7519 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7520 ins_encode %{
7521 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7522 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7523 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7524 noreg, nullptr, true);
7525 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7526 __ isync();
7527 } else {
7528 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7529 __ sync();
7530 }
7531 %}
7532 ins_pipe(pipe_class_default);
7533 %}
7534
7535 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7536 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7537 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7538 effect(TEMP_DEF res, TEMP cr0);
7539 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
7540 ins_encode %{
7541 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7542 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7543 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7544 noreg, nullptr, true);
7545 %}
7546 ins_pipe(pipe_class_default);
7547 %}
7548
7549 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7550 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7551 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7552 effect(TEMP_DEF res, TEMP cr0);
7553 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
7554 ins_encode %{
7555 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7556 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7557 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7558 noreg, nullptr, true);
7559 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7560 __ isync();
7561 } else {
7562 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7563 __ sync();
7564 }
7565 %}
7566 ins_pipe(pipe_class_default);
7567 %}
7568
7569 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7570 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7571 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst)
7572 && n->as_LoadStore()->barrier_data() == 0);
7573 effect(TEMP_DEF res, TEMP cr0);
7574 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7575 ins_encode %{
7576 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7577 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7578 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7579 noreg, nullptr, true);
7580 %}
7581 ins_pipe(pipe_class_default);
7582 %}
7583
7584 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7585 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7586 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst)
7587 && n->as_LoadStore()->barrier_data() == 0);
7588 effect(TEMP_DEF res, TEMP cr0);
7589 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7590 ins_encode %{
7591 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7592 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7593 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7594 noreg, nullptr, true);
7595 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7596 __ isync();
7597 } else {
7598 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7599 __ sync();
7600 }
7601 %}
7602 ins_pipe(pipe_class_default);
7603 %}
7604
7605 // Special RMW
7606
7607 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7608 match(Set res (GetAndAddB mem_ptr src));
7609 effect(TEMP_DEF res, TEMP cr0);
7610 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
7611 ins_encode %{
7612 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
7613 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7614 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7615 __ isync();
7616 } else {
7617 __ sync();
7618 }
7619 %}
7620 ins_pipe(pipe_class_default);
7621 %}
7622
7623 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7624 match(Set res (GetAndAddS mem_ptr src));
7625 effect(TEMP_DEF res, TEMP cr0);
7626 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
7627 ins_encode %{
7628 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
7629 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7630 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7631 __ isync();
7632 } else {
7633 __ sync();
7634 }
7635 %}
7636 ins_pipe(pipe_class_default);
7637 %}
7638
7639
7640 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7641 match(Set res (GetAndAddI mem_ptr src));
7642 effect(TEMP_DEF res, TEMP cr0);
7643 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
7644 ins_encode %{
7645 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
7646 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7647 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7648 __ isync();
7649 } else {
7650 __ sync();
7651 }
7652 %}
7653 ins_pipe(pipe_class_default);
7654 %}
7655
7656 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7657 match(Set res (GetAndAddL mem_ptr src));
7658 effect(TEMP_DEF res, TEMP cr0);
7659 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
7660 ins_encode %{
7661 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
7662 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7663 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7664 __ isync();
7665 } else {
7666 __ sync();
7667 }
7668 %}
7669 ins_pipe(pipe_class_default);
7670 %}
7671
7672 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7673 match(Set res (GetAndSetB mem_ptr src));
7674 effect(TEMP_DEF res, TEMP cr0);
7675 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
7676 ins_encode %{
7677 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
7678 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7679 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7680 __ isync();
7681 } else {
7682 __ sync();
7683 }
7684 %}
7685 ins_pipe(pipe_class_default);
7686 %}
7687
7688 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7689 match(Set res (GetAndSetS mem_ptr src));
7690 effect(TEMP_DEF res, TEMP cr0);
7691 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
7692 ins_encode %{
7693 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
7694 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7695 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7696 __ isync();
7697 } else {
7698 __ sync();
7699 }
7700 %}
7701 ins_pipe(pipe_class_default);
7702 %}
7703
7704
7705 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7706 match(Set res (GetAndSetI mem_ptr src));
7707 effect(TEMP_DEF res, TEMP cr0);
7708 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
7709 ins_encode %{
7710 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7711 MacroAssembler::cmpxchgx_hint_atomic_update());
7712 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7713 __ isync();
7714 } else {
7715 __ sync();
7716 }
7717 %}
7718 ins_pipe(pipe_class_default);
7719 %}
7720
7721 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7722 match(Set res (GetAndSetL mem_ptr src));
7723 effect(TEMP_DEF res, TEMP cr0);
7724 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
7725 ins_encode %{
7726 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7727 MacroAssembler::cmpxchgx_hint_atomic_update());
7728 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7729 __ isync();
7730 } else {
7731 __ sync();
7732 }
7733 %}
7734 ins_pipe(pipe_class_default);
7735 %}
7736
7737 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
7738 match(Set res (GetAndSetP mem_ptr src));
7739 predicate(n->as_LoadStore()->barrier_data() == 0);
7740 effect(TEMP_DEF res, TEMP cr0);
7741 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
7742 ins_encode %{
7743 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7744 MacroAssembler::cmpxchgx_hint_atomic_update());
7745 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7746 __ isync();
7747 } else {
7748 __ sync();
7749 }
7750 %}
7751 ins_pipe(pipe_class_default);
7752 %}
7753
7754 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
7755 match(Set res (GetAndSetN mem_ptr src));
7756 predicate(n->as_LoadStore()->barrier_data() == 0);
7757 effect(TEMP_DEF res, TEMP cr0);
7758 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
7759 ins_encode %{
7760 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7761 MacroAssembler::cmpxchgx_hint_atomic_update());
7762 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7763 __ isync();
7764 } else {
7765 __ sync();
7766 }
7767 %}
7768 ins_pipe(pipe_class_default);
7769 %}
7770
7771 //----------Arithmetic Instructions--------------------------------------------
7772 // Addition Instructions
7773
7774 // Register Addition
7775 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
7776 match(Set dst (AddI src1 src2));
7777 format %{ "ADD $dst, $src1, $src2" %}
7778 size(4);
7779 ins_encode %{
7780 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7781 %}
7782 ins_pipe(pipe_class_default);
7783 %}
7784
7785 // Expand does not work with above instruct. (??)
7786 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7787 // no match-rule
7788 effect(DEF dst, USE src1, USE src2);
7789 format %{ "ADD $dst, $src1, $src2" %}
7790 size(4);
7791 ins_encode %{
7792 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7793 %}
7794 ins_pipe(pipe_class_default);
7795 %}
7796
7797 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
7798 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
7799 ins_cost(DEFAULT_COST*3);
7800
7801 expand %{
7802 // FIXME: we should do this in the ideal world.
7803 iRegIdst tmp1;
7804 iRegIdst tmp2;
7805 addI_reg_reg(tmp1, src1, src2);
7806 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
7807 addI_reg_reg(dst, tmp1, tmp2);
7808 %}
7809 %}
7810
7811 // Immediate Addition
7812 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
7813 match(Set dst (AddI src1 src2));
7814 format %{ "ADDI $dst, $src1, $src2" %}
7815 size(4);
7816 ins_encode %{
7817 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7818 %}
7819 ins_pipe(pipe_class_default);
7820 %}
7821
7822 // Immediate Addition with 16-bit shifted operand
7823 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
7824 match(Set dst (AddI src1 src2));
7825 format %{ "ADDIS $dst, $src1, $src2" %}
7826 size(4);
7827 ins_encode %{
7828 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7829 %}
7830 ins_pipe(pipe_class_default);
7831 %}
7832
7833 // Immediate Addition using prefixed addi
7834 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{
7835 match(Set dst (AddI src1 src2));
7836 predicate(PowerArchitecturePPC64 >= 10);
7837 ins_cost(DEFAULT_COST+1);
7838 format %{ "PADDI $dst, $src1, $src2" %}
7839 size(8);
7840 ins_encode %{
7841 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7842 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7843 %}
7844 ins_pipe(pipe_class_default);
7845 ins_alignment(2);
7846 %}
7847
7848 // Long Addition
7849 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7850 match(Set dst (AddL src1 src2));
7851 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7852 size(4);
7853 ins_encode %{
7854 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7855 %}
7856 ins_pipe(pipe_class_default);
7857 %}
7858
7859 // Expand does not work with above instruct. (??)
7860 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7861 // no match-rule
7862 effect(DEF dst, USE src1, USE src2);
7863 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7864 size(4);
7865 ins_encode %{
7866 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7867 %}
7868 ins_pipe(pipe_class_default);
7869 %}
7870
7871 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
7872 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
7873 ins_cost(DEFAULT_COST*3);
7874
7875 expand %{
7876 // FIXME: we should do this in the ideal world.
7877 iRegLdst tmp1;
7878 iRegLdst tmp2;
7879 addL_reg_reg(tmp1, src1, src2);
7880 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
7881 addL_reg_reg(dst, tmp1, tmp2);
7882 %}
7883 %}
7884
7885 // AddL + ConvL2I.
7886 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
7887 match(Set dst (ConvL2I (AddL src1 src2)));
7888
7889 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %}
7890 size(4);
7891 ins_encode %{
7892 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7893 %}
7894 ins_pipe(pipe_class_default);
7895 %}
7896
7897 // No constant pool entries required.
7898 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
7899 match(Set dst (AddL src1 src2));
7900
7901 format %{ "ADDI $dst, $src1, $src2" %}
7902 size(4);
7903 ins_encode %{
7904 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7905 %}
7906 ins_pipe(pipe_class_default);
7907 %}
7908
7909 // Long Immediate Addition with 16-bit shifted operand.
7910 // No constant pool entries required.
7911 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
7912 match(Set dst (AddL src1 src2));
7913
7914 format %{ "ADDIS $dst, $src1, $src2" %}
7915 size(4);
7916 ins_encode %{
7917 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7918 %}
7919 ins_pipe(pipe_class_default);
7920 %}
7921
7922 // Long Immediate Addition using prefixed addi
7923 // No constant pool entries required.
7924 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{
7925 match(Set dst (AddL src1 src2));
7926 predicate(PowerArchitecturePPC64 >= 10);
7927 ins_cost(DEFAULT_COST+1);
7928
7929 format %{ "PADDI $dst, $src1, $src2" %}
7930 size(8);
7931 ins_encode %{
7932 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7933 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7934 %}
7935 ins_pipe(pipe_class_default);
7936 ins_alignment(2);
7937 %}
7938
7939 // Pointer Register Addition
7940 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
7941 match(Set dst (AddP src1 src2));
7942 format %{ "ADD $dst, $src1, $src2" %}
7943 size(4);
7944 ins_encode %{
7945 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7946 %}
7947 ins_pipe(pipe_class_default);
7948 %}
7949
7950 // Pointer Immediate Addition
7951 // No constant pool entries required.
7952 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
7953 match(Set dst (AddP src1 src2));
7954
7955 format %{ "ADDI $dst, $src1, $src2" %}
7956 size(4);
7957 ins_encode %{
7958 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7959 %}
7960 ins_pipe(pipe_class_default);
7961 %}
7962
7963 // Pointer Immediate Addition with 16-bit shifted operand.
7964 // No constant pool entries required.
7965 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
7966 match(Set dst (AddP src1 src2));
7967
7968 format %{ "ADDIS $dst, $src1, $src2" %}
7969 size(4);
7970 ins_encode %{
7971 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7972 %}
7973 ins_pipe(pipe_class_default);
7974 %}
7975
7976 // Pointer Immediate Addition using prefixed addi
7977 // No constant pool entries required.
7978 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{
7979 match(Set dst (AddP src1 src2));
7980 predicate(PowerArchitecturePPC64 >= 10);
7981 ins_cost(DEFAULT_COST+1);
7982
7983 format %{ "PADDI $dst, $src1, $src2" %}
7984 size(8);
7985 ins_encode %{
7986 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7987 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7988 %}
7989 ins_pipe(pipe_class_default);
7990 ins_alignment(2);
7991 %}
7992
7993 //---------------------
7994 // Subtraction Instructions
7995
7996 // Register Subtraction
7997 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7998 match(Set dst (SubI src1 src2));
7999 format %{ "SUBF $dst, $src2, $src1" %}
8000 size(4);
8001 ins_encode %{
8002 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8003 %}
8004 ins_pipe(pipe_class_default);
8005 %}
8006
8007 // Immediate Subtraction
8008 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
8009 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
8010
8011 // SubI from constant (using subfic).
8012 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
8013 match(Set dst (SubI src1 src2));
8014 format %{ "SUBI $dst, $src1, $src2" %}
8015
8016 size(4);
8017 ins_encode %{
8018 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
8019 %}
8020 ins_pipe(pipe_class_default);
8021 %}
8022
8023 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
8024 // positive integers and 0xF...F for negative ones.
8025 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
8026 // no match-rule, false predicate
8027 effect(DEF dst, USE src);
8028 predicate(false);
8029
8030 format %{ "SRAWI $dst, $src, #31" %}
8031 size(4);
8032 ins_encode %{
8033 __ srawi($dst$$Register, $src$$Register, 0x1f);
8034 %}
8035 ins_pipe(pipe_class_default);
8036 %}
8037
8038 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
8039 match(Set dst (AbsI src));
8040 ins_cost(DEFAULT_COST*3);
8041
8042 expand %{
8043 iRegIdst tmp1;
8044 iRegIdst tmp2;
8045 signmask32I_regI(tmp1, src);
8046 xorI_reg_reg(tmp2, tmp1, src);
8047 subI_reg_reg(dst, tmp2, tmp1);
8048 %}
8049 %}
8050
8051 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
8052 match(Set dst (SubI zero src2));
8053 format %{ "NEG $dst, $src2" %}
8054 size(4);
8055 ins_encode %{
8056 __ neg($dst$$Register, $src2$$Register);
8057 %}
8058 ins_pipe(pipe_class_default);
8059 %}
8060
8061 // Long subtraction
8062 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8063 match(Set dst (SubL src1 src2));
8064 format %{ "SUBF $dst, $src2, $src1 \t// long" %}
8065 size(4);
8066 ins_encode %{
8067 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8068 %}
8069 ins_pipe(pipe_class_default);
8070 %}
8071
8072 // SubL + convL2I.
8073 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8074 match(Set dst (ConvL2I (SubL src1 src2)));
8075
8076 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
8077 size(4);
8078 ins_encode %{
8079 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8080 %}
8081 ins_pipe(pipe_class_default);
8082 %}
8083
8084 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8085 // positive longs and 0xF...F for negative ones.
8086 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8087 // no match-rule, false predicate
8088 effect(DEF dst, USE src);
8089 predicate(false);
8090
8091 format %{ "SRADI $dst, $src, #63" %}
8092 size(4);
8093 ins_encode %{
8094 __ sradi($dst$$Register, $src$$Register, 0x3f);
8095 %}
8096 ins_pipe(pipe_class_default);
8097 %}
8098
8099 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8100 // positive longs and 0xF...F for negative ones.
8101 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8102 // no match-rule, false predicate
8103 effect(DEF dst, USE src);
8104 predicate(false);
8105
8106 format %{ "SRADI $dst, $src, #63" %}
8107 size(4);
8108 ins_encode %{
8109 __ sradi($dst$$Register, $src$$Register, 0x3f);
8110 %}
8111 ins_pipe(pipe_class_default);
8112 %}
8113
8114 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{
8115 match(Set dst (AbsL src));
8116 ins_cost(DEFAULT_COST*3);
8117
8118 expand %{
8119 iRegLdst tmp1;
8120 iRegLdst tmp2;
8121 signmask64L_regL(tmp1, src);
8122 xorL_reg_reg(tmp2, tmp1, src);
8123 subL_reg_reg(dst, tmp2, tmp1);
8124 %}
8125 %}
8126
8127 // Long negation
8128 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8129 match(Set dst (SubL zero src2));
8130 format %{ "NEG $dst, $src2 \t// long" %}
8131 size(4);
8132 ins_encode %{
8133 __ neg($dst$$Register, $src2$$Register);
8134 %}
8135 ins_pipe(pipe_class_default);
8136 %}
8137
8138 // NegL + ConvL2I.
8139 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8140 match(Set dst (ConvL2I (SubL zero src2)));
8141
8142 format %{ "NEG $dst, $src2 \t// long + l2i" %}
8143 size(4);
8144 ins_encode %{
8145 __ neg($dst$$Register, $src2$$Register);
8146 %}
8147 ins_pipe(pipe_class_default);
8148 %}
8149
8150 // Multiplication Instructions
8151 // Integer Multiplication
8152
8153 // Register Multiplication
8154 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8155 match(Set dst (MulI src1 src2));
8156 ins_cost(DEFAULT_COST);
8157
8158 format %{ "MULLW $dst, $src1, $src2" %}
8159 size(4);
8160 ins_encode %{
8161 __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8162 %}
8163 ins_pipe(pipe_class_default);
8164 %}
8165
8166 // Immediate Multiplication
8167 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8168 match(Set dst (MulI src1 src2));
8169 ins_cost(DEFAULT_COST);
8170
8171 format %{ "MULLI $dst, $src1, $src2" %}
8172 size(4);
8173 ins_encode %{
8174 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8175 %}
8176 ins_pipe(pipe_class_default);
8177 %}
8178
8179 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8180 match(Set dst (MulL src1 src2));
8181 ins_cost(DEFAULT_COST);
8182
8183 format %{ "MULLD $dst $src1, $src2 \t// long" %}
8184 size(4);
8185 ins_encode %{
8186 __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8187 %}
8188 ins_pipe(pipe_class_default);
8189 %}
8190
8191 // Multiply high for optimized long division by constant.
8192 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8193 match(Set dst (MulHiL src1 src2));
8194 ins_cost(DEFAULT_COST);
8195
8196 format %{ "MULHD $dst $src1, $src2 \t// long" %}
8197 size(4);
8198 ins_encode %{
8199 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8200 %}
8201 ins_pipe(pipe_class_default);
8202 %}
8203
8204 instruct uMulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8205 match(Set dst (UMulHiL src1 src2));
8206 ins_cost(DEFAULT_COST);
8207
8208 format %{ "MULHDU $dst $src1, $src2 \t// unsigned long" %}
8209 size(4);
8210 ins_encode %{
8211 __ mulhdu($dst$$Register, $src1$$Register, $src2$$Register);
8212 %}
8213 ins_pipe(pipe_class_default);
8214 %}
8215
8216 // Immediate Multiplication
8217 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8218 match(Set dst (MulL src1 src2));
8219 ins_cost(DEFAULT_COST);
8220
8221 format %{ "MULLI $dst, $src1, $src2" %}
8222 size(4);
8223 ins_encode %{
8224 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8225 %}
8226 ins_pipe(pipe_class_default);
8227 %}
8228
8229 // Integer Division with Immediate -1: Negate.
8230 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8231 match(Set dst (DivI src1 src2));
8232 ins_cost(DEFAULT_COST);
8233
8234 format %{ "NEG $dst, $src1 \t// /-1" %}
8235 size(4);
8236 ins_encode %{
8237 __ neg($dst$$Register, $src1$$Register);
8238 %}
8239 ins_pipe(pipe_class_default);
8240 %}
8241
8242 // Integer Division with constant, but not -1.
8243 // We should be able to improve this by checking the type of src2.
8244 // It might well be that src2 is known to be positive.
8245 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8246 match(Set dst (DivI src1 src2));
8247 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8248 ins_cost(2*DEFAULT_COST);
8249
8250 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8251 size(4);
8252 ins_encode %{
8253 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8254 %}
8255 ins_pipe(pipe_class_default);
8256 %}
8257
8258 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8259 effect(USE_DEF dst, USE src1, USE crx);
8260 predicate(false);
8261
8262 format %{ "CMOVE $dst, neg($src1), $crx" %}
8263 size(8);
8264 ins_encode %{
8265 Label done;
8266 __ bne($crx$$CondRegister, done);
8267 __ neg($dst$$Register, $src1$$Register);
8268 __ bind(done);
8269 %}
8270 ins_pipe(pipe_class_default);
8271 %}
8272
8273 // Integer Division with Registers not containing constants.
8274 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8275 match(Set dst (DivI src1 src2));
8276 ins_cost(10*DEFAULT_COST);
8277
8278 expand %{
8279 immI16 imm %{ (int)-1 %}
8280 flagsReg tmp1;
8281 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8282 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8283 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8284 %}
8285 %}
8286
8287 // Long Division with Immediate -1: Negate.
8288 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8289 match(Set dst (DivL src1 src2));
8290 ins_cost(DEFAULT_COST);
8291
8292 format %{ "NEG $dst, $src1 \t// /-1, long" %}
8293 size(4);
8294 ins_encode %{
8295 __ neg($dst$$Register, $src1$$Register);
8296 %}
8297 ins_pipe(pipe_class_default);
8298 %}
8299
8300 // Long Division with constant, but not -1.
8301 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8302 match(Set dst (DivL src1 src2));
8303 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8304 ins_cost(2*DEFAULT_COST);
8305
8306 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8307 size(4);
8308 ins_encode %{
8309 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8310 %}
8311 ins_pipe(pipe_class_default);
8312 %}
8313
8314 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8315 effect(USE_DEF dst, USE src1, USE crx);
8316 predicate(false);
8317
8318 format %{ "CMOVE $dst, neg($src1), $crx" %}
8319 size(8);
8320 ins_encode %{
8321 Label done;
8322 __ bne($crx$$CondRegister, done);
8323 __ neg($dst$$Register, $src1$$Register);
8324 __ bind(done);
8325 %}
8326 ins_pipe(pipe_class_default);
8327 %}
8328
8329 // Long Division with Registers not containing constants.
8330 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8331 match(Set dst (DivL src1 src2));
8332 ins_cost(10*DEFAULT_COST);
8333
8334 expand %{
8335 immL16 imm %{ (int)-1 %}
8336 flagsReg tmp1;
8337 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8338 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8339 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8340 %}
8341 %}
8342
8343 // Integer Remainder with registers.
8344 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8345 match(Set dst (ModI src1 src2));
8346 ins_cost(10*DEFAULT_COST);
8347
8348 expand %{
8349 immI16 imm %{ (int)-1 %}
8350 flagsReg tmp1;
8351 iRegIdst tmp2;
8352 iRegIdst tmp3;
8353 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8354 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8355 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8356 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8357 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8358 %}
8359 %}
8360
8361 // Long Remainder with registers
8362 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8363 match(Set dst (ModL src1 src2));
8364 ins_cost(10*DEFAULT_COST);
8365
8366 expand %{
8367 immL16 imm %{ (int)-1 %}
8368 flagsReg tmp1;
8369 iRegLdst tmp2;
8370 iRegLdst tmp3;
8371 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8372 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8373 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8374 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8375 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8376 %}
8377 %}
8378
8379 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8380 match(Set dst (UDivI src1 src2));
8381 format %{ "DIVWU $dst, $src1, $src2" %}
8382 size(4);
8383 ins_encode %{
8384 __ divwu($dst$$Register, $src1$$Register, $src2$$Register);
8385 %}
8386 ins_pipe(pipe_class_default);
8387 %}
8388
8389 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8390 match(Set dst (UModI src1 src2));
8391 expand %{
8392 iRegIdst tmp1;
8393 iRegIdst tmp2;
8394 udivI_reg_reg(tmp1, src1, src2);
8395 // Compute lower 32 bit result using signed instructions as suggested by ISA.
8396 // Upper 32 bit will contain garbage.
8397 mulI_reg_reg(tmp2, src2, tmp1);
8398 subI_reg_reg(dst, src1, tmp2);
8399 %}
8400 %}
8401
8402 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8403 match(Set dst (UDivL src1 src2));
8404 format %{ "DIVDU $dst, $src1, $src2" %}
8405 size(4);
8406 ins_encode %{
8407 __ divdu($dst$$Register, $src1$$Register, $src2$$Register);
8408 %}
8409 ins_pipe(pipe_class_default);
8410 %}
8411
8412 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8413 match(Set dst (UModL src1 src2));
8414 expand %{
8415 iRegLdst tmp1;
8416 iRegLdst tmp2;
8417 udivL_reg_reg(tmp1, src1, src2);
8418 mulL_reg_reg(tmp2, src2, tmp1);
8419 subL_reg_reg(dst, src1, tmp2);
8420 %}
8421 %}
8422
8423 // Integer Shift Instructions
8424
8425 // Register Shift Left
8426
8427 // Clear all but the lowest #mask bits.
8428 // Used to normalize shift amounts in registers.
8429 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
8430 // no match-rule, false predicate
8431 effect(DEF dst, USE src, USE mask);
8432 predicate(false);
8433
8434 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %}
8435 size(4);
8436 ins_encode %{
8437 __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
8438 %}
8439 ins_pipe(pipe_class_default);
8440 %}
8441
8442 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8443 // no match-rule, false predicate
8444 effect(DEF dst, USE src1, USE src2);
8445 predicate(false);
8446
8447 format %{ "SLW $dst, $src1, $src2" %}
8448 size(4);
8449 ins_encode %{
8450 __ slw($dst$$Register, $src1$$Register, $src2$$Register);
8451 %}
8452 ins_pipe(pipe_class_default);
8453 %}
8454
8455 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8456 match(Set dst (LShiftI src1 src2));
8457 ins_cost(DEFAULT_COST*2);
8458 expand %{
8459 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8460 iRegIdst tmpI;
8461 maskI_reg_imm(tmpI, src2, mask);
8462 lShiftI_reg_reg(dst, src1, tmpI);
8463 %}
8464 %}
8465
8466 // Register Shift Left Immediate
8467 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8468 match(Set dst (LShiftI src1 src2));
8469
8470 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %}
8471 size(4);
8472 ins_encode %{
8473 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8474 %}
8475 ins_pipe(pipe_class_default);
8476 %}
8477
8478 // AndI with negpow2-constant + LShiftI
8479 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8480 match(Set dst (LShiftI (AndI src1 src2) src3));
8481 predicate(UseRotateAndMaskInstructionsPPC64);
8482
8483 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %}
8484 size(4);
8485 ins_encode %{
8486 long src3 = $src3$$constant;
8487 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8488 if (maskbits >= 32) {
8489 __ li($dst$$Register, 0); // addi
8490 } else {
8491 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
8492 }
8493 %}
8494 ins_pipe(pipe_class_default);
8495 %}
8496
8497 // RShiftI + AndI with negpow2-constant + LShiftI
8498 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8499 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
8500 predicate(UseRotateAndMaskInstructionsPPC64);
8501
8502 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
8503 size(4);
8504 ins_encode %{
8505 long src3 = $src3$$constant;
8506 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8507 if (maskbits >= 32) {
8508 __ li($dst$$Register, 0); // addi
8509 } else {
8510 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
8511 }
8512 %}
8513 ins_pipe(pipe_class_default);
8514 %}
8515
8516 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8517 // no match-rule, false predicate
8518 effect(DEF dst, USE src1, USE src2);
8519 predicate(false);
8520
8521 format %{ "SLD $dst, $src1, $src2" %}
8522 size(4);
8523 ins_encode %{
8524 __ sld($dst$$Register, $src1$$Register, $src2$$Register);
8525 %}
8526 ins_pipe(pipe_class_default);
8527 %}
8528
8529 // Register Shift Left
8530 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8531 match(Set dst (LShiftL src1 src2));
8532 ins_cost(DEFAULT_COST*2);
8533 expand %{
8534 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8535 iRegIdst tmpI;
8536 maskI_reg_imm(tmpI, src2, mask);
8537 lShiftL_regL_regI(dst, src1, tmpI);
8538 %}
8539 %}
8540
8541 // Register Shift Left Immediate
8542 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8543 match(Set dst (LShiftL src1 src2));
8544 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %}
8545 size(4);
8546 ins_encode %{
8547 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8548 %}
8549 ins_pipe(pipe_class_default);
8550 %}
8551
8552 // If we shift more than 32 bits, we need not convert I2L.
8553 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
8554 match(Set dst (LShiftL (ConvI2L src1) src2));
8555 ins_cost(DEFAULT_COST);
8556
8557 size(4);
8558 format %{ "SLDI $dst, i2l($src1), $src2" %}
8559 ins_encode %{
8560 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8561 %}
8562 ins_pipe(pipe_class_default);
8563 %}
8564
8565 // Shift a postivie int to the left.
8566 // Clrlsldi clears the upper 32 bits and shifts.
8567 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
8568 match(Set dst (LShiftL (ConvI2L src1) src2));
8569 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
8570
8571 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %}
8572 size(4);
8573 ins_encode %{
8574 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
8575 %}
8576 ins_pipe(pipe_class_default);
8577 %}
8578
8579 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8580 // no match-rule, false predicate
8581 effect(DEF dst, USE src1, USE src2);
8582 predicate(false);
8583
8584 format %{ "SRAW $dst, $src1, $src2" %}
8585 size(4);
8586 ins_encode %{
8587 __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
8588 %}
8589 ins_pipe(pipe_class_default);
8590 %}
8591
8592 // Register Arithmetic Shift Right
8593 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8594 match(Set dst (RShiftI src1 src2));
8595 ins_cost(DEFAULT_COST*2);
8596 expand %{
8597 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8598 iRegIdst tmpI;
8599 maskI_reg_imm(tmpI, src2, mask);
8600 arShiftI_reg_reg(dst, src1, tmpI);
8601 %}
8602 %}
8603
8604 // Register Arithmetic Shift Right Immediate
8605 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8606 match(Set dst (RShiftI src1 src2));
8607
8608 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %}
8609 size(4);
8610 ins_encode %{
8611 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8612 %}
8613 ins_pipe(pipe_class_default);
8614 %}
8615
8616 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8617 // no match-rule, false predicate
8618 effect(DEF dst, USE src1, USE src2);
8619 predicate(false);
8620
8621 format %{ "SRAD $dst, $src1, $src2" %}
8622 size(4);
8623 ins_encode %{
8624 __ srad($dst$$Register, $src1$$Register, $src2$$Register);
8625 %}
8626 ins_pipe(pipe_class_default);
8627 %}
8628
8629 // Register Shift Right Arithmetic Long
8630 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8631 match(Set dst (RShiftL src1 src2));
8632 ins_cost(DEFAULT_COST*2);
8633
8634 expand %{
8635 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8636 iRegIdst tmpI;
8637 maskI_reg_imm(tmpI, src2, mask);
8638 arShiftL_regL_regI(dst, src1, tmpI);
8639 %}
8640 %}
8641
8642 // Register Shift Right Immediate
8643 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8644 match(Set dst (RShiftL src1 src2));
8645
8646 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %}
8647 size(4);
8648 ins_encode %{
8649 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8650 %}
8651 ins_pipe(pipe_class_default);
8652 %}
8653
8654 // RShiftL + ConvL2I
8655 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8656 match(Set dst (ConvL2I (RShiftL src1 src2)));
8657
8658 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8659 size(4);
8660 ins_encode %{
8661 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8662 %}
8663 ins_pipe(pipe_class_default);
8664 %}
8665
8666 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8667 // no match-rule, false predicate
8668 effect(DEF dst, USE src1, USE src2);
8669 predicate(false);
8670
8671 format %{ "SRW $dst, $src1, $src2" %}
8672 size(4);
8673 ins_encode %{
8674 __ srw($dst$$Register, $src1$$Register, $src2$$Register);
8675 %}
8676 ins_pipe(pipe_class_default);
8677 %}
8678
8679 // Register Shift Right
8680 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8681 match(Set dst (URShiftI src1 src2));
8682 ins_cost(DEFAULT_COST*2);
8683
8684 expand %{
8685 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8686 iRegIdst tmpI;
8687 maskI_reg_imm(tmpI, src2, mask);
8688 urShiftI_reg_reg(dst, src1, tmpI);
8689 %}
8690 %}
8691
8692 // Register Shift Right Immediate
8693 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8694 match(Set dst (URShiftI src1 src2));
8695
8696 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %}
8697 size(4);
8698 ins_encode %{
8699 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8700 %}
8701 ins_pipe(pipe_class_default);
8702 %}
8703
8704 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8705 // no match-rule, false predicate
8706 effect(DEF dst, USE src1, USE src2);
8707 predicate(false);
8708
8709 format %{ "SRD $dst, $src1, $src2" %}
8710 size(4);
8711 ins_encode %{
8712 __ srd($dst$$Register, $src1$$Register, $src2$$Register);
8713 %}
8714 ins_pipe(pipe_class_default);
8715 %}
8716
8717 // Register Shift Right
8718 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8719 match(Set dst (URShiftL src1 src2));
8720 ins_cost(DEFAULT_COST*2);
8721
8722 expand %{
8723 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8724 iRegIdst tmpI;
8725 maskI_reg_imm(tmpI, src2, mask);
8726 urShiftL_regL_regI(dst, src1, tmpI);
8727 %}
8728 %}
8729
8730 // Register Shift Right Immediate
8731 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8732 match(Set dst (URShiftL src1 src2));
8733
8734 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %}
8735 size(4);
8736 ins_encode %{
8737 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8738 %}
8739 ins_pipe(pipe_class_default);
8740 %}
8741
8742 // URShiftL + ConvL2I.
8743 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8744 match(Set dst (ConvL2I (URShiftL src1 src2)));
8745
8746 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8747 size(4);
8748 ins_encode %{
8749 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8750 %}
8751 ins_pipe(pipe_class_default);
8752 %}
8753
8754 // Register Shift Right Immediate with a CastP2X
8755 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
8756 match(Set dst (URShiftL (CastP2X src1) src2));
8757
8758 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
8759 size(4);
8760 ins_encode %{
8761 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8762 %}
8763 ins_pipe(pipe_class_default);
8764 %}
8765
8766 // Bitfield Extract: URShiftI + AndI
8767 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
8768 match(Set dst (AndI (URShiftI src1 src2) src3));
8769
8770 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
8771 size(4);
8772 ins_encode %{
8773 int rshift = ($src2$$constant) & 0x1f;
8774 int length = log2i_exact((juint)$src3$$constant + 1u);
8775 if (rshift + length > 32) {
8776 // if necessary, adjust mask to omit rotated bits.
8777 length = 32 - rshift;
8778 }
8779 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8780 %}
8781 ins_pipe(pipe_class_default);
8782 %}
8783
8784 // Bitfield Extract: URShiftL + AndL
8785 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
8786 match(Set dst (AndL (URShiftL src1 src2) src3));
8787
8788 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
8789 size(4);
8790 ins_encode %{
8791 int rshift = ($src2$$constant) & 0x3f;
8792 int length = log2i_exact((julong)$src3$$constant + 1ull);
8793 if (rshift + length > 64) {
8794 // if necessary, adjust mask to omit rotated bits.
8795 length = 64 - rshift;
8796 }
8797 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8798 %}
8799 ins_pipe(pipe_class_default);
8800 %}
8801
8802 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
8803 match(Set dst (ConvL2I (ConvI2L src)));
8804
8805 format %{ "EXTSW $dst, $src \t// int->int" %}
8806 size(4);
8807 ins_encode %{
8808 __ extsw($dst$$Register, $src$$Register);
8809 %}
8810 ins_pipe(pipe_class_default);
8811 %}
8812
8813 //----------Rotate Instructions------------------------------------------------
8814
8815 // Rotate Left by 8-bit immediate
8816 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
8817 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
8818 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8819
8820 format %{ "ROTLWI $dst, $src, $lshift" %}
8821 size(4);
8822 ins_encode %{
8823 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
8824 %}
8825 ins_pipe(pipe_class_default);
8826 %}
8827
8828 // Rotate Right by 8-bit immediate
8829 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
8830 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
8831 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8832
8833 format %{ "ROTRWI $dst, $rshift" %}
8834 size(4);
8835 ins_encode %{
8836 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
8837 %}
8838 ins_pipe(pipe_class_default);
8839 %}
8840
8841 //----------Floating Point Arithmetic Instructions-----------------------------
8842
8843 // Add float single precision
8844 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
8845 match(Set dst (AddF src1 src2));
8846
8847 format %{ "FADDS $dst, $src1, $src2" %}
8848 size(4);
8849 ins_encode %{
8850 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8851 %}
8852 ins_pipe(pipe_class_default);
8853 %}
8854
8855 // Add float double precision
8856 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
8857 match(Set dst (AddD src1 src2));
8858
8859 format %{ "FADD $dst, $src1, $src2" %}
8860 size(4);
8861 ins_encode %{
8862 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8863 %}
8864 ins_pipe(pipe_class_default);
8865 %}
8866
8867 // Sub float single precision
8868 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
8869 match(Set dst (SubF src1 src2));
8870
8871 format %{ "FSUBS $dst, $src1, $src2" %}
8872 size(4);
8873 ins_encode %{
8874 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8875 %}
8876 ins_pipe(pipe_class_default);
8877 %}
8878
8879 // Sub float double precision
8880 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
8881 match(Set dst (SubD src1 src2));
8882 format %{ "FSUB $dst, $src1, $src2" %}
8883 size(4);
8884 ins_encode %{
8885 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8886 %}
8887 ins_pipe(pipe_class_default);
8888 %}
8889
8890 // Mul float single precision
8891 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
8892 match(Set dst (MulF src1 src2));
8893 format %{ "FMULS $dst, $src1, $src2" %}
8894 size(4);
8895 ins_encode %{
8896 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8897 %}
8898 ins_pipe(pipe_class_default);
8899 %}
8900
8901 // Mul float double precision
8902 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
8903 match(Set dst (MulD src1 src2));
8904 format %{ "FMUL $dst, $src1, $src2" %}
8905 size(4);
8906 ins_encode %{
8907 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8908 %}
8909 ins_pipe(pipe_class_default);
8910 %}
8911
8912 // Div float single precision
8913 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
8914 match(Set dst (DivF src1 src2));
8915 format %{ "FDIVS $dst, $src1, $src2" %}
8916 size(4);
8917 ins_encode %{
8918 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8919 %}
8920 ins_pipe(pipe_class_default);
8921 %}
8922
8923 // Div float double precision
8924 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
8925 match(Set dst (DivD src1 src2));
8926 format %{ "FDIV $dst, $src1, $src2" %}
8927 size(4);
8928 ins_encode %{
8929 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8930 %}
8931 ins_pipe(pipe_class_default);
8932 %}
8933
8934 // Absolute float single precision
8935 instruct absF_reg(regF dst, regF src) %{
8936 match(Set dst (AbsF src));
8937 format %{ "FABS $dst, $src \t// float" %}
8938 size(4);
8939 ins_encode %{
8940 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8941 %}
8942 ins_pipe(pipe_class_default);
8943 %}
8944
8945 // Absolute float double precision
8946 instruct absD_reg(regD dst, regD src) %{
8947 match(Set dst (AbsD src));
8948 format %{ "FABS $dst, $src \t// double" %}
8949 size(4);
8950 ins_encode %{
8951 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8952 %}
8953 ins_pipe(pipe_class_default);
8954 %}
8955
8956 instruct negF_reg(regF dst, regF src) %{
8957 match(Set dst (NegF src));
8958 format %{ "FNEG $dst, $src \t// float" %}
8959 size(4);
8960 ins_encode %{
8961 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8962 %}
8963 ins_pipe(pipe_class_default);
8964 %}
8965
8966 instruct negD_reg(regD dst, regD src) %{
8967 match(Set dst (NegD src));
8968 format %{ "FNEG $dst, $src \t// double" %}
8969 size(4);
8970 ins_encode %{
8971 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8972 %}
8973 ins_pipe(pipe_class_default);
8974 %}
8975
8976 // AbsF + NegF.
8977 instruct negF_absF_reg(regF dst, regF src) %{
8978 match(Set dst (NegF (AbsF src)));
8979 format %{ "FNABS $dst, $src \t// float" %}
8980 size(4);
8981 ins_encode %{
8982 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
8983 %}
8984 ins_pipe(pipe_class_default);
8985 %}
8986
8987 // AbsD + NegD.
8988 instruct negD_absD_reg(regD dst, regD src) %{
8989 match(Set dst (NegD (AbsD src)));
8990 format %{ "FNABS $dst, $src \t// double" %}
8991 size(4);
8992 ins_encode %{
8993 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
8994 %}
8995 ins_pipe(pipe_class_default);
8996 %}
8997
8998 // Sqrt float double precision
8999 instruct sqrtD_reg(regD dst, regD src) %{
9000 match(Set dst (SqrtD src));
9001 format %{ "FSQRT $dst, $src" %}
9002 size(4);
9003 ins_encode %{
9004 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
9005 %}
9006 ins_pipe(pipe_class_default);
9007 %}
9008
9009 // Single-precision sqrt.
9010 instruct sqrtF_reg(regF dst, regF src) %{
9011 match(Set dst (SqrtF src));
9012 ins_cost(DEFAULT_COST);
9013
9014 format %{ "FSQRTS $dst, $src" %}
9015 size(4);
9016 ins_encode %{
9017 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
9018 %}
9019 ins_pipe(pipe_class_default);
9020 %}
9021
9022
9023 // Multiply-Accumulate
9024 // src1 * src2 + src3
9025 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9026 match(Set dst (FmaF src3 (Binary src1 src2)));
9027
9028 format %{ "FMADDS $dst, $src1, $src2, $src3" %}
9029 size(4);
9030 ins_encode %{
9031 assert(UseFMA, "Needs FMA instructions support.");
9032 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9033 %}
9034 ins_pipe(pipe_class_default);
9035 %}
9036
9037 // src1 * src2 + src3
9038 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9039 match(Set dst (FmaD src3 (Binary src1 src2)));
9040
9041 format %{ "FMADD $dst, $src1, $src2, $src3" %}
9042 size(4);
9043 ins_encode %{
9044 assert(UseFMA, "Needs FMA instructions support.");
9045 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9046 %}
9047 ins_pipe(pipe_class_default);
9048 %}
9049
9050 // src1 * (-src2) + src3 = -(src1*src2-src3)
9051 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9052 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9053 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
9054
9055 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
9056 size(4);
9057 ins_encode %{
9058 assert(UseFMA, "Needs FMA instructions support.");
9059 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9060 %}
9061 ins_pipe(pipe_class_default);
9062 %}
9063
9064 // src1 * (-src2) + src3 = -(src1*src2-src3)
9065 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9066 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9067 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
9068
9069 format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
9070 size(4);
9071 ins_encode %{
9072 assert(UseFMA, "Needs FMA instructions support.");
9073 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9074 %}
9075 ins_pipe(pipe_class_default);
9076 %}
9077
9078 // src1 * (-src2) - src3 = -(src1*src2+src3)
9079 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9080 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9081 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
9082
9083 format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
9084 size(4);
9085 ins_encode %{
9086 assert(UseFMA, "Needs FMA instructions support.");
9087 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9088 %}
9089 ins_pipe(pipe_class_default);
9090 %}
9091
9092 // src1 * (-src2) - src3 = -(src1*src2+src3)
9093 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9094 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9095 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9096
9097 format %{ "FNMADD $dst, $src1, $src2, $src3" %}
9098 size(4);
9099 ins_encode %{
9100 assert(UseFMA, "Needs FMA instructions support.");
9101 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9102 %}
9103 ins_pipe(pipe_class_default);
9104 %}
9105
9106 // src1 * src2 - src3
9107 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9108 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9109
9110 format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
9111 size(4);
9112 ins_encode %{
9113 assert(UseFMA, "Needs FMA instructions support.");
9114 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9115 %}
9116 ins_pipe(pipe_class_default);
9117 %}
9118
9119 // src1 * src2 - src3
9120 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9121 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9122
9123 format %{ "FMSUB $dst, $src1, $src2, $src3" %}
9124 size(4);
9125 ins_encode %{
9126 assert(UseFMA, "Needs FMA instructions support.");
9127 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9128 %}
9129 ins_pipe(pipe_class_default);
9130 %}
9131
9132
9133 //----------Logical Instructions-----------------------------------------------
9134
9135 // And Instructions
9136
9137 // Register And
9138 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9139 match(Set dst (AndI src1 src2));
9140 format %{ "AND $dst, $src1, $src2" %}
9141 size(4);
9142 ins_encode %{
9143 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9144 %}
9145 ins_pipe(pipe_class_default);
9146 %}
9147
9148 instruct andI_reg_immI(iRegIdst dst, iRegIsrc src1, immI src2, flagsRegCR0 cr0) %{
9149 match(Set dst (AndI src1 src2));
9150 predicate(Assembler::andi_supports((juint)(n->in(2)->get_int())));
9151 effect(KILL cr0);
9152 format %{ "ANDI $dst, $src1, $src2" %}
9153 size(4);
9154 ins_encode %{
9155 __ andi($dst$$Register, $src1$$Register, (juint)$src2$$constant); // optimized version
9156 %}
9157 ins_pipe(pipe_class_default);
9158 %}
9159
9160 // Register And Long
9161 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9162 match(Set dst (AndL src1 src2));
9163 ins_cost(DEFAULT_COST);
9164
9165 format %{ "AND $dst, $src1, $src2 \t// long" %}
9166 size(4);
9167 ins_encode %{
9168 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9169 %}
9170 ins_pipe(pipe_class_default);
9171 %}
9172
9173 instruct andL_reg_immL(iRegLdst dst, iRegLsrc src1, immL src2, flagsRegCR0 cr0) %{
9174 match(Set dst (AndL src1 src2));
9175 predicate(Assembler::andi_supports(n->in(2)->get_long()));
9176 effect(KILL cr0);
9177 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9178 size(4);
9179 ins_encode %{
9180 __ andi($dst$$Register, $src1$$Register, $src2$$constant); // optimized version
9181 %}
9182 ins_pipe(pipe_class_default);
9183 %}
9184
9185 // AndL + ConvL2I.
9186 instruct convL2I_andL_reg_immL(iRegIdst dst, iRegLsrc src1, immL src2, flagsRegCR0 cr0) %{
9187 match(Set dst (ConvL2I (AndL src1 src2)));
9188 predicate(Assembler::andi_supports(n->in(1)->in(2)->get_long()));
9189 effect(KILL cr0);
9190 format %{ "ANDI $dst, $src1, $src2 \t// long + l2i" %}
9191 size(4);
9192 ins_encode %{
9193 __ andi($dst$$Register, $src1$$Register, $src2$$constant); // optimized version
9194 %}
9195 ins_pipe(pipe_class_default);
9196 %}
9197
9198 // Or Instructions
9199
9200 // Register Or
9201 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9202 match(Set dst (OrI src1 src2));
9203 format %{ "OR $dst, $src1, $src2" %}
9204 size(4);
9205 ins_encode %{
9206 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9207 %}
9208 ins_pipe(pipe_class_default);
9209 %}
9210
9211 // Expand does not work with above instruct. (??)
9212 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9213 // no match-rule
9214 effect(DEF dst, USE src1, USE src2);
9215 format %{ "OR $dst, $src1, $src2" %}
9216 size(4);
9217 ins_encode %{
9218 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9219 %}
9220 ins_pipe(pipe_class_default);
9221 %}
9222
9223 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9224 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9225 ins_cost(DEFAULT_COST*3);
9226
9227 expand %{
9228 // FIXME: we should do this in the ideal world.
9229 iRegIdst tmp1;
9230 iRegIdst tmp2;
9231 orI_reg_reg(tmp1, src1, src2);
9232 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9233 orI_reg_reg(dst, tmp1, tmp2);
9234 %}
9235 %}
9236
9237 // Immediate Or
9238 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9239 match(Set dst (OrI src1 src2));
9240 format %{ "ORI $dst, $src1, $src2" %}
9241 size(4);
9242 ins_encode %{
9243 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9244 %}
9245 ins_pipe(pipe_class_default);
9246 %}
9247
9248 // Register Or Long
9249 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9250 match(Set dst (OrL src1 src2));
9251 ins_cost(DEFAULT_COST);
9252
9253 size(4);
9254 format %{ "OR $dst, $src1, $src2 \t// long" %}
9255 ins_encode %{
9256 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9257 %}
9258 ins_pipe(pipe_class_default);
9259 %}
9260
9261 // OrL + ConvL2I.
9262 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9263 match(Set dst (ConvL2I (OrL src1 src2)));
9264 ins_cost(DEFAULT_COST);
9265
9266 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %}
9267 size(4);
9268 ins_encode %{
9269 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9270 %}
9271 ins_pipe(pipe_class_default);
9272 %}
9273
9274 // Immediate Or long
9275 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9276 match(Set dst (OrL src1 con));
9277 ins_cost(DEFAULT_COST);
9278
9279 format %{ "ORI $dst, $src1, $con \t// long" %}
9280 size(4);
9281 ins_encode %{
9282 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9283 %}
9284 ins_pipe(pipe_class_default);
9285 %}
9286
9287 // Xor Instructions
9288
9289 // Register Xor
9290 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9291 match(Set dst (XorI src1 src2));
9292 format %{ "XOR $dst, $src1, $src2" %}
9293 size(4);
9294 ins_encode %{
9295 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9296 %}
9297 ins_pipe(pipe_class_default);
9298 %}
9299
9300 // Expand does not work with above instruct. (??)
9301 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9302 // no match-rule
9303 effect(DEF dst, USE src1, USE src2);
9304 format %{ "XOR $dst, $src1, $src2" %}
9305 size(4);
9306 ins_encode %{
9307 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9308 %}
9309 ins_pipe(pipe_class_default);
9310 %}
9311
9312 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9313 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
9314 ins_cost(DEFAULT_COST*3);
9315
9316 expand %{
9317 // FIXME: we should do this in the ideal world.
9318 iRegIdst tmp1;
9319 iRegIdst tmp2;
9320 xorI_reg_reg(tmp1, src1, src2);
9321 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
9322 xorI_reg_reg(dst, tmp1, tmp2);
9323 %}
9324 %}
9325
9326 // Immediate Xor
9327 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9328 match(Set dst (XorI src1 src2));
9329 format %{ "XORI $dst, $src1, $src2" %}
9330 size(4);
9331 ins_encode %{
9332 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9333 %}
9334 ins_pipe(pipe_class_default);
9335 %}
9336
9337 // Register Xor Long
9338 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9339 match(Set dst (XorL src1 src2));
9340 ins_cost(DEFAULT_COST);
9341
9342 format %{ "XOR $dst, $src1, $src2 \t// long" %}
9343 size(4);
9344 ins_encode %{
9345 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9346 %}
9347 ins_pipe(pipe_class_default);
9348 %}
9349
9350 // XorL + ConvL2I.
9351 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9352 match(Set dst (ConvL2I (XorL src1 src2)));
9353 ins_cost(DEFAULT_COST);
9354
9355 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %}
9356 size(4);
9357 ins_encode %{
9358 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9359 %}
9360 ins_pipe(pipe_class_default);
9361 %}
9362
9363 // Immediate Xor Long
9364 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
9365 match(Set dst (XorL src1 src2));
9366 ins_cost(DEFAULT_COST);
9367
9368 format %{ "XORI $dst, $src1, $src2 \t// long" %}
9369 size(4);
9370 ins_encode %{
9371 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9372 %}
9373 ins_pipe(pipe_class_default);
9374 %}
9375
9376 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
9377 match(Set dst (XorI src1 src2));
9378 ins_cost(DEFAULT_COST);
9379
9380 format %{ "NOT $dst, $src1 ($src2)" %}
9381 size(4);
9382 ins_encode %{
9383 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9384 %}
9385 ins_pipe(pipe_class_default);
9386 %}
9387
9388 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
9389 match(Set dst (XorL src1 src2));
9390 ins_cost(DEFAULT_COST);
9391
9392 format %{ "NOT $dst, $src1 ($src2) \t// long" %}
9393 size(4);
9394 ins_encode %{
9395 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9396 %}
9397 ins_pipe(pipe_class_default);
9398 %}
9399
9400 // And-complement
9401 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
9402 match(Set dst (AndI (XorI src1 src2) src3));
9403 ins_cost(DEFAULT_COST);
9404
9405 format %{ "ANDW $dst, xori($src1, $src2), $src3" %}
9406 size(4);
9407 ins_encode( enc_andc(dst, src3, src1) );
9408 ins_pipe(pipe_class_default);
9409 %}
9410
9411 // And-complement
9412 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9413 // no match-rule, false predicate
9414 effect(DEF dst, USE src1, USE src2);
9415 predicate(false);
9416
9417 format %{ "ANDC $dst, $src1, $src2" %}
9418 size(4);
9419 ins_encode %{
9420 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
9421 %}
9422 ins_pipe(pipe_class_default);
9423 %}
9424
9425 //----------Moves between int/long and float/double----------------------------
9426 //
9427 // The following rules move values from int/long registers/stack-locations
9428 // to float/double registers/stack-locations and vice versa, without doing any
9429 // conversions. These rules are used to implement the bit-conversion methods
9430 // of java.lang.Float etc., e.g.
9431 // int floatToIntBits(float value)
9432 // float intBitsToFloat(int bits)
9433
9434 instruct moveL2D_reg(regD dst, iRegLsrc src) %{
9435 match(Set dst (MoveL2D src));
9436
9437 format %{ "MTFPRD $dst, $src" %}
9438 size(4);
9439 ins_encode %{
9440 __ mtfprd($dst$$FloatRegister, $src$$Register);
9441 %}
9442 ins_pipe(pipe_class_default);
9443 %}
9444
9445 instruct moveI2D_reg(regD dst, iRegIsrc src) %{
9446 // no match-rule, false predicate
9447 effect(DEF dst, USE src);
9448 predicate(false);
9449
9450 format %{ "MTFPRWA $dst, $src" %}
9451 size(4);
9452 ins_encode %{
9453 __ mtfprwa($dst$$FloatRegister, $src$$Register);
9454 %}
9455 ins_pipe(pipe_class_default);
9456 %}
9457
9458 //---------- Chain stack slots between similar types --------
9459
9460 // These are needed so that the rules below can match.
9461
9462 // Load integer from stack slot
9463 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
9464 match(Set dst src);
9465 ins_cost(MEMORY_REF_COST);
9466
9467 format %{ "LWZ $dst, $src" %}
9468 size(4);
9469 ins_encode( enc_lwz(dst, src) );
9470 ins_pipe(pipe_class_memory);
9471 %}
9472
9473 // Store integer to stack slot
9474 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
9475 match(Set dst src);
9476 ins_cost(MEMORY_REF_COST);
9477
9478 format %{ "STW $src, $dst \t// stk" %}
9479 size(4);
9480 ins_encode( enc_stw(src, dst) ); // rs=rt
9481 ins_pipe(pipe_class_memory);
9482 %}
9483
9484 // Load long from stack slot
9485 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
9486 match(Set dst src);
9487 ins_cost(MEMORY_REF_COST);
9488
9489 format %{ "LD $dst, $src \t// long" %}
9490 size(4);
9491 ins_encode( enc_ld(dst, src) );
9492 ins_pipe(pipe_class_memory);
9493 %}
9494
9495 // Store long to stack slot
9496 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
9497 match(Set dst src);
9498 ins_cost(MEMORY_REF_COST);
9499
9500 format %{ "STD $src, $dst \t// long" %}
9501 size(4);
9502 ins_encode( enc_std(src, dst) ); // rs=rt
9503 ins_pipe(pipe_class_memory);
9504 %}
9505
9506 //----------Moves between int and float
9507
9508 // Move float value from float stack-location to integer register.
9509 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
9510 match(Set dst (MoveF2I src));
9511 ins_cost(MEMORY_REF_COST);
9512
9513 format %{ "LWZ $dst, $src \t// MoveF2I" %}
9514 size(4);
9515 ins_encode( enc_lwz(dst, src) );
9516 ins_pipe(pipe_class_memory);
9517 %}
9518
9519 // Move float value from float register to integer stack-location.
9520 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
9521 match(Set dst (MoveF2I src));
9522 ins_cost(MEMORY_REF_COST);
9523
9524 format %{ "STFS $src, $dst \t// MoveF2I" %}
9525 size(4);
9526 ins_encode( enc_stfs(src, dst) );
9527 ins_pipe(pipe_class_memory);
9528 %}
9529
9530 // Move integer value from integer stack-location to float register.
9531 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
9532 match(Set dst (MoveI2F src));
9533 ins_cost(MEMORY_REF_COST);
9534
9535 format %{ "LFS $dst, $src \t// MoveI2F" %}
9536 size(4);
9537 ins_encode %{
9538 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
9539 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
9540 %}
9541 ins_pipe(pipe_class_memory);
9542 %}
9543
9544 // Move integer value from integer register to float stack-location.
9545 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
9546 match(Set dst (MoveI2F src));
9547 ins_cost(MEMORY_REF_COST);
9548
9549 format %{ "STW $src, $dst \t// MoveI2F" %}
9550 size(4);
9551 ins_encode( enc_stw(src, dst) );
9552 ins_pipe(pipe_class_memory);
9553 %}
9554
9555
9556 //----------Moves between long and double
9557
9558 // Move double value from double stack-location to long register.
9559 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
9560 match(Set dst (MoveD2L src));
9561 ins_cost(MEMORY_REF_COST);
9562 size(4);
9563 format %{ "LD $dst, $src \t// MoveD2L" %}
9564 ins_encode( enc_ld(dst, src) );
9565 ins_pipe(pipe_class_memory);
9566 %}
9567
9568 // Move double value from double register to long stack-location.
9569 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
9570 match(Set dst (MoveD2L src));
9571 effect(DEF dst, USE src);
9572 ins_cost(MEMORY_REF_COST);
9573
9574 format %{ "STFD $src, $dst \t// MoveD2L" %}
9575 size(4);
9576 ins_encode( enc_stfd(src, dst) );
9577 ins_pipe(pipe_class_memory);
9578 %}
9579
9580
9581 //----------Register Move Instructions-----------------------------------------
9582
9583 // Replicate for Superword
9584
9585 instruct moveReg(iRegLdst dst, iRegIsrc src) %{
9586 predicate(false);
9587 effect(DEF dst, USE src);
9588
9589 format %{ "MR $dst, $src \t// replicate " %}
9590 // variable size, 0 or 4.
9591 ins_encode %{
9592 __ mr_if_needed($dst$$Register, $src$$Register);
9593 %}
9594 ins_pipe(pipe_class_default);
9595 %}
9596
9597 //----------Cast instructions (Java-level type cast)---------------------------
9598
9599 // Cast Long to Pointer for unsafe natives.
9600 instruct castX2P(iRegPdst dst, iRegLsrc src) %{
9601 match(Set dst (CastX2P src));
9602
9603 format %{ "MR $dst, $src \t// Long->Ptr" %}
9604 // variable size, 0 or 4.
9605 ins_encode %{
9606 __ mr_if_needed($dst$$Register, $src$$Register);
9607 %}
9608 ins_pipe(pipe_class_default);
9609 %}
9610
9611 // Cast Pointer to Long for unsafe natives.
9612 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
9613 match(Set dst (CastP2X src));
9614
9615 format %{ "MR $dst, $src \t// Ptr->Long" %}
9616 // variable size, 0 or 4.
9617 ins_encode %{
9618 __ mr_if_needed($dst$$Register, $src$$Register);
9619 %}
9620 ins_pipe(pipe_class_default);
9621 %}
9622
9623 instruct castN2X(iRegLdst dst, iRegNsrc src) %{
9624 match(Set dst (CastP2X src));
9625
9626 format %{ "MR $dst, $src \t// Ptr->Long" %}
9627 // variable size, 0 or 4.
9628 ins_encode %{
9629 __ mr_if_needed($dst$$Register, $src$$Register);
9630 %}
9631 ins_pipe(pipe_class_default);
9632 %}
9633
9634 instruct castPP(iRegPdst dst) %{
9635 match(Set dst (CastPP dst));
9636 format %{ " -- \t// castPP of $dst" %}
9637 size(0);
9638 ins_encode( /*empty*/ );
9639 ins_pipe(pipe_class_default);
9640 %}
9641
9642 instruct castII(iRegIdst dst) %{
9643 match(Set dst (CastII dst));
9644 format %{ " -- \t// castII of $dst" %}
9645 size(0);
9646 ins_encode( /*empty*/ );
9647 ins_pipe(pipe_class_default);
9648 %}
9649
9650 instruct castLL(iRegLdst dst) %{
9651 match(Set dst (CastLL dst));
9652 format %{ " -- \t// castLL of $dst" %}
9653 size(0);
9654 ins_encode( /*empty*/ );
9655 ins_pipe(pipe_class_default);
9656 %}
9657
9658 instruct castFF(regF dst) %{
9659 match(Set dst (CastFF dst));
9660 format %{ " -- \t// castFF of $dst" %}
9661 size(0);
9662 ins_encode( /*empty*/ );
9663 ins_pipe(pipe_class_default);
9664 %}
9665
9666 instruct castDD(regD dst) %{
9667 match(Set dst (CastDD dst));
9668 format %{ " -- \t// castDD of $dst" %}
9669 size(0);
9670 ins_encode( /*empty*/ );
9671 ins_pipe(pipe_class_default);
9672 %}
9673
9674 instruct castVV8(iRegLdst dst) %{
9675 match(Set dst (CastVV dst));
9676 format %{ " -- \t// castVV of $dst" %}
9677 size(0);
9678 ins_encode( /*empty*/ );
9679 ins_pipe(pipe_class_default);
9680 %}
9681
9682 instruct castVV16(vecX dst) %{
9683 match(Set dst (CastVV dst));
9684 format %{ " -- \t// castVV of $dst" %}
9685 size(0);
9686 ins_encode( /*empty*/ );
9687 ins_pipe(pipe_class_default);
9688 %}
9689
9690 instruct checkCastPP(iRegPdst dst) %{
9691 match(Set dst (CheckCastPP dst));
9692 format %{ " -- \t// checkcastPP of $dst" %}
9693 size(0);
9694 ins_encode( /*empty*/ );
9695 ins_pipe(pipe_class_default);
9696 %}
9697
9698 //----------Convert instructions-----------------------------------------------
9699
9700 // Convert to boolean.
9701
9702 // int_to_bool(src) : { 1 if src != 0
9703 // { 0 else
9704 //
9705 // strategy:
9706 // 1) Count leading zeros of 32 bit-value src,
9707 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
9708 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9709 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9710
9711 // convI2Bool
9712 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
9713 match(Set dst (Conv2B src));
9714 predicate(UseCountLeadingZerosInstructionsPPC64);
9715 ins_cost(DEFAULT_COST);
9716
9717 expand %{
9718 immI shiftAmount %{ 0x5 %}
9719 uimmI16 mask %{ 0x1 %}
9720 iRegIdst tmp1;
9721 iRegIdst tmp2;
9722 countLeadingZerosI(tmp1, src);
9723 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9724 xorI_reg_uimm16(dst, tmp2, mask);
9725 %}
9726 %}
9727
9728 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
9729 match(Set dst (Conv2B src));
9730 effect(TEMP crx);
9731 predicate(!UseCountLeadingZerosInstructionsPPC64);
9732 ins_cost(DEFAULT_COST);
9733
9734 format %{ "CMPWI $crx, $src, #0 \t// convI2B"
9735 "LI $dst, #0\n\t"
9736 "BEQ $crx, done\n\t"
9737 "LI $dst, #1\n"
9738 "done:" %}
9739 size(16);
9740 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
9741 ins_pipe(pipe_class_compare);
9742 %}
9743
9744 // ConvI2B + XorI
9745 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
9746 match(Set dst (XorI (Conv2B src) mask));
9747 predicate(UseCountLeadingZerosInstructionsPPC64);
9748 ins_cost(DEFAULT_COST);
9749
9750 expand %{
9751 immI shiftAmount %{ 0x5 %}
9752 iRegIdst tmp1;
9753 countLeadingZerosI(tmp1, src);
9754 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9755 %}
9756 %}
9757
9758 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
9759 match(Set dst (XorI (Conv2B src) mask));
9760 effect(TEMP crx);
9761 predicate(!UseCountLeadingZerosInstructionsPPC64);
9762 ins_cost(DEFAULT_COST);
9763
9764 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
9765 "LI $dst, #1\n\t"
9766 "BEQ $crx, done\n\t"
9767 "LI $dst, #0\n"
9768 "done:" %}
9769 size(16);
9770 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
9771 ins_pipe(pipe_class_compare);
9772 %}
9773
9774 // AndI 0b0..010..0 + ConvI2B
9775 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
9776 match(Set dst (Conv2B (AndI src mask)));
9777 predicate(UseRotateAndMaskInstructionsPPC64);
9778 ins_cost(DEFAULT_COST);
9779
9780 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
9781 size(4);
9782 ins_encode %{
9783 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31);
9784 %}
9785 ins_pipe(pipe_class_default);
9786 %}
9787
9788 // Convert pointer to boolean.
9789 //
9790 // ptr_to_bool(src) : { 1 if src != 0
9791 // { 0 else
9792 //
9793 // strategy:
9794 // 1) Count leading zeros of 64 bit-value src,
9795 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
9796 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9797 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9798
9799 // ConvP2B
9800 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
9801 match(Set dst (Conv2B src));
9802 predicate(UseCountLeadingZerosInstructionsPPC64);
9803 ins_cost(DEFAULT_COST);
9804
9805 expand %{
9806 immI shiftAmount %{ 0x6 %}
9807 uimmI16 mask %{ 0x1 %}
9808 iRegIdst tmp1;
9809 iRegIdst tmp2;
9810 countLeadingZerosP(tmp1, src);
9811 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9812 xorI_reg_uimm16(dst, tmp2, mask);
9813 %}
9814 %}
9815
9816 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
9817 match(Set dst (Conv2B src));
9818 effect(TEMP crx);
9819 predicate(!UseCountLeadingZerosInstructionsPPC64);
9820 ins_cost(DEFAULT_COST);
9821
9822 format %{ "CMPDI $crx, $src, #0 \t// convP2B"
9823 "LI $dst, #0\n\t"
9824 "BEQ $crx, done\n\t"
9825 "LI $dst, #1\n"
9826 "done:" %}
9827 size(16);
9828 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
9829 ins_pipe(pipe_class_compare);
9830 %}
9831
9832 // ConvP2B + XorI
9833 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
9834 match(Set dst (XorI (Conv2B src) mask));
9835 predicate(UseCountLeadingZerosInstructionsPPC64);
9836 ins_cost(DEFAULT_COST);
9837
9838 expand %{
9839 immI shiftAmount %{ 0x6 %}
9840 iRegIdst tmp1;
9841 countLeadingZerosP(tmp1, src);
9842 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9843 %}
9844 %}
9845
9846 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
9847 match(Set dst (XorI (Conv2B src) mask));
9848 effect(TEMP crx);
9849 predicate(!UseCountLeadingZerosInstructionsPPC64);
9850 ins_cost(DEFAULT_COST);
9851
9852 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
9853 "LI $dst, #1\n\t"
9854 "BEQ $crx, done\n\t"
9855 "LI $dst, #0\n"
9856 "done:" %}
9857 size(16);
9858 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
9859 ins_pipe(pipe_class_compare);
9860 %}
9861
9862 // if src1 < src2, return -1 else return 0
9863 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9864 match(Set dst (CmpLTMask src1 src2));
9865 ins_cost(DEFAULT_COST*4);
9866
9867 expand %{
9868 iRegLdst src1s;
9869 iRegLdst src2s;
9870 iRegLdst diff;
9871 convI2L_reg(src1s, src1); // Ensure proper sign extension.
9872 convI2L_reg(src2s, src2); // Ensure proper sign extension.
9873 subL_reg_reg(diff, src1s, src2s);
9874 // Need to consider >=33 bit result, therefore we need signmaskL.
9875 signmask64I_regL(dst, diff);
9876 %}
9877 %}
9878
9879 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
9880 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
9881 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %}
9882 size(4);
9883 ins_encode %{
9884 __ srawi($dst$$Register, $src1$$Register, 0x1f);
9885 %}
9886 ins_pipe(pipe_class_default);
9887 %}
9888
9889 //----------Arithmetic Conversion Instructions---------------------------------
9890
9891 // Convert to Byte -- nop
9892 // Convert to Short -- nop
9893
9894 // Convert to Int
9895
9896 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
9897 match(Set dst (RShiftI (LShiftI src amount) amount));
9898 format %{ "EXTSB $dst, $src \t// byte->int" %}
9899 size(4);
9900 ins_encode %{
9901 __ extsb($dst$$Register, $src$$Register);
9902 %}
9903 ins_pipe(pipe_class_default);
9904 %}
9905
9906 instruct extsh(iRegIdst dst, iRegIsrc src) %{
9907 effect(DEF dst, USE src);
9908
9909 size(4);
9910 ins_encode %{
9911 __ extsh($dst$$Register, $src$$Register);
9912 %}
9913 ins_pipe(pipe_class_default);
9914 %}
9915
9916 // LShiftI 16 + RShiftI 16 converts short to int.
9917 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
9918 match(Set dst (RShiftI (LShiftI src amount) amount));
9919 format %{ "EXTSH $dst, $src \t// short->int" %}
9920 size(4);
9921 ins_encode %{
9922 __ extsh($dst$$Register, $src$$Register);
9923 %}
9924 ins_pipe(pipe_class_default);
9925 %}
9926
9927 // ConvL2I + ConvI2L: Sign extend int in long register.
9928 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
9929 match(Set dst (ConvI2L (ConvL2I src)));
9930
9931 format %{ "EXTSW $dst, $src \t// long->long" %}
9932 size(4);
9933 ins_encode %{
9934 __ extsw($dst$$Register, $src$$Register);
9935 %}
9936 ins_pipe(pipe_class_default);
9937 %}
9938
9939 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
9940 match(Set dst (ConvL2I src));
9941 format %{ "MR $dst, $src \t// long->int" %}
9942 // variable size, 0 or 4
9943 ins_encode %{
9944 __ mr_if_needed($dst$$Register, $src$$Register);
9945 %}
9946 ins_pipe(pipe_class_default);
9947 %}
9948
9949 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
9950 // no match-rule, false predicate
9951 effect(DEF dst, USE crx, USE src);
9952 predicate(false);
9953
9954 format %{ "CMOVI $crx, $dst, $src" %}
9955 size(8);
9956 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
9957 ins_pipe(pipe_class_default);
9958 %}
9959
9960 instruct cmovI_bso_reg_con0(iRegIdst dst, flagsRegSrc crx, regD src) %{
9961 // no match-rule, false predicate
9962 effect(DEF dst, USE crx, USE src);
9963 predicate(false);
9964
9965 format %{ "CMOVI $dst, $crx, $src, 0 \t// set to 0 if unordered" %}
9966 size(12);
9967 ins_encode %{
9968 Label done;
9969 __ li($dst$$Register, 0);
9970 __ bso($crx$$CondRegister, done);
9971 __ mffprd($dst$$Register, $src$$FloatRegister);
9972 __ bind(done);
9973 %}
9974 ins_pipe(pipe_class_default);
9975 %}
9976
9977 instruct convD2IRaw_regD(regD dst, regD src) %{
9978 // no match-rule, false predicate
9979 effect(DEF dst, USE src);
9980 predicate(false);
9981
9982 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
9983 size(4);
9984 ins_encode %{
9985 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
9986 %}
9987 ins_pipe(pipe_class_default);
9988 %}
9989
9990 // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
9991 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
9992 match(Set dst (ConvD2I src));
9993 ins_cost(DEFAULT_COST);
9994
9995 expand %{
9996 regD tmpD;
9997 flagsReg crx;
9998 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
9999 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
10000 cmovI_bso_reg_con0(dst, crx, tmpD); // Cmove based on NaN check.
10001 %}
10002 %}
10003
10004 instruct convF2IRaw_regF(regF dst, regF src) %{
10005 // no match-rule, false predicate
10006 effect(DEF dst, USE src);
10007 predicate(false);
10008
10009 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
10010 size(4);
10011 ins_encode %{
10012 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10013 %}
10014 ins_pipe(pipe_class_default);
10015 %}
10016
10017
10018 // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
10019 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
10020 match(Set dst (ConvF2I src));
10021 ins_cost(DEFAULT_COST);
10022
10023 expand %{
10024 regF tmpF;
10025 flagsReg crx;
10026 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10027 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10028 cmovI_bso_reg_con0(dst, crx, tmpF); // Cmove based on NaN check.
10029 %}
10030 %}
10031
10032 // Convert to Long
10033
10034 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
10035 match(Set dst (ConvI2L src));
10036 format %{ "EXTSW $dst, $src \t// int->long" %}
10037 size(4);
10038 ins_encode %{
10039 __ extsw($dst$$Register, $src$$Register);
10040 %}
10041 ins_pipe(pipe_class_default);
10042 %}
10043
10044 // Zero-extend: convert unsigned int to long (convUI2L).
10045 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
10046 match(Set dst (AndL (ConvI2L src) mask));
10047 ins_cost(DEFAULT_COST);
10048
10049 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10050 size(4);
10051 ins_encode %{
10052 __ clrldi($dst$$Register, $src$$Register, 32);
10053 %}
10054 ins_pipe(pipe_class_default);
10055 %}
10056
10057 // Zero-extend: convert unsigned int to long in long register.
10058 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
10059 match(Set dst (AndL src mask));
10060 ins_cost(DEFAULT_COST);
10061
10062 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10063 size(4);
10064 ins_encode %{
10065 __ clrldi($dst$$Register, $src$$Register, 32);
10066 %}
10067 ins_pipe(pipe_class_default);
10068 %}
10069
10070 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
10071 // no match-rule, false predicate
10072 effect(DEF dst, USE crx, USE src);
10073 predicate(false);
10074
10075 format %{ "CMOVL $crx, $dst, $src" %}
10076 size(8);
10077 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10078 ins_pipe(pipe_class_default);
10079 %}
10080
10081 instruct cmovL_bso_reg_con0(iRegLdst dst, flagsRegSrc crx, regD src) %{
10082 // no match-rule, false predicate
10083 effect(DEF dst, USE crx, USE src);
10084 predicate(false);
10085
10086 format %{ "CMOVL $dst, $crx, $src, 0 \t// set to 0 if unordered" %}
10087 size(12);
10088 ins_encode %{
10089 Label done;
10090 __ li($dst$$Register, 0);
10091 __ bso($crx$$CondRegister, done);
10092 __ mffprd($dst$$Register, $src$$FloatRegister);
10093 __ bind(done);
10094 %}
10095 ins_pipe(pipe_class_default);
10096 %}
10097
10098 instruct convF2LRaw_regF(regF dst, regF src) %{
10099 // no match-rule, false predicate
10100 effect(DEF dst, USE src);
10101 predicate(false);
10102
10103 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10104 size(4);
10105 ins_encode %{
10106 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10107 %}
10108 ins_pipe(pipe_class_default);
10109 %}
10110
10111 // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
10112 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
10113 match(Set dst (ConvF2L src));
10114 ins_cost(DEFAULT_COST);
10115
10116 expand %{
10117 regF tmpF;
10118 flagsReg crx;
10119 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10120 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
10121 cmovL_bso_reg_con0(dst, crx, tmpF); // Cmove based on NaN check.
10122 %}
10123 %}
10124
10125 instruct convD2LRaw_regD(regD dst, regD src) %{
10126 // no match-rule, false predicate
10127 effect(DEF dst, USE src);
10128 predicate(false);
10129
10130 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
10131 size(4);
10132 ins_encode %{
10133 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10134 %}
10135 ins_pipe(pipe_class_default);
10136 %}
10137
10138 // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
10139 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
10140 match(Set dst (ConvD2L src));
10141 ins_cost(DEFAULT_COST);
10142
10143 expand %{
10144 regD tmpD;
10145 flagsReg crx;
10146 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10147 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
10148 cmovL_bso_reg_con0(dst, crx, tmpD); // Cmove based on NaN check.
10149 %}
10150 %}
10151
10152 // Convert to Float
10153
10154 // Placed here as needed in expand.
10155 instruct convL2DRaw_regD(regD dst, regD src) %{
10156 // no match-rule, false predicate
10157 effect(DEF dst, USE src);
10158 predicate(false);
10159
10160 format %{ "FCFID $dst, $src \t// convL2D" %}
10161 size(4);
10162 ins_encode %{
10163 __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
10164 %}
10165 ins_pipe(pipe_class_default);
10166 %}
10167
10168 // Placed here as needed in expand.
10169 instruct convD2F_reg(regF dst, regD src) %{
10170 match(Set dst (ConvD2F src));
10171 format %{ "FRSP $dst, $src \t// convD2F" %}
10172 size(4);
10173 ins_encode %{
10174 __ frsp($dst$$FloatRegister, $src$$FloatRegister);
10175 %}
10176 ins_pipe(pipe_class_default);
10177 %}
10178
10179 instruct convL2FRaw_regF(regF dst, regD src) %{
10180 // no match-rule, false predicate
10181 effect(DEF dst, USE src);
10182 predicate(false);
10183
10184 format %{ "FCFIDS $dst, $src \t// convL2F" %}
10185 size(4);
10186 ins_encode %{
10187 __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
10188 %}
10189 ins_pipe(pipe_class_default);
10190 %}
10191
10192
10193 // Integer to Float conversion. Special version for Power8.
10194 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
10195 match(Set dst (ConvI2F src));
10196 ins_cost(DEFAULT_COST);
10197
10198 expand %{
10199 regD tmpD;
10200 moveI2D_reg(tmpD, src);
10201 convL2FRaw_regF(dst, tmpD); // Convert to float.
10202 %}
10203 %}
10204
10205
10206 // L2F to avoid runtime call. Special version for Power8.
10207 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
10208 match(Set dst (ConvL2F src));
10209 ins_cost(DEFAULT_COST);
10210
10211 expand %{
10212 regD tmpD;
10213 moveL2D_reg(tmpD, src);
10214 convL2FRaw_regF(dst, tmpD); // Convert to float.
10215 %}
10216 %}
10217
10218 // Moved up as used in expand.
10219 //instruct convD2F_reg(regF dst, regD src) %{%}
10220
10221 // Convert to Double
10222
10223
10224 // Integer to Double conversion. Special version for Power8.
10225 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
10226 match(Set dst (ConvI2D src));
10227 ins_cost(DEFAULT_COST);
10228
10229 expand %{
10230 regD tmpD;
10231 moveI2D_reg(tmpD, src);
10232 convL2DRaw_regD(dst, tmpD); // Convert to double.
10233 %}
10234 %}
10235
10236
10237 // Long to Double conversion. Special version for Power8.
10238 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
10239 match(Set dst (ConvL2D src));
10240 ins_cost(DEFAULT_COST);
10241
10242 expand %{
10243 regD tmpD;
10244 moveL2D_reg(tmpD, src);
10245 convL2DRaw_regD(dst, tmpD); // Convert to double.
10246 %}
10247 %}
10248
10249 instruct convF2D_reg(regD dst, regF src) %{
10250 match(Set dst (ConvF2D src));
10251 format %{ "FMR $dst, $src \t// float->double" %}
10252 // variable size, 0 or 4
10253 ins_encode %{
10254 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
10255 %}
10256 ins_pipe(pipe_class_default);
10257 %}
10258
10259 instruct convF2HF_reg_reg(iRegIdst dst, regF src, regF tmp) %{
10260 match(Set dst (ConvF2HF src));
10261 effect(TEMP tmp);
10262 ins_cost(3 * DEFAULT_COST);
10263 size(12);
10264 format %{ "XSCVDPHP $tmp, $src\t# convert to half precision\n\t"
10265 "MFFPRD $dst, $tmp\t# move result from $tmp to $dst\n\t"
10266 "EXTSH $dst, $dst\t# make it a proper short"
10267 %}
10268 ins_encode %{
10269 __ f2hf($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
10270 %}
10271 ins_pipe(pipe_class_default);
10272 %}
10273
10274 instruct convHF2F_reg_reg(regF dst, iRegIsrc src) %{
10275 match(Set dst (ConvHF2F src));
10276 ins_cost(2 * DEFAULT_COST);
10277 size(8);
10278 format %{ "MTFPRD $dst, $src\t# move source from $src to $dst\n\t"
10279 "XSCVHPDP $dst, $dst\t# convert from half precision"
10280 %}
10281 ins_encode %{
10282 __ hf2f($dst$$FloatRegister, $src$$Register);
10283 %}
10284 ins_pipe(pipe_class_default);
10285 %}
10286
10287 //----------Control Flow Instructions------------------------------------------
10288 // Compare Instructions
10289
10290 // Compare Integers
10291 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10292 match(Set crx (CmpI src1 src2));
10293 size(4);
10294 format %{ "CMPW $crx, $src1, $src2" %}
10295 ins_encode %{
10296 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10297 %}
10298 ins_pipe(pipe_class_compare);
10299 %}
10300
10301 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
10302 match(Set crx (CmpI src1 src2));
10303 format %{ "CMPWI $crx, $src1, $src2" %}
10304 size(4);
10305 ins_encode %{
10306 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10307 %}
10308 ins_pipe(pipe_class_compare);
10309 %}
10310
10311 // (src1 & src2) == 0?
10312 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
10313 match(Set cr0 (CmpI (AndI src1 src2) zero));
10314 // r0 is killed
10315 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
10316 size(4);
10317 ins_encode %{
10318 __ andi_(R0, $src1$$Register, $src2$$constant);
10319 %}
10320 ins_pipe(pipe_class_compare);
10321 %}
10322
10323 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10324 match(Set crx (CmpL src1 src2));
10325 format %{ "CMPD $crx, $src1, $src2" %}
10326 size(4);
10327 ins_encode %{
10328 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
10329 %}
10330 ins_pipe(pipe_class_compare);
10331 %}
10332
10333 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
10334 match(Set crx (CmpL src1 src2));
10335 format %{ "CMPDI $crx, $src1, $src2" %}
10336 size(4);
10337 ins_encode %{
10338 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10339 %}
10340 ins_pipe(pipe_class_compare);
10341 %}
10342
10343 // Added CmpUL for LoopPredicate.
10344 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10345 match(Set crx (CmpUL src1 src2));
10346 format %{ "CMPLD $crx, $src1, $src2" %}
10347 size(4);
10348 ins_encode %{
10349 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10350 %}
10351 ins_pipe(pipe_class_compare);
10352 %}
10353
10354 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
10355 match(Set crx (CmpUL src1 src2));
10356 format %{ "CMPLDI $crx, $src1, $src2" %}
10357 size(4);
10358 ins_encode %{
10359 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10360 %}
10361 ins_pipe(pipe_class_compare);
10362 %}
10363
10364 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
10365 match(Set cr0 (CmpL (AndL src1 src2) zero));
10366 // r0 is killed
10367 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
10368 size(4);
10369 ins_encode %{
10370 __ and_(R0, $src1$$Register, $src2$$Register);
10371 %}
10372 ins_pipe(pipe_class_compare);
10373 %}
10374
10375 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
10376 match(Set cr0 (CmpL (AndL src1 src2) zero));
10377 // r0 is killed
10378 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
10379 size(4);
10380 ins_encode %{
10381 __ andi_(R0, $src1$$Register, $src2$$constant);
10382 %}
10383 ins_pipe(pipe_class_compare);
10384 %}
10385
10386 // Manifest a CmpL3 result in an integer register.
10387 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10388 match(Set dst (CmpL3 src1 src2));
10389 effect(KILL cr0);
10390 ins_cost(DEFAULT_COST * 5);
10391 size((VM_Version::has_brw() ? 16 : 20));
10392
10393 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %}
10394
10395 ins_encode %{
10396 __ cmpd(CR0, $src1$$Register, $src2$$Register);
10397 __ set_cmp3($dst$$Register);
10398 %}
10399 ins_pipe(pipe_class_default);
10400 %}
10401
10402 instruct cmpU3_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
10403 match(Set dst (CmpU3 src1 src2));
10404 effect(KILL cr0);
10405 ins_cost(DEFAULT_COST * 5);
10406 size((VM_Version::has_brw() ? 16 : 20));
10407
10408 format %{ "cmpU3_reg_reg $dst, $src1, $src2" %}
10409
10410 ins_encode %{
10411 __ cmplw(CR0, $src1$$Register, $src2$$Register);
10412 __ set_cmp3($dst$$Register);
10413 %}
10414 ins_pipe(pipe_class_default);
10415 %}
10416
10417 instruct cmpUL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10418 match(Set dst (CmpUL3 src1 src2));
10419 effect(KILL cr0);
10420 ins_cost(DEFAULT_COST * 5);
10421 size((VM_Version::has_brw() ? 16 : 20));
10422
10423 format %{ "cmpUL3_reg_reg $dst, $src1, $src2" %}
10424
10425 ins_encode %{
10426 __ cmpld(CR0, $src1$$Register, $src2$$Register);
10427 __ set_cmp3($dst$$Register);
10428 %}
10429 ins_pipe(pipe_class_default);
10430 %}
10431
10432 // Implicit range checks.
10433 // A range check in the ideal world has one of the following shapes:
10434 // - (If le (CmpU length index)), (IfTrue throw exception)
10435 // - (If lt (CmpU index length)), (IfFalse throw exception)
10436 //
10437 // Match range check 'If le (CmpU length index)'.
10438 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
10439 match(If cmp (CmpU src_length index));
10440 effect(USE labl);
10441 predicate(TrapBasedRangeChecks &&
10442 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
10443 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
10444 (Matcher::branches_to_uncommon_trap(_leaf)));
10445
10446 ins_is_TrapBasedCheckNode(true);
10447
10448 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %}
10449 size(4);
10450 ins_encode %{
10451 if ($cmp$$cmpcode == 0x1 /* less_equal */) {
10452 __ trap_range_check_le($src_length$$Register, $index$$constant);
10453 } else {
10454 // Both successors are uncommon traps, probability is 0.
10455 // Node got flipped during fixup flow.
10456 assert($cmp$$cmpcode == 0x9, "must be greater");
10457 __ trap_range_check_g($src_length$$Register, $index$$constant);
10458 }
10459 %}
10460 ins_pipe(pipe_class_trap);
10461 %}
10462
10463 // Match range check 'If lt (CmpU index length)'.
10464 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
10465 match(If cmp (CmpU src_index src_length));
10466 effect(USE labl);
10467 predicate(TrapBasedRangeChecks &&
10468 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10469 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10470 (Matcher::branches_to_uncommon_trap(_leaf)));
10471
10472 ins_is_TrapBasedCheckNode(true);
10473
10474 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
10475 size(4);
10476 ins_encode %{
10477 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10478 __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
10479 } else {
10480 // Both successors are uncommon traps, probability is 0.
10481 // Node got flipped during fixup flow.
10482 assert($cmp$$cmpcode == 0x8, "must be less");
10483 __ trap_range_check_l($src_index$$Register, $src_length$$Register);
10484 }
10485 %}
10486 ins_pipe(pipe_class_trap);
10487 %}
10488
10489 // Match range check 'If lt (CmpU index length)'.
10490 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
10491 match(If cmp (CmpU src_index length));
10492 effect(USE labl);
10493 predicate(TrapBasedRangeChecks &&
10494 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10495 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10496 (Matcher::branches_to_uncommon_trap(_leaf)));
10497
10498 ins_is_TrapBasedCheckNode(true);
10499
10500 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %}
10501 size(4);
10502 ins_encode %{
10503 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10504 __ trap_range_check_ge($src_index$$Register, $length$$constant);
10505 } else {
10506 // Both successors are uncommon traps, probability is 0.
10507 // Node got flipped during fixup flow.
10508 assert($cmp$$cmpcode == 0x8, "must be less");
10509 __ trap_range_check_l($src_index$$Register, $length$$constant);
10510 }
10511 %}
10512 ins_pipe(pipe_class_trap);
10513 %}
10514
10515 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10516 match(Set crx (CmpU src1 src2));
10517 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %}
10518 size(4);
10519 ins_encode %{
10520 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10521 %}
10522 ins_pipe(pipe_class_compare);
10523 %}
10524
10525 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
10526 match(Set crx (CmpU src1 src2));
10527 size(4);
10528 format %{ "CMPLWI $crx, $src1, $src2" %}
10529 ins_encode %{
10530 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10531 %}
10532 ins_pipe(pipe_class_compare);
10533 %}
10534
10535 // Implicit zero checks (more implicit null checks).
10536 // No constant pool entries required.
10537 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
10538 match(If cmp (CmpN value zero));
10539 effect(USE labl);
10540 predicate(TrapBasedNullChecks &&
10541 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10542 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10543 Matcher::branches_to_uncommon_trap(_leaf));
10544 ins_cost(1);
10545
10546 ins_is_TrapBasedCheckNode(true);
10547
10548 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
10549 size(4);
10550 ins_encode %{
10551 if ($cmp$$cmpcode == 0xA) {
10552 __ trap_null_check($value$$Register);
10553 } else {
10554 // Both successors are uncommon traps, probability is 0.
10555 // Node got flipped during fixup flow.
10556 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10557 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10558 }
10559 %}
10560 ins_pipe(pipe_class_trap);
10561 %}
10562
10563 // Compare narrow oops.
10564 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
10565 match(Set crx (CmpN src1 src2));
10566
10567 size(4);
10568 ins_cost(2);
10569 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %}
10570 ins_encode %{
10571 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10572 %}
10573 ins_pipe(pipe_class_compare);
10574 %}
10575
10576 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
10577 match(Set crx (CmpN src1 src2));
10578 // Make this more expensive than zeroCheckN_iReg_imm0.
10579 ins_cost(2);
10580
10581 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %}
10582 size(4);
10583 ins_encode %{
10584 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10585 %}
10586 ins_pipe(pipe_class_compare);
10587 %}
10588
10589 // Implicit zero checks (more implicit null checks).
10590 // No constant pool entries required.
10591 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
10592 match(If cmp (CmpP value zero));
10593 effect(USE labl);
10594 predicate(TrapBasedNullChecks &&
10595 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10596 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10597 Matcher::branches_to_uncommon_trap(_leaf));
10598 ins_cost(1); // Should not be cheaper than zeroCheckN.
10599
10600 ins_is_TrapBasedCheckNode(true);
10601
10602 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
10603 size(4);
10604 ins_encode %{
10605 if ($cmp$$cmpcode == 0xA) {
10606 __ trap_null_check($value$$Register);
10607 } else {
10608 // Both successors are uncommon traps, probability is 0.
10609 // Node got flipped during fixup flow.
10610 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10611 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10612 }
10613 %}
10614 ins_pipe(pipe_class_trap);
10615 %}
10616
10617 // Compare Pointers
10618 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
10619 match(Set crx (CmpP src1 src2));
10620 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %}
10621 size(4);
10622 ins_encode %{
10623 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10624 %}
10625 ins_pipe(pipe_class_compare);
10626 %}
10627
10628 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
10629 match(Set crx (CmpP src1 src2));
10630 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %}
10631 size(4);
10632 ins_encode %{
10633 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
10634 %}
10635 ins_pipe(pipe_class_compare);
10636 %}
10637
10638 // Used in postalloc expand.
10639 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
10640 // This match rule prevents reordering of node before a safepoint.
10641 // This only makes sense if this instructions is used exclusively
10642 // for the expansion of EncodeP!
10643 match(Set crx (CmpP src1 src2));
10644 predicate(false);
10645
10646 format %{ "CMPDI $crx, $src1, $src2" %}
10647 size(4);
10648 ins_encode %{
10649 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10650 %}
10651 ins_pipe(pipe_class_compare);
10652 %}
10653
10654 //----------Float Compares----------------------------------------------------
10655
10656 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
10657 // Needs matchrule, see cmpDUnordered.
10658 match(Set crx (CmpF src1 src2));
10659 // no match-rule, false predicate
10660 predicate(false);
10661
10662 format %{ "cmpFUrd $crx, $src1, $src2" %}
10663 size(4);
10664 ins_encode %{
10665 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10666 %}
10667 ins_pipe(pipe_class_default);
10668 %}
10669
10670 // Compare floating, generate condition code.
10671 instruct cmpF_reg_reg(flagsReg crx, regF src1, regF src2) %{
10672 match(Set crx (CmpF src1 src2));
10673 ins_cost(DEFAULT_COST+BRANCH_COST);
10674
10675 format %{ "CMPF $crx, $src1, $src2" %}
10676 size(16);
10677 ins_encode %{
10678 Label done;
10679 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10680 __ bns($crx$$CondRegister, done);
10681 __ li(R0, 0);
10682 __ cmpwi($crx$$CondRegister, R0, 1);
10683 __ bind(done);
10684 %}
10685 ins_pipe(pipe_class_default);
10686 %}
10687
10688 // Compare float, generate -1,0,1
10689 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{
10690 match(Set dst (CmpF3 src1 src2));
10691 effect(KILL cr0);
10692 ins_cost(DEFAULT_COST * 6);
10693 size((VM_Version::has_brw() ? 20 : 24));
10694
10695 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %}
10696
10697 ins_encode %{
10698 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
10699 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
10700 %}
10701 ins_pipe(pipe_class_default);
10702 %}
10703
10704 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
10705 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
10706 // node right before the conditional move using it.
10707 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
10708 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
10709 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
10710 // conditional move was supposed to be spilled.
10711 match(Set crx (CmpD src1 src2));
10712 // False predicate, shall not be matched.
10713 predicate(false);
10714
10715 format %{ "cmpFUrd $crx, $src1, $src2" %}
10716 size(4);
10717 ins_encode %{
10718 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10719 %}
10720 ins_pipe(pipe_class_default);
10721 %}
10722
10723 instruct cmpD_reg_reg(flagsReg crx, regD src1, regD src2) %{
10724 match(Set crx (CmpD src1 src2));
10725 ins_cost(DEFAULT_COST+BRANCH_COST);
10726
10727 format %{ "CMPD $crx, $src1, $src2" %}
10728 size(16);
10729 ins_encode %{
10730 Label done;
10731 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10732 __ bns($crx$$CondRegister, done);
10733 __ li(R0, 0);
10734 __ cmpwi($crx$$CondRegister, R0, 1);
10735 __ bind(done);
10736 %}
10737 ins_pipe(pipe_class_default);
10738 %}
10739
10740 // Compare double, generate -1,0,1
10741 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{
10742 match(Set dst (CmpD3 src1 src2));
10743 effect(KILL cr0);
10744 ins_cost(DEFAULT_COST * 6);
10745 size((VM_Version::has_brw() ? 20 : 24));
10746
10747 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %}
10748
10749 ins_encode %{
10750 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
10751 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
10752 %}
10753 ins_pipe(pipe_class_default);
10754 %}
10755
10756 // Compare char
10757 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10758 match(Set dst (Digit src1));
10759 effect(TEMP src2, TEMP crx);
10760 ins_cost(3 * DEFAULT_COST);
10761
10762 format %{ "LI $src2, 0x3930\n\t"
10763 "CMPRB $crx, 0, $src1, $src2\n\t"
10764 "SETB $dst, $crx" %}
10765 size(12);
10766 ins_encode %{
10767 // 0x30: 0, 0x39: 9
10768 __ li($src2$$Register, 0x3930);
10769 // compare src1 with ranges 0x30 to 0x39
10770 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
10771 __ setb($dst$$Register, $crx$$CondRegister);
10772 %}
10773 ins_pipe(pipe_class_default);
10774 %}
10775
10776 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10777 match(Set dst (LowerCase src1));
10778 effect(TEMP src2, TEMP crx);
10779 ins_cost(12 * DEFAULT_COST);
10780
10781 format %{ "LI $src2, 0x7A61\n\t"
10782 "CMPRB $crx, 0, $src1, $src2\n\t"
10783 "BGT $crx, done\n\t"
10784 "LIS $src2, (signed short)0xF6DF\n\t"
10785 "ORI $src2, $src2, 0xFFF8\n\t"
10786 "CMPRB $crx, 1, $src1, $src2\n\t"
10787 "BGT $crx, done\n\t"
10788 "LIS $src2, (signed short)0xAAB5\n\t"
10789 "ORI $src2, $src2, 0xBABA\n\t"
10790 "INSRDI $src2, $src2, 32, 0\n\t"
10791 "CMPEQB $crx, 1, $src1, $src2\n"
10792 "done:\n\t"
10793 "SETB $dst, $crx" %}
10794
10795 size(48);
10796 ins_encode %{
10797 Label done;
10798 // 0x61: a, 0x7A: z
10799 __ li($src2$$Register, 0x7A61);
10800 // compare src1 with ranges 0x61 to 0x7A
10801 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
10802 __ bgt($crx$$CondRegister, done);
10803
10804 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
10805 __ lis($src2$$Register, (signed short)0xF6DF);
10806 __ ori($src2$$Register, $src2$$Register, 0xFFF8);
10807 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
10808 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10809 __ bgt($crx$$CondRegister, done);
10810
10811 // 0xAA: feminine ordinal indicator
10812 // 0xB5: micro sign
10813 // 0xBA: masculine ordinal indicator
10814 __ lis($src2$$Register, (signed short)0xAAB5);
10815 __ ori($src2$$Register, $src2$$Register, 0xBABA);
10816 __ insrdi($src2$$Register, $src2$$Register, 32, 0);
10817 // compare src1 with 0xAA, 0xB5, and 0xBA
10818 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
10819
10820 __ bind(done);
10821 __ setb($dst$$Register, $crx$$CondRegister);
10822 %}
10823 ins_pipe(pipe_class_default);
10824 %}
10825
10826 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10827 match(Set dst (UpperCase src1));
10828 effect(TEMP src2, TEMP crx);
10829 ins_cost(7 * DEFAULT_COST);
10830
10831 format %{ "LI $src2, 0x5A41\n\t"
10832 "CMPRB $crx, 0, $src1, $src2\n\t"
10833 "BGT $crx, done\n\t"
10834 "LIS $src2, (signed short)0xD6C0\n\t"
10835 "ORI $src2, $src2, 0xDED8\n\t"
10836 "CMPRB $crx, 1, $src1, $src2\n"
10837 "done:\n\t"
10838 "SETB $dst, $crx" %}
10839
10840 size(28);
10841 ins_encode %{
10842 Label done;
10843 // 0x41: A, 0x5A: Z
10844 __ li($src2$$Register, 0x5A41);
10845 // compare src1 with a range 0x41 to 0x5A
10846 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
10847 __ bgt($crx$$CondRegister, done);
10848
10849 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
10850 __ lis($src2$$Register, (signed short)0xD6C0);
10851 __ ori($src2$$Register, $src2$$Register, 0xDED8);
10852 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
10853 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10854
10855 __ bind(done);
10856 __ setb($dst$$Register, $crx$$CondRegister);
10857 %}
10858 ins_pipe(pipe_class_default);
10859 %}
10860
10861 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10862 match(Set dst (Whitespace src1));
10863 predicate(PowerArchitecturePPC64 <= 9);
10864 effect(TEMP src2, TEMP crx);
10865 ins_cost(4 * DEFAULT_COST);
10866
10867 format %{ "LI $src2, 0x0D09\n\t"
10868 "ADDIS $src2, 0x201C\n\t"
10869 "CMPRB $crx, 1, $src1, $src2\n\t"
10870 "SETB $dst, $crx" %}
10871 size(16);
10872 ins_encode %{
10873 // 0x09 to 0x0D, 0x1C to 0x20
10874 __ li($src2$$Register, 0x0D09);
10875 __ addis($src2$$Register, $src2$$Register, 0x0201C);
10876 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
10877 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10878 __ setb($dst$$Register, $crx$$CondRegister);
10879 %}
10880 ins_pipe(pipe_class_default);
10881 %}
10882
10883 // Power 10 version, using prefixed addi to load 32-bit constant
10884 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10885 match(Set dst (Whitespace src1));
10886 predicate(PowerArchitecturePPC64 >= 10);
10887 effect(TEMP src2, TEMP crx);
10888 ins_cost(3 * DEFAULT_COST);
10889
10890 format %{ "PLI $src2, 0x201C0D09\n\t"
10891 "CMPRB $crx, 1, $src1, $src2\n\t"
10892 "SETB $dst, $crx" %}
10893 size(16);
10894 ins_encode %{
10895 // 0x09 to 0x0D, 0x1C to 0x20
10896 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
10897 __ pli($src2$$Register, 0x201C0D09);
10898 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
10899 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10900 __ setb($dst$$Register, $crx$$CondRegister);
10901 %}
10902 ins_pipe(pipe_class_default);
10903 ins_alignment(2);
10904 %}
10905
10906 //----------Branches---------------------------------------------------------
10907 // Jump
10908
10909 // Direct Branch.
10910 instruct branch(label labl) %{
10911 match(Goto);
10912 effect(USE labl);
10913 ins_cost(BRANCH_COST);
10914
10915 format %{ "B $labl" %}
10916 size(4);
10917 ins_encode %{
10918 Label d; // dummy
10919 __ bind(d);
10920 Label* p = $labl$$label;
10921 // `p' is `nullptr' when this encoding class is used only to
10922 // determine the size of the encoded instruction.
10923 Label& l = (nullptr == p)? d : *(p);
10924 __ b(l);
10925 %}
10926 ins_pipe(pipe_class_default);
10927 %}
10928
10929 // Conditional Near Branch
10930 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
10931 // Same match rule as `branchConFar'.
10932 match(If cmp crx);
10933 effect(USE lbl);
10934 ins_cost(BRANCH_COST);
10935
10936 // If set to 1 this indicates that the current instruction is a
10937 // short variant of a long branch. This avoids using this
10938 // instruction in first-pass matching. It will then only be used in
10939 // the `Shorten_branches' pass.
10940 ins_short_branch(1);
10941
10942 format %{ "B$cmp $crx, $lbl" %}
10943 size(4);
10944 ins_encode( enc_bc(crx, cmp, lbl) );
10945 ins_pipe(pipe_class_default);
10946 %}
10947
10948 // This is for cases when the ppc64 `bc' instruction does not
10949 // reach far enough. So we emit a far branch here, which is more
10950 // expensive.
10951 //
10952 // Conditional Far Branch
10953 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
10954 // Same match rule as `branchCon'.
10955 match(If cmp crx);
10956 effect(USE crx, USE lbl);
10957 // Higher cost than `branchCon'.
10958 ins_cost(5*BRANCH_COST);
10959
10960 // This is not a short variant of a branch, but the long variant.
10961 ins_short_branch(0);
10962
10963 format %{ "B_FAR$cmp $crx, $lbl" %}
10964 size(8);
10965 ins_encode( enc_bc_far(crx, cmp, lbl) );
10966 ins_pipe(pipe_class_default);
10967 %}
10968
10969 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
10970 match(CountedLoopEnd cmp crx);
10971 effect(USE labl);
10972 ins_cost(BRANCH_COST);
10973
10974 // short variant.
10975 ins_short_branch(1);
10976
10977 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
10978 size(4);
10979 ins_encode( enc_bc(crx, cmp, labl) );
10980 ins_pipe(pipe_class_default);
10981 %}
10982
10983 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
10984 match(CountedLoopEnd cmp crx);
10985 effect(USE labl);
10986 ins_cost(BRANCH_COST);
10987
10988 // Long variant.
10989 ins_short_branch(0);
10990
10991 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
10992 size(8);
10993 ins_encode( enc_bc_far(crx, cmp, labl) );
10994 ins_pipe(pipe_class_default);
10995 %}
10996
10997 // ============================================================================
10998 // Java runtime operations, intrinsics and other complex operations.
10999
11000 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
11001 // array for an instance of the superklass. Set a hidden internal cache on a
11002 // hit (cache is checked with exposed code in gen_subtype_check()). Return
11003 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
11004 //
11005 // GL TODO: Improve this.
11006 // - result should not be a TEMP
11007 // - Add match rule as on sparc avoiding additional Cmp.
11008 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
11009 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
11010 match(Set result (PartialSubtypeCheck subklass superklass));
11011 predicate(!UseSecondarySupersTable);
11012 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
11013 ins_cost(DEFAULT_COST*10);
11014
11015 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
11016 ins_encode %{
11017 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
11018 $tmp_klass$$Register, nullptr, $result$$Register);
11019 %}
11020 ins_pipe(pipe_class_default);
11021 %}
11022
11023 // Two versions of partialSubtypeCheck, both used when we need to
11024 // search for a super class in the secondary supers array. The first
11025 // is used when we don't know _a priori_ the class being searched
11026 // for. The second, far more common, is used when we do know: this is
11027 // used for instanceof, checkcast, and any case where C2 can determine
11028 // it by constant propagation.
11029 instruct partialSubtypeCheckVarSuper(iRegPsrc sub, iRegPsrc super, iRegPdst result,
11030 iRegPdst tempR1, iRegPdst tempR2, iRegPdst tempR3, iRegPdst tempR4,
11031 flagsRegCR0 cr0, regCTR ctr)
11032 %{
11033 match(Set result (PartialSubtypeCheck sub super));
11034 predicate(UseSecondarySupersTable);
11035 effect(KILL cr0, KILL ctr, TEMP_DEF result, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11036
11037 ins_cost(DEFAULT_COST * 10); // slightly larger than the next version
11038 format %{ "partialSubtypeCheck $result, $sub, $super" %}
11039 ins_encode %{
11040 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register,
11041 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11042 $result$$Register);
11043 %}
11044 ins_pipe(pipe_class_memory);
11045 %}
11046
11047 instruct partialSubtypeCheckConstSuper(rarg3RegP sub, rarg2RegP super_reg, immP super_con, rarg6RegP result,
11048 rarg1RegP tempR1, rarg5RegP tempR2, rarg4RegP tempR3, rscratch1RegP tempR4,
11049 flagsRegCR0 cr0, regCTR ctr)
11050 %{
11051 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
11052 predicate(UseSecondarySupersTable);
11053 effect(KILL cr0, KILL ctr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11054
11055 ins_cost(DEFAULT_COST*8); // smaller than the other version
11056 format %{ "partialSubtypeCheck $result, $sub, $super_reg" %}
11057
11058 ins_encode %{
11059 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
11060 if (InlineSecondarySupersTest) {
11061 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register,
11062 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11063 $result$$Register, super_klass_slot);
11064 } else {
11065 address stub = StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot);
11066 Register r_stub_addr = $tempR1$$Register;
11067 __ add_const_optimized(r_stub_addr, R29_TOC, MacroAssembler::offset_to_global_toc(stub), R0);
11068 __ mtctr(r_stub_addr);
11069 __ bctrl();
11070 }
11071 %}
11072
11073 ins_pipe(pipe_class_memory);
11074 %}
11075
11076 // inlined locking and unlocking
11077
11078 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
11079 predicate(!UseObjectMonitorTable);
11080 match(Set crx (FastLock oop box));
11081 effect(TEMP tmp1, TEMP tmp2);
11082
11083 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %}
11084 ins_encode %{
11085 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11086 $tmp1$$Register, $tmp2$$Register, noreg /*tmp3*/);
11087 // If locking was successful, crx should indicate 'EQ'.
11088 // The compiler generates a branch to the runtime call to
11089 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11090 %}
11091 ins_pipe(pipe_class_compare);
11092 %}
11093
11094 instruct cmpFastLockMonitorTable(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, flagsRegCR1 cr1) %{
11095 predicate(UseObjectMonitorTable);
11096 match(Set crx (FastLock oop box));
11097 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr1);
11098
11099 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3" %}
11100 ins_encode %{
11101 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11102 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11103 // If locking was successful, crx should indicate 'EQ'.
11104 // The compiler generates a branch to the runtime call to
11105 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11106 %}
11107 ins_pipe(pipe_class_compare);
11108 %}
11109
11110 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11111 match(Set crx (FastUnlock oop box));
11112 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11113
11114 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
11115 ins_encode %{
11116 __ fast_unlock($crx$$CondRegister, $oop$$Register, $box$$Register,
11117 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11118 // If unlocking was successful, crx should indicate 'EQ'.
11119 // The compiler generates a branch to the runtime call to
11120 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11121 %}
11122 ins_pipe(pipe_class_compare);
11123 %}
11124
11125 // Align address.
11126 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11127 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11128
11129 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
11130 size(4);
11131 ins_encode %{
11132 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant));
11133 %}
11134 ins_pipe(pipe_class_default);
11135 %}
11136
11137 // Array size computation.
11138 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11139 match(Set dst (SubL (CastP2X end) (CastP2X start)));
11140
11141 format %{ "SUB $dst, $end, $start \t// array size in bytes" %}
11142 size(4);
11143 ins_encode %{
11144 __ subf($dst$$Register, $start$$Register, $end$$Register);
11145 %}
11146 ins_pipe(pipe_class_default);
11147 %}
11148
11149 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
11150 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, immL_0 zero, Universe dummy, regCTR ctr) %{
11151 match(Set dummy (ClearArray (Binary cnt base) zero));
11152 effect(USE_KILL base, KILL ctr);
11153 ins_cost(2 * MEMORY_REF_COST);
11154
11155 format %{ "ClearArray $cnt, $base" %}
11156 ins_encode %{
11157 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
11158 %}
11159 ins_pipe(pipe_class_default);
11160 %}
11161
11162 // Clear-array with constant large array length.
11163 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, immL_0 zero, Universe dummy, iRegLdst tmp, regCTR ctr) %{
11164 match(Set dummy (ClearArray (Binary cnt base) zero));
11165 effect(USE_KILL base, TEMP tmp, KILL ctr);
11166 ins_cost(3 * MEMORY_REF_COST);
11167
11168 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
11169 ins_encode %{
11170 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
11171 %}
11172 ins_pipe(pipe_class_default);
11173 %}
11174
11175 // Clear-array with dynamic array length.
11176 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, immL_0 zero, Universe dummy, regCTR ctr) %{
11177 match(Set dummy (ClearArray (Binary cnt base) zero));
11178 effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11179 ins_cost(4 * MEMORY_REF_COST);
11180
11181 format %{ "ClearArray $cnt, $base" %}
11182 ins_encode %{
11183 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
11184 %}
11185 ins_pipe(pipe_class_default);
11186 %}
11187
11188 // Clear-array with dynamic array length and non-zero value.
11189 instruct inlineCallClearArrayWordCopy(rarg1RegL cnt, rarg2RegP base, iRegLdst val, Universe dummy, regCTR ctr) %{
11190 predicate(((ClearArrayNode*)n)->word_copy_only());
11191 match(Set dummy (ClearArray (Binary cnt base) val));
11192 effect(USE_KILL base, KILL ctr);
11193 ins_cost(8 * MEMORY_REF_COST);
11194
11195 format %{ "ClearArray $cnt, $base, $val" %}
11196 ins_encode %{
11197 __ fill_words($base$$Register, $cnt$$Register, $val$$Register);
11198 %}
11199 ins_pipe(pipe_class_default);
11200 %}
11201
11202 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11203 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11204 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11205 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11206 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11207 ins_cost(300);
11208 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11209 ins_encode %{
11210 __ string_compare($str1$$Register, $str2$$Register,
11211 $cnt1$$Register, $cnt2$$Register,
11212 $tmp$$Register,
11213 $result$$Register, StrIntrinsicNode::LL);
11214 %}
11215 ins_pipe(pipe_class_default);
11216 %}
11217
11218 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11219 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11220 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11221 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11222 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11223 ins_cost(300);
11224 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11225 ins_encode %{
11226 __ string_compare($str1$$Register, $str2$$Register,
11227 $cnt1$$Register, $cnt2$$Register,
11228 $tmp$$Register,
11229 $result$$Register, StrIntrinsicNode::UU);
11230 %}
11231 ins_pipe(pipe_class_default);
11232 %}
11233
11234 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11235 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11236 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11237 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11238 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11239 ins_cost(300);
11240 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11241 ins_encode %{
11242 __ string_compare($str1$$Register, $str2$$Register,
11243 $cnt1$$Register, $cnt2$$Register,
11244 $tmp$$Register,
11245 $result$$Register, StrIntrinsicNode::LU);
11246 %}
11247 ins_pipe(pipe_class_default);
11248 %}
11249
11250 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11251 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11252 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11253 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11254 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11255 ins_cost(300);
11256 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11257 ins_encode %{
11258 __ string_compare($str2$$Register, $str1$$Register,
11259 $cnt2$$Register, $cnt1$$Register,
11260 $tmp$$Register,
11261 $result$$Register, StrIntrinsicNode::UL);
11262 %}
11263 ins_pipe(pipe_class_default);
11264 %}
11265
11266 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11267 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11268 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11269 match(Set result (StrEquals (Binary str1 str2) cnt));
11270 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11271 ins_cost(300);
11272 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11273 ins_encode %{
11274 __ array_equals(false, $str1$$Register, $str2$$Register,
11275 $cnt$$Register, $tmp$$Register,
11276 $result$$Register, true /* byte */);
11277 %}
11278 ins_pipe(pipe_class_default);
11279 %}
11280
11281 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11282 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11283 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11284 match(Set result (AryEq ary1 ary2));
11285 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11286 ins_cost(300);
11287 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11288 ins_encode %{
11289 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11290 $tmp1$$Register, $tmp2$$Register,
11291 $result$$Register, true /* byte */);
11292 %}
11293 ins_pipe(pipe_class_default);
11294 %}
11295
11296 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11297 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11298 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11299 match(Set result (AryEq ary1 ary2));
11300 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11301 ins_cost(300);
11302 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11303 ins_encode %{
11304 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11305 $tmp1$$Register, $tmp2$$Register,
11306 $result$$Register, false /* byte */);
11307 %}
11308 ins_pipe(pipe_class_default);
11309 %}
11310
11311 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11312 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11313 iRegIdst tmp1, iRegIdst tmp2,
11314 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11315 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11316 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11317 // Required for EA: check if it is still a type_array.
11318 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11319 ins_cost(150);
11320
11321 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11322 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11323
11324 ins_encode %{
11325 immPOper *needleOper = (immPOper *)$needleImm;
11326 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11327 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11328 jchar chr;
11329 #ifdef VM_LITTLE_ENDIAN
11330 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11331 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11332 #else
11333 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11334 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11335 #endif
11336 __ string_indexof_char($result$$Register,
11337 $haystack$$Register, $haycnt$$Register,
11338 R0, chr,
11339 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11340 %}
11341 ins_pipe(pipe_class_compare);
11342 %}
11343
11344 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11345 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11346 iRegIdst tmp1, iRegIdst tmp2,
11347 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11348 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11349 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11350 // Required for EA: check if it is still a type_array.
11351 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11352 ins_cost(150);
11353
11354 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11355 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11356
11357 ins_encode %{
11358 immPOper *needleOper = (immPOper *)$needleImm;
11359 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11360 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11361 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11362 __ string_indexof_char($result$$Register,
11363 $haystack$$Register, $haycnt$$Register,
11364 R0, chr,
11365 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11366 %}
11367 ins_pipe(pipe_class_compare);
11368 %}
11369
11370 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11371 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11372 iRegIdst tmp1, iRegIdst tmp2,
11373 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11374 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11375 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11376 // Required for EA: check if it is still a type_array.
11377 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11378 ins_cost(150);
11379
11380 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11381 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11382
11383 ins_encode %{
11384 immPOper *needleOper = (immPOper *)$needleImm;
11385 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11386 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11387 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11388 __ string_indexof_char($result$$Register,
11389 $haystack$$Register, $haycnt$$Register,
11390 R0, chr,
11391 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11392 %}
11393 ins_pipe(pipe_class_compare);
11394 %}
11395
11396 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11397 rscratch2RegP needle, immI_1 needlecntImm,
11398 iRegIdst tmp1, iRegIdst tmp2,
11399 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11400 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11401 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11402 // Required for EA: check if it is still a type_array.
11403 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11404 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11405 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11406 ins_cost(180);
11407
11408 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11409 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11410 ins_encode %{
11411 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11412 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11413 guarantee(needle_values, "sanity");
11414 jchar chr;
11415 #ifdef VM_LITTLE_ENDIAN
11416 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11417 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11418 #else
11419 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11420 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11421 #endif
11422 __ string_indexof_char($result$$Register,
11423 $haystack$$Register, $haycnt$$Register,
11424 R0, chr,
11425 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11426 %}
11427 ins_pipe(pipe_class_compare);
11428 %}
11429
11430 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11431 rscratch2RegP needle, immI_1 needlecntImm,
11432 iRegIdst tmp1, iRegIdst tmp2,
11433 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11434 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11435 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11436 // Required for EA: check if it is still a type_array.
11437 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11438 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11439 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11440 ins_cost(180);
11441
11442 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11443 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11444 ins_encode %{
11445 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11446 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11447 guarantee(needle_values, "sanity");
11448 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11449 __ string_indexof_char($result$$Register,
11450 $haystack$$Register, $haycnt$$Register,
11451 R0, chr,
11452 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11453 %}
11454 ins_pipe(pipe_class_compare);
11455 %}
11456
11457 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11458 rscratch2RegP needle, immI_1 needlecntImm,
11459 iRegIdst tmp1, iRegIdst tmp2,
11460 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11461 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11462 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11463 // Required for EA: check if it is still a type_array.
11464 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11465 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11466 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11467 ins_cost(180);
11468
11469 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11470 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11471 ins_encode %{
11472 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11473 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11474 guarantee(needle_values, "sanity");
11475 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11476 __ string_indexof_char($result$$Register,
11477 $haystack$$Register, $haycnt$$Register,
11478 R0, chr,
11479 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11480 %}
11481 ins_pipe(pipe_class_compare);
11482 %}
11483
11484 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11485 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11486 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11487 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11488 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11489 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
11490 ins_cost(180);
11491
11492 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch"
11493 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11494 ins_encode %{
11495 __ string_indexof_char($result$$Register,
11496 $haystack$$Register, $haycnt$$Register,
11497 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11498 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11499 %}
11500 ins_pipe(pipe_class_compare);
11501 %}
11502
11503 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11504 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11505 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11506 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11507 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11508 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
11509 ins_cost(180);
11510
11511 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch"
11512 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11513 ins_encode %{
11514 __ string_indexof_char($result$$Register,
11515 $haystack$$Register, $haycnt$$Register,
11516 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11517 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11518 %}
11519 ins_pipe(pipe_class_compare);
11520 %}
11521
11522 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11523 iRegPsrc needle, uimmI15 needlecntImm,
11524 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11525 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11526 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11527 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11528 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11529 // Required for EA: check if it is still a type_array.
11530 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11531 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11532 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11533 ins_cost(250);
11534
11535 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11536 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11537 ins_encode %{
11538 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11539 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11540
11541 __ string_indexof($result$$Register,
11542 $haystack$$Register, $haycnt$$Register,
11543 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11544 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11545 %}
11546 ins_pipe(pipe_class_compare);
11547 %}
11548
11549 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11550 iRegPsrc needle, uimmI15 needlecntImm,
11551 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11552 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11553 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11554 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11555 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11556 // Required for EA: check if it is still a type_array.
11557 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11558 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11559 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11560 ins_cost(250);
11561
11562 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11563 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11564 ins_encode %{
11565 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11566 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11567
11568 __ string_indexof($result$$Register,
11569 $haystack$$Register, $haycnt$$Register,
11570 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11571 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11572 %}
11573 ins_pipe(pipe_class_compare);
11574 %}
11575
11576 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11577 iRegPsrc needle, uimmI15 needlecntImm,
11578 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11579 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11580 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11581 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11582 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11583 // Required for EA: check if it is still a type_array.
11584 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11585 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11586 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11587 ins_cost(250);
11588
11589 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11590 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11591 ins_encode %{
11592 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11593 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11594
11595 __ string_indexof($result$$Register,
11596 $haystack$$Register, $haycnt$$Register,
11597 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11598 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11599 %}
11600 ins_pipe(pipe_class_compare);
11601 %}
11602
11603 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11604 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11605 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11606 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11607 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11608 TEMP_DEF result,
11609 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11610 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11611 ins_cost(300);
11612
11613 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11614 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11615 ins_encode %{
11616 __ string_indexof($result$$Register,
11617 $haystack$$Register, $haycnt$$Register,
11618 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11619 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11620 %}
11621 ins_pipe(pipe_class_compare);
11622 %}
11623
11624 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11625 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11626 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11627 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11628 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11629 TEMP_DEF result,
11630 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11631 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11632 ins_cost(300);
11633
11634 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11635 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11636 ins_encode %{
11637 __ string_indexof($result$$Register,
11638 $haystack$$Register, $haycnt$$Register,
11639 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11640 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11641 %}
11642 ins_pipe(pipe_class_compare);
11643 %}
11644
11645 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11646 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11647 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11648 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11649 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11650 TEMP_DEF result,
11651 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11652 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11653 ins_cost(300);
11654
11655 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11656 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11657 ins_encode %{
11658 __ string_indexof($result$$Register,
11659 $haystack$$Register, $haycnt$$Register,
11660 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11661 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11662 %}
11663 ins_pipe(pipe_class_compare);
11664 %}
11665
11666 // char[] to byte[] compression
11667 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11668 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11669 match(Set result (StrCompressedCopy src (Binary dst len)));
11670 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11671 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11672 ins_cost(300);
11673 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11674 ins_encode %{
11675 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11676 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11677 %}
11678 ins_pipe(pipe_class_default);
11679 %}
11680
11681 // byte[] to char[] inflation
11682 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
11683 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11684 match(Set dummy (StrInflatedCopy src (Binary dst len)));
11685 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11686 ins_cost(300);
11687 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11688 ins_encode %{
11689 Label Ldone;
11690 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
11691 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11692 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
11693 __ beq(CR0, Ldone);
11694 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
11695 __ bind(Ldone);
11696 %}
11697 ins_pipe(pipe_class_default);
11698 %}
11699
11700 // StringCoding.java intrinsics
11701 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
11702 regCTR ctr, flagsRegCR0 cr0)
11703 %{
11704 match(Set result (CountPositives ary1 len));
11705 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
11706 ins_cost(300);
11707 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
11708 ins_encode %{
11709 __ count_positives($ary1$$Register, $len$$Register, $result$$Register,
11710 $tmp1$$Register, $tmp2$$Register);
11711 %}
11712 ins_pipe(pipe_class_default);
11713 %}
11714
11715 // encode char[] to byte[] in ISO_8859_1
11716 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11717 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11718 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
11719 match(Set result (EncodeISOArray src (Binary dst len)));
11720 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11721 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11722 ins_cost(300);
11723 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11724 ins_encode %{
11725 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11726 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11727 %}
11728 ins_pipe(pipe_class_default);
11729 %}
11730
11731 // encode char[] to byte[] in ASCII
11732 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11733 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11734 predicate(((EncodeISOArrayNode*)n)->is_ascii());
11735 match(Set result (EncodeISOArray src (Binary dst len)));
11736 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11737 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11738 ins_cost(300);
11739 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11740 ins_encode %{
11741 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11742 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
11743 %}
11744 ins_pipe(pipe_class_default);
11745 %}
11746
11747
11748 //---------- Min/Max Instructions ---------------------------------------------
11749
11750
11751 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
11752 match(Set dst (MinI src1 src2));
11753 effect(KILL cr0);
11754 ins_cost(DEFAULT_COST*2);
11755
11756 size(8);
11757 ins_encode %{
11758 __ cmpw(CR0, $src1$$Register, $src2$$Register);
11759 __ isel($dst$$Register, CR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
11760 %}
11761 ins_pipe(pipe_class_default);
11762 %}
11763
11764
11765 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
11766 match(Set dst (MaxI src1 src2));
11767 effect(KILL cr0);
11768 ins_cost(DEFAULT_COST*2);
11769
11770 size(8);
11771 ins_encode %{
11772 __ cmpw(CR0, $src1$$Register, $src2$$Register);
11773 __ isel($dst$$Register, CR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
11774 %}
11775 ins_pipe(pipe_class_default);
11776 %}
11777
11778 instruct minF(regF dst, regF src1, regF src2) %{
11779 match(Set dst (MinF src1 src2));
11780 predicate(PowerArchitecturePPC64 >= 9);
11781 ins_cost(DEFAULT_COST);
11782
11783 format %{ "XSMINJDP $dst, $src1, $src2\t// MinF" %}
11784 size(4);
11785 ins_encode %{
11786 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11787 %}
11788 ins_pipe(pipe_class_default);
11789 %}
11790
11791 instruct minD(regD dst, regD src1, regD src2) %{
11792 match(Set dst (MinD src1 src2));
11793 predicate(PowerArchitecturePPC64 >= 9);
11794 ins_cost(DEFAULT_COST);
11795
11796 format %{ "XSMINJDP $dst, $src1, $src2\t// MinD" %}
11797 size(4);
11798 ins_encode %{
11799 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11800 %}
11801 ins_pipe(pipe_class_default);
11802 %}
11803
11804 instruct maxF(regF dst, regF src1, regF src2) %{
11805 match(Set dst (MaxF src1 src2));
11806 predicate(PowerArchitecturePPC64 >= 9);
11807 ins_cost(DEFAULT_COST);
11808
11809 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxF" %}
11810 size(4);
11811 ins_encode %{
11812 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11813 %}
11814 ins_pipe(pipe_class_default);
11815 %}
11816
11817 instruct maxD(regD dst, regD src1, regD src2) %{
11818 match(Set dst (MaxD src1 src2));
11819 predicate(PowerArchitecturePPC64 >= 9);
11820 ins_cost(DEFAULT_COST);
11821
11822 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxD" %}
11823 size(4);
11824 ins_encode %{
11825 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11826 %}
11827 ins_pipe(pipe_class_default);
11828 %}
11829
11830 //---------- Population Count Instructions ------------------------------------
11831
11832 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
11833 match(Set dst (PopCountI src));
11834 predicate(UsePopCountInstruction);
11835 ins_cost(DEFAULT_COST);
11836
11837 format %{ "POPCNTW $dst, $src" %}
11838 size(4);
11839 ins_encode %{
11840 __ popcntw($dst$$Register, $src$$Register);
11841 %}
11842 ins_pipe(pipe_class_default);
11843 %}
11844
11845 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
11846 predicate(UsePopCountInstruction);
11847 match(Set dst (PopCountL src));
11848 ins_cost(DEFAULT_COST);
11849
11850 format %{ "POPCNTD $dst, $src" %}
11851 size(4);
11852 ins_encode %{
11853 __ popcntd($dst$$Register, $src$$Register);
11854 %}
11855 ins_pipe(pipe_class_default);
11856 %}
11857
11858 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
11859 match(Set dst (CountLeadingZerosI src));
11860 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
11861 ins_cost(DEFAULT_COST);
11862
11863 format %{ "CNTLZW $dst, $src" %}
11864 size(4);
11865 ins_encode %{
11866 __ cntlzw($dst$$Register, $src$$Register);
11867 %}
11868 ins_pipe(pipe_class_default);
11869 %}
11870
11871 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
11872 match(Set dst (CountLeadingZerosL src));
11873 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
11874 ins_cost(DEFAULT_COST);
11875
11876 format %{ "CNTLZD $dst, $src" %}
11877 size(4);
11878 ins_encode %{
11879 __ cntlzd($dst$$Register, $src$$Register);
11880 %}
11881 ins_pipe(pipe_class_default);
11882 %}
11883
11884 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
11885 // no match-rule, false predicate
11886 effect(DEF dst, USE src);
11887 predicate(false);
11888
11889 format %{ "CNTLZD $dst, $src" %}
11890 size(4);
11891 ins_encode %{
11892 __ cntlzd($dst$$Register, $src$$Register);
11893 %}
11894 ins_pipe(pipe_class_default);
11895 %}
11896
11897 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
11898 match(Set dst (CountTrailingZerosI src));
11899 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
11900 ins_cost(DEFAULT_COST);
11901
11902 expand %{
11903 immI16 imm1 %{ (int)-1 %}
11904 immI16 imm2 %{ (int)32 %}
11905 immI_minus1 m1 %{ -1 %}
11906 iRegIdst tmpI1;
11907 iRegIdst tmpI2;
11908 iRegIdst tmpI3;
11909 addI_reg_imm16(tmpI1, src, imm1);
11910 andcI_reg_reg(tmpI2, src, m1, tmpI1);
11911 countLeadingZerosI(tmpI3, tmpI2);
11912 subI_imm16_reg(dst, imm2, tmpI3);
11913 %}
11914 %}
11915
11916 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{
11917 match(Set dst (CountTrailingZerosI src));
11918 predicate(UseCountTrailingZerosInstructionsPPC64);
11919 ins_cost(DEFAULT_COST);
11920
11921 format %{ "CNTTZW $dst, $src" %}
11922 size(4);
11923 ins_encode %{
11924 __ cnttzw($dst$$Register, $src$$Register);
11925 %}
11926 ins_pipe(pipe_class_default);
11927 %}
11928
11929 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
11930 match(Set dst (CountTrailingZerosL src));
11931 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
11932 ins_cost(DEFAULT_COST);
11933
11934 expand %{
11935 immL16 imm1 %{ (long)-1 %}
11936 immI16 imm2 %{ (int)64 %}
11937 iRegLdst tmpL1;
11938 iRegLdst tmpL2;
11939 iRegIdst tmpL3;
11940 addL_reg_imm16(tmpL1, src, imm1);
11941 andcL_reg_reg(tmpL2, tmpL1, src);
11942 countLeadingZerosL(tmpL3, tmpL2);
11943 subI_imm16_reg(dst, imm2, tmpL3);
11944 %}
11945 %}
11946
11947 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{
11948 match(Set dst (CountTrailingZerosL src));
11949 predicate(UseCountTrailingZerosInstructionsPPC64);
11950 ins_cost(DEFAULT_COST);
11951
11952 format %{ "CNTTZD $dst, $src" %}
11953 size(4);
11954 ins_encode %{
11955 __ cnttzd($dst$$Register, $src$$Register);
11956 %}
11957 ins_pipe(pipe_class_default);
11958 %}
11959
11960 // Expand nodes for byte_reverse_int/ushort/short.
11961 instruct rlwinm(iRegIdst dst, iRegIsrc src, immI16 shift, immI16 mb, immI16 me) %{
11962 effect(DEF dst, USE src, USE shift, USE mb, USE me);
11963 predicate(false);
11964
11965 format %{ "RLWINM $dst, $src, $shift, $mb, $me" %}
11966 size(4);
11967 ins_encode %{
11968 __ rlwinm($dst$$Register, $src$$Register, $shift$$constant, $mb$$constant, $me$$constant);
11969 %}
11970 ins_pipe(pipe_class_default);
11971 %}
11972
11973 // Expand nodes for byte_reverse_int.
11974 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
11975 effect(DEF dst, USE src, USE n, USE b);
11976 predicate(false);
11977
11978 format %{ "INSRWI $dst, $src, $n, $b" %}
11979 size(4);
11980 ins_encode %{
11981 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
11982 %}
11983 ins_pipe(pipe_class_default);
11984 %}
11985
11986 // As insrwi_a, but with USE_DEF.
11987 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
11988 effect(USE_DEF dst, USE src, USE n, USE b);
11989 predicate(false);
11990
11991 format %{ "INSRWI $dst, $src, $n, $b" %}
11992 size(4);
11993 ins_encode %{
11994 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
11995 %}
11996 ins_pipe(pipe_class_default);
11997 %}
11998
11999 // Just slightly faster than java implementation.
12000 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
12001 match(Set dst (ReverseBytesI src));
12002 predicate(!UseByteReverseInstructions);
12003 ins_cost(7*DEFAULT_COST);
12004
12005 expand %{
12006 immI16 imm24 %{ (int) 24 %}
12007 immI16 imm16 %{ (int) 16 %}
12008 immI16 imm8 %{ (int) 8 %}
12009 immI16 imm4 %{ (int) 4 %}
12010 immI16 imm0 %{ (int) 0 %}
12011 iRegLdst tmpI1;
12012 iRegLdst tmpI2;
12013 iRegLdst tmpI3;
12014
12015 urShiftI_reg_imm(tmpI1, src, imm24);
12016 insrwi_a(dst, tmpI1, imm8, imm24);
12017 urShiftI_reg_imm(tmpI2, src, imm16);
12018 insrwi(dst, tmpI2, imm16, imm8);
12019 urShiftI_reg_imm(tmpI3, src, imm8);
12020 insrwi(dst, tmpI3, imm8, imm8);
12021 insrwi(dst, src, imm8, imm0);
12022 %}
12023 %}
12024
12025 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{
12026 match(Set dst (ReverseBytesI src));
12027 predicate(UseVectorByteReverseInstructionsPPC64);
12028 effect(TEMP tmpV);
12029 ins_cost(DEFAULT_COST*3);
12030 size(12);
12031 format %{ "MTVSRWZ $tmpV, $src\n"
12032 "\tXXBRW $tmpV, $tmpV\n"
12033 "\tMFVSRWZ $dst, $tmpV" %}
12034
12035 ins_encode %{
12036 __ mtvsrwz($tmpV$$VectorRegister.to_vsr(), $src$$Register);
12037 __ xxbrw($tmpV$$VectorRegister.to_vsr(), $tmpV$$VectorRegister->to_vsr());
12038 __ mfvsrwz($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12039 %}
12040 ins_pipe(pipe_class_default);
12041 %}
12042
12043 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{
12044 match(Set dst (ReverseBytesI src));
12045 predicate(UseByteReverseInstructions);
12046 ins_cost(DEFAULT_COST);
12047 size(4);
12048
12049 format %{ "BRW $dst, $src" %}
12050
12051 ins_encode %{
12052 __ brw($dst$$Register, $src$$Register);
12053 %}
12054 ins_pipe(pipe_class_default);
12055 %}
12056
12057 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
12058 match(Set dst (ReverseBytesL src));
12059 predicate(!UseByteReverseInstructions);
12060 ins_cost(15*DEFAULT_COST);
12061
12062 expand %{
12063 immI16 imm56 %{ (int) 56 %}
12064 immI16 imm48 %{ (int) 48 %}
12065 immI16 imm40 %{ (int) 40 %}
12066 immI16 imm32 %{ (int) 32 %}
12067 immI16 imm24 %{ (int) 24 %}
12068 immI16 imm16 %{ (int) 16 %}
12069 immI16 imm8 %{ (int) 8 %}
12070 immI16 imm0 %{ (int) 0 %}
12071 iRegLdst tmpL1;
12072 iRegLdst tmpL2;
12073 iRegLdst tmpL3;
12074 iRegLdst tmpL4;
12075 iRegLdst tmpL5;
12076 iRegLdst tmpL6;
12077
12078 // src : |a|b|c|d|e|f|g|h|
12079 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
12080 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
12081 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
12082 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
12083 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
12084 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
12085 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
12086 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
12087 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
12088 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
12089 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
12090 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
12091 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
12092 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
12093 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
12094 %}
12095 %}
12096
12097 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{
12098 match(Set dst (ReverseBytesL src));
12099 predicate(UseVectorByteReverseInstructionsPPC64);
12100 effect(TEMP tmpV);
12101 ins_cost(DEFAULT_COST*3);
12102 size(12);
12103 format %{ "MTVSRD $tmpV, $src\n"
12104 "\tXXBRD $tmpV, $tmpV\n"
12105 "\tMFVSRD $dst, $tmpV" %}
12106
12107 ins_encode %{
12108 __ mtvsrd($tmpV$$VectorRegister->to_vsr(), $src$$Register);
12109 __ xxbrd($tmpV$$VectorRegister->to_vsr(), $tmpV$$VectorRegister->to_vsr());
12110 __ mfvsrd($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12111 %}
12112 ins_pipe(pipe_class_default);
12113 %}
12114
12115 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{
12116 match(Set dst (ReverseBytesL src));
12117 predicate(UseByteReverseInstructions);
12118 ins_cost(DEFAULT_COST);
12119 size(4);
12120
12121 format %{ "BRD $dst, $src" %}
12122
12123 ins_encode %{
12124 __ brd($dst$$Register, $src$$Register);
12125 %}
12126 ins_pipe(pipe_class_default);
12127 %}
12128
12129 // Need zero extend. Must not use brh only.
12130 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
12131 match(Set dst (ReverseBytesUS src));
12132 ins_cost(2*DEFAULT_COST);
12133
12134 expand %{
12135 immI16 imm31 %{ (int) 31 %}
12136 immI16 imm24 %{ (int) 24 %}
12137 immI16 imm16 %{ (int) 16 %}
12138 immI16 imm8 %{ (int) 8 %}
12139
12140 rlwinm(dst, src, imm24, imm24, imm31);
12141 insrwi(dst, src, imm8, imm16);
12142 %}
12143 %}
12144
12145 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
12146 match(Set dst (ReverseBytesS src));
12147 predicate(!UseByteReverseInstructions);
12148 ins_cost(3*DEFAULT_COST);
12149
12150 expand %{
12151 immI16 imm16 %{ (int) 16 %}
12152 immI16 imm8 %{ (int) 8 %}
12153 iRegLdst tmpI1;
12154
12155 urShiftI_reg_imm(tmpI1, src, imm8);
12156 insrwi(tmpI1, src, imm8, imm16);
12157 extsh(dst, tmpI1);
12158 %}
12159 %}
12160
12161 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{
12162 match(Set dst (ReverseBytesS src));
12163 predicate(UseByteReverseInstructions);
12164 ins_cost(DEFAULT_COST);
12165 size(8);
12166
12167 format %{ "BRH $dst, $src\n\t"
12168 "EXTSH $dst, $dst" %}
12169
12170 ins_encode %{
12171 __ brh($dst$$Register, $src$$Register);
12172 __ extsh($dst$$Register, $dst$$Register);
12173 %}
12174 ins_pipe(pipe_class_default);
12175 %}
12176
12177 // Load Integer reversed byte order
12178 instruct loadI_reversed(iRegIdst dst, indirect mem) %{
12179 match(Set dst (ReverseBytesI (LoadI mem)));
12180 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12181 ins_cost(MEMORY_REF_COST);
12182
12183 size(4);
12184 ins_encode %{
12185 __ lwbrx($dst$$Register, $mem$$Register);
12186 %}
12187 ins_pipe(pipe_class_default);
12188 %}
12189
12190 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{
12191 match(Set dst (ReverseBytesI (LoadI mem)));
12192 ins_cost(2 * MEMORY_REF_COST);
12193
12194 size(12);
12195 ins_encode %{
12196 __ lwbrx($dst$$Register, $mem$$Register);
12197 __ twi_0($dst$$Register);
12198 __ isync();
12199 %}
12200 ins_pipe(pipe_class_default);
12201 %}
12202
12203 // Load Long - aligned and reversed
12204 instruct loadL_reversed(iRegLdst dst, indirect mem) %{
12205 match(Set dst (ReverseBytesL (LoadL mem)));
12206 predicate((n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))));
12207 ins_cost(MEMORY_REF_COST);
12208
12209 size(4);
12210 ins_encode %{
12211 __ ldbrx($dst$$Register, $mem$$Register);
12212 %}
12213 ins_pipe(pipe_class_default);
12214 %}
12215
12216 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{
12217 match(Set dst (ReverseBytesL (LoadL mem)));
12218 ins_cost(2 * MEMORY_REF_COST);
12219
12220 size(12);
12221 ins_encode %{
12222 __ ldbrx($dst$$Register, $mem$$Register);
12223 __ twi_0($dst$$Register);
12224 __ isync();
12225 %}
12226 ins_pipe(pipe_class_default);
12227 %}
12228
12229 // Load unsigned short / char reversed byte order
12230 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
12231 match(Set dst (ReverseBytesUS (LoadUS mem)));
12232 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12233 ins_cost(MEMORY_REF_COST);
12234
12235 size(4);
12236 ins_encode %{
12237 __ lhbrx($dst$$Register, $mem$$Register);
12238 %}
12239 ins_pipe(pipe_class_default);
12240 %}
12241
12242 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{
12243 match(Set dst (ReverseBytesUS (LoadUS mem)));
12244 ins_cost(2 * MEMORY_REF_COST);
12245
12246 size(12);
12247 ins_encode %{
12248 __ lhbrx($dst$$Register, $mem$$Register);
12249 __ twi_0($dst$$Register);
12250 __ isync();
12251 %}
12252 ins_pipe(pipe_class_default);
12253 %}
12254
12255 // Load short reversed byte order
12256 instruct loadS_reversed(iRegIdst dst, indirect mem) %{
12257 match(Set dst (ReverseBytesS (LoadS mem)));
12258 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12259 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
12260
12261 size(8);
12262 ins_encode %{
12263 __ lhbrx($dst$$Register, $mem$$Register);
12264 __ extsh($dst$$Register, $dst$$Register);
12265 %}
12266 ins_pipe(pipe_class_default);
12267 %}
12268
12269 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{
12270 match(Set dst (ReverseBytesS (LoadS mem)));
12271 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12272
12273 size(16);
12274 ins_encode %{
12275 __ lhbrx($dst$$Register, $mem$$Register);
12276 __ twi_0($dst$$Register);
12277 __ extsh($dst$$Register, $dst$$Register);
12278 __ isync();
12279 %}
12280 ins_pipe(pipe_class_default);
12281 %}
12282
12283 // Store Integer reversed byte order
12284 instruct storeI_reversed(iRegIsrc src, indirect mem) %{
12285 match(Set mem (StoreI mem (ReverseBytesI src)));
12286 ins_cost(MEMORY_REF_COST);
12287
12288 size(4);
12289 ins_encode %{
12290 __ stwbrx($src$$Register, $mem$$Register);
12291 %}
12292 ins_pipe(pipe_class_default);
12293 %}
12294
12295 // Store Long reversed byte order
12296 instruct storeL_reversed(iRegLsrc src, indirect mem) %{
12297 match(Set mem (StoreL mem (ReverseBytesL src)));
12298 ins_cost(MEMORY_REF_COST);
12299
12300 size(4);
12301 ins_encode %{
12302 __ stdbrx($src$$Register, $mem$$Register);
12303 %}
12304 ins_pipe(pipe_class_default);
12305 %}
12306
12307 // Store unsigned short / char reversed byte order
12308 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
12309 match(Set mem (StoreC mem (ReverseBytesUS src)));
12310 ins_cost(MEMORY_REF_COST);
12311
12312 size(4);
12313 ins_encode %{
12314 __ sthbrx($src$$Register, $mem$$Register);
12315 %}
12316 ins_pipe(pipe_class_default);
12317 %}
12318
12319 // Store short reversed byte order
12320 instruct storeS_reversed(iRegIsrc src, indirect mem) %{
12321 match(Set mem (StoreC mem (ReverseBytesS src)));
12322 ins_cost(MEMORY_REF_COST);
12323
12324 size(4);
12325 ins_encode %{
12326 __ sthbrx($src$$Register, $mem$$Register);
12327 %}
12328 ins_pipe(pipe_class_default);
12329 %}
12330
12331 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
12332 effect(DEF temp1, USE src);
12333
12334 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %}
12335 size(4);
12336 ins_encode %{
12337 __ mtvsrwz($temp1$$VectorRegister->to_vsr(), $src$$Register);
12338 %}
12339 ins_pipe(pipe_class_default);
12340 %}
12341
12342 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{
12343 effect(DEF dst, USE src, USE imm1);
12344
12345 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %}
12346 size(4);
12347 ins_encode %{
12348 __ xxspltw($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $imm1$$constant);
12349 %}
12350 ins_pipe(pipe_class_default);
12351 %}
12352
12353 instruct xscvdpspn_regF(vecX dst, regF src) %{
12354 effect(DEF dst, USE src);
12355
12356 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %}
12357 size(4);
12358 ins_encode %{
12359 __ xscvdpspn($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr());
12360 %}
12361 ins_pipe(pipe_class_default);
12362 %}
12363
12364 //---------- Replicate Vector Instructions ------------------------------------
12365
12366 // Insrdi does replicate if src == dst.
12367 instruct repl32(iRegLdst dst) %{
12368 predicate(false);
12369 effect(USE_DEF dst);
12370
12371 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %}
12372 size(4);
12373 ins_encode %{
12374 __ insrdi($dst$$Register, $dst$$Register, 32, 0);
12375 %}
12376 ins_pipe(pipe_class_default);
12377 %}
12378
12379 // Insrdi does replicate if src == dst.
12380 instruct repl48(iRegLdst dst) %{
12381 predicate(false);
12382 effect(USE_DEF dst);
12383
12384 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %}
12385 size(4);
12386 ins_encode %{
12387 __ insrdi($dst$$Register, $dst$$Register, 48, 0);
12388 %}
12389 ins_pipe(pipe_class_default);
12390 %}
12391
12392 // Insrdi does replicate if src == dst.
12393 instruct repl56(iRegLdst dst) %{
12394 predicate(false);
12395 effect(USE_DEF dst);
12396
12397 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %}
12398 size(4);
12399 ins_encode %{
12400 __ insrdi($dst$$Register, $dst$$Register, 56, 0);
12401 %}
12402 ins_pipe(pipe_class_default);
12403 %}
12404
12405 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12406 match(Set dst (Replicate src));
12407 predicate(n->as_Vector()->length() == 8 &&
12408 Matcher::vector_element_basic_type(n) == T_BYTE);
12409 expand %{
12410 moveReg(dst, src);
12411 repl56(dst);
12412 repl48(dst);
12413 repl32(dst);
12414 %}
12415 %}
12416
12417 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
12418 match(Set dst (Replicate zero));
12419 predicate(n->as_Vector()->length() == 8 &&
12420 Matcher::vector_element_basic_type(n) == T_BYTE);
12421 format %{ "LI $dst, #0 \t// replicate8B" %}
12422 size(4);
12423 ins_encode %{
12424 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12425 %}
12426 ins_pipe(pipe_class_default);
12427 %}
12428
12429 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
12430 match(Set dst (Replicate src));
12431 predicate(n->as_Vector()->length() == 8 &&
12432 Matcher::vector_element_basic_type(n) == T_BYTE);
12433 format %{ "LI $dst, #-1 \t// replicate8B" %}
12434 size(4);
12435 ins_encode %{
12436 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12437 %}
12438 ins_pipe(pipe_class_default);
12439 %}
12440
12441 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{
12442 match(Set dst (Replicate src));
12443 predicate(n->as_Vector()->length() == 16 &&
12444 Matcher::vector_element_basic_type(n) == T_BYTE);
12445
12446 expand %{
12447 iRegLdst tmpL;
12448 vecX tmpV;
12449 immI8 imm1 %{ (int) 1 %}
12450 moveReg(tmpL, src);
12451 repl56(tmpL);
12452 repl48(tmpL);
12453 mtvsrwz(tmpV, tmpL);
12454 xxspltw(dst, tmpV, imm1);
12455 %}
12456 %}
12457
12458 instruct repl16B_immI0(vecX dst, immI_0 zero) %{
12459 match(Set dst (Replicate zero));
12460 predicate(n->as_Vector()->length() == 16 &&
12461 Matcher::vector_element_basic_type(n) == T_BYTE);
12462
12463 format %{ "XXLXOR $dst, $zero \t// replicate16B" %}
12464 size(4);
12465 ins_encode %{
12466 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12467 %}
12468 ins_pipe(pipe_class_default);
12469 %}
12470
12471 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{
12472 match(Set dst (Replicate src));
12473 predicate(n->as_Vector()->length() == 16 &&
12474 Matcher::vector_element_basic_type(n) == T_BYTE);
12475
12476 format %{ "XXLEQV $dst, $src \t// replicate16B" %}
12477 size(4);
12478 ins_encode %{
12479 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12480 %}
12481 ins_pipe(pipe_class_default);
12482 %}
12483
12484 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12485 match(Set dst (Replicate src));
12486 predicate(n->as_Vector()->length() == 4 &&
12487 Matcher::vector_element_basic_type(n) == T_SHORT);
12488 expand %{
12489 moveReg(dst, src);
12490 repl48(dst);
12491 repl32(dst);
12492 %}
12493 %}
12494
12495 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
12496 match(Set dst (Replicate zero));
12497 predicate(n->as_Vector()->length() == 4 &&
12498 Matcher::vector_element_basic_type(n) == T_SHORT);
12499 format %{ "LI $dst, #0 \t// replicate4S" %}
12500 size(4);
12501 ins_encode %{
12502 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12503 %}
12504 ins_pipe(pipe_class_default);
12505 %}
12506
12507 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
12508 match(Set dst (Replicate src));
12509 predicate(n->as_Vector()->length() == 4 &&
12510 Matcher::vector_element_basic_type(n) == T_SHORT);
12511 format %{ "LI $dst, -1 \t// replicate4S" %}
12512 size(4);
12513 ins_encode %{
12514 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12515 %}
12516 ins_pipe(pipe_class_default);
12517 %}
12518
12519 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{
12520 match(Set dst (Replicate src));
12521 predicate(n->as_Vector()->length() == 8 &&
12522 Matcher::vector_element_basic_type(n) == T_SHORT);
12523
12524 expand %{
12525 iRegLdst tmpL;
12526 vecX tmpV;
12527 immI8 zero %{ (int) 0 %}
12528 moveReg(tmpL, src);
12529 repl48(tmpL);
12530 repl32(tmpL);
12531 mtvsrd(tmpV, tmpL);
12532 xxpermdi(dst, tmpV, tmpV, zero);
12533 %}
12534 %}
12535
12536 instruct repl8S_immI0(vecX dst, immI_0 zero) %{
12537 match(Set dst (Replicate zero));
12538 predicate(n->as_Vector()->length() == 8 &&
12539 Matcher::vector_element_basic_type(n) == T_SHORT);
12540
12541 format %{ "XXLXOR $dst, $zero \t// replicate8S" %}
12542 size(4);
12543 ins_encode %{
12544 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12545 %}
12546 ins_pipe(pipe_class_default);
12547 %}
12548
12549 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{
12550 match(Set dst (Replicate src));
12551 predicate(n->as_Vector()->length() == 8 &&
12552 Matcher::vector_element_basic_type(n) == T_SHORT);
12553
12554 format %{ "XXLEQV $dst, $src \t// replicate8S" %}
12555 size(4);
12556 ins_encode %{
12557 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12558 %}
12559 ins_pipe(pipe_class_default);
12560 %}
12561
12562 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12563 match(Set dst (Replicate src));
12564 predicate(n->as_Vector()->length() == 2 &&
12565 Matcher::vector_element_basic_type(n) == T_INT);
12566 ins_cost(2 * DEFAULT_COST);
12567 expand %{
12568 moveReg(dst, src);
12569 repl32(dst);
12570 %}
12571 %}
12572
12573 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
12574 match(Set dst (Replicate zero));
12575 predicate(n->as_Vector()->length() == 2 &&
12576 Matcher::vector_element_basic_type(n) == T_INT);
12577 format %{ "LI $dst, #0 \t// replicate2I" %}
12578 size(4);
12579 ins_encode %{
12580 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12581 %}
12582 ins_pipe(pipe_class_default);
12583 %}
12584
12585 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
12586 match(Set dst (Replicate src));
12587 predicate(n->as_Vector()->length() == 2 &&
12588 Matcher::vector_element_basic_type(n) == T_INT);
12589 format %{ "LI $dst, -1 \t// replicate2I" %}
12590 size(4);
12591 ins_encode %{
12592 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12593 %}
12594 ins_pipe(pipe_class_default);
12595 %}
12596
12597 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{
12598 match(Set dst (Replicate src));
12599 predicate(n->as_Vector()->length() == 4 &&
12600 Matcher::vector_element_basic_type(n) == T_INT);
12601 ins_cost(2 * DEFAULT_COST);
12602
12603 expand %{
12604 iRegLdst tmpL;
12605 vecX tmpV;
12606 immI8 zero %{ (int) 0 %}
12607 moveReg(tmpL, src);
12608 repl32(tmpL);
12609 mtvsrd(tmpV, tmpL);
12610 xxpermdi(dst, tmpV, tmpV, zero);
12611 %}
12612 %}
12613
12614 instruct repl4I_immI0(vecX dst, immI_0 zero) %{
12615 match(Set dst (Replicate zero));
12616 predicate(n->as_Vector()->length() == 4 &&
12617 Matcher::vector_element_basic_type(n) == T_INT);
12618
12619 format %{ "XXLXOR $dst, $zero \t// replicate4I" %}
12620 size(4);
12621 ins_encode %{
12622 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12623 %}
12624 ins_pipe(pipe_class_default);
12625 %}
12626
12627 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{
12628 match(Set dst (Replicate src));
12629 predicate(n->as_Vector()->length() == 4 &&
12630 Matcher::vector_element_basic_type(n) == T_INT);
12631
12632 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %}
12633 size(4);
12634 ins_encode %{
12635 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12636 %}
12637 ins_pipe(pipe_class_default);
12638 %}
12639
12640 // Move float to int register via stack, replicate.
12641 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
12642 match(Set dst (Replicate src));
12643 predicate(n->as_Vector()->length() == 2 &&
12644 Matcher::vector_element_basic_type(n) == T_FLOAT);
12645 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12646 expand %{
12647 stackSlotL tmpS;
12648 iRegIdst tmpI;
12649 moveF2I_reg_stack(tmpS, src); // Move float to stack.
12650 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
12651 moveReg(dst, tmpI); // Move int to long reg.
12652 repl32(dst); // Replicate bitpattern.
12653 %}
12654 %}
12655
12656 // Replicate scalar constant to packed float values in Double register
12657 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
12658 match(Set dst (Replicate src));
12659 predicate(n->as_Vector()->length() == 2 &&
12660 Matcher::vector_element_basic_type(n) == T_FLOAT);
12661 ins_cost(5 * DEFAULT_COST);
12662
12663 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
12664 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
12665 %}
12666
12667 // Replicate scalar zero constant to packed float values in Double register
12668 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
12669 match(Set dst (Replicate zero));
12670 predicate(n->as_Vector()->length() == 2 &&
12671 Matcher::vector_element_basic_type(n) == T_FLOAT);
12672
12673 format %{ "LI $dst, #0 \t// replicate2F" %}
12674 size(4);
12675 ins_encode %{
12676 __ li($dst$$Register, 0x0);
12677 %}
12678 ins_pipe(pipe_class_default);
12679 %}
12680
12681
12682 //----------Vector Arithmetic Instructions--------------------------------------
12683
12684 // Vector Addition Instructions
12685
12686 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
12687 match(Set dst (AddVB src1 src2));
12688 predicate(n->as_Vector()->length() == 16);
12689 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %}
12690 size(4);
12691 ins_encode %{
12692 __ vaddubm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12693 %}
12694 ins_pipe(pipe_class_default);
12695 %}
12696
12697 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
12698 match(Set dst (AddVS src1 src2));
12699 predicate(n->as_Vector()->length() == 8);
12700 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %}
12701 size(4);
12702 ins_encode %{
12703 __ vadduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12704 %}
12705 ins_pipe(pipe_class_default);
12706 %}
12707
12708 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
12709 match(Set dst (AddVI src1 src2));
12710 predicate(n->as_Vector()->length() == 4);
12711 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %}
12712 size(4);
12713 ins_encode %{
12714 __ vadduwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12715 %}
12716 ins_pipe(pipe_class_default);
12717 %}
12718
12719 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
12720 match(Set dst (AddVF src1 src2));
12721 predicate(n->as_Vector()->length() == 4);
12722 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %}
12723 size(4);
12724 ins_encode %{
12725 __ vaddfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12726 %}
12727 ins_pipe(pipe_class_default);
12728 %}
12729
12730 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
12731 match(Set dst (AddVL src1 src2));
12732 predicate(n->as_Vector()->length() == 2);
12733 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %}
12734 size(4);
12735 ins_encode %{
12736 __ vaddudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12737 %}
12738 ins_pipe(pipe_class_default);
12739 %}
12740
12741 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
12742 match(Set dst (AddVD src1 src2));
12743 predicate(n->as_Vector()->length() == 2);
12744 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %}
12745 size(4);
12746 ins_encode %{
12747 __ xvadddp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12748 %}
12749 ins_pipe(pipe_class_default);
12750 %}
12751
12752 // Vector Subtraction Instructions
12753
12754 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
12755 match(Set dst (SubVB src1 src2));
12756 predicate(n->as_Vector()->length() == 16);
12757 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %}
12758 size(4);
12759 ins_encode %{
12760 __ vsububm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12761 %}
12762 ins_pipe(pipe_class_default);
12763 %}
12764
12765 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
12766 match(Set dst (SubVS src1 src2));
12767 predicate(n->as_Vector()->length() == 8);
12768 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %}
12769 size(4);
12770 ins_encode %{
12771 __ vsubuhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12772 %}
12773 ins_pipe(pipe_class_default);
12774 %}
12775
12776 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
12777 match(Set dst (SubVI src1 src2));
12778 predicate(n->as_Vector()->length() == 4);
12779 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %}
12780 size(4);
12781 ins_encode %{
12782 __ vsubuwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12783 %}
12784 ins_pipe(pipe_class_default);
12785 %}
12786
12787 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
12788 match(Set dst (SubVF src1 src2));
12789 predicate(n->as_Vector()->length() == 4);
12790 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %}
12791 size(4);
12792 ins_encode %{
12793 __ vsubfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12794 %}
12795 ins_pipe(pipe_class_default);
12796 %}
12797
12798 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
12799 match(Set dst (SubVL src1 src2));
12800 predicate(n->as_Vector()->length() == 2);
12801 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %}
12802 size(4);
12803 ins_encode %{
12804 __ vsubudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12805 %}
12806 ins_pipe(pipe_class_default);
12807 %}
12808
12809 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
12810 match(Set dst (SubVD src1 src2));
12811 predicate(n->as_Vector()->length() == 2);
12812 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %}
12813 size(4);
12814 ins_encode %{
12815 __ xvsubdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12816 %}
12817 ins_pipe(pipe_class_default);
12818 %}
12819
12820 // Vector Multiplication Instructions
12821
12822 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
12823 match(Set dst (MulVS src1 src2));
12824 predicate(n->as_Vector()->length() == 8);
12825 effect(TEMP tmp);
12826 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %}
12827 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %}
12828 size(8);
12829 ins_encode %{
12830 __ vspltish($tmp$$VectorRegister, 0);
12831 __ vmladduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister, $tmp$$VectorRegister);
12832 %}
12833 ins_pipe(pipe_class_default);
12834 %}
12835
12836 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
12837 match(Set dst (MulVI src1 src2));
12838 predicate(n->as_Vector()->length() == 4);
12839 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %}
12840 size(4);
12841 ins_encode %{
12842 __ vmuluwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12843 %}
12844 ins_pipe(pipe_class_default);
12845 %}
12846
12847 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
12848 match(Set dst (MulVF src1 src2));
12849 predicate(n->as_Vector()->length() == 4);
12850 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %}
12851 size(4);
12852 ins_encode %{
12853 __ xvmulsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12854 %}
12855 ins_pipe(pipe_class_default);
12856 %}
12857
12858 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
12859 match(Set dst (MulVD src1 src2));
12860 predicate(n->as_Vector()->length() == 2);
12861 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %}
12862 size(4);
12863 ins_encode %{
12864 __ xvmuldp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12865 %}
12866 ins_pipe(pipe_class_default);
12867 %}
12868
12869 // Vector Division Instructions
12870
12871 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
12872 match(Set dst (DivVF src1 src2));
12873 predicate(n->as_Vector()->length() == 4);
12874 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %}
12875 size(4);
12876 ins_encode %{
12877 __ xvdivsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12878 %}
12879 ins_pipe(pipe_class_default);
12880 %}
12881
12882 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
12883 match(Set dst (DivVD src1 src2));
12884 predicate(n->as_Vector()->length() == 2);
12885 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %}
12886 size(4);
12887 ins_encode %{
12888 __ xvdivdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12889 %}
12890 ins_pipe(pipe_class_default);
12891 %}
12892
12893 // Vector Min / Max Instructions
12894
12895 instruct vmin_reg(vecX dst, vecX src1, vecX src2) %{
12896 match(Set dst (MinV src1 src2));
12897 format %{ "VMIN $dst,$src1,$src2\t// vector min" %}
12898 size(4);
12899 ins_encode %{
12900 BasicType bt = Matcher::vector_element_basic_type(this);
12901 switch (bt) {
12902 case T_INT:
12903 __ vminsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12904 break;
12905 case T_LONG:
12906 __ vminsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12907 break;
12908 default:
12909 ShouldNotReachHere();
12910 }
12911 %}
12912 ins_pipe(pipe_class_default);
12913 %}
12914
12915 instruct vmax_reg(vecX dst, vecX src1, vecX src2) %{
12916 match(Set dst (MaxV src1 src2));
12917 format %{ "VMAX $dst,$src1,$src2\t// vector max" %}
12918 size(4);
12919 ins_encode %{
12920 BasicType bt = Matcher::vector_element_basic_type(this);
12921 switch (bt) {
12922 case T_INT:
12923 __ vmaxsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12924 break;
12925 case T_LONG:
12926 __ vmaxsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12927 break;
12928 default:
12929 ShouldNotReachHere();
12930 }
12931 %}
12932 ins_pipe(pipe_class_default);
12933 %}
12934
12935 instruct vminu_reg(vecX dst, vecX src1, vecX src2) %{
12936 match(Set dst (UMinV src1 src2));
12937 format %{ "VMINU $dst,$src1,$src2\t// vector unsigned min" %}
12938 size(4);
12939 ins_encode %{
12940 BasicType bt = Matcher::vector_element_basic_type(this);
12941 switch (bt) {
12942 case T_INT:
12943 __ vminuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12944 break;
12945 case T_LONG:
12946 __ vminud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12947 break;
12948 default:
12949 ShouldNotReachHere();
12950 }
12951 %}
12952 ins_pipe(pipe_class_default);
12953 %}
12954
12955 instruct vmaxu_reg(vecX dst, vecX src1, vecX src2) %{
12956 match(Set dst (UMaxV src1 src2));
12957 format %{ "VMAXU $dst,$src1,$src2\t// vector unsigned max" %}
12958 size(4);
12959 ins_encode %{
12960 BasicType bt = Matcher::vector_element_basic_type(this);
12961 switch (bt) {
12962 case T_INT:
12963 __ vmaxuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12964 break;
12965 case T_LONG:
12966 __ vmaxud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12967 break;
12968 default:
12969 ShouldNotReachHere();
12970 }
12971 %}
12972 ins_pipe(pipe_class_default);
12973 %}
12974
12975 instruct vand(vecX dst, vecX src1, vecX src2) %{
12976 match(Set dst (AndV src1 src2));
12977 size(4);
12978 format %{ "VAND $dst,$src1,$src2\t// and vectors" %}
12979 ins_encode %{
12980 __ vand($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12981 %}
12982 ins_pipe(pipe_class_default);
12983 %}
12984
12985 instruct vor(vecX dst, vecX src1, vecX src2) %{
12986 match(Set dst (OrV src1 src2));
12987 size(4);
12988 format %{ "VOR $dst,$src1,$src2\t// or vectors" %}
12989 ins_encode %{
12990 __ vor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12991 %}
12992 ins_pipe(pipe_class_default);
12993 %}
12994
12995 instruct vxor(vecX dst, vecX src1, vecX src2) %{
12996 match(Set dst (XorV src1 src2));
12997 size(4);
12998 format %{ "VXOR $dst,$src1,$src2\t// xor vectors" %}
12999 ins_encode %{
13000 __ vxor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
13001 %}
13002 ins_pipe(pipe_class_default);
13003 %}
13004
13005 instruct reductionI_arith_logic(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2) %{
13006 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13007 match(Set dst (AddReductionVI srcInt srcVec));
13008 match(Set dst (MulReductionVI srcInt srcVec));
13009 match(Set dst (AndReductionV srcInt srcVec));
13010 match(Set dst ( OrReductionV srcInt srcVec));
13011 match(Set dst (XorReductionV srcInt srcVec));
13012 effect(TEMP tmp1, TEMP tmp2);
13013 ins_cost(DEFAULT_COST * 6);
13014 format %{ "REDUCEI_ARITH_LOGIC // $dst,$srcInt,$srcVec,$tmp1,$tmp2\t// reduce vector int add/mul/and/or/xor" %}
13015 size(24);
13016 ins_encode %{
13017 int opcode = this->ideal_Opcode();
13018 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13019 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13020 %}
13021 ins_pipe(pipe_class_default);
13022 %}
13023
13024 instruct reductionI_min_max(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2, flagsRegCR0 cr0) %{
13025 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13026 match(Set dst (MinReductionV srcInt srcVec));
13027 match(Set dst (MaxReductionV srcInt srcVec));
13028 effect(TEMP tmp1, TEMP tmp2, KILL cr0);
13029 ins_cost(DEFAULT_COST * 7);
13030 format %{ "REDUCEI_MINMAX // $dst,$srcInt,$srcVec,$tmp1,$tmp2,cr0\t// reduce vector int min/max" %}
13031 size(28);
13032 ins_encode %{
13033 int opcode = this->ideal_Opcode();
13034 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13035 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13036 %}
13037 ins_pipe(pipe_class_default);
13038 %}
13039
13040 // Vector Absolute Instructions
13041
13042 instruct vabs4F_reg(vecX dst, vecX src) %{
13043 match(Set dst (AbsVF src));
13044 predicate(n->as_Vector()->length() == 4);
13045 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
13046 size(4);
13047 ins_encode %{
13048 __ xvabssp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13049 %}
13050 ins_pipe(pipe_class_default);
13051 %}
13052
13053 instruct vabs2D_reg(vecX dst, vecX src) %{
13054 match(Set dst (AbsVD src));
13055 predicate(n->as_Vector()->length() == 2);
13056 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
13057 size(4);
13058 ins_encode %{
13059 __ xvabsdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13060 %}
13061 ins_pipe(pipe_class_default);
13062 %}
13063
13064 // Round Instructions
13065 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{
13066 match(Set dst (RoundDoubleMode src rmode));
13067 format %{ "RoundDoubleMode $src,$rmode" %}
13068 size(4);
13069 ins_encode %{
13070 switch ($rmode$$constant) {
13071 case RoundDoubleModeNode::rmode_rint:
13072 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr());
13073 break;
13074 case RoundDoubleModeNode::rmode_floor:
13075 __ frim($dst$$FloatRegister, $src$$FloatRegister);
13076 break;
13077 case RoundDoubleModeNode::rmode_ceil:
13078 __ frip($dst$$FloatRegister, $src$$FloatRegister);
13079 break;
13080 default:
13081 ShouldNotReachHere();
13082 }
13083 %}
13084 ins_pipe(pipe_class_default);
13085 %}
13086
13087 // Vector Round Instructions
13088 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
13089 match(Set dst (RoundDoubleModeV src rmode));
13090 predicate(n->as_Vector()->length() == 2);
13091 format %{ "RoundDoubleModeV $src,$rmode" %}
13092 size(4);
13093 ins_encode %{
13094 switch ($rmode$$constant) {
13095 case RoundDoubleModeNode::rmode_rint:
13096 __ xvrdpic($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13097 break;
13098 case RoundDoubleModeNode::rmode_floor:
13099 __ xvrdpim($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13100 break;
13101 case RoundDoubleModeNode::rmode_ceil:
13102 __ xvrdpip($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13103 break;
13104 default:
13105 ShouldNotReachHere();
13106 }
13107 %}
13108 ins_pipe(pipe_class_default);
13109 %}
13110
13111 // Vector Negate Instructions
13112
13113 instruct vneg4F_reg(vecX dst, vecX src) %{
13114 match(Set dst (NegVF src));
13115 predicate(n->as_Vector()->length() == 4);
13116 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
13117 size(4);
13118 ins_encode %{
13119 __ xvnegsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13120 %}
13121 ins_pipe(pipe_class_default);
13122 %}
13123
13124 instruct vneg2D_reg(vecX dst, vecX src) %{
13125 match(Set dst (NegVD src));
13126 predicate(n->as_Vector()->length() == 2);
13127 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
13128 size(4);
13129 ins_encode %{
13130 __ xvnegdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13131 %}
13132 ins_pipe(pipe_class_default);
13133 %}
13134
13135 instruct vneg4I_reg(vecX dst, vecX src) %{
13136 match(Set dst (NegVI src));
13137 predicate(Matcher::vector_element_basic_type(n) == T_INT);
13138 format %{ "VNEGW $dst,$src\t// negate int vector" %}
13139 size(4);
13140 ins_encode %{
13141 __ vnegw($dst$$VectorRegister, $src$$VectorRegister);
13142 %}
13143 ins_pipe(pipe_class_default);
13144 %}
13145
13146 // Vector Square Root Instructions
13147
13148 instruct vsqrt4F_reg(vecX dst, vecX src) %{
13149 match(Set dst (SqrtVF src));
13150 predicate(n->as_Vector()->length() == 4);
13151 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
13152 size(4);
13153 ins_encode %{
13154 __ xvsqrtsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13155 %}
13156 ins_pipe(pipe_class_default);
13157 %}
13158
13159 instruct vsqrt2D_reg(vecX dst, vecX src) %{
13160 match(Set dst (SqrtVD src));
13161 predicate(n->as_Vector()->length() == 2);
13162 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %}
13163 size(4);
13164 ins_encode %{
13165 __ xvsqrtdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13166 %}
13167 ins_pipe(pipe_class_default);
13168 %}
13169
13170 // Vector Population Count and Zeros Count Instructions
13171
13172 instruct vpopcnt_reg(vecX dst, vecX src) %{
13173 match(Set dst (PopCountVI src));
13174 match(Set dst (PopCountVL src));
13175 format %{ "VPOPCNT $dst,$src\t// pop count packed" %}
13176 size(4);
13177 ins_encode %{
13178 BasicType bt = Matcher::vector_element_basic_type(this);
13179 switch (bt) {
13180 case T_BYTE:
13181 __ vpopcntb($dst$$VectorRegister, $src$$VectorRegister);
13182 break;
13183 case T_SHORT:
13184 __ vpopcnth($dst$$VectorRegister, $src$$VectorRegister);
13185 break;
13186 case T_INT:
13187 __ vpopcntw($dst$$VectorRegister, $src$$VectorRegister);
13188 break;
13189 case T_LONG:
13190 __ vpopcntd($dst$$VectorRegister, $src$$VectorRegister);
13191 break;
13192 default:
13193 ShouldNotReachHere();
13194 }
13195 %}
13196 ins_pipe(pipe_class_default);
13197 %}
13198
13199 instruct vcount_leading_zeros_reg(vecX dst, vecX src) %{
13200 match(Set dst (CountLeadingZerosV src));
13201 format %{ "VCLZ $dst,$src\t// leading zeros count packed" %}
13202 size(4);
13203 ins_encode %{
13204 BasicType bt = Matcher::vector_element_basic_type(this);
13205 switch (bt) {
13206 case T_BYTE:
13207 __ vclzb($dst$$VectorRegister, $src$$VectorRegister);
13208 break;
13209 case T_SHORT:
13210 __ vclzh($dst$$VectorRegister, $src$$VectorRegister);
13211 break;
13212 case T_INT:
13213 __ vclzw($dst$$VectorRegister, $src$$VectorRegister);
13214 break;
13215 case T_LONG:
13216 __ vclzd($dst$$VectorRegister, $src$$VectorRegister);
13217 break;
13218 default:
13219 ShouldNotReachHere();
13220 }
13221 %}
13222 ins_pipe(pipe_class_default);
13223 %}
13224
13225 instruct vcount_trailing_zeros_reg(vecX dst, vecX src) %{
13226 match(Set dst (CountTrailingZerosV src));
13227 format %{ "VCTZ $dst,$src\t// trailing zeros count packed" %}
13228 size(4);
13229 ins_encode %{
13230 BasicType bt = Matcher::vector_element_basic_type(this);
13231 switch (bt) {
13232 case T_BYTE:
13233 __ vctzb($dst$$VectorRegister, $src$$VectorRegister);
13234 break;
13235 case T_SHORT:
13236 __ vctzh($dst$$VectorRegister, $src$$VectorRegister);
13237 break;
13238 case T_INT:
13239 __ vctzw($dst$$VectorRegister, $src$$VectorRegister);
13240 break;
13241 case T_LONG:
13242 __ vctzd($dst$$VectorRegister, $src$$VectorRegister);
13243 break;
13244 default:
13245 ShouldNotReachHere();
13246 }
13247 %}
13248 ins_pipe(pipe_class_default);
13249 %}
13250
13251 // --------------------------------- FMA --------------------------------------
13252 // src1 * src2 + dst
13253 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{
13254 match(Set dst (FmaVF dst (Binary src1 src2)));
13255 predicate(n->as_Vector()->length() == 4);
13256
13257 format %{ "XVMADDASP $dst, $src1, $src2" %}
13258
13259 size(4);
13260 ins_encode %{
13261 assert(UseFMA, "Needs FMA instructions support.");
13262 __ xvmaddasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13263 %}
13264 ins_pipe(pipe_class_default);
13265 %}
13266
13267 // src1 * (-src2) + dst
13268 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13269 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{
13270 match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
13271 predicate(n->as_Vector()->length() == 4);
13272
13273 format %{ "XVNMSUBASP $dst, $src1, $src2" %}
13274
13275 size(4);
13276 ins_encode %{
13277 assert(UseFMA, "Needs FMA instructions support.");
13278 __ xvnmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13279 %}
13280 ins_pipe(pipe_class_default);
13281 %}
13282
13283 // src1 * src2 - dst
13284 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{
13285 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2)));
13286 predicate(n->as_Vector()->length() == 4);
13287
13288 format %{ "XVMSUBASP $dst, $src1, $src2" %}
13289
13290 size(4);
13291 ins_encode %{
13292 assert(UseFMA, "Needs FMA instructions support.");
13293 __ xvmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13294 %}
13295 ins_pipe(pipe_class_default);
13296 %}
13297
13298 // src1 * src2 + dst
13299 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{
13300 match(Set dst (FmaVD dst (Binary src1 src2)));
13301 predicate(n->as_Vector()->length() == 2);
13302
13303 format %{ "XVMADDADP $dst, $src1, $src2" %}
13304
13305 size(4);
13306 ins_encode %{
13307 assert(UseFMA, "Needs FMA instructions support.");
13308 __ xvmaddadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13309 %}
13310 ins_pipe(pipe_class_default);
13311 %}
13312
13313 // src1 * (-src2) + dst
13314 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13315 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{
13316 match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
13317 predicate(n->as_Vector()->length() == 2);
13318
13319 format %{ "XVNMSUBADP $dst, $src1, $src2" %}
13320
13321 size(4);
13322 ins_encode %{
13323 assert(UseFMA, "Needs FMA instructions support.");
13324 __ xvnmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13325 %}
13326 ins_pipe(pipe_class_default);
13327 %}
13328
13329 // src1 * src2 - dst
13330 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
13331 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2)));
13332 predicate(n->as_Vector()->length() == 2);
13333
13334 format %{ "XVMSUBADP $dst, $src1, $src2" %}
13335
13336 size(4);
13337 ins_encode %{
13338 assert(UseFMA, "Needs FMA instructions support.");
13339 __ xvmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13340 %}
13341 ins_pipe(pipe_class_default);
13342 %}
13343
13344 //----------Overflow Math Instructions-----------------------------------------
13345
13346 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
13347 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
13348 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
13349
13350 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13351 match(Set cr0 (OverflowAddL op1 op2));
13352
13353 format %{ "ADD_ $op1, $op2\t# overflow check long" %}
13354 size(12);
13355 ins_encode %{
13356 __ li(R0, 0);
13357 __ mtxer(R0); // clear XER.SO
13358 __ addo_(R0, $op1$$Register, $op2$$Register);
13359 %}
13360 ins_pipe(pipe_class_default);
13361 %}
13362
13363 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13364 match(Set cr0 (OverflowSubL op1 op2));
13365
13366 format %{ "SUBFO_ R0, $op2, $op1\t# overflow check long" %}
13367 size(12);
13368 ins_encode %{
13369 __ li(R0, 0);
13370 __ mtxer(R0); // clear XER.SO
13371 __ subfo_(R0, $op2$$Register, $op1$$Register);
13372 %}
13373 ins_pipe(pipe_class_default);
13374 %}
13375
13376 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
13377 match(Set cr0 (OverflowSubL zero op2));
13378
13379 format %{ "NEGO_ R0, $op2\t# overflow check long" %}
13380 size(12);
13381 ins_encode %{
13382 __ li(R0, 0);
13383 __ mtxer(R0); // clear XER.SO
13384 __ nego_(R0, $op2$$Register);
13385 %}
13386 ins_pipe(pipe_class_default);
13387 %}
13388
13389 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13390 match(Set cr0 (OverflowMulL op1 op2));
13391
13392 format %{ "MULLDO_ R0, $op1, $op2\t# overflow check long" %}
13393 size(12);
13394 ins_encode %{
13395 __ li(R0, 0);
13396 __ mtxer(R0); // clear XER.SO
13397 __ mulldo_(R0, $op1$$Register, $op2$$Register);
13398 %}
13399 ins_pipe(pipe_class_default);
13400 %}
13401
13402 instruct repl4F_reg_Ex(vecX dst, regF src) %{
13403 match(Set dst (Replicate src));
13404 predicate(n->as_Vector()->length() == 4 &&
13405 Matcher::vector_element_basic_type(n) == T_FLOAT);
13406 ins_cost(DEFAULT_COST);
13407 expand %{
13408 vecX tmpV;
13409 immI8 zero %{ (int) 0 %}
13410
13411 xscvdpspn_regF(tmpV, src);
13412 xxspltw(dst, tmpV, zero);
13413 %}
13414 %}
13415
13416 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{
13417 match(Set dst (Replicate src));
13418 predicate(n->as_Vector()->length() == 4 &&
13419 Matcher::vector_element_basic_type(n) == T_FLOAT);
13420 effect(TEMP tmp);
13421 ins_cost(10 * DEFAULT_COST);
13422
13423 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) );
13424 %}
13425
13426 instruct repl4F_immF0(vecX dst, immF_0 zero) %{
13427 match(Set dst (Replicate zero));
13428 predicate(n->as_Vector()->length() == 4 &&
13429 Matcher::vector_element_basic_type(n) == T_FLOAT);
13430
13431 format %{ "XXLXOR $dst, $zero \t// replicate4F" %}
13432 size(4);
13433 ins_encode %{
13434 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13435 %}
13436 ins_pipe(pipe_class_default);
13437 %}
13438
13439 instruct repl2D_reg_Ex(vecX dst, regD src) %{
13440 match(Set dst (Replicate src));
13441 predicate(n->as_Vector()->length() == 2 &&
13442 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13443
13444 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %}
13445 size(4);
13446 ins_encode %{
13447 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0);
13448 %}
13449 ins_pipe(pipe_class_default);
13450 %}
13451
13452 instruct repl2D_immD0(vecX dst, immD_0 zero) %{
13453 match(Set dst (Replicate zero));
13454 predicate(n->as_Vector()->length() == 2 &&
13455 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13456
13457 format %{ "XXLXOR $dst, $zero \t// replicate2D" %}
13458 size(4);
13459 ins_encode %{
13460 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13461 %}
13462 ins_pipe(pipe_class_default);
13463 %}
13464
13465 instruct mtvsrd(vecX dst, iRegLsrc src) %{
13466 predicate(false);
13467 effect(DEF dst, USE src);
13468
13469 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %}
13470 size(4);
13471 ins_encode %{
13472 __ mtvsrd($dst$$VectorRegister->to_vsr(), $src$$Register);
13473 %}
13474 ins_pipe(pipe_class_default);
13475 %}
13476
13477 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{
13478 effect(DEF dst, USE src, USE zero);
13479
13480 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %}
13481 size(4);
13482 ins_encode %{
13483 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $zero$$constant);
13484 %}
13485 ins_pipe(pipe_class_default);
13486 %}
13487
13488 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{
13489 effect(DEF dst, USE src1, USE src2, USE zero);
13490
13491 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %}
13492 size(4);
13493 ins_encode %{
13494 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr(), $zero$$constant);
13495 %}
13496 ins_pipe(pipe_class_default);
13497 %}
13498
13499 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{
13500 predicate(Matcher::vector_element_basic_type(n) == T_LONG);
13501 match(Set dst (Replicate src));
13502 predicate(n->as_Vector()->length() == 2);
13503 expand %{
13504 vecX tmpV;
13505 immI8 zero %{ (int) 0 %}
13506 mtvsrd(tmpV, src);
13507 xxpermdi(dst, tmpV, tmpV, zero);
13508 %}
13509 %}
13510
13511 instruct repl2L_immI0(vecX dst, immI_0 zero) %{
13512 match(Set dst (Replicate zero));
13513 predicate(n->as_Vector()->length() == 2 &&
13514 Matcher::vector_element_basic_type(n) == T_LONG);
13515
13516 format %{ "XXLXOR $dst, $zero \t// replicate2L" %}
13517 size(4);
13518 ins_encode %{
13519 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13520 %}
13521 ins_pipe(pipe_class_default);
13522 %}
13523
13524 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{
13525 match(Set dst (Replicate src));
13526 predicate(n->as_Vector()->length() == 2 &&
13527 Matcher::vector_element_basic_type(n) == T_LONG);
13528
13529 format %{ "XXLEQV $dst, $src \t// replicate2L" %}
13530 size(4);
13531 ins_encode %{
13532 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13533 %}
13534 ins_pipe(pipe_class_default);
13535 %}
13536
13537 // ============================================================================
13538 // Safepoint Instruction
13539
13540 instruct safePoint_poll(iRegPdst poll) %{
13541 match(SafePoint poll);
13542
13543 // It caused problems to add the effect that r0 is killed, but this
13544 // effect no longer needs to be mentioned, since r0 is not contained
13545 // in a reg_class.
13546
13547 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
13548 size(4);
13549 ins_encode( enc_poll(0x0, poll) );
13550 ins_pipe(pipe_class_default);
13551 %}
13552
13553 // ============================================================================
13554 // Call Instructions
13555
13556 source %{
13557
13558 #include "runtime/continuation.hpp"
13559
13560 %}
13561
13562 // Call Java Static Instruction
13563
13564 instruct CallStaticJavaDirect(method meth) %{
13565 match(CallStaticJava);
13566 effect(USE meth);
13567 ins_cost(CALL_COST);
13568
13569 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
13570
13571 format %{ "CALL,static $meth \t// ==> " %}
13572 size((Continuations::enabled() ? 8 : 4));
13573 ins_encode( enc_java_static_call(meth) );
13574 ins_pipe(pipe_class_call);
13575 %}
13576
13577 // Call Java Dynamic Instruction
13578
13579 instruct CallDynamicJavaDirect(method meth) %{
13580 match(CallDynamicJava);
13581 effect(USE meth);
13582 ins_cost(CALL_COST);
13583
13584 // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
13585 ins_num_consts(4);
13586
13587 format %{ "CALL,dynamic $meth \t// ==> " %}
13588 ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
13589 ins_pipe(pipe_class_call);
13590 %}
13591
13592 // Call Runtime Instruction
13593
13594 instruct CallRuntimeDirect(method meth) %{
13595 match(CallRuntime);
13596 effect(USE meth);
13597 ins_cost(CALL_COST);
13598
13599 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13600 // env for callee, C-toc.
13601 ins_num_consts(3);
13602
13603 format %{ "CALL,runtime" %}
13604 ins_encode( enc_java_to_runtime_call(meth) );
13605 ins_pipe(pipe_class_call);
13606 %}
13607
13608 // Call Leaf
13609
13610 // Used by postalloc expand of CallLeafDirect_Ex (mtctr).
13611 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
13612 effect(DEF dst, USE src);
13613
13614 ins_num_consts(1);
13615
13616 format %{ "MTCTR $src" %}
13617 size(4);
13618 ins_encode( enc_leaf_call_mtctr(src) );
13619 ins_pipe(pipe_class_default);
13620 %}
13621
13622 // Used by postalloc expand of CallLeafDirect_Ex (actual call).
13623 instruct CallLeafDirect(method meth) %{
13624 match(CallLeaf); // To get the data all the data fields we need ...
13625 effect(USE meth);
13626 predicate(false); // but never match.
13627
13628 format %{ "BCTRL \t// leaf call $meth ==> " %}
13629 size((Continuations::enabled() ? 8 : 4));
13630 ins_encode %{
13631 __ bctrl();
13632 __ post_call_nop();
13633 %}
13634 ins_pipe(pipe_class_call);
13635 %}
13636
13637 // postalloc expand of CallLeafDirect.
13638 // Load address to call from TOC, then bl to it.
13639 instruct CallLeafDirect_Ex(method meth) %{
13640 match(CallLeaf);
13641 effect(USE meth);
13642 ins_cost(CALL_COST);
13643
13644 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
13645 // env for callee, C-toc.
13646 ins_num_consts(3);
13647
13648 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
13649 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13650 %}
13651
13652 // Call runtime without safepoint - same as CallLeaf.
13653 // postalloc expand of CallLeafNoFPDirect.
13654 // Load address to call from TOC, then bl to it.
13655 instruct CallLeafNoFPDirect_Ex(method meth) %{
13656 match(CallLeafNoFP);
13657 effect(USE meth);
13658 ins_cost(CALL_COST);
13659
13660 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13661 // env for callee, C-toc.
13662 ins_num_consts(3);
13663
13664 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
13665 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13666 %}
13667
13668 // Tail Call; Jump from runtime stub to Java code.
13669 // Also known as an 'interprocedural jump'.
13670 // Target of jump will eventually return to caller.
13671 // TailJump below removes the return address.
13672 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{
13673 match(TailCall jump_target method_ptr);
13674 ins_cost(CALL_COST);
13675
13676 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t"
13677 "BCTR \t// tail call" %}
13678 size(8);
13679 ins_encode %{
13680 __ mtctr($jump_target$$Register);
13681 __ bctr();
13682 %}
13683 ins_pipe(pipe_class_call);
13684 %}
13685
13686 // Return Instruction
13687 instruct Ret() %{
13688 match(Return);
13689 format %{ "BLR \t// branch to link register" %}
13690 size(4);
13691 ins_encode %{
13692 // LR is restored in MachEpilogNode. Just do the RET here.
13693 __ blr();
13694 %}
13695 ins_pipe(pipe_class_default);
13696 %}
13697
13698 // Tail Jump; remove the return address; jump to target.
13699 // TailCall above leaves the return address around.
13700 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13701 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13702 // "restore" before this instruction (in Epilogue), we need to materialize it
13703 // in %i0.
13704 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
13705 match(TailJump jump_target ex_oop);
13706 ins_cost(CALL_COST);
13707
13708 format %{ "LD R4_ARG2 = LR\n\t"
13709 "MTCTR $jump_target\n\t"
13710 "BCTR \t// TailJump, exception oop: $ex_oop" %}
13711 size(12);
13712 ins_encode %{
13713 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP);
13714 __ mtctr($jump_target$$Register);
13715 __ bctr();
13716 %}
13717 ins_pipe(pipe_class_call);
13718 %}
13719
13720 // Forward exception.
13721 instruct ForwardExceptionjmp()
13722 %{
13723 match(ForwardException);
13724 ins_cost(CALL_COST);
13725
13726 format %{ "JMP forward_exception_stub" %}
13727 ins_encode %{
13728 __ set_inst_mark();
13729 __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
13730 __ clear_inst_mark();
13731 %}
13732 ins_pipe(pipe_class_call);
13733 %}
13734
13735 // Create exception oop: created by stack-crawling runtime code.
13736 // Created exception is now available to this handler, and is setup
13737 // just prior to jumping to this handler. No code emitted.
13738 instruct CreateException(rarg1RegP ex_oop) %{
13739 match(Set ex_oop (CreateEx));
13740 ins_cost(0);
13741
13742 format %{ " -- \t// exception oop; no code emitted" %}
13743 size(0);
13744 ins_encode( /*empty*/ );
13745 ins_pipe(pipe_class_default);
13746 %}
13747
13748 // Rethrow exception: The exception oop will come in the first
13749 // argument position. Then JUMP (not call) to the rethrow stub code.
13750 instruct RethrowException() %{
13751 match(Rethrow);
13752 ins_cost(CALL_COST);
13753
13754 format %{ "JMP rethrow_stub" %}
13755 ins_encode %{
13756 __ set_inst_mark();
13757 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
13758 __ clear_inst_mark();
13759 %}
13760 ins_pipe(pipe_class_call);
13761 %}
13762
13763 // Die now.
13764 instruct ShouldNotReachHere() %{
13765 match(Halt);
13766 ins_cost(CALL_COST);
13767
13768 format %{ "ShouldNotReachHere" %}
13769 ins_encode %{
13770 if (is_reachable()) {
13771 const char* str = __ code_string(_halt_reason);
13772 __ stop(str);
13773 }
13774 %}
13775 ins_pipe(pipe_class_default);
13776 %}
13777
13778 // This name is KNOWN by the ADLC and cannot be changed. The ADLC
13779 // forces a 'TypeRawPtr::BOTTOM' output type for this guy.
13780 // Get a DEF on threadRegP, no costs, no encoding, use
13781 // 'ins_should_rematerialize(true)' to avoid spilling.
13782 instruct tlsLoadP(threadRegP dst) %{
13783 match(Set dst (ThreadLocal));
13784 ins_cost(0);
13785
13786 ins_should_rematerialize(true);
13787
13788 format %{ " -- \t// $dst=Thread::current(), empty" %}
13789 size(0);
13790 ins_encode( /*empty*/ );
13791 ins_pipe(pipe_class_empty);
13792 %}
13793
13794 //---Some PPC specific nodes---------------------------------------------------
13795
13796 // Nop instructions
13797
13798 instruct fxNop() %{
13799 ins_cost(0);
13800
13801 ins_is_nop(true);
13802
13803 format %{ "fxNop" %}
13804 size(4);
13805 ins_encode %{
13806 __ nop();
13807 %}
13808 ins_pipe(pipe_class_default);
13809 %}
13810
13811 instruct fpNop0() %{
13812 ins_cost(0);
13813
13814 ins_is_nop(true);
13815
13816 format %{ "fpNop0" %}
13817 size(4);
13818 ins_encode %{
13819 __ fpnop0();
13820 %}
13821 ins_pipe(pipe_class_default);
13822 %}
13823
13824 instruct fpNop1() %{
13825 ins_cost(0);
13826
13827 ins_is_nop(true);
13828
13829 format %{ "fpNop1" %}
13830 size(4);
13831 ins_encode %{
13832 __ fpnop1();
13833 %}
13834 ins_pipe(pipe_class_default);
13835 %}
13836
13837 instruct brNop0() %{
13838 ins_cost(0);
13839 size(4);
13840 format %{ "brNop0" %}
13841 ins_encode %{
13842 __ brnop0();
13843 %}
13844 ins_is_nop(true);
13845 ins_pipe(pipe_class_default);
13846 %}
13847
13848 instruct brNop1() %{
13849 ins_cost(0);
13850
13851 ins_is_nop(true);
13852
13853 format %{ "brNop1" %}
13854 size(4);
13855 ins_encode %{
13856 __ brnop1();
13857 %}
13858 ins_pipe(pipe_class_default);
13859 %}
13860
13861 instruct brNop2() %{
13862 ins_cost(0);
13863
13864 ins_is_nop(true);
13865
13866 format %{ "brNop2" %}
13867 size(4);
13868 ins_encode %{
13869 __ brnop2();
13870 %}
13871 ins_pipe(pipe_class_default);
13872 %}
13873
13874 instruct cacheWB(indirect addr)
13875 %{
13876 match(CacheWB addr);
13877
13878 ins_cost(100);
13879 format %{ "cache writeback, address = $addr" %}
13880 ins_encode %{
13881 assert($addr->index_position() < 0, "should be");
13882 assert($addr$$disp == 0, "should be");
13883 __ cache_wb(Address($addr$$base$$Register));
13884 %}
13885 ins_pipe(pipe_class_default);
13886 %}
13887
13888 instruct cacheWBPreSync()
13889 %{
13890 match(CacheWBPreSync);
13891
13892 ins_cost(0);
13893 format %{ "cache writeback presync" %}
13894 ins_encode %{
13895 __ cache_wbsync(true);
13896 %}
13897 ins_pipe(pipe_class_default);
13898 %}
13899
13900 instruct cacheWBPostSync()
13901 %{
13902 match(CacheWBPostSync);
13903
13904 ins_cost(100);
13905 format %{ "cache writeback postsync" %}
13906 ins_encode %{
13907 __ cache_wbsync(false);
13908 %}
13909 ins_pipe(pipe_class_default);
13910 %}
13911
13912 //----------PEEPHOLE RULES-----------------------------------------------------
13913 // These must follow all instruction definitions as they use the names
13914 // defined in the instructions definitions.
13915 //
13916 // peepmatch ( root_instr_name [preceeding_instruction]* );
13917 //
13918 // peepconstraint %{
13919 // (instruction_number.operand_name relational_op instruction_number.operand_name
13920 // [, ...] );
13921 // // instruction numbers are zero-based using left to right order in peepmatch
13922 //
13923 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
13924 // // provide an instruction_number.operand_name for each operand that appears
13925 // // in the replacement instruction's match rule
13926 //
13927 // ---------VM FLAGS---------------------------------------------------------
13928 //
13929 // All peephole optimizations can be turned off using -XX:-OptoPeephole
13930 //
13931 // Each peephole rule is given an identifying number starting with zero and
13932 // increasing by one in the order seen by the parser. An individual peephole
13933 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
13934 // on the command-line.
13935 //
13936 // ---------CURRENT LIMITATIONS----------------------------------------------
13937 //
13938 // Only match adjacent instructions in same basic block
13939 // Only equality constraints
13940 // Only constraints between operands, not (0.dest_reg == EAX_enc)
13941 // Only one replacement instruction
13942 //
13943 // ---------EXAMPLE----------------------------------------------------------
13944 //
13945 // // pertinent parts of existing instructions in architecture description
13946 // instruct movI(eRegI dst, eRegI src) %{
13947 // match(Set dst (CopyI src));
13948 // %}
13949 //
13950 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
13951 // match(Set dst (AddI dst src));
13952 // effect(KILL cr);
13953 // %}
13954 //
13955 // // Change (inc mov) to lea
13956 // peephole %{
13957 // // increment preceded by register-register move
13958 // peepmatch ( incI_eReg movI );
13959 // // require that the destination register of the increment
13960 // // match the destination register of the move
13961 // peepconstraint ( 0.dst == 1.dst );
13962 // // construct a replacement instruction that sets
13963 // // the destination to ( move's source register + one )
13964 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13965 // %}
13966 //
13967 // Implementation no longer uses movX instructions since
13968 // machine-independent system no longer uses CopyX nodes.
13969 //
13970 // peephole %{
13971 // peepmatch ( incI_eReg movI );
13972 // peepconstraint ( 0.dst == 1.dst );
13973 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13974 // %}
13975 //
13976 // peephole %{
13977 // peepmatch ( decI_eReg movI );
13978 // peepconstraint ( 0.dst == 1.dst );
13979 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13980 // %}
13981 //
13982 // peephole %{
13983 // peepmatch ( addI_eReg_imm movI );
13984 // peepconstraint ( 0.dst == 1.dst );
13985 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13986 // %}
13987 //
13988 // peephole %{
13989 // peepmatch ( addP_eReg_imm movP );
13990 // peepconstraint ( 0.dst == 1.dst );
13991 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
13992 // %}
13993
13994 // // Change load of spilled value to only a spill
13995 // instruct storeI(memory mem, eRegI src) %{
13996 // match(Set mem (StoreI mem src));
13997 // %}
13998 //
13999 // instruct loadI(eRegI dst, memory mem) %{
14000 // match(Set dst (LoadI mem));
14001 // %}
14002 //
14003 peephole %{
14004 peepmatch ( loadI storeI );
14005 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14006 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14007 %}
14008
14009 peephole %{
14010 peepmatch ( loadL storeL );
14011 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14012 peepreplace ( storeL( 1.mem 1.mem 1.src ) );
14013 %}
14014
14015 peephole %{
14016 peepmatch ( loadP storeP );
14017 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
14018 peepreplace ( storeP( 1.dst 1.dst 1.src ) );
14019 %}
14020
14021 //----------SMARTSPILL RULES---------------------------------------------------
14022 // These must follow all instruction definitions as they use the names
14023 // defined in the instructions definitions.