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 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1546 // Variable size. determine dynamically.
1547 return MachNode::size(ra_);
1548 }
1549
1550 int MachPrologNode::reloc() const {
1551 // Return number of relocatable values contained in this instruction.
1552 return 1; // 1 reloc entry for load_const(toc).
1553 }
1554
1555 //=============================================================================
1556
1557 #ifndef PRODUCT
1558 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1559 Compile* C = ra_->C;
1560
1561 st->print("EPILOG\n\t");
1562 st->print("restore return pc\n\t");
1563 st->print("pop frame\n\t");
1564
1565 if (do_polling() && C->is_method_compilation()) {
1566 st->print("safepoint poll\n\t");
1567 }
1568 }
1569 #endif
1570
1571 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1572 Compile* C = ra_->C;
1573
1574 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt;
1575 assert(framesize >= 0, "negative frame-size?");
1576
1577 const bool method_needs_polling = do_polling() && C->is_method_compilation();
1578 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1579 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
1580 const Register temp = R12;
1581
1582 if (!method_is_frameless) {
1583 // Restore return pc relative to callers' sp.
1584 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP);
1585 // Move return pc to LR.
1586 __ mtlr(return_pc);
1587 // Pop frame (fixed frame-size).
1588 __ addi(R1_SP, R1_SP, (int)framesize);
1589 }
1590
1591 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1592 __ reserved_stack_check(return_pc);
1593 }
1594
1595 if (method_needs_polling) {
1596 Label dummy_label;
1597 Label* code_stub = &dummy_label;
1598 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) {
1599 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1600 C->output()->add_stub(stub);
1601 code_stub = &stub->entry();
1602 __ relocate(relocInfo::poll_return_type);
1603 }
1604 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */);
1605 }
1606 }
1607
1608 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1609 // Variable size. Determine dynamically.
1610 return MachNode::size(ra_);
1611 }
1612
1613 int MachEpilogNode::reloc() const {
1614 // Return number of relocatable values contained in this instruction.
1615 return 1; // 1 for load_from_polling_page.
1616 }
1617
1618 const Pipeline * MachEpilogNode::pipeline() const {
1619 return MachNode::pipeline_class();
1620 }
1621
1622 // =============================================================================
1623
1624 // Figure out which register class each belongs in: rc_int, rc_float, rc_vec or
1625 // rc_stack.
1626 enum RC { rc_bad, rc_int, rc_float, rc_vec, rc_stack };
1627
1628 static enum RC rc_class(OptoReg::Name reg) {
1629 // Return the register class for the given register. The given register
1630 // reg is a <register>_num value, which is an index into the MachRegisterNumbers
1631 // enumeration in adGlobals_ppc.hpp.
1632
1633 if (reg == OptoReg::Bad) return rc_bad;
1634
1635 // We have 64 integer register halves, starting at index 0.
1636 STATIC_ASSERT((int)ConcreteRegisterImpl::max_gpr == (int)MachRegisterNumbers::F0_num);
1637 if (reg < ConcreteRegisterImpl::max_gpr) return rc_int;
1638
1639 // We have 64 floating-point register halves, starting at index 64.
1640 STATIC_ASSERT((int)ConcreteRegisterImpl::max_fpr == (int)MachRegisterNumbers::VR0_num);
1641 if (reg < ConcreteRegisterImpl::max_fpr) return rc_float;
1642
1643 // We have 64 vector-scalar registers, starting at index 128.
1644 STATIC_ASSERT((int)ConcreteRegisterImpl::max_vr == (int)MachRegisterNumbers::CR0_num);
1645 if (reg < ConcreteRegisterImpl::max_vr) return rc_vec;
1646
1647 // Condition and special purpose registers are not allocated. We only accept stack from here.
1648 assert(OptoReg::is_stack(reg), "what else is it?");
1649 return rc_stack;
1650 }
1651
1652 static int ld_st_helper(C2_MacroAssembler *masm, const char *op_str, uint opcode, int reg, int offset,
1653 bool do_print, Compile* C, outputStream *st) {
1654
1655 assert(opcode == Assembler::LD_OPCODE ||
1656 opcode == Assembler::STD_OPCODE ||
1657 opcode == Assembler::LWZ_OPCODE ||
1658 opcode == Assembler::STW_OPCODE ||
1659 opcode == Assembler::LFD_OPCODE ||
1660 opcode == Assembler::STFD_OPCODE ||
1661 opcode == Assembler::LFS_OPCODE ||
1662 opcode == Assembler::STFS_OPCODE,
1663 "opcode not supported");
1664
1665 if (masm) {
1666 int d =
1667 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ?
1668 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/)
1669 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build.
1670 emit_long(masm, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP));
1671 }
1672 #ifndef PRODUCT
1673 else if (do_print) {
1674 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy",
1675 op_str,
1676 Matcher::regName[reg],
1677 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/);
1678 }
1679 #endif
1680 return 4; // size
1681 }
1682
1683 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1684 Compile* C = ra_->C;
1685
1686 // Get registers to move.
1687 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1688 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1689 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1690 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1691
1692 enum RC src_hi_rc = rc_class(src_hi);
1693 enum RC src_lo_rc = rc_class(src_lo);
1694 enum RC dst_hi_rc = rc_class(dst_hi);
1695 enum RC dst_lo_rc = rc_class(dst_lo);
1696
1697 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1698 if (src_hi != OptoReg::Bad)
1699 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1700 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1701 "expected aligned-adjacent pairs");
1702 // Generate spill code!
1703 int size = 0;
1704
1705 if (src_lo == dst_lo && src_hi == dst_hi)
1706 return size; // Self copy, no move.
1707
1708 if (bottom_type()->isa_vect() != nullptr && ideal_reg() == Op_VecX) {
1709 int src_offset = ra_->reg2offset(src_lo);
1710 int dst_offset = ra_->reg2offset(dst_lo);
1711 DEBUG_ONLY(int algm = MIN2(RegMask::num_registers(ideal_reg()), (int)Matcher::stack_alignment_in_slots()) * VMRegImpl::stack_slot_size);
1712 assert((src_lo_rc != rc_stack) || is_aligned(src_offset, algm), "unaligned vector spill sp offset %d (src)", src_offset);
1713 assert((dst_lo_rc != rc_stack) || is_aligned(dst_offset, algm), "unaligned vector spill sp offset %d (dst)", dst_offset);
1714 // Memory->Memory Spill.
1715 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1716 if (masm) {
1717 __ ld(R0, src_offset, R1_SP);
1718 __ std(R0, dst_offset, R1_SP);
1719 __ ld(R0, src_offset+8, R1_SP);
1720 __ std(R0, dst_offset+8, R1_SP);
1721 }
1722 size += 16;
1723 #ifndef PRODUCT
1724 if (st != nullptr) {
1725 st->print("%-7s [R1_SP + #%d] -> [R1_SP + #%d] \t// vector spill copy", "SPILL", src_offset, dst_offset);
1726 }
1727 #endif // !PRODUCT
1728 }
1729 // VectorRegister->Memory Spill.
1730 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_stack) {
1731 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1732 if (masm) {
1733 __ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16
1734 }
1735 size += 4;
1736 #ifndef PRODUCT
1737 if (st != nullptr) {
1738 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "STXV", Matcher::regName[src_lo], dst_offset);
1739 }
1740 #endif // !PRODUCT
1741 }
1742 // Memory->VectorRegister Spill.
1743 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vec) {
1744 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1745 if (masm) {
1746 __ lxv(Rdst, src_offset, R1_SP);
1747 }
1748 size += 4;
1749 #ifndef PRODUCT
1750 if (st != nullptr) {
1751 st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "LXV", Matcher::regName[dst_lo], src_offset);
1752 }
1753 #endif // !PRODUCT
1754 }
1755 // VectorRegister->VectorRegister.
1756 else if (src_lo_rc == rc_vec && dst_lo_rc == rc_vec) {
1757 VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
1758 VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
1759 if (masm) {
1760 __ xxlor(Rdst, Rsrc, Rsrc);
1761 }
1762 size += 4;
1763 #ifndef PRODUCT
1764 if (st != nullptr) {
1765 st->print("%-7s %s, %s, %s\t// vector spill copy",
1766 "XXLOR", Matcher::regName[dst_lo], Matcher::regName[src_lo], Matcher::regName[src_lo]);
1767 }
1768 #endif // !PRODUCT
1769 }
1770 else {
1771 ShouldNotReachHere(); // No VR spill.
1772 }
1773 return size;
1774 }
1775
1776 // --------------------------------------
1777 // Memory->Memory Spill. Use R0 to hold the value.
1778 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1779 int src_offset = ra_->reg2offset(src_lo);
1780 int dst_offset = ra_->reg2offset(dst_lo);
1781 if (src_hi != OptoReg::Bad) {
1782 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack,
1783 "expected same type of move for high parts");
1784 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st);
1785 if (!masm && !do_size) st->print("\n\t");
1786 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st);
1787 } else {
1788 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st);
1789 if (!masm && !do_size) st->print("\n\t");
1790 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st);
1791 }
1792 return size;
1793 }
1794
1795 // --------------------------------------
1796 // Check for float->int copy; requires a trip through memory.
1797 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1798 Unimplemented();
1799 }
1800
1801 // --------------------------------------
1802 // Check for integer reg-reg copy.
1803 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1804 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1805 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1806 size = (Rsrc != Rdst) ? 4 : 0;
1807
1808 if (masm) {
1809 if (size) {
1810 __ mr(Rdst, Rsrc);
1811 }
1812 }
1813 #ifndef PRODUCT
1814 else if (!do_size) {
1815 if (size) {
1816 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1817 } else {
1818 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1819 }
1820 }
1821 #endif
1822 return size;
1823 }
1824
1825 // Check for integer store.
1826 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1827 int dst_offset = ra_->reg2offset(dst_lo);
1828 if (src_hi != OptoReg::Bad) {
1829 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack,
1830 "expected same type of move for high parts");
1831 size += ld_st_helper(masm, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1832 } else {
1833 size += ld_st_helper(masm, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st);
1834 }
1835 return size;
1836 }
1837
1838 // Check for integer load.
1839 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1840 int src_offset = ra_->reg2offset(src_lo);
1841 if (src_hi != OptoReg::Bad) {
1842 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack,
1843 "expected same type of move for high parts");
1844 size += ld_st_helper(masm, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1845 } else {
1846 size += ld_st_helper(masm, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st);
1847 }
1848 return size;
1849 }
1850
1851 // Check for float reg-reg copy.
1852 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1853 if (masm) {
1854 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]);
1855 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]);
1856 __ fmr(Rdst, Rsrc);
1857 }
1858 #ifndef PRODUCT
1859 else if (!do_size) {
1860 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1861 }
1862 #endif
1863 return 4;
1864 }
1865
1866 // Check for float store.
1867 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1868 int dst_offset = ra_->reg2offset(dst_lo);
1869 if (src_hi != OptoReg::Bad) {
1870 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack,
1871 "expected same type of move for high parts");
1872 size += ld_st_helper(masm, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1873 } else {
1874 size += ld_st_helper(masm, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st);
1875 }
1876 return size;
1877 }
1878
1879 // Check for float load.
1880 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1881 int src_offset = ra_->reg2offset(src_lo);
1882 if (src_hi != OptoReg::Bad) {
1883 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack,
1884 "expected same type of move for high parts");
1885 size += ld_st_helper(masm, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1886 } else {
1887 size += ld_st_helper(masm, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st);
1888 }
1889 return size;
1890 }
1891
1892 // --------------------------------------------------------------------
1893 // Check for hi bits still needing moving. Only happens for misaligned
1894 // arguments to native calls.
1895 if (src_hi == dst_hi)
1896 return size; // Self copy; no move.
1897
1898 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad");
1899 ShouldNotReachHere(); // Unimplemented
1900 return 0;
1901 }
1902
1903 #ifndef PRODUCT
1904 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1905 if (!ra_)
1906 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1907 else
1908 implementation(nullptr, ra_, false, st);
1909 }
1910 #endif
1911
1912 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1913 implementation(masm, ra_, false, nullptr);
1914 }
1915
1916 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1917 return implementation(nullptr, ra_, true, nullptr);
1918 }
1919
1920 #ifndef PRODUCT
1921 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1922 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count);
1923 }
1924 #endif
1925
1926 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *) const {
1927 // _count contains the number of nops needed for padding.
1928 for (int i = 0; i < _count; i++) {
1929 __ nop();
1930 }
1931 }
1932
1933 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
1934 return _count * 4;
1935 }
1936
1937 #ifndef PRODUCT
1938 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1939 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1940 char reg_str[128];
1941 ra_->dump_register(this, reg_str, sizeof(reg_str));
1942 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset);
1943 }
1944 #endif
1945
1946 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1947 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1948 int reg = ra_->get_encode(this);
1949
1950 if (Assembler::is_simm(offset, 16)) {
1951 __ addi(as_Register(reg), R1, offset);
1952 } else {
1953 ShouldNotReachHere();
1954 }
1955 }
1956
1957 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1958 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1959 return 4;
1960 }
1961
1962 #ifndef PRODUCT
1963 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1964 st->print_cr("---- MachUEPNode ----");
1965 st->print_cr("...");
1966 }
1967 #endif
1968
1969 void MachUEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1970 // This is the unverified entry point.
1971 __ ic_check(CodeEntryAlignment);
1972 // Argument is valid and klass is as expected, continue.
1973 }
1974
1975 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1976 // Variable size. Determine dynamically.
1977 return MachNode::size(ra_);
1978 }
1979
1980 //=============================================================================
1981
1982 %} // interrupt source
1983
1984 source_hpp %{ // Header information of the source block.
1985
1986 class HandlerImpl {
1987
1988 public:
1989
1990 static int emit_deopt_handler(C2_MacroAssembler* masm);
1991
1992 static uint size_deopt_handler() {
1993 // The deopt_handler is a bl64_patchable.
1994 return MacroAssembler::bl64_patchable_size + BytesPerInstWord;
1995 }
1996
1997 };
1998
1999 class Node::PD {
2000 public:
2001 enum NodeFlags {
2002 _last_flag = Node::_last_flag
2003 };
2004 };
2005
2006 %} // end source_hpp
2007
2008 source %{
2009
2010 // The deopt_handler is like the exception handler, but it calls to
2011 // the deoptimization blob instead of jumping to the exception blob.
2012 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
2013 address base = __ start_a_stub(size_deopt_handler());
2014 if (base == nullptr) {
2015 ciEnv::current()->record_failure("CodeCache is full");
2016 return 0; // CodeBuffer::expand failed
2017 }
2018
2019 int offset = __ offset();
2020
2021 Label start;
2022 __ bind(start);
2023
2024 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
2025 relocInfo::runtime_call_type);
2026
2027 int entry_offset = __ offset();
2028
2029 __ b(start);
2030
2031 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
2032 assert(__ offset() - entry_offset >= NativePostCallNop::first_check_size,
2033 "out of bounds read in post-call NOP check");
2034 __ end_a_stub();
2035
2036 return entry_offset;
2037 }
2038
2039 //=============================================================================
2040
2041 // Use a frame slots bias for frameless methods if accessing the stack.
2042 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) {
2043 if (as_Register(reg_enc) == R1_SP) {
2044 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes();
2045 }
2046 return 0;
2047 }
2048
2049 bool Matcher::match_rule_supported(int opcode) {
2050 if (!has_match_rule(opcode)) {
2051 return false; // no match rule present
2052 }
2053
2054 switch (opcode) {
2055 case Op_CountLeadingZerosI:
2056 case Op_CountLeadingZerosL:
2057 return UseCountLeadingZerosInstructionsPPC64;
2058 case Op_CountTrailingZerosI:
2059 case Op_CountTrailingZerosL:
2060 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64);
2061 case Op_PopCountI:
2062 case Op_PopCountL:
2063 return UsePopCountInstruction;
2064 case Op_ConvF2HF:
2065 case Op_ConvHF2F:
2066 return VM_Version::supports_float16();
2067 case Op_AddVB:
2068 case Op_AddVS:
2069 case Op_AddVI:
2070 case Op_AddVF:
2071 case Op_AddVD:
2072 case Op_SubVB:
2073 case Op_SubVS:
2074 case Op_SubVI:
2075 case Op_SubVF:
2076 case Op_SubVD:
2077 case Op_MulVS:
2078 case Op_MulVF:
2079 case Op_MulVD:
2080 case Op_DivVF:
2081 case Op_DivVD:
2082 case Op_AbsVF:
2083 case Op_AbsVD:
2084 case Op_NegVI:
2085 case Op_NegVF:
2086 case Op_NegVD:
2087 case Op_SqrtVF:
2088 case Op_SqrtVD:
2089 case Op_AddVL:
2090 case Op_SubVL:
2091 case Op_MulVI:
2092 case Op_RoundDoubleModeV:
2093 case Op_MinV:
2094 case Op_MaxV:
2095 case Op_UMinV:
2096 case Op_UMaxV:
2097 case Op_AndV:
2098 case Op_OrV:
2099 case Op_XorV:
2100 case Op_AddReductionVI:
2101 case Op_MulReductionVI:
2102 case Op_AndReductionV:
2103 case Op_OrReductionV:
2104 case Op_XorReductionV:
2105 case Op_MinReductionV:
2106 case Op_MaxReductionV:
2107 return SuperwordUseVSX;
2108 case Op_PopCountVI:
2109 case Op_PopCountVL:
2110 return (SuperwordUseVSX && UsePopCountInstruction);
2111 case Op_CountLeadingZerosV:
2112 return SuperwordUseVSX && UseCountLeadingZerosInstructionsPPC64;
2113 case Op_CountTrailingZerosV:
2114 return SuperwordUseVSX && UseCountTrailingZerosInstructionsPPC64;
2115 case Op_FmaF:
2116 case Op_FmaD:
2117 return UseFMA;
2118 case Op_FmaVF:
2119 case Op_FmaVD:
2120 return (SuperwordUseVSX && UseFMA);
2121
2122 case Op_MinF:
2123 case Op_MaxF:
2124 case Op_MinD:
2125 case Op_MaxD:
2126 return (PowerArchitecturePPC64 >= 9);
2127
2128 case Op_Digit:
2129 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit);
2130 case Op_LowerCase:
2131 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase);
2132 case Op_UpperCase:
2133 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase);
2134 case Op_Whitespace:
2135 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace);
2136
2137 case Op_CacheWB:
2138 case Op_CacheWBPreSync:
2139 case Op_CacheWBPostSync:
2140 return VM_Version::supports_data_cache_line_flush();
2141
2142 case Op_OnSpinWait:
2143 return VM_Version::supports_on_spin_wait();
2144 }
2145
2146 return true; // Per default match rules are supported.
2147 }
2148
2149 bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
2150 return match_rule_supported_vector(opcode, vlen, bt);
2151 }
2152
2153 bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
2154 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
2155 return false;
2156 }
2157 // Special cases
2158 switch (opcode) {
2159 // Reductions only support INT at the moment.
2160 case Op_AddReductionVI:
2161 case Op_MulReductionVI:
2162 case Op_AndReductionV:
2163 case Op_OrReductionV:
2164 case Op_XorReductionV:
2165 case Op_MinReductionV:
2166 case Op_MaxReductionV:
2167 return bt == T_INT;
2168 // MaxV, MinV need types == INT || LONG.
2169 case Op_MaxV:
2170 case Op_MinV:
2171 case Op_UMinV:
2172 case Op_UMaxV:
2173 return bt == T_INT || bt == T_LONG;
2174 case Op_NegVI:
2175 return bt == T_INT;
2176 }
2177 return true; // Per default match rules are supported.
2178 }
2179
2180 bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
2181 return false;
2182 }
2183
2184 bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
2185 return false;
2186 }
2187
2188 bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
2189 return false;
2190 }
2191
2192 bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
2193 return false;
2194 }
2195
2196 const RegMask* Matcher::predicate_reg_mask(void) {
2197 return nullptr;
2198 }
2199
2200 // Vector calling convention not yet implemented.
2201 bool Matcher::supports_vector_calling_convention(void) {
2202 return false;
2203 }
2204
2205 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2206 Unimplemented();
2207 return OptoRegPair(0, 0);
2208 }
2209
2210 // Vector width in bytes.
2211 int Matcher::vector_width_in_bytes(BasicType bt) {
2212 if (SuperwordUseVSX) {
2213 assert(MaxVectorSize == 16,
2214 "SuperwordUseVSX requires MaxVectorSize 16, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2215 return 16;
2216 } else {
2217 assert(MaxVectorSize == 8,
2218 "expected MaxVectorSize 8, got " INT64_FORMAT, (int64_t)MaxVectorSize);
2219 return 8;
2220 }
2221 }
2222
2223 // Vector ideal reg.
2224 uint Matcher::vector_ideal_reg(int size) {
2225 if (SuperwordUseVSX) {
2226 assert(MaxVectorSize == 16 && size == 16,
2227 "SuperwordUseVSX requires MaxVectorSize 16 and size 16, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2228 (int64_t)MaxVectorSize, size);
2229 return Op_VecX;
2230 } else {
2231 assert(MaxVectorSize == 8 && size == 8,
2232 "expected MaxVectorSize 8 and size 8, got MaxVectorSize=" INT64_FORMAT ", size=%d",
2233 (int64_t)MaxVectorSize, size);
2234 return Op_RegL;
2235 }
2236 }
2237
2238 // Limits on vector size (number of elements) loaded into vector.
2239 int Matcher::max_vector_size(const BasicType bt) {
2240 assert(is_java_primitive(bt), "only primitive type vectors");
2241 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2242 }
2243
2244 int Matcher::min_vector_size(const BasicType bt) {
2245 return max_vector_size(bt); // Same as max.
2246 }
2247
2248 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
2249 return Matcher::max_vector_size(bt);
2250 }
2251
2252 int Matcher::scalable_vector_reg_size(const BasicType bt) {
2253 return -1;
2254 }
2255
2256 // RETURNS: whether this branch offset is short enough that a short
2257 // branch can be used.
2258 //
2259 // If the platform does not provide any short branch variants, then
2260 // this method should return `false' for offset 0.
2261 //
2262 // `Compile::Fill_buffer' will decide on basis of this information
2263 // whether to do the pass `Compile::Shorten_branches' at all.
2264 //
2265 // And `Compile::Shorten_branches' will decide on basis of this
2266 // information whether to replace particular branch sites by short
2267 // ones.
2268 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2269 // Is the offset within the range of a ppc64 pc relative branch?
2270 bool b;
2271
2272 const int safety_zone = 3 * BytesPerInstWord;
2273 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2274 29 - 16 + 1 + 2);
2275 return b;
2276 }
2277
2278 /* TODO: PPC port
2279 // Make a new machine dependent decode node (with its operands).
2280 MachTypeNode *Matcher::make_decode_node() {
2281 assert(CompressedOops::base() == nullptr && CompressedOops::shift() == 0,
2282 "This method is only implemented for unscaled cOops mode so far");
2283 MachTypeNode *decode = new decodeN_unscaledNode();
2284 decode->set_opnd_array(0, new iRegPdstOper());
2285 decode->set_opnd_array(1, new iRegNsrcOper());
2286 return decode;
2287 }
2288 */
2289
2290 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
2291 ShouldNotReachHere(); // generic vector operands not supported
2292 return nullptr;
2293 }
2294
2295 bool Matcher::is_reg2reg_move(MachNode* m) {
2296 ShouldNotReachHere(); // generic vector operands not supported
2297 return false;
2298 }
2299
2300 bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
2301 return false;
2302 }
2303
2304 bool Matcher::is_generic_vector(MachOper* opnd) {
2305 ShouldNotReachHere(); // generic vector operands not supported
2306 return false;
2307 }
2308
2309 #ifdef ASSERT
2310 // Return whether or not this register is ever used as an argument.
2311 bool Matcher::can_be_java_arg(int reg) {
2312 // We must include the virtual halves in order to get STDs and LDs
2313 // instead of STWs and LWs in the trampoline stubs.
2314
2315 if ( reg == R3_num || reg == R3_H_num
2316 || reg == R4_num || reg == R4_H_num
2317 || reg == R5_num || reg == R5_H_num
2318 || reg == R6_num || reg == R6_H_num
2319 || reg == R7_num || reg == R7_H_num
2320 || reg == R8_num || reg == R8_H_num
2321 || reg == R9_num || reg == R9_H_num
2322 || reg == R10_num || reg == R10_H_num)
2323 return true;
2324
2325 if ( reg == F1_num || reg == F1_H_num
2326 || reg == F2_num || reg == F2_H_num
2327 || reg == F3_num || reg == F3_H_num
2328 || reg == F4_num || reg == F4_H_num
2329 || reg == F5_num || reg == F5_H_num
2330 || reg == F6_num || reg == F6_H_num
2331 || reg == F7_num || reg == F7_H_num
2332 || reg == F8_num || reg == F8_H_num
2333 || reg == F9_num || reg == F9_H_num
2334 || reg == F10_num || reg == F10_H_num
2335 || reg == F11_num || reg == F11_H_num
2336 || reg == F12_num || reg == F12_H_num
2337 || reg == F13_num || reg == F13_H_num)
2338 return true;
2339
2340 return false;
2341 }
2342 #endif
2343
2344 uint Matcher::int_pressure_limit()
2345 {
2346 return (INTPRESSURE == -1) ? 26 : INTPRESSURE;
2347 }
2348
2349 uint Matcher::float_pressure_limit()
2350 {
2351 return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE;
2352 }
2353
2354 // Register for the first projection of an int pair
2355 const RegMask& Matcher::firstI_proj_mask() {
2356 ShouldNotReachHere();
2357 return RegMask::EMPTY;
2358 }
2359
2360 // Register for the second projection of an int pair
2361 const RegMask& Matcher::secondI_proj_mask() {
2362 ShouldNotReachHere();
2363 return RegMask::EMPTY;
2364 }
2365
2366 // Register for the first projection of a long pair
2367 const RegMask& Matcher::firstL_proj_mask() {
2368 ShouldNotReachHere();
2369 return RegMask::EMPTY;
2370 }
2371
2372 // Register for the second projection of a long pair
2373 const RegMask& Matcher::secondL_proj_mask() {
2374 ShouldNotReachHere();
2375 return RegMask::EMPTY;
2376 }
2377
2378 %}
2379
2380 //----------ENCODING BLOCK-----------------------------------------------------
2381 // This block specifies the encoding classes used by the compiler to output
2382 // byte streams. Encoding classes are parameterized macros used by
2383 // Machine Instruction Nodes in order to generate the bit encoding of the
2384 // instruction. Operands specify their base encoding interface with the
2385 // interface keyword. There are currently supported four interfaces,
2386 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
2387 // operand to generate a function which returns its register number when
2388 // queried. CONST_INTER causes an operand to generate a function which
2389 // returns the value of the constant when queried. MEMORY_INTER causes an
2390 // operand to generate four functions which return the Base Register, the
2391 // Index Register, the Scale Value, and the Offset Value of the operand when
2392 // queried. COND_INTER causes an operand to generate six functions which
2393 // return the encoding code (ie - encoding bits for the instruction)
2394 // associated with each basic boolean condition for a conditional instruction.
2395 //
2396 // Instructions specify two basic values for encoding. Again, a function
2397 // is available to check if the constant displacement is an oop. They use the
2398 // ins_encode keyword to specify their encoding classes (which must be
2399 // a sequence of enc_class names, and their parameters, specified in
2400 // the encoding block), and they use the
2401 // opcode keyword to specify, in order, their primary, secondary, and
2402 // tertiary opcode. Only the opcode sections which a particular instruction
2403 // needs for encoding need to be specified.
2404 encode %{
2405 enc_class enc_unimplemented %{
2406 __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
2407 %}
2408
2409 enc_class enc_untested %{
2410 #ifdef ASSERT
2411 __ untested("Untested mach node encoding in AD file.");
2412 #else
2413 #endif
2414 %}
2415
2416 enc_class enc_lbz(iRegIdst dst, memory mem) %{
2417 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2418 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2419 %}
2420
2421 // Load acquire.
2422 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
2423 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2424 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2425 __ twi_0($dst$$Register);
2426 __ isync();
2427 %}
2428
2429 enc_class enc_lhz(iRegIdst dst, memory mem) %{
2430 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2431 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2432 %}
2433
2434 // Load acquire.
2435 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
2436 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2437 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2438 __ twi_0($dst$$Register);
2439 __ isync();
2440 %}
2441
2442 enc_class enc_lwz(iRegIdst dst, memory mem) %{
2443 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2444 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2445 %}
2446
2447 // Load acquire.
2448 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
2449 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2450 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2451 __ twi_0($dst$$Register);
2452 __ isync();
2453 %}
2454
2455 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
2456 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2457 // Operand 'ds' requires 4-alignment.
2458 assert((Idisp & 0x3) == 0, "unaligned offset");
2459 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2460 %}
2461
2462 // Load acquire.
2463 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
2464 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2465 // Operand 'ds' requires 4-alignment.
2466 assert((Idisp & 0x3) == 0, "unaligned offset");
2467 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2468 __ twi_0($dst$$Register);
2469 __ isync();
2470 %}
2471
2472 enc_class enc_lfd(RegF dst, memory mem) %{
2473 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2474 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2475 %}
2476
2477 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2478 int toc_offset = 0;
2479
2480 address const_toc_addr;
2481 // Create a non-oop constant, no relocation needed.
2482 // If it is an IC, it has a virtual_call_Relocation.
2483 const_toc_addr = __ long_constant((jlong)$src$$constant);
2484 if (const_toc_addr == nullptr) {
2485 ciEnv::current()->record_out_of_memory_failure();
2486 return;
2487 }
2488
2489 // Get the constant's TOC offset.
2490 toc_offset = __ offset_to_method_toc(const_toc_addr);
2491
2492 // Keep the current instruction offset in mind.
2493 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2494
2495 __ ld($dst$$Register, toc_offset, $toc$$Register);
2496 %}
2497
2498 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2499 if (!ra_->C->output()->in_scratch_emit_size()) {
2500 address const_toc_addr;
2501 // Create a non-oop constant, no relocation needed.
2502 // If it is an IC, it has a virtual_call_Relocation.
2503 const_toc_addr = __ long_constant((jlong)$src$$constant);
2504 if (const_toc_addr == nullptr) {
2505 ciEnv::current()->record_out_of_memory_failure();
2506 return;
2507 }
2508
2509 // Get the constant's TOC offset.
2510 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2511 // Store the toc offset of the constant.
2512 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2513
2514 // Also keep the current instruction offset in mind.
2515 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2516 }
2517
2518 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2519 %}
2520
2521 %} // encode
2522
2523 source %{
2524
2525 typedef struct {
2526 loadConL_hiNode *_large_hi;
2527 loadConL_loNode *_large_lo;
2528 loadConLNode *_small;
2529 MachNode *_last;
2530 } loadConLNodesTuple;
2531
2532 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2533 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2534 loadConLNodesTuple nodes;
2535
2536 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2537 if (large_constant_pool) {
2538 // Create new nodes.
2539 loadConL_hiNode *m1 = new loadConL_hiNode();
2540 loadConL_loNode *m2 = new loadConL_loNode();
2541
2542 // inputs for new nodes
2543 m1->add_req(nullptr, toc);
2544 m2->add_req(nullptr, m1);
2545
2546 // operands for new nodes
2547 m1->_opnds[0] = new iRegLdstOper(); // dst
2548 m1->_opnds[1] = immSrc; // src
2549 m1->_opnds[2] = new iRegLdstOper(); // toc
2550 m2->_opnds[0] = new iRegLdstOper(); // dst
2551 m2->_opnds[1] = immSrc; // src
2552 m2->_opnds[2] = new iRegLdstOper(); // base
2553
2554 // Initialize ins_attrib TOC fields.
2555 m1->_const_toc_offset = -1;
2556 m2->_const_toc_offset_hi_node = m1;
2557
2558 // Initialize ins_attrib instruction offset.
2559 m1->_cbuf_insts_offset = -1;
2560
2561 // register allocation for new nodes
2562 ra_->set_pair(m1->_idx, reg_second, reg_first);
2563 ra_->set_pair(m2->_idx, reg_second, reg_first);
2564
2565 // Create result.
2566 nodes._large_hi = m1;
2567 nodes._large_lo = m2;
2568 nodes._small = nullptr;
2569 nodes._last = nodes._large_lo;
2570 assert(m2->bottom_type()->isa_long(), "must be long");
2571 } else {
2572 loadConLNode *m2 = new loadConLNode();
2573
2574 // inputs for new nodes
2575 m2->add_req(nullptr, toc);
2576
2577 // operands for new nodes
2578 m2->_opnds[0] = new iRegLdstOper(); // dst
2579 m2->_opnds[1] = immSrc; // src
2580 m2->_opnds[2] = new iRegLdstOper(); // toc
2581
2582 // Initialize ins_attrib instruction offset.
2583 m2->_cbuf_insts_offset = -1;
2584
2585 // register allocation for new nodes
2586 ra_->set_pair(m2->_idx, reg_second, reg_first);
2587
2588 // Create result.
2589 nodes._large_hi = nullptr;
2590 nodes._large_lo = nullptr;
2591 nodes._small = m2;
2592 nodes._last = nodes._small;
2593 assert(m2->bottom_type()->isa_long(), "must be long");
2594 }
2595
2596 return nodes;
2597 }
2598
2599 typedef struct {
2600 loadConL_hiNode *_large_hi;
2601 loadConL_loNode *_large_lo;
2602 mtvsrdNode *_moved;
2603 xxspltdNode *_replicated;
2604 loadConLNode *_small;
2605 MachNode *_last;
2606 } loadConLReplicatedNodesTuple;
2607
2608 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2609 vecXOper *dst, immI_0Oper *zero,
2610 OptoReg::Name reg_second, OptoReg::Name reg_first,
2611 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) {
2612 loadConLReplicatedNodesTuple nodes;
2613
2614 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2615 if (large_constant_pool) {
2616 // Create new nodes.
2617 loadConL_hiNode *m1 = new loadConL_hiNode();
2618 loadConL_loNode *m2 = new loadConL_loNode();
2619 mtvsrdNode *m3 = new mtvsrdNode();
2620 xxspltdNode *m4 = new xxspltdNode();
2621
2622 // inputs for new nodes
2623 m1->add_req(nullptr, toc);
2624 m2->add_req(nullptr, m1);
2625 m3->add_req(nullptr, m2);
2626 m4->add_req(nullptr, m3);
2627
2628 // operands for new nodes
2629 m1->_opnds[0] = new iRegLdstOper(); // dst
2630 m1->_opnds[1] = immSrc; // src
2631 m1->_opnds[2] = new iRegLdstOper(); // toc
2632
2633 m2->_opnds[0] = new iRegLdstOper(); // dst
2634 m2->_opnds[1] = immSrc; // src
2635 m2->_opnds[2] = new iRegLdstOper(); // base
2636
2637 m3->_opnds[0] = new vecXOper(); // dst
2638 m3->_opnds[1] = new iRegLdstOper(); // src
2639
2640 m4->_opnds[0] = new vecXOper(); // dst
2641 m4->_opnds[1] = new vecXOper(); // src
2642 m4->_opnds[2] = zero;
2643
2644 // Initialize ins_attrib TOC fields.
2645 m1->_const_toc_offset = -1;
2646 m2->_const_toc_offset_hi_node = m1;
2647
2648 // Initialize ins_attrib instruction offset.
2649 m1->_cbuf_insts_offset = -1;
2650
2651 // register allocation for new nodes
2652 ra_->set_pair(m1->_idx, reg_second, reg_first);
2653 ra_->set_pair(m2->_idx, reg_second, reg_first);
2654 ra_->set1(m3->_idx, reg_second);
2655 ra_->set2(m3->_idx, reg_vec_first);
2656 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2657
2658 // Create result.
2659 nodes._large_hi = m1;
2660 nodes._large_lo = m2;
2661 nodes._moved = m3;
2662 nodes._replicated = m4;
2663 nodes._small = nullptr;
2664 nodes._last = nodes._replicated;
2665 assert(m2->bottom_type()->isa_long(), "must be long");
2666 } else {
2667 loadConLNode *m2 = new loadConLNode();
2668 mtvsrdNode *m3 = new mtvsrdNode();
2669 xxspltdNode *m4 = new xxspltdNode();
2670
2671 // inputs for new nodes
2672 m2->add_req(nullptr, toc);
2673
2674 // operands for new nodes
2675 m2->_opnds[0] = new iRegLdstOper(); // dst
2676 m2->_opnds[1] = immSrc; // src
2677 m2->_opnds[2] = new iRegLdstOper(); // toc
2678
2679 m3->_opnds[0] = new vecXOper(); // dst
2680 m3->_opnds[1] = new iRegLdstOper(); // src
2681
2682 m4->_opnds[0] = new vecXOper(); // dst
2683 m4->_opnds[1] = new vecXOper(); // src
2684 m4->_opnds[2] = zero;
2685
2686 // Initialize ins_attrib instruction offset.
2687 m2->_cbuf_insts_offset = -1;
2688 ra_->set1(m3->_idx, reg_second);
2689 ra_->set2(m3->_idx, reg_vec_first);
2690 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2691
2692 // register allocation for new nodes
2693 ra_->set_pair(m2->_idx, reg_second, reg_first);
2694
2695 // Create result.
2696 nodes._large_hi = nullptr;
2697 nodes._large_lo = nullptr;
2698 nodes._small = m2;
2699 nodes._moved = m3;
2700 nodes._replicated = m4;
2701 nodes._last = nodes._replicated;
2702 assert(m2->bottom_type()->isa_long(), "must be long");
2703 }
2704
2705 return nodes;
2706 }
2707
2708 %} // source
2709
2710 encode %{
2711 // Postalloc expand emitter for loading a long constant from the method's TOC.
2712 // Enc_class needed as consttanttablebase is not supported by postalloc
2713 // expand.
2714 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2715 // Create new nodes.
2716 loadConLNodesTuple loadConLNodes =
2717 loadConLNodesTuple_create(ra_, n_toc, op_src,
2718 ra_->get_reg_second(this), ra_->get_reg_first(this));
2719
2720 // Push new nodes.
2721 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2722 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2723
2724 // some asserts
2725 assert(nodes->length() >= 1, "must have created at least 1 node");
2726 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2727 %}
2728
2729 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2730 int toc_offset = 0;
2731
2732 intptr_t val = $src$$constant;
2733 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2734 address const_toc_addr;
2735 RelocationHolder r; // Initializes type to none.
2736 if (constant_reloc == relocInfo::oop_type) {
2737 // Create an oop constant and a corresponding relocation.
2738 AddressLiteral a = __ constant_oop_address((jobject)val);
2739 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2740 r = a.rspec();
2741 } else if (constant_reloc == relocInfo::metadata_type) {
2742 // Notify OOP recorder (don't need the relocation)
2743 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2744 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2745 } else {
2746 // Create a non-oop constant, no relocation needed.
2747 const_toc_addr = __ long_constant((jlong)$src$$constant);
2748 }
2749
2750 if (const_toc_addr == nullptr) {
2751 ciEnv::current()->record_out_of_memory_failure();
2752 return;
2753 }
2754 __ relocate(r); // If set above.
2755 // Get the constant's TOC offset.
2756 toc_offset = __ offset_to_method_toc(const_toc_addr);
2757
2758 __ ld($dst$$Register, toc_offset, $toc$$Register);
2759 %}
2760
2761 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2762 if (!ra_->C->output()->in_scratch_emit_size()) {
2763 intptr_t val = $src$$constant;
2764 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2765 address const_toc_addr;
2766 RelocationHolder r; // Initializes type to none.
2767 if (constant_reloc == relocInfo::oop_type) {
2768 // Create an oop constant and a corresponding relocation.
2769 AddressLiteral a = __ constant_oop_address((jobject)val);
2770 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2771 r = a.rspec();
2772 } else if (constant_reloc == relocInfo::metadata_type) {
2773 // Notify OOP recorder (don't need the relocation)
2774 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2775 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2776 } else { // non-oop pointers, e.g. card mark base, heap top
2777 // Create a non-oop constant, no relocation needed.
2778 const_toc_addr = __ long_constant((jlong)$src$$constant);
2779 }
2780
2781 if (const_toc_addr == nullptr) {
2782 ciEnv::current()->record_out_of_memory_failure();
2783 return;
2784 }
2785 __ relocate(r); // If set above.
2786 // Get the constant's TOC offset.
2787 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2788 // Store the toc offset of the constant.
2789 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2790 }
2791
2792 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2793 %}
2794
2795 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2796 // Enc_class needed as consttanttablebase is not supported by postalloc
2797 // expand.
2798 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2799 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2800 if (large_constant_pool) {
2801 // Create new nodes.
2802 loadConP_hiNode *m1 = new loadConP_hiNode();
2803 loadConP_loNode *m2 = new loadConP_loNode();
2804
2805 // If this is an oop, both m1 and m2 must be consider oops so postalloc scheduling does not
2806 // put a safepoint between them
2807 m1->_bottom_type = bottom_type();
2808 m2->_bottom_type = bottom_type();
2809
2810 // inputs for new nodes
2811 m1->add_req(nullptr, n_toc);
2812 m2->add_req(nullptr, m1);
2813
2814 // operands for new nodes
2815 m1->_opnds[0] = new iRegPdstOper(); // dst
2816 m1->_opnds[1] = op_src; // src
2817 m1->_opnds[2] = new iRegLdstOper(); // toc
2818
2819 m2->_opnds[0] = new iRegPdstOper(); // dst
2820 m2->_opnds[1] = op_src; // src
2821 m2->_opnds[2] = new iRegLdstOper(); // base
2822
2823 // Initialize ins_attrib TOC fields.
2824 m1->_const_toc_offset = -1;
2825 m2->_const_toc_offset_hi_node = m1;
2826
2827 // Register allocation for new nodes.
2828 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2829 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2830
2831 nodes->push(m1);
2832 nodes->push(m2);
2833 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2834 } else {
2835 loadConPNode *m2 = new loadConPNode();
2836
2837 // inputs for new nodes
2838 m2->add_req(nullptr, n_toc);
2839
2840 // operands for new nodes
2841 m2->_opnds[0] = new iRegPdstOper(); // dst
2842 m2->_opnds[1] = op_src; // src
2843 m2->_opnds[2] = new iRegLdstOper(); // toc
2844
2845 // Register allocation for new nodes.
2846 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2847
2848 nodes->push(m2);
2849 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2850 }
2851 %}
2852
2853 // Enc_class needed as consttanttablebase is not supported by postalloc
2854 // expand.
2855 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2856 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2857
2858 MachNode *m2;
2859 if (large_constant_pool) {
2860 m2 = new loadConFCompNode();
2861 } else {
2862 m2 = new loadConFNode();
2863 }
2864 // inputs for new nodes
2865 m2->add_req(nullptr, n_toc);
2866
2867 // operands for new nodes
2868 m2->_opnds[0] = op_dst;
2869 m2->_opnds[1] = op_src;
2870 m2->_opnds[2] = new iRegLdstOper(); // constanttablebase
2871
2872 // register allocation for new nodes
2873 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2874 nodes->push(m2);
2875 %}
2876
2877 // Enc_class needed as consttanttablebase is not supported by postalloc
2878 // expand.
2879 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2880 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2881
2882 MachNode *m2;
2883 if (large_constant_pool) {
2884 m2 = new loadConDCompNode();
2885 } else {
2886 m2 = new loadConDNode();
2887 }
2888 // inputs for new nodes
2889 m2->add_req(nullptr, n_toc);
2890
2891 // operands for new nodes
2892 m2->_opnds[0] = op_dst;
2893 m2->_opnds[1] = op_src;
2894 m2->_opnds[2] = new iRegLdstOper(); // constanttablebase
2895
2896 // register allocation for new nodes
2897 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2898 nodes->push(m2);
2899 %}
2900
2901 enc_class enc_stw(iRegIsrc src, memory mem) %{
2902 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2903 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2904 %}
2905
2906 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2907 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2908 // Operand 'ds' requires 4-alignment.
2909 assert((Idisp & 0x3) == 0, "unaligned offset");
2910 __ std($src$$Register, Idisp, $mem$$base$$Register);
2911 %}
2912
2913 enc_class enc_stfs(RegF src, memory mem) %{
2914 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2915 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2916 %}
2917
2918 enc_class enc_stfd(RegF src, memory mem) %{
2919 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2920 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2921 %}
2922
2923 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2924 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
2925 encodeP_subNode *n_sub_base = new encodeP_subNode();
2926 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
2927 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode();
2928
2929 n_compare->add_req(n_region, n_src);
2930 n_compare->_opnds[0] = op_crx;
2931 n_compare->_opnds[1] = op_src;
2932 n_compare->_opnds[2] = new immL16Oper(0);
2933
2934 n_sub_base->add_req(n_region, n_src);
2935 n_sub_base->_opnds[0] = op_dst;
2936 n_sub_base->_opnds[1] = op_src;
2937 n_sub_base->_bottom_type = _bottom_type;
2938
2939 n_shift->add_req(n_region, n_sub_base);
2940 n_shift->_opnds[0] = op_dst;
2941 n_shift->_opnds[1] = op_dst;
2942 n_shift->_bottom_type = _bottom_type;
2943
2944 n_cond_set->add_req(n_region, n_compare, n_shift);
2945 n_cond_set->_opnds[0] = op_dst;
2946 n_cond_set->_opnds[1] = op_crx;
2947 n_cond_set->_opnds[2] = op_dst;
2948 n_cond_set->_bottom_type = _bottom_type;
2949
2950 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2951 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2952 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2953 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2954
2955 nodes->push(n_compare);
2956 nodes->push(n_sub_base);
2957 nodes->push(n_shift);
2958 nodes->push(n_cond_set);
2959
2960 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2961 %}
2962
2963 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
2964
2965 encodeP_subNode *n1 = new encodeP_subNode();
2966 n1->add_req(n_region, n_src);
2967 n1->_opnds[0] = op_dst;
2968 n1->_opnds[1] = op_src;
2969 n1->_bottom_type = _bottom_type;
2970
2971 encodeP_shiftNode *n2 = new encodeP_shiftNode();
2972 n2->add_req(n_region, n1);
2973 n2->_opnds[0] = op_dst;
2974 n2->_opnds[1] = op_dst;
2975 n2->_bottom_type = _bottom_type;
2976 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2977 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2978
2979 nodes->push(n1);
2980 nodes->push(n2);
2981 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2982 %}
2983
2984 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
2985 decodeN_shiftNode *n_shift = new decodeN_shiftNode();
2986 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
2987
2988 n_compare->add_req(n_region, n_src);
2989 n_compare->_opnds[0] = op_crx;
2990 n_compare->_opnds[1] = op_src;
2991 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
2992
2993 n_shift->add_req(n_region, n_src);
2994 n_shift->_opnds[0] = op_dst;
2995 n_shift->_opnds[1] = op_src;
2996 n_shift->_bottom_type = _bottom_type;
2997
2998 decodeN_addNode *n_add_base = new decodeN_addNode();
2999 n_add_base->add_req(n_region, n_shift);
3000 n_add_base->_opnds[0] = op_dst;
3001 n_add_base->_opnds[1] = op_dst;
3002 n_add_base->_bottom_type = _bottom_type;
3003
3004 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
3005 n_cond_set->add_req(n_region, n_compare, n_add_base);
3006 n_cond_set->_opnds[0] = op_dst;
3007 n_cond_set->_opnds[1] = op_crx;
3008 n_cond_set->_opnds[2] = op_dst;
3009 n_cond_set->_bottom_type = _bottom_type;
3010
3011 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3012 ra_->set_oop(n_cond_set, true);
3013
3014 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3015 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3016 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3017 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3018
3019 nodes->push(n_compare);
3020 nodes->push(n_shift);
3021 nodes->push(n_add_base);
3022 nodes->push(n_cond_set);
3023
3024 %}
3025
3026 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3027 decodeN_shiftNode *n1 = new decodeN_shiftNode();
3028 n1->add_req(n_region, n_src);
3029 n1->_opnds[0] = op_dst;
3030 n1->_opnds[1] = op_src;
3031 n1->_bottom_type = _bottom_type;
3032
3033 decodeN_addNode *n2 = new decodeN_addNode();
3034 n2->add_req(n_region, n1);
3035 n2->_opnds[0] = op_dst;
3036 n2->_opnds[1] = op_dst;
3037 n2->_bottom_type = _bottom_type;
3038 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3039 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3040
3041 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3042 ra_->set_oop(n2, true);
3043
3044 nodes->push(n1);
3045 nodes->push(n2);
3046 %}
3047
3048
3049 // This enc_class is needed so that scheduler gets proper
3050 // input mapping for latency computation.
3051 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
3052 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
3053 %}
3054
3055 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3056 Label done;
3057 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3058 __ li($dst$$Register, $zero$$constant);
3059 __ beq($crx$$CondRegister, done);
3060 __ li($dst$$Register, $notzero$$constant);
3061 __ bind(done);
3062 %}
3063
3064 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3065 Label done;
3066 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3067 __ li($dst$$Register, $zero$$constant);
3068 __ beq($crx$$CondRegister, done);
3069 __ li($dst$$Register, $notzero$$constant);
3070 __ bind(done);
3071 %}
3072
3073 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3074 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3075 Label done;
3076 __ bso($crx$$CondRegister, done);
3077 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3078 __ bind(done);
3079 %}
3080
3081 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3082 Label d; // dummy
3083 __ bind(d);
3084 Label* p = ($lbl$$label);
3085 // `p' is `nullptr' when this encoding class is used only to
3086 // determine the size of the encoded instruction.
3087 Label& l = (nullptr == p)? d : *(p);
3088 int cc = $cmp$$cmpcode;
3089 int flags_reg = $crx$$reg;
3090 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3091 int bhint = Assembler::bhintNoHint;
3092
3093 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3094 if (_prob <= PROB_NEVER) {
3095 bhint = Assembler::bhintIsNotTaken;
3096 } else if (_prob >= PROB_ALWAYS) {
3097 bhint = Assembler::bhintIsTaken;
3098 }
3099 }
3100
3101 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3102 cc_to_biint(cc, flags_reg),
3103 l);
3104 %}
3105
3106 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3107 // The scheduler doesn't know about branch shortening, so we set the opcode
3108 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3109 Label d; // dummy
3110 __ bind(d);
3111 Label* p = ($lbl$$label);
3112 // `p' is `nullptr' when this encoding class is used only to
3113 // determine the size of the encoded instruction.
3114 Label& l = (nullptr == p)? d : *(p);
3115 int cc = $cmp$$cmpcode;
3116 int flags_reg = $crx$$reg;
3117 int bhint = Assembler::bhintNoHint;
3118
3119 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3120 if (_prob <= PROB_NEVER) {
3121 bhint = Assembler::bhintIsNotTaken;
3122 } else if (_prob >= PROB_ALWAYS) {
3123 bhint = Assembler::bhintIsTaken;
3124 }
3125 }
3126
3127 // Tell the conditional far branch to optimize itself when being relocated.
3128 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3129 cc_to_biint(cc, flags_reg),
3130 l,
3131 MacroAssembler::bc_far_optimize_on_relocate);
3132 %}
3133
3134 // Postalloc expand emitter for loading a replicatef float constant from
3135 // the method's TOC.
3136 // Enc_class needed as consttanttablebase is not supported by postalloc
3137 // expand.
3138 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3139 // Create new nodes.
3140
3141 // Make an operand with the bit pattern to load as float.
3142 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3143
3144 loadConLNodesTuple loadConLNodes =
3145 loadConLNodesTuple_create(ra_, n_toc, op_repl,
3146 ra_->get_reg_second(this), ra_->get_reg_first(this));
3147
3148 // Push new nodes.
3149 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3150 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3151
3152 assert(nodes->length() >= 1, "must have created at least 1 node");
3153 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3154 %}
3155
3156 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{
3157 // Create new nodes.
3158
3159 // Make an operand with the bit pattern to load as float.
3160 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3161 immI_0Oper *op_zero = new immI_0Oper(0);
3162
3163 loadConLReplicatedNodesTuple loadConLNodes =
3164 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero,
3165 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp),
3166 ra_->get_reg_second(this), ra_->get_reg_first(this));
3167
3168 // Push new nodes.
3169 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); }
3170 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); }
3171 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); }
3172 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); }
3173
3174 assert(nodes->length() >= 1, "must have created at least 1 node");
3175 %}
3176
3177 // This enc_class is needed so that scheduler gets proper
3178 // input mapping for latency computation.
3179 enc_class enc_poll(immI dst, iRegLdst poll) %{
3180 // Fake operand dst needed for PPC scheduler.
3181 assert($dst$$constant == 0x0, "dst must be 0x0");
3182
3183 // Mark the code position where the load from the safepoint
3184 // polling page was emitted as relocInfo::poll_type.
3185 __ relocate(relocInfo::poll_type);
3186 __ load_from_polling_page($poll$$Register);
3187 %}
3188
3189 // A Java static call or a runtime call.
3190 //
3191 // Branch-and-link relative to a trampoline.
3192 // The trampoline loads the target address and does a long branch to there.
3193 // In case we call java, the trampoline branches to a interpreter_stub
3194 // which loads the inline cache and the real call target from the constant pool.
3195 //
3196 // This basically looks like this:
3197 //
3198 // >>>> consts -+ -+
3199 // | |- offset1
3200 // [call target1] | <-+
3201 // [IC cache] |- offset2
3202 // [call target2] <--+
3203 //
3204 // <<<< consts
3205 // >>>> insts
3206 //
3207 // bl offset16 -+ -+ ??? // How many bits available?
3208 // | |
3209 // <<<< insts | |
3210 // >>>> stubs | |
3211 // | |- trampoline_stub_Reloc
3212 // trampoline stub: | <-+
3213 // r2 = toc |
3214 // r2 = [r2 + offset1] | // Load call target1 from const section
3215 // mtctr r2 |
3216 // bctr |- static_stub_Reloc
3217 // comp_to_interp_stub: <---+
3218 // r1 = toc
3219 // ICreg = [r1 + IC_offset] // Load IC from const section
3220 // r1 = [r1 + offset2] // Load call target2 from const section
3221 // mtctr r1
3222 // bctr
3223 //
3224 // <<<< stubs
3225 //
3226 // The call instruction in the code either
3227 // - Branches directly to a compiled method if the offset is encodable in instruction.
3228 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3229 // - Branches to the compiled_to_interp stub if the target is interpreted.
3230 //
3231 // Further there are three relocations from the loads to the constants in
3232 // the constant section.
3233 //
3234 // Usage of r1 and r2 in the stubs allows to distinguish them.
3235 enc_class enc_java_static_call(method meth) %{
3236 address entry_point = (address)$meth$$method;
3237 address call_pc;
3238
3239 if (!_method) {
3240 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3241 call_pc = __ trampoline_call(AddressLiteral(entry_point, relocInfo::runtime_call_type));
3242 if (call_pc == nullptr) {
3243 ciEnv::current()->record_failure("CodeCache is full");
3244 return;
3245 }
3246 } else {
3247 int method_index = resolved_method_index(masm);
3248 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3249 : static_call_Relocation::spec(method_index);
3250 call_pc = __ trampoline_call(AddressLiteral(entry_point, rspec));
3251 if (call_pc == nullptr) {
3252 ciEnv::current()->record_failure("CodeCache is full");
3253 return;
3254 }
3255
3256 // Emit stub for static call
3257 address stub = CompiledDirectCall::emit_to_interp_stub(masm, call_pc);
3258 if (stub == nullptr) {
3259 ciEnv::current()->record_failure("CodeCache is full");
3260 return;
3261 }
3262 }
3263 __ post_call_nop();
3264 %}
3265
3266 // Compound version of call dynamic
3267 // Toc is only passed so that it can be used in ins_encode statement.
3268 // In the code we have to use $constanttablebase.
3269 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
3270 int start_offset = __ offset();
3271 int method_index = resolved_method_index(masm);
3272 bool scratch_emit = ra_ == nullptr;
3273 Register Rtoc = scratch_emit ? R2_TOC : $constanttablebase;
3274 bool success = __ ic_call(Rtoc, (address)$meth$$method, method_index, scratch_emit, true /*fixed_size*/);
3275 if (!success) {
3276 ciEnv::current()->record_failure("CodeCache is full");
3277 return;
3278 }
3279 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3280 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3281 __ post_call_nop();
3282 %}
3283
3284 // a runtime call
3285 enc_class enc_java_to_runtime_call (method meth) %{
3286 const address start_pc = __ pc();
3287
3288 #if defined(ABI_ELFv2)
3289 address entry= !($meth$$method) ? nullptr : (address)$meth$$method;
3290 __ call_c(entry, relocInfo::runtime_call_type);
3291 __ post_call_nop();
3292 #else
3293 // The function we're going to call.
3294 FunctionDescriptor fdtemp;
3295 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3296
3297 Register Rtoc = R12_scratch2;
3298 // Calculate the method's TOC.
3299 __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3300 // Put entry, env, toc into the constant pool, this needs up to 3 constant
3301 // pool entries; call_c_using_toc will optimize the call.
3302 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3303 if (!success) {
3304 ciEnv::current()->record_out_of_memory_failure();
3305 return;
3306 }
3307 __ post_call_nop();
3308 #endif
3309
3310 // Check the ret_addr_offset.
3311 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3312 "Fix constant in ret_addr_offset()");
3313 %}
3314
3315 // Move to ctr for leaf call.
3316 // This enc_class is needed so that scheduler gets proper
3317 // input mapping for latency computation.
3318 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3319 __ mtctr($src$$Register);
3320 %}
3321
3322 // Postalloc expand emitter for runtime leaf calls.
3323 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3324 loadConLNodesTuple loadConLNodes_Entry;
3325 #if defined(ABI_ELFv2)
3326 jlong entry_address = (jlong) this->entry_point();
3327 assert(entry_address, "need address here");
3328 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3329 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3330 #else
3331 // Get the struct that describes the function we are about to call.
3332 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3333 assert(fd, "need fd here");
3334 jlong entry_address = (jlong) fd->entry();
3335 // new nodes
3336 loadConLNodesTuple loadConLNodes_Env;
3337 loadConLNodesTuple loadConLNodes_Toc;
3338
3339 // Create nodes and operands for loading the entry point.
3340 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3341 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3342
3343
3344 // Create nodes and operands for loading the env pointer.
3345 if (fd->env() != nullptr) {
3346 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3347 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3348 } else {
3349 loadConLNodes_Env._large_hi = nullptr;
3350 loadConLNodes_Env._large_lo = nullptr;
3351 loadConLNodes_Env._small = nullptr;
3352 loadConLNodes_Env._last = new loadConL16Node();
3353 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3354 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3355 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3356 }
3357
3358 // Create nodes and operands for loading the Toc point.
3359 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3360 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3361 #endif // ABI_ELFv2
3362 // mtctr node
3363 MachNode *mtctr = new CallLeafDirect_mtctrNode();
3364
3365 assert(loadConLNodes_Entry._last != nullptr, "entry must exist");
3366 mtctr->add_req(nullptr, loadConLNodes_Entry._last);
3367
3368 mtctr->_opnds[0] = new iRegLdstOper();
3369 mtctr->_opnds[1] = new iRegLdstOper();
3370
3371 // call node
3372 MachCallLeafNode *call = new CallLeafDirectNode();
3373
3374 call->_opnds[0] = _opnds[0];
3375 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3376
3377 // Make the new call node look like the old one.
3378 call->_name = _name;
3379 call->_tf = _tf;
3380 call->_entry_point = _entry_point;
3381 call->_cnt = _cnt;
3382 call->_guaranteed_safepoint = false;
3383 call->_oop_map = _oop_map;
3384 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3385 call->_jvms = nullptr;
3386 call->_jvmadj = _jvmadj;
3387 call->_in_rms = _in_rms;
3388 call->_nesting = _nesting;
3389
3390 // New call needs all inputs of old call.
3391 // Req...
3392 for (uint i = 0; i < req(); ++i) {
3393 if (i != mach_constant_base_node_input()) {
3394 call->add_req(in(i));
3395 }
3396 }
3397
3398 // These must be reqired edges, as the registers are live up to
3399 // the call. Else the constants are handled as kills.
3400 call->add_req(mtctr);
3401 #if !defined(ABI_ELFv2)
3402 call->add_req(loadConLNodes_Env._last);
3403 call->add_req(loadConLNodes_Toc._last);
3404 #endif
3405
3406 // ...as well as prec
3407 for (uint i = req(); i < len(); ++i) {
3408 call->add_prec(in(i));
3409 }
3410
3411 // registers
3412 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3413
3414 // Insert the new nodes.
3415 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3416 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last);
3417 #if !defined(ABI_ELFv2)
3418 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi);
3419 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last);
3420 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi);
3421 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last);
3422 #endif
3423 nodes->push(mtctr);
3424 nodes->push(call);
3425 %}
3426 %}
3427
3428 //----------FRAME--------------------------------------------------------------
3429 // Definition of frame structure and management information.
3430
3431 frame %{
3432 // These two registers define part of the calling convention between
3433 // compiled code and the interpreter.
3434
3435 // Inline Cache Register or method for I2C.
3436 inline_cache_reg(R19); // R19_method
3437
3438 // Optional: name the operand used by cisc-spilling to access
3439 // [stack_pointer + offset].
3440 cisc_spilling_operand_name(indOffset);
3441
3442 // Number of stack slots consumed by a Monitor enter.
3443 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size));
3444
3445 // Compiled code's Frame Pointer.
3446 frame_pointer(R1); // R1_SP
3447
3448 stack_alignment(frame::alignment_in_bytes);
3449
3450 // Number of outgoing stack slots killed above the
3451 // out_preserve_stack_slots for calls to C. Supports the var-args
3452 // backing area for register parms.
3453 //
3454 varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3455
3456 // The after-PROLOG location of the return address. Location of
3457 // return address specifies a type (REG or STACK) and a number
3458 // representing the register number (i.e. - use a register name) or
3459 // stack slot.
3460 //
3461 // A: Link register is stored in stack slot ...
3462 // M: ... but it's in the caller's frame according to PPC-64 ABI.
3463 // J: Therefore, we make sure that the link register is also in R11_scratch1
3464 // at the end of the prolog.
3465 // B: We use R20, now.
3466 //return_addr(REG R20);
3467
3468 // G: After reading the comments made by all the luminaries on their
3469 // failure to tell the compiler where the return address really is,
3470 // I hardly dare to try myself. However, I'm convinced it's in slot
3471 // 4 what apparently works and saves us some spills.
3472 return_addr(STACK 4);
3473
3474 // Location of compiled Java return values. Same as C
3475 return_value %{
3476 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3477 (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0),
3478 "only return normal values");
3479 // enum names from opcodes.hpp
3480 static int typeToRegLo[Op_RegL+1] = {
3481 0, // Op_Node
3482 0, // Op_Set
3483 R3_num, // Op_RegN
3484 R3_num, // Op_RegI
3485 R3_num, // Op_RegP
3486 F1_num, // Op_RegF
3487 F1_num, // Op_RegD
3488 R3_num, // Op_RegL
3489 };
3490
3491 static int typeToRegHi[Op_RegL+1] = {
3492 0, // Op_Node
3493 0, // Op_Set
3494 OptoReg::Bad, // Op_RegN
3495 OptoReg::Bad, // Op_RegI
3496 R3_H_num, // Op_RegP
3497 OptoReg::Bad, // Op_RegF
3498 F1_H_num, // Op_RegD
3499 R3_H_num // Op_RegL
3500 };
3501
3502 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3503 %}
3504 %}
3505
3506
3507 //----------ATTRIBUTES---------------------------------------------------------
3508
3509 //----------Operand Attributes-------------------------------------------------
3510 op_attrib op_cost(1); // Required cost attribute.
3511
3512 //----------Instruction Attributes---------------------------------------------
3513
3514 // Cost attribute. required.
3515 ins_attrib ins_cost(DEFAULT_COST);
3516
3517 // Is this instruction a non-matching short branch variant of some
3518 // long branch? Not required.
3519 ins_attrib ins_short_branch(0);
3520
3521 ins_attrib ins_is_TrapBasedCheckNode(true);
3522
3523 // Number of constants.
3524 // This instruction uses the given number of constants
3525 // (optional attribute).
3526 // This is needed to determine in time whether the constant pool will
3527 // exceed 4000 entries. Before postalloc_expand the overall number of constants
3528 // is determined. It's also used to compute the constant pool size
3529 // in Output().
3530 ins_attrib ins_num_consts(0);
3531
3532 // Required alignment attribute (must be a power of 2) specifies the
3533 // alignment that some part of the instruction (not necessarily the
3534 // start) requires. If > 1, a compute_padding() function must be
3535 // provided for the instruction.
3536 ins_attrib ins_alignment(1);
3537
3538 // Enforce/prohibit rematerializations.
3539 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3540 // then rematerialization of that instruction is prohibited and the
3541 // instruction's value will be spilled if necessary.
3542 // Causes that MachNode::rematerialize() returns false.
3543 // - If an instruction is attributed with 'ins_should_rematerialize(true)'
3544 // then rematerialization should be enforced and a copy of the instruction
3545 // should be inserted if possible; rematerialization is not guaranteed.
3546 // Note: this may result in rematerializations in front of every use.
3547 // Causes that MachNode::rematerialize() can return true.
3548 // (optional attribute)
3549 ins_attrib ins_cannot_rematerialize(false);
3550 ins_attrib ins_should_rematerialize(false);
3551
3552 // Instruction is a nop.
3553 ins_attrib ins_is_nop(false);
3554
3555 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock).
3556 ins_attrib ins_use_mach_if_fast_lock_node(false);
3557
3558 // Field for the toc offset of a constant.
3559 //
3560 // This is needed if the toc offset is not encodable as an immediate in
3561 // the PPC load instruction. If so, the upper (hi) bits of the offset are
3562 // added to the toc, and from this a load with immediate is performed.
3563 // With postalloc expand, we get two nodes that require the same offset
3564 // but which don't know about each other. The offset is only known
3565 // when the constant is added to the constant pool during emitting.
3566 // It is generated in the 'hi'-node adding the upper bits, and saved
3567 // in this node. The 'lo'-node has a link to the 'hi'-node and reads
3568 // the offset from there when it gets encoded.
3569 ins_attrib ins_field_const_toc_offset(0);
3570 ins_attrib ins_field_const_toc_offset_hi_node(0);
3571
3572 // A field that can hold the instructions offset in the code buffer.
3573 // Set in the nodes emitter.
3574 ins_attrib ins_field_cbuf_insts_offset(-1);
3575
3576 // Fields for referencing a call's load-IC-node.
3577 // If the toc offset can not be encoded as an immediate in a load, we
3578 // use two nodes.
3579 ins_attrib ins_field_load_ic_hi_node(0);
3580 ins_attrib ins_field_load_ic_node(0);
3581
3582 // Whether this node is expanded during code emission into a sequence of
3583 // instructions and the first instruction can perform an implicit null check.
3584 ins_attrib ins_is_late_expanded_null_check_candidate(false);
3585
3586 //----------OPERANDS-----------------------------------------------------------
3587 // Operand definitions must precede instruction definitions for correct
3588 // parsing in the ADLC because operands constitute user defined types
3589 // which are used in instruction definitions.
3590 //
3591 // Formats are generated automatically for constants and base registers.
3592
3593 operand vecX() %{
3594 constraint(ALLOC_IN_RC(v_reg));
3595 match(VecX);
3596
3597 format %{ %}
3598 interface(REG_INTER);
3599 %}
3600
3601 //----------Simple Operands----------------------------------------------------
3602 // Immediate Operands
3603
3604 // Integer Immediate: 32-bit
3605 operand immI() %{
3606 match(ConI);
3607 op_cost(40);
3608 format %{ %}
3609 interface(CONST_INTER);
3610 %}
3611
3612 operand immI8() %{
3613 predicate(Assembler::is_simm(n->get_int(), 8));
3614 op_cost(0);
3615 match(ConI);
3616 format %{ %}
3617 interface(CONST_INTER);
3618 %}
3619
3620 // Integer Immediate: 16-bit
3621 operand immI16() %{
3622 predicate(Assembler::is_simm(n->get_int(), 16));
3623 op_cost(0);
3624 match(ConI);
3625 format %{ %}
3626 interface(CONST_INTER);
3627 %}
3628
3629 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000.
3630 operand immIhi16() %{
3631 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0));
3632 match(ConI);
3633 op_cost(0);
3634 format %{ %}
3635 interface(CONST_INTER);
3636 %}
3637
3638 // Integer Immediate: 32-bit immediate for prefixed addi and load/store.
3639 operand immI32() %{
3640 predicate(PowerArchitecturePPC64 >= 10);
3641 op_cost(0);
3642 match(ConI);
3643 format %{ %}
3644 interface(CONST_INTER);
3645 %}
3646
3647 operand immInegpow2() %{
3648 predicate(is_power_of_2(-(juint)(n->get_int())));
3649 match(ConI);
3650 op_cost(0);
3651 format %{ %}
3652 interface(CONST_INTER);
3653 %}
3654
3655 operand immIpow2minus1() %{
3656 predicate(is_power_of_2((juint)(n->get_int()) + 1u));
3657 match(ConI);
3658 op_cost(0);
3659 format %{ %}
3660 interface(CONST_INTER);
3661 %}
3662
3663 operand immIpowerOf2() %{
3664 predicate(is_power_of_2((juint)(n->get_int())));
3665 match(ConI);
3666 op_cost(0);
3667 format %{ %}
3668 interface(CONST_INTER);
3669 %}
3670
3671 // Unsigned Integer Immediate: the values 0-31
3672 operand uimmI5() %{
3673 predicate(Assembler::is_uimm(n->get_int(), 5));
3674 match(ConI);
3675 op_cost(0);
3676 format %{ %}
3677 interface(CONST_INTER);
3678 %}
3679
3680 // Unsigned Integer Immediate: 6-bit
3681 operand uimmI6() %{
3682 predicate(Assembler::is_uimm(n->get_int(), 6));
3683 match(ConI);
3684 op_cost(0);
3685 format %{ %}
3686 interface(CONST_INTER);
3687 %}
3688
3689 // Unsigned Integer Immediate: 6-bit int, greater than 32
3690 operand uimmI6_ge32() %{
3691 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32);
3692 match(ConI);
3693 op_cost(0);
3694 format %{ %}
3695 interface(CONST_INTER);
3696 %}
3697
3698 // Unsigned Integer Immediate: 15-bit
3699 operand uimmI15() %{
3700 predicate(Assembler::is_uimm(n->get_int(), 15));
3701 match(ConI);
3702 op_cost(0);
3703 format %{ %}
3704 interface(CONST_INTER);
3705 %}
3706
3707 // Unsigned Integer Immediate: 16-bit
3708 operand uimmI16() %{
3709 predicate(Assembler::is_uimm(n->get_int(), 16));
3710 match(ConI);
3711 op_cost(0);
3712 format %{ %}
3713 interface(CONST_INTER);
3714 %}
3715
3716 // constant 'int 0'.
3717 operand immI_0() %{
3718 predicate(n->get_int() == 0);
3719 match(ConI);
3720 op_cost(0);
3721 format %{ %}
3722 interface(CONST_INTER);
3723 %}
3724
3725 // constant 'int 1'.
3726 operand immI_1() %{
3727 predicate(n->get_int() == 1);
3728 match(ConI);
3729 op_cost(0);
3730 format %{ %}
3731 interface(CONST_INTER);
3732 %}
3733
3734 // constant 'int -1'.
3735 operand immI_minus1() %{
3736 predicate(n->get_int() == -1);
3737 match(ConI);
3738 op_cost(0);
3739 format %{ %}
3740 interface(CONST_INTER);
3741 %}
3742
3743 // int value 16.
3744 operand immI_16() %{
3745 predicate(n->get_int() == 16);
3746 match(ConI);
3747 op_cost(0);
3748 format %{ %}
3749 interface(CONST_INTER);
3750 %}
3751
3752 // int value 24.
3753 operand immI_24() %{
3754 predicate(n->get_int() == 24);
3755 match(ConI);
3756 op_cost(0);
3757 format %{ %}
3758 interface(CONST_INTER);
3759 %}
3760
3761 // Compressed oops constants
3762 // Pointer Immediate
3763 operand immN() %{
3764 match(ConN);
3765
3766 op_cost(10);
3767 format %{ %}
3768 interface(CONST_INTER);
3769 %}
3770
3771 // nullptr Pointer Immediate
3772 operand immN_0() %{
3773 predicate(n->get_narrowcon() == 0);
3774 match(ConN);
3775
3776 op_cost(0);
3777 format %{ %}
3778 interface(CONST_INTER);
3779 %}
3780
3781 // Compressed klass constants
3782 operand immNKlass() %{
3783 match(ConNKlass);
3784
3785 op_cost(0);
3786 format %{ %}
3787 interface(CONST_INTER);
3788 %}
3789
3790 // This operand can be used to avoid matching of an instruct
3791 // with chain rule.
3792 operand immNKlass_NM() %{
3793 match(ConNKlass);
3794 predicate(false);
3795 op_cost(0);
3796 format %{ %}
3797 interface(CONST_INTER);
3798 %}
3799
3800 // Pointer Immediate: 64-bit
3801 operand immP() %{
3802 match(ConP);
3803 op_cost(0);
3804 format %{ %}
3805 interface(CONST_INTER);
3806 %}
3807
3808 // Operand to avoid match of loadConP.
3809 // This operand can be used to avoid matching of an instruct
3810 // with chain rule.
3811 operand immP_NM() %{
3812 match(ConP);
3813 predicate(false);
3814 op_cost(0);
3815 format %{ %}
3816 interface(CONST_INTER);
3817 %}
3818
3819 // constant 'pointer 0'.
3820 operand immP_0() %{
3821 predicate(n->get_ptr() == 0);
3822 match(ConP);
3823 op_cost(0);
3824 format %{ %}
3825 interface(CONST_INTER);
3826 %}
3827
3828 // pointer 0x0 or 0x1
3829 operand immP_0or1() %{
3830 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
3831 match(ConP);
3832 op_cost(0);
3833 format %{ %}
3834 interface(CONST_INTER);
3835 %}
3836
3837 operand immL() %{
3838 match(ConL);
3839 op_cost(40);
3840 format %{ %}
3841 interface(CONST_INTER);
3842 %}
3843
3844 operand immLmax30() %{
3845 predicate((n->get_long() <= 30));
3846 match(ConL);
3847 op_cost(0);
3848 format %{ %}
3849 interface(CONST_INTER);
3850 %}
3851
3852 // Long Immediate: 16-bit
3853 operand immL16() %{
3854 predicate(Assembler::is_simm(n->get_long(), 16));
3855 match(ConL);
3856 op_cost(0);
3857 format %{ %}
3858 interface(CONST_INTER);
3859 %}
3860
3861 // Long Immediate: 16-bit, 4-aligned
3862 operand immL16Alg4() %{
3863 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
3864 match(ConL);
3865 op_cost(0);
3866 format %{ %}
3867 interface(CONST_INTER);
3868 %}
3869
3870 // Long Immediate: 16-bit, 16-aligned
3871 operand immL16Alg16() %{
3872 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0xf) == 0));
3873 match(ConL);
3874 op_cost(0);
3875 format %{ %}
3876 interface(CONST_INTER);
3877 %}
3878
3879 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
3880 operand immL32hi16() %{
3881 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L));
3882 match(ConL);
3883 op_cost(0);
3884 format %{ %}
3885 interface(CONST_INTER);
3886 %}
3887
3888 // Long Immediate: 32-bit
3889 operand immL32() %{
3890 predicate(Assembler::is_simm(n->get_long(), 32));
3891 match(ConL);
3892 op_cost(0);
3893 format %{ %}
3894 interface(CONST_INTER);
3895 %}
3896
3897 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store.
3898 operand immL34() %{
3899 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34));
3900 match(ConL);
3901 op_cost(0);
3902 format %{ %}
3903 interface(CONST_INTER);
3904 %}
3905
3906 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000.
3907 operand immLhighest16() %{
3908 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L);
3909 match(ConL);
3910 op_cost(0);
3911 format %{ %}
3912 interface(CONST_INTER);
3913 %}
3914
3915 operand immLnegpow2() %{
3916 predicate(is_power_of_2(-(julong)(n->get_long())));
3917 match(ConL);
3918 op_cost(0);
3919 format %{ %}
3920 interface(CONST_INTER);
3921 %}
3922
3923 operand immLpow2minus1() %{
3924 predicate(is_power_of_2((julong)(n->get_long()) + 1ull));
3925 match(ConL);
3926 op_cost(0);
3927 format %{ %}
3928 interface(CONST_INTER);
3929 %}
3930
3931 // constant 'long 0'.
3932 operand immL_0() %{
3933 predicate(n->get_long() == 0L);
3934 match(ConL);
3935 op_cost(0);
3936 format %{ %}
3937 interface(CONST_INTER);
3938 %}
3939
3940 // constat ' long -1'.
3941 operand immL_minus1() %{
3942 predicate(n->get_long() == -1L);
3943 match(ConL);
3944 op_cost(0);
3945 format %{ %}
3946 interface(CONST_INTER);
3947 %}
3948
3949 // Long Immediate: low 32-bit mask
3950 operand immL_32bits() %{
3951 predicate(n->get_long() == 0xFFFFFFFFL);
3952 match(ConL);
3953 op_cost(0);
3954 format %{ %}
3955 interface(CONST_INTER);
3956 %}
3957
3958 // Unsigned Long Immediate: 16-bit
3959 operand uimmL16() %{
3960 predicate(Assembler::is_uimm(n->get_long(), 16));
3961 match(ConL);
3962 op_cost(0);
3963 format %{ %}
3964 interface(CONST_INTER);
3965 %}
3966
3967 // Float Immediate
3968 operand immF() %{
3969 match(ConF);
3970 op_cost(40);
3971 format %{ %}
3972 interface(CONST_INTER);
3973 %}
3974
3975 // Float Immediate: +0.0f.
3976 operand immF_0() %{
3977 predicate(jint_cast(n->getf()) == 0);
3978 match(ConF);
3979
3980 op_cost(0);
3981 format %{ %}
3982 interface(CONST_INTER);
3983 %}
3984
3985 // Double Immediate
3986 operand immD() %{
3987 match(ConD);
3988 op_cost(40);
3989 format %{ %}
3990 interface(CONST_INTER);
3991 %}
3992
3993 // Double Immediate: +0.0d.
3994 operand immD_0() %{
3995 predicate(jlong_cast(n->getd()) == 0);
3996 match(ConD);
3997
3998 op_cost(0);
3999 format %{ %}
4000 interface(CONST_INTER);
4001 %}
4002
4003 // Integer Register Operands
4004 // Integer Destination Register
4005 // See definition of reg_class bits32_reg_rw.
4006 operand iRegIdst() %{
4007 constraint(ALLOC_IN_RC(bits32_reg_rw));
4008 match(RegI);
4009 match(rscratch1RegI);
4010 match(rscratch2RegI);
4011 match(rarg1RegI);
4012 match(rarg2RegI);
4013 match(rarg3RegI);
4014 match(rarg4RegI);
4015 format %{ %}
4016 interface(REG_INTER);
4017 %}
4018
4019 // Integer Source Register
4020 // See definition of reg_class bits32_reg_ro.
4021 operand iRegIsrc() %{
4022 constraint(ALLOC_IN_RC(bits32_reg_ro));
4023 match(RegI);
4024 match(rscratch1RegI);
4025 match(rscratch2RegI);
4026 match(rarg1RegI);
4027 match(rarg2RegI);
4028 match(rarg3RegI);
4029 match(rarg4RegI);
4030 format %{ %}
4031 interface(REG_INTER);
4032 %}
4033
4034 operand rscratch1RegI() %{
4035 constraint(ALLOC_IN_RC(rscratch1_bits32_reg));
4036 match(iRegIdst);
4037 format %{ %}
4038 interface(REG_INTER);
4039 %}
4040
4041 operand rscratch2RegI() %{
4042 constraint(ALLOC_IN_RC(rscratch2_bits32_reg));
4043 match(iRegIdst);
4044 format %{ %}
4045 interface(REG_INTER);
4046 %}
4047
4048 operand rarg1RegI() %{
4049 constraint(ALLOC_IN_RC(rarg1_bits32_reg));
4050 match(iRegIdst);
4051 format %{ %}
4052 interface(REG_INTER);
4053 %}
4054
4055 operand rarg2RegI() %{
4056 constraint(ALLOC_IN_RC(rarg2_bits32_reg));
4057 match(iRegIdst);
4058 format %{ %}
4059 interface(REG_INTER);
4060 %}
4061
4062 operand rarg3RegI() %{
4063 constraint(ALLOC_IN_RC(rarg3_bits32_reg));
4064 match(iRegIdst);
4065 format %{ %}
4066 interface(REG_INTER);
4067 %}
4068
4069 operand rarg4RegI() %{
4070 constraint(ALLOC_IN_RC(rarg4_bits32_reg));
4071 match(iRegIdst);
4072 format %{ %}
4073 interface(REG_INTER);
4074 %}
4075
4076 operand rarg1RegL() %{
4077 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4078 match(iRegLdst);
4079 format %{ %}
4080 interface(REG_INTER);
4081 %}
4082
4083 // Pointer Destination Register
4084 // See definition of reg_class bits64_reg_rw.
4085 operand iRegPdst() %{
4086 constraint(ALLOC_IN_RC(bits64_reg_rw));
4087 match(RegP);
4088 match(rscratch1RegP);
4089 match(rscratch2RegP);
4090 match(rarg1RegP);
4091 match(rarg2RegP);
4092 match(rarg3RegP);
4093 match(rarg4RegP);
4094 format %{ %}
4095 interface(REG_INTER);
4096 %}
4097
4098 // Pointer Destination Register
4099 // Operand not using r11 and r12 (killed in epilog).
4100 operand iRegPdstNoScratch() %{
4101 constraint(ALLOC_IN_RC(bits64_reg_leaf_call));
4102 match(RegP);
4103 match(rarg1RegP);
4104 match(rarg2RegP);
4105 match(rarg3RegP);
4106 match(rarg4RegP);
4107 format %{ %}
4108 interface(REG_INTER);
4109 %}
4110
4111 // Pointer Source Register
4112 // See definition of reg_class bits64_reg_ro.
4113 operand iRegPsrc() %{
4114 constraint(ALLOC_IN_RC(bits64_reg_ro));
4115 match(RegP);
4116 match(iRegPdst);
4117 match(rscratch1RegP);
4118 match(rscratch2RegP);
4119 match(rarg1RegP);
4120 match(rarg2RegP);
4121 match(rarg3RegP);
4122 match(rarg4RegP);
4123 match(rarg5RegP);
4124 match(rarg6RegP);
4125 match(threadRegP);
4126 format %{ %}
4127 interface(REG_INTER);
4128 %}
4129
4130 // Thread operand.
4131 operand threadRegP() %{
4132 constraint(ALLOC_IN_RC(thread_bits64_reg));
4133 match(iRegPdst);
4134 format %{ "R16" %}
4135 interface(REG_INTER);
4136 %}
4137
4138 operand rscratch1RegP() %{
4139 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4140 match(iRegPdst);
4141 format %{ "R11" %}
4142 interface(REG_INTER);
4143 %}
4144
4145 operand rscratch2RegP() %{
4146 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4147 match(iRegPdst);
4148 format %{ %}
4149 interface(REG_INTER);
4150 %}
4151
4152 operand rarg1RegP() %{
4153 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4154 match(iRegPdst);
4155 format %{ %}
4156 interface(REG_INTER);
4157 %}
4158
4159 operand rarg2RegP() %{
4160 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4161 match(iRegPdst);
4162 format %{ %}
4163 interface(REG_INTER);
4164 %}
4165
4166 operand rarg3RegP() %{
4167 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4168 match(iRegPdst);
4169 format %{ %}
4170 interface(REG_INTER);
4171 %}
4172
4173 operand rarg4RegP() %{
4174 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4175 match(iRegPdst);
4176 format %{ %}
4177 interface(REG_INTER);
4178 %}
4179
4180 operand rarg5RegP() %{
4181 constraint(ALLOC_IN_RC(rarg5_bits64_reg));
4182 match(iRegPdst);
4183 format %{ %}
4184 interface(REG_INTER);
4185 %}
4186
4187 operand rarg6RegP() %{
4188 constraint(ALLOC_IN_RC(rarg6_bits64_reg));
4189 match(iRegPdst);
4190 format %{ %}
4191 interface(REG_INTER);
4192 %}
4193
4194 operand iRegNsrc() %{
4195 constraint(ALLOC_IN_RC(bits32_reg_ro));
4196 match(RegN);
4197 match(iRegNdst);
4198
4199 format %{ %}
4200 interface(REG_INTER);
4201 %}
4202
4203 operand iRegNdst() %{
4204 constraint(ALLOC_IN_RC(bits32_reg_rw));
4205 match(RegN);
4206
4207 format %{ %}
4208 interface(REG_INTER);
4209 %}
4210
4211 // Long Destination Register
4212 // See definition of reg_class bits64_reg_rw.
4213 operand iRegLdst() %{
4214 constraint(ALLOC_IN_RC(bits64_reg_rw));
4215 match(RegL);
4216 match(rscratch1RegL);
4217 match(rscratch2RegL);
4218 format %{ %}
4219 interface(REG_INTER);
4220 %}
4221
4222 // Long Source Register
4223 // See definition of reg_class bits64_reg_ro.
4224 operand iRegLsrc() %{
4225 constraint(ALLOC_IN_RC(bits64_reg_ro));
4226 match(RegL);
4227 match(iRegLdst);
4228 match(rscratch1RegL);
4229 match(rscratch2RegL);
4230 format %{ %}
4231 interface(REG_INTER);
4232 %}
4233
4234 // Special operand for ConvL2I.
4235 operand iRegL2Isrc(iRegLsrc reg) %{
4236 constraint(ALLOC_IN_RC(bits64_reg_ro));
4237 match(ConvL2I reg);
4238 format %{ "ConvL2I($reg)" %}
4239 interface(REG_INTER)
4240 %}
4241
4242 operand rscratch1RegL() %{
4243 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4244 match(RegL);
4245 format %{ %}
4246 interface(REG_INTER);
4247 %}
4248
4249 operand rscratch2RegL() %{
4250 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4251 match(RegL);
4252 format %{ %}
4253 interface(REG_INTER);
4254 %}
4255
4256 // Condition Code Flag Registers
4257 operand flagsReg() %{
4258 constraint(ALLOC_IN_RC(int_flags));
4259 match(RegFlags);
4260 format %{ %}
4261 interface(REG_INTER);
4262 %}
4263
4264 operand flagsRegSrc() %{
4265 constraint(ALLOC_IN_RC(int_flags_ro));
4266 match(RegFlags);
4267 match(flagsReg);
4268 match(flagsRegCR0);
4269 format %{ %}
4270 interface(REG_INTER);
4271 %}
4272
4273 // Condition Code Flag Register CR0
4274 operand flagsRegCR0() %{
4275 constraint(ALLOC_IN_RC(int_flags_CR0));
4276 match(RegFlags);
4277 format %{ "CR0" %}
4278 interface(REG_INTER);
4279 %}
4280
4281 operand flagsRegCR1() %{
4282 constraint(ALLOC_IN_RC(int_flags_CR1));
4283 match(RegFlags);
4284 format %{ "CR1" %}
4285 interface(REG_INTER);
4286 %}
4287
4288 operand flagsRegCR6() %{
4289 constraint(ALLOC_IN_RC(int_flags_CR6));
4290 match(RegFlags);
4291 format %{ "CR6" %}
4292 interface(REG_INTER);
4293 %}
4294
4295 operand regCTR() %{
4296 constraint(ALLOC_IN_RC(ctr_reg));
4297 // RegFlags should work. Introducing a RegSpecial type would cause a
4298 // lot of changes.
4299 match(RegFlags);
4300 format %{"SR_CTR" %}
4301 interface(REG_INTER);
4302 %}
4303
4304 operand regD() %{
4305 constraint(ALLOC_IN_RC(dbl_reg));
4306 match(RegD);
4307 format %{ %}
4308 interface(REG_INTER);
4309 %}
4310
4311 operand regF() %{
4312 constraint(ALLOC_IN_RC(flt_reg));
4313 match(RegF);
4314 format %{ %}
4315 interface(REG_INTER);
4316 %}
4317
4318 // Special Registers
4319
4320 // Method Register
4321 operand inline_cache_regP(iRegPdst reg) %{
4322 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg
4323 match(reg);
4324 format %{ %}
4325 interface(REG_INTER);
4326 %}
4327
4328 // Operands to remove register moves in unscaled mode.
4329 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4330 operand iRegP2N(iRegPsrc reg) %{
4331 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0);
4332 constraint(ALLOC_IN_RC(bits64_reg_ro));
4333 match(EncodeP reg);
4334 format %{ "$reg" %}
4335 interface(REG_INTER)
4336 %}
4337
4338 operand iRegN2P(iRegNsrc reg) %{
4339 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4340 constraint(ALLOC_IN_RC(bits32_reg_ro));
4341 match(DecodeN reg);
4342 format %{ "$reg" %}
4343 interface(REG_INTER)
4344 %}
4345
4346 operand iRegN2P_klass(iRegNsrc reg) %{
4347 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4348 constraint(ALLOC_IN_RC(bits32_reg_ro));
4349 match(DecodeNKlass reg);
4350 format %{ "$reg" %}
4351 interface(REG_INTER)
4352 %}
4353
4354 //----------Complex Operands---------------------------------------------------
4355 // Indirect Memory Reference
4356 operand indirect(iRegPsrc reg) %{
4357 constraint(ALLOC_IN_RC(bits64_reg_ro));
4358 match(reg);
4359 op_cost(100);
4360 format %{ "[$reg]" %}
4361 interface(MEMORY_INTER) %{
4362 base($reg);
4363 index(0x0);
4364 scale(0x0);
4365 disp(0x0);
4366 %}
4367 %}
4368
4369 // Indirect with Offset
4370 operand indOffset16(iRegPsrc reg, immL16 offset) %{
4371 constraint(ALLOC_IN_RC(bits64_reg_ro));
4372 match(AddP reg offset);
4373 op_cost(100);
4374 format %{ "[$reg + $offset]" %}
4375 interface(MEMORY_INTER) %{
4376 base($reg);
4377 index(0x0);
4378 scale(0x0);
4379 disp($offset);
4380 %}
4381 %}
4382
4383 // Indirect with 4-aligned Offset
4384 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{
4385 constraint(ALLOC_IN_RC(bits64_reg_ro));
4386 match(AddP reg offset);
4387 op_cost(100);
4388 format %{ "[$reg + $offset]" %}
4389 interface(MEMORY_INTER) %{
4390 base($reg);
4391 index(0x0);
4392 scale(0x0);
4393 disp($offset);
4394 %}
4395 %}
4396
4397 // Indirect with 16-aligned Offset
4398 operand indOffset16Alg16(iRegPsrc reg, immL16Alg16 offset) %{
4399 constraint(ALLOC_IN_RC(bits64_reg_ro));
4400 match(AddP reg offset);
4401 op_cost(100);
4402 format %{ "[$reg + $offset]" %}
4403 interface(MEMORY_INTER) %{
4404 base($reg);
4405 index(0x0);
4406 scale(0x0);
4407 disp($offset);
4408 %}
4409 %}
4410
4411 //----------Complex Operands for Compressed OOPs-------------------------------
4412 // Compressed OOPs with narrow_oop_shift == 0.
4413
4414 // Indirect Memory Reference, compressed OOP
4415 operand indirectNarrow(iRegNsrc reg) %{
4416 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4417 constraint(ALLOC_IN_RC(bits64_reg_ro));
4418 match(DecodeN reg);
4419 op_cost(100);
4420 format %{ "[$reg]" %}
4421 interface(MEMORY_INTER) %{
4422 base($reg);
4423 index(0x0);
4424 scale(0x0);
4425 disp(0x0);
4426 %}
4427 %}
4428
4429 operand indirectNarrow_klass(iRegNsrc reg) %{
4430 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4431 constraint(ALLOC_IN_RC(bits64_reg_ro));
4432 match(DecodeNKlass reg);
4433 op_cost(100);
4434 format %{ "[$reg]" %}
4435 interface(MEMORY_INTER) %{
4436 base($reg);
4437 index(0x0);
4438 scale(0x0);
4439 disp(0x0);
4440 %}
4441 %}
4442
4443 // Indirect with Offset, compressed OOP
4444 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4445 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4446 constraint(ALLOC_IN_RC(bits64_reg_ro));
4447 match(AddP (DecodeN reg) offset);
4448 op_cost(100);
4449 format %{ "[$reg + $offset]" %}
4450 interface(MEMORY_INTER) %{
4451 base($reg);
4452 index(0x0);
4453 scale(0x0);
4454 disp($offset);
4455 %}
4456 %}
4457
4458 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4459 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4460 constraint(ALLOC_IN_RC(bits64_reg_ro));
4461 match(AddP (DecodeNKlass reg) offset);
4462 op_cost(100);
4463 format %{ "[$reg + $offset]" %}
4464 interface(MEMORY_INTER) %{
4465 base($reg);
4466 index(0x0);
4467 scale(0x0);
4468 disp($offset);
4469 %}
4470 %}
4471
4472 // Indirect with 4-aligned Offset, compressed OOP
4473 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4474 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4475 constraint(ALLOC_IN_RC(bits64_reg_ro));
4476 match(AddP (DecodeN reg) offset);
4477 op_cost(100);
4478 format %{ "[$reg + $offset]" %}
4479 interface(MEMORY_INTER) %{
4480 base($reg);
4481 index(0x0);
4482 scale(0x0);
4483 disp($offset);
4484 %}
4485 %}
4486
4487 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4488 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0);
4489 constraint(ALLOC_IN_RC(bits64_reg_ro));
4490 match(AddP (DecodeNKlass reg) offset);
4491 op_cost(100);
4492 format %{ "[$reg + $offset]" %}
4493 interface(MEMORY_INTER) %{
4494 base($reg);
4495 index(0x0);
4496 scale(0x0);
4497 disp($offset);
4498 %}
4499 %}
4500
4501 //----------Special Memory Operands--------------------------------------------
4502 // Stack Slot Operand
4503 //
4504 // This operand is used for loading and storing temporary values on
4505 // the stack where a match requires a value to flow through memory.
4506 operand stackSlotI(sRegI reg) %{
4507 constraint(ALLOC_IN_RC(stack_slots));
4508 op_cost(100);
4509 //match(RegI);
4510 format %{ "[sp+$reg]" %}
4511 interface(MEMORY_INTER) %{
4512 base(0x1); // R1_SP
4513 index(0x0);
4514 scale(0x0);
4515 disp($reg); // Stack Offset
4516 %}
4517 %}
4518
4519 operand stackSlotL(sRegL reg) %{
4520 constraint(ALLOC_IN_RC(stack_slots));
4521 op_cost(100);
4522 //match(RegL);
4523 format %{ "[sp+$reg]" %}
4524 interface(MEMORY_INTER) %{
4525 base(0x1); // R1_SP
4526 index(0x0);
4527 scale(0x0);
4528 disp($reg); // Stack Offset
4529 %}
4530 %}
4531
4532 operand stackSlotP(sRegP reg) %{
4533 constraint(ALLOC_IN_RC(stack_slots));
4534 op_cost(100);
4535 //match(RegP);
4536 format %{ "[sp+$reg]" %}
4537 interface(MEMORY_INTER) %{
4538 base(0x1); // R1_SP
4539 index(0x0);
4540 scale(0x0);
4541 disp($reg); // Stack Offset
4542 %}
4543 %}
4544
4545 operand stackSlotF(sRegF reg) %{
4546 constraint(ALLOC_IN_RC(stack_slots));
4547 op_cost(100);
4548 //match(RegF);
4549 format %{ "[sp+$reg]" %}
4550 interface(MEMORY_INTER) %{
4551 base(0x1); // R1_SP
4552 index(0x0);
4553 scale(0x0);
4554 disp($reg); // Stack Offset
4555 %}
4556 %}
4557
4558 operand stackSlotD(sRegD reg) %{
4559 constraint(ALLOC_IN_RC(stack_slots));
4560 op_cost(100);
4561 //match(RegD);
4562 format %{ "[sp+$reg]" %}
4563 interface(MEMORY_INTER) %{
4564 base(0x1); // R1_SP
4565 index(0x0);
4566 scale(0x0);
4567 disp($reg); // Stack Offset
4568 %}
4569 %}
4570
4571 // Operands for expressing Control Flow
4572 // NOTE: Label is a predefined operand which should not be redefined in
4573 // the AD file. It is generically handled within the ADLC.
4574
4575 //----------Conditional Branch Operands----------------------------------------
4576 // Comparison Op
4577 //
4578 // This is the operation of the comparison, and is limited to the
4579 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE
4580 // (!=).
4581 //
4582 // Other attributes of the comparison, such as unsignedness, are specified
4583 // by the comparison instruction that sets a condition code flags register.
4584 // That result is represented by a flags operand whose subtype is appropriate
4585 // to the unsignedness (etc.) of the comparison.
4586 //
4587 // Later, the instruction which matches both the Comparison Op (a Bool) and
4588 // the flags (produced by the Cmp) specifies the coding of the comparison op
4589 // by matching a specific subtype of Bool operand below.
4590
4591 // When used for floating point comparisons: unordered same as less.
4592 operand cmpOp() %{
4593 match(Bool);
4594 format %{ "" %}
4595 interface(COND_INTER) %{
4596 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'.
4597 // BO & BI
4598 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4599 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4600 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4601 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4602 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4603 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4604 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4605 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4606 %}
4607 %}
4608
4609 //----------OPERAND CLASSES----------------------------------------------------
4610 // Operand Classes are groups of operands that are used to simplify
4611 // instruction definitions by not requiring the AD writer to specify
4612 // separate instructions for every form of operand when the
4613 // instruction accepts multiple operand types with the same basic
4614 // encoding and format. The classic case of this is memory operands.
4615 // Indirect is not included since its use is limited to Compare & Swap.
4616
4617 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4618 // Memory operand where offsets are 4-aligned. Required for ld, std.
4619 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4620 opclass memoryAlg16(indirect, indOffset16Alg16);
4621 opclass indirectMemory(indirect, indirectNarrow);
4622
4623 // Special opclass for I and ConvL2I.
4624 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4625
4626 // Operand classes to match encode and decode. iRegN_P2N is only used
4627 // for storeN. I have never seen an encode node elsewhere.
4628 opclass iRegN_P2N(iRegNsrc, iRegP2N);
4629 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4630
4631 //----------PIPELINE-----------------------------------------------------------
4632
4633 pipeline %{
4634
4635 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4636 // J. Res. & Dev., No. 1, Jan. 2002.
4637
4638 //----------ATTRIBUTES---------------------------------------------------------
4639 attributes %{
4640
4641 // Power4 instructions are of fixed length.
4642 fixed_size_instructions;
4643
4644 // TODO: if `bundle' means number of instructions fetched
4645 // per cycle, this is 8. If `bundle' means Power4 `group', that is
4646 // max instructions issued per cycle, this is 5.
4647 max_instructions_per_bundle = 8;
4648
4649 // A Power4 instruction is 4 bytes long.
4650 instruction_unit_size = 4;
4651
4652 // The Power4 processor fetches 64 bytes...
4653 instruction_fetch_unit_size = 64;
4654
4655 // ...in one line
4656 instruction_fetch_units = 1
4657 %}
4658
4659 //----------RESOURCES----------------------------------------------------------
4660 // Resources are the functional units available to the machine
4661 resources(
4662 PPC_BR, // branch unit
4663 PPC_CR, // condition unit
4664 PPC_FX1, // integer arithmetic unit 1
4665 PPC_FX2, // integer arithmetic unit 2
4666 PPC_LDST1, // load/store unit 1
4667 PPC_LDST2, // load/store unit 2
4668 PPC_FP1, // float arithmetic unit 1
4669 PPC_FP2, // float arithmetic unit 2
4670 PPC_LDST = PPC_LDST1 | PPC_LDST2,
4671 PPC_FX = PPC_FX1 | PPC_FX2,
4672 PPC_FP = PPC_FP1 | PPC_FP2
4673 );
4674
4675 //----------PIPELINE DESCRIPTION-----------------------------------------------
4676 // Pipeline Description specifies the stages in the machine's pipeline
4677 pipe_desc(
4678 // Power4 longest pipeline path
4679 PPC_IF, // instruction fetch
4680 PPC_IC,
4681 //PPC_BP, // branch prediction
4682 PPC_D0, // decode
4683 PPC_D1, // decode
4684 PPC_D2, // decode
4685 PPC_D3, // decode
4686 PPC_Xfer1,
4687 PPC_GD, // group definition
4688 PPC_MP, // map
4689 PPC_ISS, // issue
4690 PPC_RF, // resource fetch
4691 PPC_EX1, // execute (all units)
4692 PPC_EX2, // execute (FP, LDST)
4693 PPC_EX3, // execute (FP, LDST)
4694 PPC_EX4, // execute (FP)
4695 PPC_EX5, // execute (FP)
4696 PPC_EX6, // execute (FP)
4697 PPC_WB, // write back
4698 PPC_Xfer2,
4699 PPC_CP
4700 );
4701
4702 //----------PIPELINE CLASSES---------------------------------------------------
4703 // Pipeline Classes describe the stages in which input and output are
4704 // referenced by the hardware pipeline.
4705
4706 // Simple pipeline classes.
4707
4708 // Default pipeline class.
4709 pipe_class pipe_class_default() %{
4710 single_instruction;
4711 fixed_latency(2);
4712 %}
4713
4714 // Pipeline class for empty instructions.
4715 pipe_class pipe_class_empty() %{
4716 single_instruction;
4717 fixed_latency(0);
4718 %}
4719
4720 // Pipeline class for compares.
4721 pipe_class pipe_class_compare() %{
4722 single_instruction;
4723 fixed_latency(16);
4724 %}
4725
4726 // Pipeline class for traps.
4727 pipe_class pipe_class_trap() %{
4728 single_instruction;
4729 fixed_latency(100);
4730 %}
4731
4732 // Pipeline class for memory operations.
4733 pipe_class pipe_class_memory() %{
4734 single_instruction;
4735 fixed_latency(16);
4736 %}
4737
4738 // Pipeline class for call.
4739 pipe_class pipe_class_call() %{
4740 single_instruction;
4741 fixed_latency(100);
4742 %}
4743
4744 // Define the class for the Nop node.
4745 define %{
4746 MachNop = pipe_class_default;
4747 %}
4748
4749 %}
4750
4751 //----------INSTRUCTIONS-------------------------------------------------------
4752
4753 // Naming of instructions:
4754 // opA_operB / opA_operB_operC:
4755 // Operation 'op' with one or two source operands 'oper'. Result
4756 // type is A, source operand types are B and C.
4757 // Iff A == B == C, B and C are left out.
4758 //
4759 // The instructions are ordered according to the following scheme:
4760 // - loads
4761 // - load constants
4762 // - prefetch
4763 // - store
4764 // - encode/decode
4765 // - membar
4766 // - conditional moves
4767 // - compare & swap
4768 // - arithmetic and logic operations
4769 // * int: Add, Sub, Mul, Div, Mod
4770 // * int: lShift, arShift, urShift, rot
4771 // * float: Add, Sub, Mul, Div
4772 // * and, or, xor ...
4773 // - register moves: float <-> int, reg <-> stack, repl
4774 // - cast (high level type cast, XtoP, castPP, castII, not_null etc.
4775 // - conv (low level type cast requiring bit changes (sign extend etc)
4776 // - compares, range & zero checks.
4777 // - branches
4778 // - complex operations, intrinsics, min, max, replicate
4779 // - lock
4780 // - Calls
4781 //
4782 // If there are similar instructions with different types they are sorted:
4783 // int before float
4784 // small before big
4785 // signed before unsigned
4786 // e.g., loadS before loadUS before loadI before loadF.
4787
4788
4789 //----------Load/Store Instructions--------------------------------------------
4790
4791 //----------Load Instructions--------------------------------------------------
4792
4793 // Converts byte to int.
4794 // As convB2I_reg, but without match rule. The match rule of convB2I_reg
4795 // reuses the 'amount' operand, but adlc expects that operand specification
4796 // and operands in match rule are equivalent.
4797 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
4798 effect(DEF dst, USE src);
4799 format %{ "EXTSB $dst, $src \t// byte->int" %}
4800 size(4);
4801 ins_encode %{
4802 __ extsb($dst$$Register, $src$$Register);
4803 %}
4804 ins_pipe(pipe_class_default);
4805 %}
4806
4807 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{
4808 // match-rule, false predicate
4809 match(Set dst (LoadB mem));
4810 predicate(false);
4811
4812 format %{ "LBZ $dst, $mem" %}
4813 size(4);
4814 ins_encode( enc_lbz(dst, mem) );
4815 ins_pipe(pipe_class_memory);
4816 %}
4817
4818 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{
4819 // match-rule, false predicate
4820 match(Set dst (LoadB mem));
4821 predicate(false);
4822
4823 format %{ "LBZ $dst, $mem\n\t"
4824 "TWI $dst\n\t"
4825 "ISYNC" %}
4826 size(12);
4827 ins_encode( enc_lbz_ac(dst, mem) );
4828 ins_pipe(pipe_class_memory);
4829 %}
4830
4831 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
4832 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{
4833 match(Set dst (LoadB mem));
4834 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4835 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4836 expand %{
4837 iRegIdst tmp;
4838 loadUB_indirect(tmp, mem);
4839 convB2I_reg_2(dst, tmp);
4840 %}
4841 %}
4842
4843 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{
4844 match(Set dst (LoadB mem));
4845 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
4846 expand %{
4847 iRegIdst tmp;
4848 loadUB_indirect_ac(tmp, mem);
4849 convB2I_reg_2(dst, tmp);
4850 %}
4851 %}
4852
4853 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{
4854 // match-rule, false predicate
4855 match(Set dst (LoadB mem));
4856 predicate(false);
4857
4858 format %{ "LBZ $dst, $mem" %}
4859 size(4);
4860 ins_encode( enc_lbz(dst, mem) );
4861 ins_pipe(pipe_class_memory);
4862 %}
4863
4864 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{
4865 // match-rule, false predicate
4866 match(Set dst (LoadB mem));
4867 predicate(false);
4868
4869 format %{ "LBZ $dst, $mem\n\t"
4870 "TWI $dst\n\t"
4871 "ISYNC" %}
4872 size(12);
4873 ins_encode( enc_lbz_ac(dst, mem) );
4874 ins_pipe(pipe_class_memory);
4875 %}
4876
4877 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
4878 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{
4879 match(Set dst (LoadB mem));
4880 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4881 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4882
4883 expand %{
4884 iRegIdst tmp;
4885 loadUB_indOffset16(tmp, mem);
4886 convB2I_reg_2(dst, tmp);
4887 %}
4888 %}
4889
4890 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{
4891 match(Set dst (LoadB mem));
4892 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
4893
4894 expand %{
4895 iRegIdst tmp;
4896 loadUB_indOffset16_ac(tmp, mem);
4897 convB2I_reg_2(dst, tmp);
4898 %}
4899 %}
4900
4901 // Load Unsigned Byte (8bit UNsigned) into an int reg.
4902 instruct loadUB(iRegIdst dst, memory mem) %{
4903 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4904 match(Set dst (LoadUB mem));
4905 ins_cost(MEMORY_REF_COST);
4906
4907 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %}
4908 size(4);
4909 ins_encode( enc_lbz(dst, mem) );
4910 ins_pipe(pipe_class_memory);
4911 %}
4912
4913 // Load Unsigned Byte (8bit UNsigned) acquire.
4914 instruct loadUB_ac(iRegIdst dst, memory mem) %{
4915 match(Set dst (LoadUB mem));
4916 ins_cost(3*MEMORY_REF_COST);
4917
4918 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t"
4919 "TWI $dst\n\t"
4920 "ISYNC" %}
4921 size(12);
4922 ins_encode( enc_lbz_ac(dst, mem) );
4923 ins_pipe(pipe_class_memory);
4924 %}
4925
4926 // Load Unsigned Byte (8bit UNsigned) into a Long Register.
4927 instruct loadUB2L(iRegLdst dst, memory mem) %{
4928 match(Set dst (ConvI2L (LoadUB mem)));
4929 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
4930 ins_cost(MEMORY_REF_COST);
4931
4932 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %}
4933 size(4);
4934 ins_encode( enc_lbz(dst, mem) );
4935 ins_pipe(pipe_class_memory);
4936 %}
4937
4938 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{
4939 match(Set dst (ConvI2L (LoadUB mem)));
4940 ins_cost(3*MEMORY_REF_COST);
4941
4942 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t"
4943 "TWI $dst\n\t"
4944 "ISYNC" %}
4945 size(12);
4946 ins_encode( enc_lbz_ac(dst, mem) );
4947 ins_pipe(pipe_class_memory);
4948 %}
4949
4950 // Load Short (16bit signed)
4951 instruct loadS(iRegIdst dst, memory mem) %{
4952 match(Set dst (LoadS mem));
4953 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4954 ins_cost(MEMORY_REF_COST);
4955
4956 format %{ "LHA $dst, $mem" %}
4957 size(4);
4958 ins_encode %{
4959 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
4960 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
4961 %}
4962 ins_pipe(pipe_class_memory);
4963 %}
4964
4965 // Load Short (16bit signed) acquire.
4966 instruct loadS_ac(iRegIdst dst, memory mem) %{
4967 match(Set dst (LoadS mem));
4968 ins_cost(3*MEMORY_REF_COST);
4969
4970 format %{ "LHA $dst, $mem\t acquire\n\t"
4971 "TWI $dst\n\t"
4972 "ISYNC" %}
4973 size(12);
4974 ins_encode %{
4975 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
4976 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
4977 __ twi_0($dst$$Register);
4978 __ isync();
4979 %}
4980 ins_pipe(pipe_class_memory);
4981 %}
4982
4983 // Load Char (16bit unsigned)
4984 instruct loadUS(iRegIdst dst, memory mem) %{
4985 match(Set dst (LoadUS mem));
4986 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
4987 ins_cost(MEMORY_REF_COST);
4988
4989 format %{ "LHZ $dst, $mem" %}
4990 size(4);
4991 ins_encode( enc_lhz(dst, mem) );
4992 ins_pipe(pipe_class_memory);
4993 %}
4994
4995 // Load Char (16bit unsigned) acquire.
4996 instruct loadUS_ac(iRegIdst dst, memory mem) %{
4997 match(Set dst (LoadUS mem));
4998 ins_cost(3*MEMORY_REF_COST);
4999
5000 format %{ "LHZ $dst, $mem \t// acquire\n\t"
5001 "TWI $dst\n\t"
5002 "ISYNC" %}
5003 size(12);
5004 ins_encode( enc_lhz_ac(dst, mem) );
5005 ins_pipe(pipe_class_memory);
5006 %}
5007
5008 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register.
5009 instruct loadUS2L(iRegLdst dst, memory mem) %{
5010 match(Set dst (ConvI2L (LoadUS mem)));
5011 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5012 ins_cost(MEMORY_REF_COST);
5013
5014 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %}
5015 size(4);
5016 ins_encode( enc_lhz(dst, mem) );
5017 ins_pipe(pipe_class_memory);
5018 %}
5019
5020 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire.
5021 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{
5022 match(Set dst (ConvI2L (LoadUS mem)));
5023 ins_cost(3*MEMORY_REF_COST);
5024
5025 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t"
5026 "TWI $dst\n\t"
5027 "ISYNC" %}
5028 size(12);
5029 ins_encode( enc_lhz_ac(dst, mem) );
5030 ins_pipe(pipe_class_memory);
5031 %}
5032
5033 // Load Integer.
5034 instruct loadI(iRegIdst dst, memory mem) %{
5035 match(Set dst (LoadI mem));
5036 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5037 ins_cost(MEMORY_REF_COST);
5038
5039 format %{ "LWZ $dst, $mem" %}
5040 size(4);
5041 ins_encode( enc_lwz(dst, mem) );
5042 ins_pipe(pipe_class_memory);
5043 %}
5044
5045 // Load Integer acquire.
5046 instruct loadI_ac(iRegIdst dst, memory mem) %{
5047 match(Set dst (LoadI mem));
5048 ins_cost(3*MEMORY_REF_COST);
5049
5050 format %{ "LWZ $dst, $mem \t// load acquire\n\t"
5051 "TWI $dst\n\t"
5052 "ISYNC" %}
5053 size(12);
5054 ins_encode( enc_lwz_ac(dst, mem) );
5055 ins_pipe(pipe_class_memory);
5056 %}
5057
5058 // Match loading integer and casting it to unsigned int in
5059 // long register.
5060 // LoadI + ConvI2L + AndL 0xffffffff.
5061 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
5062 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5063 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered());
5064 ins_cost(MEMORY_REF_COST);
5065
5066 format %{ "LWZ $dst, $mem \t// zero-extend to long" %}
5067 size(4);
5068 ins_encode( enc_lwz(dst, mem) );
5069 ins_pipe(pipe_class_memory);
5070 %}
5071
5072 // Match loading integer and casting it to long.
5073 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
5074 match(Set dst (ConvI2L (LoadI mem)));
5075 predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5076 ins_cost(MEMORY_REF_COST);
5077
5078 format %{ "LWA $dst, $mem \t// loadI2L" %}
5079 size(4);
5080 ins_encode %{
5081 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5082 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5083 %}
5084 ins_pipe(pipe_class_memory);
5085 %}
5086
5087 // Match loading integer and casting it to long - acquire.
5088 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
5089 match(Set dst (ConvI2L (LoadI mem)));
5090 ins_cost(3*MEMORY_REF_COST);
5091
5092 format %{ "LWA $dst, $mem \t// loadI2L acquire"
5093 "TWI $dst\n\t"
5094 "ISYNC" %}
5095 size(12);
5096 ins_encode %{
5097 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5098 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5099 __ twi_0($dst$$Register);
5100 __ isync();
5101 %}
5102 ins_pipe(pipe_class_memory);
5103 %}
5104
5105 // Load Long - aligned
5106 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{
5107 match(Set dst (LoadL mem));
5108 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5109 ins_cost(MEMORY_REF_COST);
5110
5111 format %{ "LD $dst, $mem \t// long" %}
5112 size(4);
5113 ins_encode( enc_ld(dst, mem) );
5114 ins_pipe(pipe_class_memory);
5115 %}
5116
5117 // Load Long - aligned acquire.
5118 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{
5119 match(Set dst (LoadL mem));
5120 ins_cost(3*MEMORY_REF_COST);
5121
5122 format %{ "LD $dst, $mem \t// long acquire\n\t"
5123 "TWI $dst\n\t"
5124 "ISYNC" %}
5125 size(12);
5126 ins_encode( enc_ld_ac(dst, mem) );
5127 ins_pipe(pipe_class_memory);
5128 %}
5129
5130 // Load Long - UNaligned
5131 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{
5132 match(Set dst (LoadL_unaligned mem));
5133 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5134 ins_cost(MEMORY_REF_COST);
5135
5136 format %{ "LD $dst, $mem \t// unaligned long" %}
5137 size(4);
5138 ins_encode( enc_ld(dst, mem) );
5139 ins_pipe(pipe_class_memory);
5140 %}
5141
5142 // Load nodes for superwords
5143
5144 // Load Aligned Packed Byte
5145 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{
5146 predicate(n->as_LoadVector()->memory_size() == 8);
5147 match(Set dst (LoadVector mem));
5148 ins_cost(MEMORY_REF_COST);
5149
5150 format %{ "LD $dst, $mem \t// load 8-byte Vector" %}
5151 size(4);
5152 ins_encode( enc_ld(dst, mem) );
5153 ins_pipe(pipe_class_memory);
5154 %}
5155
5156
5157 instruct loadV16(vecX dst, memoryAlg16 mem) %{
5158 predicate(n->as_LoadVector()->memory_size() == 16);
5159 match(Set dst (LoadVector mem));
5160 ins_cost(MEMORY_REF_COST);
5161
5162 format %{ "LXV $dst, $mem \t// load 16-byte Vector" %}
5163 size(4);
5164 ins_encode %{
5165 __ lxv($dst$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
5166 %}
5167 ins_pipe(pipe_class_default);
5168 %}
5169
5170 // Load Range, range = array length (=jint)
5171 instruct loadRange(iRegIdst dst, memory mem) %{
5172 match(Set dst (LoadRange mem));
5173 ins_cost(MEMORY_REF_COST);
5174
5175 format %{ "LWZ $dst, $mem \t// range" %}
5176 size(4);
5177 ins_encode( enc_lwz(dst, mem) );
5178 ins_pipe(pipe_class_memory);
5179 %}
5180
5181 // Load Compressed Pointer
5182 instruct loadN(iRegNdst dst, memory mem) %{
5183 match(Set dst (LoadN mem));
5184 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5185 ins_cost(MEMORY_REF_COST);
5186
5187 format %{ "LWZ $dst, $mem \t// load compressed ptr" %}
5188 size(4);
5189 ins_encode( enc_lwz(dst, mem) );
5190 ins_pipe(pipe_class_memory);
5191 %}
5192
5193 // Load Compressed Pointer acquire.
5194 instruct loadN_ac(iRegNdst dst, memory mem) %{
5195 match(Set dst (LoadN mem));
5196 predicate(n->as_Load()->barrier_data() == 0);
5197 ins_cost(3*MEMORY_REF_COST);
5198
5199 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5200 "TWI $dst\n\t"
5201 "ISYNC" %}
5202 size(12);
5203 ins_encode( enc_lwz_ac(dst, mem) );
5204 ins_pipe(pipe_class_memory);
5205 %}
5206
5207 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5208 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5209 match(Set dst (DecodeN (LoadN mem)));
5210 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0 && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5211 ins_cost(MEMORY_REF_COST);
5212
5213 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5214 size(4);
5215 ins_encode( enc_lwz(dst, mem) );
5216 ins_pipe(pipe_class_memory);
5217 %}
5218
5219 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5220 match(Set dst (DecodeNKlass (LoadNKlass mem)));
5221 predicate(CompressedKlassPointers::base() == nullptr && CompressedKlassPointers::shift() == 0 &&
5222 _kids[0]->_leaf->as_Load()->is_unordered());
5223 ins_cost(MEMORY_REF_COST);
5224
5225 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5226 size(4);
5227 ins_encode( enc_lwz(dst, mem) );
5228 ins_pipe(pipe_class_memory);
5229 %}
5230
5231 // Load Pointer
5232 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5233 match(Set dst (LoadP mem));
5234 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5235 ins_cost(MEMORY_REF_COST);
5236
5237 format %{ "LD $dst, $mem \t// ptr" %}
5238 size(4);
5239 ins_encode( enc_ld(dst, mem) );
5240 ins_pipe(pipe_class_memory);
5241 %}
5242
5243 // Load Pointer acquire.
5244 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5245 match(Set dst (LoadP mem));
5246 ins_cost(3*MEMORY_REF_COST);
5247
5248 predicate(n->as_Load()->barrier_data() == 0);
5249
5250 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5251 "TWI $dst\n\t"
5252 "ISYNC" %}
5253 size(12);
5254 ins_encode( enc_ld_ac(dst, mem) );
5255 ins_pipe(pipe_class_memory);
5256 %}
5257
5258 // LoadP + CastP2L
5259 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
5260 match(Set dst (CastP2X (LoadP mem)));
5261 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5262 ins_cost(MEMORY_REF_COST);
5263
5264 format %{ "LD $dst, $mem \t// ptr + p2x" %}
5265 size(4);
5266 ins_encode( enc_ld(dst, mem) );
5267 ins_pipe(pipe_class_memory);
5268 %}
5269
5270 // Load compressed klass pointer.
5271 instruct loadNKlass(iRegNdst dst, memory mem) %{
5272 match(Set dst (LoadNKlass mem));
5273 predicate(!UseCompactObjectHeaders);
5274 ins_cost(MEMORY_REF_COST);
5275
5276 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %}
5277 size(4);
5278 ins_encode( enc_lwz(dst, mem) );
5279 ins_pipe(pipe_class_memory);
5280 %}
5281
5282 instruct loadNKlassCompactHeaders(iRegNdst dst, memory mem) %{
5283 match(Set dst (LoadNKlass mem));
5284 predicate(UseCompactObjectHeaders);
5285 ins_cost(MEMORY_REF_COST);
5286
5287 format %{ "load_narrow_klass_compact $dst, $mem \t// compressed class ptr" %}
5288 size(8);
5289 ins_encode %{
5290 assert($mem$$index$$Register == R0, "must not have indexed address: %s[%s]", $mem$$base$$Register.name(), $mem$$index$$Register.name());
5291 __ load_narrow_klass_compact_c2($dst$$Register, $mem$$base$$Register, $mem$$disp);
5292 %}
5293 ins_pipe(pipe_class_memory);
5294 %}
5295
5296 // Load Klass Pointer
5297 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
5298 match(Set dst (LoadKlass mem));
5299 ins_cost(MEMORY_REF_COST);
5300
5301 format %{ "LD $dst, $mem \t// klass ptr" %}
5302 size(4);
5303 ins_encode( enc_ld(dst, mem) );
5304 ins_pipe(pipe_class_memory);
5305 %}
5306
5307 // Load Float
5308 instruct loadF(regF dst, memory mem) %{
5309 match(Set dst (LoadF mem));
5310 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5311 ins_cost(MEMORY_REF_COST);
5312
5313 format %{ "LFS $dst, $mem" %}
5314 size(4);
5315 ins_encode %{
5316 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5317 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5318 %}
5319 ins_pipe(pipe_class_memory);
5320 %}
5321
5322 // Load Float acquire.
5323 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5324 match(Set dst (LoadF mem));
5325 effect(TEMP cr0);
5326 ins_cost(3*MEMORY_REF_COST);
5327
5328 format %{ "LFS $dst, $mem \t// acquire\n\t"
5329 "FCMPU cr0, $dst, $dst\n\t"
5330 "BNE cr0, next\n"
5331 "next:\n\t"
5332 "ISYNC" %}
5333 size(16);
5334 ins_encode %{
5335 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5336 Label next;
5337 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5338 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5339 __ bne(CR0, next);
5340 __ bind(next);
5341 __ isync();
5342 %}
5343 ins_pipe(pipe_class_memory);
5344 %}
5345
5346 // Load Double - aligned
5347 instruct loadD(regD dst, memory mem) %{
5348 match(Set dst (LoadD mem));
5349 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5350 ins_cost(MEMORY_REF_COST);
5351
5352 format %{ "LFD $dst, $mem" %}
5353 size(4);
5354 ins_encode( enc_lfd(dst, mem) );
5355 ins_pipe(pipe_class_memory);
5356 %}
5357
5358 // Load Double - aligned acquire.
5359 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5360 match(Set dst (LoadD mem));
5361 effect(TEMP cr0);
5362 ins_cost(3*MEMORY_REF_COST);
5363
5364 format %{ "LFD $dst, $mem \t// acquire\n\t"
5365 "FCMPU cr0, $dst, $dst\n\t"
5366 "BNE cr0, next\n"
5367 "next:\n\t"
5368 "ISYNC" %}
5369 size(16);
5370 ins_encode %{
5371 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5372 Label next;
5373 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5374 __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister);
5375 __ bne(CR0, next);
5376 __ bind(next);
5377 __ isync();
5378 %}
5379 ins_pipe(pipe_class_memory);
5380 %}
5381
5382 // Load Double - UNaligned
5383 instruct loadD_unaligned(regD dst, memory mem) %{
5384 match(Set dst (LoadD_unaligned mem));
5385 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5386 ins_cost(MEMORY_REF_COST);
5387
5388 format %{ "LFD $dst, $mem" %}
5389 size(4);
5390 ins_encode( enc_lfd(dst, mem) );
5391 ins_pipe(pipe_class_memory);
5392 %}
5393
5394 //----------Constants--------------------------------------------------------
5395
5396 // Load MachConstantTableBase: add hi offset to global toc.
5397 // TODO: Handle hidden register r29 in bundler!
5398 instruct loadToc_hi(iRegLdst dst) %{
5399 effect(DEF dst);
5400 ins_cost(DEFAULT_COST);
5401
5402 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %}
5403 size(4);
5404 ins_encode %{
5405 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
5406 %}
5407 ins_pipe(pipe_class_default);
5408 %}
5409
5410 // Load MachConstantTableBase: add lo offset to global toc.
5411 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
5412 effect(DEF dst, USE src);
5413 ins_cost(DEFAULT_COST);
5414
5415 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %}
5416 size(4);
5417 ins_encode %{
5418 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
5419 %}
5420 ins_pipe(pipe_class_default);
5421 %}
5422
5423 // Load 16-bit integer constant 0xssss????
5424 instruct loadConI16(iRegIdst dst, immI16 src) %{
5425 match(Set dst src);
5426
5427 format %{ "LI $dst, $src" %}
5428 size(4);
5429 ins_encode %{
5430 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5431 %}
5432 ins_pipe(pipe_class_default);
5433 %}
5434
5435 // Load integer constant 0x????0000
5436 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
5437 match(Set dst src);
5438 ins_cost(DEFAULT_COST);
5439
5440 format %{ "LIS $dst, $src.hi" %}
5441 size(4);
5442 ins_encode %{
5443 // Lis sign extends 16-bit src then shifts it 16 bit to the left.
5444 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5445 %}
5446 ins_pipe(pipe_class_default);
5447 %}
5448
5449 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted
5450 // and sign extended), this adds the low 16 bits.
5451 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
5452 // no match-rule, false predicate
5453 effect(DEF dst, USE src1, USE src2);
5454 predicate(false);
5455
5456 format %{ "ORI $dst, $src1.hi, $src2.lo" %}
5457 size(4);
5458 ins_encode %{
5459 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5460 %}
5461 ins_pipe(pipe_class_default);
5462 %}
5463
5464 instruct loadConI32(iRegIdst dst, immI32 src) %{
5465 match(Set dst src);
5466 // This macro is valid only in Power 10 and up, but adding the following predicate here
5467 // caused a build error, so we comment it out for now.
5468 // predicate(PowerArchitecturePPC64 >= 10);
5469 ins_cost(DEFAULT_COST+1);
5470
5471 format %{ "PLI $dst, $src" %}
5472 size(8);
5473 ins_encode %{
5474 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5475 __ pli($dst$$Register, $src$$constant);
5476 %}
5477 ins_pipe(pipe_class_default);
5478 ins_alignment(2);
5479 %}
5480
5481 instruct loadConI_Ex(iRegIdst dst, immI src) %{
5482 match(Set dst src);
5483 ins_cost(DEFAULT_COST*2);
5484
5485 expand %{
5486 // Would like to use $src$$constant.
5487 immI16 srcLo %{ _opnds[1]->constant() %}
5488 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5489 immIhi16 srcHi %{ _opnds[1]->constant() %}
5490 iRegIdst tmpI;
5491 loadConIhi16(tmpI, srcHi);
5492 loadConI32_lo16(dst, tmpI, srcLo);
5493 %}
5494 %}
5495
5496 // No constant pool entries required.
5497 instruct loadConL16(iRegLdst dst, immL16 src) %{
5498 match(Set dst src);
5499
5500 format %{ "LI $dst, $src \t// long" %}
5501 size(4);
5502 ins_encode %{
5503 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
5504 %}
5505 ins_pipe(pipe_class_default);
5506 %}
5507
5508 // Load long constant 0xssssssss????0000
5509 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
5510 match(Set dst src);
5511 ins_cost(DEFAULT_COST);
5512
5513 format %{ "LIS $dst, $src.hi \t// long" %}
5514 size(4);
5515 ins_encode %{
5516 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5517 %}
5518 ins_pipe(pipe_class_default);
5519 %}
5520
5521 // To load a 32 bit constant: merge lower 16 bits into already loaded
5522 // high 16 bits.
5523 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
5524 // no match-rule, false predicate
5525 effect(DEF dst, USE src1, USE src2);
5526 predicate(false);
5527
5528 format %{ "ORI $dst, $src1, $src2.lo" %}
5529 size(4);
5530 ins_encode %{
5531 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5532 %}
5533 ins_pipe(pipe_class_default);
5534 %}
5535
5536 // Load 32-bit long constant
5537 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{
5538 match(Set dst src);
5539 ins_cost(DEFAULT_COST*2);
5540
5541 expand %{
5542 // Would like to use $src$$constant.
5543 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%}
5544 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5545 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%}
5546 iRegLdst tmpL;
5547 loadConL32hi16(tmpL, srcHi);
5548 loadConL32_lo16(dst, tmpL, srcLo);
5549 %}
5550 %}
5551
5552 // Load 34-bit long constant using prefixed addi. No constant pool entries required.
5553 instruct loadConL34(iRegLdst dst, immL34 src) %{
5554 match(Set dst src);
5555 // This macro is valid only in Power 10 and up, but adding the following predicate here
5556 // caused a build error, so we comment it out for now.
5557 // predicate(PowerArchitecturePPC64 >= 10);
5558 ins_cost(DEFAULT_COST+1);
5559
5560 format %{ "PLI $dst, $src \t// long" %}
5561 size(8);
5562 ins_encode %{
5563 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5564 __ pli($dst$$Register, $src$$constant);
5565 %}
5566 ins_pipe(pipe_class_default);
5567 ins_alignment(2);
5568 %}
5569
5570 // Load long constant 0x????000000000000.
5571 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{
5572 match(Set dst src);
5573 ins_cost(DEFAULT_COST);
5574
5575 expand %{
5576 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%}
5577 immI shift32 %{ 32 %}
5578 iRegLdst tmpL;
5579 loadConL32hi16(tmpL, srcHi);
5580 lshiftL_regL_immI(dst, tmpL, shift32);
5581 %}
5582 %}
5583
5584 // Expand node for constant pool load: small offset.
5585 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{
5586 effect(DEF dst, USE src, USE toc);
5587 ins_cost(MEMORY_REF_COST);
5588
5589 ins_num_consts(1);
5590 // Needed so that CallDynamicJavaDirect can compute the address of this
5591 // instruction for relocation.
5592 ins_field_cbuf_insts_offset(int);
5593
5594 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %}
5595 size(4);
5596 ins_encode( enc_load_long_constL(dst, src, toc) );
5597 ins_pipe(pipe_class_memory);
5598 %}
5599
5600 // Expand node for constant pool load: large offset.
5601 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{
5602 effect(DEF dst, USE src, USE toc);
5603 predicate(false);
5604
5605 ins_num_consts(1);
5606 ins_field_const_toc_offset(int);
5607 // Needed so that CallDynamicJavaDirect can compute the address of this
5608 // instruction for relocation.
5609 ins_field_cbuf_insts_offset(int);
5610
5611 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %}
5612 size(4);
5613 ins_encode( enc_load_long_constL_hi(dst, toc, src) );
5614 ins_pipe(pipe_class_default);
5615 %}
5616
5617 // Expand node for constant pool load: large offset.
5618 // No constant pool entries required.
5619 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
5620 effect(DEF dst, USE src, USE base);
5621 predicate(false);
5622
5623 ins_field_const_toc_offset_hi_node(loadConL_hiNode*);
5624
5625 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %}
5626 size(4);
5627 ins_encode %{
5628 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5629 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5630 %}
5631 ins_pipe(pipe_class_memory);
5632 %}
5633
5634 // Load long constant from constant table. Expand in case of
5635 // offset > 16 bit is needed.
5636 // Adlc adds toc node MachConstantTableBase.
5637 instruct loadConL_Ex(iRegLdst dst, immL src) %{
5638 match(Set dst src);
5639 ins_cost(MEMORY_REF_COST);
5640
5641 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %}
5642 // We can not inline the enc_class for the expand as that does not support constanttablebase.
5643 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) );
5644 %}
5645
5646 // Load nullptr as compressed oop.
5647 instruct loadConN0(iRegNdst dst, immN_0 src) %{
5648 match(Set dst src);
5649 ins_cost(DEFAULT_COST);
5650
5651 format %{ "LI $dst, $src \t// compressed ptr" %}
5652 size(4);
5653 ins_encode %{
5654 __ li($dst$$Register, 0);
5655 %}
5656 ins_pipe(pipe_class_default);
5657 %}
5658
5659 // Load hi part of compressed oop constant.
5660 instruct loadConN_hi(iRegNdst dst, immN src) %{
5661 effect(DEF dst, USE src);
5662 ins_cost(DEFAULT_COST);
5663
5664 format %{ "LIS $dst, $src \t// narrow oop hi" %}
5665 size(4);
5666 ins_encode %{
5667 __ lis($dst$$Register, 0); // Will get patched.
5668 %}
5669 ins_pipe(pipe_class_default);
5670 %}
5671
5672 // Add lo part of compressed oop constant to already loaded hi part.
5673 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
5674 effect(DEF dst, USE src1, USE src2);
5675 ins_cost(DEFAULT_COST);
5676
5677 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %}
5678 size(4);
5679 ins_encode %{
5680 AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant);
5681 __ relocate(addrlit.rspec(), /*compressed format*/ 1);
5682 __ ori($dst$$Register, $src1$$Register, 0); // Will get patched.
5683 %}
5684 ins_pipe(pipe_class_default);
5685 %}
5686
5687 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
5688 effect(DEF dst, USE src, USE shift, USE mask_begin);
5689
5690 size(4);
5691 ins_encode %{
5692 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
5693 %}
5694 ins_pipe(pipe_class_default);
5695 %}
5696
5697 // Needed to postalloc expand loadConN: ConN is loaded as ConI
5698 // leaving the upper 32 bits with sign-extension bits.
5699 // This clears these bits: dst = src & 0xFFFFFFFF.
5700 // TODO: Eventually call this maskN_regN_FFFFFFFF.
5701 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
5702 effect(DEF dst, USE src);
5703 predicate(false);
5704
5705 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
5706 size(4);
5707 ins_encode %{
5708 __ clrldi($dst$$Register, $src$$Register, 0x20);
5709 %}
5710 ins_pipe(pipe_class_default);
5711 %}
5712
5713 // Optimize DecodeN for disjoint base.
5714 // Load base of compressed oops into a register
5715 instruct loadBase(iRegLdst dst) %{
5716 effect(DEF dst);
5717
5718 format %{ "LoadConst $dst, heapbase" %}
5719 ins_encode %{
5720 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0);
5721 %}
5722 ins_pipe(pipe_class_default);
5723 %}
5724
5725 // Loading ConN must be postalloc expanded so that edges between
5726 // the nodes are safe. They may not interfere with a safepoint.
5727 // GL TODO: This needs three instructions: better put this into the constant pool.
5728 instruct loadConN_Ex(iRegNdst dst, immN src) %{
5729 match(Set dst src);
5730 ins_cost(DEFAULT_COST*2);
5731
5732 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5733 postalloc_expand %{
5734 MachNode *m1 = new loadConN_hiNode();
5735 MachNode *m2 = new loadConN_loNode();
5736 MachNode *m3 = new clearMs32bNode();
5737 m1->_bottom_type = bottom_type();
5738 m2->_bottom_type = bottom_type();
5739 m3->_bottom_type = bottom_type();
5740 m1->add_req(nullptr);
5741 m2->add_req(nullptr, m1);
5742 m3->add_req(nullptr, m2);
5743 m1->_opnds[0] = op_dst;
5744 m1->_opnds[1] = op_src;
5745 m2->_opnds[0] = op_dst;
5746 m2->_opnds[1] = op_dst;
5747 m2->_opnds[2] = op_src;
5748 m3->_opnds[0] = op_dst;
5749 m3->_opnds[1] = op_dst;
5750 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5751 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5752 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5753 nodes->push(m1);
5754 nodes->push(m2);
5755 nodes->push(m3);
5756 %}
5757 %}
5758
5759 // We have seen a safepoint between the hi and lo parts, and this node was handled
5760 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is
5761 // not a narrow oop.
5762 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
5763 match(Set dst src);
5764 effect(DEF dst, USE src);
5765 ins_cost(DEFAULT_COST);
5766
5767 format %{ "LIS $dst, $src \t// narrow klass hi" %}
5768 size(4);
5769 ins_encode %{
5770 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant);
5771 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
5772 %}
5773 ins_pipe(pipe_class_default);
5774 %}
5775
5776 // As loadConNKlass_hi this must be recognized as narrow klass, not oop!
5777 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5778 match(Set dst src1);
5779 effect(TEMP src2);
5780 ins_cost(DEFAULT_COST);
5781
5782 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
5783 size(4);
5784 ins_encode %{
5785 __ clrldi($dst$$Register, $src2$$Register, 0x20);
5786 %}
5787 ins_pipe(pipe_class_default);
5788 %}
5789
5790 // This needs a match rule so that build_oop_map knows this is
5791 // not a narrow oop.
5792 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5793 match(Set dst src1);
5794 effect(TEMP src2);
5795 ins_cost(DEFAULT_COST);
5796
5797 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
5798 size(4);
5799 ins_encode %{
5800 // Notify OOP recorder (don't need the relocation)
5801 AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant);
5802 intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value());
5803 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
5804 %}
5805 ins_pipe(pipe_class_default);
5806 %}
5807
5808 // Loading ConNKlass must be postalloc expanded so that edges between
5809 // the nodes are safe. They may not interfere with a safepoint.
5810 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
5811 match(Set dst src);
5812 ins_cost(DEFAULT_COST*2);
5813
5814 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
5815 postalloc_expand %{
5816 // Load high bits into register. Sign extended.
5817 MachNode *m1 = new loadConNKlass_hiNode();
5818 m1->_bottom_type = bottom_type();
5819 m1->add_req(nullptr);
5820 m1->_opnds[0] = op_dst;
5821 m1->_opnds[1] = op_src;
5822 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5823 nodes->push(m1);
5824
5825 MachNode *m2 = m1;
5826 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) {
5827 // Value might be 1-extended. Mask out these bits.
5828 m2 = new loadConNKlass_maskNode();
5829 m2->_bottom_type = bottom_type();
5830 m2->add_req(nullptr, m1);
5831 m2->_opnds[0] = op_dst;
5832 m2->_opnds[1] = op_src;
5833 m2->_opnds[2] = op_dst;
5834 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5835 nodes->push(m2);
5836 }
5837
5838 MachNode *m3 = new loadConNKlass_loNode();
5839 m3->_bottom_type = bottom_type();
5840 m3->add_req(nullptr, m2);
5841 m3->_opnds[0] = op_dst;
5842 m3->_opnds[1] = op_src;
5843 m3->_opnds[2] = op_dst;
5844 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5845 nodes->push(m3);
5846 %}
5847 %}
5848
5849 // 0x1 is used in object initialization (initial object header).
5850 // No constant pool entries required.
5851 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
5852 match(Set dst src);
5853
5854 format %{ "LI $dst, $src \t// ptr" %}
5855 size(4);
5856 ins_encode %{
5857 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5858 %}
5859 ins_pipe(pipe_class_default);
5860 %}
5861
5862 // Expand node for constant pool load: small offset.
5863 // The match rule is needed to generate the correct bottom_type(),
5864 // however this node should never match. The use of predicate is not
5865 // possible since ADLC forbids predicates for chain rules. The higher
5866 // costs do not prevent matching in this case. For that reason the
5867 // operand immP_NM with predicate(false) is used.
5868 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{
5869 match(Set dst src);
5870 effect(TEMP toc);
5871
5872 ins_num_consts(1);
5873
5874 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %}
5875 size(4);
5876 ins_encode( enc_load_long_constP(dst, src, toc) );
5877 ins_pipe(pipe_class_memory);
5878 %}
5879
5880 // Expand node for constant pool load: large offset.
5881 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{
5882 effect(DEF dst, USE src, USE toc);
5883 predicate(false);
5884
5885 ins_num_consts(1);
5886 ins_field_const_toc_offset(int);
5887
5888 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %}
5889 size(4);
5890 ins_encode( enc_load_long_constP_hi(dst, src, toc) );
5891 ins_pipe(pipe_class_default);
5892 %}
5893
5894 // Expand node for constant pool load: large offset.
5895 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
5896 match(Set dst src);
5897 effect(TEMP base);
5898
5899 ins_field_const_toc_offset_hi_node(loadConP_hiNode*);
5900
5901 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
5902 size(4);
5903 ins_encode %{
5904 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5905 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5906 %}
5907 ins_pipe(pipe_class_memory);
5908 %}
5909
5910 // Load pointer constant from constant table. Expand in case an
5911 // offset > 16 bit is needed.
5912 // Adlc adds toc node MachConstantTableBase.
5913 instruct loadConP_Ex(iRegPdst dst, immP src) %{
5914 match(Set dst src);
5915 ins_cost(MEMORY_REF_COST);
5916
5917 // This rule does not use "expand" because then
5918 // the result type is not known to be an Oop. An ADLC
5919 // enhancement will be needed to make that work - not worth it!
5920
5921 // If this instruction rematerializes, it prolongs the live range
5922 // of the toc node, causing illegal graphs.
5923 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule().
5924 ins_cannot_rematerialize(true);
5925
5926 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %}
5927 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) );
5928 %}
5929
5930 // Expand node for constant pool load: small offset.
5931 instruct loadConF(regF dst, immF src, iRegLdst toc) %{
5932 effect(DEF dst, USE src, USE toc);
5933 ins_cost(MEMORY_REF_COST);
5934
5935 ins_num_consts(1);
5936
5937 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %}
5938 size(4);
5939 ins_encode %{
5940 address float_address = __ float_constant($src$$constant);
5941 if (float_address == nullptr) {
5942 ciEnv::current()->record_out_of_memory_failure();
5943 return;
5944 }
5945 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register);
5946 %}
5947 ins_pipe(pipe_class_memory);
5948 %}
5949
5950 // Expand node for constant pool load: large offset.
5951 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
5952 effect(DEF dst, USE src, USE toc);
5953 ins_cost(MEMORY_REF_COST);
5954
5955 ins_num_consts(1);
5956
5957 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
5958 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t"
5959 "ADDIS $toc, $toc, -offset_hi"%}
5960 size(12);
5961 ins_encode %{
5962 FloatRegister Rdst = $dst$$FloatRegister;
5963 Register Rtoc = $toc$$Register;
5964 address float_address = __ float_constant($src$$constant);
5965 if (float_address == nullptr) {
5966 ciEnv::current()->record_out_of_memory_failure();
5967 return;
5968 }
5969 int offset = __ offset_to_method_toc(float_address);
5970 int hi = (offset + (1<<15))>>16;
5971 int lo = offset - hi * (1<<16);
5972
5973 __ addis(Rtoc, Rtoc, hi);
5974 __ lfs(Rdst, lo, Rtoc);
5975 __ addis(Rtoc, Rtoc, -hi);
5976 %}
5977 ins_pipe(pipe_class_memory);
5978 %}
5979
5980 // Adlc adds toc node MachConstantTableBase.
5981 instruct loadConF_Ex(regF dst, immF src) %{
5982 match(Set dst src);
5983 ins_cost(MEMORY_REF_COST);
5984
5985 // See loadConP.
5986 ins_cannot_rematerialize(true);
5987
5988 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
5989 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) );
5990 %}
5991
5992 // Expand node for constant pool load: small offset.
5993 instruct loadConD(regD dst, immD src, iRegLdst toc) %{
5994 effect(DEF dst, USE src, USE toc);
5995 ins_cost(MEMORY_REF_COST);
5996
5997 ins_num_consts(1);
5998
5999 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %}
6000 size(4);
6001 ins_encode %{
6002 address float_address = __ double_constant($src$$constant);
6003 if (float_address == nullptr) {
6004 ciEnv::current()->record_out_of_memory_failure();
6005 return;
6006 }
6007 int offset = __ offset_to_method_toc(float_address);
6008 __ lfd($dst$$FloatRegister, offset, $toc$$Register);
6009 %}
6010 ins_pipe(pipe_class_memory);
6011 %}
6012
6013 // Expand node for constant pool load: large offset.
6014 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
6015 effect(DEF dst, USE src, USE toc);
6016 ins_cost(MEMORY_REF_COST);
6017
6018 ins_num_consts(1);
6019
6020 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6021 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t"
6022 "ADDIS $toc, $toc, -offset_hi" %}
6023 size(12);
6024 ins_encode %{
6025 FloatRegister Rdst = $dst$$FloatRegister;
6026 Register Rtoc = $toc$$Register;
6027 address float_address = __ double_constant($src$$constant);
6028 if (float_address == nullptr) {
6029 ciEnv::current()->record_out_of_memory_failure();
6030 return;
6031 }
6032 int offset = __ offset_to_method_toc(float_address);
6033 int hi = (offset + (1<<15))>>16;
6034 int lo = offset - hi * (1<<16);
6035
6036 __ addis(Rtoc, Rtoc, hi);
6037 __ lfd(Rdst, lo, Rtoc);
6038 __ addis(Rtoc, Rtoc, -hi);
6039 %}
6040 ins_pipe(pipe_class_memory);
6041 %}
6042
6043 // Adlc adds toc node MachConstantTableBase.
6044 instruct loadConD_Ex(regD dst, immD src) %{
6045 match(Set dst src);
6046 ins_cost(MEMORY_REF_COST);
6047
6048 // See loadConP.
6049 ins_cannot_rematerialize(true);
6050
6051 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6052 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) );
6053 %}
6054
6055 // Prefetch instructions.
6056 // Must be safe to execute with invalid address (cannot fault).
6057
6058 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
6059 match(PrefetchAllocation (AddP mem src));
6060 ins_cost(MEMORY_REF_COST);
6061
6062 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
6063 size(4);
6064 ins_encode %{
6065 __ dcbtst($src$$Register, $mem$$base$$Register);
6066 %}
6067 ins_pipe(pipe_class_memory);
6068 %}
6069
6070 instruct prefetch_alloc_no_offset(indirectMemory mem) %{
6071 match(PrefetchAllocation mem);
6072 ins_cost(MEMORY_REF_COST);
6073
6074 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
6075 size(4);
6076 ins_encode %{
6077 __ dcbtst($mem$$base$$Register);
6078 %}
6079 ins_pipe(pipe_class_memory);
6080 %}
6081
6082 //----------Store Instructions-------------------------------------------------
6083
6084 // Store Byte
6085 instruct storeB(memory mem, iRegIsrc src) %{
6086 match(Set mem (StoreB mem src));
6087 ins_cost(MEMORY_REF_COST);
6088
6089 format %{ "STB $src, $mem \t// byte" %}
6090 size(4);
6091 ins_encode %{
6092 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6093 __ stb($src$$Register, Idisp, $mem$$base$$Register);
6094 %}
6095 ins_pipe(pipe_class_memory);
6096 %}
6097
6098 // Store Char/Short
6099 instruct storeC(memory mem, iRegIsrc src) %{
6100 match(Set mem (StoreC mem src));
6101 ins_cost(MEMORY_REF_COST);
6102
6103 format %{ "STH $src, $mem \t// short" %}
6104 size(4);
6105 ins_encode %{
6106 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6107 __ sth($src$$Register, Idisp, $mem$$base$$Register);
6108 %}
6109 ins_pipe(pipe_class_memory);
6110 %}
6111
6112 // Store Integer
6113 instruct storeI(memory mem, iRegIsrc src) %{
6114 match(Set mem (StoreI mem src));
6115 ins_cost(MEMORY_REF_COST);
6116
6117 format %{ "STW $src, $mem" %}
6118 size(4);
6119 ins_encode( enc_stw(src, mem) );
6120 ins_pipe(pipe_class_memory);
6121 %}
6122
6123 // ConvL2I + StoreI.
6124 instruct storeI_convL2I(memory mem, iRegLsrc src) %{
6125 match(Set mem (StoreI mem (ConvL2I src)));
6126 ins_cost(MEMORY_REF_COST);
6127
6128 format %{ "STW l2i($src), $mem" %}
6129 size(4);
6130 ins_encode( enc_stw(src, mem) );
6131 ins_pipe(pipe_class_memory);
6132 %}
6133
6134 // Store Long
6135 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{
6136 match(Set mem (StoreL mem src));
6137 ins_cost(MEMORY_REF_COST);
6138
6139 format %{ "STD $src, $mem \t// long" %}
6140 size(4);
6141 ins_encode( enc_std(src, mem) );
6142 ins_pipe(pipe_class_memory);
6143 %}
6144
6145 // Store super word nodes.
6146
6147 // Store Aligned Packed Byte long register to memory
6148 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{
6149 predicate(n->as_StoreVector()->memory_size() == 8);
6150 match(Set mem (StoreVector mem src));
6151 ins_cost(MEMORY_REF_COST);
6152
6153 format %{ "STD $mem, $src \t// packed8B" %}
6154 size(4);
6155 ins_encode( enc_std(src, mem) );
6156 ins_pipe(pipe_class_memory);
6157 %}
6158
6159
6160 instruct storeV16(memoryAlg16 mem, vecX src) %{
6161 predicate(n->as_StoreVector()->memory_size() == 16);
6162 match(Set mem (StoreVector mem src));
6163 ins_cost(MEMORY_REF_COST);
6164
6165 format %{ "STXV $mem, $src \t// store 16-byte Vector" %}
6166 size(4);
6167 ins_encode %{
6168 __ stxv($src$$VectorRegister.to_vsr(), $mem$$disp, $mem$$Register);
6169 %}
6170 ins_pipe(pipe_class_default);
6171 %}
6172
6173 // Reinterpret: only one vector size used: either L or X
6174 instruct reinterpretL(iRegLdst dst) %{
6175 match(Set dst (VectorReinterpret dst));
6176 ins_cost(0);
6177 format %{ "reinterpret $dst" %}
6178 size(0);
6179 ins_encode( /*empty*/ );
6180 ins_pipe(pipe_class_empty);
6181 %}
6182
6183 instruct reinterpretX(vecX dst) %{
6184 match(Set dst (VectorReinterpret dst));
6185 ins_cost(0);
6186 format %{ "reinterpret $dst" %}
6187 size(0);
6188 ins_encode( /*empty*/ );
6189 ins_pipe(pipe_class_empty);
6190 %}
6191
6192 // Store Compressed Oop
6193 instruct storeN(memory dst, iRegN_P2N src) %{
6194 match(Set dst (StoreN dst src));
6195 predicate(n->as_Store()->barrier_data() == 0);
6196 ins_cost(MEMORY_REF_COST);
6197
6198 format %{ "STW $src, $dst \t// compressed oop" %}
6199 size(4);
6200 ins_encode( enc_stw(src, dst) );
6201 ins_pipe(pipe_class_memory);
6202 %}
6203
6204 // Store Compressed KLass
6205 instruct storeNKlass(memory dst, iRegN_P2N src) %{
6206 match(Set dst (StoreNKlass dst src));
6207 ins_cost(MEMORY_REF_COST);
6208
6209 format %{ "STW $src, $dst \t// compressed klass" %}
6210 size(4);
6211 ins_encode( enc_stw(src, dst) );
6212 ins_pipe(pipe_class_memory);
6213 %}
6214
6215 // Store Pointer
6216 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{
6217 match(Set dst (StoreP dst src));
6218 predicate(n->as_Store()->barrier_data() == 0);
6219 ins_cost(MEMORY_REF_COST);
6220
6221 format %{ "STD $src, $dst \t// ptr" %}
6222 size(4);
6223 ins_encode( enc_std(src, dst) );
6224 ins_pipe(pipe_class_memory);
6225 %}
6226
6227 // Store Float
6228 instruct storeF(memory mem, regF src) %{
6229 match(Set mem (StoreF mem src));
6230 ins_cost(MEMORY_REF_COST);
6231
6232 format %{ "STFS $src, $mem" %}
6233 size(4);
6234 ins_encode( enc_stfs(src, mem) );
6235 ins_pipe(pipe_class_memory);
6236 %}
6237
6238 // Store Double
6239 instruct storeD(memory mem, regD src) %{
6240 match(Set mem (StoreD mem src));
6241 ins_cost(MEMORY_REF_COST);
6242
6243 format %{ "STFD $src, $mem" %}
6244 size(4);
6245 ins_encode( enc_stfd(src, mem) );
6246 ins_pipe(pipe_class_memory);
6247 %}
6248
6249 // Convert oop pointer into compressed form.
6250
6251 // Nodes for postalloc expand.
6252
6253 // Shift node for expand.
6254 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
6255 // The match rule is needed to make it a 'MachTypeNode'!
6256 match(Set dst (EncodeP src));
6257 predicate(false);
6258
6259 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6260 size(4);
6261 ins_encode %{
6262 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6263 %}
6264 ins_pipe(pipe_class_default);
6265 %}
6266
6267 // Add node for expand.
6268 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6269 // The match rule is needed to make it a 'MachTypeNode'!
6270 match(Set dst (EncodeP src));
6271 predicate(false);
6272
6273 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6274 ins_encode %{
6275 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6276 %}
6277 ins_pipe(pipe_class_default);
6278 %}
6279
6280 // Conditional sub base.
6281 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6282 // The match rule is needed to make it a 'MachTypeNode'!
6283 match(Set dst (EncodeP (Binary crx src1)));
6284 predicate(false);
6285
6286 format %{ "BEQ $crx, done\n\t"
6287 "SUB $dst, $src1, heapbase \t// encode: subtract base if != nullptr\n"
6288 "done:" %}
6289 ins_encode %{
6290 Label done;
6291 __ beq($crx$$CondRegister, done);
6292 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0);
6293 __ bind(done);
6294 %}
6295 ins_pipe(pipe_class_default);
6296 %}
6297
6298 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6299 // The match rule is needed to make it a 'MachTypeNode'!
6300 match(Set dst (EncodeP (Binary crx src1)));
6301 predicate(false);
6302
6303 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6304 size(4);
6305 ins_encode %{
6306 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6307 %}
6308 ins_pipe(pipe_class_default);
6309 %}
6310
6311 // Disjoint narrow oop base.
6312 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6313 match(Set dst (EncodeP src));
6314 predicate(CompressedOops::base_disjoint());
6315
6316 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6317 size(4);
6318 ins_encode %{
6319 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32);
6320 %}
6321 ins_pipe(pipe_class_default);
6322 %}
6323
6324 // shift != 0, base != 0
6325 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6326 match(Set dst (EncodeP src));
6327 effect(TEMP crx);
6328 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6329 CompressedOops::shift() != 0 &&
6330 CompressedOops::base_overlaps());
6331
6332 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6333 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6334 %}
6335
6336 // shift != 0, base != 0
6337 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6338 match(Set dst (EncodeP src));
6339 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6340 CompressedOops::shift() != 0 &&
6341 CompressedOops::base_overlaps());
6342
6343 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6344 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6345 %}
6346
6347 // shift != 0, base == 0
6348 // TODO: This is the same as encodeP_shift. Merge!
6349 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6350 match(Set dst (EncodeP src));
6351 predicate(CompressedOops::shift() != 0 &&
6352 CompressedOops::base() == nullptr);
6353
6354 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != nullptr" %}
6355 size(4);
6356 ins_encode %{
6357 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6358 %}
6359 ins_pipe(pipe_class_default);
6360 %}
6361
6362 // Compressed OOPs with narrow_oop_shift == 0.
6363 // shift == 0, base == 0
6364 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
6365 match(Set dst (EncodeP src));
6366 predicate(CompressedOops::shift() == 0);
6367
6368 format %{ "MR $dst, $src \t// Ptr->Narrow" %}
6369 // variable size, 0 or 4.
6370 ins_encode %{
6371 __ mr_if_needed($dst$$Register, $src$$Register);
6372 %}
6373 ins_pipe(pipe_class_default);
6374 %}
6375
6376 // Decode nodes.
6377
6378 // Shift node for expand.
6379 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6380 // The match rule is needed to make it a 'MachTypeNode'!
6381 match(Set dst (DecodeN src));
6382 predicate(false);
6383
6384 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6385 size(4);
6386 ins_encode %{
6387 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6388 %}
6389 ins_pipe(pipe_class_default);
6390 %}
6391
6392 // Add node for expand.
6393 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6394 // The match rule is needed to make it a 'MachTypeNode'!
6395 match(Set dst (DecodeN src));
6396 predicate(false);
6397
6398 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %}
6399 ins_encode %{
6400 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6401 %}
6402 ins_pipe(pipe_class_default);
6403 %}
6404
6405 // conditianal add base for expand
6406 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6407 // The match rule is needed to make it a 'MachTypeNode'!
6408 // NOTICE that the rule is nonsense - we just have to make sure that:
6409 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6410 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6411 match(Set dst (DecodeN (Binary crx src)));
6412 predicate(false);
6413
6414 format %{ "BEQ $crx, done\n\t"
6415 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != nullptr\n"
6416 "done:" %}
6417 ins_encode %{
6418 Label done;
6419 __ beq($crx$$CondRegister, done);
6420 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6421 __ bind(done);
6422 %}
6423 ins_pipe(pipe_class_default);
6424 %}
6425
6426 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6427 // The match rule is needed to make it a 'MachTypeNode'!
6428 // NOTICE that the rule is nonsense - we just have to make sure that:
6429 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6430 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6431 match(Set dst (DecodeN (Binary crx src1)));
6432 predicate(false);
6433
6434 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6435 size(4);
6436 ins_encode %{
6437 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6438 %}
6439 ins_pipe(pipe_class_default);
6440 %}
6441
6442 // shift != 0, base != 0
6443 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6444 match(Set dst (DecodeN src));
6445 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6446 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6447 CompressedOops::shift() != 0 &&
6448 CompressedOops::base() != nullptr);
6449 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6450 effect(TEMP crx);
6451
6452 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6453 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6454 %}
6455
6456 // shift != 0, base == 0
6457 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6458 match(Set dst (DecodeN src));
6459 predicate(CompressedOops::shift() != 0 &&
6460 CompressedOops::base() == nullptr);
6461
6462 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %}
6463 size(4);
6464 ins_encode %{
6465 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6466 %}
6467 ins_pipe(pipe_class_default);
6468 %}
6469
6470 // Optimize DecodeN for disjoint base.
6471 // Shift narrow oop and or it into register that already contains the heap base.
6472 // Base == dst must hold, and is assured by construction in postaloc_expand.
6473 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6474 match(Set dst (DecodeN src));
6475 effect(TEMP base);
6476 predicate(false);
6477
6478 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6479 size(4);
6480 ins_encode %{
6481 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift());
6482 %}
6483 ins_pipe(pipe_class_default);
6484 %}
6485
6486 // Optimize DecodeN for disjoint base.
6487 // This node requires only one cycle on the critical path.
6488 // We must postalloc_expand as we can not express use_def effects where
6489 // the used register is L and the def'ed register P.
6490 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6491 match(Set dst (DecodeN src));
6492 effect(TEMP_DEF dst);
6493 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6494 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6495 CompressedOops::base_disjoint());
6496 ins_cost(DEFAULT_COST);
6497
6498 format %{ "MOV $dst, heapbase \t\n"
6499 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6500 postalloc_expand %{
6501 loadBaseNode *n1 = new loadBaseNode();
6502 n1->add_req(nullptr);
6503 n1->_opnds[0] = op_dst;
6504
6505 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6506 n2->add_req(n_region, n_src, n1);
6507 n2->_opnds[0] = op_dst;
6508 n2->_opnds[1] = op_src;
6509 n2->_opnds[2] = op_dst;
6510 n2->_bottom_type = _bottom_type;
6511
6512 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6513 ra_->set_oop(n2, true);
6514
6515 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6516 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6517
6518 nodes->push(n1);
6519 nodes->push(n2);
6520 %}
6521 %}
6522
6523 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6524 match(Set dst (DecodeN src));
6525 effect(TEMP_DEF dst, TEMP crx);
6526 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6527 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6528 CompressedOops::base_disjoint());
6529 ins_cost(3 * DEFAULT_COST);
6530
6531 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %}
6532 postalloc_expand %{
6533 loadBaseNode *n1 = new loadBaseNode();
6534 n1->add_req(nullptr);
6535 n1->_opnds[0] = op_dst;
6536
6537 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
6538 n_compare->add_req(n_region, n_src);
6539 n_compare->_opnds[0] = op_crx;
6540 n_compare->_opnds[1] = op_src;
6541 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6542
6543 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6544 n2->add_req(n_region, n_src, n1);
6545 n2->_opnds[0] = op_dst;
6546 n2->_opnds[1] = op_src;
6547 n2->_opnds[2] = op_dst;
6548 n2->_bottom_type = _bottom_type;
6549
6550 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6551 n_cond_set->add_req(n_region, n_compare, n2);
6552 n_cond_set->_opnds[0] = op_dst;
6553 n_cond_set->_opnds[1] = op_crx;
6554 n_cond_set->_opnds[2] = op_dst;
6555 n_cond_set->_bottom_type = _bottom_type;
6556
6557 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6558 ra_->set_oop(n_cond_set, true);
6559
6560 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6561 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
6562 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6563 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6564
6565 nodes->push(n1);
6566 nodes->push(n_compare);
6567 nodes->push(n2);
6568 nodes->push(n_cond_set);
6569 %}
6570 %}
6571
6572 // src != 0, shift != 0, base != 0
6573 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6574 match(Set dst (DecodeN src));
6575 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6576 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6577 CompressedOops::shift() != 0 &&
6578 CompressedOops::base() != nullptr);
6579 ins_cost(2 * DEFAULT_COST);
6580
6581 format %{ "DecodeN $dst, $src \t// $src != nullptr, postalloc expanded" %}
6582 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6583 %}
6584
6585 // Compressed OOPs with narrow_oop_shift == 0.
6586 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6587 match(Set dst (DecodeN src));
6588 predicate(CompressedOops::shift() == 0);
6589 ins_cost(DEFAULT_COST);
6590
6591 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %}
6592 // variable size, 0 or 4.
6593 ins_encode %{
6594 __ mr_if_needed($dst$$Register, $src$$Register);
6595 %}
6596 ins_pipe(pipe_class_default);
6597 %}
6598
6599 // Convert compressed oop into int for vectors alignment masking.
6600 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
6601 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6602 predicate(CompressedOops::shift() == 0);
6603 ins_cost(DEFAULT_COST);
6604
6605 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %}
6606 // variable size, 0 or 4.
6607 ins_encode %{
6608 __ mr_if_needed($dst$$Register, $src$$Register);
6609 %}
6610 ins_pipe(pipe_class_default);
6611 %}
6612
6613 // Convert klass pointer into compressed form.
6614
6615 // Nodes for postalloc expand.
6616
6617 // Shift node for expand.
6618 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
6619 // The match rule is needed to make it a 'MachTypeNode'!
6620 match(Set dst (EncodePKlass src));
6621 predicate(false);
6622
6623 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6624 size(4);
6625 ins_encode %{
6626 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6627 %}
6628 ins_pipe(pipe_class_default);
6629 %}
6630
6631 // Add node for expand.
6632 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6633 // The match rule is needed to make it a 'MachTypeNode'!
6634 match(Set dst (EncodePKlass (Binary base src)));
6635 predicate(false);
6636
6637 format %{ "SUB $dst, $base, $src \t// encode" %}
6638 size(4);
6639 ins_encode %{
6640 __ subf($dst$$Register, $base$$Register, $src$$Register);
6641 %}
6642 ins_pipe(pipe_class_default);
6643 %}
6644
6645 // Disjoint narrow oop base.
6646 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
6647 match(Set dst (EncodePKlass src));
6648 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/);
6649
6650 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6651 size(4);
6652 ins_encode %{
6653 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
6654 %}
6655 ins_pipe(pipe_class_default);
6656 %}
6657
6658 // shift != 0, base != 0
6659 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6660 match(Set dst (EncodePKlass (Binary base src)));
6661 predicate(false);
6662
6663 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6664 postalloc_expand %{
6665 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
6666 n1->add_req(n_region, n_base, n_src);
6667 n1->_opnds[0] = op_dst;
6668 n1->_opnds[1] = op_base;
6669 n1->_opnds[2] = op_src;
6670 n1->_bottom_type = _bottom_type;
6671
6672 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode();
6673 n2->add_req(n_region, n1);
6674 n2->_opnds[0] = op_dst;
6675 n2->_opnds[1] = op_dst;
6676 n2->_bottom_type = _bottom_type;
6677 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6678 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6679
6680 nodes->push(n1);
6681 nodes->push(n2);
6682 %}
6683 %}
6684
6685 // shift != 0, base != 0
6686 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
6687 match(Set dst (EncodePKlass src));
6688 //predicate(CompressedKlassPointers::shift() != 0 &&
6689 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/);
6690
6691 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6692 ins_cost(DEFAULT_COST*2); // Don't count constant.
6693 expand %{
6694 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %}
6695 iRegLdst base;
6696 loadConL_Ex(base, baseImm);
6697 encodePKlass_not_null_Ex(dst, base, src);
6698 %}
6699 %}
6700
6701 // Decode nodes.
6702
6703 // Shift node for expand.
6704 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
6705 // The match rule is needed to make it a 'MachTypeNode'!
6706 match(Set dst (DecodeNKlass src));
6707 predicate(false);
6708
6709 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %}
6710 size(4);
6711 ins_encode %{
6712 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6713 %}
6714 ins_pipe(pipe_class_default);
6715 %}
6716
6717 // Add node for expand.
6718
6719 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6720 // The match rule is needed to make it a 'MachTypeNode'!
6721 match(Set dst (DecodeNKlass (Binary base src)));
6722 predicate(false);
6723
6724 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
6725 size(4);
6726 ins_encode %{
6727 __ add($dst$$Register, $base$$Register, $src$$Register);
6728 %}
6729 ins_pipe(pipe_class_default);
6730 %}
6731
6732 // src != 0, shift != 0, base != 0
6733 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
6734 match(Set dst (DecodeNKlass (Binary base src)));
6735 //effect(kill src); // We need a register for the immediate result after shifting.
6736 predicate(false);
6737
6738 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != nullptr, postalloc expanded" %}
6739 postalloc_expand %{
6740 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode();
6741 n1->add_req(n_region, n_base, n_src);
6742 n1->_opnds[0] = op_dst;
6743 n1->_opnds[1] = op_base;
6744 n1->_opnds[2] = op_src;
6745 n1->_bottom_type = _bottom_type;
6746
6747 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode();
6748 n2->add_req(n_region, n1);
6749 n2->_opnds[0] = op_dst;
6750 n2->_opnds[1] = op_dst;
6751 n2->_bottom_type = _bottom_type;
6752
6753 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6754 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6755
6756 nodes->push(n1);
6757 nodes->push(n2);
6758 %}
6759 %}
6760
6761 // src != 0, shift != 0, base != 0
6762 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
6763 match(Set dst (DecodeNKlass src));
6764 // predicate(CompressedKlassPointers::shift() != 0 &&
6765 // CompressedKlassPointers::base() != 0);
6766
6767 //format %{ "DecodeNKlass $dst, $src \t// $src != nullptr, expanded" %}
6768
6769 ins_cost(DEFAULT_COST*2); // Don't count constant.
6770 expand %{
6771 // We add first, then we shift. Like this, we can get along with one register less.
6772 // But we have to load the base pre-shifted.
6773 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %}
6774 iRegLdst base;
6775 loadConL_Ex(base, baseImm);
6776 decodeNKlass_notNull_addBase_Ex(dst, base, src);
6777 %}
6778 %}
6779
6780 //----------MemBar Instructions-----------------------------------------------
6781 // Memory barrier flavors
6782
6783 instruct membar_acquire() %{
6784 match(LoadFence);
6785 ins_cost(4*MEMORY_REF_COST);
6786
6787 format %{ "MEMBAR-acquire" %}
6788 size(4);
6789 ins_encode %{
6790 __ acquire();
6791 %}
6792 ins_pipe(pipe_class_default);
6793 %}
6794
6795 instruct unnecessary_membar_acquire() %{
6796 match(MemBarAcquire);
6797 ins_cost(0);
6798
6799 format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
6800 size(0);
6801 ins_encode( /*empty*/ );
6802 ins_pipe(pipe_class_default);
6803 %}
6804
6805 instruct membar_acquire_lock() %{
6806 match(MemBarAcquireLock);
6807 ins_cost(0);
6808
6809 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
6810 size(0);
6811 ins_encode( /*empty*/ );
6812 ins_pipe(pipe_class_default);
6813 %}
6814
6815 instruct membar_release() %{
6816 match(MemBarRelease);
6817 match(StoreFence);
6818 ins_cost(4*MEMORY_REF_COST);
6819
6820 format %{ "MEMBAR-release" %}
6821 size(4);
6822 ins_encode %{
6823 __ release();
6824 %}
6825 ins_pipe(pipe_class_default);
6826 %}
6827
6828 instruct membar_storestore() %{
6829 match(MemBarStoreStore);
6830 match(StoreStoreFence);
6831 ins_cost(4*MEMORY_REF_COST);
6832
6833 format %{ "MEMBAR-store-store" %}
6834 size(4);
6835 ins_encode %{
6836 __ membar(Assembler::StoreStore);
6837 %}
6838 ins_pipe(pipe_class_default);
6839 %}
6840
6841 instruct membar_release_lock() %{
6842 match(MemBarReleaseLock);
6843 ins_cost(0);
6844
6845 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
6846 size(0);
6847 ins_encode( /*empty*/ );
6848 ins_pipe(pipe_class_default);
6849 %}
6850
6851 instruct membar_storeload() %{
6852 match(MemBarStoreLoad);
6853 ins_cost(4*MEMORY_REF_COST);
6854
6855 format %{ "MEMBAR-store-load" %}
6856 size(4);
6857 ins_encode %{
6858 __ fence();
6859 %}
6860 ins_pipe(pipe_class_default);
6861 %}
6862
6863 instruct membar_volatile() %{
6864 match(MemBarVolatile);
6865 ins_cost(4*MEMORY_REF_COST);
6866
6867 format %{ "MEMBAR-volatile" %}
6868 size(4);
6869 ins_encode %{
6870 __ fence();
6871 %}
6872 ins_pipe(pipe_class_default);
6873 %}
6874
6875 // This optimization is wrong on PPC. The following pattern is not supported:
6876 // MemBarVolatile
6877 // ^ ^
6878 // | |
6879 // CtrlProj MemProj
6880 // ^ ^
6881 // | |
6882 // | Load
6883 // |
6884 // MemBarVolatile
6885 //
6886 // The first MemBarVolatile could get optimized out! According to
6887 // Vladimir, this pattern can not occur on Oracle platforms.
6888 // However, it does occur on PPC64 (because of membars in
6889 // inline_unsafe_load_store).
6890 //
6891 // Add this node again if we found a good solution for inline_unsafe_load_store().
6892 // Don't forget to look at the implementation of post_store_load_barrier again,
6893 // we did other fixes in that method.
6894 //instruct unnecessary_membar_volatile() %{
6895 // match(MemBarVolatile);
6896 // predicate(Matcher::post_store_load_barrier(n));
6897 // ins_cost(0);
6898 //
6899 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
6900 // size(0);
6901 // ins_encode( /*empty*/ );
6902 // ins_pipe(pipe_class_default);
6903 //%}
6904
6905 instruct membar_full() %{
6906 match(MemBarFull);
6907 ins_cost(4*MEMORY_REF_COST);
6908
6909 format %{ "MEMBAR-full" %}
6910 size(4);
6911 ins_encode %{
6912 __ fence();
6913 %}
6914 ins_pipe(pipe_class_default);
6915 %}
6916
6917 instruct membar_CPUOrder() %{
6918 match(MemBarCPUOrder);
6919 ins_cost(0);
6920
6921 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
6922 size(0);
6923 ins_encode( /*empty*/ );
6924 ins_pipe(pipe_class_default);
6925 %}
6926
6927 instruct onspinwait() %{
6928 match(OnSpinWait);
6929 ins_cost(DEFAULT_COST);
6930
6931 format %{ "OnSpinWait (smt_prio_low ; smt_prio_medium)" %}
6932 size(8);
6933 ins_encode %{
6934 __ block_comment("spin_wait {");
6935 __ smt_prio_low();
6936 __ smt_prio_medium();
6937 __ block_comment("}");
6938 %}
6939 ins_pipe(pipe_class_default);
6940 %}
6941
6942 //----------Conditional Move---------------------------------------------------
6943
6944 // Cmove using isel.
6945 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
6946 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
6947 ins_cost(DEFAULT_COST);
6948
6949 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6950 size(4);
6951 ins_encode %{
6952 int cc = $cmp$$cmpcode;
6953 __ isel($dst$$Register, $crx$$CondRegister,
6954 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6955 %}
6956 ins_pipe(pipe_class_default);
6957 %}
6958
6959 // Cmove using isel.
6960 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
6961 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
6962 ins_cost(DEFAULT_COST);
6963
6964 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6965 size(4);
6966 ins_encode %{
6967 int cc = $cmp$$cmpcode;
6968 __ isel($dst$$Register, $crx$$CondRegister,
6969 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6970 %}
6971 ins_pipe(pipe_class_default);
6972 %}
6973
6974 // Cmove using isel.
6975 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
6976 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
6977 ins_cost(DEFAULT_COST);
6978
6979 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6980 size(4);
6981 ins_encode %{
6982 int cc = $cmp$$cmpcode;
6983 __ isel($dst$$Register, $crx$$CondRegister,
6984 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
6985 %}
6986 ins_pipe(pipe_class_default);
6987 %}
6988
6989 // Cmove using isel.
6990 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
6991 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
6992 ins_cost(DEFAULT_COST);
6993
6994 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
6995 size(4);
6996 ins_encode %{
6997 int cc = $cmp$$cmpcode;
6998 __ isel($dst$$Register, $crx$$CondRegister,
6999 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7000 %}
7001 ins_pipe(pipe_class_default);
7002 %}
7003
7004 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
7005 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
7006 ins_cost(DEFAULT_COST+BRANCH_COST);
7007
7008 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7009 size(8);
7010 ins_encode %{
7011 Label done;
7012 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7013 // Branch if not (cmp crx).
7014 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7015 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7016 __ bind(done);
7017 %}
7018 ins_pipe(pipe_class_default);
7019 %}
7020
7021 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7022 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7023 ins_cost(DEFAULT_COST+BRANCH_COST);
7024
7025 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7026 size(8);
7027 ins_encode %{
7028 Label done;
7029 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7030 // Branch if not (cmp crx).
7031 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7032 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7033 __ bind(done);
7034 %}
7035 ins_pipe(pipe_class_default);
7036 %}
7037
7038 instruct cmovF_cmpF(cmpOp cop, regF op1, regF op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7039 match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7040 predicate(PowerArchitecturePPC64 >= 9);
7041 effect(TEMP tmp);
7042 ins_cost(2*DEFAULT_COST);
7043 format %{ "cmovF_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7044 size(8);
7045 ins_encode %{
7046 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7047 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7048 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7049 $tmp$$FloatRegister->to_vsr());
7050 %}
7051 ins_pipe(pipe_class_default);
7052 %}
7053
7054 instruct cmovF_cmpD(cmpOp cop, regD op1, regD op2, regF dst, regF false_result, regF true_result, regD tmp) %{
7055 match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7056 predicate(PowerArchitecturePPC64 >= 9);
7057 effect(TEMP tmp);
7058 ins_cost(2*DEFAULT_COST);
7059 format %{ "cmovF_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7060 size(8);
7061 ins_encode %{
7062 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7063 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7064 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7065 $tmp$$FloatRegister->to_vsr());
7066 %}
7067 ins_pipe(pipe_class_default);
7068 %}
7069
7070 instruct cmovD_cmpD(cmpOp cop, regD op1, regD op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7071 match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary false_result true_result)));
7072 predicate(PowerArchitecturePPC64 >= 9);
7073 effect(TEMP tmp);
7074 ins_cost(2*DEFAULT_COST);
7075 format %{ "cmovD_cmpD $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7076 size(8);
7077 ins_encode %{
7078 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7079 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7080 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7081 $tmp$$FloatRegister->to_vsr());
7082 %}
7083 ins_pipe(pipe_class_default);
7084 %}
7085
7086 instruct cmovD_cmpF(cmpOp cop, regF op1, regF op2, regD dst, regD false_result, regD true_result, regD tmp) %{
7087 match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary false_result true_result)));
7088 predicate(PowerArchitecturePPC64 >= 9);
7089 effect(TEMP tmp);
7090 ins_cost(2*DEFAULT_COST);
7091 format %{ "cmovD_cmpF $dst = ($op1 $cop $op2) ? $true_result : $false_result\n\t" %}
7092 size(8);
7093 ins_encode %{
7094 __ cmovF($cop$$cmpcode, $dst$$FloatRegister->to_vsr(),
7095 $op1$$FloatRegister->to_vsr(), $op2$$FloatRegister->to_vsr(),
7096 $true_result$$FloatRegister->to_vsr(), $false_result$$FloatRegister->to_vsr(),
7097 $tmp$$FloatRegister->to_vsr());
7098 %}
7099 ins_pipe(pipe_class_default);
7100 %}
7101
7102 //----------Compare-And-Swap---------------------------------------------------
7103
7104 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7105 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7106 // matched.
7107
7108 // Strong versions:
7109
7110 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7111 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7112 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7113 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7114 ins_encode %{
7115 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7116 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7117 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7118 $res$$Register, nullptr, true);
7119 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7120 __ isync();
7121 } else {
7122 __ sync();
7123 }
7124 %}
7125 ins_pipe(pipe_class_default);
7126 %}
7127
7128 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7129 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7130 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7131 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7132 ins_encode %{
7133 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7134 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7135 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7136 $res$$Register, nullptr, true);
7137 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7138 __ isync();
7139 } else {
7140 __ sync();
7141 }
7142 %}
7143 ins_pipe(pipe_class_default);
7144 %}
7145
7146 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7147 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7148 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7149 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7150 ins_encode %{
7151 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7152 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7153 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7154 $res$$Register, nullptr, true);
7155 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7156 __ isync();
7157 } else {
7158 __ sync();
7159 }
7160 %}
7161 ins_pipe(pipe_class_default);
7162 %}
7163
7164 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7165 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7166 predicate(n->as_LoadStore()->barrier_data() == 0);
7167 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7168 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7169 ins_encode %{
7170 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7171 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7172 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7173 $res$$Register, nullptr, true);
7174 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7175 __ isync();
7176 } else {
7177 __ sync();
7178 }
7179 %}
7180 ins_pipe(pipe_class_default);
7181 %}
7182
7183 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7184 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7185 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7186 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7187 ins_encode %{
7188 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7189 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7190 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7191 $res$$Register, nullptr, true);
7192 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7193 __ isync();
7194 } else {
7195 __ sync();
7196 }
7197 %}
7198 ins_pipe(pipe_class_default);
7199 %}
7200
7201 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7202 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7203 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7204 predicate(n->as_LoadStore()->barrier_data() == 0);
7205 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7206 ins_encode %{
7207 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7208 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7209 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7210 $res$$Register, nullptr, true);
7211 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7212 __ isync();
7213 } else {
7214 __ sync();
7215 }
7216 %}
7217 ins_pipe(pipe_class_default);
7218 %}
7219
7220 // Weak versions:
7221
7222 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7223 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7224 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7225 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7226 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7227 ins_encode %{
7228 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7229 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7230 MacroAssembler::MemBarNone,
7231 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7232 %}
7233 ins_pipe(pipe_class_default);
7234 %}
7235
7236 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7237 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7238 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) );
7239 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7240 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7241 ins_encode %{
7242 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7243 __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7244 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7245 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7246 %}
7247 ins_pipe(pipe_class_default);
7248 %}
7249
7250 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7251 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7252 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7253 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7254 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7255 ins_encode %{
7256 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7257 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7258 MacroAssembler::MemBarNone,
7259 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7260 %}
7261 ins_pipe(pipe_class_default);
7262 %}
7263
7264 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7265 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7266 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7267 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7268 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7269 ins_encode %{
7270 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7271 __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7272 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7273 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7274 %}
7275 ins_pipe(pipe_class_default);
7276 %}
7277
7278 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7279 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7280 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7281 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7282 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7283 ins_encode %{
7284 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7285 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7286 MacroAssembler::MemBarNone,
7287 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7288 %}
7289 ins_pipe(pipe_class_default);
7290 %}
7291
7292 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7293 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7294 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7295 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7296 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7297 ins_encode %{
7298 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7299 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7300 // value is never passed to caller.
7301 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7302 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7303 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7304 %}
7305 ins_pipe(pipe_class_default);
7306 %}
7307
7308 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7309 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7310 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7311 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7312 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7313 ins_encode %{
7314 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7315 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7316 MacroAssembler::MemBarNone,
7317 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7318 %}
7319 ins_pipe(pipe_class_default);
7320 %}
7321
7322 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7323 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7324 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7325 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7326 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7327 ins_encode %{
7328 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7329 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7330 // value is never passed to caller.
7331 __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7332 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7333 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7334 %}
7335 ins_pipe(pipe_class_default);
7336 %}
7337
7338 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7339 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7340 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7341 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7342 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7343 ins_encode %{
7344 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7345 // value is never passed to caller.
7346 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7347 MacroAssembler::MemBarNone,
7348 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7349 %}
7350 ins_pipe(pipe_class_default);
7351 %}
7352
7353 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7354 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7355 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7356 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7357 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7358 ins_encode %{
7359 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7360 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7361 // value is never passed to caller.
7362 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7363 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7364 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7365 %}
7366 ins_pipe(pipe_class_default);
7367 %}
7368
7369 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7370 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7371 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7372 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7373 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7374 ins_encode %{
7375 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7376 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7377 MacroAssembler::MemBarNone,
7378 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7379 %}
7380 ins_pipe(pipe_class_default);
7381 %}
7382
7383 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7384 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7385 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7386 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7387 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7388 ins_encode %{
7389 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7390 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7391 // value is never passed to caller.
7392 __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7393 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7394 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true);
7395 %}
7396 ins_pipe(pipe_class_default);
7397 %}
7398
7399 // CompareAndExchange
7400
7401 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7402 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7403 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7404 effect(TEMP_DEF res, TEMP cr0);
7405 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7406 ins_encode %{
7407 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7408 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7409 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7410 noreg, nullptr, true);
7411 %}
7412 ins_pipe(pipe_class_default);
7413 %}
7414
7415 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7416 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7417 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7418 effect(TEMP_DEF res, TEMP cr0);
7419 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7420 ins_encode %{
7421 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7422 __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7423 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7424 noreg, nullptr, true);
7425 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7426 __ isync();
7427 } else {
7428 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7429 __ sync();
7430 }
7431 %}
7432 ins_pipe(pipe_class_default);
7433 %}
7434
7435
7436 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7437 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7438 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7439 effect(TEMP_DEF res, TEMP cr0);
7440 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7441 ins_encode %{
7442 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7443 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7444 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7445 noreg, nullptr, true);
7446 %}
7447 ins_pipe(pipe_class_default);
7448 %}
7449
7450 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7451 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7452 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst));
7453 effect(TEMP_DEF res, TEMP cr0);
7454 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7455 ins_encode %{
7456 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7457 __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7458 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7459 noreg, nullptr, true);
7460 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7461 __ isync();
7462 } else {
7463 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7464 __ sync();
7465 }
7466 %}
7467 ins_pipe(pipe_class_default);
7468 %}
7469
7470 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7471 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7472 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7473 effect(TEMP_DEF res, TEMP cr0);
7474 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
7475 ins_encode %{
7476 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7477 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7478 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7479 noreg, nullptr, true);
7480 %}
7481 ins_pipe(pipe_class_default);
7482 %}
7483
7484 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7485 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7486 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7487 effect(TEMP_DEF res, TEMP cr0);
7488 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
7489 ins_encode %{
7490 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7491 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7492 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7493 noreg, nullptr, true);
7494 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7495 __ isync();
7496 } else {
7497 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7498 __ sync();
7499 }
7500 %}
7501 ins_pipe(pipe_class_default);
7502 %}
7503
7504 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7505 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7506 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && n->as_LoadStore()->barrier_data() == 0);
7507 effect(TEMP_DEF res, TEMP cr0);
7508 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7509 ins_encode %{
7510 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7511 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7512 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7513 noreg, nullptr, true);
7514 %}
7515 ins_pipe(pipe_class_default);
7516 %}
7517
7518 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7519 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
7520 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7521 effect(TEMP_DEF res, TEMP cr0);
7522 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
7523 ins_encode %{
7524 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7525 __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7526 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7527 noreg, nullptr, true);
7528 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7529 __ isync();
7530 } else {
7531 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7532 __ sync();
7533 }
7534 %}
7535 ins_pipe(pipe_class_default);
7536 %}
7537
7538 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7539 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7540 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7541 effect(TEMP_DEF res, TEMP cr0);
7542 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
7543 ins_encode %{
7544 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7545 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7546 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7547 noreg, nullptr, true);
7548 %}
7549 ins_pipe(pipe_class_default);
7550 %}
7551
7552 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7553 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
7554 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7555 effect(TEMP_DEF res, TEMP cr0);
7556 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
7557 ins_encode %{
7558 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7559 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7560 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7561 noreg, nullptr, true);
7562 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7563 __ isync();
7564 } else {
7565 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7566 __ sync();
7567 }
7568 %}
7569 ins_pipe(pipe_class_default);
7570 %}
7571
7572 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7573 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7574 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst)
7575 && n->as_LoadStore()->barrier_data() == 0);
7576 effect(TEMP_DEF res, TEMP cr0);
7577 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7578 ins_encode %{
7579 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7580 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7581 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7582 noreg, nullptr, true);
7583 %}
7584 ins_pipe(pipe_class_default);
7585 %}
7586
7587 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7588 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
7589 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst)
7590 && n->as_LoadStore()->barrier_data() == 0);
7591 effect(TEMP_DEF res, TEMP cr0);
7592 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
7593 ins_encode %{
7594 // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7595 __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7596 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7597 noreg, nullptr, true);
7598 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7599 __ isync();
7600 } else {
7601 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7602 __ sync();
7603 }
7604 %}
7605 ins_pipe(pipe_class_default);
7606 %}
7607
7608 // Special RMW
7609
7610 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7611 match(Set res (GetAndAddB mem_ptr src));
7612 effect(TEMP_DEF res, TEMP cr0);
7613 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
7614 ins_encode %{
7615 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
7616 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7617 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7618 __ isync();
7619 } else {
7620 __ sync();
7621 }
7622 %}
7623 ins_pipe(pipe_class_default);
7624 %}
7625
7626 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7627 match(Set res (GetAndAddS mem_ptr src));
7628 effect(TEMP_DEF res, TEMP cr0);
7629 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
7630 ins_encode %{
7631 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
7632 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7633 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7634 __ isync();
7635 } else {
7636 __ sync();
7637 }
7638 %}
7639 ins_pipe(pipe_class_default);
7640 %}
7641
7642
7643 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7644 match(Set res (GetAndAddI mem_ptr src));
7645 effect(TEMP_DEF res, TEMP cr0);
7646 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
7647 ins_encode %{
7648 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
7649 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7650 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7651 __ isync();
7652 } else {
7653 __ sync();
7654 }
7655 %}
7656 ins_pipe(pipe_class_default);
7657 %}
7658
7659 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7660 match(Set res (GetAndAddL mem_ptr src));
7661 effect(TEMP_DEF res, TEMP cr0);
7662 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
7663 ins_encode %{
7664 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
7665 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
7666 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7667 __ isync();
7668 } else {
7669 __ sync();
7670 }
7671 %}
7672 ins_pipe(pipe_class_default);
7673 %}
7674
7675 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7676 match(Set res (GetAndSetB mem_ptr src));
7677 effect(TEMP_DEF res, TEMP cr0);
7678 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
7679 ins_encode %{
7680 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
7681 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7682 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7683 __ isync();
7684 } else {
7685 __ sync();
7686 }
7687 %}
7688 ins_pipe(pipe_class_default);
7689 %}
7690
7691 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7692 match(Set res (GetAndSetS mem_ptr src));
7693 effect(TEMP_DEF res, TEMP cr0);
7694 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
7695 ins_encode %{
7696 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
7697 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
7698 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7699 __ isync();
7700 } else {
7701 __ sync();
7702 }
7703 %}
7704 ins_pipe(pipe_class_default);
7705 %}
7706
7707
7708 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7709 match(Set res (GetAndSetI mem_ptr src));
7710 effect(TEMP_DEF res, TEMP cr0);
7711 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
7712 ins_encode %{
7713 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7714 MacroAssembler::cmpxchgx_hint_atomic_update());
7715 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7716 __ isync();
7717 } else {
7718 __ sync();
7719 }
7720 %}
7721 ins_pipe(pipe_class_default);
7722 %}
7723
7724 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7725 match(Set res (GetAndSetL mem_ptr src));
7726 effect(TEMP_DEF res, TEMP cr0);
7727 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
7728 ins_encode %{
7729 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7730 MacroAssembler::cmpxchgx_hint_atomic_update());
7731 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7732 __ isync();
7733 } else {
7734 __ sync();
7735 }
7736 %}
7737 ins_pipe(pipe_class_default);
7738 %}
7739
7740 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
7741 match(Set res (GetAndSetP mem_ptr src));
7742 predicate(n->as_LoadStore()->barrier_data() == 0);
7743 effect(TEMP_DEF res, TEMP cr0);
7744 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
7745 ins_encode %{
7746 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
7747 MacroAssembler::cmpxchgx_hint_atomic_update());
7748 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7749 __ isync();
7750 } else {
7751 __ sync();
7752 }
7753 %}
7754 ins_pipe(pipe_class_default);
7755 %}
7756
7757 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
7758 match(Set res (GetAndSetN mem_ptr src));
7759 predicate(n->as_LoadStore()->barrier_data() == 0);
7760 effect(TEMP_DEF res, TEMP cr0);
7761 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
7762 ins_encode %{
7763 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
7764 MacroAssembler::cmpxchgx_hint_atomic_update());
7765 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7766 __ isync();
7767 } else {
7768 __ sync();
7769 }
7770 %}
7771 ins_pipe(pipe_class_default);
7772 %}
7773
7774 //----------Arithmetic Instructions--------------------------------------------
7775 // Addition Instructions
7776
7777 // Register Addition
7778 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
7779 match(Set dst (AddI src1 src2));
7780 format %{ "ADD $dst, $src1, $src2" %}
7781 size(4);
7782 ins_encode %{
7783 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7784 %}
7785 ins_pipe(pipe_class_default);
7786 %}
7787
7788 // Expand does not work with above instruct. (??)
7789 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7790 // no match-rule
7791 effect(DEF dst, USE src1, USE src2);
7792 format %{ "ADD $dst, $src1, $src2" %}
7793 size(4);
7794 ins_encode %{
7795 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7796 %}
7797 ins_pipe(pipe_class_default);
7798 %}
7799
7800 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
7801 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
7802 ins_cost(DEFAULT_COST*3);
7803
7804 expand %{
7805 // FIXME: we should do this in the ideal world.
7806 iRegIdst tmp1;
7807 iRegIdst tmp2;
7808 addI_reg_reg(tmp1, src1, src2);
7809 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
7810 addI_reg_reg(dst, tmp1, tmp2);
7811 %}
7812 %}
7813
7814 // Immediate Addition
7815 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
7816 match(Set dst (AddI src1 src2));
7817 format %{ "ADDI $dst, $src1, $src2" %}
7818 size(4);
7819 ins_encode %{
7820 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7821 %}
7822 ins_pipe(pipe_class_default);
7823 %}
7824
7825 // Immediate Addition with 16-bit shifted operand
7826 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
7827 match(Set dst (AddI src1 src2));
7828 format %{ "ADDIS $dst, $src1, $src2" %}
7829 size(4);
7830 ins_encode %{
7831 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7832 %}
7833 ins_pipe(pipe_class_default);
7834 %}
7835
7836 // Immediate Addition using prefixed addi
7837 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{
7838 match(Set dst (AddI src1 src2));
7839 predicate(PowerArchitecturePPC64 >= 10);
7840 ins_cost(DEFAULT_COST+1);
7841 format %{ "PADDI $dst, $src1, $src2" %}
7842 size(8);
7843 ins_encode %{
7844 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7845 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7846 %}
7847 ins_pipe(pipe_class_default);
7848 ins_alignment(2);
7849 %}
7850
7851 // Long Addition
7852 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7853 match(Set dst (AddL src1 src2));
7854 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7855 size(4);
7856 ins_encode %{
7857 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7858 %}
7859 ins_pipe(pipe_class_default);
7860 %}
7861
7862 // Expand does not work with above instruct. (??)
7863 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
7864 // no match-rule
7865 effect(DEF dst, USE src1, USE src2);
7866 format %{ "ADD $dst, $src1, $src2 \t// long" %}
7867 size(4);
7868 ins_encode %{
7869 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7870 %}
7871 ins_pipe(pipe_class_default);
7872 %}
7873
7874 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
7875 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
7876 ins_cost(DEFAULT_COST*3);
7877
7878 expand %{
7879 // FIXME: we should do this in the ideal world.
7880 iRegLdst tmp1;
7881 iRegLdst tmp2;
7882 addL_reg_reg(tmp1, src1, src2);
7883 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
7884 addL_reg_reg(dst, tmp1, tmp2);
7885 %}
7886 %}
7887
7888 // AddL + ConvL2I.
7889 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
7890 match(Set dst (ConvL2I (AddL src1 src2)));
7891
7892 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %}
7893 size(4);
7894 ins_encode %{
7895 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7896 %}
7897 ins_pipe(pipe_class_default);
7898 %}
7899
7900 // No constant pool entries required.
7901 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
7902 match(Set dst (AddL src1 src2));
7903
7904 format %{ "ADDI $dst, $src1, $src2" %}
7905 size(4);
7906 ins_encode %{
7907 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7908 %}
7909 ins_pipe(pipe_class_default);
7910 %}
7911
7912 // Long Immediate Addition with 16-bit shifted operand.
7913 // No constant pool entries required.
7914 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
7915 match(Set dst (AddL src1 src2));
7916
7917 format %{ "ADDIS $dst, $src1, $src2" %}
7918 size(4);
7919 ins_encode %{
7920 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7921 %}
7922 ins_pipe(pipe_class_default);
7923 %}
7924
7925 // Long Immediate Addition using prefixed addi
7926 // No constant pool entries required.
7927 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{
7928 match(Set dst (AddL src1 src2));
7929 predicate(PowerArchitecturePPC64 >= 10);
7930 ins_cost(DEFAULT_COST+1);
7931
7932 format %{ "PADDI $dst, $src1, $src2" %}
7933 size(8);
7934 ins_encode %{
7935 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7936 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7937 %}
7938 ins_pipe(pipe_class_default);
7939 ins_alignment(2);
7940 %}
7941
7942 // Pointer Register Addition
7943 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
7944 match(Set dst (AddP src1 src2));
7945 format %{ "ADD $dst, $src1, $src2" %}
7946 size(4);
7947 ins_encode %{
7948 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7949 %}
7950 ins_pipe(pipe_class_default);
7951 %}
7952
7953 // Pointer Immediate Addition
7954 // No constant pool entries required.
7955 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
7956 match(Set dst (AddP src1 src2));
7957
7958 format %{ "ADDI $dst, $src1, $src2" %}
7959 size(4);
7960 ins_encode %{
7961 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
7962 %}
7963 ins_pipe(pipe_class_default);
7964 %}
7965
7966 // Pointer Immediate Addition with 16-bit shifted operand.
7967 // No constant pool entries required.
7968 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
7969 match(Set dst (AddP src1 src2));
7970
7971 format %{ "ADDIS $dst, $src1, $src2" %}
7972 size(4);
7973 ins_encode %{
7974 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
7975 %}
7976 ins_pipe(pipe_class_default);
7977 %}
7978
7979 // Pointer Immediate Addition using prefixed addi
7980 // No constant pool entries required.
7981 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{
7982 match(Set dst (AddP src1 src2));
7983 predicate(PowerArchitecturePPC64 >= 10);
7984 ins_cost(DEFAULT_COST+1);
7985
7986 format %{ "PADDI $dst, $src1, $src2" %}
7987 size(8);
7988 ins_encode %{
7989 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
7990 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
7991 %}
7992 ins_pipe(pipe_class_default);
7993 ins_alignment(2);
7994 %}
7995
7996 //---------------------
7997 // Subtraction Instructions
7998
7999 // Register Subtraction
8000 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8001 match(Set dst (SubI src1 src2));
8002 format %{ "SUBF $dst, $src2, $src1" %}
8003 size(4);
8004 ins_encode %{
8005 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8006 %}
8007 ins_pipe(pipe_class_default);
8008 %}
8009
8010 // Immediate Subtraction
8011 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
8012 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
8013
8014 // SubI from constant (using subfic).
8015 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
8016 match(Set dst (SubI src1 src2));
8017 format %{ "SUBI $dst, $src1, $src2" %}
8018
8019 size(4);
8020 ins_encode %{
8021 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
8022 %}
8023 ins_pipe(pipe_class_default);
8024 %}
8025
8026 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
8027 // positive integers and 0xF...F for negative ones.
8028 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
8029 // no match-rule, false predicate
8030 effect(DEF dst, USE src);
8031 predicate(false);
8032
8033 format %{ "SRAWI $dst, $src, #31" %}
8034 size(4);
8035 ins_encode %{
8036 __ srawi($dst$$Register, $src$$Register, 0x1f);
8037 %}
8038 ins_pipe(pipe_class_default);
8039 %}
8040
8041 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
8042 match(Set dst (AbsI src));
8043 ins_cost(DEFAULT_COST*3);
8044
8045 expand %{
8046 iRegIdst tmp1;
8047 iRegIdst tmp2;
8048 signmask32I_regI(tmp1, src);
8049 xorI_reg_reg(tmp2, tmp1, src);
8050 subI_reg_reg(dst, tmp2, tmp1);
8051 %}
8052 %}
8053
8054 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
8055 match(Set dst (SubI zero src2));
8056 format %{ "NEG $dst, $src2" %}
8057 size(4);
8058 ins_encode %{
8059 __ neg($dst$$Register, $src2$$Register);
8060 %}
8061 ins_pipe(pipe_class_default);
8062 %}
8063
8064 // Long subtraction
8065 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8066 match(Set dst (SubL src1 src2));
8067 format %{ "SUBF $dst, $src2, $src1 \t// long" %}
8068 size(4);
8069 ins_encode %{
8070 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8071 %}
8072 ins_pipe(pipe_class_default);
8073 %}
8074
8075 // SubL + convL2I.
8076 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8077 match(Set dst (ConvL2I (SubL src1 src2)));
8078
8079 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
8080 size(4);
8081 ins_encode %{
8082 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8083 %}
8084 ins_pipe(pipe_class_default);
8085 %}
8086
8087 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8088 // positive longs and 0xF...F for negative ones.
8089 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8090 // no match-rule, false predicate
8091 effect(DEF dst, USE src);
8092 predicate(false);
8093
8094 format %{ "SRADI $dst, $src, #63" %}
8095 size(4);
8096 ins_encode %{
8097 __ sradi($dst$$Register, $src$$Register, 0x3f);
8098 %}
8099 ins_pipe(pipe_class_default);
8100 %}
8101
8102 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8103 // positive longs and 0xF...F for negative ones.
8104 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8105 // no match-rule, false predicate
8106 effect(DEF dst, USE src);
8107 predicate(false);
8108
8109 format %{ "SRADI $dst, $src, #63" %}
8110 size(4);
8111 ins_encode %{
8112 __ sradi($dst$$Register, $src$$Register, 0x3f);
8113 %}
8114 ins_pipe(pipe_class_default);
8115 %}
8116
8117 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{
8118 match(Set dst (AbsL src));
8119 ins_cost(DEFAULT_COST*3);
8120
8121 expand %{
8122 iRegLdst tmp1;
8123 iRegLdst tmp2;
8124 signmask64L_regL(tmp1, src);
8125 xorL_reg_reg(tmp2, tmp1, src);
8126 subL_reg_reg(dst, tmp2, tmp1);
8127 %}
8128 %}
8129
8130 // Long negation
8131 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8132 match(Set dst (SubL zero src2));
8133 format %{ "NEG $dst, $src2 \t// long" %}
8134 size(4);
8135 ins_encode %{
8136 __ neg($dst$$Register, $src2$$Register);
8137 %}
8138 ins_pipe(pipe_class_default);
8139 %}
8140
8141 // NegL + ConvL2I.
8142 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8143 match(Set dst (ConvL2I (SubL zero src2)));
8144
8145 format %{ "NEG $dst, $src2 \t// long + l2i" %}
8146 size(4);
8147 ins_encode %{
8148 __ neg($dst$$Register, $src2$$Register);
8149 %}
8150 ins_pipe(pipe_class_default);
8151 %}
8152
8153 // Multiplication Instructions
8154 // Integer Multiplication
8155
8156 // Register Multiplication
8157 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8158 match(Set dst (MulI src1 src2));
8159 ins_cost(DEFAULT_COST);
8160
8161 format %{ "MULLW $dst, $src1, $src2" %}
8162 size(4);
8163 ins_encode %{
8164 __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8165 %}
8166 ins_pipe(pipe_class_default);
8167 %}
8168
8169 // Immediate Multiplication
8170 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8171 match(Set dst (MulI src1 src2));
8172 ins_cost(DEFAULT_COST);
8173
8174 format %{ "MULLI $dst, $src1, $src2" %}
8175 size(4);
8176 ins_encode %{
8177 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8178 %}
8179 ins_pipe(pipe_class_default);
8180 %}
8181
8182 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8183 match(Set dst (MulL src1 src2));
8184 ins_cost(DEFAULT_COST);
8185
8186 format %{ "MULLD $dst $src1, $src2 \t// long" %}
8187 size(4);
8188 ins_encode %{
8189 __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8190 %}
8191 ins_pipe(pipe_class_default);
8192 %}
8193
8194 // Multiply high for optimized long division by constant.
8195 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8196 match(Set dst (MulHiL src1 src2));
8197 ins_cost(DEFAULT_COST);
8198
8199 format %{ "MULHD $dst $src1, $src2 \t// long" %}
8200 size(4);
8201 ins_encode %{
8202 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8203 %}
8204 ins_pipe(pipe_class_default);
8205 %}
8206
8207 instruct uMulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8208 match(Set dst (UMulHiL src1 src2));
8209 ins_cost(DEFAULT_COST);
8210
8211 format %{ "MULHDU $dst $src1, $src2 \t// unsigned long" %}
8212 size(4);
8213 ins_encode %{
8214 __ mulhdu($dst$$Register, $src1$$Register, $src2$$Register);
8215 %}
8216 ins_pipe(pipe_class_default);
8217 %}
8218
8219 // Immediate Multiplication
8220 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8221 match(Set dst (MulL src1 src2));
8222 ins_cost(DEFAULT_COST);
8223
8224 format %{ "MULLI $dst, $src1, $src2" %}
8225 size(4);
8226 ins_encode %{
8227 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8228 %}
8229 ins_pipe(pipe_class_default);
8230 %}
8231
8232 // Integer Division with Immediate -1: Negate.
8233 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8234 match(Set dst (DivI src1 src2));
8235 ins_cost(DEFAULT_COST);
8236
8237 format %{ "NEG $dst, $src1 \t// /-1" %}
8238 size(4);
8239 ins_encode %{
8240 __ neg($dst$$Register, $src1$$Register);
8241 %}
8242 ins_pipe(pipe_class_default);
8243 %}
8244
8245 // Integer Division with constant, but not -1.
8246 // We should be able to improve this by checking the type of src2.
8247 // It might well be that src2 is known to be positive.
8248 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8249 match(Set dst (DivI src1 src2));
8250 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8251 ins_cost(2*DEFAULT_COST);
8252
8253 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8254 size(4);
8255 ins_encode %{
8256 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8257 %}
8258 ins_pipe(pipe_class_default);
8259 %}
8260
8261 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8262 effect(USE_DEF dst, USE src1, USE crx);
8263 predicate(false);
8264
8265 format %{ "CMOVE $dst, neg($src1), $crx" %}
8266 size(8);
8267 ins_encode %{
8268 Label done;
8269 __ bne($crx$$CondRegister, done);
8270 __ neg($dst$$Register, $src1$$Register);
8271 __ bind(done);
8272 %}
8273 ins_pipe(pipe_class_default);
8274 %}
8275
8276 // Integer Division with Registers not containing constants.
8277 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8278 match(Set dst (DivI src1 src2));
8279 ins_cost(10*DEFAULT_COST);
8280
8281 expand %{
8282 immI16 imm %{ (int)-1 %}
8283 flagsReg tmp1;
8284 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8285 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8286 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8287 %}
8288 %}
8289
8290 // Long Division with Immediate -1: Negate.
8291 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8292 match(Set dst (DivL src1 src2));
8293 ins_cost(DEFAULT_COST);
8294
8295 format %{ "NEG $dst, $src1 \t// /-1, long" %}
8296 size(4);
8297 ins_encode %{
8298 __ neg($dst$$Register, $src1$$Register);
8299 %}
8300 ins_pipe(pipe_class_default);
8301 %}
8302
8303 // Long Division with constant, but not -1.
8304 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8305 match(Set dst (DivL src1 src2));
8306 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8307 ins_cost(2*DEFAULT_COST);
8308
8309 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8310 size(4);
8311 ins_encode %{
8312 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8313 %}
8314 ins_pipe(pipe_class_default);
8315 %}
8316
8317 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8318 effect(USE_DEF dst, USE src1, USE crx);
8319 predicate(false);
8320
8321 format %{ "CMOVE $dst, neg($src1), $crx" %}
8322 size(8);
8323 ins_encode %{
8324 Label done;
8325 __ bne($crx$$CondRegister, done);
8326 __ neg($dst$$Register, $src1$$Register);
8327 __ bind(done);
8328 %}
8329 ins_pipe(pipe_class_default);
8330 %}
8331
8332 // Long Division with Registers not containing constants.
8333 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8334 match(Set dst (DivL src1 src2));
8335 ins_cost(10*DEFAULT_COST);
8336
8337 expand %{
8338 immL16 imm %{ (int)-1 %}
8339 flagsReg tmp1;
8340 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8341 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8342 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8343 %}
8344 %}
8345
8346 // Integer Remainder with registers.
8347 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8348 match(Set dst (ModI src1 src2));
8349 ins_cost(10*DEFAULT_COST);
8350
8351 expand %{
8352 immI16 imm %{ (int)-1 %}
8353 flagsReg tmp1;
8354 iRegIdst tmp2;
8355 iRegIdst tmp3;
8356 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8357 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8358 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8359 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8360 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8361 %}
8362 %}
8363
8364 // Long Remainder with registers
8365 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8366 match(Set dst (ModL src1 src2));
8367 ins_cost(10*DEFAULT_COST);
8368
8369 expand %{
8370 immL16 imm %{ (int)-1 %}
8371 flagsReg tmp1;
8372 iRegLdst tmp2;
8373 iRegLdst tmp3;
8374 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8375 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8376 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8377 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8378 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8379 %}
8380 %}
8381
8382 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8383 match(Set dst (UDivI src1 src2));
8384 format %{ "DIVWU $dst, $src1, $src2" %}
8385 size(4);
8386 ins_encode %{
8387 __ divwu($dst$$Register, $src1$$Register, $src2$$Register);
8388 %}
8389 ins_pipe(pipe_class_default);
8390 %}
8391
8392 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8393 match(Set dst (UModI src1 src2));
8394 expand %{
8395 iRegIdst tmp1;
8396 iRegIdst tmp2;
8397 udivI_reg_reg(tmp1, src1, src2);
8398 // Compute lower 32 bit result using signed instructions as suggested by ISA.
8399 // Upper 32 bit will contain garbage.
8400 mulI_reg_reg(tmp2, src2, tmp1);
8401 subI_reg_reg(dst, src1, tmp2);
8402 %}
8403 %}
8404
8405 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8406 match(Set dst (UDivL src1 src2));
8407 format %{ "DIVDU $dst, $src1, $src2" %}
8408 size(4);
8409 ins_encode %{
8410 __ divdu($dst$$Register, $src1$$Register, $src2$$Register);
8411 %}
8412 ins_pipe(pipe_class_default);
8413 %}
8414
8415 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8416 match(Set dst (UModL src1 src2));
8417 expand %{
8418 iRegLdst tmp1;
8419 iRegLdst tmp2;
8420 udivL_reg_reg(tmp1, src1, src2);
8421 mulL_reg_reg(tmp2, src2, tmp1);
8422 subL_reg_reg(dst, src1, tmp2);
8423 %}
8424 %}
8425
8426 // Integer Shift Instructions
8427
8428 // Register Shift Left
8429
8430 // Clear all but the lowest #mask bits.
8431 // Used to normalize shift amounts in registers.
8432 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
8433 // no match-rule, false predicate
8434 effect(DEF dst, USE src, USE mask);
8435 predicate(false);
8436
8437 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %}
8438 size(4);
8439 ins_encode %{
8440 __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
8441 %}
8442 ins_pipe(pipe_class_default);
8443 %}
8444
8445 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8446 // no match-rule, false predicate
8447 effect(DEF dst, USE src1, USE src2);
8448 predicate(false);
8449
8450 format %{ "SLW $dst, $src1, $src2" %}
8451 size(4);
8452 ins_encode %{
8453 __ slw($dst$$Register, $src1$$Register, $src2$$Register);
8454 %}
8455 ins_pipe(pipe_class_default);
8456 %}
8457
8458 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8459 match(Set dst (LShiftI src1 src2));
8460 ins_cost(DEFAULT_COST*2);
8461 expand %{
8462 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8463 iRegIdst tmpI;
8464 maskI_reg_imm(tmpI, src2, mask);
8465 lShiftI_reg_reg(dst, src1, tmpI);
8466 %}
8467 %}
8468
8469 // Register Shift Left Immediate
8470 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8471 match(Set dst (LShiftI src1 src2));
8472
8473 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %}
8474 size(4);
8475 ins_encode %{
8476 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8477 %}
8478 ins_pipe(pipe_class_default);
8479 %}
8480
8481 // AndI with negpow2-constant + LShiftI
8482 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8483 match(Set dst (LShiftI (AndI src1 src2) src3));
8484 predicate(UseRotateAndMaskInstructionsPPC64);
8485
8486 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %}
8487 size(4);
8488 ins_encode %{
8489 long src3 = $src3$$constant;
8490 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8491 if (maskbits >= 32) {
8492 __ li($dst$$Register, 0); // addi
8493 } else {
8494 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
8495 }
8496 %}
8497 ins_pipe(pipe_class_default);
8498 %}
8499
8500 // RShiftI + AndI with negpow2-constant + LShiftI
8501 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
8502 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
8503 predicate(UseRotateAndMaskInstructionsPPC64);
8504
8505 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
8506 size(4);
8507 ins_encode %{
8508 long src3 = $src3$$constant;
8509 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
8510 if (maskbits >= 32) {
8511 __ li($dst$$Register, 0); // addi
8512 } else {
8513 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
8514 }
8515 %}
8516 ins_pipe(pipe_class_default);
8517 %}
8518
8519 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8520 // no match-rule, false predicate
8521 effect(DEF dst, USE src1, USE src2);
8522 predicate(false);
8523
8524 format %{ "SLD $dst, $src1, $src2" %}
8525 size(4);
8526 ins_encode %{
8527 __ sld($dst$$Register, $src1$$Register, $src2$$Register);
8528 %}
8529 ins_pipe(pipe_class_default);
8530 %}
8531
8532 // Register Shift Left
8533 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8534 match(Set dst (LShiftL src1 src2));
8535 ins_cost(DEFAULT_COST*2);
8536 expand %{
8537 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8538 iRegIdst tmpI;
8539 maskI_reg_imm(tmpI, src2, mask);
8540 lShiftL_regL_regI(dst, src1, tmpI);
8541 %}
8542 %}
8543
8544 // Register Shift Left Immediate
8545 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8546 match(Set dst (LShiftL src1 src2));
8547 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %}
8548 size(4);
8549 ins_encode %{
8550 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8551 %}
8552 ins_pipe(pipe_class_default);
8553 %}
8554
8555 // If we shift more than 32 bits, we need not convert I2L.
8556 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
8557 match(Set dst (LShiftL (ConvI2L src1) src2));
8558 ins_cost(DEFAULT_COST);
8559
8560 size(4);
8561 format %{ "SLDI $dst, i2l($src1), $src2" %}
8562 ins_encode %{
8563 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8564 %}
8565 ins_pipe(pipe_class_default);
8566 %}
8567
8568 // Shift a postivie int to the left.
8569 // Clrlsldi clears the upper 32 bits and shifts.
8570 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
8571 match(Set dst (LShiftL (ConvI2L src1) src2));
8572 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
8573
8574 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %}
8575 size(4);
8576 ins_encode %{
8577 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
8578 %}
8579 ins_pipe(pipe_class_default);
8580 %}
8581
8582 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8583 // no match-rule, false predicate
8584 effect(DEF dst, USE src1, USE src2);
8585 predicate(false);
8586
8587 format %{ "SRAW $dst, $src1, $src2" %}
8588 size(4);
8589 ins_encode %{
8590 __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
8591 %}
8592 ins_pipe(pipe_class_default);
8593 %}
8594
8595 // Register Arithmetic Shift Right
8596 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8597 match(Set dst (RShiftI src1 src2));
8598 ins_cost(DEFAULT_COST*2);
8599 expand %{
8600 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8601 iRegIdst tmpI;
8602 maskI_reg_imm(tmpI, src2, mask);
8603 arShiftI_reg_reg(dst, src1, tmpI);
8604 %}
8605 %}
8606
8607 // Register Arithmetic Shift Right Immediate
8608 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8609 match(Set dst (RShiftI src1 src2));
8610
8611 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %}
8612 size(4);
8613 ins_encode %{
8614 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8615 %}
8616 ins_pipe(pipe_class_default);
8617 %}
8618
8619 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8620 // no match-rule, false predicate
8621 effect(DEF dst, USE src1, USE src2);
8622 predicate(false);
8623
8624 format %{ "SRAD $dst, $src1, $src2" %}
8625 size(4);
8626 ins_encode %{
8627 __ srad($dst$$Register, $src1$$Register, $src2$$Register);
8628 %}
8629 ins_pipe(pipe_class_default);
8630 %}
8631
8632 // Register Shift Right Arithmetic Long
8633 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8634 match(Set dst (RShiftL src1 src2));
8635 ins_cost(DEFAULT_COST*2);
8636
8637 expand %{
8638 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8639 iRegIdst tmpI;
8640 maskI_reg_imm(tmpI, src2, mask);
8641 arShiftL_regL_regI(dst, src1, tmpI);
8642 %}
8643 %}
8644
8645 // Register Shift Right Immediate
8646 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8647 match(Set dst (RShiftL src1 src2));
8648
8649 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %}
8650 size(4);
8651 ins_encode %{
8652 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8653 %}
8654 ins_pipe(pipe_class_default);
8655 %}
8656
8657 // RShiftL + ConvL2I
8658 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8659 match(Set dst (ConvL2I (RShiftL src1 src2)));
8660
8661 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8662 size(4);
8663 ins_encode %{
8664 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8665 %}
8666 ins_pipe(pipe_class_default);
8667 %}
8668
8669 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8670 // no match-rule, false predicate
8671 effect(DEF dst, USE src1, USE src2);
8672 predicate(false);
8673
8674 format %{ "SRW $dst, $src1, $src2" %}
8675 size(4);
8676 ins_encode %{
8677 __ srw($dst$$Register, $src1$$Register, $src2$$Register);
8678 %}
8679 ins_pipe(pipe_class_default);
8680 %}
8681
8682 // Register Shift Right
8683 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8684 match(Set dst (URShiftI src1 src2));
8685 ins_cost(DEFAULT_COST*2);
8686
8687 expand %{
8688 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8689 iRegIdst tmpI;
8690 maskI_reg_imm(tmpI, src2, mask);
8691 urShiftI_reg_reg(dst, src1, tmpI);
8692 %}
8693 %}
8694
8695 // Register Shift Right Immediate
8696 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8697 match(Set dst (URShiftI src1 src2));
8698
8699 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %}
8700 size(4);
8701 ins_encode %{
8702 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8703 %}
8704 ins_pipe(pipe_class_default);
8705 %}
8706
8707 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8708 // no match-rule, false predicate
8709 effect(DEF dst, USE src1, USE src2);
8710 predicate(false);
8711
8712 format %{ "SRD $dst, $src1, $src2" %}
8713 size(4);
8714 ins_encode %{
8715 __ srd($dst$$Register, $src1$$Register, $src2$$Register);
8716 %}
8717 ins_pipe(pipe_class_default);
8718 %}
8719
8720 // Register Shift Right
8721 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
8722 match(Set dst (URShiftL src1 src2));
8723 ins_cost(DEFAULT_COST*2);
8724
8725 expand %{
8726 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
8727 iRegIdst tmpI;
8728 maskI_reg_imm(tmpI, src2, mask);
8729 urShiftL_regL_regI(dst, src1, tmpI);
8730 %}
8731 %}
8732
8733 // Register Shift Right Immediate
8734 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
8735 match(Set dst (URShiftL src1 src2));
8736
8737 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %}
8738 size(4);
8739 ins_encode %{
8740 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8741 %}
8742 ins_pipe(pipe_class_default);
8743 %}
8744
8745 // URShiftL + ConvL2I.
8746 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
8747 match(Set dst (ConvL2I (URShiftL src1 src2)));
8748
8749 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
8750 size(4);
8751 ins_encode %{
8752 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8753 %}
8754 ins_pipe(pipe_class_default);
8755 %}
8756
8757 // Register Shift Right Immediate with a CastP2X
8758 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
8759 match(Set dst (URShiftL (CastP2X src1) src2));
8760
8761 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
8762 size(4);
8763 ins_encode %{
8764 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
8765 %}
8766 ins_pipe(pipe_class_default);
8767 %}
8768
8769 // Bitfield Extract: URShiftI + AndI
8770 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
8771 match(Set dst (AndI (URShiftI src1 src2) src3));
8772
8773 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
8774 size(4);
8775 ins_encode %{
8776 int rshift = ($src2$$constant) & 0x1f;
8777 int length = log2i_exact((juint)$src3$$constant + 1u);
8778 if (rshift + length > 32) {
8779 // if necessary, adjust mask to omit rotated bits.
8780 length = 32 - rshift;
8781 }
8782 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8783 %}
8784 ins_pipe(pipe_class_default);
8785 %}
8786
8787 // Bitfield Extract: URShiftL + AndL
8788 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
8789 match(Set dst (AndL (URShiftL src1 src2) src3));
8790
8791 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
8792 size(4);
8793 ins_encode %{
8794 int rshift = ($src2$$constant) & 0x3f;
8795 int length = log2i_exact((julong)$src3$$constant + 1ull);
8796 if (rshift + length > 64) {
8797 // if necessary, adjust mask to omit rotated bits.
8798 length = 64 - rshift;
8799 }
8800 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
8801 %}
8802 ins_pipe(pipe_class_default);
8803 %}
8804
8805 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
8806 match(Set dst (ConvL2I (ConvI2L src)));
8807
8808 format %{ "EXTSW $dst, $src \t// int->int" %}
8809 size(4);
8810 ins_encode %{
8811 __ extsw($dst$$Register, $src$$Register);
8812 %}
8813 ins_pipe(pipe_class_default);
8814 %}
8815
8816 //----------Rotate Instructions------------------------------------------------
8817
8818 // Rotate Left by 8-bit immediate
8819 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
8820 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
8821 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8822
8823 format %{ "ROTLWI $dst, $src, $lshift" %}
8824 size(4);
8825 ins_encode %{
8826 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
8827 %}
8828 ins_pipe(pipe_class_default);
8829 %}
8830
8831 // Rotate Right by 8-bit immediate
8832 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
8833 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
8834 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8835
8836 format %{ "ROTRWI $dst, $rshift" %}
8837 size(4);
8838 ins_encode %{
8839 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
8840 %}
8841 ins_pipe(pipe_class_default);
8842 %}
8843
8844 //----------Floating Point Arithmetic Instructions-----------------------------
8845
8846 // Add float single precision
8847 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
8848 match(Set dst (AddF src1 src2));
8849
8850 format %{ "FADDS $dst, $src1, $src2" %}
8851 size(4);
8852 ins_encode %{
8853 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8854 %}
8855 ins_pipe(pipe_class_default);
8856 %}
8857
8858 // Add float double precision
8859 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
8860 match(Set dst (AddD src1 src2));
8861
8862 format %{ "FADD $dst, $src1, $src2" %}
8863 size(4);
8864 ins_encode %{
8865 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8866 %}
8867 ins_pipe(pipe_class_default);
8868 %}
8869
8870 // Sub float single precision
8871 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
8872 match(Set dst (SubF src1 src2));
8873
8874 format %{ "FSUBS $dst, $src1, $src2" %}
8875 size(4);
8876 ins_encode %{
8877 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8878 %}
8879 ins_pipe(pipe_class_default);
8880 %}
8881
8882 // Sub float double precision
8883 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
8884 match(Set dst (SubD src1 src2));
8885 format %{ "FSUB $dst, $src1, $src2" %}
8886 size(4);
8887 ins_encode %{
8888 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8889 %}
8890 ins_pipe(pipe_class_default);
8891 %}
8892
8893 // Mul float single precision
8894 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
8895 match(Set dst (MulF src1 src2));
8896 format %{ "FMULS $dst, $src1, $src2" %}
8897 size(4);
8898 ins_encode %{
8899 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8900 %}
8901 ins_pipe(pipe_class_default);
8902 %}
8903
8904 // Mul float double precision
8905 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
8906 match(Set dst (MulD src1 src2));
8907 format %{ "FMUL $dst, $src1, $src2" %}
8908 size(4);
8909 ins_encode %{
8910 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8911 %}
8912 ins_pipe(pipe_class_default);
8913 %}
8914
8915 // Div float single precision
8916 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
8917 match(Set dst (DivF src1 src2));
8918 format %{ "FDIVS $dst, $src1, $src2" %}
8919 size(4);
8920 ins_encode %{
8921 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8922 %}
8923 ins_pipe(pipe_class_default);
8924 %}
8925
8926 // Div float double precision
8927 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
8928 match(Set dst (DivD src1 src2));
8929 format %{ "FDIV $dst, $src1, $src2" %}
8930 size(4);
8931 ins_encode %{
8932 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8933 %}
8934 ins_pipe(pipe_class_default);
8935 %}
8936
8937 // Absolute float single precision
8938 instruct absF_reg(regF dst, regF src) %{
8939 match(Set dst (AbsF src));
8940 format %{ "FABS $dst, $src \t// float" %}
8941 size(4);
8942 ins_encode %{
8943 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8944 %}
8945 ins_pipe(pipe_class_default);
8946 %}
8947
8948 // Absolute float double precision
8949 instruct absD_reg(regD dst, regD src) %{
8950 match(Set dst (AbsD src));
8951 format %{ "FABS $dst, $src \t// double" %}
8952 size(4);
8953 ins_encode %{
8954 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
8955 %}
8956 ins_pipe(pipe_class_default);
8957 %}
8958
8959 instruct negF_reg(regF dst, regF src) %{
8960 match(Set dst (NegF src));
8961 format %{ "FNEG $dst, $src \t// float" %}
8962 size(4);
8963 ins_encode %{
8964 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8965 %}
8966 ins_pipe(pipe_class_default);
8967 %}
8968
8969 instruct negD_reg(regD dst, regD src) %{
8970 match(Set dst (NegD src));
8971 format %{ "FNEG $dst, $src \t// double" %}
8972 size(4);
8973 ins_encode %{
8974 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
8975 %}
8976 ins_pipe(pipe_class_default);
8977 %}
8978
8979 // AbsF + NegF.
8980 instruct negF_absF_reg(regF dst, regF src) %{
8981 match(Set dst (NegF (AbsF src)));
8982 format %{ "FNABS $dst, $src \t// float" %}
8983 size(4);
8984 ins_encode %{
8985 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
8986 %}
8987 ins_pipe(pipe_class_default);
8988 %}
8989
8990 // AbsD + NegD.
8991 instruct negD_absD_reg(regD dst, regD src) %{
8992 match(Set dst (NegD (AbsD src)));
8993 format %{ "FNABS $dst, $src \t// double" %}
8994 size(4);
8995 ins_encode %{
8996 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
8997 %}
8998 ins_pipe(pipe_class_default);
8999 %}
9000
9001 // Sqrt float double precision
9002 instruct sqrtD_reg(regD dst, regD src) %{
9003 match(Set dst (SqrtD src));
9004 format %{ "FSQRT $dst, $src" %}
9005 size(4);
9006 ins_encode %{
9007 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
9008 %}
9009 ins_pipe(pipe_class_default);
9010 %}
9011
9012 // Single-precision sqrt.
9013 instruct sqrtF_reg(regF dst, regF src) %{
9014 match(Set dst (SqrtF src));
9015 ins_cost(DEFAULT_COST);
9016
9017 format %{ "FSQRTS $dst, $src" %}
9018 size(4);
9019 ins_encode %{
9020 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
9021 %}
9022 ins_pipe(pipe_class_default);
9023 %}
9024
9025
9026 // Multiply-Accumulate
9027 // src1 * src2 + src3
9028 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9029 match(Set dst (FmaF src3 (Binary src1 src2)));
9030
9031 format %{ "FMADDS $dst, $src1, $src2, $src3" %}
9032 size(4);
9033 ins_encode %{
9034 assert(UseFMA, "Needs FMA instructions support.");
9035 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9036 %}
9037 ins_pipe(pipe_class_default);
9038 %}
9039
9040 // src1 * src2 + src3
9041 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9042 match(Set dst (FmaD src3 (Binary src1 src2)));
9043
9044 format %{ "FMADD $dst, $src1, $src2, $src3" %}
9045 size(4);
9046 ins_encode %{
9047 assert(UseFMA, "Needs FMA instructions support.");
9048 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9049 %}
9050 ins_pipe(pipe_class_default);
9051 %}
9052
9053 // src1 * (-src2) + src3 = -(src1*src2-src3)
9054 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9055 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9056 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
9057
9058 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
9059 size(4);
9060 ins_encode %{
9061 assert(UseFMA, "Needs FMA instructions support.");
9062 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9063 %}
9064 ins_pipe(pipe_class_default);
9065 %}
9066
9067 // src1 * (-src2) + src3 = -(src1*src2-src3)
9068 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
9069 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9070 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
9071
9072 format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
9073 size(4);
9074 ins_encode %{
9075 assert(UseFMA, "Needs FMA instructions support.");
9076 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9077 %}
9078 ins_pipe(pipe_class_default);
9079 %}
9080
9081 // src1 * (-src2) - src3 = -(src1*src2+src3)
9082 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9083 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9084 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
9085
9086 format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
9087 size(4);
9088 ins_encode %{
9089 assert(UseFMA, "Needs FMA instructions support.");
9090 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9091 %}
9092 ins_pipe(pipe_class_default);
9093 %}
9094
9095 // src1 * (-src2) - src3 = -(src1*src2+src3)
9096 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
9097 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9098 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9099
9100 format %{ "FNMADD $dst, $src1, $src2, $src3" %}
9101 size(4);
9102 ins_encode %{
9103 assert(UseFMA, "Needs FMA instructions support.");
9104 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9105 %}
9106 ins_pipe(pipe_class_default);
9107 %}
9108
9109 // src1 * src2 - src3
9110 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9111 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9112
9113 format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
9114 size(4);
9115 ins_encode %{
9116 assert(UseFMA, "Needs FMA instructions support.");
9117 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9118 %}
9119 ins_pipe(pipe_class_default);
9120 %}
9121
9122 // src1 * src2 - src3
9123 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9124 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9125
9126 format %{ "FMSUB $dst, $src1, $src2, $src3" %}
9127 size(4);
9128 ins_encode %{
9129 assert(UseFMA, "Needs FMA instructions support.");
9130 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9131 %}
9132 ins_pipe(pipe_class_default);
9133 %}
9134
9135
9136 //----------Logical Instructions-----------------------------------------------
9137
9138 // And Instructions
9139
9140 // Register And
9141 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9142 match(Set dst (AndI src1 src2));
9143 format %{ "AND $dst, $src1, $src2" %}
9144 size(4);
9145 ins_encode %{
9146 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9147 %}
9148 ins_pipe(pipe_class_default);
9149 %}
9150
9151 instruct andI_reg_immI(iRegIdst dst, iRegIsrc src1, immI src2, flagsRegCR0 cr0) %{
9152 match(Set dst (AndI src1 src2));
9153 predicate(Assembler::andi_supports((juint)(n->in(2)->get_int())));
9154 effect(KILL cr0);
9155 format %{ "ANDI $dst, $src1, $src2" %}
9156 size(4);
9157 ins_encode %{
9158 __ andi($dst$$Register, $src1$$Register, (juint)$src2$$constant); // optimized version
9159 %}
9160 ins_pipe(pipe_class_default);
9161 %}
9162
9163 // Register And Long
9164 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9165 match(Set dst (AndL src1 src2));
9166 ins_cost(DEFAULT_COST);
9167
9168 format %{ "AND $dst, $src1, $src2 \t// long" %}
9169 size(4);
9170 ins_encode %{
9171 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9172 %}
9173 ins_pipe(pipe_class_default);
9174 %}
9175
9176 instruct andL_reg_immL(iRegLdst dst, iRegLsrc src1, immL src2, flagsRegCR0 cr0) %{
9177 match(Set dst (AndL src1 src2));
9178 predicate(Assembler::andi_supports(n->in(2)->get_long()));
9179 effect(KILL cr0);
9180 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9181 size(4);
9182 ins_encode %{
9183 __ andi($dst$$Register, $src1$$Register, $src2$$constant); // optimized version
9184 %}
9185 ins_pipe(pipe_class_default);
9186 %}
9187
9188 // AndL + ConvL2I.
9189 instruct convL2I_andL_reg_immL(iRegIdst dst, iRegLsrc src1, immL src2, flagsRegCR0 cr0) %{
9190 match(Set dst (ConvL2I (AndL src1 src2)));
9191 predicate(Assembler::andi_supports(n->in(1)->in(2)->get_long()));
9192 effect(KILL cr0);
9193 format %{ "ANDI $dst, $src1, $src2 \t// long + l2i" %}
9194 size(4);
9195 ins_encode %{
9196 __ andi($dst$$Register, $src1$$Register, $src2$$constant); // optimized version
9197 %}
9198 ins_pipe(pipe_class_default);
9199 %}
9200
9201 // Or Instructions
9202
9203 // Register Or
9204 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9205 match(Set dst (OrI src1 src2));
9206 format %{ "OR $dst, $src1, $src2" %}
9207 size(4);
9208 ins_encode %{
9209 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9210 %}
9211 ins_pipe(pipe_class_default);
9212 %}
9213
9214 // Expand does not work with above instruct. (??)
9215 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9216 // no match-rule
9217 effect(DEF dst, USE src1, USE src2);
9218 format %{ "OR $dst, $src1, $src2" %}
9219 size(4);
9220 ins_encode %{
9221 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9222 %}
9223 ins_pipe(pipe_class_default);
9224 %}
9225
9226 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9227 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9228 ins_cost(DEFAULT_COST*3);
9229
9230 expand %{
9231 // FIXME: we should do this in the ideal world.
9232 iRegIdst tmp1;
9233 iRegIdst tmp2;
9234 orI_reg_reg(tmp1, src1, src2);
9235 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9236 orI_reg_reg(dst, tmp1, tmp2);
9237 %}
9238 %}
9239
9240 // Immediate Or
9241 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9242 match(Set dst (OrI src1 src2));
9243 format %{ "ORI $dst, $src1, $src2" %}
9244 size(4);
9245 ins_encode %{
9246 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9247 %}
9248 ins_pipe(pipe_class_default);
9249 %}
9250
9251 // Register Or Long
9252 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9253 match(Set dst (OrL src1 src2));
9254 ins_cost(DEFAULT_COST);
9255
9256 size(4);
9257 format %{ "OR $dst, $src1, $src2 \t// long" %}
9258 ins_encode %{
9259 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9260 %}
9261 ins_pipe(pipe_class_default);
9262 %}
9263
9264 // OrL + ConvL2I.
9265 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9266 match(Set dst (ConvL2I (OrL src1 src2)));
9267 ins_cost(DEFAULT_COST);
9268
9269 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %}
9270 size(4);
9271 ins_encode %{
9272 __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9273 %}
9274 ins_pipe(pipe_class_default);
9275 %}
9276
9277 // Immediate Or long
9278 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9279 match(Set dst (OrL src1 con));
9280 ins_cost(DEFAULT_COST);
9281
9282 format %{ "ORI $dst, $src1, $con \t// long" %}
9283 size(4);
9284 ins_encode %{
9285 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9286 %}
9287 ins_pipe(pipe_class_default);
9288 %}
9289
9290 // Xor Instructions
9291
9292 // Register Xor
9293 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9294 match(Set dst (XorI src1 src2));
9295 format %{ "XOR $dst, $src1, $src2" %}
9296 size(4);
9297 ins_encode %{
9298 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9299 %}
9300 ins_pipe(pipe_class_default);
9301 %}
9302
9303 // Expand does not work with above instruct. (??)
9304 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9305 // no match-rule
9306 effect(DEF dst, USE src1, USE src2);
9307 format %{ "XOR $dst, $src1, $src2" %}
9308 size(4);
9309 ins_encode %{
9310 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9311 %}
9312 ins_pipe(pipe_class_default);
9313 %}
9314
9315 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9316 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
9317 ins_cost(DEFAULT_COST*3);
9318
9319 expand %{
9320 // FIXME: we should do this in the ideal world.
9321 iRegIdst tmp1;
9322 iRegIdst tmp2;
9323 xorI_reg_reg(tmp1, src1, src2);
9324 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
9325 xorI_reg_reg(dst, tmp1, tmp2);
9326 %}
9327 %}
9328
9329 // Immediate Xor
9330 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9331 match(Set dst (XorI src1 src2));
9332 format %{ "XORI $dst, $src1, $src2" %}
9333 size(4);
9334 ins_encode %{
9335 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9336 %}
9337 ins_pipe(pipe_class_default);
9338 %}
9339
9340 // Register Xor Long
9341 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9342 match(Set dst (XorL src1 src2));
9343 ins_cost(DEFAULT_COST);
9344
9345 format %{ "XOR $dst, $src1, $src2 \t// long" %}
9346 size(4);
9347 ins_encode %{
9348 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9349 %}
9350 ins_pipe(pipe_class_default);
9351 %}
9352
9353 // XorL + ConvL2I.
9354 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9355 match(Set dst (ConvL2I (XorL src1 src2)));
9356 ins_cost(DEFAULT_COST);
9357
9358 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %}
9359 size(4);
9360 ins_encode %{
9361 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9362 %}
9363 ins_pipe(pipe_class_default);
9364 %}
9365
9366 // Immediate Xor Long
9367 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
9368 match(Set dst (XorL src1 src2));
9369 ins_cost(DEFAULT_COST);
9370
9371 format %{ "XORI $dst, $src1, $src2 \t// long" %}
9372 size(4);
9373 ins_encode %{
9374 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9375 %}
9376 ins_pipe(pipe_class_default);
9377 %}
9378
9379 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
9380 match(Set dst (XorI src1 src2));
9381 ins_cost(DEFAULT_COST);
9382
9383 format %{ "NOT $dst, $src1 ($src2)" %}
9384 size(4);
9385 ins_encode %{
9386 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9387 %}
9388 ins_pipe(pipe_class_default);
9389 %}
9390
9391 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
9392 match(Set dst (XorL src1 src2));
9393 ins_cost(DEFAULT_COST);
9394
9395 format %{ "NOT $dst, $src1 ($src2) \t// long" %}
9396 size(4);
9397 ins_encode %{
9398 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
9399 %}
9400 ins_pipe(pipe_class_default);
9401 %}
9402
9403 // And-complement
9404 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
9405 match(Set dst (AndI (XorI src1 src2) src3));
9406 ins_cost(DEFAULT_COST);
9407
9408 format %{ "ANDW $dst, xori($src1, $src2), $src3" %}
9409 size(4);
9410 ins_encode( enc_andc(dst, src3, src1) );
9411 ins_pipe(pipe_class_default);
9412 %}
9413
9414 // And-complement
9415 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9416 // no match-rule, false predicate
9417 effect(DEF dst, USE src1, USE src2);
9418 predicate(false);
9419
9420 format %{ "ANDC $dst, $src1, $src2" %}
9421 size(4);
9422 ins_encode %{
9423 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
9424 %}
9425 ins_pipe(pipe_class_default);
9426 %}
9427
9428 //----------Moves between int/long and float/double----------------------------
9429 //
9430 // The following rules move values from int/long registers/stack-locations
9431 // to float/double registers/stack-locations and vice versa, without doing any
9432 // conversions. These rules are used to implement the bit-conversion methods
9433 // of java.lang.Float etc., e.g.
9434 // int floatToIntBits(float value)
9435 // float intBitsToFloat(int bits)
9436
9437 instruct moveL2D_reg(regD dst, iRegLsrc src) %{
9438 match(Set dst (MoveL2D src));
9439
9440 format %{ "MTFPRD $dst, $src" %}
9441 size(4);
9442 ins_encode %{
9443 __ mtfprd($dst$$FloatRegister, $src$$Register);
9444 %}
9445 ins_pipe(pipe_class_default);
9446 %}
9447
9448 instruct moveI2D_reg(regD dst, iRegIsrc src) %{
9449 // no match-rule, false predicate
9450 effect(DEF dst, USE src);
9451 predicate(false);
9452
9453 format %{ "MTFPRWA $dst, $src" %}
9454 size(4);
9455 ins_encode %{
9456 __ mtfprwa($dst$$FloatRegister, $src$$Register);
9457 %}
9458 ins_pipe(pipe_class_default);
9459 %}
9460
9461 //---------- Chain stack slots between similar types --------
9462
9463 // These are needed so that the rules below can match.
9464
9465 // Load integer from stack slot
9466 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
9467 match(Set dst src);
9468 ins_cost(MEMORY_REF_COST);
9469
9470 format %{ "LWZ $dst, $src" %}
9471 size(4);
9472 ins_encode( enc_lwz(dst, src) );
9473 ins_pipe(pipe_class_memory);
9474 %}
9475
9476 // Store integer to stack slot
9477 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
9478 match(Set dst src);
9479 ins_cost(MEMORY_REF_COST);
9480
9481 format %{ "STW $src, $dst \t// stk" %}
9482 size(4);
9483 ins_encode( enc_stw(src, dst) ); // rs=rt
9484 ins_pipe(pipe_class_memory);
9485 %}
9486
9487 // Load long from stack slot
9488 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
9489 match(Set dst src);
9490 ins_cost(MEMORY_REF_COST);
9491
9492 format %{ "LD $dst, $src \t// long" %}
9493 size(4);
9494 ins_encode( enc_ld(dst, src) );
9495 ins_pipe(pipe_class_memory);
9496 %}
9497
9498 // Store long to stack slot
9499 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
9500 match(Set dst src);
9501 ins_cost(MEMORY_REF_COST);
9502
9503 format %{ "STD $src, $dst \t// long" %}
9504 size(4);
9505 ins_encode( enc_std(src, dst) ); // rs=rt
9506 ins_pipe(pipe_class_memory);
9507 %}
9508
9509 //----------Moves between int and float
9510
9511 // Move float value from float stack-location to integer register.
9512 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
9513 match(Set dst (MoveF2I src));
9514 ins_cost(MEMORY_REF_COST);
9515
9516 format %{ "LWZ $dst, $src \t// MoveF2I" %}
9517 size(4);
9518 ins_encode( enc_lwz(dst, src) );
9519 ins_pipe(pipe_class_memory);
9520 %}
9521
9522 // Move float value from float register to integer stack-location.
9523 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
9524 match(Set dst (MoveF2I src));
9525 ins_cost(MEMORY_REF_COST);
9526
9527 format %{ "STFS $src, $dst \t// MoveF2I" %}
9528 size(4);
9529 ins_encode( enc_stfs(src, dst) );
9530 ins_pipe(pipe_class_memory);
9531 %}
9532
9533 // Move integer value from integer stack-location to float register.
9534 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
9535 match(Set dst (MoveI2F src));
9536 ins_cost(MEMORY_REF_COST);
9537
9538 format %{ "LFS $dst, $src \t// MoveI2F" %}
9539 size(4);
9540 ins_encode %{
9541 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
9542 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
9543 %}
9544 ins_pipe(pipe_class_memory);
9545 %}
9546
9547 // Move integer value from integer register to float stack-location.
9548 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
9549 match(Set dst (MoveI2F src));
9550 ins_cost(MEMORY_REF_COST);
9551
9552 format %{ "STW $src, $dst \t// MoveI2F" %}
9553 size(4);
9554 ins_encode( enc_stw(src, dst) );
9555 ins_pipe(pipe_class_memory);
9556 %}
9557
9558
9559 //----------Moves between long and double
9560
9561 // Move double value from double stack-location to long register.
9562 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
9563 match(Set dst (MoveD2L src));
9564 ins_cost(MEMORY_REF_COST);
9565 size(4);
9566 format %{ "LD $dst, $src \t// MoveD2L" %}
9567 ins_encode( enc_ld(dst, src) );
9568 ins_pipe(pipe_class_memory);
9569 %}
9570
9571 // Move double value from double register to long stack-location.
9572 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
9573 match(Set dst (MoveD2L src));
9574 effect(DEF dst, USE src);
9575 ins_cost(MEMORY_REF_COST);
9576
9577 format %{ "STFD $src, $dst \t// MoveD2L" %}
9578 size(4);
9579 ins_encode( enc_stfd(src, dst) );
9580 ins_pipe(pipe_class_memory);
9581 %}
9582
9583
9584 //----------Register Move Instructions-----------------------------------------
9585
9586 // Replicate for Superword
9587
9588 instruct moveReg(iRegLdst dst, iRegIsrc src) %{
9589 predicate(false);
9590 effect(DEF dst, USE src);
9591
9592 format %{ "MR $dst, $src \t// replicate " %}
9593 // variable size, 0 or 4.
9594 ins_encode %{
9595 __ mr_if_needed($dst$$Register, $src$$Register);
9596 %}
9597 ins_pipe(pipe_class_default);
9598 %}
9599
9600 //----------Cast instructions (Java-level type cast)---------------------------
9601
9602 // Cast Long to Pointer for unsafe natives.
9603 instruct castX2P(iRegPdst dst, iRegLsrc src) %{
9604 match(Set dst (CastX2P src));
9605
9606 format %{ "MR $dst, $src \t// Long->Ptr" %}
9607 // variable size, 0 or 4.
9608 ins_encode %{
9609 __ mr_if_needed($dst$$Register, $src$$Register);
9610 %}
9611 ins_pipe(pipe_class_default);
9612 %}
9613
9614 // Cast Pointer to Long for unsafe natives.
9615 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
9616 match(Set dst (CastP2X src));
9617
9618 format %{ "MR $dst, $src \t// Ptr->Long" %}
9619 // variable size, 0 or 4.
9620 ins_encode %{
9621 __ mr_if_needed($dst$$Register, $src$$Register);
9622 %}
9623 ins_pipe(pipe_class_default);
9624 %}
9625
9626 instruct castPP(iRegPdst dst) %{
9627 match(Set dst (CastPP dst));
9628 format %{ " -- \t// castPP of $dst" %}
9629 size(0);
9630 ins_encode( /*empty*/ );
9631 ins_pipe(pipe_class_default);
9632 %}
9633
9634 instruct castII(iRegIdst dst) %{
9635 match(Set dst (CastII dst));
9636 format %{ " -- \t// castII of $dst" %}
9637 size(0);
9638 ins_encode( /*empty*/ );
9639 ins_pipe(pipe_class_default);
9640 %}
9641
9642 instruct castLL(iRegLdst dst) %{
9643 match(Set dst (CastLL dst));
9644 format %{ " -- \t// castLL of $dst" %}
9645 size(0);
9646 ins_encode( /*empty*/ );
9647 ins_pipe(pipe_class_default);
9648 %}
9649
9650 instruct castFF(regF dst) %{
9651 match(Set dst (CastFF dst));
9652 format %{ " -- \t// castFF of $dst" %}
9653 size(0);
9654 ins_encode( /*empty*/ );
9655 ins_pipe(pipe_class_default);
9656 %}
9657
9658 instruct castDD(regD dst) %{
9659 match(Set dst (CastDD dst));
9660 format %{ " -- \t// castDD of $dst" %}
9661 size(0);
9662 ins_encode( /*empty*/ );
9663 ins_pipe(pipe_class_default);
9664 %}
9665
9666 instruct castVV8(iRegLdst dst) %{
9667 match(Set dst (CastVV dst));
9668 format %{ " -- \t// castVV of $dst" %}
9669 size(0);
9670 ins_encode( /*empty*/ );
9671 ins_pipe(pipe_class_default);
9672 %}
9673
9674 instruct castVV16(vecX 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 checkCastPP(iRegPdst dst) %{
9683 match(Set dst (CheckCastPP dst));
9684 format %{ " -- \t// checkcastPP of $dst" %}
9685 size(0);
9686 ins_encode( /*empty*/ );
9687 ins_pipe(pipe_class_default);
9688 %}
9689
9690 //----------Convert instructions-----------------------------------------------
9691
9692 // Convert to boolean.
9693
9694 // int_to_bool(src) : { 1 if src != 0
9695 // { 0 else
9696 //
9697 // strategy:
9698 // 1) Count leading zeros of 32 bit-value src,
9699 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
9700 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9701 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9702
9703 // convI2Bool
9704 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
9705 match(Set dst (Conv2B src));
9706 predicate(UseCountLeadingZerosInstructionsPPC64);
9707 ins_cost(DEFAULT_COST);
9708
9709 expand %{
9710 immI shiftAmount %{ 0x5 %}
9711 uimmI16 mask %{ 0x1 %}
9712 iRegIdst tmp1;
9713 iRegIdst tmp2;
9714 countLeadingZerosI(tmp1, src);
9715 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9716 xorI_reg_uimm16(dst, tmp2, mask);
9717 %}
9718 %}
9719
9720 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
9721 match(Set dst (Conv2B src));
9722 effect(TEMP crx);
9723 predicate(!UseCountLeadingZerosInstructionsPPC64);
9724 ins_cost(DEFAULT_COST);
9725
9726 format %{ "CMPWI $crx, $src, #0 \t// convI2B"
9727 "LI $dst, #0\n\t"
9728 "BEQ $crx, done\n\t"
9729 "LI $dst, #1\n"
9730 "done:" %}
9731 size(16);
9732 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
9733 ins_pipe(pipe_class_compare);
9734 %}
9735
9736 // ConvI2B + XorI
9737 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
9738 match(Set dst (XorI (Conv2B src) mask));
9739 predicate(UseCountLeadingZerosInstructionsPPC64);
9740 ins_cost(DEFAULT_COST);
9741
9742 expand %{
9743 immI shiftAmount %{ 0x5 %}
9744 iRegIdst tmp1;
9745 countLeadingZerosI(tmp1, src);
9746 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9747 %}
9748 %}
9749
9750 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
9751 match(Set dst (XorI (Conv2B src) mask));
9752 effect(TEMP crx);
9753 predicate(!UseCountLeadingZerosInstructionsPPC64);
9754 ins_cost(DEFAULT_COST);
9755
9756 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
9757 "LI $dst, #1\n\t"
9758 "BEQ $crx, done\n\t"
9759 "LI $dst, #0\n"
9760 "done:" %}
9761 size(16);
9762 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
9763 ins_pipe(pipe_class_compare);
9764 %}
9765
9766 // AndI 0b0..010..0 + ConvI2B
9767 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
9768 match(Set dst (Conv2B (AndI src mask)));
9769 predicate(UseRotateAndMaskInstructionsPPC64);
9770 ins_cost(DEFAULT_COST);
9771
9772 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
9773 size(4);
9774 ins_encode %{
9775 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31);
9776 %}
9777 ins_pipe(pipe_class_default);
9778 %}
9779
9780 // Convert pointer to boolean.
9781 //
9782 // ptr_to_bool(src) : { 1 if src != 0
9783 // { 0 else
9784 //
9785 // strategy:
9786 // 1) Count leading zeros of 64 bit-value src,
9787 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
9788 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
9789 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
9790
9791 // ConvP2B
9792 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
9793 match(Set dst (Conv2B src));
9794 predicate(UseCountLeadingZerosInstructionsPPC64);
9795 ins_cost(DEFAULT_COST);
9796
9797 expand %{
9798 immI shiftAmount %{ 0x6 %}
9799 uimmI16 mask %{ 0x1 %}
9800 iRegIdst tmp1;
9801 iRegIdst tmp2;
9802 countLeadingZerosP(tmp1, src);
9803 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
9804 xorI_reg_uimm16(dst, tmp2, mask);
9805 %}
9806 %}
9807
9808 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
9809 match(Set dst (Conv2B src));
9810 effect(TEMP crx);
9811 predicate(!UseCountLeadingZerosInstructionsPPC64);
9812 ins_cost(DEFAULT_COST);
9813
9814 format %{ "CMPDI $crx, $src, #0 \t// convP2B"
9815 "LI $dst, #0\n\t"
9816 "BEQ $crx, done\n\t"
9817 "LI $dst, #1\n"
9818 "done:" %}
9819 size(16);
9820 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
9821 ins_pipe(pipe_class_compare);
9822 %}
9823
9824 // ConvP2B + XorI
9825 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
9826 match(Set dst (XorI (Conv2B src) mask));
9827 predicate(UseCountLeadingZerosInstructionsPPC64);
9828 ins_cost(DEFAULT_COST);
9829
9830 expand %{
9831 immI shiftAmount %{ 0x6 %}
9832 iRegIdst tmp1;
9833 countLeadingZerosP(tmp1, src);
9834 urShiftI_reg_imm(dst, tmp1, shiftAmount);
9835 %}
9836 %}
9837
9838 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
9839 match(Set dst (XorI (Conv2B src) mask));
9840 effect(TEMP crx);
9841 predicate(!UseCountLeadingZerosInstructionsPPC64);
9842 ins_cost(DEFAULT_COST);
9843
9844 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
9845 "LI $dst, #1\n\t"
9846 "BEQ $crx, done\n\t"
9847 "LI $dst, #0\n"
9848 "done:" %}
9849 size(16);
9850 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
9851 ins_pipe(pipe_class_compare);
9852 %}
9853
9854 // if src1 < src2, return -1 else return 0
9855 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9856 match(Set dst (CmpLTMask src1 src2));
9857 ins_cost(DEFAULT_COST*4);
9858
9859 expand %{
9860 iRegLdst src1s;
9861 iRegLdst src2s;
9862 iRegLdst diff;
9863 convI2L_reg(src1s, src1); // Ensure proper sign extension.
9864 convI2L_reg(src2s, src2); // Ensure proper sign extension.
9865 subL_reg_reg(diff, src1s, src2s);
9866 // Need to consider >=33 bit result, therefore we need signmaskL.
9867 signmask64I_regL(dst, diff);
9868 %}
9869 %}
9870
9871 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
9872 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
9873 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %}
9874 size(4);
9875 ins_encode %{
9876 __ srawi($dst$$Register, $src1$$Register, 0x1f);
9877 %}
9878 ins_pipe(pipe_class_default);
9879 %}
9880
9881 //----------Arithmetic Conversion Instructions---------------------------------
9882
9883 // Convert to Byte -- nop
9884 // Convert to Short -- nop
9885
9886 // Convert to Int
9887
9888 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
9889 match(Set dst (RShiftI (LShiftI src amount) amount));
9890 format %{ "EXTSB $dst, $src \t// byte->int" %}
9891 size(4);
9892 ins_encode %{
9893 __ extsb($dst$$Register, $src$$Register);
9894 %}
9895 ins_pipe(pipe_class_default);
9896 %}
9897
9898 instruct extsh(iRegIdst dst, iRegIsrc src) %{
9899 effect(DEF dst, USE src);
9900
9901 size(4);
9902 ins_encode %{
9903 __ extsh($dst$$Register, $src$$Register);
9904 %}
9905 ins_pipe(pipe_class_default);
9906 %}
9907
9908 // LShiftI 16 + RShiftI 16 converts short to int.
9909 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
9910 match(Set dst (RShiftI (LShiftI src amount) amount));
9911 format %{ "EXTSH $dst, $src \t// short->int" %}
9912 size(4);
9913 ins_encode %{
9914 __ extsh($dst$$Register, $src$$Register);
9915 %}
9916 ins_pipe(pipe_class_default);
9917 %}
9918
9919 // ConvL2I + ConvI2L: Sign extend int in long register.
9920 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
9921 match(Set dst (ConvI2L (ConvL2I src)));
9922
9923 format %{ "EXTSW $dst, $src \t// long->long" %}
9924 size(4);
9925 ins_encode %{
9926 __ extsw($dst$$Register, $src$$Register);
9927 %}
9928 ins_pipe(pipe_class_default);
9929 %}
9930
9931 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
9932 match(Set dst (ConvL2I src));
9933 format %{ "MR $dst, $src \t// long->int" %}
9934 // variable size, 0 or 4
9935 ins_encode %{
9936 __ mr_if_needed($dst$$Register, $src$$Register);
9937 %}
9938 ins_pipe(pipe_class_default);
9939 %}
9940
9941 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
9942 // no match-rule, false predicate
9943 effect(DEF dst, USE crx, USE src);
9944 predicate(false);
9945
9946 format %{ "CMOVI $crx, $dst, $src" %}
9947 size(8);
9948 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
9949 ins_pipe(pipe_class_default);
9950 %}
9951
9952 instruct cmovI_bso_reg_con0(iRegIdst dst, flagsRegSrc crx, regD src) %{
9953 // no match-rule, false predicate
9954 effect(DEF dst, USE crx, USE src);
9955 predicate(false);
9956
9957 format %{ "CMOVI $dst, $crx, $src, 0 \t// set to 0 if unordered" %}
9958 size(12);
9959 ins_encode %{
9960 Label done;
9961 __ li($dst$$Register, 0);
9962 __ bso($crx$$CondRegister, done);
9963 __ mffprd($dst$$Register, $src$$FloatRegister);
9964 __ bind(done);
9965 %}
9966 ins_pipe(pipe_class_default);
9967 %}
9968
9969 instruct convD2IRaw_regD(regD dst, regD src) %{
9970 // no match-rule, false predicate
9971 effect(DEF dst, USE src);
9972 predicate(false);
9973
9974 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
9975 size(4);
9976 ins_encode %{
9977 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
9978 %}
9979 ins_pipe(pipe_class_default);
9980 %}
9981
9982 // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
9983 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
9984 match(Set dst (ConvD2I src));
9985 ins_cost(DEFAULT_COST);
9986
9987 expand %{
9988 regD tmpD;
9989 flagsReg crx;
9990 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
9991 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
9992 cmovI_bso_reg_con0(dst, crx, tmpD); // Cmove based on NaN check.
9993 %}
9994 %}
9995
9996 instruct convF2IRaw_regF(regF dst, regF src) %{
9997 // no match-rule, false predicate
9998 effect(DEF dst, USE src);
9999 predicate(false);
10000
10001 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
10002 size(4);
10003 ins_encode %{
10004 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10005 %}
10006 ins_pipe(pipe_class_default);
10007 %}
10008
10009
10010 // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
10011 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
10012 match(Set dst (ConvF2I src));
10013 ins_cost(DEFAULT_COST);
10014
10015 expand %{
10016 regF tmpF;
10017 flagsReg crx;
10018 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10019 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10020 cmovI_bso_reg_con0(dst, crx, tmpF); // Cmove based on NaN check.
10021 %}
10022 %}
10023
10024 // Convert to Long
10025
10026 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
10027 match(Set dst (ConvI2L src));
10028 format %{ "EXTSW $dst, $src \t// int->long" %}
10029 size(4);
10030 ins_encode %{
10031 __ extsw($dst$$Register, $src$$Register);
10032 %}
10033 ins_pipe(pipe_class_default);
10034 %}
10035
10036 // Zero-extend: convert unsigned int to long (convUI2L).
10037 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
10038 match(Set dst (AndL (ConvI2L src) mask));
10039 ins_cost(DEFAULT_COST);
10040
10041 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10042 size(4);
10043 ins_encode %{
10044 __ clrldi($dst$$Register, $src$$Register, 32);
10045 %}
10046 ins_pipe(pipe_class_default);
10047 %}
10048
10049 // Zero-extend: convert unsigned int to long in long register.
10050 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
10051 match(Set dst (AndL src mask));
10052 ins_cost(DEFAULT_COST);
10053
10054 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10055 size(4);
10056 ins_encode %{
10057 __ clrldi($dst$$Register, $src$$Register, 32);
10058 %}
10059 ins_pipe(pipe_class_default);
10060 %}
10061
10062 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
10063 // no match-rule, false predicate
10064 effect(DEF dst, USE crx, USE src);
10065 predicate(false);
10066
10067 format %{ "CMOVL $crx, $dst, $src" %}
10068 size(8);
10069 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10070 ins_pipe(pipe_class_default);
10071 %}
10072
10073 instruct cmovL_bso_reg_con0(iRegLdst dst, flagsRegSrc crx, regD src) %{
10074 // no match-rule, false predicate
10075 effect(DEF dst, USE crx, USE src);
10076 predicate(false);
10077
10078 format %{ "CMOVL $dst, $crx, $src, 0 \t// set to 0 if unordered" %}
10079 size(12);
10080 ins_encode %{
10081 Label done;
10082 __ li($dst$$Register, 0);
10083 __ bso($crx$$CondRegister, done);
10084 __ mffprd($dst$$Register, $src$$FloatRegister);
10085 __ bind(done);
10086 %}
10087 ins_pipe(pipe_class_default);
10088 %}
10089
10090 instruct convF2LRaw_regF(regF dst, regF src) %{
10091 // no match-rule, false predicate
10092 effect(DEF dst, USE src);
10093 predicate(false);
10094
10095 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10096 size(4);
10097 ins_encode %{
10098 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10099 %}
10100 ins_pipe(pipe_class_default);
10101 %}
10102
10103 // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
10104 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
10105 match(Set dst (ConvF2L src));
10106 ins_cost(DEFAULT_COST);
10107
10108 expand %{
10109 regF tmpF;
10110 flagsReg crx;
10111 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10112 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
10113 cmovL_bso_reg_con0(dst, crx, tmpF); // Cmove based on NaN check.
10114 %}
10115 %}
10116
10117 instruct convD2LRaw_regD(regD dst, regD src) %{
10118 // no match-rule, false predicate
10119 effect(DEF dst, USE src);
10120 predicate(false);
10121
10122 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
10123 size(4);
10124 ins_encode %{
10125 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10126 %}
10127 ins_pipe(pipe_class_default);
10128 %}
10129
10130 // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
10131 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
10132 match(Set dst (ConvD2L src));
10133 ins_cost(DEFAULT_COST);
10134
10135 expand %{
10136 regD tmpD;
10137 flagsReg crx;
10138 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10139 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
10140 cmovL_bso_reg_con0(dst, crx, tmpD); // Cmove based on NaN check.
10141 %}
10142 %}
10143
10144 // Convert to Float
10145
10146 // Placed here as needed in expand.
10147 instruct convL2DRaw_regD(regD dst, regD src) %{
10148 // no match-rule, false predicate
10149 effect(DEF dst, USE src);
10150 predicate(false);
10151
10152 format %{ "FCFID $dst, $src \t// convL2D" %}
10153 size(4);
10154 ins_encode %{
10155 __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
10156 %}
10157 ins_pipe(pipe_class_default);
10158 %}
10159
10160 // Placed here as needed in expand.
10161 instruct convD2F_reg(regF dst, regD src) %{
10162 match(Set dst (ConvD2F src));
10163 format %{ "FRSP $dst, $src \t// convD2F" %}
10164 size(4);
10165 ins_encode %{
10166 __ frsp($dst$$FloatRegister, $src$$FloatRegister);
10167 %}
10168 ins_pipe(pipe_class_default);
10169 %}
10170
10171 instruct convL2FRaw_regF(regF dst, regD src) %{
10172 // no match-rule, false predicate
10173 effect(DEF dst, USE src);
10174 predicate(false);
10175
10176 format %{ "FCFIDS $dst, $src \t// convL2F" %}
10177 size(4);
10178 ins_encode %{
10179 __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
10180 %}
10181 ins_pipe(pipe_class_default);
10182 %}
10183
10184
10185 // Integer to Float conversion. Special version for Power8.
10186 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
10187 match(Set dst (ConvI2F src));
10188 ins_cost(DEFAULT_COST);
10189
10190 expand %{
10191 regD tmpD;
10192 moveI2D_reg(tmpD, src);
10193 convL2FRaw_regF(dst, tmpD); // Convert to float.
10194 %}
10195 %}
10196
10197
10198 // L2F to avoid runtime call. Special version for Power8.
10199 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
10200 match(Set dst (ConvL2F src));
10201 ins_cost(DEFAULT_COST);
10202
10203 expand %{
10204 regD tmpD;
10205 moveL2D_reg(tmpD, src);
10206 convL2FRaw_regF(dst, tmpD); // Convert to float.
10207 %}
10208 %}
10209
10210 // Moved up as used in expand.
10211 //instruct convD2F_reg(regF dst, regD src) %{%}
10212
10213 // Convert to Double
10214
10215
10216 // Integer to Double conversion. Special version for Power8.
10217 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
10218 match(Set dst (ConvI2D src));
10219 ins_cost(DEFAULT_COST);
10220
10221 expand %{
10222 regD tmpD;
10223 moveI2D_reg(tmpD, src);
10224 convL2DRaw_regD(dst, tmpD); // Convert to double.
10225 %}
10226 %}
10227
10228
10229 // Long to Double conversion. Special version for Power8.
10230 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
10231 match(Set dst (ConvL2D src));
10232 ins_cost(DEFAULT_COST);
10233
10234 expand %{
10235 regD tmpD;
10236 moveL2D_reg(tmpD, src);
10237 convL2DRaw_regD(dst, tmpD); // Convert to double.
10238 %}
10239 %}
10240
10241 instruct convF2D_reg(regD dst, regF src) %{
10242 match(Set dst (ConvF2D src));
10243 format %{ "FMR $dst, $src \t// float->double" %}
10244 // variable size, 0 or 4
10245 ins_encode %{
10246 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
10247 %}
10248 ins_pipe(pipe_class_default);
10249 %}
10250
10251 instruct convF2HF_reg_reg(iRegIdst dst, regF src, regF tmp) %{
10252 match(Set dst (ConvF2HF src));
10253 effect(TEMP tmp);
10254 ins_cost(3 * DEFAULT_COST);
10255 size(12);
10256 format %{ "XSCVDPHP $tmp, $src\t# convert to half precision\n\t"
10257 "MFFPRD $dst, $tmp\t# move result from $tmp to $dst\n\t"
10258 "EXTSH $dst, $dst\t# make it a proper short"
10259 %}
10260 ins_encode %{
10261 __ f2hf($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
10262 %}
10263 ins_pipe(pipe_class_default);
10264 %}
10265
10266 instruct convHF2F_reg_reg(regF dst, iRegIsrc src) %{
10267 match(Set dst (ConvHF2F src));
10268 ins_cost(2 * DEFAULT_COST);
10269 size(8);
10270 format %{ "MTFPRD $dst, $src\t# move source from $src to $dst\n\t"
10271 "XSCVHPDP $dst, $dst\t# convert from half precision"
10272 %}
10273 ins_encode %{
10274 __ hf2f($dst$$FloatRegister, $src$$Register);
10275 %}
10276 ins_pipe(pipe_class_default);
10277 %}
10278
10279 //----------Control Flow Instructions------------------------------------------
10280 // Compare Instructions
10281
10282 // Compare Integers
10283 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10284 match(Set crx (CmpI src1 src2));
10285 size(4);
10286 format %{ "CMPW $crx, $src1, $src2" %}
10287 ins_encode %{
10288 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10289 %}
10290 ins_pipe(pipe_class_compare);
10291 %}
10292
10293 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
10294 match(Set crx (CmpI src1 src2));
10295 format %{ "CMPWI $crx, $src1, $src2" %}
10296 size(4);
10297 ins_encode %{
10298 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10299 %}
10300 ins_pipe(pipe_class_compare);
10301 %}
10302
10303 // (src1 & src2) == 0?
10304 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
10305 match(Set cr0 (CmpI (AndI src1 src2) zero));
10306 // r0 is killed
10307 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
10308 size(4);
10309 ins_encode %{
10310 __ andi_(R0, $src1$$Register, $src2$$constant);
10311 %}
10312 ins_pipe(pipe_class_compare);
10313 %}
10314
10315 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10316 match(Set crx (CmpL src1 src2));
10317 format %{ "CMPD $crx, $src1, $src2" %}
10318 size(4);
10319 ins_encode %{
10320 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
10321 %}
10322 ins_pipe(pipe_class_compare);
10323 %}
10324
10325 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
10326 match(Set crx (CmpL src1 src2));
10327 format %{ "CMPDI $crx, $src1, $src2" %}
10328 size(4);
10329 ins_encode %{
10330 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10331 %}
10332 ins_pipe(pipe_class_compare);
10333 %}
10334
10335 // Added CmpUL for LoopPredicate.
10336 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10337 match(Set crx (CmpUL src1 src2));
10338 format %{ "CMPLD $crx, $src1, $src2" %}
10339 size(4);
10340 ins_encode %{
10341 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10342 %}
10343 ins_pipe(pipe_class_compare);
10344 %}
10345
10346 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
10347 match(Set crx (CmpUL src1 src2));
10348 format %{ "CMPLDI $crx, $src1, $src2" %}
10349 size(4);
10350 ins_encode %{
10351 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10352 %}
10353 ins_pipe(pipe_class_compare);
10354 %}
10355
10356 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
10357 match(Set cr0 (CmpL (AndL src1 src2) zero));
10358 // r0 is killed
10359 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
10360 size(4);
10361 ins_encode %{
10362 __ and_(R0, $src1$$Register, $src2$$Register);
10363 %}
10364 ins_pipe(pipe_class_compare);
10365 %}
10366
10367 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
10368 match(Set cr0 (CmpL (AndL src1 src2) zero));
10369 // r0 is killed
10370 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
10371 size(4);
10372 ins_encode %{
10373 __ andi_(R0, $src1$$Register, $src2$$constant);
10374 %}
10375 ins_pipe(pipe_class_compare);
10376 %}
10377
10378 // Manifest a CmpL3 result in an integer register.
10379 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10380 match(Set dst (CmpL3 src1 src2));
10381 effect(KILL cr0);
10382 ins_cost(DEFAULT_COST * 5);
10383 size((VM_Version::has_brw() ? 16 : 20));
10384
10385 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %}
10386
10387 ins_encode %{
10388 __ cmpd(CR0, $src1$$Register, $src2$$Register);
10389 __ set_cmp3($dst$$Register);
10390 %}
10391 ins_pipe(pipe_class_default);
10392 %}
10393
10394 instruct cmpU3_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
10395 match(Set dst (CmpU3 src1 src2));
10396 effect(KILL cr0);
10397 ins_cost(DEFAULT_COST * 5);
10398 size((VM_Version::has_brw() ? 16 : 20));
10399
10400 format %{ "cmpU3_reg_reg $dst, $src1, $src2" %}
10401
10402 ins_encode %{
10403 __ cmplw(CR0, $src1$$Register, $src2$$Register);
10404 __ set_cmp3($dst$$Register);
10405 %}
10406 ins_pipe(pipe_class_default);
10407 %}
10408
10409 instruct cmpUL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
10410 match(Set dst (CmpUL3 src1 src2));
10411 effect(KILL cr0);
10412 ins_cost(DEFAULT_COST * 5);
10413 size((VM_Version::has_brw() ? 16 : 20));
10414
10415 format %{ "cmpUL3_reg_reg $dst, $src1, $src2" %}
10416
10417 ins_encode %{
10418 __ cmpld(CR0, $src1$$Register, $src2$$Register);
10419 __ set_cmp3($dst$$Register);
10420 %}
10421 ins_pipe(pipe_class_default);
10422 %}
10423
10424 // Implicit range checks.
10425 // A range check in the ideal world has one of the following shapes:
10426 // - (If le (CmpU length index)), (IfTrue throw exception)
10427 // - (If lt (CmpU index length)), (IfFalse throw exception)
10428 //
10429 // Match range check 'If le (CmpU length index)'.
10430 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
10431 match(If cmp (CmpU src_length index));
10432 effect(USE labl);
10433 predicate(TrapBasedRangeChecks &&
10434 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
10435 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
10436 (Matcher::branches_to_uncommon_trap(_leaf)));
10437
10438 ins_is_TrapBasedCheckNode(true);
10439
10440 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %}
10441 size(4);
10442 ins_encode %{
10443 if ($cmp$$cmpcode == 0x1 /* less_equal */) {
10444 __ trap_range_check_le($src_length$$Register, $index$$constant);
10445 } else {
10446 // Both successors are uncommon traps, probability is 0.
10447 // Node got flipped during fixup flow.
10448 assert($cmp$$cmpcode == 0x9, "must be greater");
10449 __ trap_range_check_g($src_length$$Register, $index$$constant);
10450 }
10451 %}
10452 ins_pipe(pipe_class_trap);
10453 %}
10454
10455 // Match range check 'If lt (CmpU index length)'.
10456 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
10457 match(If cmp (CmpU src_index src_length));
10458 effect(USE labl);
10459 predicate(TrapBasedRangeChecks &&
10460 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10461 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10462 (Matcher::branches_to_uncommon_trap(_leaf)));
10463
10464 ins_is_TrapBasedCheckNode(true);
10465
10466 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
10467 size(4);
10468 ins_encode %{
10469 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10470 __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
10471 } else {
10472 // Both successors are uncommon traps, probability is 0.
10473 // Node got flipped during fixup flow.
10474 assert($cmp$$cmpcode == 0x8, "must be less");
10475 __ trap_range_check_l($src_index$$Register, $src_length$$Register);
10476 }
10477 %}
10478 ins_pipe(pipe_class_trap);
10479 %}
10480
10481 // Match range check 'If lt (CmpU index length)'.
10482 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
10483 match(If cmp (CmpU src_index length));
10484 effect(USE labl);
10485 predicate(TrapBasedRangeChecks &&
10486 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
10487 _leaf->as_If()->_prob >= PROB_ALWAYS &&
10488 (Matcher::branches_to_uncommon_trap(_leaf)));
10489
10490 ins_is_TrapBasedCheckNode(true);
10491
10492 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %}
10493 size(4);
10494 ins_encode %{
10495 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
10496 __ trap_range_check_ge($src_index$$Register, $length$$constant);
10497 } else {
10498 // Both successors are uncommon traps, probability is 0.
10499 // Node got flipped during fixup flow.
10500 assert($cmp$$cmpcode == 0x8, "must be less");
10501 __ trap_range_check_l($src_index$$Register, $length$$constant);
10502 }
10503 %}
10504 ins_pipe(pipe_class_trap);
10505 %}
10506
10507 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10508 match(Set crx (CmpU src1 src2));
10509 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %}
10510 size(4);
10511 ins_encode %{
10512 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10513 %}
10514 ins_pipe(pipe_class_compare);
10515 %}
10516
10517 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
10518 match(Set crx (CmpU src1 src2));
10519 size(4);
10520 format %{ "CMPLWI $crx, $src1, $src2" %}
10521 ins_encode %{
10522 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10523 %}
10524 ins_pipe(pipe_class_compare);
10525 %}
10526
10527 // Implicit zero checks (more implicit null checks).
10528 // No constant pool entries required.
10529 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
10530 match(If cmp (CmpN value zero));
10531 effect(USE labl);
10532 predicate(TrapBasedNullChecks &&
10533 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10534 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10535 Matcher::branches_to_uncommon_trap(_leaf));
10536 ins_cost(1);
10537
10538 ins_is_TrapBasedCheckNode(true);
10539
10540 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
10541 size(4);
10542 ins_encode %{
10543 if ($cmp$$cmpcode == 0xA) {
10544 __ trap_null_check($value$$Register);
10545 } else {
10546 // Both successors are uncommon traps, probability is 0.
10547 // Node got flipped during fixup flow.
10548 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10549 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10550 }
10551 %}
10552 ins_pipe(pipe_class_trap);
10553 %}
10554
10555 // Compare narrow oops.
10556 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
10557 match(Set crx (CmpN src1 src2));
10558
10559 size(4);
10560 ins_cost(2);
10561 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %}
10562 ins_encode %{
10563 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10564 %}
10565 ins_pipe(pipe_class_compare);
10566 %}
10567
10568 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
10569 match(Set crx (CmpN src1 src2));
10570 // Make this more expensive than zeroCheckN_iReg_imm0.
10571 ins_cost(2);
10572
10573 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %}
10574 size(4);
10575 ins_encode %{
10576 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10577 %}
10578 ins_pipe(pipe_class_compare);
10579 %}
10580
10581 // Implicit zero checks (more implicit null checks).
10582 // No constant pool entries required.
10583 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
10584 match(If cmp (CmpP value zero));
10585 effect(USE labl);
10586 predicate(TrapBasedNullChecks &&
10587 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10588 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10589 Matcher::branches_to_uncommon_trap(_leaf));
10590 ins_cost(1); // Should not be cheaper than zeroCheckN.
10591
10592 ins_is_TrapBasedCheckNode(true);
10593
10594 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
10595 size(4);
10596 ins_encode %{
10597 if ($cmp$$cmpcode == 0xA) {
10598 __ trap_null_check($value$$Register);
10599 } else {
10600 // Both successors are uncommon traps, probability is 0.
10601 // Node got flipped during fixup flow.
10602 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10603 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10604 }
10605 %}
10606 ins_pipe(pipe_class_trap);
10607 %}
10608
10609 // Compare Pointers
10610 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
10611 match(Set crx (CmpP src1 src2));
10612 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %}
10613 size(4);
10614 ins_encode %{
10615 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
10616 %}
10617 ins_pipe(pipe_class_compare);
10618 %}
10619
10620 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
10621 match(Set crx (CmpP src1 src2));
10622 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %}
10623 size(4);
10624 ins_encode %{
10625 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
10626 %}
10627 ins_pipe(pipe_class_compare);
10628 %}
10629
10630 // Used in postalloc expand.
10631 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
10632 // This match rule prevents reordering of node before a safepoint.
10633 // This only makes sense if this instructions is used exclusively
10634 // for the expansion of EncodeP!
10635 match(Set crx (CmpP src1 src2));
10636 predicate(false);
10637
10638 format %{ "CMPDI $crx, $src1, $src2" %}
10639 size(4);
10640 ins_encode %{
10641 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10642 %}
10643 ins_pipe(pipe_class_compare);
10644 %}
10645
10646 //----------Float Compares----------------------------------------------------
10647
10648 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
10649 // Needs matchrule, see cmpDUnordered.
10650 match(Set crx (CmpF src1 src2));
10651 // no match-rule, false predicate
10652 predicate(false);
10653
10654 format %{ "cmpFUrd $crx, $src1, $src2" %}
10655 size(4);
10656 ins_encode %{
10657 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10658 %}
10659 ins_pipe(pipe_class_default);
10660 %}
10661
10662 // Compare floating, generate condition code.
10663 instruct cmpF_reg_reg(flagsReg crx, regF src1, regF src2) %{
10664 match(Set crx (CmpF src1 src2));
10665 ins_cost(DEFAULT_COST+BRANCH_COST);
10666
10667 format %{ "CMPF $crx, $src1, $src2" %}
10668 size(16);
10669 ins_encode %{
10670 Label done;
10671 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10672 __ bns($crx$$CondRegister, done);
10673 __ li(R0, 0);
10674 __ cmpwi($crx$$CondRegister, R0, 1);
10675 __ bind(done);
10676 %}
10677 ins_pipe(pipe_class_default);
10678 %}
10679
10680 // Compare float, generate -1,0,1
10681 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{
10682 match(Set dst (CmpF3 src1 src2));
10683 effect(KILL cr0);
10684 ins_cost(DEFAULT_COST * 6);
10685 size((VM_Version::has_brw() ? 20 : 24));
10686
10687 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %}
10688
10689 ins_encode %{
10690 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
10691 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
10692 %}
10693 ins_pipe(pipe_class_default);
10694 %}
10695
10696 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
10697 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
10698 // node right before the conditional move using it.
10699 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
10700 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
10701 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
10702 // conditional move was supposed to be spilled.
10703 match(Set crx (CmpD src1 src2));
10704 // False predicate, shall not be matched.
10705 predicate(false);
10706
10707 format %{ "cmpFUrd $crx, $src1, $src2" %}
10708 size(4);
10709 ins_encode %{
10710 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10711 %}
10712 ins_pipe(pipe_class_default);
10713 %}
10714
10715 instruct cmpD_reg_reg(flagsReg crx, regD src1, regD src2) %{
10716 match(Set crx (CmpD src1 src2));
10717 ins_cost(DEFAULT_COST+BRANCH_COST);
10718
10719 format %{ "CMPD $crx, $src1, $src2" %}
10720 size(16);
10721 ins_encode %{
10722 Label done;
10723 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10724 __ bns($crx$$CondRegister, done);
10725 __ li(R0, 0);
10726 __ cmpwi($crx$$CondRegister, R0, 1);
10727 __ bind(done);
10728 %}
10729 ins_pipe(pipe_class_default);
10730 %}
10731
10732 // Compare double, generate -1,0,1
10733 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{
10734 match(Set dst (CmpD3 src1 src2));
10735 effect(KILL cr0);
10736 ins_cost(DEFAULT_COST * 6);
10737 size((VM_Version::has_brw() ? 20 : 24));
10738
10739 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %}
10740
10741 ins_encode %{
10742 __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister);
10743 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
10744 %}
10745 ins_pipe(pipe_class_default);
10746 %}
10747
10748 // Compare char
10749 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10750 match(Set dst (Digit src1));
10751 effect(TEMP src2, TEMP crx);
10752 ins_cost(3 * DEFAULT_COST);
10753
10754 format %{ "LI $src2, 0x3930\n\t"
10755 "CMPRB $crx, 0, $src1, $src2\n\t"
10756 "SETB $dst, $crx" %}
10757 size(12);
10758 ins_encode %{
10759 // 0x30: 0, 0x39: 9
10760 __ li($src2$$Register, 0x3930);
10761 // compare src1 with ranges 0x30 to 0x39
10762 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
10763 __ setb($dst$$Register, $crx$$CondRegister);
10764 %}
10765 ins_pipe(pipe_class_default);
10766 %}
10767
10768 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10769 match(Set dst (LowerCase src1));
10770 effect(TEMP src2, TEMP crx);
10771 ins_cost(12 * DEFAULT_COST);
10772
10773 format %{ "LI $src2, 0x7A61\n\t"
10774 "CMPRB $crx, 0, $src1, $src2\n\t"
10775 "BGT $crx, done\n\t"
10776 "LIS $src2, (signed short)0xF6DF\n\t"
10777 "ORI $src2, $src2, 0xFFF8\n\t"
10778 "CMPRB $crx, 1, $src1, $src2\n\t"
10779 "BGT $crx, done\n\t"
10780 "LIS $src2, (signed short)0xAAB5\n\t"
10781 "ORI $src2, $src2, 0xBABA\n\t"
10782 "INSRDI $src2, $src2, 32, 0\n\t"
10783 "CMPEQB $crx, 1, $src1, $src2\n"
10784 "done:\n\t"
10785 "SETB $dst, $crx" %}
10786
10787 size(48);
10788 ins_encode %{
10789 Label done;
10790 // 0x61: a, 0x7A: z
10791 __ li($src2$$Register, 0x7A61);
10792 // compare src1 with ranges 0x61 to 0x7A
10793 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
10794 __ bgt($crx$$CondRegister, done);
10795
10796 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
10797 __ lis($src2$$Register, (signed short)0xF6DF);
10798 __ ori($src2$$Register, $src2$$Register, 0xFFF8);
10799 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
10800 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10801 __ bgt($crx$$CondRegister, done);
10802
10803 // 0xAA: feminine ordinal indicator
10804 // 0xB5: micro sign
10805 // 0xBA: masculine ordinal indicator
10806 __ lis($src2$$Register, (signed short)0xAAB5);
10807 __ ori($src2$$Register, $src2$$Register, 0xBABA);
10808 __ insrdi($src2$$Register, $src2$$Register, 32, 0);
10809 // compare src1 with 0xAA, 0xB5, and 0xBA
10810 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
10811
10812 __ bind(done);
10813 __ setb($dst$$Register, $crx$$CondRegister);
10814 %}
10815 ins_pipe(pipe_class_default);
10816 %}
10817
10818 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10819 match(Set dst (UpperCase src1));
10820 effect(TEMP src2, TEMP crx);
10821 ins_cost(7 * DEFAULT_COST);
10822
10823 format %{ "LI $src2, 0x5A41\n\t"
10824 "CMPRB $crx, 0, $src1, $src2\n\t"
10825 "BGT $crx, done\n\t"
10826 "LIS $src2, (signed short)0xD6C0\n\t"
10827 "ORI $src2, $src2, 0xDED8\n\t"
10828 "CMPRB $crx, 1, $src1, $src2\n"
10829 "done:\n\t"
10830 "SETB $dst, $crx" %}
10831
10832 size(28);
10833 ins_encode %{
10834 Label done;
10835 // 0x41: A, 0x5A: Z
10836 __ li($src2$$Register, 0x5A41);
10837 // compare src1 with a range 0x41 to 0x5A
10838 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
10839 __ bgt($crx$$CondRegister, done);
10840
10841 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
10842 __ lis($src2$$Register, (signed short)0xD6C0);
10843 __ ori($src2$$Register, $src2$$Register, 0xDED8);
10844 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
10845 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10846
10847 __ bind(done);
10848 __ setb($dst$$Register, $crx$$CondRegister);
10849 %}
10850 ins_pipe(pipe_class_default);
10851 %}
10852
10853 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10854 match(Set dst (Whitespace src1));
10855 predicate(PowerArchitecturePPC64 <= 9);
10856 effect(TEMP src2, TEMP crx);
10857 ins_cost(4 * DEFAULT_COST);
10858
10859 format %{ "LI $src2, 0x0D09\n\t"
10860 "ADDIS $src2, 0x201C\n\t"
10861 "CMPRB $crx, 1, $src1, $src2\n\t"
10862 "SETB $dst, $crx" %}
10863 size(16);
10864 ins_encode %{
10865 // 0x09 to 0x0D, 0x1C to 0x20
10866 __ li($src2$$Register, 0x0D09);
10867 __ addis($src2$$Register, $src2$$Register, 0x0201C);
10868 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
10869 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10870 __ setb($dst$$Register, $crx$$CondRegister);
10871 %}
10872 ins_pipe(pipe_class_default);
10873 %}
10874
10875 // Power 10 version, using prefixed addi to load 32-bit constant
10876 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
10877 match(Set dst (Whitespace src1));
10878 predicate(PowerArchitecturePPC64 >= 10);
10879 effect(TEMP src2, TEMP crx);
10880 ins_cost(3 * DEFAULT_COST);
10881
10882 format %{ "PLI $src2, 0x201C0D09\n\t"
10883 "CMPRB $crx, 1, $src1, $src2\n\t"
10884 "SETB $dst, $crx" %}
10885 size(16);
10886 ins_encode %{
10887 // 0x09 to 0x0D, 0x1C to 0x20
10888 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
10889 __ pli($src2$$Register, 0x201C0D09);
10890 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
10891 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
10892 __ setb($dst$$Register, $crx$$CondRegister);
10893 %}
10894 ins_pipe(pipe_class_default);
10895 ins_alignment(2);
10896 %}
10897
10898 //----------Branches---------------------------------------------------------
10899 // Jump
10900
10901 // Direct Branch.
10902 instruct branch(label labl) %{
10903 match(Goto);
10904 effect(USE labl);
10905 ins_cost(BRANCH_COST);
10906
10907 format %{ "B $labl" %}
10908 size(4);
10909 ins_encode %{
10910 Label d; // dummy
10911 __ bind(d);
10912 Label* p = $labl$$label;
10913 // `p' is `nullptr' when this encoding class is used only to
10914 // determine the size of the encoded instruction.
10915 Label& l = (nullptr == p)? d : *(p);
10916 __ b(l);
10917 %}
10918 ins_pipe(pipe_class_default);
10919 %}
10920
10921 // Conditional Near Branch
10922 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
10923 // Same match rule as `branchConFar'.
10924 match(If cmp crx);
10925 effect(USE lbl);
10926 ins_cost(BRANCH_COST);
10927
10928 // If set to 1 this indicates that the current instruction is a
10929 // short variant of a long branch. This avoids using this
10930 // instruction in first-pass matching. It will then only be used in
10931 // the `Shorten_branches' pass.
10932 ins_short_branch(1);
10933
10934 format %{ "B$cmp $crx, $lbl" %}
10935 size(4);
10936 ins_encode( enc_bc(crx, cmp, lbl) );
10937 ins_pipe(pipe_class_default);
10938 %}
10939
10940 // This is for cases when the ppc64 `bc' instruction does not
10941 // reach far enough. So we emit a far branch here, which is more
10942 // expensive.
10943 //
10944 // Conditional Far Branch
10945 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
10946 // Same match rule as `branchCon'.
10947 match(If cmp crx);
10948 effect(USE crx, USE lbl);
10949 // Higher cost than `branchCon'.
10950 ins_cost(5*BRANCH_COST);
10951
10952 // This is not a short variant of a branch, but the long variant.
10953 ins_short_branch(0);
10954
10955 format %{ "B_FAR$cmp $crx, $lbl" %}
10956 size(8);
10957 ins_encode( enc_bc_far(crx, cmp, lbl) );
10958 ins_pipe(pipe_class_default);
10959 %}
10960
10961 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
10962 match(CountedLoopEnd cmp crx);
10963 effect(USE labl);
10964 ins_cost(BRANCH_COST);
10965
10966 // short variant.
10967 ins_short_branch(1);
10968
10969 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
10970 size(4);
10971 ins_encode( enc_bc(crx, cmp, labl) );
10972 ins_pipe(pipe_class_default);
10973 %}
10974
10975 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
10976 match(CountedLoopEnd cmp crx);
10977 effect(USE labl);
10978 ins_cost(BRANCH_COST);
10979
10980 // Long variant.
10981 ins_short_branch(0);
10982
10983 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
10984 size(8);
10985 ins_encode( enc_bc_far(crx, cmp, labl) );
10986 ins_pipe(pipe_class_default);
10987 %}
10988
10989 // ============================================================================
10990 // Java runtime operations, intrinsics and other complex operations.
10991
10992 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
10993 // array for an instance of the superklass. Set a hidden internal cache on a
10994 // hit (cache is checked with exposed code in gen_subtype_check()). Return
10995 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
10996 //
10997 // GL TODO: Improve this.
10998 // - result should not be a TEMP
10999 // - Add match rule as on sparc avoiding additional Cmp.
11000 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
11001 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
11002 match(Set result (PartialSubtypeCheck subklass superklass));
11003 predicate(!UseSecondarySupersTable);
11004 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
11005 ins_cost(DEFAULT_COST*10);
11006
11007 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
11008 ins_encode %{
11009 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
11010 $tmp_klass$$Register, nullptr, $result$$Register);
11011 %}
11012 ins_pipe(pipe_class_default);
11013 %}
11014
11015 // Two versions of partialSubtypeCheck, both used when we need to
11016 // search for a super class in the secondary supers array. The first
11017 // is used when we don't know _a priori_ the class being searched
11018 // for. The second, far more common, is used when we do know: this is
11019 // used for instanceof, checkcast, and any case where C2 can determine
11020 // it by constant propagation.
11021 instruct partialSubtypeCheckVarSuper(iRegPsrc sub, iRegPsrc super, iRegPdst result,
11022 iRegPdst tempR1, iRegPdst tempR2, iRegPdst tempR3, iRegPdst tempR4,
11023 flagsRegCR0 cr0, regCTR ctr)
11024 %{
11025 match(Set result (PartialSubtypeCheck sub super));
11026 predicate(UseSecondarySupersTable);
11027 effect(KILL cr0, KILL ctr, TEMP_DEF result, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11028
11029 ins_cost(DEFAULT_COST * 10); // slightly larger than the next version
11030 format %{ "partialSubtypeCheck $result, $sub, $super" %}
11031 ins_encode %{
11032 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register,
11033 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11034 $result$$Register);
11035 %}
11036 ins_pipe(pipe_class_memory);
11037 %}
11038
11039 instruct partialSubtypeCheckConstSuper(rarg3RegP sub, rarg2RegP super_reg, immP super_con, rarg6RegP result,
11040 rarg1RegP tempR1, rarg5RegP tempR2, rarg4RegP tempR3, rscratch1RegP tempR4,
11041 flagsRegCR0 cr0, regCTR ctr)
11042 %{
11043 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
11044 predicate(UseSecondarySupersTable);
11045 effect(KILL cr0, KILL ctr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4);
11046
11047 ins_cost(DEFAULT_COST*8); // smaller than the other version
11048 format %{ "partialSubtypeCheck $result, $sub, $super_reg" %}
11049
11050 ins_encode %{
11051 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
11052 if (InlineSecondarySupersTest) {
11053 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register,
11054 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register,
11055 $result$$Register, super_klass_slot);
11056 } else {
11057 address stub = StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot);
11058 Register r_stub_addr = $tempR1$$Register;
11059 __ add_const_optimized(r_stub_addr, R29_TOC, MacroAssembler::offset_to_global_toc(stub), R0);
11060 __ mtctr(r_stub_addr);
11061 __ bctrl();
11062 }
11063 %}
11064
11065 ins_pipe(pipe_class_memory);
11066 %}
11067
11068 // inlined locking and unlocking
11069
11070 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
11071 predicate(!UseObjectMonitorTable);
11072 match(Set crx (FastLock oop box));
11073 effect(TEMP tmp1, TEMP tmp2);
11074
11075 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %}
11076 ins_encode %{
11077 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11078 $tmp1$$Register, $tmp2$$Register, noreg /*tmp3*/);
11079 // If locking was successful, crx should indicate 'EQ'.
11080 // The compiler generates a branch to the runtime call to
11081 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11082 %}
11083 ins_pipe(pipe_class_compare);
11084 %}
11085
11086 instruct cmpFastLockMonitorTable(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, flagsRegCR1 cr1) %{
11087 predicate(UseObjectMonitorTable);
11088 match(Set crx (FastLock oop box));
11089 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr1);
11090
11091 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3" %}
11092 ins_encode %{
11093 __ fast_lock($crx$$CondRegister, $oop$$Register, $box$$Register,
11094 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11095 // If locking was successful, crx should indicate 'EQ'.
11096 // The compiler generates a branch to the runtime call to
11097 // _complete_monitor_locking_Java for the case where crx is 'NE'.
11098 %}
11099 ins_pipe(pipe_class_compare);
11100 %}
11101
11102 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11103 match(Set crx (FastUnlock oop box));
11104 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11105
11106 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
11107 ins_encode %{
11108 __ fast_unlock($crx$$CondRegister, $oop$$Register, $box$$Register,
11109 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11110 // If unlocking was successful, crx should indicate 'EQ'.
11111 // The compiler generates a branch to the runtime call to
11112 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11113 %}
11114 ins_pipe(pipe_class_compare);
11115 %}
11116
11117 // Align address.
11118 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11119 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11120
11121 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
11122 size(4);
11123 ins_encode %{
11124 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant));
11125 %}
11126 ins_pipe(pipe_class_default);
11127 %}
11128
11129 // Array size computation.
11130 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11131 match(Set dst (SubL (CastP2X end) (CastP2X start)));
11132
11133 format %{ "SUB $dst, $end, $start \t// array size in bytes" %}
11134 size(4);
11135 ins_encode %{
11136 __ subf($dst$$Register, $start$$Register, $end$$Register);
11137 %}
11138 ins_pipe(pipe_class_default);
11139 %}
11140
11141 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
11142 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11143 match(Set dummy (ClearArray cnt base));
11144 effect(USE_KILL base, KILL ctr);
11145 ins_cost(2 * MEMORY_REF_COST);
11146
11147 format %{ "ClearArray $cnt, $base" %}
11148 ins_encode %{
11149 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
11150 %}
11151 ins_pipe(pipe_class_default);
11152 %}
11153
11154 // Clear-array with constant large array length.
11155 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{
11156 match(Set dummy (ClearArray cnt base));
11157 effect(USE_KILL base, TEMP tmp, KILL ctr);
11158 ins_cost(3 * MEMORY_REF_COST);
11159
11160 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
11161 ins_encode %{
11162 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
11163 %}
11164 ins_pipe(pipe_class_default);
11165 %}
11166
11167 // Clear-array with dynamic array length.
11168 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11169 match(Set dummy (ClearArray cnt base));
11170 effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11171 ins_cost(4 * MEMORY_REF_COST);
11172
11173 format %{ "ClearArray $cnt, $base" %}
11174 ins_encode %{
11175 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
11176 %}
11177 ins_pipe(pipe_class_default);
11178 %}
11179
11180 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11181 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11182 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11183 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11184 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11185 ins_cost(300);
11186 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11187 ins_encode %{
11188 __ string_compare($str1$$Register, $str2$$Register,
11189 $cnt1$$Register, $cnt2$$Register,
11190 $tmp$$Register,
11191 $result$$Register, StrIntrinsicNode::LL);
11192 %}
11193 ins_pipe(pipe_class_default);
11194 %}
11195
11196 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11197 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11198 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11199 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11200 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11201 ins_cost(300);
11202 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11203 ins_encode %{
11204 __ string_compare($str1$$Register, $str2$$Register,
11205 $cnt1$$Register, $cnt2$$Register,
11206 $tmp$$Register,
11207 $result$$Register, StrIntrinsicNode::UU);
11208 %}
11209 ins_pipe(pipe_class_default);
11210 %}
11211
11212 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11213 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11214 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11215 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11216 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11217 ins_cost(300);
11218 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11219 ins_encode %{
11220 __ string_compare($str1$$Register, $str2$$Register,
11221 $cnt1$$Register, $cnt2$$Register,
11222 $tmp$$Register,
11223 $result$$Register, StrIntrinsicNode::LU);
11224 %}
11225 ins_pipe(pipe_class_default);
11226 %}
11227
11228 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11229 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11230 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11231 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11232 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11233 ins_cost(300);
11234 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11235 ins_encode %{
11236 __ string_compare($str2$$Register, $str1$$Register,
11237 $cnt2$$Register, $cnt1$$Register,
11238 $tmp$$Register,
11239 $result$$Register, StrIntrinsicNode::UL);
11240 %}
11241 ins_pipe(pipe_class_default);
11242 %}
11243
11244 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11245 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11246 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11247 match(Set result (StrEquals (Binary str1 str2) cnt));
11248 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11249 ins_cost(300);
11250 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11251 ins_encode %{
11252 __ array_equals(false, $str1$$Register, $str2$$Register,
11253 $cnt$$Register, $tmp$$Register,
11254 $result$$Register, true /* byte */);
11255 %}
11256 ins_pipe(pipe_class_default);
11257 %}
11258
11259 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11260 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11261 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11262 match(Set result (AryEq ary1 ary2));
11263 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11264 ins_cost(300);
11265 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11266 ins_encode %{
11267 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11268 $tmp1$$Register, $tmp2$$Register,
11269 $result$$Register, true /* byte */);
11270 %}
11271 ins_pipe(pipe_class_default);
11272 %}
11273
11274 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11275 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11276 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11277 match(Set result (AryEq ary1 ary2));
11278 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11279 ins_cost(300);
11280 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11281 ins_encode %{
11282 __ array_equals(true, $ary1$$Register, $ary2$$Register,
11283 $tmp1$$Register, $tmp2$$Register,
11284 $result$$Register, false /* byte */);
11285 %}
11286 ins_pipe(pipe_class_default);
11287 %}
11288
11289 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11290 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11291 iRegIdst tmp1, iRegIdst tmp2,
11292 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11293 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11294 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11295 // Required for EA: check if it is still a type_array.
11296 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11297 ins_cost(150);
11298
11299 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11300 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11301
11302 ins_encode %{
11303 immPOper *needleOper = (immPOper *)$needleImm;
11304 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11305 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11306 jchar chr;
11307 #ifdef VM_LITTLE_ENDIAN
11308 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11309 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11310 #else
11311 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11312 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11313 #endif
11314 __ string_indexof_char($result$$Register,
11315 $haystack$$Register, $haycnt$$Register,
11316 R0, chr,
11317 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11318 %}
11319 ins_pipe(pipe_class_compare);
11320 %}
11321
11322 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11323 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11324 iRegIdst tmp1, iRegIdst tmp2,
11325 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11326 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11327 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11328 // Required for EA: check if it is still a type_array.
11329 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11330 ins_cost(150);
11331
11332 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11333 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11334
11335 ins_encode %{
11336 immPOper *needleOper = (immPOper *)$needleImm;
11337 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11338 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11339 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11340 __ string_indexof_char($result$$Register,
11341 $haystack$$Register, $haycnt$$Register,
11342 R0, chr,
11343 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11344 %}
11345 ins_pipe(pipe_class_compare);
11346 %}
11347
11348 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11349 immP needleImm, immL offsetImm, immI_1 needlecntImm,
11350 iRegIdst tmp1, iRegIdst tmp2,
11351 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11352 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11353 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11354 // Required for EA: check if it is still a type_array.
11355 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11356 ins_cost(150);
11357
11358 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11359 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11360
11361 ins_encode %{
11362 immPOper *needleOper = (immPOper *)$needleImm;
11363 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11364 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
11365 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11366 __ string_indexof_char($result$$Register,
11367 $haystack$$Register, $haycnt$$Register,
11368 R0, chr,
11369 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11370 %}
11371 ins_pipe(pipe_class_compare);
11372 %}
11373
11374 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11375 rscratch2RegP needle, immI_1 needlecntImm,
11376 iRegIdst tmp1, iRegIdst tmp2,
11377 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11378 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11379 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11380 // Required for EA: check if it is still a type_array.
11381 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11382 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11383 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11384 ins_cost(180);
11385
11386 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11387 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11388 ins_encode %{
11389 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11390 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11391 guarantee(needle_values, "sanity");
11392 jchar chr;
11393 #ifdef VM_LITTLE_ENDIAN
11394 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11395 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11396 #else
11397 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11398 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11399 #endif
11400 __ string_indexof_char($result$$Register,
11401 $haystack$$Register, $haycnt$$Register,
11402 R0, chr,
11403 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11404 %}
11405 ins_pipe(pipe_class_compare);
11406 %}
11407
11408 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11409 rscratch2RegP needle, immI_1 needlecntImm,
11410 iRegIdst tmp1, iRegIdst tmp2,
11411 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11412 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11413 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11414 // Required for EA: check if it is still a type_array.
11415 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11416 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11417 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11418 ins_cost(180);
11419
11420 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11421 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11422 ins_encode %{
11423 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11424 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11425 guarantee(needle_values, "sanity");
11426 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11427 __ string_indexof_char($result$$Register,
11428 $haystack$$Register, $haycnt$$Register,
11429 R0, chr,
11430 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11431 %}
11432 ins_pipe(pipe_class_compare);
11433 %}
11434
11435 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11436 rscratch2RegP needle, immI_1 needlecntImm,
11437 iRegIdst tmp1, iRegIdst tmp2,
11438 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11439 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11440 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11441 // Required for EA: check if it is still a type_array.
11442 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11443 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11444 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11445 ins_cost(180);
11446
11447 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11448 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11449 ins_encode %{
11450 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11451 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11452 guarantee(needle_values, "sanity");
11453 jchar chr = (jchar)needle_values->element_value(0).as_byte();
11454 __ string_indexof_char($result$$Register,
11455 $haystack$$Register, $haycnt$$Register,
11456 R0, chr,
11457 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11458 %}
11459 ins_pipe(pipe_class_compare);
11460 %}
11461
11462 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11463 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11464 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11465 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11466 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11467 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
11468 ins_cost(180);
11469
11470 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch"
11471 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11472 ins_encode %{
11473 __ string_indexof_char($result$$Register,
11474 $haystack$$Register, $haycnt$$Register,
11475 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11476 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11477 %}
11478 ins_pipe(pipe_class_compare);
11479 %}
11480
11481 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11482 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11483 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11484 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11485 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11486 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
11487 ins_cost(180);
11488
11489 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch"
11490 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11491 ins_encode %{
11492 __ string_indexof_char($result$$Register,
11493 $haystack$$Register, $haycnt$$Register,
11494 $ch$$Register, 0 /* this is not used if the character is already in a register */,
11495 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11496 %}
11497 ins_pipe(pipe_class_compare);
11498 %}
11499
11500 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11501 iRegPsrc needle, uimmI15 needlecntImm,
11502 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11503 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11504 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11505 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11506 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11507 // Required for EA: check if it is still a type_array.
11508 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11509 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11510 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11511 ins_cost(250);
11512
11513 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11514 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11515 ins_encode %{
11516 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11517 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11518
11519 __ string_indexof($result$$Register,
11520 $haystack$$Register, $haycnt$$Register,
11521 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11522 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11523 %}
11524 ins_pipe(pipe_class_compare);
11525 %}
11526
11527 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11528 iRegPsrc needle, uimmI15 needlecntImm,
11529 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11530 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11531 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11532 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11533 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11534 // Required for EA: check if it is still a type_array.
11535 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11536 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11537 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11538 ins_cost(250);
11539
11540 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11541 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11542 ins_encode %{
11543 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11544 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11545
11546 __ string_indexof($result$$Register,
11547 $haystack$$Register, $haycnt$$Register,
11548 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11549 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11550 %}
11551 ins_pipe(pipe_class_compare);
11552 %}
11553
11554 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11555 iRegPsrc needle, uimmI15 needlecntImm,
11556 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11557 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11558 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11559 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11560 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11561 // Required for EA: check if it is still a type_array.
11562 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11563 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11564 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11565 ins_cost(250);
11566
11567 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11568 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11569 ins_encode %{
11570 Node *ndl = in(operand_index($needle)); // The node that defines needle.
11571 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11572
11573 __ string_indexof($result$$Register,
11574 $haystack$$Register, $haycnt$$Register,
11575 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11576 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11577 %}
11578 ins_pipe(pipe_class_compare);
11579 %}
11580
11581 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11582 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11583 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11584 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11585 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11586 TEMP_DEF result,
11587 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11588 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11589 ins_cost(300);
11590
11591 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11592 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11593 ins_encode %{
11594 __ string_indexof($result$$Register,
11595 $haystack$$Register, $haycnt$$Register,
11596 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11597 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11598 %}
11599 ins_pipe(pipe_class_compare);
11600 %}
11601
11602 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11603 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11604 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11605 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11606 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11607 TEMP_DEF result,
11608 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11609 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11610 ins_cost(300);
11611
11612 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11613 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11614 ins_encode %{
11615 __ string_indexof($result$$Register,
11616 $haystack$$Register, $haycnt$$Register,
11617 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11618 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11619 %}
11620 ins_pipe(pipe_class_compare);
11621 %}
11622
11623 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11624 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11625 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11626 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11627 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11628 TEMP_DEF result,
11629 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11630 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11631 ins_cost(300);
11632
11633 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11634 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11635 ins_encode %{
11636 __ string_indexof($result$$Register,
11637 $haystack$$Register, $haycnt$$Register,
11638 $needle$$Register, nullptr, $needlecnt$$Register, 0, // needlecnt not constant.
11639 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11640 %}
11641 ins_pipe(pipe_class_compare);
11642 %}
11643
11644 // char[] to byte[] compression
11645 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11646 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11647 match(Set result (StrCompressedCopy src (Binary dst len)));
11648 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11649 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11650 ins_cost(300);
11651 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11652 ins_encode %{
11653 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11654 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11655 %}
11656 ins_pipe(pipe_class_default);
11657 %}
11658
11659 // byte[] to char[] inflation
11660 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
11661 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11662 match(Set dummy (StrInflatedCopy src (Binary dst len)));
11663 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11664 ins_cost(300);
11665 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11666 ins_encode %{
11667 Label Ldone;
11668 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
11669 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11670 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
11671 __ beq(CR0, Ldone);
11672 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
11673 __ bind(Ldone);
11674 %}
11675 ins_pipe(pipe_class_default);
11676 %}
11677
11678 // StringCoding.java intrinsics
11679 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
11680 regCTR ctr, flagsRegCR0 cr0)
11681 %{
11682 match(Set result (CountPositives ary1 len));
11683 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
11684 ins_cost(300);
11685 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
11686 ins_encode %{
11687 __ count_positives($ary1$$Register, $len$$Register, $result$$Register,
11688 $tmp1$$Register, $tmp2$$Register);
11689 %}
11690 ins_pipe(pipe_class_default);
11691 %}
11692
11693 // encode char[] to byte[] in ISO_8859_1
11694 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11695 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11696 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
11697 match(Set result (EncodeISOArray src (Binary dst len)));
11698 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11699 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11700 ins_cost(300);
11701 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11702 ins_encode %{
11703 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11704 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
11705 %}
11706 ins_pipe(pipe_class_default);
11707 %}
11708
11709 // encode char[] to byte[] in ASCII
11710 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11711 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11712 predicate(((EncodeISOArrayNode*)n)->is_ascii());
11713 match(Set result (EncodeISOArray src (Binary dst len)));
11714 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11715 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11716 ins_cost(300);
11717 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11718 ins_encode %{
11719 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
11720 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
11721 %}
11722 ins_pipe(pipe_class_default);
11723 %}
11724
11725
11726 //---------- Min/Max Instructions ---------------------------------------------
11727
11728
11729 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
11730 match(Set dst (MinI src1 src2));
11731 effect(KILL cr0);
11732 ins_cost(DEFAULT_COST*2);
11733
11734 size(8);
11735 ins_encode %{
11736 __ cmpw(CR0, $src1$$Register, $src2$$Register);
11737 __ isel($dst$$Register, CR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
11738 %}
11739 ins_pipe(pipe_class_default);
11740 %}
11741
11742
11743 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
11744 match(Set dst (MaxI src1 src2));
11745 effect(KILL cr0);
11746 ins_cost(DEFAULT_COST*2);
11747
11748 size(8);
11749 ins_encode %{
11750 __ cmpw(CR0, $src1$$Register, $src2$$Register);
11751 __ isel($dst$$Register, CR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
11752 %}
11753 ins_pipe(pipe_class_default);
11754 %}
11755
11756 instruct minF(regF dst, regF src1, regF src2) %{
11757 match(Set dst (MinF src1 src2));
11758 predicate(PowerArchitecturePPC64 >= 9);
11759 ins_cost(DEFAULT_COST);
11760
11761 format %{ "XSMINJDP $dst, $src1, $src2\t// MinF" %}
11762 size(4);
11763 ins_encode %{
11764 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11765 %}
11766 ins_pipe(pipe_class_default);
11767 %}
11768
11769 instruct minD(regD dst, regD src1, regD src2) %{
11770 match(Set dst (MinD src1 src2));
11771 predicate(PowerArchitecturePPC64 >= 9);
11772 ins_cost(DEFAULT_COST);
11773
11774 format %{ "XSMINJDP $dst, $src1, $src2\t// MinD" %}
11775 size(4);
11776 ins_encode %{
11777 __ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11778 %}
11779 ins_pipe(pipe_class_default);
11780 %}
11781
11782 instruct maxF(regF dst, regF src1, regF src2) %{
11783 match(Set dst (MaxF src1 src2));
11784 predicate(PowerArchitecturePPC64 >= 9);
11785 ins_cost(DEFAULT_COST);
11786
11787 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxF" %}
11788 size(4);
11789 ins_encode %{
11790 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11791 %}
11792 ins_pipe(pipe_class_default);
11793 %}
11794
11795 instruct maxD(regD dst, regD src1, regD src2) %{
11796 match(Set dst (MaxD src1 src2));
11797 predicate(PowerArchitecturePPC64 >= 9);
11798 ins_cost(DEFAULT_COST);
11799
11800 format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxD" %}
11801 size(4);
11802 ins_encode %{
11803 __ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
11804 %}
11805 ins_pipe(pipe_class_default);
11806 %}
11807
11808 //---------- Population Count Instructions ------------------------------------
11809
11810 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
11811 match(Set dst (PopCountI src));
11812 predicate(UsePopCountInstruction);
11813 ins_cost(DEFAULT_COST);
11814
11815 format %{ "POPCNTW $dst, $src" %}
11816 size(4);
11817 ins_encode %{
11818 __ popcntw($dst$$Register, $src$$Register);
11819 %}
11820 ins_pipe(pipe_class_default);
11821 %}
11822
11823 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
11824 predicate(UsePopCountInstruction);
11825 match(Set dst (PopCountL src));
11826 ins_cost(DEFAULT_COST);
11827
11828 format %{ "POPCNTD $dst, $src" %}
11829 size(4);
11830 ins_encode %{
11831 __ popcntd($dst$$Register, $src$$Register);
11832 %}
11833 ins_pipe(pipe_class_default);
11834 %}
11835
11836 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
11837 match(Set dst (CountLeadingZerosI src));
11838 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
11839 ins_cost(DEFAULT_COST);
11840
11841 format %{ "CNTLZW $dst, $src" %}
11842 size(4);
11843 ins_encode %{
11844 __ cntlzw($dst$$Register, $src$$Register);
11845 %}
11846 ins_pipe(pipe_class_default);
11847 %}
11848
11849 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
11850 match(Set dst (CountLeadingZerosL src));
11851 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
11852 ins_cost(DEFAULT_COST);
11853
11854 format %{ "CNTLZD $dst, $src" %}
11855 size(4);
11856 ins_encode %{
11857 __ cntlzd($dst$$Register, $src$$Register);
11858 %}
11859 ins_pipe(pipe_class_default);
11860 %}
11861
11862 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
11863 // no match-rule, false predicate
11864 effect(DEF dst, USE src);
11865 predicate(false);
11866
11867 format %{ "CNTLZD $dst, $src" %}
11868 size(4);
11869 ins_encode %{
11870 __ cntlzd($dst$$Register, $src$$Register);
11871 %}
11872 ins_pipe(pipe_class_default);
11873 %}
11874
11875 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
11876 match(Set dst (CountTrailingZerosI src));
11877 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
11878 ins_cost(DEFAULT_COST);
11879
11880 expand %{
11881 immI16 imm1 %{ (int)-1 %}
11882 immI16 imm2 %{ (int)32 %}
11883 immI_minus1 m1 %{ -1 %}
11884 iRegIdst tmpI1;
11885 iRegIdst tmpI2;
11886 iRegIdst tmpI3;
11887 addI_reg_imm16(tmpI1, src, imm1);
11888 andcI_reg_reg(tmpI2, src, m1, tmpI1);
11889 countLeadingZerosI(tmpI3, tmpI2);
11890 subI_imm16_reg(dst, imm2, tmpI3);
11891 %}
11892 %}
11893
11894 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{
11895 match(Set dst (CountTrailingZerosI src));
11896 predicate(UseCountTrailingZerosInstructionsPPC64);
11897 ins_cost(DEFAULT_COST);
11898
11899 format %{ "CNTTZW $dst, $src" %}
11900 size(4);
11901 ins_encode %{
11902 __ cnttzw($dst$$Register, $src$$Register);
11903 %}
11904 ins_pipe(pipe_class_default);
11905 %}
11906
11907 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
11908 match(Set dst (CountTrailingZerosL src));
11909 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
11910 ins_cost(DEFAULT_COST);
11911
11912 expand %{
11913 immL16 imm1 %{ (long)-1 %}
11914 immI16 imm2 %{ (int)64 %}
11915 iRegLdst tmpL1;
11916 iRegLdst tmpL2;
11917 iRegIdst tmpL3;
11918 addL_reg_imm16(tmpL1, src, imm1);
11919 andcL_reg_reg(tmpL2, tmpL1, src);
11920 countLeadingZerosL(tmpL3, tmpL2);
11921 subI_imm16_reg(dst, imm2, tmpL3);
11922 %}
11923 %}
11924
11925 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{
11926 match(Set dst (CountTrailingZerosL src));
11927 predicate(UseCountTrailingZerosInstructionsPPC64);
11928 ins_cost(DEFAULT_COST);
11929
11930 format %{ "CNTTZD $dst, $src" %}
11931 size(4);
11932 ins_encode %{
11933 __ cnttzd($dst$$Register, $src$$Register);
11934 %}
11935 ins_pipe(pipe_class_default);
11936 %}
11937
11938 // Expand nodes for byte_reverse_int/ushort/short.
11939 instruct rlwinm(iRegIdst dst, iRegIsrc src, immI16 shift, immI16 mb, immI16 me) %{
11940 effect(DEF dst, USE src, USE shift, USE mb, USE me);
11941 predicate(false);
11942
11943 format %{ "RLWINM $dst, $src, $shift, $mb, $me" %}
11944 size(4);
11945 ins_encode %{
11946 __ rlwinm($dst$$Register, $src$$Register, $shift$$constant, $mb$$constant, $me$$constant);
11947 %}
11948 ins_pipe(pipe_class_default);
11949 %}
11950
11951 // Expand nodes for byte_reverse_int.
11952 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
11953 effect(DEF dst, USE src, USE n, USE b);
11954 predicate(false);
11955
11956 format %{ "INSRWI $dst, $src, $n, $b" %}
11957 size(4);
11958 ins_encode %{
11959 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
11960 %}
11961 ins_pipe(pipe_class_default);
11962 %}
11963
11964 // As insrwi_a, but with USE_DEF.
11965 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 n, immI16 b) %{
11966 effect(USE_DEF dst, USE src, USE n, USE b);
11967 predicate(false);
11968
11969 format %{ "INSRWI $dst, $src, $n, $b" %}
11970 size(4);
11971 ins_encode %{
11972 __ insrwi($dst$$Register, $src$$Register, $n$$constant, $b$$constant);
11973 %}
11974 ins_pipe(pipe_class_default);
11975 %}
11976
11977 // Just slightly faster than java implementation.
11978 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
11979 match(Set dst (ReverseBytesI src));
11980 predicate(!UseByteReverseInstructions);
11981 ins_cost(7*DEFAULT_COST);
11982
11983 expand %{
11984 immI16 imm24 %{ (int) 24 %}
11985 immI16 imm16 %{ (int) 16 %}
11986 immI16 imm8 %{ (int) 8 %}
11987 immI16 imm4 %{ (int) 4 %}
11988 immI16 imm0 %{ (int) 0 %}
11989 iRegLdst tmpI1;
11990 iRegLdst tmpI2;
11991 iRegLdst tmpI3;
11992
11993 urShiftI_reg_imm(tmpI1, src, imm24);
11994 insrwi_a(dst, tmpI1, imm8, imm24);
11995 urShiftI_reg_imm(tmpI2, src, imm16);
11996 insrwi(dst, tmpI2, imm16, imm8);
11997 urShiftI_reg_imm(tmpI3, src, imm8);
11998 insrwi(dst, tmpI3, imm8, imm8);
11999 insrwi(dst, src, imm8, imm0);
12000 %}
12001 %}
12002
12003 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{
12004 match(Set dst (ReverseBytesI src));
12005 predicate(UseVectorByteReverseInstructionsPPC64);
12006 effect(TEMP tmpV);
12007 ins_cost(DEFAULT_COST*3);
12008 size(12);
12009 format %{ "MTVSRWZ $tmpV, $src\n"
12010 "\tXXBRW $tmpV, $tmpV\n"
12011 "\tMFVSRWZ $dst, $tmpV" %}
12012
12013 ins_encode %{
12014 __ mtvsrwz($tmpV$$VectorRegister.to_vsr(), $src$$Register);
12015 __ xxbrw($tmpV$$VectorRegister.to_vsr(), $tmpV$$VectorRegister->to_vsr());
12016 __ mfvsrwz($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12017 %}
12018 ins_pipe(pipe_class_default);
12019 %}
12020
12021 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{
12022 match(Set dst (ReverseBytesI src));
12023 predicate(UseByteReverseInstructions);
12024 ins_cost(DEFAULT_COST);
12025 size(4);
12026
12027 format %{ "BRW $dst, $src" %}
12028
12029 ins_encode %{
12030 __ brw($dst$$Register, $src$$Register);
12031 %}
12032 ins_pipe(pipe_class_default);
12033 %}
12034
12035 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
12036 match(Set dst (ReverseBytesL src));
12037 predicate(!UseByteReverseInstructions);
12038 ins_cost(15*DEFAULT_COST);
12039
12040 expand %{
12041 immI16 imm56 %{ (int) 56 %}
12042 immI16 imm48 %{ (int) 48 %}
12043 immI16 imm40 %{ (int) 40 %}
12044 immI16 imm32 %{ (int) 32 %}
12045 immI16 imm24 %{ (int) 24 %}
12046 immI16 imm16 %{ (int) 16 %}
12047 immI16 imm8 %{ (int) 8 %}
12048 immI16 imm0 %{ (int) 0 %}
12049 iRegLdst tmpL1;
12050 iRegLdst tmpL2;
12051 iRegLdst tmpL3;
12052 iRegLdst tmpL4;
12053 iRegLdst tmpL5;
12054 iRegLdst tmpL6;
12055
12056 // src : |a|b|c|d|e|f|g|h|
12057 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
12058 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
12059 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
12060 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
12061 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
12062 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
12063 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
12064 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
12065 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
12066 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
12067 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
12068 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
12069 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
12070 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
12071 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
12072 %}
12073 %}
12074
12075 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{
12076 match(Set dst (ReverseBytesL src));
12077 predicate(UseVectorByteReverseInstructionsPPC64);
12078 effect(TEMP tmpV);
12079 ins_cost(DEFAULT_COST*3);
12080 size(12);
12081 format %{ "MTVSRD $tmpV, $src\n"
12082 "\tXXBRD $tmpV, $tmpV\n"
12083 "\tMFVSRD $dst, $tmpV" %}
12084
12085 ins_encode %{
12086 __ mtvsrd($tmpV$$VectorRegister->to_vsr(), $src$$Register);
12087 __ xxbrd($tmpV$$VectorRegister->to_vsr(), $tmpV$$VectorRegister->to_vsr());
12088 __ mfvsrd($dst$$Register, $tmpV$$VectorRegister->to_vsr());
12089 %}
12090 ins_pipe(pipe_class_default);
12091 %}
12092
12093 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{
12094 match(Set dst (ReverseBytesL src));
12095 predicate(UseByteReverseInstructions);
12096 ins_cost(DEFAULT_COST);
12097 size(4);
12098
12099 format %{ "BRD $dst, $src" %}
12100
12101 ins_encode %{
12102 __ brd($dst$$Register, $src$$Register);
12103 %}
12104 ins_pipe(pipe_class_default);
12105 %}
12106
12107 // Need zero extend. Must not use brh only.
12108 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
12109 match(Set dst (ReverseBytesUS src));
12110 ins_cost(2*DEFAULT_COST);
12111
12112 expand %{
12113 immI16 imm31 %{ (int) 31 %}
12114 immI16 imm24 %{ (int) 24 %}
12115 immI16 imm16 %{ (int) 16 %}
12116 immI16 imm8 %{ (int) 8 %}
12117
12118 rlwinm(dst, src, imm24, imm24, imm31);
12119 insrwi(dst, src, imm8, imm16);
12120 %}
12121 %}
12122
12123 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
12124 match(Set dst (ReverseBytesS src));
12125 predicate(!UseByteReverseInstructions);
12126 ins_cost(3*DEFAULT_COST);
12127
12128 expand %{
12129 immI16 imm16 %{ (int) 16 %}
12130 immI16 imm8 %{ (int) 8 %}
12131 iRegLdst tmpI1;
12132
12133 urShiftI_reg_imm(tmpI1, src, imm8);
12134 insrwi(tmpI1, src, imm8, imm16);
12135 extsh(dst, tmpI1);
12136 %}
12137 %}
12138
12139 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{
12140 match(Set dst (ReverseBytesS src));
12141 predicate(UseByteReverseInstructions);
12142 ins_cost(DEFAULT_COST);
12143 size(8);
12144
12145 format %{ "BRH $dst, $src\n\t"
12146 "EXTSH $dst, $dst" %}
12147
12148 ins_encode %{
12149 __ brh($dst$$Register, $src$$Register);
12150 __ extsh($dst$$Register, $dst$$Register);
12151 %}
12152 ins_pipe(pipe_class_default);
12153 %}
12154
12155 // Load Integer reversed byte order
12156 instruct loadI_reversed(iRegIdst dst, indirect mem) %{
12157 match(Set dst (ReverseBytesI (LoadI mem)));
12158 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12159 ins_cost(MEMORY_REF_COST);
12160
12161 size(4);
12162 ins_encode %{
12163 __ lwbrx($dst$$Register, $mem$$Register);
12164 %}
12165 ins_pipe(pipe_class_default);
12166 %}
12167
12168 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{
12169 match(Set dst (ReverseBytesI (LoadI mem)));
12170 ins_cost(2 * MEMORY_REF_COST);
12171
12172 size(12);
12173 ins_encode %{
12174 __ lwbrx($dst$$Register, $mem$$Register);
12175 __ twi_0($dst$$Register);
12176 __ isync();
12177 %}
12178 ins_pipe(pipe_class_default);
12179 %}
12180
12181 // Load Long - aligned and reversed
12182 instruct loadL_reversed(iRegLdst dst, indirect mem) %{
12183 match(Set dst (ReverseBytesL (LoadL mem)));
12184 predicate((n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))));
12185 ins_cost(MEMORY_REF_COST);
12186
12187 size(4);
12188 ins_encode %{
12189 __ ldbrx($dst$$Register, $mem$$Register);
12190 %}
12191 ins_pipe(pipe_class_default);
12192 %}
12193
12194 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{
12195 match(Set dst (ReverseBytesL (LoadL mem)));
12196 ins_cost(2 * MEMORY_REF_COST);
12197
12198 size(12);
12199 ins_encode %{
12200 __ ldbrx($dst$$Register, $mem$$Register);
12201 __ twi_0($dst$$Register);
12202 __ isync();
12203 %}
12204 ins_pipe(pipe_class_default);
12205 %}
12206
12207 // Load unsigned short / char reversed byte order
12208 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
12209 match(Set dst (ReverseBytesUS (LoadUS mem)));
12210 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12211 ins_cost(MEMORY_REF_COST);
12212
12213 size(4);
12214 ins_encode %{
12215 __ lhbrx($dst$$Register, $mem$$Register);
12216 %}
12217 ins_pipe(pipe_class_default);
12218 %}
12219
12220 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{
12221 match(Set dst (ReverseBytesUS (LoadUS mem)));
12222 ins_cost(2 * MEMORY_REF_COST);
12223
12224 size(12);
12225 ins_encode %{
12226 __ lhbrx($dst$$Register, $mem$$Register);
12227 __ twi_0($dst$$Register);
12228 __ isync();
12229 %}
12230 ins_pipe(pipe_class_default);
12231 %}
12232
12233 // Load short reversed byte order
12234 instruct loadS_reversed(iRegIdst dst, indirect mem) %{
12235 match(Set dst (ReverseBytesS (LoadS mem)));
12236 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
12237 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
12238
12239 size(8);
12240 ins_encode %{
12241 __ lhbrx($dst$$Register, $mem$$Register);
12242 __ extsh($dst$$Register, $dst$$Register);
12243 %}
12244 ins_pipe(pipe_class_default);
12245 %}
12246
12247 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{
12248 match(Set dst (ReverseBytesS (LoadS mem)));
12249 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12250
12251 size(16);
12252 ins_encode %{
12253 __ lhbrx($dst$$Register, $mem$$Register);
12254 __ twi_0($dst$$Register);
12255 __ extsh($dst$$Register, $dst$$Register);
12256 __ isync();
12257 %}
12258 ins_pipe(pipe_class_default);
12259 %}
12260
12261 // Store Integer reversed byte order
12262 instruct storeI_reversed(iRegIsrc src, indirect mem) %{
12263 match(Set mem (StoreI mem (ReverseBytesI src)));
12264 ins_cost(MEMORY_REF_COST);
12265
12266 size(4);
12267 ins_encode %{
12268 __ stwbrx($src$$Register, $mem$$Register);
12269 %}
12270 ins_pipe(pipe_class_default);
12271 %}
12272
12273 // Store Long reversed byte order
12274 instruct storeL_reversed(iRegLsrc src, indirect mem) %{
12275 match(Set mem (StoreL mem (ReverseBytesL src)));
12276 ins_cost(MEMORY_REF_COST);
12277
12278 size(4);
12279 ins_encode %{
12280 __ stdbrx($src$$Register, $mem$$Register);
12281 %}
12282 ins_pipe(pipe_class_default);
12283 %}
12284
12285 // Store unsigned short / char reversed byte order
12286 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
12287 match(Set mem (StoreC mem (ReverseBytesUS src)));
12288 ins_cost(MEMORY_REF_COST);
12289
12290 size(4);
12291 ins_encode %{
12292 __ sthbrx($src$$Register, $mem$$Register);
12293 %}
12294 ins_pipe(pipe_class_default);
12295 %}
12296
12297 // Store short reversed byte order
12298 instruct storeS_reversed(iRegIsrc src, indirect mem) %{
12299 match(Set mem (StoreC mem (ReverseBytesS src)));
12300 ins_cost(MEMORY_REF_COST);
12301
12302 size(4);
12303 ins_encode %{
12304 __ sthbrx($src$$Register, $mem$$Register);
12305 %}
12306 ins_pipe(pipe_class_default);
12307 %}
12308
12309 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
12310 effect(DEF temp1, USE src);
12311
12312 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %}
12313 size(4);
12314 ins_encode %{
12315 __ mtvsrwz($temp1$$VectorRegister->to_vsr(), $src$$Register);
12316 %}
12317 ins_pipe(pipe_class_default);
12318 %}
12319
12320 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{
12321 effect(DEF dst, USE src, USE imm1);
12322
12323 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %}
12324 size(4);
12325 ins_encode %{
12326 __ xxspltw($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $imm1$$constant);
12327 %}
12328 ins_pipe(pipe_class_default);
12329 %}
12330
12331 instruct xscvdpspn_regF(vecX dst, regF src) %{
12332 effect(DEF dst, USE src);
12333
12334 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %}
12335 size(4);
12336 ins_encode %{
12337 __ xscvdpspn($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr());
12338 %}
12339 ins_pipe(pipe_class_default);
12340 %}
12341
12342 //---------- Replicate Vector Instructions ------------------------------------
12343
12344 // Insrdi does replicate if src == dst.
12345 instruct repl32(iRegLdst dst) %{
12346 predicate(false);
12347 effect(USE_DEF dst);
12348
12349 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %}
12350 size(4);
12351 ins_encode %{
12352 __ insrdi($dst$$Register, $dst$$Register, 32, 0);
12353 %}
12354 ins_pipe(pipe_class_default);
12355 %}
12356
12357 // Insrdi does replicate if src == dst.
12358 instruct repl48(iRegLdst dst) %{
12359 predicate(false);
12360 effect(USE_DEF dst);
12361
12362 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %}
12363 size(4);
12364 ins_encode %{
12365 __ insrdi($dst$$Register, $dst$$Register, 48, 0);
12366 %}
12367 ins_pipe(pipe_class_default);
12368 %}
12369
12370 // Insrdi does replicate if src == dst.
12371 instruct repl56(iRegLdst dst) %{
12372 predicate(false);
12373 effect(USE_DEF dst);
12374
12375 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %}
12376 size(4);
12377 ins_encode %{
12378 __ insrdi($dst$$Register, $dst$$Register, 56, 0);
12379 %}
12380 ins_pipe(pipe_class_default);
12381 %}
12382
12383 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12384 match(Set dst (Replicate src));
12385 predicate(n->as_Vector()->length() == 8 &&
12386 Matcher::vector_element_basic_type(n) == T_BYTE);
12387 expand %{
12388 moveReg(dst, src);
12389 repl56(dst);
12390 repl48(dst);
12391 repl32(dst);
12392 %}
12393 %}
12394
12395 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
12396 match(Set dst (Replicate zero));
12397 predicate(n->as_Vector()->length() == 8 &&
12398 Matcher::vector_element_basic_type(n) == T_BYTE);
12399 format %{ "LI $dst, #0 \t// replicate8B" %}
12400 size(4);
12401 ins_encode %{
12402 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12403 %}
12404 ins_pipe(pipe_class_default);
12405 %}
12406
12407 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
12408 match(Set dst (Replicate src));
12409 predicate(n->as_Vector()->length() == 8 &&
12410 Matcher::vector_element_basic_type(n) == T_BYTE);
12411 format %{ "LI $dst, #-1 \t// replicate8B" %}
12412 size(4);
12413 ins_encode %{
12414 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12415 %}
12416 ins_pipe(pipe_class_default);
12417 %}
12418
12419 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{
12420 match(Set dst (Replicate src));
12421 predicate(n->as_Vector()->length() == 16 &&
12422 Matcher::vector_element_basic_type(n) == T_BYTE);
12423
12424 expand %{
12425 iRegLdst tmpL;
12426 vecX tmpV;
12427 immI8 imm1 %{ (int) 1 %}
12428 moveReg(tmpL, src);
12429 repl56(tmpL);
12430 repl48(tmpL);
12431 mtvsrwz(tmpV, tmpL);
12432 xxspltw(dst, tmpV, imm1);
12433 %}
12434 %}
12435
12436 instruct repl16B_immI0(vecX dst, immI_0 zero) %{
12437 match(Set dst (Replicate zero));
12438 predicate(n->as_Vector()->length() == 16 &&
12439 Matcher::vector_element_basic_type(n) == T_BYTE);
12440
12441 format %{ "XXLXOR $dst, $zero \t// replicate16B" %}
12442 size(4);
12443 ins_encode %{
12444 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12445 %}
12446 ins_pipe(pipe_class_default);
12447 %}
12448
12449 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{
12450 match(Set dst (Replicate src));
12451 predicate(n->as_Vector()->length() == 16 &&
12452 Matcher::vector_element_basic_type(n) == T_BYTE);
12453
12454 format %{ "XXLEQV $dst, $src \t// replicate16B" %}
12455 size(4);
12456 ins_encode %{
12457 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12458 %}
12459 ins_pipe(pipe_class_default);
12460 %}
12461
12462 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12463 match(Set dst (Replicate src));
12464 predicate(n->as_Vector()->length() == 4 &&
12465 Matcher::vector_element_basic_type(n) == T_SHORT);
12466 expand %{
12467 moveReg(dst, src);
12468 repl48(dst);
12469 repl32(dst);
12470 %}
12471 %}
12472
12473 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
12474 match(Set dst (Replicate zero));
12475 predicate(n->as_Vector()->length() == 4 &&
12476 Matcher::vector_element_basic_type(n) == T_SHORT);
12477 format %{ "LI $dst, #0 \t// replicate4S" %}
12478 size(4);
12479 ins_encode %{
12480 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12481 %}
12482 ins_pipe(pipe_class_default);
12483 %}
12484
12485 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
12486 match(Set dst (Replicate src));
12487 predicate(n->as_Vector()->length() == 4 &&
12488 Matcher::vector_element_basic_type(n) == T_SHORT);
12489 format %{ "LI $dst, -1 \t// replicate4S" %}
12490 size(4);
12491 ins_encode %{
12492 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12493 %}
12494 ins_pipe(pipe_class_default);
12495 %}
12496
12497 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{
12498 match(Set dst (Replicate src));
12499 predicate(n->as_Vector()->length() == 8 &&
12500 Matcher::vector_element_basic_type(n) == T_SHORT);
12501
12502 expand %{
12503 iRegLdst tmpL;
12504 vecX tmpV;
12505 immI8 zero %{ (int) 0 %}
12506 moveReg(tmpL, src);
12507 repl48(tmpL);
12508 repl32(tmpL);
12509 mtvsrd(tmpV, tmpL);
12510 xxpermdi(dst, tmpV, tmpV, zero);
12511 %}
12512 %}
12513
12514 instruct repl8S_immI0(vecX dst, immI_0 zero) %{
12515 match(Set dst (Replicate zero));
12516 predicate(n->as_Vector()->length() == 8 &&
12517 Matcher::vector_element_basic_type(n) == T_SHORT);
12518
12519 format %{ "XXLXOR $dst, $zero \t// replicate8S" %}
12520 size(4);
12521 ins_encode %{
12522 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12523 %}
12524 ins_pipe(pipe_class_default);
12525 %}
12526
12527 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{
12528 match(Set dst (Replicate src));
12529 predicate(n->as_Vector()->length() == 8 &&
12530 Matcher::vector_element_basic_type(n) == T_SHORT);
12531
12532 format %{ "XXLEQV $dst, $src \t// replicate8S" %}
12533 size(4);
12534 ins_encode %{
12535 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12536 %}
12537 ins_pipe(pipe_class_default);
12538 %}
12539
12540 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12541 match(Set dst (Replicate src));
12542 predicate(n->as_Vector()->length() == 2 &&
12543 Matcher::vector_element_basic_type(n) == T_INT);
12544 ins_cost(2 * DEFAULT_COST);
12545 expand %{
12546 moveReg(dst, src);
12547 repl32(dst);
12548 %}
12549 %}
12550
12551 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
12552 match(Set dst (Replicate zero));
12553 predicate(n->as_Vector()->length() == 2 &&
12554 Matcher::vector_element_basic_type(n) == T_INT);
12555 format %{ "LI $dst, #0 \t// replicate2I" %}
12556 size(4);
12557 ins_encode %{
12558 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12559 %}
12560 ins_pipe(pipe_class_default);
12561 %}
12562
12563 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
12564 match(Set dst (Replicate src));
12565 predicate(n->as_Vector()->length() == 2 &&
12566 Matcher::vector_element_basic_type(n) == T_INT);
12567 format %{ "LI $dst, -1 \t// replicate2I" %}
12568 size(4);
12569 ins_encode %{
12570 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12571 %}
12572 ins_pipe(pipe_class_default);
12573 %}
12574
12575 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{
12576 match(Set dst (Replicate src));
12577 predicate(n->as_Vector()->length() == 4 &&
12578 Matcher::vector_element_basic_type(n) == T_INT);
12579 ins_cost(2 * DEFAULT_COST);
12580
12581 expand %{
12582 iRegLdst tmpL;
12583 vecX tmpV;
12584 immI8 zero %{ (int) 0 %}
12585 moveReg(tmpL, src);
12586 repl32(tmpL);
12587 mtvsrd(tmpV, tmpL);
12588 xxpermdi(dst, tmpV, tmpV, zero);
12589 %}
12590 %}
12591
12592 instruct repl4I_immI0(vecX dst, immI_0 zero) %{
12593 match(Set dst (Replicate zero));
12594 predicate(n->as_Vector()->length() == 4 &&
12595 Matcher::vector_element_basic_type(n) == T_INT);
12596
12597 format %{ "XXLXOR $dst, $zero \t// replicate4I" %}
12598 size(4);
12599 ins_encode %{
12600 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12601 %}
12602 ins_pipe(pipe_class_default);
12603 %}
12604
12605 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{
12606 match(Set dst (Replicate src));
12607 predicate(n->as_Vector()->length() == 4 &&
12608 Matcher::vector_element_basic_type(n) == T_INT);
12609
12610 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %}
12611 size(4);
12612 ins_encode %{
12613 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
12614 %}
12615 ins_pipe(pipe_class_default);
12616 %}
12617
12618 // Move float to int register via stack, replicate.
12619 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
12620 match(Set dst (Replicate src));
12621 predicate(n->as_Vector()->length() == 2 &&
12622 Matcher::vector_element_basic_type(n) == T_FLOAT);
12623 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12624 expand %{
12625 stackSlotL tmpS;
12626 iRegIdst tmpI;
12627 moveF2I_reg_stack(tmpS, src); // Move float to stack.
12628 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
12629 moveReg(dst, tmpI); // Move int to long reg.
12630 repl32(dst); // Replicate bitpattern.
12631 %}
12632 %}
12633
12634 // Replicate scalar constant to packed float values in Double register
12635 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
12636 match(Set dst (Replicate src));
12637 predicate(n->as_Vector()->length() == 2 &&
12638 Matcher::vector_element_basic_type(n) == T_FLOAT);
12639 ins_cost(5 * DEFAULT_COST);
12640
12641 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
12642 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
12643 %}
12644
12645 // Replicate scalar zero constant to packed float values in Double register
12646 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
12647 match(Set dst (Replicate zero));
12648 predicate(n->as_Vector()->length() == 2 &&
12649 Matcher::vector_element_basic_type(n) == T_FLOAT);
12650
12651 format %{ "LI $dst, #0 \t// replicate2F" %}
12652 size(4);
12653 ins_encode %{
12654 __ li($dst$$Register, 0x0);
12655 %}
12656 ins_pipe(pipe_class_default);
12657 %}
12658
12659
12660 //----------Vector Arithmetic Instructions--------------------------------------
12661
12662 // Vector Addition Instructions
12663
12664 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
12665 match(Set dst (AddVB src1 src2));
12666 predicate(n->as_Vector()->length() == 16);
12667 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %}
12668 size(4);
12669 ins_encode %{
12670 __ vaddubm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12671 %}
12672 ins_pipe(pipe_class_default);
12673 %}
12674
12675 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
12676 match(Set dst (AddVS src1 src2));
12677 predicate(n->as_Vector()->length() == 8);
12678 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %}
12679 size(4);
12680 ins_encode %{
12681 __ vadduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12682 %}
12683 ins_pipe(pipe_class_default);
12684 %}
12685
12686 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
12687 match(Set dst (AddVI src1 src2));
12688 predicate(n->as_Vector()->length() == 4);
12689 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %}
12690 size(4);
12691 ins_encode %{
12692 __ vadduwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12693 %}
12694 ins_pipe(pipe_class_default);
12695 %}
12696
12697 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
12698 match(Set dst (AddVF src1 src2));
12699 predicate(n->as_Vector()->length() == 4);
12700 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %}
12701 size(4);
12702 ins_encode %{
12703 __ vaddfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12704 %}
12705 ins_pipe(pipe_class_default);
12706 %}
12707
12708 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
12709 match(Set dst (AddVL src1 src2));
12710 predicate(n->as_Vector()->length() == 2);
12711 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %}
12712 size(4);
12713 ins_encode %{
12714 __ vaddudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12715 %}
12716 ins_pipe(pipe_class_default);
12717 %}
12718
12719 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
12720 match(Set dst (AddVD src1 src2));
12721 predicate(n->as_Vector()->length() == 2);
12722 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %}
12723 size(4);
12724 ins_encode %{
12725 __ xvadddp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12726 %}
12727 ins_pipe(pipe_class_default);
12728 %}
12729
12730 // Vector Subtraction Instructions
12731
12732 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
12733 match(Set dst (SubVB src1 src2));
12734 predicate(n->as_Vector()->length() == 16);
12735 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %}
12736 size(4);
12737 ins_encode %{
12738 __ vsububm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12739 %}
12740 ins_pipe(pipe_class_default);
12741 %}
12742
12743 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
12744 match(Set dst (SubVS src1 src2));
12745 predicate(n->as_Vector()->length() == 8);
12746 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %}
12747 size(4);
12748 ins_encode %{
12749 __ vsubuhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12750 %}
12751 ins_pipe(pipe_class_default);
12752 %}
12753
12754 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
12755 match(Set dst (SubVI src1 src2));
12756 predicate(n->as_Vector()->length() == 4);
12757 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %}
12758 size(4);
12759 ins_encode %{
12760 __ vsubuwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12761 %}
12762 ins_pipe(pipe_class_default);
12763 %}
12764
12765 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
12766 match(Set dst (SubVF src1 src2));
12767 predicate(n->as_Vector()->length() == 4);
12768 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %}
12769 size(4);
12770 ins_encode %{
12771 __ vsubfp($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12772 %}
12773 ins_pipe(pipe_class_default);
12774 %}
12775
12776 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
12777 match(Set dst (SubVL src1 src2));
12778 predicate(n->as_Vector()->length() == 2);
12779 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %}
12780 size(4);
12781 ins_encode %{
12782 __ vsubudm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12783 %}
12784 ins_pipe(pipe_class_default);
12785 %}
12786
12787 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
12788 match(Set dst (SubVD src1 src2));
12789 predicate(n->as_Vector()->length() == 2);
12790 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %}
12791 size(4);
12792 ins_encode %{
12793 __ xvsubdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12794 %}
12795 ins_pipe(pipe_class_default);
12796 %}
12797
12798 // Vector Multiplication Instructions
12799
12800 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
12801 match(Set dst (MulVS src1 src2));
12802 predicate(n->as_Vector()->length() == 8);
12803 effect(TEMP tmp);
12804 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %}
12805 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %}
12806 size(8);
12807 ins_encode %{
12808 __ vspltish($tmp$$VectorRegister, 0);
12809 __ vmladduhm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister, $tmp$$VectorRegister);
12810 %}
12811 ins_pipe(pipe_class_default);
12812 %}
12813
12814 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
12815 match(Set dst (MulVI src1 src2));
12816 predicate(n->as_Vector()->length() == 4);
12817 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %}
12818 size(4);
12819 ins_encode %{
12820 __ vmuluwm($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12821 %}
12822 ins_pipe(pipe_class_default);
12823 %}
12824
12825 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
12826 match(Set dst (MulVF src1 src2));
12827 predicate(n->as_Vector()->length() == 4);
12828 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %}
12829 size(4);
12830 ins_encode %{
12831 __ xvmulsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12832 %}
12833 ins_pipe(pipe_class_default);
12834 %}
12835
12836 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
12837 match(Set dst (MulVD src1 src2));
12838 predicate(n->as_Vector()->length() == 2);
12839 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %}
12840 size(4);
12841 ins_encode %{
12842 __ xvmuldp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12843 %}
12844 ins_pipe(pipe_class_default);
12845 %}
12846
12847 // Vector Division Instructions
12848
12849 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
12850 match(Set dst (DivVF src1 src2));
12851 predicate(n->as_Vector()->length() == 4);
12852 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %}
12853 size(4);
12854 ins_encode %{
12855 __ xvdivsp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12856 %}
12857 ins_pipe(pipe_class_default);
12858 %}
12859
12860 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
12861 match(Set dst (DivVD src1 src2));
12862 predicate(n->as_Vector()->length() == 2);
12863 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %}
12864 size(4);
12865 ins_encode %{
12866 __ xvdivdp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
12867 %}
12868 ins_pipe(pipe_class_default);
12869 %}
12870
12871 // Vector Min / Max Instructions
12872
12873 instruct vmin_reg(vecX dst, vecX src1, vecX src2) %{
12874 match(Set dst (MinV src1 src2));
12875 format %{ "VMIN $dst,$src1,$src2\t// vector min" %}
12876 size(4);
12877 ins_encode %{
12878 BasicType bt = Matcher::vector_element_basic_type(this);
12879 switch (bt) {
12880 case T_INT:
12881 __ vminsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12882 break;
12883 case T_LONG:
12884 __ vminsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12885 break;
12886 default:
12887 ShouldNotReachHere();
12888 }
12889 %}
12890 ins_pipe(pipe_class_default);
12891 %}
12892
12893 instruct vmax_reg(vecX dst, vecX src1, vecX src2) %{
12894 match(Set dst (MaxV src1 src2));
12895 format %{ "VMAX $dst,$src1,$src2\t// vector max" %}
12896 size(4);
12897 ins_encode %{
12898 BasicType bt = Matcher::vector_element_basic_type(this);
12899 switch (bt) {
12900 case T_INT:
12901 __ vmaxsw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12902 break;
12903 case T_LONG:
12904 __ vmaxsd($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12905 break;
12906 default:
12907 ShouldNotReachHere();
12908 }
12909 %}
12910 ins_pipe(pipe_class_default);
12911 %}
12912
12913 instruct vminu_reg(vecX dst, vecX src1, vecX src2) %{
12914 match(Set dst (UMinV src1 src2));
12915 format %{ "VMINU $dst,$src1,$src2\t// vector unsigned min" %}
12916 size(4);
12917 ins_encode %{
12918 BasicType bt = Matcher::vector_element_basic_type(this);
12919 switch (bt) {
12920 case T_INT:
12921 __ vminuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12922 break;
12923 case T_LONG:
12924 __ vminud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12925 break;
12926 default:
12927 ShouldNotReachHere();
12928 }
12929 %}
12930 ins_pipe(pipe_class_default);
12931 %}
12932
12933 instruct vmaxu_reg(vecX dst, vecX src1, vecX src2) %{
12934 match(Set dst (UMaxV src1 src2));
12935 format %{ "VMAXU $dst,$src1,$src2\t// vector unsigned max" %}
12936 size(4);
12937 ins_encode %{
12938 BasicType bt = Matcher::vector_element_basic_type(this);
12939 switch (bt) {
12940 case T_INT:
12941 __ vmaxuw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12942 break;
12943 case T_LONG:
12944 __ vmaxud($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12945 break;
12946 default:
12947 ShouldNotReachHere();
12948 }
12949 %}
12950 ins_pipe(pipe_class_default);
12951 %}
12952
12953 instruct vand(vecX dst, vecX src1, vecX src2) %{
12954 match(Set dst (AndV src1 src2));
12955 size(4);
12956 format %{ "VAND $dst,$src1,$src2\t// and vectors" %}
12957 ins_encode %{
12958 __ vand($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12959 %}
12960 ins_pipe(pipe_class_default);
12961 %}
12962
12963 instruct vor(vecX dst, vecX src1, vecX src2) %{
12964 match(Set dst (OrV src1 src2));
12965 size(4);
12966 format %{ "VOR $dst,$src1,$src2\t// or vectors" %}
12967 ins_encode %{
12968 __ vor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12969 %}
12970 ins_pipe(pipe_class_default);
12971 %}
12972
12973 instruct vxor(vecX dst, vecX src1, vecX src2) %{
12974 match(Set dst (XorV src1 src2));
12975 size(4);
12976 format %{ "VXOR $dst,$src1,$src2\t// xor vectors" %}
12977 ins_encode %{
12978 __ vxor($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister);
12979 %}
12980 ins_pipe(pipe_class_default);
12981 %}
12982
12983 instruct reductionI_arith_logic(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2) %{
12984 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
12985 match(Set dst (AddReductionVI srcInt srcVec));
12986 match(Set dst (MulReductionVI srcInt srcVec));
12987 match(Set dst (AndReductionV srcInt srcVec));
12988 match(Set dst ( OrReductionV srcInt srcVec));
12989 match(Set dst (XorReductionV srcInt srcVec));
12990 effect(TEMP tmp1, TEMP tmp2);
12991 ins_cost(DEFAULT_COST * 6);
12992 format %{ "REDUCEI_ARITH_LOGIC // $dst,$srcInt,$srcVec,$tmp1,$tmp2\t// reduce vector int add/mul/and/or/xor" %}
12993 size(24);
12994 ins_encode %{
12995 int opcode = this->ideal_Opcode();
12996 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
12997 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
12998 %}
12999 ins_pipe(pipe_class_default);
13000 %}
13001
13002 instruct reductionI_min_max(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2, flagsRegCR0 cr0) %{
13003 predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT);
13004 match(Set dst (MinReductionV srcInt srcVec));
13005 match(Set dst (MaxReductionV srcInt srcVec));
13006 effect(TEMP tmp1, TEMP tmp2, KILL cr0);
13007 ins_cost(DEFAULT_COST * 7);
13008 format %{ "REDUCEI_MINMAX // $dst,$srcInt,$srcVec,$tmp1,$tmp2,cr0\t// reduce vector int min/max" %}
13009 size(28);
13010 ins_encode %{
13011 int opcode = this->ideal_Opcode();
13012 __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorRegister,
13013 $tmp1$$VectorRegister, $tmp2$$VectorRegister);
13014 %}
13015 ins_pipe(pipe_class_default);
13016 %}
13017
13018 // Vector Absolute Instructions
13019
13020 instruct vabs4F_reg(vecX dst, vecX src) %{
13021 match(Set dst (AbsVF src));
13022 predicate(n->as_Vector()->length() == 4);
13023 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
13024 size(4);
13025 ins_encode %{
13026 __ xvabssp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13027 %}
13028 ins_pipe(pipe_class_default);
13029 %}
13030
13031 instruct vabs2D_reg(vecX dst, vecX src) %{
13032 match(Set dst (AbsVD src));
13033 predicate(n->as_Vector()->length() == 2);
13034 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
13035 size(4);
13036 ins_encode %{
13037 __ xvabsdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13038 %}
13039 ins_pipe(pipe_class_default);
13040 %}
13041
13042 // Round Instructions
13043 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{
13044 match(Set dst (RoundDoubleMode src rmode));
13045 format %{ "RoundDoubleMode $src,$rmode" %}
13046 size(4);
13047 ins_encode %{
13048 switch ($rmode$$constant) {
13049 case RoundDoubleModeNode::rmode_rint:
13050 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr());
13051 break;
13052 case RoundDoubleModeNode::rmode_floor:
13053 __ frim($dst$$FloatRegister, $src$$FloatRegister);
13054 break;
13055 case RoundDoubleModeNode::rmode_ceil:
13056 __ frip($dst$$FloatRegister, $src$$FloatRegister);
13057 break;
13058 default:
13059 ShouldNotReachHere();
13060 }
13061 %}
13062 ins_pipe(pipe_class_default);
13063 %}
13064
13065 // Vector Round Instructions
13066 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
13067 match(Set dst (RoundDoubleModeV src rmode));
13068 predicate(n->as_Vector()->length() == 2);
13069 format %{ "RoundDoubleModeV $src,$rmode" %}
13070 size(4);
13071 ins_encode %{
13072 switch ($rmode$$constant) {
13073 case RoundDoubleModeNode::rmode_rint:
13074 __ xvrdpic($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13075 break;
13076 case RoundDoubleModeNode::rmode_floor:
13077 __ xvrdpim($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13078 break;
13079 case RoundDoubleModeNode::rmode_ceil:
13080 __ xvrdpip($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13081 break;
13082 default:
13083 ShouldNotReachHere();
13084 }
13085 %}
13086 ins_pipe(pipe_class_default);
13087 %}
13088
13089 // Vector Negate Instructions
13090
13091 instruct vneg4F_reg(vecX dst, vecX src) %{
13092 match(Set dst (NegVF src));
13093 predicate(n->as_Vector()->length() == 4);
13094 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
13095 size(4);
13096 ins_encode %{
13097 __ xvnegsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13098 %}
13099 ins_pipe(pipe_class_default);
13100 %}
13101
13102 instruct vneg2D_reg(vecX dst, vecX src) %{
13103 match(Set dst (NegVD src));
13104 predicate(n->as_Vector()->length() == 2);
13105 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
13106 size(4);
13107 ins_encode %{
13108 __ xvnegdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13109 %}
13110 ins_pipe(pipe_class_default);
13111 %}
13112
13113 instruct vneg4I_reg(vecX dst, vecX src) %{
13114 match(Set dst (NegVI src));
13115 predicate(Matcher::vector_element_basic_type(n) == T_INT);
13116 format %{ "VNEGW $dst,$src\t// negate int vector" %}
13117 size(4);
13118 ins_encode %{
13119 __ vnegw($dst$$VectorRegister, $src$$VectorRegister);
13120 %}
13121 ins_pipe(pipe_class_default);
13122 %}
13123
13124 // Vector Square Root Instructions
13125
13126 instruct vsqrt4F_reg(vecX dst, vecX src) %{
13127 match(Set dst (SqrtVF src));
13128 predicate(n->as_Vector()->length() == 4);
13129 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
13130 size(4);
13131 ins_encode %{
13132 __ xvsqrtsp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13133 %}
13134 ins_pipe(pipe_class_default);
13135 %}
13136
13137 instruct vsqrt2D_reg(vecX dst, vecX src) %{
13138 match(Set dst (SqrtVD src));
13139 predicate(n->as_Vector()->length() == 2);
13140 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %}
13141 size(4);
13142 ins_encode %{
13143 __ xvsqrtdp($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr());
13144 %}
13145 ins_pipe(pipe_class_default);
13146 %}
13147
13148 // Vector Population Count and Zeros Count Instructions
13149
13150 instruct vpopcnt_reg(vecX dst, vecX src) %{
13151 match(Set dst (PopCountVI src));
13152 match(Set dst (PopCountVL src));
13153 format %{ "VPOPCNT $dst,$src\t// pop count packed" %}
13154 size(4);
13155 ins_encode %{
13156 BasicType bt = Matcher::vector_element_basic_type(this);
13157 switch (bt) {
13158 case T_BYTE:
13159 __ vpopcntb($dst$$VectorRegister, $src$$VectorRegister);
13160 break;
13161 case T_SHORT:
13162 __ vpopcnth($dst$$VectorRegister, $src$$VectorRegister);
13163 break;
13164 case T_INT:
13165 __ vpopcntw($dst$$VectorRegister, $src$$VectorRegister);
13166 break;
13167 case T_LONG:
13168 __ vpopcntd($dst$$VectorRegister, $src$$VectorRegister);
13169 break;
13170 default:
13171 ShouldNotReachHere();
13172 }
13173 %}
13174 ins_pipe(pipe_class_default);
13175 %}
13176
13177 instruct vcount_leading_zeros_reg(vecX dst, vecX src) %{
13178 match(Set dst (CountLeadingZerosV src));
13179 format %{ "VCLZ $dst,$src\t// leading zeros count packed" %}
13180 size(4);
13181 ins_encode %{
13182 BasicType bt = Matcher::vector_element_basic_type(this);
13183 switch (bt) {
13184 case T_BYTE:
13185 __ vclzb($dst$$VectorRegister, $src$$VectorRegister);
13186 break;
13187 case T_SHORT:
13188 __ vclzh($dst$$VectorRegister, $src$$VectorRegister);
13189 break;
13190 case T_INT:
13191 __ vclzw($dst$$VectorRegister, $src$$VectorRegister);
13192 break;
13193 case T_LONG:
13194 __ vclzd($dst$$VectorRegister, $src$$VectorRegister);
13195 break;
13196 default:
13197 ShouldNotReachHere();
13198 }
13199 %}
13200 ins_pipe(pipe_class_default);
13201 %}
13202
13203 instruct vcount_trailing_zeros_reg(vecX dst, vecX src) %{
13204 match(Set dst (CountTrailingZerosV src));
13205 format %{ "VCTZ $dst,$src\t// trailing zeros count packed" %}
13206 size(4);
13207 ins_encode %{
13208 BasicType bt = Matcher::vector_element_basic_type(this);
13209 switch (bt) {
13210 case T_BYTE:
13211 __ vctzb($dst$$VectorRegister, $src$$VectorRegister);
13212 break;
13213 case T_SHORT:
13214 __ vctzh($dst$$VectorRegister, $src$$VectorRegister);
13215 break;
13216 case T_INT:
13217 __ vctzw($dst$$VectorRegister, $src$$VectorRegister);
13218 break;
13219 case T_LONG:
13220 __ vctzd($dst$$VectorRegister, $src$$VectorRegister);
13221 break;
13222 default:
13223 ShouldNotReachHere();
13224 }
13225 %}
13226 ins_pipe(pipe_class_default);
13227 %}
13228
13229 // --------------------------------- FMA --------------------------------------
13230 // src1 * src2 + dst
13231 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{
13232 match(Set dst (FmaVF dst (Binary src1 src2)));
13233 predicate(n->as_Vector()->length() == 4);
13234
13235 format %{ "XVMADDASP $dst, $src1, $src2" %}
13236
13237 size(4);
13238 ins_encode %{
13239 assert(UseFMA, "Needs FMA instructions support.");
13240 __ xvmaddasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13241 %}
13242 ins_pipe(pipe_class_default);
13243 %}
13244
13245 // src1 * (-src2) + dst
13246 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13247 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{
13248 match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
13249 predicate(n->as_Vector()->length() == 4);
13250
13251 format %{ "XVNMSUBASP $dst, $src1, $src2" %}
13252
13253 size(4);
13254 ins_encode %{
13255 assert(UseFMA, "Needs FMA instructions support.");
13256 __ xvnmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13257 %}
13258 ins_pipe(pipe_class_default);
13259 %}
13260
13261 // src1 * src2 - dst
13262 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{
13263 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2)));
13264 predicate(n->as_Vector()->length() == 4);
13265
13266 format %{ "XVMSUBASP $dst, $src1, $src2" %}
13267
13268 size(4);
13269 ins_encode %{
13270 assert(UseFMA, "Needs FMA instructions support.");
13271 __ xvmsubasp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13272 %}
13273 ins_pipe(pipe_class_default);
13274 %}
13275
13276 // src1 * src2 + dst
13277 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{
13278 match(Set dst (FmaVD dst (Binary src1 src2)));
13279 predicate(n->as_Vector()->length() == 2);
13280
13281 format %{ "XVMADDADP $dst, $src1, $src2" %}
13282
13283 size(4);
13284 ins_encode %{
13285 assert(UseFMA, "Needs FMA instructions support.");
13286 __ xvmaddadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13287 %}
13288 ins_pipe(pipe_class_default);
13289 %}
13290
13291 // src1 * (-src2) + dst
13292 // "(-src1) * src2 + dst" has been idealized to "src2 * (-src1) + dst"
13293 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{
13294 match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
13295 predicate(n->as_Vector()->length() == 2);
13296
13297 format %{ "XVNMSUBADP $dst, $src1, $src2" %}
13298
13299 size(4);
13300 ins_encode %{
13301 assert(UseFMA, "Needs FMA instructions support.");
13302 __ xvnmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13303 %}
13304 ins_pipe(pipe_class_default);
13305 %}
13306
13307 // src1 * src2 - dst
13308 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
13309 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2)));
13310 predicate(n->as_Vector()->length() == 2);
13311
13312 format %{ "XVMSUBADP $dst, $src1, $src2" %}
13313
13314 size(4);
13315 ins_encode %{
13316 assert(UseFMA, "Needs FMA instructions support.");
13317 __ xvmsubadp($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr());
13318 %}
13319 ins_pipe(pipe_class_default);
13320 %}
13321
13322 //----------Overflow Math Instructions-----------------------------------------
13323
13324 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
13325 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
13326 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
13327
13328 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13329 match(Set cr0 (OverflowAddL op1 op2));
13330
13331 format %{ "ADD_ $op1, $op2\t# overflow check long" %}
13332 size(12);
13333 ins_encode %{
13334 __ li(R0, 0);
13335 __ mtxer(R0); // clear XER.SO
13336 __ addo_(R0, $op1$$Register, $op2$$Register);
13337 %}
13338 ins_pipe(pipe_class_default);
13339 %}
13340
13341 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13342 match(Set cr0 (OverflowSubL op1 op2));
13343
13344 format %{ "SUBFO_ R0, $op2, $op1\t# overflow check long" %}
13345 size(12);
13346 ins_encode %{
13347 __ li(R0, 0);
13348 __ mtxer(R0); // clear XER.SO
13349 __ subfo_(R0, $op2$$Register, $op1$$Register);
13350 %}
13351 ins_pipe(pipe_class_default);
13352 %}
13353
13354 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
13355 match(Set cr0 (OverflowSubL zero op2));
13356
13357 format %{ "NEGO_ R0, $op2\t# overflow check long" %}
13358 size(12);
13359 ins_encode %{
13360 __ li(R0, 0);
13361 __ mtxer(R0); // clear XER.SO
13362 __ nego_(R0, $op2$$Register);
13363 %}
13364 ins_pipe(pipe_class_default);
13365 %}
13366
13367 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
13368 match(Set cr0 (OverflowMulL op1 op2));
13369
13370 format %{ "MULLDO_ R0, $op1, $op2\t# overflow check long" %}
13371 size(12);
13372 ins_encode %{
13373 __ li(R0, 0);
13374 __ mtxer(R0); // clear XER.SO
13375 __ mulldo_(R0, $op1$$Register, $op2$$Register);
13376 %}
13377 ins_pipe(pipe_class_default);
13378 %}
13379
13380 instruct repl4F_reg_Ex(vecX dst, regF src) %{
13381 match(Set dst (Replicate src));
13382 predicate(n->as_Vector()->length() == 4 &&
13383 Matcher::vector_element_basic_type(n) == T_FLOAT);
13384 ins_cost(DEFAULT_COST);
13385 expand %{
13386 vecX tmpV;
13387 immI8 zero %{ (int) 0 %}
13388
13389 xscvdpspn_regF(tmpV, src);
13390 xxspltw(dst, tmpV, zero);
13391 %}
13392 %}
13393
13394 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{
13395 match(Set dst (Replicate src));
13396 predicate(n->as_Vector()->length() == 4 &&
13397 Matcher::vector_element_basic_type(n) == T_FLOAT);
13398 effect(TEMP tmp);
13399 ins_cost(10 * DEFAULT_COST);
13400
13401 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) );
13402 %}
13403
13404 instruct repl4F_immF0(vecX dst, immF_0 zero) %{
13405 match(Set dst (Replicate zero));
13406 predicate(n->as_Vector()->length() == 4 &&
13407 Matcher::vector_element_basic_type(n) == T_FLOAT);
13408
13409 format %{ "XXLXOR $dst, $zero \t// replicate4F" %}
13410 size(4);
13411 ins_encode %{
13412 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13413 %}
13414 ins_pipe(pipe_class_default);
13415 %}
13416
13417 instruct repl2D_reg_Ex(vecX dst, regD src) %{
13418 match(Set dst (Replicate src));
13419 predicate(n->as_Vector()->length() == 2 &&
13420 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13421
13422 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %}
13423 size(4);
13424 ins_encode %{
13425 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0);
13426 %}
13427 ins_pipe(pipe_class_default);
13428 %}
13429
13430 instruct repl2D_immD0(vecX dst, immD_0 zero) %{
13431 match(Set dst (Replicate zero));
13432 predicate(n->as_Vector()->length() == 2 &&
13433 Matcher::vector_element_basic_type(n) == T_DOUBLE);
13434
13435 format %{ "XXLXOR $dst, $zero \t// replicate2D" %}
13436 size(4);
13437 ins_encode %{
13438 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13439 %}
13440 ins_pipe(pipe_class_default);
13441 %}
13442
13443 instruct mtvsrd(vecX dst, iRegLsrc src) %{
13444 predicate(false);
13445 effect(DEF dst, USE src);
13446
13447 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %}
13448 size(4);
13449 ins_encode %{
13450 __ mtvsrd($dst$$VectorRegister->to_vsr(), $src$$Register);
13451 %}
13452 ins_pipe(pipe_class_default);
13453 %}
13454
13455 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{
13456 effect(DEF dst, USE src, USE zero);
13457
13458 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %}
13459 size(4);
13460 ins_encode %{
13461 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $src$$VectorRegister->to_vsr(), $zero$$constant);
13462 %}
13463 ins_pipe(pipe_class_default);
13464 %}
13465
13466 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{
13467 effect(DEF dst, USE src1, USE src2, USE zero);
13468
13469 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %}
13470 size(4);
13471 ins_encode %{
13472 __ xxpermdi($dst$$VectorRegister->to_vsr(), $src1$$VectorRegister->to_vsr(), $src2$$VectorRegister->to_vsr(), $zero$$constant);
13473 %}
13474 ins_pipe(pipe_class_default);
13475 %}
13476
13477 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{
13478 predicate(Matcher::vector_element_basic_type(n) == T_LONG);
13479 match(Set dst (Replicate src));
13480 predicate(n->as_Vector()->length() == 2);
13481 expand %{
13482 vecX tmpV;
13483 immI8 zero %{ (int) 0 %}
13484 mtvsrd(tmpV, src);
13485 xxpermdi(dst, tmpV, tmpV, zero);
13486 %}
13487 %}
13488
13489 instruct repl2L_immI0(vecX dst, immI_0 zero) %{
13490 match(Set dst (Replicate zero));
13491 predicate(n->as_Vector()->length() == 2 &&
13492 Matcher::vector_element_basic_type(n) == T_LONG);
13493
13494 format %{ "XXLXOR $dst, $zero \t// replicate2L" %}
13495 size(4);
13496 ins_encode %{
13497 __ xxlxor($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13498 %}
13499 ins_pipe(pipe_class_default);
13500 %}
13501
13502 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{
13503 match(Set dst (Replicate src));
13504 predicate(n->as_Vector()->length() == 2 &&
13505 Matcher::vector_element_basic_type(n) == T_LONG);
13506
13507 format %{ "XXLEQV $dst, $src \t// replicate2L" %}
13508 size(4);
13509 ins_encode %{
13510 __ xxleqv($dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr(), $dst$$VectorRegister->to_vsr());
13511 %}
13512 ins_pipe(pipe_class_default);
13513 %}
13514
13515 // ============================================================================
13516 // Safepoint Instruction
13517
13518 instruct safePoint_poll(iRegPdst poll) %{
13519 match(SafePoint poll);
13520
13521 // It caused problems to add the effect that r0 is killed, but this
13522 // effect no longer needs to be mentioned, since r0 is not contained
13523 // in a reg_class.
13524
13525 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
13526 size(4);
13527 ins_encode( enc_poll(0x0, poll) );
13528 ins_pipe(pipe_class_default);
13529 %}
13530
13531 // ============================================================================
13532 // Call Instructions
13533
13534 source %{
13535
13536 #include "runtime/continuation.hpp"
13537
13538 %}
13539
13540 // Call Java Static Instruction
13541
13542 instruct CallStaticJavaDirect(method meth) %{
13543 match(CallStaticJava);
13544 effect(USE meth);
13545 ins_cost(CALL_COST);
13546
13547 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
13548
13549 format %{ "CALL,static $meth \t// ==> " %}
13550 size((Continuations::enabled() ? 8 : 4));
13551 ins_encode( enc_java_static_call(meth) );
13552 ins_pipe(pipe_class_call);
13553 %}
13554
13555 // Call Java Dynamic Instruction
13556
13557 instruct CallDynamicJavaDirect(method meth) %{
13558 match(CallDynamicJava);
13559 effect(USE meth);
13560 ins_cost(CALL_COST);
13561
13562 // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
13563 ins_num_consts(4);
13564
13565 format %{ "CALL,dynamic $meth \t// ==> " %}
13566 ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
13567 ins_pipe(pipe_class_call);
13568 %}
13569
13570 // Call Runtime Instruction
13571
13572 instruct CallRuntimeDirect(method meth) %{
13573 match(CallRuntime);
13574 effect(USE meth);
13575 ins_cost(CALL_COST);
13576
13577 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13578 // env for callee, C-toc.
13579 ins_num_consts(3);
13580
13581 format %{ "CALL,runtime" %}
13582 ins_encode( enc_java_to_runtime_call(meth) );
13583 ins_pipe(pipe_class_call);
13584 %}
13585
13586 // Call Leaf
13587
13588 // Used by postalloc expand of CallLeafDirect_Ex (mtctr).
13589 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
13590 effect(DEF dst, USE src);
13591
13592 ins_num_consts(1);
13593
13594 format %{ "MTCTR $src" %}
13595 size(4);
13596 ins_encode( enc_leaf_call_mtctr(src) );
13597 ins_pipe(pipe_class_default);
13598 %}
13599
13600 // Used by postalloc expand of CallLeafDirect_Ex (actual call).
13601 instruct CallLeafDirect(method meth) %{
13602 match(CallLeaf); // To get the data all the data fields we need ...
13603 effect(USE meth);
13604 predicate(false); // but never match.
13605
13606 format %{ "BCTRL \t// leaf call $meth ==> " %}
13607 size((Continuations::enabled() ? 8 : 4));
13608 ins_encode %{
13609 __ bctrl();
13610 __ post_call_nop();
13611 %}
13612 ins_pipe(pipe_class_call);
13613 %}
13614
13615 // postalloc expand of CallLeafDirect.
13616 // Load address to call from TOC, then bl to it.
13617 instruct CallLeafDirect_Ex(method meth) %{
13618 match(CallLeaf);
13619 effect(USE meth);
13620 ins_cost(CALL_COST);
13621
13622 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
13623 // env for callee, C-toc.
13624 ins_num_consts(3);
13625
13626 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
13627 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13628 %}
13629
13630 // Call runtime without safepoint - same as CallLeaf.
13631 // postalloc expand of CallLeafNoFPDirect.
13632 // Load address to call from TOC, then bl to it.
13633 instruct CallLeafNoFPDirect_Ex(method meth) %{
13634 match(CallLeafNoFP);
13635 effect(USE meth);
13636 ins_cost(CALL_COST);
13637
13638 // Enc_java_to_runtime_call needs up to 3 constants: call target,
13639 // env for callee, C-toc.
13640 ins_num_consts(3);
13641
13642 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
13643 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13644 %}
13645
13646 // Tail Call; Jump from runtime stub to Java code.
13647 // Also known as an 'interprocedural jump'.
13648 // Target of jump will eventually return to caller.
13649 // TailJump below removes the return address.
13650 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{
13651 match(TailCall jump_target method_ptr);
13652 ins_cost(CALL_COST);
13653
13654 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t"
13655 "BCTR \t// tail call" %}
13656 size(8);
13657 ins_encode %{
13658 __ mtctr($jump_target$$Register);
13659 __ bctr();
13660 %}
13661 ins_pipe(pipe_class_call);
13662 %}
13663
13664 // Return Instruction
13665 instruct Ret() %{
13666 match(Return);
13667 format %{ "BLR \t// branch to link register" %}
13668 size(4);
13669 ins_encode %{
13670 // LR is restored in MachEpilogNode. Just do the RET here.
13671 __ blr();
13672 %}
13673 ins_pipe(pipe_class_default);
13674 %}
13675
13676 // Tail Jump; remove the return address; jump to target.
13677 // TailCall above leaves the return address around.
13678 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13679 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13680 // "restore" before this instruction (in Epilogue), we need to materialize it
13681 // in %i0.
13682 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
13683 match(TailJump jump_target ex_oop);
13684 ins_cost(CALL_COST);
13685
13686 format %{ "LD R4_ARG2 = LR\n\t"
13687 "MTCTR $jump_target\n\t"
13688 "BCTR \t// TailJump, exception oop: $ex_oop" %}
13689 size(12);
13690 ins_encode %{
13691 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP);
13692 __ mtctr($jump_target$$Register);
13693 __ bctr();
13694 %}
13695 ins_pipe(pipe_class_call);
13696 %}
13697
13698 // Forward exception.
13699 instruct ForwardExceptionjmp()
13700 %{
13701 match(ForwardException);
13702 ins_cost(CALL_COST);
13703
13704 format %{ "JMP forward_exception_stub" %}
13705 ins_encode %{
13706 __ set_inst_mark();
13707 __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
13708 __ clear_inst_mark();
13709 %}
13710 ins_pipe(pipe_class_call);
13711 %}
13712
13713 // Create exception oop: created by stack-crawling runtime code.
13714 // Created exception is now available to this handler, and is setup
13715 // just prior to jumping to this handler. No code emitted.
13716 instruct CreateException(rarg1RegP ex_oop) %{
13717 match(Set ex_oop (CreateEx));
13718 ins_cost(0);
13719
13720 format %{ " -- \t// exception oop; no code emitted" %}
13721 size(0);
13722 ins_encode( /*empty*/ );
13723 ins_pipe(pipe_class_default);
13724 %}
13725
13726 // Rethrow exception: The exception oop will come in the first
13727 // argument position. Then JUMP (not call) to the rethrow stub code.
13728 instruct RethrowException() %{
13729 match(Rethrow);
13730 ins_cost(CALL_COST);
13731
13732 format %{ "JMP rethrow_stub" %}
13733 ins_encode %{
13734 __ set_inst_mark();
13735 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
13736 __ clear_inst_mark();
13737 %}
13738 ins_pipe(pipe_class_call);
13739 %}
13740
13741 // Die now.
13742 instruct ShouldNotReachHere() %{
13743 match(Halt);
13744 ins_cost(CALL_COST);
13745
13746 format %{ "ShouldNotReachHere" %}
13747 ins_encode %{
13748 if (is_reachable()) {
13749 const char* str = __ code_string(_halt_reason);
13750 __ stop(str);
13751 }
13752 %}
13753 ins_pipe(pipe_class_default);
13754 %}
13755
13756 // This name is KNOWN by the ADLC and cannot be changed. The ADLC
13757 // forces a 'TypeRawPtr::BOTTOM' output type for this guy.
13758 // Get a DEF on threadRegP, no costs, no encoding, use
13759 // 'ins_should_rematerialize(true)' to avoid spilling.
13760 instruct tlsLoadP(threadRegP dst) %{
13761 match(Set dst (ThreadLocal));
13762 ins_cost(0);
13763
13764 ins_should_rematerialize(true);
13765
13766 format %{ " -- \t// $dst=Thread::current(), empty" %}
13767 size(0);
13768 ins_encode( /*empty*/ );
13769 ins_pipe(pipe_class_empty);
13770 %}
13771
13772 //---Some PPC specific nodes---------------------------------------------------
13773
13774 // Nop instructions
13775
13776 instruct fxNop() %{
13777 ins_cost(0);
13778
13779 ins_is_nop(true);
13780
13781 format %{ "fxNop" %}
13782 size(4);
13783 ins_encode %{
13784 __ nop();
13785 %}
13786 ins_pipe(pipe_class_default);
13787 %}
13788
13789 instruct fpNop0() %{
13790 ins_cost(0);
13791
13792 ins_is_nop(true);
13793
13794 format %{ "fpNop0" %}
13795 size(4);
13796 ins_encode %{
13797 __ fpnop0();
13798 %}
13799 ins_pipe(pipe_class_default);
13800 %}
13801
13802 instruct fpNop1() %{
13803 ins_cost(0);
13804
13805 ins_is_nop(true);
13806
13807 format %{ "fpNop1" %}
13808 size(4);
13809 ins_encode %{
13810 __ fpnop1();
13811 %}
13812 ins_pipe(pipe_class_default);
13813 %}
13814
13815 instruct brNop0() %{
13816 ins_cost(0);
13817 size(4);
13818 format %{ "brNop0" %}
13819 ins_encode %{
13820 __ brnop0();
13821 %}
13822 ins_is_nop(true);
13823 ins_pipe(pipe_class_default);
13824 %}
13825
13826 instruct brNop1() %{
13827 ins_cost(0);
13828
13829 ins_is_nop(true);
13830
13831 format %{ "brNop1" %}
13832 size(4);
13833 ins_encode %{
13834 __ brnop1();
13835 %}
13836 ins_pipe(pipe_class_default);
13837 %}
13838
13839 instruct brNop2() %{
13840 ins_cost(0);
13841
13842 ins_is_nop(true);
13843
13844 format %{ "brNop2" %}
13845 size(4);
13846 ins_encode %{
13847 __ brnop2();
13848 %}
13849 ins_pipe(pipe_class_default);
13850 %}
13851
13852 instruct cacheWB(indirect addr)
13853 %{
13854 match(CacheWB addr);
13855
13856 ins_cost(100);
13857 format %{ "cache writeback, address = $addr" %}
13858 ins_encode %{
13859 assert($addr->index_position() < 0, "should be");
13860 assert($addr$$disp == 0, "should be");
13861 __ cache_wb(Address($addr$$base$$Register));
13862 %}
13863 ins_pipe(pipe_class_default);
13864 %}
13865
13866 instruct cacheWBPreSync()
13867 %{
13868 match(CacheWBPreSync);
13869
13870 ins_cost(0);
13871 format %{ "cache writeback presync" %}
13872 ins_encode %{
13873 __ cache_wbsync(true);
13874 %}
13875 ins_pipe(pipe_class_default);
13876 %}
13877
13878 instruct cacheWBPostSync()
13879 %{
13880 match(CacheWBPostSync);
13881
13882 ins_cost(100);
13883 format %{ "cache writeback postsync" %}
13884 ins_encode %{
13885 __ cache_wbsync(false);
13886 %}
13887 ins_pipe(pipe_class_default);
13888 %}
13889
13890 //----------PEEPHOLE RULES-----------------------------------------------------
13891 // These must follow all instruction definitions as they use the names
13892 // defined in the instructions definitions.
13893 //
13894 // peepmatch ( root_instr_name [preceeding_instruction]* );
13895 //
13896 // peepconstraint %{
13897 // (instruction_number.operand_name relational_op instruction_number.operand_name
13898 // [, ...] );
13899 // // instruction numbers are zero-based using left to right order in peepmatch
13900 //
13901 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
13902 // // provide an instruction_number.operand_name for each operand that appears
13903 // // in the replacement instruction's match rule
13904 //
13905 // ---------VM FLAGS---------------------------------------------------------
13906 //
13907 // All peephole optimizations can be turned off using -XX:-OptoPeephole
13908 //
13909 // Each peephole rule is given an identifying number starting with zero and
13910 // increasing by one in the order seen by the parser. An individual peephole
13911 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
13912 // on the command-line.
13913 //
13914 // ---------CURRENT LIMITATIONS----------------------------------------------
13915 //
13916 // Only match adjacent instructions in same basic block
13917 // Only equality constraints
13918 // Only constraints between operands, not (0.dest_reg == EAX_enc)
13919 // Only one replacement instruction
13920 //
13921 // ---------EXAMPLE----------------------------------------------------------
13922 //
13923 // // pertinent parts of existing instructions in architecture description
13924 // instruct movI(eRegI dst, eRegI src) %{
13925 // match(Set dst (CopyI src));
13926 // %}
13927 //
13928 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
13929 // match(Set dst (AddI dst src));
13930 // effect(KILL cr);
13931 // %}
13932 //
13933 // // Change (inc mov) to lea
13934 // peephole %{
13935 // // increment preceded by register-register move
13936 // peepmatch ( incI_eReg movI );
13937 // // require that the destination register of the increment
13938 // // match the destination register of the move
13939 // peepconstraint ( 0.dst == 1.dst );
13940 // // construct a replacement instruction that sets
13941 // // the destination to ( move's source register + one )
13942 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13943 // %}
13944 //
13945 // Implementation no longer uses movX instructions since
13946 // machine-independent system no longer uses CopyX nodes.
13947 //
13948 // peephole %{
13949 // peepmatch ( incI_eReg movI );
13950 // peepconstraint ( 0.dst == 1.dst );
13951 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13952 // %}
13953 //
13954 // peephole %{
13955 // peepmatch ( decI_eReg movI );
13956 // peepconstraint ( 0.dst == 1.dst );
13957 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13958 // %}
13959 //
13960 // peephole %{
13961 // peepmatch ( addI_eReg_imm movI );
13962 // peepconstraint ( 0.dst == 1.dst );
13963 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13964 // %}
13965 //
13966 // peephole %{
13967 // peepmatch ( addP_eReg_imm movP );
13968 // peepconstraint ( 0.dst == 1.dst );
13969 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
13970 // %}
13971
13972 // // Change load of spilled value to only a spill
13973 // instruct storeI(memory mem, eRegI src) %{
13974 // match(Set mem (StoreI mem src));
13975 // %}
13976 //
13977 // instruct loadI(eRegI dst, memory mem) %{
13978 // match(Set dst (LoadI mem));
13979 // %}
13980 //
13981 peephole %{
13982 peepmatch ( loadI storeI );
13983 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
13984 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
13985 %}
13986
13987 peephole %{
13988 peepmatch ( loadL storeL );
13989 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
13990 peepreplace ( storeL( 1.mem 1.mem 1.src ) );
13991 %}
13992
13993 peephole %{
13994 peepmatch ( loadP storeP );
13995 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
13996 peepreplace ( storeP( 1.dst 1.dst 1.src ) );
13997 %}
13998
13999 //----------SMARTSPILL RULES---------------------------------------------------
14000 // These must follow all instruction definitions as they use the names
14001 // defined in the instructions definitions.