1 //
2 // Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
3 // Copyright (c) 2012, 2022 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 CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v
240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v
241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv
242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv
243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv
244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v
245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v
246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->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-Scalar Registers
259 // ----------------------------
260 // 1st 32 VSRs are aliases for the FPRs which are already defined above.
261 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, VMRegImpl::Bad());
262 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, VMRegImpl::Bad());
263 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, VMRegImpl::Bad());
264 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, VMRegImpl::Bad());
265 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, VMRegImpl::Bad());
266 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, VMRegImpl::Bad());
267 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, VMRegImpl::Bad());
268 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, VMRegImpl::Bad());
269 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, VMRegImpl::Bad());
270 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, VMRegImpl::Bad());
271 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, VMRegImpl::Bad());
272 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, VMRegImpl::Bad());
273 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, VMRegImpl::Bad());
274 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, VMRegImpl::Bad());
275 reg_def VSR14 ( SOC, SOE, Op_VecX, 14, VMRegImpl::Bad());
276 reg_def VSR15 ( SOC, SOE, Op_VecX, 15, VMRegImpl::Bad());
277 reg_def VSR16 ( SOC, SOE, Op_VecX, 16, VMRegImpl::Bad());
278 reg_def VSR17 ( SOC, SOE, Op_VecX, 17, VMRegImpl::Bad());
279 reg_def VSR18 ( SOC, SOE, Op_VecX, 18, VMRegImpl::Bad());
280 reg_def VSR19 ( SOC, SOE, Op_VecX, 19, VMRegImpl::Bad());
281 reg_def VSR20 ( SOC, SOE, Op_VecX, 20, VMRegImpl::Bad());
282 reg_def VSR21 ( SOC, SOE, Op_VecX, 21, VMRegImpl::Bad());
283 reg_def VSR22 ( SOC, SOE, Op_VecX, 22, VMRegImpl::Bad());
284 reg_def VSR23 ( SOC, SOE, Op_VecX, 23, VMRegImpl::Bad());
285 reg_def VSR24 ( SOC, SOE, Op_VecX, 24, VMRegImpl::Bad());
286 reg_def VSR25 ( SOC, SOE, Op_VecX, 25, VMRegImpl::Bad());
287 reg_def VSR26 ( SOC, SOE, Op_VecX, 26, VMRegImpl::Bad());
288 reg_def VSR27 ( SOC, SOE, Op_VecX, 27, VMRegImpl::Bad());
289 reg_def VSR28 ( SOC, SOE, Op_VecX, 28, VMRegImpl::Bad());
290 reg_def VSR29 ( SOC, SOE, Op_VecX, 29, VMRegImpl::Bad());
291 reg_def VSR30 ( SOC, SOE, Op_VecX, 30, VMRegImpl::Bad());
292 reg_def VSR31 ( SOC, SOE, Op_VecX, 31, VMRegImpl::Bad());
293 // 2nd 32 VSRs are aliases for the VRs which are only defined here.
294 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, VSR32->as_VMReg());
295 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, VSR33->as_VMReg());
296 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, VSR34->as_VMReg());
297 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, VSR35->as_VMReg());
298 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, VSR36->as_VMReg());
299 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, VSR37->as_VMReg());
300 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, VSR38->as_VMReg());
301 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, VSR39->as_VMReg());
302 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, VSR40->as_VMReg());
303 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, VSR41->as_VMReg());
304 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, VSR42->as_VMReg());
305 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, VSR43->as_VMReg());
306 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, VSR44->as_VMReg());
307 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, VSR45->as_VMReg());
308 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, VSR46->as_VMReg());
309 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, VSR47->as_VMReg());
310 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, VSR48->as_VMReg());
311 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, VSR49->as_VMReg());
312 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, VSR50->as_VMReg());
313 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, VSR51->as_VMReg());
314 reg_def VSR52 ( SOC, SOE, Op_VecX, 52, VSR52->as_VMReg());
315 reg_def VSR53 ( SOC, SOE, Op_VecX, 53, VSR53->as_VMReg());
316 reg_def VSR54 ( SOC, SOE, Op_VecX, 54, VSR54->as_VMReg());
317 reg_def VSR55 ( SOC, SOE, Op_VecX, 55, VSR55->as_VMReg());
318 reg_def VSR56 ( SOC, SOE, Op_VecX, 56, VSR56->as_VMReg());
319 reg_def VSR57 ( SOC, SOE, Op_VecX, 57, VSR57->as_VMReg());
320 reg_def VSR58 ( SOC, SOE, Op_VecX, 58, VSR58->as_VMReg());
321 reg_def VSR59 ( SOC, SOE, Op_VecX, 59, VSR59->as_VMReg());
322 reg_def VSR60 ( SOC, SOE, Op_VecX, 60, VSR60->as_VMReg());
323 reg_def VSR61 ( SOC, SOE, Op_VecX, 61, VSR61->as_VMReg());
324 reg_def VSR62 ( SOC, SOE, Op_VecX, 62, VSR62->as_VMReg());
325 reg_def VSR63 ( SOC, SOE, Op_VecX, 63, VSR63->as_VMReg());
326
327 // ----------------------------
328 // Specify priority of register selection within phases of register
329 // allocation. Highest priority is first. A useful heuristic is to
330 // give registers a low priority when they are required by machine
331 // instructions, like EAX and EDX on I486, and choose no-save registers
332 // before save-on-call, & save-on-call before save-on-entry. Registers
333 // which participate in fixed calling sequences should come last.
334 // Registers which are used as pairs must fall on an even boundary.
335
336 // It's worth about 1% on SPEC geomean to get this right.
337
338 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration
339 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g.
340 // R3_num. Therefore, R3_num may not be (and in reality is not)
341 // the same as R3->encoding()! Furthermore, we cannot make any
342 // assumptions on ordering, e.g. R3_num may be less than R2_num.
343 // Additionally, the function
344 // static enum RC rc_class(OptoReg::Name reg )
345 // maps a given <register>_num value to its chunk type (except for flags)
346 // and its current implementation relies on chunk0 and chunk1 having a
347 // size of 64 each.
348
349 // If you change this allocation class, please have a look at the
350 // default values for the parameters RoundRobinIntegerRegIntervalStart
351 // and RoundRobinFloatRegIntervalStart
352
353 alloc_class chunk0 (
354 // Chunk0 contains *all* 64 integer registers halves.
355
356 // "non-volatile" registers
357 R14, R14_H,
358 R15, R15_H,
359 R17, R17_H,
360 R18, R18_H,
361 R19, R19_H,
362 R20, R20_H,
363 R21, R21_H,
364 R22, R22_H,
365 R23, R23_H,
366 R24, R24_H,
367 R25, R25_H,
368 R26, R26_H,
369 R27, R27_H,
370 R28, R28_H,
371 R29, R29_H,
372 R30, R30_H,
373 R31, R31_H,
374
375 // scratch/special registers
376 R11, R11_H,
377 R12, R12_H,
378
379 // argument registers
380 R10, R10_H,
381 R9, R9_H,
382 R8, R8_H,
383 R7, R7_H,
384 R6, R6_H,
385 R5, R5_H,
386 R4, R4_H,
387 R3, R3_H,
388
389 // special registers, not available for allocation
390 R16, R16_H, // R16_thread
391 R13, R13_H, // system thread id
392 R2, R2_H, // may be used for TOC
393 R1, R1_H, // SP
394 R0, R0_H // R0 (scratch)
395 );
396
397 // If you change this allocation class, please have a look at the
398 // default values for the parameters RoundRobinIntegerRegIntervalStart
399 // and RoundRobinFloatRegIntervalStart
400
401 alloc_class chunk1 (
402 // Chunk1 contains *all* 64 floating-point registers halves.
403
404 // scratch register
405 F0, F0_H,
406
407 // argument registers
408 F13, F13_H,
409 F12, F12_H,
410 F11, F11_H,
411 F10, F10_H,
412 F9, F9_H,
413 F8, F8_H,
414 F7, F7_H,
415 F6, F6_H,
416 F5, F5_H,
417 F4, F4_H,
418 F3, F3_H,
419 F2, F2_H,
420 F1, F1_H,
421
422 // non-volatile registers
423 F14, F14_H,
424 F15, F15_H,
425 F16, F16_H,
426 F17, F17_H,
427 F18, F18_H,
428 F19, F19_H,
429 F20, F20_H,
430 F21, F21_H,
431 F22, F22_H,
432 F23, F23_H,
433 F24, F24_H,
434 F25, F25_H,
435 F26, F26_H,
436 F27, F27_H,
437 F28, F28_H,
438 F29, F29_H,
439 F30, F30_H,
440 F31, F31_H
441 );
442
443 alloc_class chunk2 (
444 // Chunk2 contains *all* 8 condition code registers.
445
446 CCR0,
447 CCR1,
448 CCR2,
449 CCR3,
450 CCR4,
451 CCR5,
452 CCR6,
453 CCR7
454 );
455
456 alloc_class chunk3 (
457 VSR0,
458 VSR1,
459 VSR2,
460 VSR3,
461 VSR4,
462 VSR5,
463 VSR6,
464 VSR7,
465 VSR8,
466 VSR9,
467 VSR10,
468 VSR11,
469 VSR12,
470 VSR13,
471 VSR14,
472 VSR15,
473 VSR16,
474 VSR17,
475 VSR18,
476 VSR19,
477 VSR20,
478 VSR21,
479 VSR22,
480 VSR23,
481 VSR24,
482 VSR25,
483 VSR26,
484 VSR27,
485 VSR28,
486 VSR29,
487 VSR30,
488 VSR31,
489 VSR32,
490 VSR33,
491 VSR34,
492 VSR35,
493 VSR36,
494 VSR37,
495 VSR38,
496 VSR39,
497 VSR40,
498 VSR41,
499 VSR42,
500 VSR43,
501 VSR44,
502 VSR45,
503 VSR46,
504 VSR47,
505 VSR48,
506 VSR49,
507 VSR50,
508 VSR51,
509 VSR52,
510 VSR53,
511 VSR54,
512 VSR55,
513 VSR56,
514 VSR57,
515 VSR58,
516 VSR59,
517 VSR60,
518 VSR61,
519 VSR62,
520 VSR63
521 );
522
523 alloc_class chunk4 (
524 // special registers
525 // These registers are not allocated, but used for nodes generated by postalloc expand.
526 SR_XER,
527 SR_LR,
528 SR_CTR,
529 SR_VRSAVE,
530 SR_SPEFSCR,
531 SR_PPR
532 );
533
534 //-------Architecture Description Register Classes-----------------------
535
536 // Several register classes are automatically defined based upon
537 // information in this architecture description.
538
539 // 1) reg_class inline_cache_reg ( as defined in frame section )
540 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
541 //
542
543 // ----------------------------
544 // 32 Bit Register Classes
545 // ----------------------------
546
547 // We specify registers twice, once as read/write, and once read-only.
548 // We use the read-only registers for source operands. With this, we
549 // can include preset read only registers in this class, as a hard-coded
550 // '0'-register. (We used to simulate this on ppc.)
551
552 // 32 bit registers that can be read and written i.e. these registers
553 // can be dest (or src) of normal instructions.
554 reg_class bits32_reg_rw(
555 /*R0*/ // R0
556 /*R1*/ // SP
557 R2, // TOC
558 R3,
559 R4,
560 R5,
561 R6,
562 R7,
563 R8,
564 R9,
565 R10,
566 R11,
567 R12,
568 /*R13*/ // system thread id
569 R14,
570 R15,
571 /*R16*/ // R16_thread
572 R17,
573 R18,
574 R19,
575 R20,
576 R21,
577 R22,
578 R23,
579 R24,
580 R25,
581 R26,
582 R27,
583 R28,
584 /*R29,*/ // global TOC
585 R30,
586 R31
587 );
588
589 // 32 bit registers that can only be read i.e. these registers can
590 // only be src of all instructions.
591 reg_class bits32_reg_ro(
592 /*R0*/ // R0
593 /*R1*/ // SP
594 R2 // TOC
595 R3,
596 R4,
597 R5,
598 R6,
599 R7,
600 R8,
601 R9,
602 R10,
603 R11,
604 R12,
605 /*R13*/ // system thread id
606 R14,
607 R15,
608 /*R16*/ // R16_thread
609 R17,
610 R18,
611 R19,
612 R20,
613 R21,
614 R22,
615 R23,
616 R24,
617 R25,
618 R26,
619 R27,
620 R28,
621 /*R29,*/
622 R30,
623 R31
624 );
625
626 reg_class rscratch1_bits32_reg(R11);
627 reg_class rscratch2_bits32_reg(R12);
628 reg_class rarg1_bits32_reg(R3);
629 reg_class rarg2_bits32_reg(R4);
630 reg_class rarg3_bits32_reg(R5);
631 reg_class rarg4_bits32_reg(R6);
632
633 // ----------------------------
634 // 64 Bit Register Classes
635 // ----------------------------
636 // 64-bit build means 64-bit pointers means hi/lo pairs
637
638 reg_class rscratch1_bits64_reg(R11_H, R11);
639 reg_class rscratch2_bits64_reg(R12_H, R12);
640 reg_class rarg1_bits64_reg(R3_H, R3);
641 reg_class rarg2_bits64_reg(R4_H, R4);
642 reg_class rarg3_bits64_reg(R5_H, R5);
643 reg_class rarg4_bits64_reg(R6_H, R6);
644 // Thread register, 'written' by tlsLoadP, see there.
645 reg_class thread_bits64_reg(R16_H, R16);
646
647 reg_class r19_bits64_reg(R19_H, R19);
648
649 // 64 bit registers that can be read and written i.e. these registers
650 // can be dest (or src) of normal instructions.
651 reg_class bits64_reg_rw(
652 /*R0_H, R0*/ // R0
653 /*R1_H, R1*/ // SP
654 R2_H, R2, // TOC
655 R3_H, R3,
656 R4_H, R4,
657 R5_H, R5,
658 R6_H, R6,
659 R7_H, R7,
660 R8_H, R8,
661 R9_H, R9,
662 R10_H, R10,
663 R11_H, R11,
664 R12_H, R12,
665 /*R13_H, R13*/ // system thread id
666 R14_H, R14,
667 R15_H, R15,
668 /*R16_H, R16*/ // R16_thread
669 R17_H, R17,
670 R18_H, R18,
671 R19_H, R19,
672 R20_H, R20,
673 R21_H, R21,
674 R22_H, R22,
675 R23_H, R23,
676 R24_H, R24,
677 R25_H, R25,
678 R26_H, R26,
679 R27_H, R27,
680 R28_H, R28,
681 /*R29_H, R29,*/
682 R30_H, R30,
683 R31_H, R31
684 );
685
686 // 64 bit registers used excluding r2, r11 and r12
687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses
688 // r2, r11 and r12 internally.
689 reg_class bits64_reg_leaf_call(
690 /*R0_H, R0*/ // R0
691 /*R1_H, R1*/ // SP
692 /*R2_H, R2*/ // TOC
693 R3_H, R3,
694 R4_H, R4,
695 R5_H, R5,
696 R6_H, R6,
697 R7_H, R7,
698 R8_H, R8,
699 R9_H, R9,
700 R10_H, R10,
701 /*R11_H, R11*/
702 /*R12_H, R12*/
703 /*R13_H, R13*/ // system thread id
704 R14_H, R14,
705 R15_H, R15,
706 /*R16_H, R16*/ // R16_thread
707 R17_H, R17,
708 R18_H, R18,
709 R19_H, R19,
710 R20_H, R20,
711 R21_H, R21,
712 R22_H, R22,
713 R23_H, R23,
714 R24_H, R24,
715 R25_H, R25,
716 R26_H, R26,
717 R27_H, R27,
718 R28_H, R28,
719 /*R29_H, R29,*/
720 R30_H, R30,
721 R31_H, R31
722 );
723
724 // Used to hold the TOC to avoid collisions with expanded DynamicCall
725 // which uses r19 as inline cache internally and expanded LeafCall which uses
726 // r2, r11 and r12 internally.
727 reg_class bits64_constant_table_base(
728 /*R0_H, R0*/ // R0
729 /*R1_H, R1*/ // SP
730 /*R2_H, R2*/ // TOC
731 R3_H, R3,
732 R4_H, R4,
733 R5_H, R5,
734 R6_H, R6,
735 R7_H, R7,
736 R8_H, R8,
737 R9_H, R9,
738 R10_H, R10,
739 /*R11_H, R11*/
740 /*R12_H, R12*/
741 /*R13_H, R13*/ // system thread id
742 R14_H, R14,
743 R15_H, R15,
744 /*R16_H, R16*/ // R16_thread
745 R17_H, R17,
746 R18_H, R18,
747 /*R19_H, R19*/
748 R20_H, R20,
749 R21_H, R21,
750 R22_H, R22,
751 R23_H, R23,
752 R24_H, R24,
753 R25_H, R25,
754 R26_H, R26,
755 R27_H, R27,
756 R28_H, R28,
757 /*R29_H, R29,*/
758 R30_H, R30,
759 R31_H, R31
760 );
761
762 // 64 bit registers that can only be read i.e. these registers can
763 // only be src of all instructions.
764 reg_class bits64_reg_ro(
765 /*R0_H, R0*/ // R0
766 R1_H, R1,
767 R2_H, R2, // TOC
768 R3_H, R3,
769 R4_H, R4,
770 R5_H, R5,
771 R6_H, R6,
772 R7_H, R7,
773 R8_H, R8,
774 R9_H, R9,
775 R10_H, R10,
776 R11_H, R11,
777 R12_H, R12,
778 /*R13_H, R13*/ // system thread id
779 R14_H, R14,
780 R15_H, R15,
781 R16_H, R16, // R16_thread
782 R17_H, R17,
783 R18_H, R18,
784 R19_H, R19,
785 R20_H, R20,
786 R21_H, R21,
787 R22_H, R22,
788 R23_H, R23,
789 R24_H, R24,
790 R25_H, R25,
791 R26_H, R26,
792 R27_H, R27,
793 R28_H, R28,
794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!!
795 R30_H, R30,
796 R31_H, R31
797 );
798
799
800 // ----------------------------
801 // Special Class for Condition Code Flags Register
802
803 reg_class int_flags(
804 /*CCR0*/ // scratch
805 /*CCR1*/ // scratch
806 /*CCR2*/ // nv!
807 /*CCR3*/ // nv!
808 /*CCR4*/ // nv!
809 CCR5,
810 CCR6,
811 CCR7
812 );
813
814 reg_class int_flags_ro(
815 CCR0,
816 CCR1,
817 CCR2,
818 CCR3,
819 CCR4,
820 CCR5,
821 CCR6,
822 CCR7
823 );
824
825 reg_class int_flags_CR0(CCR0);
826 reg_class int_flags_CR1(CCR1);
827 reg_class int_flags_CR6(CCR6);
828 reg_class ctr_reg(SR_CTR);
829
830 // ----------------------------
831 // Float Register Classes
832 // ----------------------------
833
834 reg_class flt_reg(
835 F0,
836 F1,
837 F2,
838 F3,
839 F4,
840 F5,
841 F6,
842 F7,
843 F8,
844 F9,
845 F10,
846 F11,
847 F12,
848 F13,
849 F14, // nv!
850 F15, // nv!
851 F16, // nv!
852 F17, // nv!
853 F18, // nv!
854 F19, // nv!
855 F20, // nv!
856 F21, // nv!
857 F22, // nv!
858 F23, // nv!
859 F24, // nv!
860 F25, // nv!
861 F26, // nv!
862 F27, // nv!
863 F28, // nv!
864 F29, // nv!
865 F30, // nv!
866 F31 // nv!
867 );
868
869 // Double precision float registers have virtual `high halves' that
870 // are needed by the allocator.
871 reg_class dbl_reg(
872 F0, F0_H,
873 F1, F1_H,
874 F2, F2_H,
875 F3, F3_H,
876 F4, F4_H,
877 F5, F5_H,
878 F6, F6_H,
879 F7, F7_H,
880 F8, F8_H,
881 F9, F9_H,
882 F10, F10_H,
883 F11, F11_H,
884 F12, F12_H,
885 F13, F13_H,
886 F14, F14_H, // nv!
887 F15, F15_H, // nv!
888 F16, F16_H, // nv!
889 F17, F17_H, // nv!
890 F18, F18_H, // nv!
891 F19, F19_H, // nv!
892 F20, F20_H, // nv!
893 F21, F21_H, // nv!
894 F22, F22_H, // nv!
895 F23, F23_H, // nv!
896 F24, F24_H, // nv!
897 F25, F25_H, // nv!
898 F26, F26_H, // nv!
899 F27, F27_H, // nv!
900 F28, F28_H, // nv!
901 F29, F29_H, // nv!
902 F30, F30_H, // nv!
903 F31, F31_H // nv!
904 );
905
906 // ----------------------------
907 // Vector-Scalar Register Class
908 // ----------------------------
909
910 reg_class vs_reg(
911 // Attention: Only these ones are saved & restored at safepoint by RegisterSaver.
912 VSR32,
913 VSR33,
914 VSR34,
915 VSR35,
916 VSR36,
917 VSR37,
918 VSR38,
919 VSR39,
920 VSR40,
921 VSR41,
922 VSR42,
923 VSR43,
924 VSR44,
925 VSR45,
926 VSR46,
927 VSR47,
928 VSR48,
929 VSR49,
930 VSR50,
931 VSR51
932 // VSR52-VSR63 // nv!
933 );
934
935 %}
936
937 //----------DEFINITION BLOCK---------------------------------------------------
938 // Define name --> value mappings to inform the ADLC of an integer valued name
939 // Current support includes integer values in the range [0, 0x7FFFFFFF]
940 // Format:
941 // int_def <name> ( <int_value>, <expression>);
942 // Generated Code in ad_<arch>.hpp
943 // #define <name> (<expression>)
944 // // value == <int_value>
945 // Generated code in ad_<arch>.cpp adlc_verification()
946 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
947 //
948 definitions %{
949 // The default cost (of an ALU instruction).
950 int_def DEFAULT_COST_LOW ( 30, 30);
951 int_def DEFAULT_COST ( 100, 100);
952 int_def HUGE_COST (1000000, 1000000);
953
954 // Memory refs
955 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2);
956 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3);
957
958 // Branches are even more expensive.
959 int_def BRANCH_COST ( 900, DEFAULT_COST * 9);
960 int_def CALL_COST ( 1300, DEFAULT_COST * 13);
961 %}
962
963
964 //----------SOURCE BLOCK-------------------------------------------------------
965 // This is a block of C++ code which provides values, functions, and
966 // definitions necessary in the rest of the architecture description.
967 source_hpp %{
968 // Header information of the source block.
969 // Method declarations/definitions which are used outside
970 // the ad-scope can conveniently be defined here.
971 //
972 // To keep related declarations/definitions/uses close together,
973 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
974
975 #include "opto/convertnode.hpp"
976
977 // Returns true if Node n is followed by a MemBar node that
978 // will do an acquire. If so, this node must not do the acquire
979 // operation.
980 bool followed_by_acquire(const Node *n);
981 %}
982
983 source %{
984
985 #include "opto/c2_CodeStubs.hpp"
986 #include "oops/klass.inline.hpp"
987
988 void PhaseOutput::pd_perform_mach_node_analysis() {
989 }
990
991 int MachNode::pd_alignment_required() const {
992 return 1;
993 }
994
995 int MachNode::compute_padding(int current_offset) const {
996 return 0;
997 }
998
999 // Should the matcher clone input 'm' of node 'n'?
1000 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
1001 return false;
1002 }
1003
1004 // Should the Matcher clone shifts on addressing modes, expecting them
1005 // to be subsumed into complex addressing expressions or compute them
1006 // into registers?
1007 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
1008 return clone_base_plus_offset_address(m, mstack, address_visited);
1009 }
1010
1011 // Optimize load-acquire.
1012 //
1013 // Check if acquire is unnecessary due to following operation that does
1014 // acquire anyways.
1015 // Walk the pattern:
1016 //
1017 // n: Load.acq
1018 // |
1019 // MemBarAcquire
1020 // | |
1021 // Proj(ctrl) Proj(mem)
1022 // | |
1023 // MemBarRelease/Volatile
1024 //
1025 bool followed_by_acquire(const Node *load) {
1026 assert(load->is_Load(), "So far implemented only for loads.");
1027
1028 // Find MemBarAcquire.
1029 const Node *mba = NULL;
1030 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) {
1031 const Node *out = load->fast_out(i);
1032 if (out->Opcode() == Op_MemBarAcquire) {
1033 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge.
1034 mba = out;
1035 break;
1036 }
1037 }
1038 if (!mba) return false;
1039
1040 // Find following MemBar node.
1041 //
1042 // The following node must be reachable by control AND memory
1043 // edge to assure no other operations are in between the two nodes.
1044 //
1045 // So first get the Proj node, mem_proj, to use it to iterate forward.
1046 Node *mem_proj = NULL;
1047 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) {
1048 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found.
1049 assert(mem_proj->is_Proj(), "only projections here");
1050 ProjNode *proj = mem_proj->as_Proj();
1051 if (proj->_con == TypeFunc::Memory &&
1052 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only
1053 break;
1054 }
1055 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken");
1056
1057 // Search MemBar behind Proj. If there are other memory operations
1058 // behind the Proj we lost.
1059 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) {
1060 Node *x = mem_proj->fast_out(j);
1061 // Proj might have an edge to a store or load node which precedes the membar.
1062 if (x->is_Mem()) return false;
1063
1064 // On PPC64 release and volatile are implemented by an instruction
1065 // that also has acquire semantics. I.e. there is no need for an
1066 // acquire before these.
1067 int xop = x->Opcode();
1068 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) {
1069 // Make sure we're not missing Call/Phi/MergeMem by checking
1070 // control edges. The control edge must directly lead back
1071 // to the MemBarAcquire
1072 Node *ctrl_proj = x->in(0);
1073 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) {
1074 return true;
1075 }
1076 }
1077 }
1078
1079 return false;
1080 }
1081
1082 #define __ _masm.
1083
1084 // Tertiary op of a LoadP or StoreP encoding.
1085 #define REGP_OP true
1086
1087 // ****************************************************************************
1088
1089 // REQUIRED FUNCTIONALITY
1090
1091 // !!!!! Special hack to get all type of calls to specify the byte offset
1092 // from the start of the call to the point where the return address
1093 // will point.
1094
1095 // PPC port: Removed use of lazy constant construct.
1096
1097 int MachCallStaticJavaNode::ret_addr_offset() {
1098 // It's only a single branch-and-link instruction.
1099 return 4;
1100 }
1101
1102 int MachCallDynamicJavaNode::ret_addr_offset() {
1103 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use
1104 // postalloc expanded calls if we use inline caches and do not update method data.
1105 if (UseInlineCaches) return 4;
1106
1107 int vtable_index = this->_vtable_index;
1108 if (vtable_index < 0) {
1109 // Must be invalid_vtable_index, not nonvirtual_vtable_index.
1110 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value");
1111 return 12;
1112 } else {
1113 return 24 + MacroAssembler::instr_size_for_decode_klass_not_null();
1114 }
1115 }
1116
1117 int MachCallRuntimeNode::ret_addr_offset() {
1118 if (rule() == CallRuntimeDirect_rule) {
1119 // CallRuntimeDirectNode uses call_c.
1120 #if defined(ABI_ELFv2)
1121 return 28;
1122 #else
1123 return 40;
1124 #endif
1125 }
1126 assert(rule() == CallLeafDirect_rule, "unexpected node with rule %u", rule());
1127 // CallLeafDirectNode uses bl.
1128 return 4;
1129 }
1130
1131 int MachCallNativeNode::ret_addr_offset() {
1132 Unimplemented();
1133 return -1;
1134 }
1135
1136 //=============================================================================
1137
1138 // condition code conversions
1139
1140 static int cc_to_boint(int cc) {
1141 return Assembler::bcondCRbiIs0 | (cc & 8);
1142 }
1143
1144 static int cc_to_inverse_boint(int cc) {
1145 return Assembler::bcondCRbiIs0 | (8-(cc & 8));
1146 }
1147
1148 static int cc_to_biint(int cc, int flags_reg) {
1149 return (flags_reg << 2) | (cc & 3);
1150 }
1151
1152 //=============================================================================
1153
1154 // Compute padding required for nodes which need alignment. The padding
1155 // is the number of bytes (not instructions) which will be inserted before
1156 // the instruction. The padding must match the size of a NOP instruction.
1157
1158 // Add nop if a prefixed (two-word) instruction is going to cross a 64-byte boundary.
1159 // (See Section 1.6 of Power ISA Version 3.1)
1160 static int compute_prefix_padding(int current_offset) {
1161 assert(PowerArchitecturePPC64 >= 10 && (CodeEntryAlignment & 63) == 0,
1162 "Code buffer must be aligned to a multiple of 64 bytes");
1163 if (is_aligned(current_offset + BytesPerInstWord, 64)) {
1164 return BytesPerInstWord;
1165 }
1166 return 0;
1167 }
1168
1169 int loadConI32Node::compute_padding(int current_offset) const {
1170 return compute_prefix_padding(current_offset);
1171 }
1172
1173 int loadConL34Node::compute_padding(int current_offset) const {
1174 return compute_prefix_padding(current_offset);
1175 }
1176
1177 int addI_reg_imm32Node::compute_padding(int current_offset) const {
1178 return compute_prefix_padding(current_offset);
1179 }
1180
1181 int addL_reg_imm34Node::compute_padding(int current_offset) const {
1182 return compute_prefix_padding(current_offset);
1183 }
1184
1185 int addP_reg_imm34Node::compute_padding(int current_offset) const {
1186 return compute_prefix_padding(current_offset);
1187 }
1188
1189 int cmprb_Whitespace_reg_reg_prefixedNode::compute_padding(int current_offset) const {
1190 return compute_prefix_padding(current_offset);
1191 }
1192
1193
1194 //=============================================================================
1195
1196 // Emit an interrupt that is caught by the debugger (for debugging compiler).
1197 void emit_break(CodeBuffer &cbuf) {
1198 C2_MacroAssembler _masm(&cbuf);
1199 __ illtrap();
1200 }
1201
1202 #ifndef PRODUCT
1203 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1204 st->print("BREAKPOINT");
1205 }
1206 #endif
1207
1208 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1209 emit_break(cbuf);
1210 }
1211
1212 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1213 return MachNode::size(ra_);
1214 }
1215
1216 //=============================================================================
1217
1218 void emit_nop(CodeBuffer &cbuf) {
1219 C2_MacroAssembler _masm(&cbuf);
1220 __ nop();
1221 }
1222
1223 static inline void emit_long(CodeBuffer &cbuf, int value) {
1224 *((int*)(cbuf.insts_end())) = value;
1225 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord);
1226 }
1227
1228 //=============================================================================
1229
1230 %} // interrupt source
1231
1232 source_hpp %{ // Header information of the source block.
1233
1234 //--------------------------------------------------------------
1235 //---< Used for optimization in Compile::Shorten_branches >---
1236 //--------------------------------------------------------------
1237
1238 class C2_MacroAssembler;
1239
1240 class CallStubImpl {
1241
1242 public:
1243
1244 // Emit call stub, compiled java to interpreter.
1245 static void emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset);
1246
1247 // Size of call trampoline stub.
1248 // This doesn't need to be accurate to the byte, but it
1249 // must be larger than or equal to the real size of the stub.
1250 static uint size_call_trampoline() {
1251 return MacroAssembler::trampoline_stub_size;
1252 }
1253
1254 // number of relocations needed by a call trampoline stub
1255 static uint reloc_call_trampoline() {
1256 return 5;
1257 }
1258
1259 };
1260
1261 %} // end source_hpp
1262
1263 source %{
1264
1265 // Emit a trampoline stub for a call to a target which is too far away.
1266 //
1267 // code sequences:
1268 //
1269 // call-site:
1270 // branch-and-link to <destination> or <trampoline stub>
1271 //
1272 // Related trampoline stub for this call-site in the stub section:
1273 // load the call target from the constant pool
1274 // branch via CTR (LR/link still points to the call-site above)
1275
1276 void CallStubImpl::emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) {
1277 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset);
1278 if (stub == NULL) {
1279 ciEnv::current()->record_out_of_memory_failure();
1280 }
1281 }
1282
1283 //=============================================================================
1284
1285 // Emit an inline branch-and-link call and a related trampoline stub.
1286 //
1287 // code sequences:
1288 //
1289 // call-site:
1290 // branch-and-link to <destination> or <trampoline stub>
1291 //
1292 // Related trampoline stub for this call-site in the stub section:
1293 // load the call target from the constant pool
1294 // branch via CTR (LR/link still points to the call-site above)
1295 //
1296
1297 typedef struct {
1298 int insts_call_instruction_offset;
1299 int ret_addr_offset;
1300 } EmitCallOffsets;
1301
1302 // Emit a branch-and-link instruction that branches to a trampoline.
1303 // - Remember the offset of the branch-and-link instruction.
1304 // - Add a relocation at the branch-and-link instruction.
1305 // - Emit a branch-and-link.
1306 // - Remember the return pc offset.
1307 EmitCallOffsets emit_call_with_trampoline_stub(C2_MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) {
1308 EmitCallOffsets offsets = { -1, -1 };
1309 const int start_offset = __ offset();
1310 offsets.insts_call_instruction_offset = __ offset();
1311
1312 // No entry point given, use the current pc.
1313 if (entry_point == NULL) entry_point = __ pc();
1314
1315 // Put the entry point as a constant into the constant pool.
1316 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
1317 if (entry_point_toc_addr == NULL) {
1318 ciEnv::current()->record_out_of_memory_failure();
1319 return offsets;
1320 }
1321 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
1322
1323 // Emit the trampoline stub which will be related to the branch-and-link below.
1324 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
1325 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
1326 __ relocate(rtype);
1327
1328 // Note: At this point we do not have the address of the trampoline
1329 // stub, and the entry point might be too far away for bl, so __ pc()
1330 // serves as dummy and the bl will be patched later.
1331 __ bl((address) __ pc());
1332
1333 offsets.ret_addr_offset = __ offset() - start_offset;
1334
1335 return offsets;
1336 }
1337
1338 //=============================================================================
1339
1340 // Factory for creating loadConL* nodes for large/small constant pool.
1341
1342 static inline jlong replicate_immF(float con) {
1343 // Replicate float con 2 times and pack into vector.
1344 int val = *((int*)&con);
1345 jlong lval = val;
1346 lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1347 return lval;
1348 }
1349
1350 //=============================================================================
1351
1352 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1353 int ConstantTable::calculate_table_base_offset() const {
1354 return 0; // absolute addressing, no offset
1355 }
1356
1357 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1358 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1359 iRegPdstOper *op_dst = new iRegPdstOper();
1360 MachNode *m1 = new loadToc_hiNode();
1361 MachNode *m2 = new loadToc_loNode();
1362
1363 m1->add_req(NULL);
1364 m2->add_req(NULL, m1);
1365 m1->_opnds[0] = op_dst;
1366 m2->_opnds[0] = op_dst;
1367 m2->_opnds[1] = op_dst;
1368 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1369 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1370 nodes->push(m1);
1371 nodes->push(m2);
1372 }
1373
1374 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1375 // Is postalloc expanded.
1376 ShouldNotReachHere();
1377 }
1378
1379 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1380 return 0;
1381 }
1382
1383 #ifndef PRODUCT
1384 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1385 st->print("-- \t// MachConstantBaseNode (empty encoding)");
1386 }
1387 #endif
1388
1389 //=============================================================================
1390
1391 #ifndef PRODUCT
1392 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1393 Compile* C = ra_->C;
1394 const long framesize = C->output()->frame_slots() << LogBytesPerInt;
1395
1396 st->print("PROLOG\n\t");
1397 if (C->output()->need_stack_bang(framesize)) {
1398 st->print("stack_overflow_check\n\t");
1399 }
1400
1401 if (!false /* TODO: PPC port C->is_frameless_method()*/) {
1402 st->print("save return pc\n\t");
1403 st->print("push frame %ld\n\t", -framesize);
1404 }
1405
1406 if (C->stub_function() == NULL) {
1407 st->print("nmethod entry barrier\n\t");
1408 }
1409 }
1410 #endif
1411
1412 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1413 Compile* C = ra_->C;
1414 C2_MacroAssembler _masm(&cbuf);
1415
1416 const long framesize = C->output()->frame_size_in_bytes();
1417 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment");
1418
1419 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1420
1421 const Register return_pc = R20; // Must match return_addr() in frame section.
1422 const Register callers_sp = R21;
1423 const Register push_frame_temp = R22;
1424 const Register toc_temp = R23;
1425 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp);
1426
1427 if (method_is_frameless) {
1428 // Add nop at beginning of all frameless methods to prevent any
1429 // oop instructions from getting overwritten by make_not_entrant
1430 // (patching attempt would fail).
1431 __ nop();
1432 } else {
1433 // Get return pc.
1434 __ mflr(return_pc);
1435 }
1436
1437 if (C->clinit_barrier_on_entry()) {
1438 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
1439
1440 Label L_skip_barrier;
1441 Register klass = toc_temp;
1442
1443 // Notify OOP recorder (don't need the relocation)
1444 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding());
1445 __ load_const_optimized(klass, md.value(), R0);
1446 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/);
1447
1448 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0);
1449 __ mtctr(klass);
1450 __ bctr();
1451
1452 __ bind(L_skip_barrier);
1453 }
1454
1455 // Calls to C2R adapters often do not accept exceptional returns.
1456 // We require that their callers must bang for them. But be
1457 // careful, because some VM calls (such as call site linkage) can
1458 // use several kilobytes of stack. But the stack safety zone should
1459 // account for that. See bugs 4446381, 4468289, 4497237.
1460
1461 int bangsize = C->output()->bang_size_in_bytes();
1462 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect");
1463 if (C->output()->need_stack_bang(bangsize)) {
1464 // Unfortunately we cannot use the function provided in
1465 // assembler.cpp as we have to emulate the pipes. So I had to
1466 // insert the code of generate_stack_overflow_check(), see
1467 // assembler.cpp for some illuminative comments.
1468 const int page_size = os::vm_page_size();
1469 int bang_end = StackOverflow::stack_shadow_zone_size();
1470
1471 // This is how far the previous frame's stack banging extended.
1472 const int bang_end_safe = bang_end;
1473
1474 if (bangsize > page_size) {
1475 bang_end += bangsize;
1476 }
1477
1478 int bang_offset = bang_end_safe;
1479
1480 while (bang_offset <= bang_end) {
1481 // Need at least one stack bang at end of shadow zone.
1482
1483 // Again I had to copy code, this time from assembler_ppc.cpp,
1484 // bang_stack_with_offset - see there for comments.
1485
1486 // Stack grows down, caller passes positive offset.
1487 assert(bang_offset > 0, "must bang with positive offset");
1488
1489 long stdoffset = -bang_offset;
1490
1491 if (Assembler::is_simm(stdoffset, 16)) {
1492 // Signed 16 bit offset, a simple std is ok.
1493 if (UseLoadInstructionsForStackBangingPPC64) {
1494 __ ld(R0, (int)(signed short)stdoffset, R1_SP);
1495 } else {
1496 __ std(R0, (int)(signed short)stdoffset, R1_SP);
1497 }
1498 } else if (Assembler::is_simm(stdoffset, 31)) {
1499 // Use largeoffset calculations for addis & ld/std.
1500 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset);
1501 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset);
1502
1503 Register tmp = R11;
1504 __ addis(tmp, R1_SP, hi);
1505 if (UseLoadInstructionsForStackBangingPPC64) {
1506 __ ld(R0, lo, tmp);
1507 } else {
1508 __ std(R0, lo, tmp);
1509 }
1510 } else {
1511 ShouldNotReachHere();
1512 }
1513
1514 bang_offset += page_size;
1515 }
1516 // R11 trashed
1517 } // C->output()->need_stack_bang(framesize)
1518
1519 unsigned int bytes = (unsigned int)framesize;
1520 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
1521 ciMethod *currMethod = C->method();
1522
1523 if (!method_is_frameless) {
1524 // Get callers sp.
1525 __ mr(callers_sp, R1_SP);
1526
1527 // Push method's frame, modifies SP.
1528 assert(Assembler::is_uimm(framesize, 32U), "wrong type");
1529 // The ABI is already accounted for in 'framesize' via the
1530 // 'out_preserve' area.
1531 Register tmp = push_frame_temp;
1532 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp).
1533 if (Assembler::is_simm(-offset, 16)) {
1534 __ stdu(R1_SP, -offset, R1_SP);
1535 } else {
1536 long x = -offset;
1537 // Had to insert load_const(tmp, -offset).
1538 __ lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16)));
1539 __ ori( tmp, tmp, ((x >> 32) & 0x0000ffff));
1540 __ sldi(tmp, tmp, 32);
1541 __ oris(tmp, tmp, (x & 0xffff0000) >> 16);
1542 __ ori( tmp, tmp, (x & 0x0000ffff));
1543
1544 __ stdux(R1_SP, R1_SP, tmp);
1545 }
1546 }
1547 #if 0 // TODO: PPC port
1548 // For testing large constant pools, emit a lot of constants to constant pool.
1549 // "Randomize" const_size.
1550 if (ConstantsALot) {
1551 const int num_consts = const_size();
1552 for (int i = 0; i < num_consts; i++) {
1553 __ long_constant(0xB0B5B00BBABE);
1554 }
1555 }
1556 #endif
1557 if (!method_is_frameless) {
1558 // Save return pc.
1559 __ std(return_pc, _abi0(lr), callers_sp);
1560 }
1561
1562 if (C->stub_function() == NULL) {
1563 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
1564 bs->nmethod_entry_barrier(&_masm, push_frame_temp);
1565 }
1566
1567 C->output()->set_frame_complete(cbuf.insts_size());
1568 }
1569
1570 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1571 // Variable size. determine dynamically.
1572 return MachNode::size(ra_);
1573 }
1574
1575 int MachPrologNode::reloc() const {
1576 // Return number of relocatable values contained in this instruction.
1577 return 1; // 1 reloc entry for load_const(toc).
1578 }
1579
1580 //=============================================================================
1581
1582 #ifndef PRODUCT
1583 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1584 Compile* C = ra_->C;
1585
1586 st->print("EPILOG\n\t");
1587 st->print("restore return pc\n\t");
1588 st->print("pop frame\n\t");
1589
1590 if (do_polling() && C->is_method_compilation()) {
1591 st->print("safepoint poll\n\t");
1592 }
1593 }
1594 #endif
1595
1596 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1597 Compile* C = ra_->C;
1598 C2_MacroAssembler _masm(&cbuf);
1599
1600 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt;
1601 assert(framesize >= 0, "negative frame-size?");
1602
1603 const bool method_needs_polling = do_polling() && C->is_method_compilation();
1604 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1605 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
1606 const Register temp = R12;
1607
1608 if (!method_is_frameless) {
1609 // Restore return pc relative to callers' sp.
1610 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP);
1611 // Move return pc to LR.
1612 __ mtlr(return_pc);
1613 // Pop frame (fixed frame-size).
1614 __ addi(R1_SP, R1_SP, (int)framesize);
1615 }
1616
1617 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1618 __ reserved_stack_check(return_pc);
1619 }
1620
1621 if (method_needs_polling) {
1622 Label dummy_label;
1623 Label* code_stub = &dummy_label;
1624 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) {
1625 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1626 C->output()->add_stub(stub);
1627 code_stub = &stub->entry();
1628 __ relocate(relocInfo::poll_return_type);
1629 }
1630 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */);
1631 }
1632 }
1633
1634 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1635 // Variable size. Determine dynamically.
1636 return MachNode::size(ra_);
1637 }
1638
1639 int MachEpilogNode::reloc() const {
1640 // Return number of relocatable values contained in this instruction.
1641 return 1; // 1 for load_from_polling_page.
1642 }
1643
1644 const Pipeline * MachEpilogNode::pipeline() const {
1645 return MachNode::pipeline_class();
1646 }
1647
1648 // =============================================================================
1649
1650 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or
1651 // rc_stack.
1652 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack };
1653
1654 static enum RC rc_class(OptoReg::Name reg) {
1655 // Return the register class for the given register. The given register
1656 // reg is a <register>_num value, which is an index into the MachRegisterNumbers
1657 // enumeration in adGlobals_ppc.hpp.
1658
1659 if (reg == OptoReg::Bad) return rc_bad;
1660
1661 // We have 64 integer register halves, starting at index 0.
1662 if (reg < 64) return rc_int;
1663
1664 // We have 64 floating-point register halves, starting at index 64.
1665 if (reg < 64+64) return rc_float;
1666
1667 // We have 64 vector-scalar registers, starting at index 128.
1668 if (reg < 64+64+64) return rc_vs;
1669
1670 // Between float regs & stack are the flags regs.
1671 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags");
1672
1673 return rc_stack;
1674 }
1675
1676 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset,
1677 bool do_print, Compile* C, outputStream *st) {
1678
1679 assert(opcode == Assembler::LD_OPCODE ||
1680 opcode == Assembler::STD_OPCODE ||
1681 opcode == Assembler::LWZ_OPCODE ||
1682 opcode == Assembler::STW_OPCODE ||
1683 opcode == Assembler::LFD_OPCODE ||
1684 opcode == Assembler::STFD_OPCODE ||
1685 opcode == Assembler::LFS_OPCODE ||
1686 opcode == Assembler::STFS_OPCODE,
1687 "opcode not supported");
1688
1689 if (cbuf) {
1690 int d =
1691 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ?
1692 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/)
1693 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build.
1694 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP));
1695 }
1696 #ifndef PRODUCT
1697 else if (do_print) {
1698 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy",
1699 op_str,
1700 Matcher::regName[reg],
1701 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/);
1702 }
1703 #endif
1704 return 4; // size
1705 }
1706
1707 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1708 Compile* C = ra_->C;
1709
1710 // Get registers to move.
1711 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1712 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1713 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1714 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1715
1716 enum RC src_hi_rc = rc_class(src_hi);
1717 enum RC src_lo_rc = rc_class(src_lo);
1718 enum RC dst_hi_rc = rc_class(dst_hi);
1719 enum RC dst_lo_rc = rc_class(dst_lo);
1720
1721 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1722 if (src_hi != OptoReg::Bad)
1723 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1724 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1725 "expected aligned-adjacent pairs");
1726 // Generate spill code!
1727 int size = 0;
1728
1729 if (src_lo == dst_lo && src_hi == dst_hi)
1730 return size; // Self copy, no move.
1731
1732 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) {
1733 // Memory->Memory Spill.
1734 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1735 int src_offset = ra_->reg2offset(src_lo);
1736 int dst_offset = ra_->reg2offset(dst_lo);
1737 if (cbuf) {
1738 C2_MacroAssembler _masm(cbuf);
1739 __ ld(R0, src_offset, R1_SP);
1740 __ std(R0, dst_offset, R1_SP);
1741 __ ld(R0, src_offset+8, R1_SP);
1742 __ std(R0, dst_offset+8, R1_SP);
1743 }
1744 size += 16;
1745 }
1746 // VectorSRegister->Memory Spill.
1747 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) {
1748 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]);
1749 int dst_offset = ra_->reg2offset(dst_lo);
1750 if (cbuf) {
1751 C2_MacroAssembler _masm(cbuf);
1752 __ addi(R0, R1_SP, dst_offset);
1753 __ stxvd2x(Rsrc, R0);
1754 }
1755 size += 8;
1756 }
1757 // Memory->VectorSRegister Spill.
1758 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) {
1759 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]);
1760 int src_offset = ra_->reg2offset(src_lo);
1761 if (cbuf) {
1762 C2_MacroAssembler _masm(cbuf);
1763 __ addi(R0, R1_SP, src_offset);
1764 __ lxvd2x(Rdst, R0);
1765 }
1766 size += 8;
1767 }
1768 // VectorSRegister->VectorSRegister.
1769 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) {
1770 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]);
1771 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]);
1772 if (cbuf) {
1773 C2_MacroAssembler _masm(cbuf);
1774 __ xxlor(Rdst, Rsrc, Rsrc);
1775 }
1776 size += 4;
1777 }
1778 else {
1779 ShouldNotReachHere(); // No VSR spill.
1780 }
1781 return size;
1782 }
1783
1784 // --------------------------------------
1785 // Memory->Memory Spill. Use R0 to hold the value.
1786 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1787 int src_offset = ra_->reg2offset(src_lo);
1788 int dst_offset = ra_->reg2offset(dst_lo);
1789 if (src_hi != OptoReg::Bad) {
1790 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack,
1791 "expected same type of move for high parts");
1792 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st);
1793 if (!cbuf && !do_size) st->print("\n\t");
1794 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st);
1795 } else {
1796 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st);
1797 if (!cbuf && !do_size) st->print("\n\t");
1798 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st);
1799 }
1800 return size;
1801 }
1802
1803 // --------------------------------------
1804 // Check for float->int copy; requires a trip through memory.
1805 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1806 Unimplemented();
1807 }
1808
1809 // --------------------------------------
1810 // Check for integer reg-reg copy.
1811 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1812 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1813 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1814 size = (Rsrc != Rdst) ? 4 : 0;
1815
1816 if (cbuf) {
1817 C2_MacroAssembler _masm(cbuf);
1818 if (size) {
1819 __ mr(Rdst, Rsrc);
1820 }
1821 }
1822 #ifndef PRODUCT
1823 else if (!do_size) {
1824 if (size) {
1825 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1826 } else {
1827 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1828 }
1829 }
1830 #endif
1831 return size;
1832 }
1833
1834 // Check for integer store.
1835 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1836 int dst_offset = ra_->reg2offset(dst_lo);
1837 if (src_hi != OptoReg::Bad) {
1838 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack,
1839 "expected same type of move for high parts");
1840 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1841 } else {
1842 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st);
1843 }
1844 return size;
1845 }
1846
1847 // Check for integer load.
1848 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1849 int src_offset = ra_->reg2offset(src_lo);
1850 if (src_hi != OptoReg::Bad) {
1851 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack,
1852 "expected same type of move for high parts");
1853 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1854 } else {
1855 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st);
1856 }
1857 return size;
1858 }
1859
1860 // Check for float reg-reg copy.
1861 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1862 if (cbuf) {
1863 C2_MacroAssembler _masm(cbuf);
1864 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]);
1865 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]);
1866 __ fmr(Rdst, Rsrc);
1867 }
1868 #ifndef PRODUCT
1869 else if (!do_size) {
1870 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1871 }
1872 #endif
1873 return 4;
1874 }
1875
1876 // Check for float store.
1877 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1878 int dst_offset = ra_->reg2offset(dst_lo);
1879 if (src_hi != OptoReg::Bad) {
1880 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack,
1881 "expected same type of move for high parts");
1882 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1883 } else {
1884 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st);
1885 }
1886 return size;
1887 }
1888
1889 // Check for float load.
1890 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1891 int src_offset = ra_->reg2offset(src_lo);
1892 if (src_hi != OptoReg::Bad) {
1893 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack,
1894 "expected same type of move for high parts");
1895 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1896 } else {
1897 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st);
1898 }
1899 return size;
1900 }
1901
1902 // --------------------------------------------------------------------
1903 // Check for hi bits still needing moving. Only happens for misaligned
1904 // arguments to native calls.
1905 if (src_hi == dst_hi)
1906 return size; // Self copy; no move.
1907
1908 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad");
1909 ShouldNotReachHere(); // Unimplemented
1910 return 0;
1911 }
1912
1913 #ifndef PRODUCT
1914 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1915 if (!ra_)
1916 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1917 else
1918 implementation(NULL, ra_, false, st);
1919 }
1920 #endif
1921
1922 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1923 implementation(&cbuf, ra_, false, NULL);
1924 }
1925
1926 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1927 return implementation(NULL, ra_, true, NULL);
1928 }
1929
1930 #ifndef PRODUCT
1931 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1932 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count);
1933 }
1934 #endif
1935
1936 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const {
1937 C2_MacroAssembler _masm(&cbuf);
1938 // _count contains the number of nops needed for padding.
1939 for (int i = 0; i < _count; i++) {
1940 __ nop();
1941 }
1942 }
1943
1944 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
1945 return _count * 4;
1946 }
1947
1948 #ifndef PRODUCT
1949 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1950 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1951 char reg_str[128];
1952 ra_->dump_register(this, reg_str);
1953 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset);
1954 }
1955 #endif
1956
1957 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1958 C2_MacroAssembler _masm(&cbuf);
1959
1960 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1961 int reg = ra_->get_encode(this);
1962
1963 if (Assembler::is_simm(offset, 16)) {
1964 __ addi(as_Register(reg), R1, offset);
1965 } else {
1966 ShouldNotReachHere();
1967 }
1968 }
1969
1970 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1971 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1972 return 4;
1973 }
1974
1975 #ifndef PRODUCT
1976 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1977 st->print_cr("---- MachUEPNode ----");
1978 st->print_cr("...");
1979 }
1980 #endif
1981
1982 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1983 // This is the unverified entry point.
1984 C2_MacroAssembler _masm(&cbuf);
1985
1986 // Inline_cache contains a klass.
1987 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode());
1988 Register receiver_klass = R12_scratch2; // tmp
1989
1990 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1);
1991 assert(R11_scratch1 == R11, "need prologue scratch register");
1992
1993 // Check for NULL argument if we don't have implicit null checks.
1994 if (!ImplicitNullChecks || !os::zero_page_read_protected()) {
1995 if (TrapBasedNullChecks) {
1996 __ trap_null_check(R3_ARG1);
1997 } else {
1998 Label valid;
1999 __ cmpdi(CCR0, R3_ARG1, 0);
2000 __ bne_predict_taken(CCR0, valid);
2001 // We have a null argument, branch to ic_miss_stub.
2002 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(),
2003 relocInfo::runtime_call_type);
2004 __ bind(valid);
2005 }
2006 }
2007 // Assume argument is not NULL, load klass from receiver.
2008 __ load_klass(receiver_klass, R3_ARG1);
2009
2010 if (TrapBasedICMissChecks) {
2011 __ trap_ic_miss_check(receiver_klass, ic_klass);
2012 } else {
2013 Label valid;
2014 __ cmpd(CCR0, receiver_klass, ic_klass);
2015 __ beq_predict_taken(CCR0, valid);
2016 // We have an unexpected klass, branch to ic_miss_stub.
2017 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(),
2018 relocInfo::runtime_call_type);
2019 __ bind(valid);
2020 }
2021
2022 // Argument is valid and klass is as expected, continue.
2023 }
2024
2025 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
2026 // Variable size. Determine dynamically.
2027 return MachNode::size(ra_);
2028 }
2029
2030 //=============================================================================
2031
2032 %} // interrupt source
2033
2034 source_hpp %{ // Header information of the source block.
2035
2036 class HandlerImpl {
2037
2038 public:
2039
2040 static int emit_exception_handler(CodeBuffer &cbuf);
2041 static int emit_deopt_handler(CodeBuffer& cbuf);
2042
2043 static uint size_exception_handler() {
2044 // The exception_handler is a b64_patchable.
2045 return MacroAssembler::b64_patchable_size;
2046 }
2047
2048 static uint size_deopt_handler() {
2049 // The deopt_handler is a bl64_patchable.
2050 return MacroAssembler::bl64_patchable_size;
2051 }
2052
2053 };
2054
2055 class Node::PD {
2056 public:
2057 enum NodeFlags {
2058 _last_flag = Node::_last_flag
2059 };
2060 };
2061
2062 %} // end source_hpp
2063
2064 source %{
2065
2066 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) {
2067 C2_MacroAssembler _masm(&cbuf);
2068
2069 address base = __ start_a_stub(size_exception_handler());
2070 if (base == NULL) return 0; // CodeBuffer::expand failed
2071
2072 int offset = __ offset();
2073 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(),
2074 relocInfo::runtime_call_type);
2075 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size");
2076 __ end_a_stub();
2077
2078 return offset;
2079 }
2080
2081 // The deopt_handler is like the exception handler, but it calls to
2082 // the deoptimization blob instead of jumping to the exception blob.
2083 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
2084 C2_MacroAssembler _masm(&cbuf);
2085
2086 address base = __ start_a_stub(size_deopt_handler());
2087 if (base == NULL) return 0; // CodeBuffer::expand failed
2088
2089 int offset = __ offset();
2090 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
2091 relocInfo::runtime_call_type);
2092 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
2093 __ end_a_stub();
2094
2095 return offset;
2096 }
2097
2098 //=============================================================================
2099
2100 // Use a frame slots bias for frameless methods if accessing the stack.
2101 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) {
2102 if (as_Register(reg_enc) == R1_SP) {
2103 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes();
2104 }
2105 return 0;
2106 }
2107
2108 const bool Matcher::match_rule_supported(int opcode) {
2109 if (!has_match_rule(opcode)) {
2110 return false; // no match rule present
2111 }
2112
2113 switch (opcode) {
2114 case Op_SqrtD:
2115 return VM_Version::has_fsqrt();
2116 case Op_RoundDoubleMode:
2117 return VM_Version::has_vsx();
2118 case Op_CountLeadingZerosI:
2119 case Op_CountLeadingZerosL:
2120 return UseCountLeadingZerosInstructionsPPC64;
2121 case Op_CountTrailingZerosI:
2122 case Op_CountTrailingZerosL:
2123 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64);
2124 case Op_PopCountI:
2125 case Op_PopCountL:
2126 return (UsePopCountInstruction && VM_Version::has_popcntw());
2127
2128 case Op_AddVB:
2129 case Op_AddVS:
2130 case Op_AddVI:
2131 case Op_AddVF:
2132 case Op_AddVD:
2133 case Op_SubVB:
2134 case Op_SubVS:
2135 case Op_SubVI:
2136 case Op_SubVF:
2137 case Op_SubVD:
2138 case Op_MulVS:
2139 case Op_MulVF:
2140 case Op_MulVD:
2141 case Op_DivVF:
2142 case Op_DivVD:
2143 case Op_AbsVF:
2144 case Op_AbsVD:
2145 case Op_NegVF:
2146 case Op_NegVD:
2147 case Op_SqrtVF:
2148 case Op_SqrtVD:
2149 case Op_AddVL:
2150 case Op_SubVL:
2151 case Op_MulVI:
2152 case Op_RoundDoubleModeV:
2153 return SuperwordUseVSX;
2154 case Op_PopCountVI:
2155 return (SuperwordUseVSX && UsePopCountInstruction);
2156 case Op_FmaVF:
2157 case Op_FmaVD:
2158 return (SuperwordUseVSX && UseFMA);
2159
2160 case Op_Digit:
2161 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit);
2162 case Op_LowerCase:
2163 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase);
2164 case Op_UpperCase:
2165 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase);
2166 case Op_Whitespace:
2167 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace);
2168
2169 case Op_CacheWB:
2170 case Op_CacheWBPreSync:
2171 case Op_CacheWBPostSync:
2172 return VM_Version::supports_data_cache_line_flush();
2173 }
2174
2175 return true; // Per default match rules are supported.
2176 }
2177
2178 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
2179 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
2180 return false;
2181 }
2182 return true; // Per default match rules are supported.
2183 }
2184
2185 const RegMask* Matcher::predicate_reg_mask(void) {
2186 return NULL;
2187 }
2188
2189 const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) {
2190 return NULL;
2191 }
2192
2193 // Vector calling convention not yet implemented.
2194 const bool Matcher::supports_vector_calling_convention(void) {
2195 return false;
2196 }
2197
2198 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2199 Unimplemented();
2200 return OptoRegPair(0, 0);
2201 }
2202
2203 const int Matcher::float_pressure(int default_pressure_threshold) {
2204 return default_pressure_threshold;
2205 }
2206
2207 // Vector width in bytes.
2208 const int Matcher::vector_width_in_bytes(BasicType bt) {
2209 if (SuperwordUseVSX) {
2210 assert(MaxVectorSize == 16, "");
2211 return 16;
2212 } else {
2213 assert(MaxVectorSize == 8, "");
2214 return 8;
2215 }
2216 }
2217
2218 // Vector ideal reg.
2219 const uint Matcher::vector_ideal_reg(int size) {
2220 if (SuperwordUseVSX) {
2221 assert(MaxVectorSize == 16 && size == 16, "");
2222 return Op_VecX;
2223 } else {
2224 assert(MaxVectorSize == 8 && size == 8, "");
2225 return Op_RegL;
2226 }
2227 }
2228
2229 // Limits on vector size (number of elements) loaded into vector.
2230 const int Matcher::max_vector_size(const BasicType bt) {
2231 assert(is_java_primitive(bt), "only primitive type vectors");
2232 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2233 }
2234
2235 const int Matcher::min_vector_size(const BasicType bt) {
2236 return max_vector_size(bt); // Same as max.
2237 }
2238
2239 const int Matcher::scalable_vector_reg_size(const BasicType bt) {
2240 return -1;
2241 }
2242
2243 // RETURNS: whether this branch offset is short enough that a short
2244 // branch can be used.
2245 //
2246 // If the platform does not provide any short branch variants, then
2247 // this method should return `false' for offset 0.
2248 //
2249 // `Compile::Fill_buffer' will decide on basis of this information
2250 // whether to do the pass `Compile::Shorten_branches' at all.
2251 //
2252 // And `Compile::Shorten_branches' will decide on basis of this
2253 // information whether to replace particular branch sites by short
2254 // ones.
2255 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2256 // Is the offset within the range of a ppc64 pc relative branch?
2257 bool b;
2258
2259 const int safety_zone = 3 * BytesPerInstWord;
2260 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2261 29 - 16 + 1 + 2);
2262 return b;
2263 }
2264
2265 /* TODO: PPC port
2266 // Make a new machine dependent decode node (with its operands).
2267 MachTypeNode *Matcher::make_decode_node() {
2268 assert(CompressedOops::base() == NULL && CompressedOops::shift() == 0,
2269 "This method is only implemented for unscaled cOops mode so far");
2270 MachTypeNode *decode = new decodeN_unscaledNode();
2271 decode->set_opnd_array(0, new iRegPdstOper());
2272 decode->set_opnd_array(1, new iRegNsrcOper());
2273 return decode;
2274 }
2275 */
2276
2277 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
2278 ShouldNotReachHere(); // generic vector operands not supported
2279 return NULL;
2280 }
2281
2282 bool Matcher::is_generic_reg2reg_move(MachNode* m) {
2283 ShouldNotReachHere(); // generic vector operands not supported
2284 return false;
2285 }
2286
2287 bool Matcher::is_generic_vector(MachOper* opnd) {
2288 ShouldNotReachHere(); // generic vector operands not supported
2289 return false;
2290 }
2291
2292 // Constants for c2c and c calling conventions.
2293
2294 const MachRegisterNumbers iarg_reg[8] = {
2295 R3_num, R4_num, R5_num, R6_num,
2296 R7_num, R8_num, R9_num, R10_num
2297 };
2298
2299 const MachRegisterNumbers farg_reg[13] = {
2300 F1_num, F2_num, F3_num, F4_num,
2301 F5_num, F6_num, F7_num, F8_num,
2302 F9_num, F10_num, F11_num, F12_num,
2303 F13_num
2304 };
2305
2306 const MachRegisterNumbers vsarg_reg[64] = {
2307 VSR0_num, VSR1_num, VSR2_num, VSR3_num,
2308 VSR4_num, VSR5_num, VSR6_num, VSR7_num,
2309 VSR8_num, VSR9_num, VSR10_num, VSR11_num,
2310 VSR12_num, VSR13_num, VSR14_num, VSR15_num,
2311 VSR16_num, VSR17_num, VSR18_num, VSR19_num,
2312 VSR20_num, VSR21_num, VSR22_num, VSR23_num,
2313 VSR24_num, VSR23_num, VSR24_num, VSR25_num,
2314 VSR28_num, VSR29_num, VSR30_num, VSR31_num,
2315 VSR32_num, VSR33_num, VSR34_num, VSR35_num,
2316 VSR36_num, VSR37_num, VSR38_num, VSR39_num,
2317 VSR40_num, VSR41_num, VSR42_num, VSR43_num,
2318 VSR44_num, VSR45_num, VSR46_num, VSR47_num,
2319 VSR48_num, VSR49_num, VSR50_num, VSR51_num,
2320 VSR52_num, VSR53_num, VSR54_num, VSR55_num,
2321 VSR56_num, VSR57_num, VSR58_num, VSR59_num,
2322 VSR60_num, VSR61_num, VSR62_num, VSR63_num
2323 };
2324
2325 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]);
2326
2327 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]);
2328
2329 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]);
2330
2331 // Return whether or not this register is ever used as an argument. This
2332 // function is used on startup to build the trampoline stubs in generateOptoStub.
2333 // Registers not mentioned will be killed by the VM call in the trampoline, and
2334 // arguments in those registers not be available to the callee.
2335 bool Matcher::can_be_java_arg(int reg) {
2336 // We return true for all registers contained in iarg_reg[] and
2337 // farg_reg[] and their virtual halves.
2338 // We must include the virtual halves in order to get STDs and LDs
2339 // instead of STWs and LWs in the trampoline stubs.
2340
2341 if ( reg == R3_num || reg == R3_H_num
2342 || reg == R4_num || reg == R4_H_num
2343 || reg == R5_num || reg == R5_H_num
2344 || reg == R6_num || reg == R6_H_num
2345 || reg == R7_num || reg == R7_H_num
2346 || reg == R8_num || reg == R8_H_num
2347 || reg == R9_num || reg == R9_H_num
2348 || reg == R10_num || reg == R10_H_num)
2349 return true;
2350
2351 if ( reg == F1_num || reg == F1_H_num
2352 || reg == F2_num || reg == F2_H_num
2353 || reg == F3_num || reg == F3_H_num
2354 || reg == F4_num || reg == F4_H_num
2355 || reg == F5_num || reg == F5_H_num
2356 || reg == F6_num || reg == F6_H_num
2357 || reg == F7_num || reg == F7_H_num
2358 || reg == F8_num || reg == F8_H_num
2359 || reg == F9_num || reg == F9_H_num
2360 || reg == F10_num || reg == F10_H_num
2361 || reg == F11_num || reg == F11_H_num
2362 || reg == F12_num || reg == F12_H_num
2363 || reg == F13_num || reg == F13_H_num)
2364 return true;
2365
2366 return false;
2367 }
2368
2369 bool Matcher::is_spillable_arg(int reg) {
2370 return can_be_java_arg(reg);
2371 }
2372
2373 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
2374 return false;
2375 }
2376
2377 // Register for DIVI projection of divmodI.
2378 RegMask Matcher::divI_proj_mask() {
2379 ShouldNotReachHere();
2380 return RegMask();
2381 }
2382
2383 // Register for MODI projection of divmodI.
2384 RegMask Matcher::modI_proj_mask() {
2385 ShouldNotReachHere();
2386 return RegMask();
2387 }
2388
2389 // Register for DIVL projection of divmodL.
2390 RegMask Matcher::divL_proj_mask() {
2391 ShouldNotReachHere();
2392 return RegMask();
2393 }
2394
2395 // Register for MODL projection of divmodL.
2396 RegMask Matcher::modL_proj_mask() {
2397 ShouldNotReachHere();
2398 return RegMask();
2399 }
2400
2401 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
2402 return RegMask();
2403 }
2404
2405 %}
2406
2407 //----------ENCODING BLOCK-----------------------------------------------------
2408 // This block specifies the encoding classes used by the compiler to output
2409 // byte streams. Encoding classes are parameterized macros used by
2410 // Machine Instruction Nodes in order to generate the bit encoding of the
2411 // instruction. Operands specify their base encoding interface with the
2412 // interface keyword. There are currently supported four interfaces,
2413 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
2414 // operand to generate a function which returns its register number when
2415 // queried. CONST_INTER causes an operand to generate a function which
2416 // returns the value of the constant when queried. MEMORY_INTER causes an
2417 // operand to generate four functions which return the Base Register, the
2418 // Index Register, the Scale Value, and the Offset Value of the operand when
2419 // queried. COND_INTER causes an operand to generate six functions which
2420 // return the encoding code (ie - encoding bits for the instruction)
2421 // associated with each basic boolean condition for a conditional instruction.
2422 //
2423 // Instructions specify two basic values for encoding. Again, a function
2424 // is available to check if the constant displacement is an oop. They use the
2425 // ins_encode keyword to specify their encoding classes (which must be
2426 // a sequence of enc_class names, and their parameters, specified in
2427 // the encoding block), and they use the
2428 // opcode keyword to specify, in order, their primary, secondary, and
2429 // tertiary opcode. Only the opcode sections which a particular instruction
2430 // needs for encoding need to be specified.
2431 encode %{
2432 enc_class enc_unimplemented %{
2433 C2_MacroAssembler _masm(&cbuf);
2434 __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
2435 %}
2436
2437 enc_class enc_untested %{
2438 #ifdef ASSERT
2439 C2_MacroAssembler _masm(&cbuf);
2440 __ untested("Untested mach node encoding in AD file.");
2441 #else
2442 #endif
2443 %}
2444
2445 enc_class enc_lbz(iRegIdst dst, memory mem) %{
2446 C2_MacroAssembler _masm(&cbuf);
2447 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2448 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2449 %}
2450
2451 // Load acquire.
2452 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
2453 C2_MacroAssembler _masm(&cbuf);
2454 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2455 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2456 __ twi_0($dst$$Register);
2457 __ isync();
2458 %}
2459
2460 enc_class enc_lhz(iRegIdst dst, memory mem) %{
2461
2462 C2_MacroAssembler _masm(&cbuf);
2463 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2464 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2465 %}
2466
2467 // Load acquire.
2468 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
2469
2470 C2_MacroAssembler _masm(&cbuf);
2471 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2472 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2473 __ twi_0($dst$$Register);
2474 __ isync();
2475 %}
2476
2477 enc_class enc_lwz(iRegIdst dst, memory mem) %{
2478
2479 C2_MacroAssembler _masm(&cbuf);
2480 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2481 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2482 %}
2483
2484 // Load acquire.
2485 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
2486
2487 C2_MacroAssembler _masm(&cbuf);
2488 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2489 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2490 __ twi_0($dst$$Register);
2491 __ isync();
2492 %}
2493
2494 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
2495 C2_MacroAssembler _masm(&cbuf);
2496 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2497 // Operand 'ds' requires 4-alignment.
2498 assert((Idisp & 0x3) == 0, "unaligned offset");
2499 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2500 %}
2501
2502 // Load acquire.
2503 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
2504 C2_MacroAssembler _masm(&cbuf);
2505 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2506 // Operand 'ds' requires 4-alignment.
2507 assert((Idisp & 0x3) == 0, "unaligned offset");
2508 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2509 __ twi_0($dst$$Register);
2510 __ isync();
2511 %}
2512
2513 enc_class enc_lfd(RegF dst, memory mem) %{
2514 C2_MacroAssembler _masm(&cbuf);
2515 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2516 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2517 %}
2518
2519 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2520
2521 C2_MacroAssembler _masm(&cbuf);
2522 int toc_offset = 0;
2523
2524 address const_toc_addr;
2525 // Create a non-oop constant, no relocation needed.
2526 // If it is an IC, it has a virtual_call_Relocation.
2527 const_toc_addr = __ long_constant((jlong)$src$$constant);
2528 if (const_toc_addr == NULL) {
2529 ciEnv::current()->record_out_of_memory_failure();
2530 return;
2531 }
2532
2533 // Get the constant's TOC offset.
2534 toc_offset = __ offset_to_method_toc(const_toc_addr);
2535
2536 // Keep the current instruction offset in mind.
2537 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2538
2539 __ ld($dst$$Register, toc_offset, $toc$$Register);
2540 %}
2541
2542 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2543
2544 C2_MacroAssembler _masm(&cbuf);
2545
2546 if (!ra_->C->output()->in_scratch_emit_size()) {
2547 address const_toc_addr;
2548 // Create a non-oop constant, no relocation needed.
2549 // If it is an IC, it has a virtual_call_Relocation.
2550 const_toc_addr = __ long_constant((jlong)$src$$constant);
2551 if (const_toc_addr == NULL) {
2552 ciEnv::current()->record_out_of_memory_failure();
2553 return;
2554 }
2555
2556 // Get the constant's TOC offset.
2557 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2558 // Store the toc offset of the constant.
2559 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2560
2561 // Also keep the current instruction offset in mind.
2562 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2563 }
2564
2565 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2566 %}
2567
2568 %} // encode
2569
2570 source %{
2571
2572 typedef struct {
2573 loadConL_hiNode *_large_hi;
2574 loadConL_loNode *_large_lo;
2575 loadConLNode *_small;
2576 MachNode *_last;
2577 } loadConLNodesTuple;
2578
2579 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2580 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2581 loadConLNodesTuple nodes;
2582
2583 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2584 if (large_constant_pool) {
2585 // Create new nodes.
2586 loadConL_hiNode *m1 = new loadConL_hiNode();
2587 loadConL_loNode *m2 = new loadConL_loNode();
2588
2589 // inputs for new nodes
2590 m1->add_req(NULL, toc);
2591 m2->add_req(NULL, m1);
2592
2593 // operands for new nodes
2594 m1->_opnds[0] = new iRegLdstOper(); // dst
2595 m1->_opnds[1] = immSrc; // src
2596 m1->_opnds[2] = new iRegPdstOper(); // toc
2597 m2->_opnds[0] = new iRegLdstOper(); // dst
2598 m2->_opnds[1] = immSrc; // src
2599 m2->_opnds[2] = new iRegLdstOper(); // base
2600
2601 // Initialize ins_attrib TOC fields.
2602 m1->_const_toc_offset = -1;
2603 m2->_const_toc_offset_hi_node = m1;
2604
2605 // Initialize ins_attrib instruction offset.
2606 m1->_cbuf_insts_offset = -1;
2607
2608 // register allocation for new nodes
2609 ra_->set_pair(m1->_idx, reg_second, reg_first);
2610 ra_->set_pair(m2->_idx, reg_second, reg_first);
2611
2612 // Create result.
2613 nodes._large_hi = m1;
2614 nodes._large_lo = m2;
2615 nodes._small = NULL;
2616 nodes._last = nodes._large_lo;
2617 assert(m2->bottom_type()->isa_long(), "must be long");
2618 } else {
2619 loadConLNode *m2 = new loadConLNode();
2620
2621 // inputs for new nodes
2622 m2->add_req(NULL, toc);
2623
2624 // operands for new nodes
2625 m2->_opnds[0] = new iRegLdstOper(); // dst
2626 m2->_opnds[1] = immSrc; // src
2627 m2->_opnds[2] = new iRegPdstOper(); // toc
2628
2629 // Initialize ins_attrib instruction offset.
2630 m2->_cbuf_insts_offset = -1;
2631
2632 // register allocation for new nodes
2633 ra_->set_pair(m2->_idx, reg_second, reg_first);
2634
2635 // Create result.
2636 nodes._large_hi = NULL;
2637 nodes._large_lo = NULL;
2638 nodes._small = m2;
2639 nodes._last = nodes._small;
2640 assert(m2->bottom_type()->isa_long(), "must be long");
2641 }
2642
2643 return nodes;
2644 }
2645
2646 typedef struct {
2647 loadConL_hiNode *_large_hi;
2648 loadConL_loNode *_large_lo;
2649 mtvsrdNode *_moved;
2650 xxspltdNode *_replicated;
2651 loadConLNode *_small;
2652 MachNode *_last;
2653 } loadConLReplicatedNodesTuple;
2654
2655 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2656 vecXOper *dst, immI_0Oper *zero,
2657 OptoReg::Name reg_second, OptoReg::Name reg_first,
2658 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) {
2659 loadConLReplicatedNodesTuple nodes;
2660
2661 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2662 if (large_constant_pool) {
2663 // Create new nodes.
2664 loadConL_hiNode *m1 = new loadConL_hiNode();
2665 loadConL_loNode *m2 = new loadConL_loNode();
2666 mtvsrdNode *m3 = new mtvsrdNode();
2667 xxspltdNode *m4 = new xxspltdNode();
2668
2669 // inputs for new nodes
2670 m1->add_req(NULL, toc);
2671 m2->add_req(NULL, m1);
2672 m3->add_req(NULL, m2);
2673 m4->add_req(NULL, m3);
2674
2675 // operands for new nodes
2676 m1->_opnds[0] = new iRegLdstOper(); // dst
2677 m1->_opnds[1] = immSrc; // src
2678 m1->_opnds[2] = new iRegPdstOper(); // toc
2679
2680 m2->_opnds[0] = new iRegLdstOper(); // dst
2681 m2->_opnds[1] = immSrc; // src
2682 m2->_opnds[2] = new iRegLdstOper(); // base
2683
2684 m3->_opnds[0] = new vecXOper(); // dst
2685 m3->_opnds[1] = new iRegLdstOper(); // src
2686
2687 m4->_opnds[0] = new vecXOper(); // dst
2688 m4->_opnds[1] = new vecXOper(); // src
2689 m4->_opnds[2] = zero;
2690
2691 // Initialize ins_attrib TOC fields.
2692 m1->_const_toc_offset = -1;
2693 m2->_const_toc_offset_hi_node = m1;
2694
2695 // Initialize ins_attrib instruction offset.
2696 m1->_cbuf_insts_offset = -1;
2697
2698 // register allocation for new nodes
2699 ra_->set_pair(m1->_idx, reg_second, reg_first);
2700 ra_->set_pair(m2->_idx, reg_second, reg_first);
2701 ra_->set1(m3->_idx, reg_second);
2702 ra_->set2(m3->_idx, reg_vec_first);
2703 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2704
2705 // Create result.
2706 nodes._large_hi = m1;
2707 nodes._large_lo = m2;
2708 nodes._moved = m3;
2709 nodes._replicated = m4;
2710 nodes._small = NULL;
2711 nodes._last = nodes._replicated;
2712 assert(m2->bottom_type()->isa_long(), "must be long");
2713 } else {
2714 loadConLNode *m2 = new loadConLNode();
2715 mtvsrdNode *m3 = new mtvsrdNode();
2716 xxspltdNode *m4 = new xxspltdNode();
2717
2718 // inputs for new nodes
2719 m2->add_req(NULL, toc);
2720
2721 // operands for new nodes
2722 m2->_opnds[0] = new iRegLdstOper(); // dst
2723 m2->_opnds[1] = immSrc; // src
2724 m2->_opnds[2] = new iRegPdstOper(); // toc
2725
2726 m3->_opnds[0] = new vecXOper(); // dst
2727 m3->_opnds[1] = new iRegLdstOper(); // src
2728
2729 m4->_opnds[0] = new vecXOper(); // dst
2730 m4->_opnds[1] = new vecXOper(); // src
2731 m4->_opnds[2] = zero;
2732
2733 // Initialize ins_attrib instruction offset.
2734 m2->_cbuf_insts_offset = -1;
2735 ra_->set1(m3->_idx, reg_second);
2736 ra_->set2(m3->_idx, reg_vec_first);
2737 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2738
2739 // register allocation for new nodes
2740 ra_->set_pair(m2->_idx, reg_second, reg_first);
2741
2742 // Create result.
2743 nodes._large_hi = NULL;
2744 nodes._large_lo = NULL;
2745 nodes._small = m2;
2746 nodes._moved = m3;
2747 nodes._replicated = m4;
2748 nodes._last = nodes._replicated;
2749 assert(m2->bottom_type()->isa_long(), "must be long");
2750 }
2751
2752 return nodes;
2753 }
2754
2755 %} // source
2756
2757 encode %{
2758 // Postalloc expand emitter for loading a long constant from the method's TOC.
2759 // Enc_class needed as consttanttablebase is not supported by postalloc
2760 // expand.
2761 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2762 // Create new nodes.
2763 loadConLNodesTuple loadConLNodes =
2764 loadConLNodesTuple_create(ra_, n_toc, op_src,
2765 ra_->get_reg_second(this), ra_->get_reg_first(this));
2766
2767 // Push new nodes.
2768 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2769 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2770
2771 // some asserts
2772 assert(nodes->length() >= 1, "must have created at least 1 node");
2773 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2774 %}
2775
2776 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2777
2778 C2_MacroAssembler _masm(&cbuf);
2779 int toc_offset = 0;
2780
2781 intptr_t val = $src$$constant;
2782 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2783 address const_toc_addr;
2784 if (constant_reloc == relocInfo::oop_type) {
2785 // Create an oop constant and a corresponding relocation.
2786 AddressLiteral a = __ allocate_oop_address((jobject)val);
2787 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2788 __ relocate(a.rspec());
2789 } else if (constant_reloc == relocInfo::metadata_type) {
2790 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2791 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2792 __ relocate(a.rspec());
2793 } else {
2794 // Create a non-oop constant, no relocation needed.
2795 const_toc_addr = __ long_constant((jlong)$src$$constant);
2796 }
2797
2798 if (const_toc_addr == NULL) {
2799 ciEnv::current()->record_out_of_memory_failure();
2800 return;
2801 }
2802 // Get the constant's TOC offset.
2803 toc_offset = __ offset_to_method_toc(const_toc_addr);
2804
2805 __ ld($dst$$Register, toc_offset, $toc$$Register);
2806 %}
2807
2808 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2809
2810 C2_MacroAssembler _masm(&cbuf);
2811 if (!ra_->C->output()->in_scratch_emit_size()) {
2812 intptr_t val = $src$$constant;
2813 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2814 address const_toc_addr;
2815 if (constant_reloc == relocInfo::oop_type) {
2816 // Create an oop constant and a corresponding relocation.
2817 AddressLiteral a = __ allocate_oop_address((jobject)val);
2818 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2819 __ relocate(a.rspec());
2820 } else if (constant_reloc == relocInfo::metadata_type) {
2821 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2822 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2823 __ relocate(a.rspec());
2824 } else { // non-oop pointers, e.g. card mark base, heap top
2825 // Create a non-oop constant, no relocation needed.
2826 const_toc_addr = __ long_constant((jlong)$src$$constant);
2827 }
2828
2829 if (const_toc_addr == NULL) {
2830 ciEnv::current()->record_out_of_memory_failure();
2831 return;
2832 }
2833 // Get the constant's TOC offset.
2834 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2835 // Store the toc offset of the constant.
2836 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2837 }
2838
2839 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2840 %}
2841
2842 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2843 // Enc_class needed as consttanttablebase is not supported by postalloc
2844 // expand.
2845 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2846 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2847 if (large_constant_pool) {
2848 // Create new nodes.
2849 loadConP_hiNode *m1 = new loadConP_hiNode();
2850 loadConP_loNode *m2 = new loadConP_loNode();
2851
2852 // inputs for new nodes
2853 m1->add_req(NULL, n_toc);
2854 m2->add_req(NULL, m1);
2855
2856 // operands for new nodes
2857 m1->_opnds[0] = new iRegPdstOper(); // dst
2858 m1->_opnds[1] = op_src; // src
2859 m1->_opnds[2] = new iRegPdstOper(); // toc
2860 m2->_opnds[0] = new iRegPdstOper(); // dst
2861 m2->_opnds[1] = op_src; // src
2862 m2->_opnds[2] = new iRegLdstOper(); // base
2863
2864 // Initialize ins_attrib TOC fields.
2865 m1->_const_toc_offset = -1;
2866 m2->_const_toc_offset_hi_node = m1;
2867
2868 // Register allocation for new nodes.
2869 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2870 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2871
2872 nodes->push(m1);
2873 nodes->push(m2);
2874 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2875 } else {
2876 loadConPNode *m2 = new loadConPNode();
2877
2878 // inputs for new nodes
2879 m2->add_req(NULL, n_toc);
2880
2881 // operands for new nodes
2882 m2->_opnds[0] = new iRegPdstOper(); // dst
2883 m2->_opnds[1] = op_src; // src
2884 m2->_opnds[2] = new iRegPdstOper(); // toc
2885
2886 // Register allocation for new nodes.
2887 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2888
2889 nodes->push(m2);
2890 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2891 }
2892 %}
2893
2894 // Enc_class needed as consttanttablebase is not supported by postalloc
2895 // expand.
2896 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2897 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2898
2899 MachNode *m2;
2900 if (large_constant_pool) {
2901 m2 = new loadConFCompNode();
2902 } else {
2903 m2 = new loadConFNode();
2904 }
2905 // inputs for new nodes
2906 m2->add_req(NULL, n_toc);
2907
2908 // operands for new nodes
2909 m2->_opnds[0] = op_dst;
2910 m2->_opnds[1] = op_src;
2911 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase
2912
2913 // register allocation for new nodes
2914 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2915 nodes->push(m2);
2916 %}
2917
2918 // Enc_class needed as consttanttablebase is not supported by postalloc
2919 // expand.
2920 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2921 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2922
2923 MachNode *m2;
2924 if (large_constant_pool) {
2925 m2 = new loadConDCompNode();
2926 } else {
2927 m2 = new loadConDNode();
2928 }
2929 // inputs for new nodes
2930 m2->add_req(NULL, n_toc);
2931
2932 // operands for new nodes
2933 m2->_opnds[0] = op_dst;
2934 m2->_opnds[1] = op_src;
2935 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase
2936
2937 // register allocation for new nodes
2938 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2939 nodes->push(m2);
2940 %}
2941
2942 enc_class enc_stw(iRegIsrc src, memory mem) %{
2943 C2_MacroAssembler _masm(&cbuf);
2944 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2945 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2946 %}
2947
2948 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2949 C2_MacroAssembler _masm(&cbuf);
2950 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2951 // Operand 'ds' requires 4-alignment.
2952 assert((Idisp & 0x3) == 0, "unaligned offset");
2953 __ std($src$$Register, Idisp, $mem$$base$$Register);
2954 %}
2955
2956 enc_class enc_stfs(RegF src, memory mem) %{
2957 C2_MacroAssembler _masm(&cbuf);
2958 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2959 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2960 %}
2961
2962 enc_class enc_stfd(RegF src, memory mem) %{
2963 C2_MacroAssembler _masm(&cbuf);
2964 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2965 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2966 %}
2967
2968 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2969
2970 if (VM_Version::has_isel()) {
2971 // use isel instruction with Power 7
2972 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
2973 encodeP_subNode *n_sub_base = new encodeP_subNode();
2974 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
2975 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode();
2976
2977 n_compare->add_req(n_region, n_src);
2978 n_compare->_opnds[0] = op_crx;
2979 n_compare->_opnds[1] = op_src;
2980 n_compare->_opnds[2] = new immL16Oper(0);
2981
2982 n_sub_base->add_req(n_region, n_src);
2983 n_sub_base->_opnds[0] = op_dst;
2984 n_sub_base->_opnds[1] = op_src;
2985 n_sub_base->_bottom_type = _bottom_type;
2986
2987 n_shift->add_req(n_region, n_sub_base);
2988 n_shift->_opnds[0] = op_dst;
2989 n_shift->_opnds[1] = op_dst;
2990 n_shift->_bottom_type = _bottom_type;
2991
2992 n_cond_set->add_req(n_region, n_compare, n_shift);
2993 n_cond_set->_opnds[0] = op_dst;
2994 n_cond_set->_opnds[1] = op_crx;
2995 n_cond_set->_opnds[2] = op_dst;
2996 n_cond_set->_bottom_type = _bottom_type;
2997
2998 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2999 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3000 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3001 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3002
3003 nodes->push(n_compare);
3004 nodes->push(n_sub_base);
3005 nodes->push(n_shift);
3006 nodes->push(n_cond_set);
3007
3008 } else {
3009 // before Power 7
3010 moveRegNode *n_move = new moveRegNode();
3011 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
3012 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
3013 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode();
3014
3015 n_move->add_req(n_region, n_src);
3016 n_move->_opnds[0] = op_dst;
3017 n_move->_opnds[1] = op_src;
3018 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop.
3019
3020 n_compare->add_req(n_region, n_src);
3021 n_compare->add_prec(n_move);
3022
3023 n_compare->_opnds[0] = op_crx;
3024 n_compare->_opnds[1] = op_src;
3025 n_compare->_opnds[2] = new immL16Oper(0);
3026
3027 n_sub_base->add_req(n_region, n_compare, n_src);
3028 n_sub_base->_opnds[0] = op_dst;
3029 n_sub_base->_opnds[1] = op_crx;
3030 n_sub_base->_opnds[2] = op_src;
3031 n_sub_base->_bottom_type = _bottom_type;
3032
3033 n_shift->add_req(n_region, n_sub_base);
3034 n_shift->_opnds[0] = op_dst;
3035 n_shift->_opnds[1] = op_dst;
3036 n_shift->_bottom_type = _bottom_type;
3037
3038 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3039 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3040 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3041 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3042
3043 nodes->push(n_move);
3044 nodes->push(n_compare);
3045 nodes->push(n_sub_base);
3046 nodes->push(n_shift);
3047 }
3048
3049 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
3050 %}
3051
3052 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
3053
3054 encodeP_subNode *n1 = new encodeP_subNode();
3055 n1->add_req(n_region, n_src);
3056 n1->_opnds[0] = op_dst;
3057 n1->_opnds[1] = op_src;
3058 n1->_bottom_type = _bottom_type;
3059
3060 encodeP_shiftNode *n2 = new encodeP_shiftNode();
3061 n2->add_req(n_region, n1);
3062 n2->_opnds[0] = op_dst;
3063 n2->_opnds[1] = op_dst;
3064 n2->_bottom_type = _bottom_type;
3065 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3066 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3067
3068 nodes->push(n1);
3069 nodes->push(n2);
3070 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
3071 %}
3072
3073 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
3074 decodeN_shiftNode *n_shift = new decodeN_shiftNode();
3075 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
3076
3077 n_compare->add_req(n_region, n_src);
3078 n_compare->_opnds[0] = op_crx;
3079 n_compare->_opnds[1] = op_src;
3080 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
3081
3082 n_shift->add_req(n_region, n_src);
3083 n_shift->_opnds[0] = op_dst;
3084 n_shift->_opnds[1] = op_src;
3085 n_shift->_bottom_type = _bottom_type;
3086
3087 if (VM_Version::has_isel()) {
3088 // use isel instruction with Power 7
3089
3090 decodeN_addNode *n_add_base = new decodeN_addNode();
3091 n_add_base->add_req(n_region, n_shift);
3092 n_add_base->_opnds[0] = op_dst;
3093 n_add_base->_opnds[1] = op_dst;
3094 n_add_base->_bottom_type = _bottom_type;
3095
3096 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
3097 n_cond_set->add_req(n_region, n_compare, n_add_base);
3098 n_cond_set->_opnds[0] = op_dst;
3099 n_cond_set->_opnds[1] = op_crx;
3100 n_cond_set->_opnds[2] = op_dst;
3101 n_cond_set->_bottom_type = _bottom_type;
3102
3103 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3104 ra_->set_oop(n_cond_set, true);
3105
3106 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3107 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3108 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3109 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3110
3111 nodes->push(n_compare);
3112 nodes->push(n_shift);
3113 nodes->push(n_add_base);
3114 nodes->push(n_cond_set);
3115
3116 } else {
3117 // before Power 7
3118 cond_add_baseNode *n_add_base = new cond_add_baseNode();
3119
3120 n_add_base->add_req(n_region, n_compare, n_shift);
3121 n_add_base->_opnds[0] = op_dst;
3122 n_add_base->_opnds[1] = op_crx;
3123 n_add_base->_opnds[2] = op_dst;
3124 n_add_base->_bottom_type = _bottom_type;
3125
3126 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3127 ra_->set_oop(n_add_base, true);
3128
3129 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3130 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3131 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3132
3133 nodes->push(n_compare);
3134 nodes->push(n_shift);
3135 nodes->push(n_add_base);
3136 }
3137 %}
3138
3139 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3140 decodeN_shiftNode *n1 = new decodeN_shiftNode();
3141 n1->add_req(n_region, n_src);
3142 n1->_opnds[0] = op_dst;
3143 n1->_opnds[1] = op_src;
3144 n1->_bottom_type = _bottom_type;
3145
3146 decodeN_addNode *n2 = new decodeN_addNode();
3147 n2->add_req(n_region, n1);
3148 n2->_opnds[0] = op_dst;
3149 n2->_opnds[1] = op_dst;
3150 n2->_bottom_type = _bottom_type;
3151 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3152 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3153
3154 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3155 ra_->set_oop(n2, true);
3156
3157 nodes->push(n1);
3158 nodes->push(n2);
3159 %}
3160
3161 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{
3162
3163 C2_MacroAssembler _masm(&cbuf);
3164 int cc = $cmp$$cmpcode;
3165 int flags_reg = $crx$$reg;
3166 Label done;
3167 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3168 // Branch if not (cmp crx).
3169 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done);
3170 __ mr($dst$$Register, $src$$Register);
3171 __ bind(done);
3172 %}
3173
3174 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{
3175
3176 C2_MacroAssembler _masm(&cbuf);
3177 Label done;
3178 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3179 // Branch if not (cmp crx).
3180 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
3181 __ li($dst$$Register, $src$$constant);
3182 __ bind(done);
3183 %}
3184
3185 // This enc_class is needed so that scheduler gets proper
3186 // input mapping for latency computation.
3187 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
3188 C2_MacroAssembler _masm(&cbuf);
3189 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
3190 %}
3191
3192 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3193
3194 C2_MacroAssembler _masm(&cbuf);
3195
3196 Label done;
3197 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3198 __ li($dst$$Register, $zero$$constant);
3199 __ beq($crx$$CondRegister, done);
3200 __ li($dst$$Register, $notzero$$constant);
3201 __ bind(done);
3202 %}
3203
3204 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3205
3206 C2_MacroAssembler _masm(&cbuf);
3207
3208 Label done;
3209 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3210 __ li($dst$$Register, $zero$$constant);
3211 __ beq($crx$$CondRegister, done);
3212 __ li($dst$$Register, $notzero$$constant);
3213 __ bind(done);
3214 %}
3215
3216 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3217
3218 C2_MacroAssembler _masm(&cbuf);
3219 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3220 Label done;
3221 __ bso($crx$$CondRegister, done);
3222 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3223 __ bind(done);
3224 %}
3225
3226 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
3227
3228 C2_MacroAssembler _masm(&cbuf);
3229 Label done;
3230 __ bso($crx$$CondRegister, done);
3231 __ mffprd($dst$$Register, $src$$FloatRegister);
3232 __ bind(done);
3233 %}
3234
3235 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3236
3237 C2_MacroAssembler _masm(&cbuf);
3238 Label d; // dummy
3239 __ bind(d);
3240 Label* p = ($lbl$$label);
3241 // `p' is `NULL' when this encoding class is used only to
3242 // determine the size of the encoded instruction.
3243 Label& l = (NULL == p)? d : *(p);
3244 int cc = $cmp$$cmpcode;
3245 int flags_reg = $crx$$reg;
3246 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3247 int bhint = Assembler::bhintNoHint;
3248
3249 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3250 if (_prob <= PROB_NEVER) {
3251 bhint = Assembler::bhintIsNotTaken;
3252 } else if (_prob >= PROB_ALWAYS) {
3253 bhint = Assembler::bhintIsTaken;
3254 }
3255 }
3256
3257 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3258 cc_to_biint(cc, flags_reg),
3259 l);
3260 %}
3261
3262 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3263 // The scheduler doesn't know about branch shortening, so we set the opcode
3264 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3265
3266 C2_MacroAssembler _masm(&cbuf);
3267 Label d; // dummy
3268 __ bind(d);
3269 Label* p = ($lbl$$label);
3270 // `p' is `NULL' when this encoding class is used only to
3271 // determine the size of the encoded instruction.
3272 Label& l = (NULL == p)? d : *(p);
3273 int cc = $cmp$$cmpcode;
3274 int flags_reg = $crx$$reg;
3275 int bhint = Assembler::bhintNoHint;
3276
3277 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3278 if (_prob <= PROB_NEVER) {
3279 bhint = Assembler::bhintIsNotTaken;
3280 } else if (_prob >= PROB_ALWAYS) {
3281 bhint = Assembler::bhintIsTaken;
3282 }
3283 }
3284
3285 // Tell the conditional far branch to optimize itself when being relocated.
3286 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3287 cc_to_biint(cc, flags_reg),
3288 l,
3289 MacroAssembler::bc_far_optimize_on_relocate);
3290 %}
3291
3292 // Postalloc expand emitter for loading a replicatef float constant from
3293 // the method's TOC.
3294 // Enc_class needed as consttanttablebase is not supported by postalloc
3295 // expand.
3296 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3297 // Create new nodes.
3298
3299 // Make an operand with the bit pattern to load as float.
3300 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3301
3302 loadConLNodesTuple loadConLNodes =
3303 loadConLNodesTuple_create(ra_, n_toc, op_repl,
3304 ra_->get_reg_second(this), ra_->get_reg_first(this));
3305
3306 // Push new nodes.
3307 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3308 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3309
3310 assert(nodes->length() >= 1, "must have created at least 1 node");
3311 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3312 %}
3313
3314 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{
3315 // Create new nodes.
3316
3317 // Make an operand with the bit pattern to load as float.
3318 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3319 immI_0Oper *op_zero = new immI_0Oper(0);
3320
3321 loadConLReplicatedNodesTuple loadConLNodes =
3322 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero,
3323 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp),
3324 ra_->get_reg_second(this), ra_->get_reg_first(this));
3325
3326 // Push new nodes.
3327 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); }
3328 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); }
3329 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); }
3330 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); }
3331
3332 assert(nodes->length() >= 1, "must have created at least 1 node");
3333 %}
3334
3335 // This enc_class is needed so that scheduler gets proper
3336 // input mapping for latency computation.
3337 enc_class enc_poll(immI dst, iRegLdst poll) %{
3338 // Fake operand dst needed for PPC scheduler.
3339 assert($dst$$constant == 0x0, "dst must be 0x0");
3340
3341 C2_MacroAssembler _masm(&cbuf);
3342 // Mark the code position where the load from the safepoint
3343 // polling page was emitted as relocInfo::poll_type.
3344 __ relocate(relocInfo::poll_type);
3345 __ load_from_polling_page($poll$$Register);
3346 %}
3347
3348 // A Java static call or a runtime call.
3349 //
3350 // Branch-and-link relative to a trampoline.
3351 // The trampoline loads the target address and does a long branch to there.
3352 // In case we call java, the trampoline branches to a interpreter_stub
3353 // which loads the inline cache and the real call target from the constant pool.
3354 //
3355 // This basically looks like this:
3356 //
3357 // >>>> consts -+ -+
3358 // | |- offset1
3359 // [call target1] | <-+
3360 // [IC cache] |- offset2
3361 // [call target2] <--+
3362 //
3363 // <<<< consts
3364 // >>>> insts
3365 //
3366 // bl offset16 -+ -+ ??? // How many bits available?
3367 // | |
3368 // <<<< insts | |
3369 // >>>> stubs | |
3370 // | |- trampoline_stub_Reloc
3371 // trampoline stub: | <-+
3372 // r2 = toc |
3373 // r2 = [r2 + offset1] | // Load call target1 from const section
3374 // mtctr r2 |
3375 // bctr |- static_stub_Reloc
3376 // comp_to_interp_stub: <---+
3377 // r1 = toc
3378 // ICreg = [r1 + IC_offset] // Load IC from const section
3379 // r1 = [r1 + offset2] // Load call target2 from const section
3380 // mtctr r1
3381 // bctr
3382 //
3383 // <<<< stubs
3384 //
3385 // The call instruction in the code either
3386 // - Branches directly to a compiled method if the offset is encodable in instruction.
3387 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3388 // - Branches to the compiled_to_interp stub if the target is interpreted.
3389 //
3390 // Further there are three relocations from the loads to the constants in
3391 // the constant section.
3392 //
3393 // Usage of r1 and r2 in the stubs allows to distinguish them.
3394 enc_class enc_java_static_call(method meth) %{
3395
3396 C2_MacroAssembler _masm(&cbuf);
3397 address entry_point = (address)$meth$$method;
3398
3399 if (!_method) {
3400 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3401 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type);
3402 } else {
3403 // Remember the offset not the address.
3404 const int start_offset = __ offset();
3405
3406 // The trampoline stub.
3407 // No entry point given, use the current pc.
3408 // Make sure branch fits into
3409 if (entry_point == 0) entry_point = __ pc();
3410
3411 // Put the entry point as a constant into the constant pool.
3412 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
3413 if (entry_point_toc_addr == NULL) {
3414 ciEnv::current()->record_out_of_memory_failure();
3415 return;
3416 }
3417 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
3418
3419 // Emit the trampoline stub which will be related to the branch-and-link below.
3420 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
3421 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3422 int method_index = resolved_method_index(cbuf);
3423 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3424 : static_call_Relocation::spec(method_index));
3425
3426 // The real call.
3427 // Note: At this point we do not have the address of the trampoline
3428 // stub, and the entry point might be too far away for bl, so __ pc()
3429 // serves as dummy and the bl will be patched later.
3430 cbuf.set_insts_mark();
3431 __ bl(__ pc()); // Emits a relocation.
3432
3433 // The stub for call to interpreter.
3434 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
3435 if (stub == NULL) {
3436 ciEnv::current()->record_failure("CodeCache is full");
3437 return;
3438 }
3439 }
3440 %}
3441
3442 // Second node of expanded dynamic call - the call.
3443 enc_class enc_java_dynamic_call_sched(method meth) %{
3444
3445 C2_MacroAssembler _masm(&cbuf);
3446
3447 if (!ra_->C->output()->in_scratch_emit_size()) {
3448 // Create a call trampoline stub for the given method.
3449 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method;
3450 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none);
3451 if (entry_point_const == NULL) {
3452 ciEnv::current()->record_out_of_memory_failure();
3453 return;
3454 }
3455 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const);
3456 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset());
3457 if (ra_->C->env()->failing()) { return; } // Code cache may be full.
3458
3459 // Build relocation at call site with ic position as data.
3460 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) ||
3461 (_load_ic_hi_node == NULL && _load_ic_node != NULL),
3462 "must have one, but can't have both");
3463 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) ||
3464 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1),
3465 "must contain instruction offset");
3466 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL
3467 ? _load_ic_hi_node->_cbuf_insts_offset
3468 : _load_ic_node->_cbuf_insts_offset;
3469 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset);
3470 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr),
3471 "should be load from TOC");
3472 int method_index = resolved_method_index(cbuf);
3473 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
3474 }
3475
3476 // At this point I do not have the address of the trampoline stub,
3477 // and the entry point might be too far away for bl. Pc() serves
3478 // as dummy and bl will be patched later.
3479 __ bl((address) __ pc());
3480 %}
3481
3482 // postalloc expand emitter for virtual calls.
3483 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{
3484
3485 // Create the nodes for loading the IC from the TOC.
3486 loadConLNodesTuple loadConLNodes_IC =
3487 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()),
3488 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num));
3489
3490 // Create the call node.
3491 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode();
3492 call->_method_handle_invoke = _method_handle_invoke;
3493 call->_vtable_index = _vtable_index;
3494 call->_method = _method;
3495 call->_optimized_virtual = _optimized_virtual;
3496 call->_tf = _tf;
3497 call->_entry_point = _entry_point;
3498 call->_cnt = _cnt;
3499 call->_guaranteed_safepoint = true;
3500 call->_oop_map = _oop_map;
3501 call->_jvms = _jvms;
3502 call->_jvmadj = _jvmadj;
3503 call->_in_rms = _in_rms;
3504 call->_nesting = _nesting;
3505 call->_override_symbolic_info = _override_symbolic_info;
3506
3507 // New call needs all inputs of old call.
3508 // Req...
3509 for (uint i = 0; i < req(); ++i) {
3510 // The expanded node does not need toc any more.
3511 // Add the inline cache constant here instead. This expresses the
3512 // register of the inline cache must be live at the call.
3513 // Else we would have to adapt JVMState by -1.
3514 if (i == mach_constant_base_node_input()) {
3515 call->add_req(loadConLNodes_IC._last);
3516 } else {
3517 call->add_req(in(i));
3518 }
3519 }
3520 // ...as well as prec
3521 for (uint i = req(); i < len(); ++i) {
3522 call->add_prec(in(i));
3523 }
3524
3525 // Remember nodes loading the inline cache into r19.
3526 call->_load_ic_hi_node = loadConLNodes_IC._large_hi;
3527 call->_load_ic_node = loadConLNodes_IC._small;
3528
3529 // Operands for new nodes.
3530 call->_opnds[0] = _opnds[0];
3531 call->_opnds[1] = _opnds[1];
3532
3533 // Only the inline cache is associated with a register.
3534 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19");
3535
3536 // Push new nodes.
3537 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi);
3538 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last);
3539 nodes->push(call);
3540 %}
3541
3542 // Compound version of call dynamic
3543 // Toc is only passed so that it can be used in ins_encode statement.
3544 // In the code we have to use $constanttablebase.
3545 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
3546 C2_MacroAssembler _masm(&cbuf);
3547 int start_offset = __ offset();
3548
3549 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC;
3550
3551 int vtable_index = this->_vtable_index;
3552 if (vtable_index < 0) {
3553 // Must be invalid_vtable_index, not nonvirtual_vtable_index.
3554 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value");
3555 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode());
3556
3557 // Virtual call relocation will point to ic load.
3558 address virtual_call_meta_addr = __ pc();
3559 // Load a clear inline cache.
3560 AddressLiteral empty_ic((address) Universe::non_oop_word());
3561 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true);
3562 if (!success) {
3563 ciEnv::current()->record_out_of_memory_failure();
3564 return;
3565 }
3566 // CALL to fixup routine. Fixup routine uses ScopeDesc info
3567 // to determine who we intended to call.
3568 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr));
3569 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none);
3570 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3571 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3572 } else {
3573 assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
3574 // Go thru the vtable. Get receiver klass. Receiver already
3575 // checked for non-null. If we'll go thru a C2I adapter, the
3576 // interpreter expects method in R19_method.
3577
3578 __ load_klass(R11_scratch1, R3);
3579
3580 int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index * vtableEntry::size_in_bytes();
3581 int v_off = entry_offset + vtableEntry::method_offset_in_bytes();
3582 __ li(R19_method, v_off);
3583 __ ldx(R19_method/*method*/, R19_method/*method offset*/, R11_scratch1/*class*/);
3584 // NOTE: for vtable dispatches, the vtable entry will never be
3585 // null. However it may very well end up in handle_wrong_method
3586 // if the method is abstract for the particular class.
3587 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method);
3588 // Call target. Either compiled code or C2I adapter.
3589 __ mtctr(R11_scratch1);
3590 __ bctrl();
3591 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3592 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3593 }
3594 %}
3595
3596 // a runtime call
3597 enc_class enc_java_to_runtime_call (method meth) %{
3598
3599 C2_MacroAssembler _masm(&cbuf);
3600 const address start_pc = __ pc();
3601
3602 #if defined(ABI_ELFv2)
3603 address entry= !($meth$$method) ? NULL : (address)$meth$$method;
3604 __ call_c(entry, relocInfo::runtime_call_type);
3605 #else
3606 // The function we're going to call.
3607 FunctionDescriptor fdtemp;
3608 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3609
3610 Register Rtoc = R12_scratch2;
3611 // Calculate the method's TOC.
3612 __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3613 // Put entry, env, toc into the constant pool, this needs up to 3 constant
3614 // pool entries; call_c_using_toc will optimize the call.
3615 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3616 if (!success) {
3617 ciEnv::current()->record_out_of_memory_failure();
3618 return;
3619 }
3620 #endif
3621
3622 // Check the ret_addr_offset.
3623 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3624 "Fix constant in ret_addr_offset()");
3625 %}
3626
3627 // Move to ctr for leaf call.
3628 // This enc_class is needed so that scheduler gets proper
3629 // input mapping for latency computation.
3630 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3631 C2_MacroAssembler _masm(&cbuf);
3632 __ mtctr($src$$Register);
3633 %}
3634
3635 // Postalloc expand emitter for runtime leaf calls.
3636 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3637 loadConLNodesTuple loadConLNodes_Entry;
3638 #if defined(ABI_ELFv2)
3639 jlong entry_address = (jlong) this->entry_point();
3640 assert(entry_address, "need address here");
3641 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3642 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3643 #else
3644 // Get the struct that describes the function we are about to call.
3645 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3646 assert(fd, "need fd here");
3647 jlong entry_address = (jlong) fd->entry();
3648 // new nodes
3649 loadConLNodesTuple loadConLNodes_Env;
3650 loadConLNodesTuple loadConLNodes_Toc;
3651
3652 // Create nodes and operands for loading the entry point.
3653 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3654 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3655
3656
3657 // Create nodes and operands for loading the env pointer.
3658 if (fd->env() != NULL) {
3659 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3660 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3661 } else {
3662 loadConLNodes_Env._large_hi = NULL;
3663 loadConLNodes_Env._large_lo = NULL;
3664 loadConLNodes_Env._small = NULL;
3665 loadConLNodes_Env._last = new loadConL16Node();
3666 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3667 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3668 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3669 }
3670
3671 // Create nodes and operands for loading the Toc point.
3672 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3673 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3674 #endif // ABI_ELFv2
3675 // mtctr node
3676 MachNode *mtctr = new CallLeafDirect_mtctrNode();
3677
3678 assert(loadConLNodes_Entry._last != NULL, "entry must exist");
3679 mtctr->add_req(0, loadConLNodes_Entry._last);
3680
3681 mtctr->_opnds[0] = new iRegLdstOper();
3682 mtctr->_opnds[1] = new iRegLdstOper();
3683
3684 // call node
3685 MachCallLeafNode *call = new CallLeafDirectNode();
3686
3687 call->_opnds[0] = _opnds[0];
3688 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3689
3690 // Make the new call node look like the old one.
3691 call->_name = _name;
3692 call->_tf = _tf;
3693 call->_entry_point = _entry_point;
3694 call->_cnt = _cnt;
3695 call->_guaranteed_safepoint = false;
3696 call->_oop_map = _oop_map;
3697 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3698 call->_jvms = NULL;
3699 call->_jvmadj = _jvmadj;
3700 call->_in_rms = _in_rms;
3701 call->_nesting = _nesting;
3702
3703 // New call needs all inputs of old call.
3704 // Req...
3705 for (uint i = 0; i < req(); ++i) {
3706 if (i != mach_constant_base_node_input()) {
3707 call->add_req(in(i));
3708 }
3709 }
3710
3711 // These must be reqired edges, as the registers are live up to
3712 // the call. Else the constants are handled as kills.
3713 call->add_req(mtctr);
3714 #if !defined(ABI_ELFv2)
3715 call->add_req(loadConLNodes_Env._last);
3716 call->add_req(loadConLNodes_Toc._last);
3717 #endif
3718
3719 // ...as well as prec
3720 for (uint i = req(); i < len(); ++i) {
3721 call->add_prec(in(i));
3722 }
3723
3724 // registers
3725 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3726
3727 // Insert the new nodes.
3728 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3729 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last);
3730 #if !defined(ABI_ELFv2)
3731 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi);
3732 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last);
3733 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi);
3734 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last);
3735 #endif
3736 nodes->push(mtctr);
3737 nodes->push(call);
3738 %}
3739 %}
3740
3741 //----------FRAME--------------------------------------------------------------
3742 // Definition of frame structure and management information.
3743
3744 frame %{
3745 // These two registers define part of the calling convention between
3746 // compiled code and the interpreter.
3747
3748 // Inline Cache Register or method for I2C.
3749 inline_cache_reg(R19); // R19_method
3750
3751 // Optional: name the operand used by cisc-spilling to access
3752 // [stack_pointer + offset].
3753 cisc_spilling_operand_name(indOffset);
3754
3755 // Number of stack slots consumed by a Monitor enter.
3756 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size));
3757
3758 // Compiled code's Frame Pointer.
3759 frame_pointer(R1); // R1_SP
3760
3761 // Interpreter stores its frame pointer in a register which is
3762 // stored to the stack by I2CAdaptors. I2CAdaptors convert from
3763 // interpreted java to compiled java.
3764 //
3765 // R14_state holds pointer to caller's cInterpreter.
3766 interpreter_frame_pointer(R14); // R14_state
3767
3768 stack_alignment(frame::alignment_in_bytes);
3769
3770 // Number of outgoing stack slots killed above the
3771 // out_preserve_stack_slots for calls to C. Supports the var-args
3772 // backing area for register parms.
3773 //
3774 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3775
3776 // The after-PROLOG location of the return address. Location of
3777 // return address specifies a type (REG or STACK) and a number
3778 // representing the register number (i.e. - use a register name) or
3779 // stack slot.
3780 //
3781 // A: Link register is stored in stack slot ...
3782 // M: ... but it's in the caller's frame according to PPC-64 ABI.
3783 // J: Therefore, we make sure that the link register is also in R11_scratch1
3784 // at the end of the prolog.
3785 // B: We use R20, now.
3786 //return_addr(REG R20);
3787
3788 // G: After reading the comments made by all the luminaries on their
3789 // failure to tell the compiler where the return address really is,
3790 // I hardly dare to try myself. However, I'm convinced it's in slot
3791 // 4 what apparently works and saves us some spills.
3792 return_addr(STACK 4);
3793
3794 // Location of native (C/C++) and interpreter return values. This
3795 // is specified to be the same as Java. In the 32-bit VM, long
3796 // values are actually returned from native calls in O0:O1 and
3797 // returned to the interpreter in I0:I1. The copying to and from
3798 // the register pairs is done by the appropriate call and epilog
3799 // opcodes. This simplifies the register allocator.
3800 c_return_value %{
3801 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3802 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0),
3803 "only return normal values");
3804 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3805 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3806 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3807 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3808 %}
3809
3810 // Location of compiled Java return values. Same as C
3811 return_value %{
3812 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3813 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0),
3814 "only return normal values");
3815 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3816 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3817 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3818 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3819 %}
3820 %}
3821
3822
3823 //----------ATTRIBUTES---------------------------------------------------------
3824
3825 //----------Operand Attributes-------------------------------------------------
3826 op_attrib op_cost(1); // Required cost attribute.
3827
3828 //----------Instruction Attributes---------------------------------------------
3829
3830 // Cost attribute. required.
3831 ins_attrib ins_cost(DEFAULT_COST);
3832
3833 // Is this instruction a non-matching short branch variant of some
3834 // long branch? Not required.
3835 ins_attrib ins_short_branch(0);
3836
3837 ins_attrib ins_is_TrapBasedCheckNode(true);
3838
3839 // Number of constants.
3840 // This instruction uses the given number of constants
3841 // (optional attribute).
3842 // This is needed to determine in time whether the constant pool will
3843 // exceed 4000 entries. Before postalloc_expand the overall number of constants
3844 // is determined. It's also used to compute the constant pool size
3845 // in Output().
3846 ins_attrib ins_num_consts(0);
3847
3848 // Required alignment attribute (must be a power of 2) specifies the
3849 // alignment that some part of the instruction (not necessarily the
3850 // start) requires. If > 1, a compute_padding() function must be
3851 // provided for the instruction.
3852 ins_attrib ins_alignment(1);
3853
3854 // Enforce/prohibit rematerializations.
3855 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3856 // then rematerialization of that instruction is prohibited and the
3857 // instruction's value will be spilled if necessary.
3858 // Causes that MachNode::rematerialize() returns false.
3859 // - If an instruction is attributed with 'ins_should_rematerialize(true)'
3860 // then rematerialization should be enforced and a copy of the instruction
3861 // should be inserted if possible; rematerialization is not guaranteed.
3862 // Note: this may result in rematerializations in front of every use.
3863 // Causes that MachNode::rematerialize() can return true.
3864 // (optional attribute)
3865 ins_attrib ins_cannot_rematerialize(false);
3866 ins_attrib ins_should_rematerialize(false);
3867
3868 // Instruction has variable size depending on alignment.
3869 ins_attrib ins_variable_size_depending_on_alignment(false);
3870
3871 // Instruction is a nop.
3872 ins_attrib ins_is_nop(false);
3873
3874 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock).
3875 ins_attrib ins_use_mach_if_fast_lock_node(false);
3876
3877 // Field for the toc offset of a constant.
3878 //
3879 // This is needed if the toc offset is not encodable as an immediate in
3880 // the PPC load instruction. If so, the upper (hi) bits of the offset are
3881 // added to the toc, and from this a load with immediate is performed.
3882 // With postalloc expand, we get two nodes that require the same offset
3883 // but which don't know about each other. The offset is only known
3884 // when the constant is added to the constant pool during emitting.
3885 // It is generated in the 'hi'-node adding the upper bits, and saved
3886 // in this node. The 'lo'-node has a link to the 'hi'-node and reads
3887 // the offset from there when it gets encoded.
3888 ins_attrib ins_field_const_toc_offset(0);
3889 ins_attrib ins_field_const_toc_offset_hi_node(0);
3890
3891 // A field that can hold the instructions offset in the code buffer.
3892 // Set in the nodes emitter.
3893 ins_attrib ins_field_cbuf_insts_offset(-1);
3894
3895 // Fields for referencing a call's load-IC-node.
3896 // If the toc offset can not be encoded as an immediate in a load, we
3897 // use two nodes.
3898 ins_attrib ins_field_load_ic_hi_node(0);
3899 ins_attrib ins_field_load_ic_node(0);
3900
3901 //----------OPERANDS-----------------------------------------------------------
3902 // Operand definitions must precede instruction definitions for correct
3903 // parsing in the ADLC because operands constitute user defined types
3904 // which are used in instruction definitions.
3905 //
3906 // Formats are generated automatically for constants and base registers.
3907
3908 operand vecX() %{
3909 constraint(ALLOC_IN_RC(vs_reg));
3910 match(VecX);
3911
3912 format %{ %}
3913 interface(REG_INTER);
3914 %}
3915
3916 //----------Simple Operands----------------------------------------------------
3917 // Immediate Operands
3918
3919 // Integer Immediate: 32-bit
3920 operand immI() %{
3921 match(ConI);
3922 op_cost(40);
3923 format %{ %}
3924 interface(CONST_INTER);
3925 %}
3926
3927 operand immI8() %{
3928 predicate(Assembler::is_simm(n->get_int(), 8));
3929 op_cost(0);
3930 match(ConI);
3931 format %{ %}
3932 interface(CONST_INTER);
3933 %}
3934
3935 // Integer Immediate: 16-bit
3936 operand immI16() %{
3937 predicate(Assembler::is_simm(n->get_int(), 16));
3938 op_cost(0);
3939 match(ConI);
3940 format %{ %}
3941 interface(CONST_INTER);
3942 %}
3943
3944 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000.
3945 operand immIhi16() %{
3946 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0));
3947 match(ConI);
3948 op_cost(0);
3949 format %{ %}
3950 interface(CONST_INTER);
3951 %}
3952
3953 // Integer Immediate: 32-bit immediate for prefixed addi and load/store.
3954 operand immI32() %{
3955 predicate(PowerArchitecturePPC64 >= 10);
3956 op_cost(0);
3957 match(ConI);
3958 format %{ %}
3959 interface(CONST_INTER);
3960 %}
3961
3962 operand immInegpow2() %{
3963 predicate(is_power_of_2(-(juint)(n->get_int())));
3964 match(ConI);
3965 op_cost(0);
3966 format %{ %}
3967 interface(CONST_INTER);
3968 %}
3969
3970 operand immIpow2minus1() %{
3971 predicate(is_power_of_2((juint)(n->get_int()) + 1u));
3972 match(ConI);
3973 op_cost(0);
3974 format %{ %}
3975 interface(CONST_INTER);
3976 %}
3977
3978 operand immIpowerOf2() %{
3979 predicate(is_power_of_2((juint)(n->get_int())));
3980 match(ConI);
3981 op_cost(0);
3982 format %{ %}
3983 interface(CONST_INTER);
3984 %}
3985
3986 // Unsigned Integer Immediate: the values 0-31
3987 operand uimmI5() %{
3988 predicate(Assembler::is_uimm(n->get_int(), 5));
3989 match(ConI);
3990 op_cost(0);
3991 format %{ %}
3992 interface(CONST_INTER);
3993 %}
3994
3995 // Unsigned Integer Immediate: 6-bit
3996 operand uimmI6() %{
3997 predicate(Assembler::is_uimm(n->get_int(), 6));
3998 match(ConI);
3999 op_cost(0);
4000 format %{ %}
4001 interface(CONST_INTER);
4002 %}
4003
4004 // Unsigned Integer Immediate: 6-bit int, greater than 32
4005 operand uimmI6_ge32() %{
4006 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32);
4007 match(ConI);
4008 op_cost(0);
4009 format %{ %}
4010 interface(CONST_INTER);
4011 %}
4012
4013 // Unsigned Integer Immediate: 15-bit
4014 operand uimmI15() %{
4015 predicate(Assembler::is_uimm(n->get_int(), 15));
4016 match(ConI);
4017 op_cost(0);
4018 format %{ %}
4019 interface(CONST_INTER);
4020 %}
4021
4022 // Unsigned Integer Immediate: 16-bit
4023 operand uimmI16() %{
4024 predicate(Assembler::is_uimm(n->get_int(), 16));
4025 match(ConI);
4026 op_cost(0);
4027 format %{ %}
4028 interface(CONST_INTER);
4029 %}
4030
4031 // constant 'int 0'.
4032 operand immI_0() %{
4033 predicate(n->get_int() == 0);
4034 match(ConI);
4035 op_cost(0);
4036 format %{ %}
4037 interface(CONST_INTER);
4038 %}
4039
4040 // constant 'int 1'.
4041 operand immI_1() %{
4042 predicate(n->get_int() == 1);
4043 match(ConI);
4044 op_cost(0);
4045 format %{ %}
4046 interface(CONST_INTER);
4047 %}
4048
4049 // constant 'int -1'.
4050 operand immI_minus1() %{
4051 predicate(n->get_int() == -1);
4052 match(ConI);
4053 op_cost(0);
4054 format %{ %}
4055 interface(CONST_INTER);
4056 %}
4057
4058 // int value 16.
4059 operand immI_16() %{
4060 predicate(n->get_int() == 16);
4061 match(ConI);
4062 op_cost(0);
4063 format %{ %}
4064 interface(CONST_INTER);
4065 %}
4066
4067 // int value 24.
4068 operand immI_24() %{
4069 predicate(n->get_int() == 24);
4070 match(ConI);
4071 op_cost(0);
4072 format %{ %}
4073 interface(CONST_INTER);
4074 %}
4075
4076 // Compressed oops constants
4077 // Pointer Immediate
4078 operand immN() %{
4079 match(ConN);
4080
4081 op_cost(10);
4082 format %{ %}
4083 interface(CONST_INTER);
4084 %}
4085
4086 // NULL Pointer Immediate
4087 operand immN_0() %{
4088 predicate(n->get_narrowcon() == 0);
4089 match(ConN);
4090
4091 op_cost(0);
4092 format %{ %}
4093 interface(CONST_INTER);
4094 %}
4095
4096 // Compressed klass constants
4097 operand immNKlass() %{
4098 match(ConNKlass);
4099
4100 op_cost(0);
4101 format %{ %}
4102 interface(CONST_INTER);
4103 %}
4104
4105 // This operand can be used to avoid matching of an instruct
4106 // with chain rule.
4107 operand immNKlass_NM() %{
4108 match(ConNKlass);
4109 predicate(false);
4110 op_cost(0);
4111 format %{ %}
4112 interface(CONST_INTER);
4113 %}
4114
4115 // Pointer Immediate: 64-bit
4116 operand immP() %{
4117 match(ConP);
4118 op_cost(0);
4119 format %{ %}
4120 interface(CONST_INTER);
4121 %}
4122
4123 // Operand to avoid match of loadConP.
4124 // This operand can be used to avoid matching of an instruct
4125 // with chain rule.
4126 operand immP_NM() %{
4127 match(ConP);
4128 predicate(false);
4129 op_cost(0);
4130 format %{ %}
4131 interface(CONST_INTER);
4132 %}
4133
4134 // costant 'pointer 0'.
4135 operand immP_0() %{
4136 predicate(n->get_ptr() == 0);
4137 match(ConP);
4138 op_cost(0);
4139 format %{ %}
4140 interface(CONST_INTER);
4141 %}
4142
4143 // pointer 0x0 or 0x1
4144 operand immP_0or1() %{
4145 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
4146 match(ConP);
4147 op_cost(0);
4148 format %{ %}
4149 interface(CONST_INTER);
4150 %}
4151
4152 operand immL() %{
4153 match(ConL);
4154 op_cost(40);
4155 format %{ %}
4156 interface(CONST_INTER);
4157 %}
4158
4159 operand immLmax30() %{
4160 predicate((n->get_long() <= 30));
4161 match(ConL);
4162 op_cost(0);
4163 format %{ %}
4164 interface(CONST_INTER);
4165 %}
4166
4167 // Long Immediate: 16-bit
4168 operand immL16() %{
4169 predicate(Assembler::is_simm(n->get_long(), 16));
4170 match(ConL);
4171 op_cost(0);
4172 format %{ %}
4173 interface(CONST_INTER);
4174 %}
4175
4176 // Long Immediate: 16-bit, 4-aligned
4177 operand immL16Alg4() %{
4178 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
4179 match(ConL);
4180 op_cost(0);
4181 format %{ %}
4182 interface(CONST_INTER);
4183 %}
4184
4185 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
4186 operand immL32hi16() %{
4187 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L));
4188 match(ConL);
4189 op_cost(0);
4190 format %{ %}
4191 interface(CONST_INTER);
4192 %}
4193
4194 // Long Immediate: 32-bit
4195 operand immL32() %{
4196 predicate(Assembler::is_simm(n->get_long(), 32));
4197 match(ConL);
4198 op_cost(0);
4199 format %{ %}
4200 interface(CONST_INTER);
4201 %}
4202
4203 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store.
4204 operand immL34() %{
4205 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34));
4206 match(ConL);
4207 op_cost(0);
4208 format %{ %}
4209 interface(CONST_INTER);
4210 %}
4211
4212 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000.
4213 operand immLhighest16() %{
4214 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L);
4215 match(ConL);
4216 op_cost(0);
4217 format %{ %}
4218 interface(CONST_INTER);
4219 %}
4220
4221 operand immLnegpow2() %{
4222 predicate(is_power_of_2(-(julong)(n->get_long())));
4223 match(ConL);
4224 op_cost(0);
4225 format %{ %}
4226 interface(CONST_INTER);
4227 %}
4228
4229 operand immLpow2minus1() %{
4230 predicate(is_power_of_2((julong)(n->get_long()) + 1ull));
4231 match(ConL);
4232 op_cost(0);
4233 format %{ %}
4234 interface(CONST_INTER);
4235 %}
4236
4237 // constant 'long 0'.
4238 operand immL_0() %{
4239 predicate(n->get_long() == 0L);
4240 match(ConL);
4241 op_cost(0);
4242 format %{ %}
4243 interface(CONST_INTER);
4244 %}
4245
4246 // constat ' long -1'.
4247 operand immL_minus1() %{
4248 predicate(n->get_long() == -1L);
4249 match(ConL);
4250 op_cost(0);
4251 format %{ %}
4252 interface(CONST_INTER);
4253 %}
4254
4255 // Long Immediate: low 32-bit mask
4256 operand immL_32bits() %{
4257 predicate(n->get_long() == 0xFFFFFFFFL);
4258 match(ConL);
4259 op_cost(0);
4260 format %{ %}
4261 interface(CONST_INTER);
4262 %}
4263
4264 // Unsigned Long Immediate: 16-bit
4265 operand uimmL16() %{
4266 predicate(Assembler::is_uimm(n->get_long(), 16));
4267 match(ConL);
4268 op_cost(0);
4269 format %{ %}
4270 interface(CONST_INTER);
4271 %}
4272
4273 // Float Immediate
4274 operand immF() %{
4275 match(ConF);
4276 op_cost(40);
4277 format %{ %}
4278 interface(CONST_INTER);
4279 %}
4280
4281 // Float Immediate: +0.0f.
4282 operand immF_0() %{
4283 predicate(jint_cast(n->getf()) == 0);
4284 match(ConF);
4285
4286 op_cost(0);
4287 format %{ %}
4288 interface(CONST_INTER);
4289 %}
4290
4291 // Double Immediate
4292 operand immD() %{
4293 match(ConD);
4294 op_cost(40);
4295 format %{ %}
4296 interface(CONST_INTER);
4297 %}
4298
4299 // Double Immediate: +0.0d.
4300 operand immD_0() %{
4301 predicate(jlong_cast(n->getd()) == 0);
4302 match(ConD);
4303
4304 op_cost(0);
4305 format %{ %}
4306 interface(CONST_INTER);
4307 %}
4308
4309 // Integer Register Operands
4310 // Integer Destination Register
4311 // See definition of reg_class bits32_reg_rw.
4312 operand iRegIdst() %{
4313 constraint(ALLOC_IN_RC(bits32_reg_rw));
4314 match(RegI);
4315 match(rscratch1RegI);
4316 match(rscratch2RegI);
4317 match(rarg1RegI);
4318 match(rarg2RegI);
4319 match(rarg3RegI);
4320 match(rarg4RegI);
4321 format %{ %}
4322 interface(REG_INTER);
4323 %}
4324
4325 // Integer Source Register
4326 // See definition of reg_class bits32_reg_ro.
4327 operand iRegIsrc() %{
4328 constraint(ALLOC_IN_RC(bits32_reg_ro));
4329 match(RegI);
4330 match(rscratch1RegI);
4331 match(rscratch2RegI);
4332 match(rarg1RegI);
4333 match(rarg2RegI);
4334 match(rarg3RegI);
4335 match(rarg4RegI);
4336 format %{ %}
4337 interface(REG_INTER);
4338 %}
4339
4340 operand rscratch1RegI() %{
4341 constraint(ALLOC_IN_RC(rscratch1_bits32_reg));
4342 match(iRegIdst);
4343 format %{ %}
4344 interface(REG_INTER);
4345 %}
4346
4347 operand rscratch2RegI() %{
4348 constraint(ALLOC_IN_RC(rscratch2_bits32_reg));
4349 match(iRegIdst);
4350 format %{ %}
4351 interface(REG_INTER);
4352 %}
4353
4354 operand rarg1RegI() %{
4355 constraint(ALLOC_IN_RC(rarg1_bits32_reg));
4356 match(iRegIdst);
4357 format %{ %}
4358 interface(REG_INTER);
4359 %}
4360
4361 operand rarg2RegI() %{
4362 constraint(ALLOC_IN_RC(rarg2_bits32_reg));
4363 match(iRegIdst);
4364 format %{ %}
4365 interface(REG_INTER);
4366 %}
4367
4368 operand rarg3RegI() %{
4369 constraint(ALLOC_IN_RC(rarg3_bits32_reg));
4370 match(iRegIdst);
4371 format %{ %}
4372 interface(REG_INTER);
4373 %}
4374
4375 operand rarg4RegI() %{
4376 constraint(ALLOC_IN_RC(rarg4_bits32_reg));
4377 match(iRegIdst);
4378 format %{ %}
4379 interface(REG_INTER);
4380 %}
4381
4382 operand rarg1RegL() %{
4383 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4384 match(iRegLdst);
4385 format %{ %}
4386 interface(REG_INTER);
4387 %}
4388
4389 operand rarg2RegL() %{
4390 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4391 match(iRegLdst);
4392 format %{ %}
4393 interface(REG_INTER);
4394 %}
4395
4396 operand rarg3RegL() %{
4397 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4398 match(iRegLdst);
4399 format %{ %}
4400 interface(REG_INTER);
4401 %}
4402
4403 operand rarg4RegL() %{
4404 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4405 match(iRegLdst);
4406 format %{ %}
4407 interface(REG_INTER);
4408 %}
4409
4410 // Pointer Destination Register
4411 // See definition of reg_class bits64_reg_rw.
4412 operand iRegPdst() %{
4413 constraint(ALLOC_IN_RC(bits64_reg_rw));
4414 match(RegP);
4415 match(rscratch1RegP);
4416 match(rscratch2RegP);
4417 match(rarg1RegP);
4418 match(rarg2RegP);
4419 match(rarg3RegP);
4420 match(rarg4RegP);
4421 format %{ %}
4422 interface(REG_INTER);
4423 %}
4424
4425 // Pointer Destination Register
4426 // Operand not using r11 and r12 (killed in epilog).
4427 operand iRegPdstNoScratch() %{
4428 constraint(ALLOC_IN_RC(bits64_reg_leaf_call));
4429 match(RegP);
4430 match(rarg1RegP);
4431 match(rarg2RegP);
4432 match(rarg3RegP);
4433 match(rarg4RegP);
4434 format %{ %}
4435 interface(REG_INTER);
4436 %}
4437
4438 // Pointer Source Register
4439 // See definition of reg_class bits64_reg_ro.
4440 operand iRegPsrc() %{
4441 constraint(ALLOC_IN_RC(bits64_reg_ro));
4442 match(RegP);
4443 match(iRegPdst);
4444 match(rscratch1RegP);
4445 match(rscratch2RegP);
4446 match(rarg1RegP);
4447 match(rarg2RegP);
4448 match(rarg3RegP);
4449 match(rarg4RegP);
4450 match(threadRegP);
4451 format %{ %}
4452 interface(REG_INTER);
4453 %}
4454
4455 // Thread operand.
4456 operand threadRegP() %{
4457 constraint(ALLOC_IN_RC(thread_bits64_reg));
4458 match(iRegPdst);
4459 format %{ "R16" %}
4460 interface(REG_INTER);
4461 %}
4462
4463 operand rscratch1RegP() %{
4464 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4465 match(iRegPdst);
4466 format %{ "R11" %}
4467 interface(REG_INTER);
4468 %}
4469
4470 operand rscratch2RegP() %{
4471 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4472 match(iRegPdst);
4473 format %{ %}
4474 interface(REG_INTER);
4475 %}
4476
4477 operand rarg1RegP() %{
4478 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4479 match(iRegPdst);
4480 format %{ %}
4481 interface(REG_INTER);
4482 %}
4483
4484 operand rarg2RegP() %{
4485 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4486 match(iRegPdst);
4487 format %{ %}
4488 interface(REG_INTER);
4489 %}
4490
4491 operand rarg3RegP() %{
4492 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4493 match(iRegPdst);
4494 format %{ %}
4495 interface(REG_INTER);
4496 %}
4497
4498 operand rarg4RegP() %{
4499 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4500 match(iRegPdst);
4501 format %{ %}
4502 interface(REG_INTER);
4503 %}
4504
4505 operand iRegNsrc() %{
4506 constraint(ALLOC_IN_RC(bits32_reg_ro));
4507 match(RegN);
4508 match(iRegNdst);
4509
4510 format %{ %}
4511 interface(REG_INTER);
4512 %}
4513
4514 operand iRegNdst() %{
4515 constraint(ALLOC_IN_RC(bits32_reg_rw));
4516 match(RegN);
4517
4518 format %{ %}
4519 interface(REG_INTER);
4520 %}
4521
4522 // Long Destination Register
4523 // See definition of reg_class bits64_reg_rw.
4524 operand iRegLdst() %{
4525 constraint(ALLOC_IN_RC(bits64_reg_rw));
4526 match(RegL);
4527 match(rscratch1RegL);
4528 match(rscratch2RegL);
4529 format %{ %}
4530 interface(REG_INTER);
4531 %}
4532
4533 // Long Source Register
4534 // See definition of reg_class bits64_reg_ro.
4535 operand iRegLsrc() %{
4536 constraint(ALLOC_IN_RC(bits64_reg_ro));
4537 match(RegL);
4538 match(iRegLdst);
4539 match(rscratch1RegL);
4540 match(rscratch2RegL);
4541 format %{ %}
4542 interface(REG_INTER);
4543 %}
4544
4545 // Special operand for ConvL2I.
4546 operand iRegL2Isrc(iRegLsrc reg) %{
4547 constraint(ALLOC_IN_RC(bits64_reg_ro));
4548 match(ConvL2I reg);
4549 format %{ "ConvL2I($reg)" %}
4550 interface(REG_INTER)
4551 %}
4552
4553 operand rscratch1RegL() %{
4554 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4555 match(RegL);
4556 format %{ %}
4557 interface(REG_INTER);
4558 %}
4559
4560 operand rscratch2RegL() %{
4561 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4562 match(RegL);
4563 format %{ %}
4564 interface(REG_INTER);
4565 %}
4566
4567 // Condition Code Flag Registers
4568 operand flagsReg() %{
4569 constraint(ALLOC_IN_RC(int_flags));
4570 match(RegFlags);
4571 format %{ %}
4572 interface(REG_INTER);
4573 %}
4574
4575 operand flagsRegSrc() %{
4576 constraint(ALLOC_IN_RC(int_flags_ro));
4577 match(RegFlags);
4578 match(flagsReg);
4579 match(flagsRegCR0);
4580 format %{ %}
4581 interface(REG_INTER);
4582 %}
4583
4584 // Condition Code Flag Register CR0
4585 operand flagsRegCR0() %{
4586 constraint(ALLOC_IN_RC(int_flags_CR0));
4587 match(RegFlags);
4588 format %{ "CR0" %}
4589 interface(REG_INTER);
4590 %}
4591
4592 operand flagsRegCR1() %{
4593 constraint(ALLOC_IN_RC(int_flags_CR1));
4594 match(RegFlags);
4595 format %{ "CR1" %}
4596 interface(REG_INTER);
4597 %}
4598
4599 operand flagsRegCR6() %{
4600 constraint(ALLOC_IN_RC(int_flags_CR6));
4601 match(RegFlags);
4602 format %{ "CR6" %}
4603 interface(REG_INTER);
4604 %}
4605
4606 operand regCTR() %{
4607 constraint(ALLOC_IN_RC(ctr_reg));
4608 // RegFlags should work. Introducing a RegSpecial type would cause a
4609 // lot of changes.
4610 match(RegFlags);
4611 format %{"SR_CTR" %}
4612 interface(REG_INTER);
4613 %}
4614
4615 operand regD() %{
4616 constraint(ALLOC_IN_RC(dbl_reg));
4617 match(RegD);
4618 format %{ %}
4619 interface(REG_INTER);
4620 %}
4621
4622 operand regF() %{
4623 constraint(ALLOC_IN_RC(flt_reg));
4624 match(RegF);
4625 format %{ %}
4626 interface(REG_INTER);
4627 %}
4628
4629 // Special Registers
4630
4631 // Method Register
4632 operand inline_cache_regP(iRegPdst reg) %{
4633 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg
4634 match(reg);
4635 format %{ %}
4636 interface(REG_INTER);
4637 %}
4638
4639 // Operands to remove register moves in unscaled mode.
4640 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4641 operand iRegP2N(iRegPsrc reg) %{
4642 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0);
4643 constraint(ALLOC_IN_RC(bits64_reg_ro));
4644 match(EncodeP reg);
4645 format %{ "$reg" %}
4646 interface(REG_INTER)
4647 %}
4648
4649 operand iRegN2P(iRegNsrc reg) %{
4650 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4651 constraint(ALLOC_IN_RC(bits32_reg_ro));
4652 match(DecodeN reg);
4653 format %{ "$reg" %}
4654 interface(REG_INTER)
4655 %}
4656
4657 operand iRegN2P_klass(iRegNsrc reg) %{
4658 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0);
4659 constraint(ALLOC_IN_RC(bits32_reg_ro));
4660 match(DecodeNKlass reg);
4661 format %{ "$reg" %}
4662 interface(REG_INTER)
4663 %}
4664
4665 //----------Complex Operands---------------------------------------------------
4666 // Indirect Memory Reference
4667 operand indirect(iRegPsrc reg) %{
4668 constraint(ALLOC_IN_RC(bits64_reg_ro));
4669 match(reg);
4670 op_cost(100);
4671 format %{ "[$reg]" %}
4672 interface(MEMORY_INTER) %{
4673 base($reg);
4674 index(0x0);
4675 scale(0x0);
4676 disp(0x0);
4677 %}
4678 %}
4679
4680 // Indirect with Offset
4681 operand indOffset16(iRegPsrc reg, immL16 offset) %{
4682 constraint(ALLOC_IN_RC(bits64_reg_ro));
4683 match(AddP reg offset);
4684 op_cost(100);
4685 format %{ "[$reg + $offset]" %}
4686 interface(MEMORY_INTER) %{
4687 base($reg);
4688 index(0x0);
4689 scale(0x0);
4690 disp($offset);
4691 %}
4692 %}
4693
4694 // Indirect with 4-aligned Offset
4695 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{
4696 constraint(ALLOC_IN_RC(bits64_reg_ro));
4697 match(AddP reg offset);
4698 op_cost(100);
4699 format %{ "[$reg + $offset]" %}
4700 interface(MEMORY_INTER) %{
4701 base($reg);
4702 index(0x0);
4703 scale(0x0);
4704 disp($offset);
4705 %}
4706 %}
4707
4708 //----------Complex Operands for Compressed OOPs-------------------------------
4709 // Compressed OOPs with narrow_oop_shift == 0.
4710
4711 // Indirect Memory Reference, compressed OOP
4712 operand indirectNarrow(iRegNsrc reg) %{
4713 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4714 constraint(ALLOC_IN_RC(bits64_reg_ro));
4715 match(DecodeN reg);
4716 op_cost(100);
4717 format %{ "[$reg]" %}
4718 interface(MEMORY_INTER) %{
4719 base($reg);
4720 index(0x0);
4721 scale(0x0);
4722 disp(0x0);
4723 %}
4724 %}
4725
4726 operand indirectNarrow_klass(iRegNsrc reg) %{
4727 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0);
4728 constraint(ALLOC_IN_RC(bits64_reg_ro));
4729 match(DecodeNKlass reg);
4730 op_cost(100);
4731 format %{ "[$reg]" %}
4732 interface(MEMORY_INTER) %{
4733 base($reg);
4734 index(0x0);
4735 scale(0x0);
4736 disp(0x0);
4737 %}
4738 %}
4739
4740 // Indirect with Offset, compressed OOP
4741 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4742 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4743 constraint(ALLOC_IN_RC(bits64_reg_ro));
4744 match(AddP (DecodeN reg) offset);
4745 op_cost(100);
4746 format %{ "[$reg + $offset]" %}
4747 interface(MEMORY_INTER) %{
4748 base($reg);
4749 index(0x0);
4750 scale(0x0);
4751 disp($offset);
4752 %}
4753 %}
4754
4755 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4756 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0);
4757 constraint(ALLOC_IN_RC(bits64_reg_ro));
4758 match(AddP (DecodeNKlass reg) offset);
4759 op_cost(100);
4760 format %{ "[$reg + $offset]" %}
4761 interface(MEMORY_INTER) %{
4762 base($reg);
4763 index(0x0);
4764 scale(0x0);
4765 disp($offset);
4766 %}
4767 %}
4768
4769 // Indirect with 4-aligned Offset, compressed OOP
4770 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4771 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4772 constraint(ALLOC_IN_RC(bits64_reg_ro));
4773 match(AddP (DecodeN reg) offset);
4774 op_cost(100);
4775 format %{ "[$reg + $offset]" %}
4776 interface(MEMORY_INTER) %{
4777 base($reg);
4778 index(0x0);
4779 scale(0x0);
4780 disp($offset);
4781 %}
4782 %}
4783
4784 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4785 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0);
4786 constraint(ALLOC_IN_RC(bits64_reg_ro));
4787 match(AddP (DecodeNKlass reg) offset);
4788 op_cost(100);
4789 format %{ "[$reg + $offset]" %}
4790 interface(MEMORY_INTER) %{
4791 base($reg);
4792 index(0x0);
4793 scale(0x0);
4794 disp($offset);
4795 %}
4796 %}
4797
4798 //----------Special Memory Operands--------------------------------------------
4799 // Stack Slot Operand
4800 //
4801 // This operand is used for loading and storing temporary values on
4802 // the stack where a match requires a value to flow through memory.
4803 operand stackSlotI(sRegI reg) %{
4804 constraint(ALLOC_IN_RC(stack_slots));
4805 op_cost(100);
4806 //match(RegI);
4807 format %{ "[sp+$reg]" %}
4808 interface(MEMORY_INTER) %{
4809 base(0x1); // R1_SP
4810 index(0x0);
4811 scale(0x0);
4812 disp($reg); // Stack Offset
4813 %}
4814 %}
4815
4816 operand stackSlotL(sRegL reg) %{
4817 constraint(ALLOC_IN_RC(stack_slots));
4818 op_cost(100);
4819 //match(RegL);
4820 format %{ "[sp+$reg]" %}
4821 interface(MEMORY_INTER) %{
4822 base(0x1); // R1_SP
4823 index(0x0);
4824 scale(0x0);
4825 disp($reg); // Stack Offset
4826 %}
4827 %}
4828
4829 operand stackSlotP(sRegP reg) %{
4830 constraint(ALLOC_IN_RC(stack_slots));
4831 op_cost(100);
4832 //match(RegP);
4833 format %{ "[sp+$reg]" %}
4834 interface(MEMORY_INTER) %{
4835 base(0x1); // R1_SP
4836 index(0x0);
4837 scale(0x0);
4838 disp($reg); // Stack Offset
4839 %}
4840 %}
4841
4842 operand stackSlotF(sRegF reg) %{
4843 constraint(ALLOC_IN_RC(stack_slots));
4844 op_cost(100);
4845 //match(RegF);
4846 format %{ "[sp+$reg]" %}
4847 interface(MEMORY_INTER) %{
4848 base(0x1); // R1_SP
4849 index(0x0);
4850 scale(0x0);
4851 disp($reg); // Stack Offset
4852 %}
4853 %}
4854
4855 operand stackSlotD(sRegD reg) %{
4856 constraint(ALLOC_IN_RC(stack_slots));
4857 op_cost(100);
4858 //match(RegD);
4859 format %{ "[sp+$reg]" %}
4860 interface(MEMORY_INTER) %{
4861 base(0x1); // R1_SP
4862 index(0x0);
4863 scale(0x0);
4864 disp($reg); // Stack Offset
4865 %}
4866 %}
4867
4868 // Operands for expressing Control Flow
4869 // NOTE: Label is a predefined operand which should not be redefined in
4870 // the AD file. It is generically handled within the ADLC.
4871
4872 //----------Conditional Branch Operands----------------------------------------
4873 // Comparison Op
4874 //
4875 // This is the operation of the comparison, and is limited to the
4876 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE
4877 // (!=).
4878 //
4879 // Other attributes of the comparison, such as unsignedness, are specified
4880 // by the comparison instruction that sets a condition code flags register.
4881 // That result is represented by a flags operand whose subtype is appropriate
4882 // to the unsignedness (etc.) of the comparison.
4883 //
4884 // Later, the instruction which matches both the Comparison Op (a Bool) and
4885 // the flags (produced by the Cmp) specifies the coding of the comparison op
4886 // by matching a specific subtype of Bool operand below.
4887
4888 // When used for floating point comparisons: unordered same as less.
4889 operand cmpOp() %{
4890 match(Bool);
4891 format %{ "" %}
4892 interface(COND_INTER) %{
4893 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'.
4894 // BO & BI
4895 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4896 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4897 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4898 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4899 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4900 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4901 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4902 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4903 %}
4904 %}
4905
4906 //----------OPERAND CLASSES----------------------------------------------------
4907 // Operand Classes are groups of operands that are used to simplify
4908 // instruction definitions by not requiring the AD writer to specify
4909 // seperate instructions for every form of operand when the
4910 // instruction accepts multiple operand types with the same basic
4911 // encoding and format. The classic case of this is memory operands.
4912 // Indirect is not included since its use is limited to Compare & Swap.
4913
4914 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4915 // Memory operand where offsets are 4-aligned. Required for ld, std.
4916 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4917 opclass indirectMemory(indirect, indirectNarrow);
4918
4919 // Special opclass for I and ConvL2I.
4920 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4921
4922 // Operand classes to match encode and decode. iRegN_P2N is only used
4923 // for storeN. I have never seen an encode node elsewhere.
4924 opclass iRegN_P2N(iRegNsrc, iRegP2N);
4925 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4926
4927 //----------PIPELINE-----------------------------------------------------------
4928
4929 pipeline %{
4930
4931 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4932 // J. Res. & Dev., No. 1, Jan. 2002.
4933
4934 //----------ATTRIBUTES---------------------------------------------------------
4935 attributes %{
4936
4937 // Power4 instructions are of fixed length.
4938 fixed_size_instructions;
4939
4940 // TODO: if `bundle' means number of instructions fetched
4941 // per cycle, this is 8. If `bundle' means Power4 `group', that is
4942 // max instructions issued per cycle, this is 5.
4943 max_instructions_per_bundle = 8;
4944
4945 // A Power4 instruction is 4 bytes long.
4946 instruction_unit_size = 4;
4947
4948 // The Power4 processor fetches 64 bytes...
4949 instruction_fetch_unit_size = 64;
4950
4951 // ...in one line
4952 instruction_fetch_units = 1
4953
4954 // Unused, list one so that array generated by adlc is not empty.
4955 // Aix compiler chokes if _nop_count = 0.
4956 nops(fxNop);
4957 %}
4958
4959 //----------RESOURCES----------------------------------------------------------
4960 // Resources are the functional units available to the machine
4961 resources(
4962 PPC_BR, // branch unit
4963 PPC_CR, // condition unit
4964 PPC_FX1, // integer arithmetic unit 1
4965 PPC_FX2, // integer arithmetic unit 2
4966 PPC_LDST1, // load/store unit 1
4967 PPC_LDST2, // load/store unit 2
4968 PPC_FP1, // float arithmetic unit 1
4969 PPC_FP2, // float arithmetic unit 2
4970 PPC_LDST = PPC_LDST1 | PPC_LDST2,
4971 PPC_FX = PPC_FX1 | PPC_FX2,
4972 PPC_FP = PPC_FP1 | PPC_FP2
4973 );
4974
4975 //----------PIPELINE DESCRIPTION-----------------------------------------------
4976 // Pipeline Description specifies the stages in the machine's pipeline
4977 pipe_desc(
4978 // Power4 longest pipeline path
4979 PPC_IF, // instruction fetch
4980 PPC_IC,
4981 //PPC_BP, // branch prediction
4982 PPC_D0, // decode
4983 PPC_D1, // decode
4984 PPC_D2, // decode
4985 PPC_D3, // decode
4986 PPC_Xfer1,
4987 PPC_GD, // group definition
4988 PPC_MP, // map
4989 PPC_ISS, // issue
4990 PPC_RF, // resource fetch
4991 PPC_EX1, // execute (all units)
4992 PPC_EX2, // execute (FP, LDST)
4993 PPC_EX3, // execute (FP, LDST)
4994 PPC_EX4, // execute (FP)
4995 PPC_EX5, // execute (FP)
4996 PPC_EX6, // execute (FP)
4997 PPC_WB, // write back
4998 PPC_Xfer2,
4999 PPC_CP
5000 );
5001
5002 //----------PIPELINE CLASSES---------------------------------------------------
5003 // Pipeline Classes describe the stages in which input and output are
5004 // referenced by the hardware pipeline.
5005
5006 // Simple pipeline classes.
5007
5008 // Default pipeline class.
5009 pipe_class pipe_class_default() %{
5010 single_instruction;
5011 fixed_latency(2);
5012 %}
5013
5014 // Pipeline class for empty instructions.
5015 pipe_class pipe_class_empty() %{
5016 single_instruction;
5017 fixed_latency(0);
5018 %}
5019
5020 // Pipeline class for compares.
5021 pipe_class pipe_class_compare() %{
5022 single_instruction;
5023 fixed_latency(16);
5024 %}
5025
5026 // Pipeline class for traps.
5027 pipe_class pipe_class_trap() %{
5028 single_instruction;
5029 fixed_latency(100);
5030 %}
5031
5032 // Pipeline class for memory operations.
5033 pipe_class pipe_class_memory() %{
5034 single_instruction;
5035 fixed_latency(16);
5036 %}
5037
5038 // Pipeline class for call.
5039 pipe_class pipe_class_call() %{
5040 single_instruction;
5041 fixed_latency(100);
5042 %}
5043
5044 // Define the class for the Nop node.
5045 define %{
5046 MachNop = pipe_class_default;
5047 %}
5048
5049 %}
5050
5051 //----------INSTRUCTIONS-------------------------------------------------------
5052
5053 // Naming of instructions:
5054 // opA_operB / opA_operB_operC:
5055 // Operation 'op' with one or two source operands 'oper'. Result
5056 // type is A, source operand types are B and C.
5057 // Iff A == B == C, B and C are left out.
5058 //
5059 // The instructions are ordered according to the following scheme:
5060 // - loads
5061 // - load constants
5062 // - prefetch
5063 // - store
5064 // - encode/decode
5065 // - membar
5066 // - conditional moves
5067 // - compare & swap
5068 // - arithmetic and logic operations
5069 // * int: Add, Sub, Mul, Div, Mod
5070 // * int: lShift, arShift, urShift, rot
5071 // * float: Add, Sub, Mul, Div
5072 // * and, or, xor ...
5073 // - register moves: float <-> int, reg <-> stack, repl
5074 // - cast (high level type cast, XtoP, castPP, castII, not_null etc.
5075 // - conv (low level type cast requiring bit changes (sign extend etc)
5076 // - compares, range & zero checks.
5077 // - branches
5078 // - complex operations, intrinsics, min, max, replicate
5079 // - lock
5080 // - Calls
5081 //
5082 // If there are similar instructions with different types they are sorted:
5083 // int before float
5084 // small before big
5085 // signed before unsigned
5086 // e.g., loadS before loadUS before loadI before loadF.
5087
5088
5089 //----------Load/Store Instructions--------------------------------------------
5090
5091 //----------Load Instructions--------------------------------------------------
5092
5093 // Converts byte to int.
5094 // As convB2I_reg, but without match rule. The match rule of convB2I_reg
5095 // reuses the 'amount' operand, but adlc expects that operand specification
5096 // and operands in match rule are equivalent.
5097 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
5098 effect(DEF dst, USE src);
5099 format %{ "EXTSB $dst, $src \t// byte->int" %}
5100 size(4);
5101 ins_encode %{
5102 __ extsb($dst$$Register, $src$$Register);
5103 %}
5104 ins_pipe(pipe_class_default);
5105 %}
5106
5107 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{
5108 // match-rule, false predicate
5109 match(Set dst (LoadB mem));
5110 predicate(false);
5111
5112 format %{ "LBZ $dst, $mem" %}
5113 size(4);
5114 ins_encode( enc_lbz(dst, mem) );
5115 ins_pipe(pipe_class_memory);
5116 %}
5117
5118 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{
5119 // match-rule, false predicate
5120 match(Set dst (LoadB mem));
5121 predicate(false);
5122
5123 format %{ "LBZ $dst, $mem\n\t"
5124 "TWI $dst\n\t"
5125 "ISYNC" %}
5126 size(12);
5127 ins_encode( enc_lbz_ac(dst, mem) );
5128 ins_pipe(pipe_class_memory);
5129 %}
5130
5131 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
5132 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{
5133 match(Set dst (LoadB mem));
5134 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5135 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5136 expand %{
5137 iRegIdst tmp;
5138 loadUB_indirect(tmp, mem);
5139 convB2I_reg_2(dst, tmp);
5140 %}
5141 %}
5142
5143 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{
5144 match(Set dst (LoadB mem));
5145 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
5146 expand %{
5147 iRegIdst tmp;
5148 loadUB_indirect_ac(tmp, mem);
5149 convB2I_reg_2(dst, tmp);
5150 %}
5151 %}
5152
5153 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{
5154 // match-rule, false predicate
5155 match(Set dst (LoadB mem));
5156 predicate(false);
5157
5158 format %{ "LBZ $dst, $mem" %}
5159 size(4);
5160 ins_encode( enc_lbz(dst, mem) );
5161 ins_pipe(pipe_class_memory);
5162 %}
5163
5164 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{
5165 // match-rule, false predicate
5166 match(Set dst (LoadB mem));
5167 predicate(false);
5168
5169 format %{ "LBZ $dst, $mem\n\t"
5170 "TWI $dst\n\t"
5171 "ISYNC" %}
5172 size(12);
5173 ins_encode( enc_lbz_ac(dst, mem) );
5174 ins_pipe(pipe_class_memory);
5175 %}
5176
5177 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
5178 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{
5179 match(Set dst (LoadB mem));
5180 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5181 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5182
5183 expand %{
5184 iRegIdst tmp;
5185 loadUB_indOffset16(tmp, mem);
5186 convB2I_reg_2(dst, tmp);
5187 %}
5188 %}
5189
5190 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{
5191 match(Set dst (LoadB mem));
5192 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
5193
5194 expand %{
5195 iRegIdst tmp;
5196 loadUB_indOffset16_ac(tmp, mem);
5197 convB2I_reg_2(dst, tmp);
5198 %}
5199 %}
5200
5201 // Load Unsigned Byte (8bit UNsigned) into an int reg.
5202 instruct loadUB(iRegIdst dst, memory mem) %{
5203 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5204 match(Set dst (LoadUB mem));
5205 ins_cost(MEMORY_REF_COST);
5206
5207 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %}
5208 size(4);
5209 ins_encode( enc_lbz(dst, mem) );
5210 ins_pipe(pipe_class_memory);
5211 %}
5212
5213 // Load Unsigned Byte (8bit UNsigned) acquire.
5214 instruct loadUB_ac(iRegIdst dst, memory mem) %{
5215 match(Set dst (LoadUB mem));
5216 ins_cost(3*MEMORY_REF_COST);
5217
5218 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t"
5219 "TWI $dst\n\t"
5220 "ISYNC" %}
5221 size(12);
5222 ins_encode( enc_lbz_ac(dst, mem) );
5223 ins_pipe(pipe_class_memory);
5224 %}
5225
5226 // Load Unsigned Byte (8bit UNsigned) into a Long Register.
5227 instruct loadUB2L(iRegLdst dst, memory mem) %{
5228 match(Set dst (ConvI2L (LoadUB mem)));
5229 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5230 ins_cost(MEMORY_REF_COST);
5231
5232 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %}
5233 size(4);
5234 ins_encode( enc_lbz(dst, mem) );
5235 ins_pipe(pipe_class_memory);
5236 %}
5237
5238 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{
5239 match(Set dst (ConvI2L (LoadUB mem)));
5240 ins_cost(3*MEMORY_REF_COST);
5241
5242 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t"
5243 "TWI $dst\n\t"
5244 "ISYNC" %}
5245 size(12);
5246 ins_encode( enc_lbz_ac(dst, mem) );
5247 ins_pipe(pipe_class_memory);
5248 %}
5249
5250 // Load Short (16bit signed)
5251 instruct loadS(iRegIdst dst, memory mem) %{
5252 match(Set dst (LoadS mem));
5253 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5254 ins_cost(MEMORY_REF_COST);
5255
5256 format %{ "LHA $dst, $mem" %}
5257 size(4);
5258 ins_encode %{
5259 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5260 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
5261 %}
5262 ins_pipe(pipe_class_memory);
5263 %}
5264
5265 // Load Short (16bit signed) acquire.
5266 instruct loadS_ac(iRegIdst dst, memory mem) %{
5267 match(Set dst (LoadS mem));
5268 ins_cost(3*MEMORY_REF_COST);
5269
5270 format %{ "LHA $dst, $mem\t acquire\n\t"
5271 "TWI $dst\n\t"
5272 "ISYNC" %}
5273 size(12);
5274 ins_encode %{
5275 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5276 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
5277 __ twi_0($dst$$Register);
5278 __ isync();
5279 %}
5280 ins_pipe(pipe_class_memory);
5281 %}
5282
5283 // Load Char (16bit unsigned)
5284 instruct loadUS(iRegIdst dst, memory mem) %{
5285 match(Set dst (LoadUS mem));
5286 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5287 ins_cost(MEMORY_REF_COST);
5288
5289 format %{ "LHZ $dst, $mem" %}
5290 size(4);
5291 ins_encode( enc_lhz(dst, mem) );
5292 ins_pipe(pipe_class_memory);
5293 %}
5294
5295 // Load Char (16bit unsigned) acquire.
5296 instruct loadUS_ac(iRegIdst dst, memory mem) %{
5297 match(Set dst (LoadUS mem));
5298 ins_cost(3*MEMORY_REF_COST);
5299
5300 format %{ "LHZ $dst, $mem \t// acquire\n\t"
5301 "TWI $dst\n\t"
5302 "ISYNC" %}
5303 size(12);
5304 ins_encode( enc_lhz_ac(dst, mem) );
5305 ins_pipe(pipe_class_memory);
5306 %}
5307
5308 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register.
5309 instruct loadUS2L(iRegLdst dst, memory mem) %{
5310 match(Set dst (ConvI2L (LoadUS mem)));
5311 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5312 ins_cost(MEMORY_REF_COST);
5313
5314 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %}
5315 size(4);
5316 ins_encode( enc_lhz(dst, mem) );
5317 ins_pipe(pipe_class_memory);
5318 %}
5319
5320 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire.
5321 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{
5322 match(Set dst (ConvI2L (LoadUS mem)));
5323 ins_cost(3*MEMORY_REF_COST);
5324
5325 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t"
5326 "TWI $dst\n\t"
5327 "ISYNC" %}
5328 size(12);
5329 ins_encode( enc_lhz_ac(dst, mem) );
5330 ins_pipe(pipe_class_memory);
5331 %}
5332
5333 // Load Integer.
5334 instruct loadI(iRegIdst dst, memory mem) %{
5335 match(Set dst (LoadI mem));
5336 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5337 ins_cost(MEMORY_REF_COST);
5338
5339 format %{ "LWZ $dst, $mem" %}
5340 size(4);
5341 ins_encode( enc_lwz(dst, mem) );
5342 ins_pipe(pipe_class_memory);
5343 %}
5344
5345 // Load Integer acquire.
5346 instruct loadI_ac(iRegIdst dst, memory mem) %{
5347 match(Set dst (LoadI mem));
5348 ins_cost(3*MEMORY_REF_COST);
5349
5350 format %{ "LWZ $dst, $mem \t// load acquire\n\t"
5351 "TWI $dst\n\t"
5352 "ISYNC" %}
5353 size(12);
5354 ins_encode( enc_lwz_ac(dst, mem) );
5355 ins_pipe(pipe_class_memory);
5356 %}
5357
5358 // Match loading integer and casting it to unsigned int in
5359 // long register.
5360 // LoadI + ConvI2L + AndL 0xffffffff.
5361 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
5362 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5363 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered());
5364 ins_cost(MEMORY_REF_COST);
5365
5366 format %{ "LWZ $dst, $mem \t// zero-extend to long" %}
5367 size(4);
5368 ins_encode( enc_lwz(dst, mem) );
5369 ins_pipe(pipe_class_memory);
5370 %}
5371
5372 // Match loading integer and casting it to long.
5373 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
5374 match(Set dst (ConvI2L (LoadI mem)));
5375 predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5376 ins_cost(MEMORY_REF_COST);
5377
5378 format %{ "LWA $dst, $mem \t// loadI2L" %}
5379 size(4);
5380 ins_encode %{
5381 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5382 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5383 %}
5384 ins_pipe(pipe_class_memory);
5385 %}
5386
5387 // Match loading integer and casting it to long - acquire.
5388 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
5389 match(Set dst (ConvI2L (LoadI mem)));
5390 ins_cost(3*MEMORY_REF_COST);
5391
5392 format %{ "LWA $dst, $mem \t// loadI2L acquire"
5393 "TWI $dst\n\t"
5394 "ISYNC" %}
5395 size(12);
5396 ins_encode %{
5397 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5398 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5399 __ twi_0($dst$$Register);
5400 __ isync();
5401 %}
5402 ins_pipe(pipe_class_memory);
5403 %}
5404
5405 // Load Long - aligned
5406 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{
5407 match(Set dst (LoadL mem));
5408 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5409 ins_cost(MEMORY_REF_COST);
5410
5411 format %{ "LD $dst, $mem \t// long" %}
5412 size(4);
5413 ins_encode( enc_ld(dst, mem) );
5414 ins_pipe(pipe_class_memory);
5415 %}
5416
5417 // Load Long - aligned acquire.
5418 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{
5419 match(Set dst (LoadL mem));
5420 ins_cost(3*MEMORY_REF_COST);
5421
5422 format %{ "LD $dst, $mem \t// long acquire\n\t"
5423 "TWI $dst\n\t"
5424 "ISYNC" %}
5425 size(12);
5426 ins_encode( enc_ld_ac(dst, mem) );
5427 ins_pipe(pipe_class_memory);
5428 %}
5429
5430 // Load Long - UNaligned
5431 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{
5432 match(Set dst (LoadL_unaligned mem));
5433 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5434 ins_cost(MEMORY_REF_COST);
5435
5436 format %{ "LD $dst, $mem \t// unaligned long" %}
5437 size(4);
5438 ins_encode( enc_ld(dst, mem) );
5439 ins_pipe(pipe_class_memory);
5440 %}
5441
5442 // Load nodes for superwords
5443
5444 // Load Aligned Packed Byte
5445 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{
5446 predicate(n->as_LoadVector()->memory_size() == 8);
5447 match(Set dst (LoadVector mem));
5448 ins_cost(MEMORY_REF_COST);
5449
5450 format %{ "LD $dst, $mem \t// load 8-byte Vector" %}
5451 size(4);
5452 ins_encode( enc_ld(dst, mem) );
5453 ins_pipe(pipe_class_memory);
5454 %}
5455
5456 // Load Aligned Packed Byte
5457 instruct loadV16(vecX dst, indirect mem) %{
5458 predicate(n->as_LoadVector()->memory_size() == 16);
5459 match(Set dst (LoadVector mem));
5460 ins_cost(MEMORY_REF_COST);
5461
5462 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %}
5463 size(4);
5464 ins_encode %{
5465 __ lxvd2x($dst$$VectorSRegister, $mem$$Register);
5466 %}
5467 ins_pipe(pipe_class_default);
5468 %}
5469
5470 // Load Range, range = array length (=jint)
5471 instruct loadRange(iRegIdst dst, memory mem) %{
5472 match(Set dst (LoadRange mem));
5473 ins_cost(MEMORY_REF_COST);
5474
5475 format %{ "LWZ $dst, $mem \t// range" %}
5476 size(4);
5477 ins_encode( enc_lwz(dst, mem) );
5478 ins_pipe(pipe_class_memory);
5479 %}
5480
5481 // Load Compressed Pointer
5482 instruct loadN(iRegNdst dst, memory mem) %{
5483 match(Set dst (LoadN mem));
5484 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5485 ins_cost(MEMORY_REF_COST);
5486
5487 format %{ "LWZ $dst, $mem \t// load compressed ptr" %}
5488 size(4);
5489 ins_encode( enc_lwz(dst, mem) );
5490 ins_pipe(pipe_class_memory);
5491 %}
5492
5493 // Load Compressed Pointer acquire.
5494 instruct loadN_ac(iRegNdst dst, memory mem) %{
5495 match(Set dst (LoadN mem));
5496 ins_cost(3*MEMORY_REF_COST);
5497
5498 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5499 "TWI $dst\n\t"
5500 "ISYNC" %}
5501 size(12);
5502 ins_encode( enc_lwz_ac(dst, mem) );
5503 ins_pipe(pipe_class_memory);
5504 %}
5505
5506 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5507 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5508 match(Set dst (DecodeN (LoadN mem)));
5509 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0);
5510 ins_cost(MEMORY_REF_COST);
5511
5512 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5513 size(4);
5514 ins_encode( enc_lwz(dst, mem) );
5515 ins_pipe(pipe_class_memory);
5516 %}
5517
5518 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5519 match(Set dst (DecodeNKlass (LoadNKlass mem)));
5520 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0 &&
5521 _kids[0]->_leaf->as_Load()->is_unordered());
5522 ins_cost(MEMORY_REF_COST);
5523
5524 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5525 size(4);
5526 ins_encode( enc_lwz(dst, mem) );
5527 ins_pipe(pipe_class_memory);
5528 %}
5529
5530 // Load Pointer
5531 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5532 match(Set dst (LoadP mem));
5533 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5534 ins_cost(MEMORY_REF_COST);
5535
5536 format %{ "LD $dst, $mem \t// ptr" %}
5537 size(4);
5538 ins_encode( enc_ld(dst, mem) );
5539 ins_pipe(pipe_class_memory);
5540 %}
5541
5542 // Load Pointer acquire.
5543 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5544 match(Set dst (LoadP mem));
5545 ins_cost(3*MEMORY_REF_COST);
5546
5547 predicate(n->as_Load()->barrier_data() == 0);
5548
5549 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5550 "TWI $dst\n\t"
5551 "ISYNC" %}
5552 size(12);
5553 ins_encode( enc_ld_ac(dst, mem) );
5554 ins_pipe(pipe_class_memory);
5555 %}
5556
5557 // LoadP + CastP2L
5558 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
5559 match(Set dst (CastP2X (LoadP mem)));
5560 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5561 ins_cost(MEMORY_REF_COST);
5562
5563 format %{ "LD $dst, $mem \t// ptr + p2x" %}
5564 size(4);
5565 ins_encode( enc_ld(dst, mem) );
5566 ins_pipe(pipe_class_memory);
5567 %}
5568
5569 // Load compressed klass pointer.
5570 instruct loadNKlass(iRegNdst dst, memory mem) %{
5571 match(Set dst (LoadNKlass mem));
5572 ins_cost(MEMORY_REF_COST);
5573
5574 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %}
5575 size(4);
5576 ins_encode( enc_lwz(dst, mem) );
5577 ins_pipe(pipe_class_memory);
5578 %}
5579
5580 // Load Klass Pointer
5581 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
5582 match(Set dst (LoadKlass mem));
5583 ins_cost(MEMORY_REF_COST);
5584
5585 format %{ "LD $dst, $mem \t// klass ptr" %}
5586 size(4);
5587 ins_encode( enc_ld(dst, mem) );
5588 ins_pipe(pipe_class_memory);
5589 %}
5590
5591 // Load Float
5592 instruct loadF(regF dst, memory mem) %{
5593 match(Set dst (LoadF mem));
5594 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5595 ins_cost(MEMORY_REF_COST);
5596
5597 format %{ "LFS $dst, $mem" %}
5598 size(4);
5599 ins_encode %{
5600 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5601 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5602 %}
5603 ins_pipe(pipe_class_memory);
5604 %}
5605
5606 // Load Float acquire.
5607 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5608 match(Set dst (LoadF mem));
5609 effect(TEMP cr0);
5610 ins_cost(3*MEMORY_REF_COST);
5611
5612 format %{ "LFS $dst, $mem \t// acquire\n\t"
5613 "FCMPU cr0, $dst, $dst\n\t"
5614 "BNE cr0, next\n"
5615 "next:\n\t"
5616 "ISYNC" %}
5617 size(16);
5618 ins_encode %{
5619 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5620 Label next;
5621 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5622 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister);
5623 __ bne(CCR0, next);
5624 __ bind(next);
5625 __ isync();
5626 %}
5627 ins_pipe(pipe_class_memory);
5628 %}
5629
5630 // Load Double - aligned
5631 instruct loadD(regD dst, memory mem) %{
5632 match(Set dst (LoadD mem));
5633 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5634 ins_cost(MEMORY_REF_COST);
5635
5636 format %{ "LFD $dst, $mem" %}
5637 size(4);
5638 ins_encode( enc_lfd(dst, mem) );
5639 ins_pipe(pipe_class_memory);
5640 %}
5641
5642 // Load Double - aligned acquire.
5643 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5644 match(Set dst (LoadD mem));
5645 effect(TEMP cr0);
5646 ins_cost(3*MEMORY_REF_COST);
5647
5648 format %{ "LFD $dst, $mem \t// acquire\n\t"
5649 "FCMPU cr0, $dst, $dst\n\t"
5650 "BNE cr0, next\n"
5651 "next:\n\t"
5652 "ISYNC" %}
5653 size(16);
5654 ins_encode %{
5655 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5656 Label next;
5657 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5658 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister);
5659 __ bne(CCR0, next);
5660 __ bind(next);
5661 __ isync();
5662 %}
5663 ins_pipe(pipe_class_memory);
5664 %}
5665
5666 // Load Double - UNaligned
5667 instruct loadD_unaligned(regD dst, memory mem) %{
5668 match(Set dst (LoadD_unaligned mem));
5669 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5670 ins_cost(MEMORY_REF_COST);
5671
5672 format %{ "LFD $dst, $mem" %}
5673 size(4);
5674 ins_encode( enc_lfd(dst, mem) );
5675 ins_pipe(pipe_class_memory);
5676 %}
5677
5678 //----------Constants--------------------------------------------------------
5679
5680 // Load MachConstantTableBase: add hi offset to global toc.
5681 // TODO: Handle hidden register r29 in bundler!
5682 instruct loadToc_hi(iRegLdst dst) %{
5683 effect(DEF dst);
5684 ins_cost(DEFAULT_COST);
5685
5686 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %}
5687 size(4);
5688 ins_encode %{
5689 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
5690 %}
5691 ins_pipe(pipe_class_default);
5692 %}
5693
5694 // Load MachConstantTableBase: add lo offset to global toc.
5695 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
5696 effect(DEF dst, USE src);
5697 ins_cost(DEFAULT_COST);
5698
5699 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %}
5700 size(4);
5701 ins_encode %{
5702 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
5703 %}
5704 ins_pipe(pipe_class_default);
5705 %}
5706
5707 // Load 16-bit integer constant 0xssss????
5708 instruct loadConI16(iRegIdst dst, immI16 src) %{
5709 match(Set dst src);
5710
5711 format %{ "LI $dst, $src" %}
5712 size(4);
5713 ins_encode %{
5714 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5715 %}
5716 ins_pipe(pipe_class_default);
5717 %}
5718
5719 // Load integer constant 0x????0000
5720 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
5721 match(Set dst src);
5722 ins_cost(DEFAULT_COST);
5723
5724 format %{ "LIS $dst, $src.hi" %}
5725 size(4);
5726 ins_encode %{
5727 // Lis sign extends 16-bit src then shifts it 16 bit to the left.
5728 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5729 %}
5730 ins_pipe(pipe_class_default);
5731 %}
5732
5733 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted
5734 // and sign extended), this adds the low 16 bits.
5735 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
5736 // no match-rule, false predicate
5737 effect(DEF dst, USE src1, USE src2);
5738 predicate(false);
5739
5740 format %{ "ORI $dst, $src1.hi, $src2.lo" %}
5741 size(4);
5742 ins_encode %{
5743 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5744 %}
5745 ins_pipe(pipe_class_default);
5746 %}
5747
5748 instruct loadConI32(iRegIdst dst, immI32 src) %{
5749 match(Set dst src);
5750 // This macro is valid only in Power 10 and up, but adding the following predicate here
5751 // caused a build error, so we comment it out for now.
5752 // predicate(PowerArchitecturePPC64 >= 10);
5753 ins_cost(DEFAULT_COST+1);
5754
5755 format %{ "PLI $dst, $src" %}
5756 size(8);
5757 ins_encode %{
5758 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5759 __ pli($dst$$Register, $src$$constant);
5760 %}
5761 ins_pipe(pipe_class_default);
5762 ins_alignment(2);
5763 %}
5764
5765 instruct loadConI_Ex(iRegIdst dst, immI src) %{
5766 match(Set dst src);
5767 ins_cost(DEFAULT_COST*2);
5768
5769 expand %{
5770 // Would like to use $src$$constant.
5771 immI16 srcLo %{ _opnds[1]->constant() %}
5772 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5773 immIhi16 srcHi %{ _opnds[1]->constant() %}
5774 iRegIdst tmpI;
5775 loadConIhi16(tmpI, srcHi);
5776 loadConI32_lo16(dst, tmpI, srcLo);
5777 %}
5778 %}
5779
5780 // No constant pool entries required.
5781 instruct loadConL16(iRegLdst dst, immL16 src) %{
5782 match(Set dst src);
5783
5784 format %{ "LI $dst, $src \t// long" %}
5785 size(4);
5786 ins_encode %{
5787 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
5788 %}
5789 ins_pipe(pipe_class_default);
5790 %}
5791
5792 // Load long constant 0xssssssss????0000
5793 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
5794 match(Set dst src);
5795 ins_cost(DEFAULT_COST);
5796
5797 format %{ "LIS $dst, $src.hi \t// long" %}
5798 size(4);
5799 ins_encode %{
5800 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5801 %}
5802 ins_pipe(pipe_class_default);
5803 %}
5804
5805 // To load a 32 bit constant: merge lower 16 bits into already loaded
5806 // high 16 bits.
5807 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
5808 // no match-rule, false predicate
5809 effect(DEF dst, USE src1, USE src2);
5810 predicate(false);
5811
5812 format %{ "ORI $dst, $src1, $src2.lo" %}
5813 size(4);
5814 ins_encode %{
5815 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5816 %}
5817 ins_pipe(pipe_class_default);
5818 %}
5819
5820 // Load 32-bit long constant
5821 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{
5822 match(Set dst src);
5823 ins_cost(DEFAULT_COST*2);
5824
5825 expand %{
5826 // Would like to use $src$$constant.
5827 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%}
5828 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5829 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%}
5830 iRegLdst tmpL;
5831 loadConL32hi16(tmpL, srcHi);
5832 loadConL32_lo16(dst, tmpL, srcLo);
5833 %}
5834 %}
5835
5836 // Load 34-bit long constant using prefixed addi. No constant pool entries required.
5837 instruct loadConL34(iRegLdst dst, immL34 src) %{
5838 match(Set dst src);
5839 // This macro is valid only in Power 10 and up, but adding the following predicate here
5840 // caused a build error, so we comment it out for now.
5841 // predicate(PowerArchitecturePPC64 >= 10);
5842 ins_cost(DEFAULT_COST+1);
5843
5844 format %{ "PLI $dst, $src \t// long" %}
5845 size(8);
5846 ins_encode %{
5847 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5848 __ pli($dst$$Register, $src$$constant);
5849 %}
5850 ins_pipe(pipe_class_default);
5851 ins_alignment(2);
5852 %}
5853
5854 // Load long constant 0x????000000000000.
5855 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{
5856 match(Set dst src);
5857 ins_cost(DEFAULT_COST);
5858
5859 expand %{
5860 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%}
5861 immI shift32 %{ 32 %}
5862 iRegLdst tmpL;
5863 loadConL32hi16(tmpL, srcHi);
5864 lshiftL_regL_immI(dst, tmpL, shift32);
5865 %}
5866 %}
5867
5868 // Expand node for constant pool load: small offset.
5869 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{
5870 effect(DEF dst, USE src, USE toc);
5871 ins_cost(MEMORY_REF_COST);
5872
5873 ins_num_consts(1);
5874 // Needed so that CallDynamicJavaDirect can compute the address of this
5875 // instruction for relocation.
5876 ins_field_cbuf_insts_offset(int);
5877
5878 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %}
5879 size(4);
5880 ins_encode( enc_load_long_constL(dst, src, toc) );
5881 ins_pipe(pipe_class_memory);
5882 %}
5883
5884 // Expand node for constant pool load: large offset.
5885 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{
5886 effect(DEF dst, USE src, USE toc);
5887 predicate(false);
5888
5889 ins_num_consts(1);
5890 ins_field_const_toc_offset(int);
5891 // Needed so that CallDynamicJavaDirect can compute the address of this
5892 // instruction for relocation.
5893 ins_field_cbuf_insts_offset(int);
5894
5895 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %}
5896 size(4);
5897 ins_encode( enc_load_long_constL_hi(dst, toc, src) );
5898 ins_pipe(pipe_class_default);
5899 %}
5900
5901 // Expand node for constant pool load: large offset.
5902 // No constant pool entries required.
5903 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
5904 effect(DEF dst, USE src, USE base);
5905 predicate(false);
5906
5907 ins_field_const_toc_offset_hi_node(loadConL_hiNode*);
5908
5909 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %}
5910 size(4);
5911 ins_encode %{
5912 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5913 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5914 %}
5915 ins_pipe(pipe_class_memory);
5916 %}
5917
5918 // Load long constant from constant table. Expand in case of
5919 // offset > 16 bit is needed.
5920 // Adlc adds toc node MachConstantTableBase.
5921 instruct loadConL_Ex(iRegLdst dst, immL src) %{
5922 match(Set dst src);
5923 ins_cost(MEMORY_REF_COST);
5924
5925 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %}
5926 // We can not inline the enc_class for the expand as that does not support constanttablebase.
5927 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) );
5928 %}
5929
5930 // Load NULL as compressed oop.
5931 instruct loadConN0(iRegNdst dst, immN_0 src) %{
5932 match(Set dst src);
5933 ins_cost(DEFAULT_COST);
5934
5935 format %{ "LI $dst, $src \t// compressed ptr" %}
5936 size(4);
5937 ins_encode %{
5938 __ li($dst$$Register, 0);
5939 %}
5940 ins_pipe(pipe_class_default);
5941 %}
5942
5943 // Load hi part of compressed oop constant.
5944 instruct loadConN_hi(iRegNdst dst, immN src) %{
5945 effect(DEF dst, USE src);
5946 ins_cost(DEFAULT_COST);
5947
5948 format %{ "LIS $dst, $src \t// narrow oop hi" %}
5949 size(4);
5950 ins_encode %{
5951 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff));
5952 %}
5953 ins_pipe(pipe_class_default);
5954 %}
5955
5956 // Add lo part of compressed oop constant to already loaded hi part.
5957 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
5958 effect(DEF dst, USE src1, USE src2);
5959 ins_cost(DEFAULT_COST);
5960
5961 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %}
5962 size(4);
5963 ins_encode %{
5964 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
5965 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant);
5966 RelocationHolder rspec = oop_Relocation::spec(oop_index);
5967 __ relocate(rspec, 1);
5968 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff);
5969 %}
5970 ins_pipe(pipe_class_default);
5971 %}
5972
5973 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
5974 effect(DEF dst, USE src, USE shift, USE mask_begin);
5975
5976 size(4);
5977 ins_encode %{
5978 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
5979 %}
5980 ins_pipe(pipe_class_default);
5981 %}
5982
5983 // Needed to postalloc expand loadConN: ConN is loaded as ConI
5984 // leaving the upper 32 bits with sign-extension bits.
5985 // This clears these bits: dst = src & 0xFFFFFFFF.
5986 // TODO: Eventually call this maskN_regN_FFFFFFFF.
5987 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
5988 effect(DEF dst, USE src);
5989 predicate(false);
5990
5991 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
5992 size(4);
5993 ins_encode %{
5994 __ clrldi($dst$$Register, $src$$Register, 0x20);
5995 %}
5996 ins_pipe(pipe_class_default);
5997 %}
5998
5999 // Optimize DecodeN for disjoint base.
6000 // Load base of compressed oops into a register
6001 instruct loadBase(iRegLdst dst) %{
6002 effect(DEF dst);
6003
6004 format %{ "LoadConst $dst, heapbase" %}
6005 ins_encode %{
6006 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0);
6007 %}
6008 ins_pipe(pipe_class_default);
6009 %}
6010
6011 // Loading ConN must be postalloc expanded so that edges between
6012 // the nodes are safe. They may not interfere with a safepoint.
6013 // GL TODO: This needs three instructions: better put this into the constant pool.
6014 instruct loadConN_Ex(iRegNdst dst, immN src) %{
6015 match(Set dst src);
6016 ins_cost(DEFAULT_COST*2);
6017
6018 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6019 postalloc_expand %{
6020 MachNode *m1 = new loadConN_hiNode();
6021 MachNode *m2 = new loadConN_loNode();
6022 MachNode *m3 = new clearMs32bNode();
6023 m1->add_req(NULL);
6024 m2->add_req(NULL, m1);
6025 m3->add_req(NULL, m2);
6026 m1->_opnds[0] = op_dst;
6027 m1->_opnds[1] = op_src;
6028 m2->_opnds[0] = op_dst;
6029 m2->_opnds[1] = op_dst;
6030 m2->_opnds[2] = op_src;
6031 m3->_opnds[0] = op_dst;
6032 m3->_opnds[1] = op_dst;
6033 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6034 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6035 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6036 nodes->push(m1);
6037 nodes->push(m2);
6038 nodes->push(m3);
6039 %}
6040 %}
6041
6042 // We have seen a safepoint between the hi and lo parts, and this node was handled
6043 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is
6044 // not a narrow oop.
6045 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
6046 match(Set dst src);
6047 effect(DEF dst, USE src);
6048 ins_cost(DEFAULT_COST);
6049
6050 format %{ "LIS $dst, $src \t// narrow klass hi" %}
6051 size(4);
6052 ins_encode %{
6053 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant);
6054 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
6055 %}
6056 ins_pipe(pipe_class_default);
6057 %}
6058
6059 // As loadConNKlass_hi this must be recognized as narrow klass, not oop!
6060 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
6061 match(Set dst src1);
6062 effect(TEMP src2);
6063 ins_cost(DEFAULT_COST);
6064
6065 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
6066 size(4);
6067 ins_encode %{
6068 __ clrldi($dst$$Register, $src2$$Register, 0x20);
6069 %}
6070 ins_pipe(pipe_class_default);
6071 %}
6072
6073 // This needs a match rule so that build_oop_map knows this is
6074 // not a narrow oop.
6075 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
6076 match(Set dst src1);
6077 effect(TEMP src2);
6078 ins_cost(DEFAULT_COST);
6079
6080 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
6081 size(4);
6082 ins_encode %{
6083 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src1$$constant);
6084 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
6085 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant);
6086 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
6087
6088 __ relocate(rspec, 1);
6089 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
6090 %}
6091 ins_pipe(pipe_class_default);
6092 %}
6093
6094 // Loading ConNKlass must be postalloc expanded so that edges between
6095 // the nodes are safe. They may not interfere with a safepoint.
6096 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
6097 match(Set dst src);
6098 ins_cost(DEFAULT_COST*2);
6099
6100 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6101 postalloc_expand %{
6102 // Load high bits into register. Sign extended.
6103 MachNode *m1 = new loadConNKlass_hiNode();
6104 m1->add_req(NULL);
6105 m1->_opnds[0] = op_dst;
6106 m1->_opnds[1] = op_src;
6107 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6108 nodes->push(m1);
6109
6110 MachNode *m2 = m1;
6111 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) {
6112 // Value might be 1-extended. Mask out these bits.
6113 m2 = new loadConNKlass_maskNode();
6114 m2->add_req(NULL, m1);
6115 m2->_opnds[0] = op_dst;
6116 m2->_opnds[1] = op_src;
6117 m2->_opnds[2] = op_dst;
6118 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6119 nodes->push(m2);
6120 }
6121
6122 MachNode *m3 = new loadConNKlass_loNode();
6123 m3->add_req(NULL, m2);
6124 m3->_opnds[0] = op_dst;
6125 m3->_opnds[1] = op_src;
6126 m3->_opnds[2] = op_dst;
6127 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6128 nodes->push(m3);
6129 %}
6130 %}
6131
6132 // 0x1 is used in object initialization (initial object header).
6133 // No constant pool entries required.
6134 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
6135 match(Set dst src);
6136
6137 format %{ "LI $dst, $src \t// ptr" %}
6138 size(4);
6139 ins_encode %{
6140 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
6141 %}
6142 ins_pipe(pipe_class_default);
6143 %}
6144
6145 // Expand node for constant pool load: small offset.
6146 // The match rule is needed to generate the correct bottom_type(),
6147 // however this node should never match. The use of predicate is not
6148 // possible since ADLC forbids predicates for chain rules. The higher
6149 // costs do not prevent matching in this case. For that reason the
6150 // operand immP_NM with predicate(false) is used.
6151 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{
6152 match(Set dst src);
6153 effect(TEMP toc);
6154
6155 ins_num_consts(1);
6156
6157 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %}
6158 size(4);
6159 ins_encode( enc_load_long_constP(dst, src, toc) );
6160 ins_pipe(pipe_class_memory);
6161 %}
6162
6163 // Expand node for constant pool load: large offset.
6164 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{
6165 effect(DEF dst, USE src, USE toc);
6166 predicate(false);
6167
6168 ins_num_consts(1);
6169 ins_field_const_toc_offset(int);
6170
6171 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %}
6172 size(4);
6173 ins_encode( enc_load_long_constP_hi(dst, src, toc) );
6174 ins_pipe(pipe_class_default);
6175 %}
6176
6177 // Expand node for constant pool load: large offset.
6178 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
6179 match(Set dst src);
6180 effect(TEMP base);
6181
6182 ins_field_const_toc_offset_hi_node(loadConP_hiNode*);
6183
6184 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
6185 size(4);
6186 ins_encode %{
6187 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
6188 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
6189 %}
6190 ins_pipe(pipe_class_memory);
6191 %}
6192
6193 // Load pointer constant from constant table. Expand in case an
6194 // offset > 16 bit is needed.
6195 // Adlc adds toc node MachConstantTableBase.
6196 instruct loadConP_Ex(iRegPdst dst, immP src) %{
6197 match(Set dst src);
6198 ins_cost(MEMORY_REF_COST);
6199
6200 // This rule does not use "expand" because then
6201 // the result type is not known to be an Oop. An ADLC
6202 // enhancement will be needed to make that work - not worth it!
6203
6204 // If this instruction rematerializes, it prolongs the live range
6205 // of the toc node, causing illegal graphs.
6206 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule().
6207 ins_cannot_rematerialize(true);
6208
6209 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %}
6210 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) );
6211 %}
6212
6213 // Expand node for constant pool load: small offset.
6214 instruct loadConF(regF dst, immF src, iRegLdst toc) %{
6215 effect(DEF dst, USE src, USE toc);
6216 ins_cost(MEMORY_REF_COST);
6217
6218 ins_num_consts(1);
6219
6220 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %}
6221 size(4);
6222 ins_encode %{
6223 address float_address = __ float_constant($src$$constant);
6224 if (float_address == NULL) {
6225 ciEnv::current()->record_out_of_memory_failure();
6226 return;
6227 }
6228 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register);
6229 %}
6230 ins_pipe(pipe_class_memory);
6231 %}
6232
6233 // Expand node for constant pool load: large offset.
6234 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
6235 effect(DEF dst, USE src, USE toc);
6236 ins_cost(MEMORY_REF_COST);
6237
6238 ins_num_consts(1);
6239
6240 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6241 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t"
6242 "ADDIS $toc, $toc, -offset_hi"%}
6243 size(12);
6244 ins_encode %{
6245 FloatRegister Rdst = $dst$$FloatRegister;
6246 Register Rtoc = $toc$$Register;
6247 address float_address = __ float_constant($src$$constant);
6248 if (float_address == NULL) {
6249 ciEnv::current()->record_out_of_memory_failure();
6250 return;
6251 }
6252 int offset = __ offset_to_method_toc(float_address);
6253 int hi = (offset + (1<<15))>>16;
6254 int lo = offset - hi * (1<<16);
6255
6256 __ addis(Rtoc, Rtoc, hi);
6257 __ lfs(Rdst, lo, Rtoc);
6258 __ addis(Rtoc, Rtoc, -hi);
6259 %}
6260 ins_pipe(pipe_class_memory);
6261 %}
6262
6263 // Adlc adds toc node MachConstantTableBase.
6264 instruct loadConF_Ex(regF dst, immF src) %{
6265 match(Set dst src);
6266 ins_cost(MEMORY_REF_COST);
6267
6268 // See loadConP.
6269 ins_cannot_rematerialize(true);
6270
6271 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6272 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) );
6273 %}
6274
6275 // Expand node for constant pool load: small offset.
6276 instruct loadConD(regD dst, immD src, iRegLdst toc) %{
6277 effect(DEF dst, USE src, USE toc);
6278 ins_cost(MEMORY_REF_COST);
6279
6280 ins_num_consts(1);
6281
6282 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %}
6283 size(4);
6284 ins_encode %{
6285 address float_address = __ double_constant($src$$constant);
6286 if (float_address == NULL) {
6287 ciEnv::current()->record_out_of_memory_failure();
6288 return;
6289 }
6290 int offset = __ offset_to_method_toc(float_address);
6291 __ lfd($dst$$FloatRegister, offset, $toc$$Register);
6292 %}
6293 ins_pipe(pipe_class_memory);
6294 %}
6295
6296 // Expand node for constant pool load: large offset.
6297 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
6298 effect(DEF dst, USE src, USE toc);
6299 ins_cost(MEMORY_REF_COST);
6300
6301 ins_num_consts(1);
6302
6303 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6304 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t"
6305 "ADDIS $toc, $toc, -offset_hi" %}
6306 size(12);
6307 ins_encode %{
6308 FloatRegister Rdst = $dst$$FloatRegister;
6309 Register Rtoc = $toc$$Register;
6310 address float_address = __ double_constant($src$$constant);
6311 if (float_address == NULL) {
6312 ciEnv::current()->record_out_of_memory_failure();
6313 return;
6314 }
6315 int offset = __ offset_to_method_toc(float_address);
6316 int hi = (offset + (1<<15))>>16;
6317 int lo = offset - hi * (1<<16);
6318
6319 __ addis(Rtoc, Rtoc, hi);
6320 __ lfd(Rdst, lo, Rtoc);
6321 __ addis(Rtoc, Rtoc, -hi);
6322 %}
6323 ins_pipe(pipe_class_memory);
6324 %}
6325
6326 // Adlc adds toc node MachConstantTableBase.
6327 instruct loadConD_Ex(regD dst, immD src) %{
6328 match(Set dst src);
6329 ins_cost(MEMORY_REF_COST);
6330
6331 // See loadConP.
6332 ins_cannot_rematerialize(true);
6333
6334 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6335 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) );
6336 %}
6337
6338 // Prefetch instructions.
6339 // Must be safe to execute with invalid address (cannot fault).
6340
6341 // Special prefetch versions which use the dcbz instruction.
6342 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{
6343 match(PrefetchAllocation (AddP mem src));
6344 predicate(AllocatePrefetchStyle == 3);
6345 ins_cost(MEMORY_REF_COST);
6346
6347 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %}
6348 size(4);
6349 ins_encode %{
6350 __ dcbz($src$$Register, $mem$$base$$Register);
6351 %}
6352 ins_pipe(pipe_class_memory);
6353 %}
6354
6355 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{
6356 match(PrefetchAllocation mem);
6357 predicate(AllocatePrefetchStyle == 3);
6358 ins_cost(MEMORY_REF_COST);
6359
6360 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %}
6361 size(4);
6362 ins_encode %{
6363 __ dcbz($mem$$base$$Register);
6364 %}
6365 ins_pipe(pipe_class_memory);
6366 %}
6367
6368 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
6369 match(PrefetchAllocation (AddP mem src));
6370 predicate(AllocatePrefetchStyle != 3);
6371 ins_cost(MEMORY_REF_COST);
6372
6373 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
6374 size(4);
6375 ins_encode %{
6376 __ dcbtst($src$$Register, $mem$$base$$Register);
6377 %}
6378 ins_pipe(pipe_class_memory);
6379 %}
6380
6381 instruct prefetch_alloc_no_offset(indirectMemory mem) %{
6382 match(PrefetchAllocation mem);
6383 predicate(AllocatePrefetchStyle != 3);
6384 ins_cost(MEMORY_REF_COST);
6385
6386 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
6387 size(4);
6388 ins_encode %{
6389 __ dcbtst($mem$$base$$Register);
6390 %}
6391 ins_pipe(pipe_class_memory);
6392 %}
6393
6394 //----------Store Instructions-------------------------------------------------
6395
6396 // Store Byte
6397 instruct storeB(memory mem, iRegIsrc src) %{
6398 match(Set mem (StoreB mem src));
6399 ins_cost(MEMORY_REF_COST);
6400
6401 format %{ "STB $src, $mem \t// byte" %}
6402 size(4);
6403 ins_encode %{
6404 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6405 __ stb($src$$Register, Idisp, $mem$$base$$Register);
6406 %}
6407 ins_pipe(pipe_class_memory);
6408 %}
6409
6410 // Store Char/Short
6411 instruct storeC(memory mem, iRegIsrc src) %{
6412 match(Set mem (StoreC mem src));
6413 ins_cost(MEMORY_REF_COST);
6414
6415 format %{ "STH $src, $mem \t// short" %}
6416 size(4);
6417 ins_encode %{
6418 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6419 __ sth($src$$Register, Idisp, $mem$$base$$Register);
6420 %}
6421 ins_pipe(pipe_class_memory);
6422 %}
6423
6424 // Store Integer
6425 instruct storeI(memory mem, iRegIsrc src) %{
6426 match(Set mem (StoreI mem src));
6427 ins_cost(MEMORY_REF_COST);
6428
6429 format %{ "STW $src, $mem" %}
6430 size(4);
6431 ins_encode( enc_stw(src, mem) );
6432 ins_pipe(pipe_class_memory);
6433 %}
6434
6435 // ConvL2I + StoreI.
6436 instruct storeI_convL2I(memory mem, iRegLsrc src) %{
6437 match(Set mem (StoreI mem (ConvL2I src)));
6438 ins_cost(MEMORY_REF_COST);
6439
6440 format %{ "STW l2i($src), $mem" %}
6441 size(4);
6442 ins_encode( enc_stw(src, mem) );
6443 ins_pipe(pipe_class_memory);
6444 %}
6445
6446 // Store Long
6447 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{
6448 match(Set mem (StoreL mem src));
6449 ins_cost(MEMORY_REF_COST);
6450
6451 format %{ "STD $src, $mem \t// long" %}
6452 size(4);
6453 ins_encode( enc_std(src, mem) );
6454 ins_pipe(pipe_class_memory);
6455 %}
6456
6457 // Store super word nodes.
6458
6459 // Store Aligned Packed Byte long register to memory
6460 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{
6461 predicate(n->as_StoreVector()->memory_size() == 8);
6462 match(Set mem (StoreVector mem src));
6463 ins_cost(MEMORY_REF_COST);
6464
6465 format %{ "STD $mem, $src \t// packed8B" %}
6466 size(4);
6467 ins_encode( enc_std(src, mem) );
6468 ins_pipe(pipe_class_memory);
6469 %}
6470
6471 // Store Packed Byte long register to memory
6472 instruct storeV16(indirect mem, vecX src) %{
6473 predicate(n->as_StoreVector()->memory_size() == 16);
6474 match(Set mem (StoreVector mem src));
6475 ins_cost(MEMORY_REF_COST);
6476
6477 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %}
6478 size(4);
6479 ins_encode %{
6480 __ stxvd2x($src$$VectorSRegister, $mem$$Register);
6481 %}
6482 ins_pipe(pipe_class_default);
6483 %}
6484
6485 // Reinterpret: only one vector size used: either L or X
6486 instruct reinterpretL(iRegLdst dst) %{
6487 match(Set dst (VectorReinterpret dst));
6488 ins_cost(0);
6489 format %{ "reinterpret $dst" %}
6490 ins_encode( /*empty*/ );
6491 ins_pipe(pipe_class_empty);
6492 %}
6493
6494 instruct reinterpretX(vecX dst) %{
6495 match(Set dst (VectorReinterpret dst));
6496 ins_cost(0);
6497 format %{ "reinterpret $dst" %}
6498 ins_encode( /*empty*/ );
6499 ins_pipe(pipe_class_empty);
6500 %}
6501
6502 // Store Compressed Oop
6503 instruct storeN(memory dst, iRegN_P2N src) %{
6504 match(Set dst (StoreN dst src));
6505 ins_cost(MEMORY_REF_COST);
6506
6507 format %{ "STW $src, $dst \t// compressed oop" %}
6508 size(4);
6509 ins_encode( enc_stw(src, dst) );
6510 ins_pipe(pipe_class_memory);
6511 %}
6512
6513 // Store Compressed KLass
6514 instruct storeNKlass(memory dst, iRegN_P2N src) %{
6515 match(Set dst (StoreNKlass dst src));
6516 ins_cost(MEMORY_REF_COST);
6517
6518 format %{ "STW $src, $dst \t// compressed klass" %}
6519 size(4);
6520 ins_encode( enc_stw(src, dst) );
6521 ins_pipe(pipe_class_memory);
6522 %}
6523
6524 // Store Pointer
6525 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{
6526 match(Set dst (StoreP dst src));
6527 ins_cost(MEMORY_REF_COST);
6528
6529 format %{ "STD $src, $dst \t// ptr" %}
6530 size(4);
6531 ins_encode( enc_std(src, dst) );
6532 ins_pipe(pipe_class_memory);
6533 %}
6534
6535 // Store Float
6536 instruct storeF(memory mem, regF src) %{
6537 match(Set mem (StoreF mem src));
6538 ins_cost(MEMORY_REF_COST);
6539
6540 format %{ "STFS $src, $mem" %}
6541 size(4);
6542 ins_encode( enc_stfs(src, mem) );
6543 ins_pipe(pipe_class_memory);
6544 %}
6545
6546 // Store Double
6547 instruct storeD(memory mem, regD src) %{
6548 match(Set mem (StoreD mem src));
6549 ins_cost(MEMORY_REF_COST);
6550
6551 format %{ "STFD $src, $mem" %}
6552 size(4);
6553 ins_encode( enc_stfd(src, mem) );
6554 ins_pipe(pipe_class_memory);
6555 %}
6556
6557 //----------Store Instructions With Zeros--------------------------------------
6558
6559 instruct storeCM(memory mem, immI_0 zero) %{
6560 match(Set mem (StoreCM mem zero));
6561 ins_cost(MEMORY_REF_COST);
6562
6563 format %{ "STB #0, $mem \t// CMS card-mark byte store" %}
6564 size(8);
6565 ins_encode %{
6566 __ li(R0, 0);
6567 // No release barrier: Oops are allowed to get visible after marking.
6568 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias");
6569 __ stb(R0, $mem$$disp, $mem$$base$$Register);
6570 %}
6571 ins_pipe(pipe_class_memory);
6572 %}
6573
6574 // Convert oop pointer into compressed form.
6575
6576 // Nodes for postalloc expand.
6577
6578 // Shift node for expand.
6579 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
6580 // The match rule is needed to make it a 'MachTypeNode'!
6581 match(Set dst (EncodeP src));
6582 predicate(false);
6583
6584 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6585 size(4);
6586 ins_encode %{
6587 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6588 %}
6589 ins_pipe(pipe_class_default);
6590 %}
6591
6592 // Add node for expand.
6593 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6594 // The match rule is needed to make it a 'MachTypeNode'!
6595 match(Set dst (EncodeP src));
6596 predicate(false);
6597
6598 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6599 ins_encode %{
6600 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6601 %}
6602 ins_pipe(pipe_class_default);
6603 %}
6604
6605 // Conditional sub base.
6606 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6607 // The match rule is needed to make it a 'MachTypeNode'!
6608 match(Set dst (EncodeP (Binary crx src1)));
6609 predicate(false);
6610
6611 format %{ "BEQ $crx, done\n\t"
6612 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n"
6613 "done:" %}
6614 ins_encode %{
6615 Label done;
6616 __ beq($crx$$CondRegister, done);
6617 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0);
6618 __ bind(done);
6619 %}
6620 ins_pipe(pipe_class_default);
6621 %}
6622
6623 // Power 7 can use isel instruction
6624 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6625 // The match rule is needed to make it a 'MachTypeNode'!
6626 match(Set dst (EncodeP (Binary crx src1)));
6627 predicate(false);
6628
6629 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6630 size(4);
6631 ins_encode %{
6632 // This is a Power7 instruction for which no machine description exists.
6633 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6634 %}
6635 ins_pipe(pipe_class_default);
6636 %}
6637
6638 // Disjoint narrow oop base.
6639 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6640 match(Set dst (EncodeP src));
6641 predicate(CompressedOops::base_disjoint());
6642
6643 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6644 size(4);
6645 ins_encode %{
6646 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32);
6647 %}
6648 ins_pipe(pipe_class_default);
6649 %}
6650
6651 // shift != 0, base != 0
6652 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6653 match(Set dst (EncodeP src));
6654 effect(TEMP crx);
6655 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6656 CompressedOops::shift() != 0 &&
6657 CompressedOops::base_overlaps());
6658
6659 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6660 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6661 %}
6662
6663 // shift != 0, base != 0
6664 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6665 match(Set dst (EncodeP src));
6666 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6667 CompressedOops::shift() != 0 &&
6668 CompressedOops::base_overlaps());
6669
6670 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6671 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6672 %}
6673
6674 // shift != 0, base == 0
6675 // TODO: This is the same as encodeP_shift. Merge!
6676 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6677 match(Set dst (EncodeP src));
6678 predicate(CompressedOops::shift() != 0 &&
6679 CompressedOops::base() ==0);
6680
6681 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %}
6682 size(4);
6683 ins_encode %{
6684 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6685 %}
6686 ins_pipe(pipe_class_default);
6687 %}
6688
6689 // Compressed OOPs with narrow_oop_shift == 0.
6690 // shift == 0, base == 0
6691 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
6692 match(Set dst (EncodeP src));
6693 predicate(CompressedOops::shift() == 0);
6694
6695 format %{ "MR $dst, $src \t// Ptr->Narrow" %}
6696 // variable size, 0 or 4.
6697 ins_encode %{
6698 __ mr_if_needed($dst$$Register, $src$$Register);
6699 %}
6700 ins_pipe(pipe_class_default);
6701 %}
6702
6703 // Decode nodes.
6704
6705 // Shift node for expand.
6706 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6707 // The match rule is needed to make it a 'MachTypeNode'!
6708 match(Set dst (DecodeN src));
6709 predicate(false);
6710
6711 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6712 size(4);
6713 ins_encode %{
6714 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6715 %}
6716 ins_pipe(pipe_class_default);
6717 %}
6718
6719 // Add node for expand.
6720 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6721 // The match rule is needed to make it a 'MachTypeNode'!
6722 match(Set dst (DecodeN src));
6723 predicate(false);
6724
6725 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %}
6726 ins_encode %{
6727 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6728 %}
6729 ins_pipe(pipe_class_default);
6730 %}
6731
6732 // conditianal add base for expand
6733 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6734 // The match rule is needed to make it a 'MachTypeNode'!
6735 // NOTICE that the rule is nonsense - we just have to make sure that:
6736 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6737 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6738 match(Set dst (DecodeN (Binary crx src)));
6739 predicate(false);
6740
6741 format %{ "BEQ $crx, done\n\t"
6742 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n"
6743 "done:" %}
6744 ins_encode %{
6745 Label done;
6746 __ beq($crx$$CondRegister, done);
6747 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6748 __ bind(done);
6749 %}
6750 ins_pipe(pipe_class_default);
6751 %}
6752
6753 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6754 // The match rule is needed to make it a 'MachTypeNode'!
6755 // NOTICE that the rule is nonsense - we just have to make sure that:
6756 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6757 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6758 match(Set dst (DecodeN (Binary crx src1)));
6759 predicate(false);
6760
6761 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6762 size(4);
6763 ins_encode %{
6764 // This is a Power7 instruction for which no machine description exists.
6765 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6766 %}
6767 ins_pipe(pipe_class_default);
6768 %}
6769
6770 // shift != 0, base != 0
6771 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6772 match(Set dst (DecodeN src));
6773 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6774 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6775 CompressedOops::shift() != 0 &&
6776 CompressedOops::base() != 0);
6777 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6778 effect(TEMP crx);
6779
6780 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6781 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6782 %}
6783
6784 // shift != 0, base == 0
6785 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6786 match(Set dst (DecodeN src));
6787 predicate(CompressedOops::shift() != 0 &&
6788 CompressedOops::base() == 0);
6789
6790 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %}
6791 size(4);
6792 ins_encode %{
6793 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6794 %}
6795 ins_pipe(pipe_class_default);
6796 %}
6797
6798 // Optimize DecodeN for disjoint base.
6799 // Shift narrow oop and or it into register that already contains the heap base.
6800 // Base == dst must hold, and is assured by construction in postaloc_expand.
6801 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6802 match(Set dst (DecodeN src));
6803 effect(TEMP base);
6804 predicate(false);
6805
6806 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6807 size(4);
6808 ins_encode %{
6809 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift());
6810 %}
6811 ins_pipe(pipe_class_default);
6812 %}
6813
6814 // Optimize DecodeN for disjoint base.
6815 // This node requires only one cycle on the critical path.
6816 // We must postalloc_expand as we can not express use_def effects where
6817 // the used register is L and the def'ed register P.
6818 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6819 match(Set dst (DecodeN src));
6820 effect(TEMP_DEF dst);
6821 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6822 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6823 CompressedOops::base_disjoint());
6824 ins_cost(DEFAULT_COST);
6825
6826 format %{ "MOV $dst, heapbase \t\n"
6827 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6828 postalloc_expand %{
6829 loadBaseNode *n1 = new loadBaseNode();
6830 n1->add_req(NULL);
6831 n1->_opnds[0] = op_dst;
6832
6833 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6834 n2->add_req(n_region, n_src, n1);
6835 n2->_opnds[0] = op_dst;
6836 n2->_opnds[1] = op_src;
6837 n2->_opnds[2] = op_dst;
6838 n2->_bottom_type = _bottom_type;
6839
6840 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6841 ra_->set_oop(n2, true);
6842
6843 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6844 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6845
6846 nodes->push(n1);
6847 nodes->push(n2);
6848 %}
6849 %}
6850
6851 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6852 match(Set dst (DecodeN src));
6853 effect(TEMP_DEF dst, TEMP crx);
6854 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6855 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6856 CompressedOops::base_disjoint() && VM_Version::has_isel());
6857 ins_cost(3 * DEFAULT_COST);
6858
6859 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %}
6860 postalloc_expand %{
6861 loadBaseNode *n1 = new loadBaseNode();
6862 n1->add_req(NULL);
6863 n1->_opnds[0] = op_dst;
6864
6865 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
6866 n_compare->add_req(n_region, n_src);
6867 n_compare->_opnds[0] = op_crx;
6868 n_compare->_opnds[1] = op_src;
6869 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6870
6871 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6872 n2->add_req(n_region, n_src, n1);
6873 n2->_opnds[0] = op_dst;
6874 n2->_opnds[1] = op_src;
6875 n2->_opnds[2] = op_dst;
6876 n2->_bottom_type = _bottom_type;
6877
6878 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6879 n_cond_set->add_req(n_region, n_compare, n2);
6880 n_cond_set->_opnds[0] = op_dst;
6881 n_cond_set->_opnds[1] = op_crx;
6882 n_cond_set->_opnds[2] = op_dst;
6883 n_cond_set->_bottom_type = _bottom_type;
6884
6885 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6886 ra_->set_oop(n_cond_set, true);
6887
6888 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6889 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
6890 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6891 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6892
6893 nodes->push(n1);
6894 nodes->push(n_compare);
6895 nodes->push(n2);
6896 nodes->push(n_cond_set);
6897 %}
6898 %}
6899
6900 // src != 0, shift != 0, base != 0
6901 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6902 match(Set dst (DecodeN src));
6903 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6904 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6905 CompressedOops::shift() != 0 &&
6906 CompressedOops::base() != 0);
6907 ins_cost(2 * DEFAULT_COST);
6908
6909 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %}
6910 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6911 %}
6912
6913 // Compressed OOPs with narrow_oop_shift == 0.
6914 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6915 match(Set dst (DecodeN src));
6916 predicate(CompressedOops::shift() == 0);
6917 ins_cost(DEFAULT_COST);
6918
6919 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %}
6920 // variable size, 0 or 4.
6921 ins_encode %{
6922 __ mr_if_needed($dst$$Register, $src$$Register);
6923 %}
6924 ins_pipe(pipe_class_default);
6925 %}
6926
6927 // Convert compressed oop into int for vectors alignment masking.
6928 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
6929 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6930 predicate(CompressedOops::shift() == 0);
6931 ins_cost(DEFAULT_COST);
6932
6933 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %}
6934 // variable size, 0 or 4.
6935 ins_encode %{
6936 __ mr_if_needed($dst$$Register, $src$$Register);
6937 %}
6938 ins_pipe(pipe_class_default);
6939 %}
6940
6941 // Convert klass pointer into compressed form.
6942
6943 // Nodes for postalloc expand.
6944
6945 // Shift node for expand.
6946 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
6947 // The match rule is needed to make it a 'MachTypeNode'!
6948 match(Set dst (EncodePKlass src));
6949 predicate(false);
6950
6951 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6952 size(4);
6953 ins_encode %{
6954 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6955 %}
6956 ins_pipe(pipe_class_default);
6957 %}
6958
6959 // Add node for expand.
6960 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6961 // The match rule is needed to make it a 'MachTypeNode'!
6962 match(Set dst (EncodePKlass (Binary base src)));
6963 predicate(false);
6964
6965 format %{ "SUB $dst, $base, $src \t// encode" %}
6966 size(4);
6967 ins_encode %{
6968 __ subf($dst$$Register, $base$$Register, $src$$Register);
6969 %}
6970 ins_pipe(pipe_class_default);
6971 %}
6972
6973 // Disjoint narrow oop base.
6974 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
6975 match(Set dst (EncodePKlass src));
6976 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/);
6977
6978 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6979 size(4);
6980 ins_encode %{
6981 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
6982 %}
6983 ins_pipe(pipe_class_default);
6984 %}
6985
6986 // shift != 0, base != 0
6987 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6988 match(Set dst (EncodePKlass (Binary base src)));
6989 predicate(false);
6990
6991 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6992 postalloc_expand %{
6993 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
6994 n1->add_req(n_region, n_base, n_src);
6995 n1->_opnds[0] = op_dst;
6996 n1->_opnds[1] = op_base;
6997 n1->_opnds[2] = op_src;
6998 n1->_bottom_type = _bottom_type;
6999
7000 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode();
7001 n2->add_req(n_region, n1);
7002 n2->_opnds[0] = op_dst;
7003 n2->_opnds[1] = op_dst;
7004 n2->_bottom_type = _bottom_type;
7005 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7006 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7007
7008 nodes->push(n1);
7009 nodes->push(n2);
7010 %}
7011 %}
7012
7013 // shift != 0, base != 0
7014 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
7015 match(Set dst (EncodePKlass src));
7016 //predicate(CompressedKlassPointers::shift() != 0 &&
7017 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/);
7018
7019 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
7020 ins_cost(DEFAULT_COST*2); // Don't count constant.
7021 expand %{
7022 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %}
7023 iRegLdst base;
7024 loadConL_Ex(base, baseImm);
7025 encodePKlass_not_null_Ex(dst, base, src);
7026 %}
7027 %}
7028
7029 // Decode nodes.
7030
7031 // Shift node for expand.
7032 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
7033 // The match rule is needed to make it a 'MachTypeNode'!
7034 match(Set dst (DecodeNKlass src));
7035 predicate(false);
7036
7037 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %}
7038 size(4);
7039 ins_encode %{
7040 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
7041 %}
7042 ins_pipe(pipe_class_default);
7043 %}
7044
7045 // Add node for expand.
7046
7047 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
7048 // The match rule is needed to make it a 'MachTypeNode'!
7049 match(Set dst (DecodeNKlass (Binary base src)));
7050 predicate(false);
7051
7052 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
7053 size(4);
7054 ins_encode %{
7055 __ add($dst$$Register, $base$$Register, $src$$Register);
7056 %}
7057 ins_pipe(pipe_class_default);
7058 %}
7059
7060 // src != 0, shift != 0, base != 0
7061 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
7062 match(Set dst (DecodeNKlass (Binary base src)));
7063 //effect(kill src); // We need a register for the immediate result after shifting.
7064 predicate(false);
7065
7066 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %}
7067 postalloc_expand %{
7068 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode();
7069 n1->add_req(n_region, n_base, n_src);
7070 n1->_opnds[0] = op_dst;
7071 n1->_opnds[1] = op_base;
7072 n1->_opnds[2] = op_src;
7073 n1->_bottom_type = _bottom_type;
7074
7075 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode();
7076 n2->add_req(n_region, n1);
7077 n2->_opnds[0] = op_dst;
7078 n2->_opnds[1] = op_dst;
7079 n2->_bottom_type = _bottom_type;
7080
7081 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7082 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7083
7084 nodes->push(n1);
7085 nodes->push(n2);
7086 %}
7087 %}
7088
7089 // src != 0, shift != 0, base != 0
7090 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
7091 match(Set dst (DecodeNKlass src));
7092 // predicate(CompressedKlassPointers::shift() != 0 &&
7093 // CompressedKlassPointers::base() != 0);
7094
7095 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %}
7096
7097 ins_cost(DEFAULT_COST*2); // Don't count constant.
7098 expand %{
7099 // We add first, then we shift. Like this, we can get along with one register less.
7100 // But we have to load the base pre-shifted.
7101 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %}
7102 iRegLdst base;
7103 loadConL_Ex(base, baseImm);
7104 decodeNKlass_notNull_addBase_Ex(dst, base, src);
7105 %}
7106 %}
7107
7108 //----------MemBar Instructions-----------------------------------------------
7109 // Memory barrier flavors
7110
7111 instruct membar_acquire() %{
7112 match(LoadFence);
7113 ins_cost(4*MEMORY_REF_COST);
7114
7115 format %{ "MEMBAR-acquire" %}
7116 size(4);
7117 ins_encode %{
7118 __ acquire();
7119 %}
7120 ins_pipe(pipe_class_default);
7121 %}
7122
7123 instruct unnecessary_membar_acquire() %{
7124 match(MemBarAcquire);
7125 ins_cost(0);
7126
7127 format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
7128 size(0);
7129 ins_encode( /*empty*/ );
7130 ins_pipe(pipe_class_default);
7131 %}
7132
7133 instruct membar_acquire_lock() %{
7134 match(MemBarAcquireLock);
7135 ins_cost(0);
7136
7137 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
7138 size(0);
7139 ins_encode( /*empty*/ );
7140 ins_pipe(pipe_class_default);
7141 %}
7142
7143 instruct membar_release() %{
7144 match(MemBarRelease);
7145 match(StoreFence);
7146 ins_cost(4*MEMORY_REF_COST);
7147
7148 format %{ "MEMBAR-release" %}
7149 size(4);
7150 ins_encode %{
7151 __ release();
7152 %}
7153 ins_pipe(pipe_class_default);
7154 %}
7155
7156 instruct membar_storestore() %{
7157 match(MemBarStoreStore);
7158 match(StoreStoreFence);
7159 ins_cost(4*MEMORY_REF_COST);
7160
7161 format %{ "MEMBAR-store-store" %}
7162 size(4);
7163 ins_encode %{
7164 __ membar(Assembler::StoreStore);
7165 %}
7166 ins_pipe(pipe_class_default);
7167 %}
7168
7169 instruct membar_release_lock() %{
7170 match(MemBarReleaseLock);
7171 ins_cost(0);
7172
7173 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
7174 size(0);
7175 ins_encode( /*empty*/ );
7176 ins_pipe(pipe_class_default);
7177 %}
7178
7179 instruct membar_volatile() %{
7180 match(MemBarVolatile);
7181 ins_cost(4*MEMORY_REF_COST);
7182
7183 format %{ "MEMBAR-volatile" %}
7184 size(4);
7185 ins_encode %{
7186 __ fence();
7187 %}
7188 ins_pipe(pipe_class_default);
7189 %}
7190
7191 // This optimization is wrong on PPC. The following pattern is not supported:
7192 // MemBarVolatile
7193 // ^ ^
7194 // | |
7195 // CtrlProj MemProj
7196 // ^ ^
7197 // | |
7198 // | Load
7199 // |
7200 // MemBarVolatile
7201 //
7202 // The first MemBarVolatile could get optimized out! According to
7203 // Vladimir, this pattern can not occur on Oracle platforms.
7204 // However, it does occur on PPC64 (because of membars in
7205 // inline_unsafe_load_store).
7206 //
7207 // Add this node again if we found a good solution for inline_unsafe_load_store().
7208 // Don't forget to look at the implementation of post_store_load_barrier again,
7209 // we did other fixes in that method.
7210 //instruct unnecessary_membar_volatile() %{
7211 // match(MemBarVolatile);
7212 // predicate(Matcher::post_store_load_barrier(n));
7213 // ins_cost(0);
7214 //
7215 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
7216 // size(0);
7217 // ins_encode( /*empty*/ );
7218 // ins_pipe(pipe_class_default);
7219 //%}
7220
7221 instruct membar_CPUOrder() %{
7222 match(MemBarCPUOrder);
7223 ins_cost(0);
7224
7225 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
7226 size(0);
7227 ins_encode( /*empty*/ );
7228 ins_pipe(pipe_class_default);
7229 %}
7230
7231 //----------Conditional Move---------------------------------------------------
7232
7233 // Cmove using isel.
7234 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
7235 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7236 predicate(VM_Version::has_isel());
7237 ins_cost(DEFAULT_COST);
7238
7239 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7240 size(4);
7241 ins_encode %{
7242 // This is a Power7 instruction for which no machine description
7243 // exists. Anyways, the scheduler should be off on Power7.
7244 int cc = $cmp$$cmpcode;
7245 __ isel($dst$$Register, $crx$$CondRegister,
7246 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7247 %}
7248 ins_pipe(pipe_class_default);
7249 %}
7250
7251 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
7252 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7253 predicate(!VM_Version::has_isel());
7254 ins_cost(DEFAULT_COST+BRANCH_COST);
7255
7256 ins_variable_size_depending_on_alignment(true);
7257
7258 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7259 // Worst case is branch + move + stop, no stop without scheduler
7260 size(8);
7261 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7262 ins_pipe(pipe_class_default);
7263 %}
7264
7265 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{
7266 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7267 ins_cost(DEFAULT_COST+BRANCH_COST);
7268
7269 ins_variable_size_depending_on_alignment(true);
7270
7271 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7272 // Worst case is branch + move + stop, no stop without scheduler
7273 size(8);
7274 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7275 ins_pipe(pipe_class_default);
7276 %}
7277
7278 // Cmove using isel.
7279 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
7280 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7281 predicate(VM_Version::has_isel());
7282 ins_cost(DEFAULT_COST);
7283
7284 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7285 size(4);
7286 ins_encode %{
7287 // This is a Power7 instruction for which no machine description
7288 // exists. Anyways, the scheduler should be off on Power7.
7289 int cc = $cmp$$cmpcode;
7290 __ isel($dst$$Register, $crx$$CondRegister,
7291 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7292 %}
7293 ins_pipe(pipe_class_default);
7294 %}
7295
7296 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
7297 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7298 predicate(!VM_Version::has_isel());
7299 ins_cost(DEFAULT_COST+BRANCH_COST);
7300
7301 ins_variable_size_depending_on_alignment(true);
7302
7303 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7304 // Worst case is branch + move + stop, no stop without scheduler.
7305 size(8);
7306 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7307 ins_pipe(pipe_class_default);
7308 %}
7309
7310 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{
7311 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7312 ins_cost(DEFAULT_COST+BRANCH_COST);
7313
7314 ins_variable_size_depending_on_alignment(true);
7315
7316 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7317 // Worst case is branch + move + stop, no stop without scheduler.
7318 size(8);
7319 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7320 ins_pipe(pipe_class_default);
7321 %}
7322
7323 // Cmove using isel.
7324 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
7325 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7326 predicate(VM_Version::has_isel());
7327 ins_cost(DEFAULT_COST);
7328
7329 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7330 size(4);
7331 ins_encode %{
7332 // This is a Power7 instruction for which no machine description
7333 // exists. Anyways, the scheduler should be off on Power7.
7334 int cc = $cmp$$cmpcode;
7335 __ isel($dst$$Register, $crx$$CondRegister,
7336 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7337 %}
7338 ins_pipe(pipe_class_default);
7339 %}
7340
7341 // Conditional move for RegN. Only cmov(reg, reg).
7342 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
7343 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7344 predicate(!VM_Version::has_isel());
7345 ins_cost(DEFAULT_COST+BRANCH_COST);
7346
7347 ins_variable_size_depending_on_alignment(true);
7348
7349 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7350 // Worst case is branch + move + stop, no stop without scheduler.
7351 size(8);
7352 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7353 ins_pipe(pipe_class_default);
7354 %}
7355
7356 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{
7357 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7358 ins_cost(DEFAULT_COST+BRANCH_COST);
7359
7360 ins_variable_size_depending_on_alignment(true);
7361
7362 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7363 // Worst case is branch + move + stop, no stop without scheduler.
7364 size(8);
7365 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7366 ins_pipe(pipe_class_default);
7367 %}
7368
7369 // Cmove using isel.
7370 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
7371 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7372 predicate(VM_Version::has_isel());
7373 ins_cost(DEFAULT_COST);
7374
7375 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7376 size(4);
7377 ins_encode %{
7378 // This is a Power7 instruction for which no machine description
7379 // exists. Anyways, the scheduler should be off on Power7.
7380 int cc = $cmp$$cmpcode;
7381 __ isel($dst$$Register, $crx$$CondRegister,
7382 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7383 %}
7384 ins_pipe(pipe_class_default);
7385 %}
7386
7387 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{
7388 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7389 predicate(!VM_Version::has_isel());
7390 ins_cost(DEFAULT_COST+BRANCH_COST);
7391
7392 ins_variable_size_depending_on_alignment(true);
7393
7394 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7395 // Worst case is branch + move + stop, no stop without scheduler.
7396 size(8);
7397 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7398 ins_pipe(pipe_class_default);
7399 %}
7400
7401 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{
7402 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7403 ins_cost(DEFAULT_COST+BRANCH_COST);
7404
7405 ins_variable_size_depending_on_alignment(true);
7406
7407 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7408 // Worst case is branch + move + stop, no stop without scheduler.
7409 size(8);
7410 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7411 ins_pipe(pipe_class_default);
7412 %}
7413
7414 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
7415 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
7416 ins_cost(DEFAULT_COST+BRANCH_COST);
7417
7418 ins_variable_size_depending_on_alignment(true);
7419
7420 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7421 // Worst case is branch + move + stop, no stop without scheduler.
7422 size(8);
7423 ins_encode %{
7424 Label done;
7425 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7426 // Branch if not (cmp crx).
7427 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7428 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7429 __ bind(done);
7430 %}
7431 ins_pipe(pipe_class_default);
7432 %}
7433
7434 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7435 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7436 ins_cost(DEFAULT_COST+BRANCH_COST);
7437
7438 ins_variable_size_depending_on_alignment(true);
7439
7440 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7441 // Worst case is branch + move + stop, no stop without scheduler.
7442 size(8);
7443 ins_encode %{
7444 Label done;
7445 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7446 // Branch if not (cmp crx).
7447 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7448 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7449 __ bind(done);
7450 %}
7451 ins_pipe(pipe_class_default);
7452 %}
7453
7454 //----------Conditional_store--------------------------------------------------
7455 // Conditional-store of the updated heap-top.
7456 // Used during allocation of the shared heap.
7457 // Sets flags (EQ) on success. Implemented with a CASA on Sparc.
7458
7459 // As compareAndSwapL, but return flag register instead of boolean value in
7460 // int register.
7461 // Used by sun/misc/AtomicLongCSImpl.java.
7462 // Mem_ptr must be a memory operand, else this node does not get
7463 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7464 // can be rematerialized which leads to errors.
7465 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{
7466 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal)));
7467 effect(TEMP cr0);
7468 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7469 ins_encode %{
7470 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
7471 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(),
7472 noreg, NULL, true);
7473 %}
7474 ins_pipe(pipe_class_default);
7475 %}
7476
7477 // As compareAndSwapP, but return flag register instead of boolean value in
7478 // int register.
7479 // This instruction is matched if UseTLAB is off.
7480 // Mem_ptr must be a memory operand, else this node does not get
7481 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7482 // can be rematerialized which leads to errors.
7483 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{
7484 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal)));
7485 ins_cost(2*MEMORY_REF_COST);
7486 predicate(n->as_LoadStore()->barrier_data() == 0);
7487
7488 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7489 ins_encode %{
7490 __ stdcx_($newVal$$Register, $mem_ptr$$Register);
7491 %}
7492 ins_pipe(pipe_class_memory);
7493 %}
7494
7495 // Implement LoadPLocked. Must be ordered against changes of the memory location
7496 // by storePConditional.
7497 // Don't know whether this is ever used.
7498 instruct loadPLocked(iRegPdst dst, memory mem) %{
7499 match(Set dst (LoadPLocked mem));
7500 ins_cost(2*MEMORY_REF_COST);
7501
7502 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %}
7503 size(4);
7504 ins_encode %{
7505 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
7506 %}
7507 ins_pipe(pipe_class_memory);
7508 %}
7509
7510 //----------Compare-And-Swap---------------------------------------------------
7511
7512 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7513 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7514 // matched.
7515
7516 // Strong versions:
7517
7518 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7519 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7520 predicate(VM_Version::has_lqarx());
7521 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7522 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7523 ins_encode %{
7524 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7525 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7526 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7527 $res$$Register, true);
7528 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7529 __ isync();
7530 } else {
7531 __ sync();
7532 }
7533 %}
7534 ins_pipe(pipe_class_default);
7535 %}
7536
7537 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7538 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7539 predicate(!VM_Version::has_lqarx());
7540 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7541 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7542 ins_encode %{
7543 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7544 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7545 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7546 $res$$Register, true);
7547 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7548 __ isync();
7549 } else {
7550 __ sync();
7551 }
7552 %}
7553 ins_pipe(pipe_class_default);
7554 %}
7555
7556 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7557 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7558 predicate(VM_Version::has_lqarx());
7559 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7560 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7561 ins_encode %{
7562 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7563 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7564 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7565 $res$$Register, true);
7566 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7567 __ isync();
7568 } else {
7569 __ sync();
7570 }
7571 %}
7572 ins_pipe(pipe_class_default);
7573 %}
7574
7575 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7576 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7577 predicate(!VM_Version::has_lqarx());
7578 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7579 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7580 ins_encode %{
7581 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7582 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7583 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7584 $res$$Register, true);
7585 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7586 __ isync();
7587 } else {
7588 __ sync();
7589 }
7590 %}
7591 ins_pipe(pipe_class_default);
7592 %}
7593
7594 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7595 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7596 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7597 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7598 ins_encode %{
7599 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7600 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7601 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7602 $res$$Register, true);
7603 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7604 __ isync();
7605 } else {
7606 __ sync();
7607 }
7608 %}
7609 ins_pipe(pipe_class_default);
7610 %}
7611
7612 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7613 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7614 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7615 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7616 ins_encode %{
7617 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7618 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7619 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7620 $res$$Register, true);
7621 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7622 __ isync();
7623 } else {
7624 __ sync();
7625 }
7626 %}
7627 ins_pipe(pipe_class_default);
7628 %}
7629
7630 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7631 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7632 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7633 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7634 ins_encode %{
7635 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7636 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7637 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7638 $res$$Register, NULL, true);
7639 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7640 __ isync();
7641 } else {
7642 __ sync();
7643 }
7644 %}
7645 ins_pipe(pipe_class_default);
7646 %}
7647
7648 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7649 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7650 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7651 predicate(n->as_LoadStore()->barrier_data() == 0);
7652 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7653 ins_encode %{
7654 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7655 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7656 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7657 $res$$Register, NULL, true);
7658 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7659 __ isync();
7660 } else {
7661 __ sync();
7662 }
7663 %}
7664 ins_pipe(pipe_class_default);
7665 %}
7666
7667 // Weak versions:
7668
7669 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7670 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7671 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7672 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7673 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7674 ins_encode %{
7675 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7676 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7677 MacroAssembler::MemBarNone,
7678 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7679 %}
7680 ins_pipe(pipe_class_default);
7681 %}
7682
7683 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7684 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7685 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7686 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7687 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7688 ins_encode %{
7689 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7690 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7691 MacroAssembler::MemBarNone,
7692 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7693 %}
7694 ins_pipe(pipe_class_default);
7695 %}
7696
7697 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7698 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7699 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7700 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7701 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7702 ins_encode %{
7703 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7704 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7705 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7706 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7707 %}
7708 ins_pipe(pipe_class_default);
7709 %}
7710
7711 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7712 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7713 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7714 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7715 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7716 ins_encode %{
7717 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7718 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7719 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7720 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7721 %}
7722 ins_pipe(pipe_class_default);
7723 %}
7724
7725 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7726 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7727 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7728 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7729 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7730 ins_encode %{
7731 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7732 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7733 MacroAssembler::MemBarNone,
7734 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7735 %}
7736 ins_pipe(pipe_class_default);
7737 %}
7738
7739 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7740 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7741 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7742 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7743 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7744 ins_encode %{
7745 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7746 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7747 MacroAssembler::MemBarNone,
7748 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7749 %}
7750 ins_pipe(pipe_class_default);
7751 %}
7752
7753 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7754 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7755 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7756 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7757 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7758 ins_encode %{
7759 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7760 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7761 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7762 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7763 %}
7764 ins_pipe(pipe_class_default);
7765 %}
7766
7767 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7768 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7769 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7770 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7771 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7772 ins_encode %{
7773 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7774 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7775 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7776 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7777 %}
7778 ins_pipe(pipe_class_default);
7779 %}
7780
7781 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7782 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7783 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7784 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7785 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7786 ins_encode %{
7787 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7788 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7789 MacroAssembler::MemBarNone,
7790 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7791 %}
7792 ins_pipe(pipe_class_default);
7793 %}
7794
7795 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7796 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7797 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7798 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7799 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7800 ins_encode %{
7801 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7802 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7803 // value is never passed to caller.
7804 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7805 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7806 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7807 %}
7808 ins_pipe(pipe_class_default);
7809 %}
7810
7811 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7812 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7813 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7814 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7815 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7816 ins_encode %{
7817 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7818 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7819 MacroAssembler::MemBarNone,
7820 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7821 %}
7822 ins_pipe(pipe_class_default);
7823 %}
7824
7825 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7826 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7827 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7828 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7829 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7830 ins_encode %{
7831 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7832 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7833 // value is never passed to caller.
7834 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7835 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7836 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7837 %}
7838 ins_pipe(pipe_class_default);
7839 %}
7840
7841 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7842 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7843 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7844 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7845 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7846 ins_encode %{
7847 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7848 // value is never passed to caller.
7849 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7850 MacroAssembler::MemBarNone,
7851 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7852 %}
7853 ins_pipe(pipe_class_default);
7854 %}
7855
7856 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7857 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7858 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7859 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7860 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7861 ins_encode %{
7862 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7863 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7864 // value is never passed to caller.
7865 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7866 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7867 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7868 %}
7869 ins_pipe(pipe_class_default);
7870 %}
7871
7872 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7873 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7874 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7875 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7876 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7877 ins_encode %{
7878 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7879 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7880 MacroAssembler::MemBarNone,
7881 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7882 %}
7883 ins_pipe(pipe_class_default);
7884 %}
7885
7886 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7887 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7888 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7889 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7890 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7891 ins_encode %{
7892 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7893 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7894 // value is never passed to caller.
7895 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7896 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7897 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7898 %}
7899 ins_pipe(pipe_class_default);
7900 %}
7901
7902 // CompareAndExchange
7903
7904 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7905 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7906 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7907 effect(TEMP_DEF res, TEMP cr0);
7908 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7909 ins_encode %{
7910 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7911 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7912 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7913 noreg, true);
7914 %}
7915 ins_pipe(pipe_class_default);
7916 %}
7917
7918 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7919 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7920 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7921 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7922 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7923 ins_encode %{
7924 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7925 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
7926 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7927 noreg, true);
7928 %}
7929 ins_pipe(pipe_class_default);
7930 %}
7931
7932 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7933 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7934 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7935 effect(TEMP_DEF res, TEMP cr0);
7936 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7937 ins_encode %{
7938 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7939 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7940 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7941 noreg, true);
7942 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7943 __ isync();
7944 } else {
7945 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7946 __ sync();
7947 }
7948 %}
7949 ins_pipe(pipe_class_default);
7950 %}
7951
7952 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7953 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7954 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7955 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7956 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7957 ins_encode %{
7958 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7959 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
7960 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7961 noreg, true);
7962 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7963 __ isync();
7964 } else {
7965 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7966 __ sync();
7967 }
7968 %}
7969 ins_pipe(pipe_class_default);
7970 %}
7971
7972 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7973 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7974 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7975 effect(TEMP_DEF res, TEMP cr0);
7976 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7977 ins_encode %{
7978 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7979 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7980 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7981 noreg, true);
7982 %}
7983 ins_pipe(pipe_class_default);
7984 %}
7985
7986 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7987 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7988 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7989 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7990 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7991 ins_encode %{
7992 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7993 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
7994 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7995 noreg, true);
7996 %}
7997 ins_pipe(pipe_class_default);
7998 %}
7999
8000 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8001 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
8002 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
8003 effect(TEMP_DEF res, TEMP cr0);
8004 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
8005 ins_encode %{
8006 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8007 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8008 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8009 noreg, true);
8010 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8011 __ isync();
8012 } else {
8013 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8014 __ sync();
8015 }
8016 %}
8017 ins_pipe(pipe_class_default);
8018 %}
8019
8020 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
8021 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
8022 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
8023 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
8024 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
8025 ins_encode %{
8026 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8027 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
8028 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8029 noreg, true);
8030 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8031 __ isync();
8032 } else {
8033 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8034 __ sync();
8035 }
8036 %}
8037 ins_pipe(pipe_class_default);
8038 %}
8039
8040 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8041 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
8042 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8043 effect(TEMP_DEF res, TEMP cr0);
8044 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
8045 ins_encode %{
8046 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8047 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8048 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8049 noreg, true);
8050 %}
8051 ins_pipe(pipe_class_default);
8052 %}
8053
8054 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8055 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
8056 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8057 effect(TEMP_DEF res, TEMP cr0);
8058 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
8059 ins_encode %{
8060 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8061 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8062 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8063 noreg, true);
8064 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8065 __ isync();
8066 } else {
8067 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8068 __ sync();
8069 }
8070 %}
8071 ins_pipe(pipe_class_default);
8072 %}
8073
8074 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8075 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
8076 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8077 effect(TEMP_DEF res, TEMP cr0);
8078 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
8079 ins_encode %{
8080 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8081 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8082 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8083 noreg, true);
8084 %}
8085 ins_pipe(pipe_class_default);
8086 %}
8087
8088 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8089 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
8090 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8091 effect(TEMP_DEF res, TEMP cr0);
8092 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
8093 ins_encode %{
8094 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8095 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8096 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8097 noreg, true);
8098 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8099 __ isync();
8100 } else {
8101 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8102 __ sync();
8103 }
8104 %}
8105 ins_pipe(pipe_class_default);
8106 %}
8107
8108 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8109 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
8110 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8111 effect(TEMP_DEF res, TEMP cr0);
8112 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
8113 ins_encode %{
8114 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8115 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8116 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8117 noreg, NULL, true);
8118 %}
8119 ins_pipe(pipe_class_default);
8120 %}
8121
8122 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8123 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
8124 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8125 effect(TEMP_DEF res, TEMP cr0);
8126 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
8127 ins_encode %{
8128 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8129 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8130 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8131 noreg, NULL, true);
8132 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8133 __ isync();
8134 } else {
8135 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8136 __ sync();
8137 }
8138 %}
8139 ins_pipe(pipe_class_default);
8140 %}
8141
8142 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8143 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
8144 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst)
8145 && n->as_LoadStore()->barrier_data() == 0);
8146 effect(TEMP_DEF res, TEMP cr0);
8147 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
8148 ins_encode %{
8149 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8150 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8151 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8152 noreg, NULL, true);
8153 %}
8154 ins_pipe(pipe_class_default);
8155 %}
8156
8157 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8158 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
8159 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst)
8160 && n->as_LoadStore()->barrier_data() == 0);
8161 effect(TEMP_DEF res, TEMP cr0);
8162 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
8163 ins_encode %{
8164 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8165 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8166 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8167 noreg, NULL, true);
8168 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8169 __ isync();
8170 } else {
8171 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8172 __ sync();
8173 }
8174 %}
8175 ins_pipe(pipe_class_default);
8176 %}
8177
8178 // Special RMW
8179
8180 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8181 match(Set res (GetAndAddB mem_ptr src));
8182 predicate(VM_Version::has_lqarx());
8183 effect(TEMP_DEF res, TEMP cr0);
8184 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
8185 ins_encode %{
8186 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
8187 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8188 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8189 __ isync();
8190 } else {
8191 __ sync();
8192 }
8193 %}
8194 ins_pipe(pipe_class_default);
8195 %}
8196
8197 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8198 match(Set res (GetAndAddB mem_ptr src));
8199 predicate(!VM_Version::has_lqarx());
8200 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8201 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
8202 ins_encode %{
8203 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
8204 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8205 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8206 __ isync();
8207 } else {
8208 __ sync();
8209 }
8210 %}
8211 ins_pipe(pipe_class_default);
8212 %}
8213
8214 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8215 match(Set res (GetAndAddS mem_ptr src));
8216 predicate(VM_Version::has_lqarx());
8217 effect(TEMP_DEF res, TEMP cr0);
8218 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
8219 ins_encode %{
8220 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
8221 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8222 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8223 __ isync();
8224 } else {
8225 __ sync();
8226 }
8227 %}
8228 ins_pipe(pipe_class_default);
8229 %}
8230
8231 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8232 match(Set res (GetAndAddS mem_ptr src));
8233 predicate(!VM_Version::has_lqarx());
8234 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8235 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
8236 ins_encode %{
8237 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
8238 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8239 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8240 __ isync();
8241 } else {
8242 __ sync();
8243 }
8244 %}
8245 ins_pipe(pipe_class_default);
8246 %}
8247
8248 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8249 match(Set res (GetAndAddI mem_ptr src));
8250 effect(TEMP_DEF res, TEMP cr0);
8251 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
8252 ins_encode %{
8253 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
8254 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
8255 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8256 __ isync();
8257 } else {
8258 __ sync();
8259 }
8260 %}
8261 ins_pipe(pipe_class_default);
8262 %}
8263
8264 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
8265 match(Set res (GetAndAddL mem_ptr src));
8266 effect(TEMP_DEF res, TEMP cr0);
8267 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
8268 ins_encode %{
8269 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
8270 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
8271 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8272 __ isync();
8273 } else {
8274 __ sync();
8275 }
8276 %}
8277 ins_pipe(pipe_class_default);
8278 %}
8279
8280 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8281 match(Set res (GetAndSetB mem_ptr src));
8282 predicate(VM_Version::has_lqarx());
8283 effect(TEMP_DEF res, TEMP cr0);
8284 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
8285 ins_encode %{
8286 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
8287 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8288 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8289 __ isync();
8290 } else {
8291 __ sync();
8292 }
8293 %}
8294 ins_pipe(pipe_class_default);
8295 %}
8296
8297 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8298 match(Set res (GetAndSetB mem_ptr src));
8299 predicate(!VM_Version::has_lqarx());
8300 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8301 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
8302 ins_encode %{
8303 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
8304 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8305 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8306 __ isync();
8307 } else {
8308 __ sync();
8309 }
8310 %}
8311 ins_pipe(pipe_class_default);
8312 %}
8313
8314 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8315 match(Set res (GetAndSetS mem_ptr src));
8316 predicate(VM_Version::has_lqarx());
8317 effect(TEMP_DEF res, TEMP cr0);
8318 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
8319 ins_encode %{
8320 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
8321 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8322 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8323 __ isync();
8324 } else {
8325 __ sync();
8326 }
8327 %}
8328 ins_pipe(pipe_class_default);
8329 %}
8330
8331 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8332 match(Set res (GetAndSetS mem_ptr src));
8333 predicate(!VM_Version::has_lqarx());
8334 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8335 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
8336 ins_encode %{
8337 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
8338 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8339 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8340 __ isync();
8341 } else {
8342 __ sync();
8343 }
8344 %}
8345 ins_pipe(pipe_class_default);
8346 %}
8347
8348 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8349 match(Set res (GetAndSetI mem_ptr src));
8350 effect(TEMP_DEF res, TEMP cr0);
8351 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
8352 ins_encode %{
8353 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
8354 MacroAssembler::cmpxchgx_hint_atomic_update());
8355 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8356 __ isync();
8357 } else {
8358 __ sync();
8359 }
8360 %}
8361 ins_pipe(pipe_class_default);
8362 %}
8363
8364 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
8365 match(Set res (GetAndSetL mem_ptr src));
8366 effect(TEMP_DEF res, TEMP cr0);
8367 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
8368 ins_encode %{
8369 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
8370 MacroAssembler::cmpxchgx_hint_atomic_update());
8371 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8372 __ isync();
8373 } else {
8374 __ sync();
8375 }
8376 %}
8377 ins_pipe(pipe_class_default);
8378 %}
8379
8380 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
8381 match(Set res (GetAndSetP mem_ptr src));
8382 predicate(n->as_LoadStore()->barrier_data() == 0);
8383 effect(TEMP_DEF res, TEMP cr0);
8384 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
8385 ins_encode %{
8386 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
8387 MacroAssembler::cmpxchgx_hint_atomic_update());
8388 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8389 __ isync();
8390 } else {
8391 __ sync();
8392 }
8393 %}
8394 ins_pipe(pipe_class_default);
8395 %}
8396
8397 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
8398 match(Set res (GetAndSetN mem_ptr src));
8399 effect(TEMP_DEF res, TEMP cr0);
8400 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
8401 ins_encode %{
8402 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
8403 MacroAssembler::cmpxchgx_hint_atomic_update());
8404 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8405 __ isync();
8406 } else {
8407 __ sync();
8408 }
8409 %}
8410 ins_pipe(pipe_class_default);
8411 %}
8412
8413 //----------Arithmetic Instructions--------------------------------------------
8414 // Addition Instructions
8415
8416 // Register Addition
8417 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
8418 match(Set dst (AddI src1 src2));
8419 format %{ "ADD $dst, $src1, $src2" %}
8420 size(4);
8421 ins_encode %{
8422 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8423 %}
8424 ins_pipe(pipe_class_default);
8425 %}
8426
8427 // Expand does not work with above instruct. (??)
8428 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8429 // no match-rule
8430 effect(DEF dst, USE src1, USE src2);
8431 format %{ "ADD $dst, $src1, $src2" %}
8432 size(4);
8433 ins_encode %{
8434 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8435 %}
8436 ins_pipe(pipe_class_default);
8437 %}
8438
8439 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
8440 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
8441 ins_cost(DEFAULT_COST*3);
8442
8443 expand %{
8444 // FIXME: we should do this in the ideal world.
8445 iRegIdst tmp1;
8446 iRegIdst tmp2;
8447 addI_reg_reg(tmp1, src1, src2);
8448 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
8449 addI_reg_reg(dst, tmp1, tmp2);
8450 %}
8451 %}
8452
8453 // Immediate Addition
8454 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8455 match(Set dst (AddI src1 src2));
8456 format %{ "ADDI $dst, $src1, $src2" %}
8457 size(4);
8458 ins_encode %{
8459 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8460 %}
8461 ins_pipe(pipe_class_default);
8462 %}
8463
8464 // Immediate Addition with 16-bit shifted operand
8465 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
8466 match(Set dst (AddI src1 src2));
8467 format %{ "ADDIS $dst, $src1, $src2" %}
8468 size(4);
8469 ins_encode %{
8470 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8471 %}
8472 ins_pipe(pipe_class_default);
8473 %}
8474
8475 // Immediate Addition using prefixed addi
8476 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{
8477 match(Set dst (AddI src1 src2));
8478 predicate(PowerArchitecturePPC64 >= 10);
8479 ins_cost(DEFAULT_COST+1);
8480 format %{ "PADDI $dst, $src1, $src2" %}
8481 size(8);
8482 ins_encode %{
8483 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8484 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8485 %}
8486 ins_pipe(pipe_class_default);
8487 ins_alignment(2);
8488 %}
8489
8490 // Long Addition
8491 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8492 match(Set dst (AddL src1 src2));
8493 format %{ "ADD $dst, $src1, $src2 \t// long" %}
8494 size(4);
8495 ins_encode %{
8496 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8497 %}
8498 ins_pipe(pipe_class_default);
8499 %}
8500
8501 // Expand does not work with above instruct. (??)
8502 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8503 // no match-rule
8504 effect(DEF dst, USE src1, USE src2);
8505 format %{ "ADD $dst, $src1, $src2 \t// long" %}
8506 size(4);
8507 ins_encode %{
8508 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8509 %}
8510 ins_pipe(pipe_class_default);
8511 %}
8512
8513 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
8514 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
8515 ins_cost(DEFAULT_COST*3);
8516
8517 expand %{
8518 // FIXME: we should do this in the ideal world.
8519 iRegLdst tmp1;
8520 iRegLdst tmp2;
8521 addL_reg_reg(tmp1, src1, src2);
8522 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
8523 addL_reg_reg(dst, tmp1, tmp2);
8524 %}
8525 %}
8526
8527 // AddL + ConvL2I.
8528 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8529 match(Set dst (ConvL2I (AddL src1 src2)));
8530
8531 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %}
8532 size(4);
8533 ins_encode %{
8534 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8535 %}
8536 ins_pipe(pipe_class_default);
8537 %}
8538
8539 // No constant pool entries required.
8540 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8541 match(Set dst (AddL src1 src2));
8542
8543 format %{ "ADDI $dst, $src1, $src2" %}
8544 size(4);
8545 ins_encode %{
8546 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8547 %}
8548 ins_pipe(pipe_class_default);
8549 %}
8550
8551 // Long Immediate Addition with 16-bit shifted operand.
8552 // No constant pool entries required.
8553 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
8554 match(Set dst (AddL src1 src2));
8555
8556 format %{ "ADDIS $dst, $src1, $src2" %}
8557 size(4);
8558 ins_encode %{
8559 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8560 %}
8561 ins_pipe(pipe_class_default);
8562 %}
8563
8564 // Long Immediate Addition using prefixed addi
8565 // No constant pool entries required.
8566 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{
8567 match(Set dst (AddL src1 src2));
8568 predicate(PowerArchitecturePPC64 >= 10);
8569 ins_cost(DEFAULT_COST+1);
8570
8571 format %{ "PADDI $dst, $src1, $src2" %}
8572 size(8);
8573 ins_encode %{
8574 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8575 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8576 %}
8577 ins_pipe(pipe_class_default);
8578 ins_alignment(2);
8579 %}
8580
8581 // Pointer Register Addition
8582 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
8583 match(Set dst (AddP src1 src2));
8584 format %{ "ADD $dst, $src1, $src2" %}
8585 size(4);
8586 ins_encode %{
8587 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8588 %}
8589 ins_pipe(pipe_class_default);
8590 %}
8591
8592 // Pointer Immediate Addition
8593 // No constant pool entries required.
8594 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
8595 match(Set dst (AddP src1 src2));
8596
8597 format %{ "ADDI $dst, $src1, $src2" %}
8598 size(4);
8599 ins_encode %{
8600 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8601 %}
8602 ins_pipe(pipe_class_default);
8603 %}
8604
8605 // Pointer Immediate Addition with 16-bit shifted operand.
8606 // No constant pool entries required.
8607 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
8608 match(Set dst (AddP src1 src2));
8609
8610 format %{ "ADDIS $dst, $src1, $src2" %}
8611 size(4);
8612 ins_encode %{
8613 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8614 %}
8615 ins_pipe(pipe_class_default);
8616 %}
8617
8618 // Pointer Immediate Addition using prefixed addi
8619 // No constant pool entries required.
8620 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{
8621 match(Set dst (AddP src1 src2));
8622 predicate(PowerArchitecturePPC64 >= 10);
8623 ins_cost(DEFAULT_COST+1);
8624
8625 format %{ "PADDI $dst, $src1, $src2" %}
8626 size(8);
8627 ins_encode %{
8628 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8629 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8630 %}
8631 ins_pipe(pipe_class_default);
8632 ins_alignment(2);
8633 %}
8634
8635 //---------------------
8636 // Subtraction Instructions
8637
8638 // Register Subtraction
8639 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8640 match(Set dst (SubI src1 src2));
8641 format %{ "SUBF $dst, $src2, $src1" %}
8642 size(4);
8643 ins_encode %{
8644 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8645 %}
8646 ins_pipe(pipe_class_default);
8647 %}
8648
8649 // Immediate Subtraction
8650 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
8651 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
8652
8653 // SubI from constant (using subfic).
8654 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
8655 match(Set dst (SubI src1 src2));
8656 format %{ "SUBI $dst, $src1, $src2" %}
8657
8658 size(4);
8659 ins_encode %{
8660 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
8661 %}
8662 ins_pipe(pipe_class_default);
8663 %}
8664
8665 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
8666 // positive integers and 0xF...F for negative ones.
8667 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
8668 // no match-rule, false predicate
8669 effect(DEF dst, USE src);
8670 predicate(false);
8671
8672 format %{ "SRAWI $dst, $src, #31" %}
8673 size(4);
8674 ins_encode %{
8675 __ srawi($dst$$Register, $src$$Register, 0x1f);
8676 %}
8677 ins_pipe(pipe_class_default);
8678 %}
8679
8680 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
8681 match(Set dst (AbsI src));
8682 ins_cost(DEFAULT_COST*3);
8683
8684 expand %{
8685 iRegIdst tmp1;
8686 iRegIdst tmp2;
8687 signmask32I_regI(tmp1, src);
8688 xorI_reg_reg(tmp2, tmp1, src);
8689 subI_reg_reg(dst, tmp2, tmp1);
8690 %}
8691 %}
8692
8693 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
8694 match(Set dst (SubI zero src2));
8695 format %{ "NEG $dst, $src2" %}
8696 size(4);
8697 ins_encode %{
8698 __ neg($dst$$Register, $src2$$Register);
8699 %}
8700 ins_pipe(pipe_class_default);
8701 %}
8702
8703 // Long subtraction
8704 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8705 match(Set dst (SubL src1 src2));
8706 format %{ "SUBF $dst, $src2, $src1 \t// long" %}
8707 size(4);
8708 ins_encode %{
8709 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8710 %}
8711 ins_pipe(pipe_class_default);
8712 %}
8713
8714 // SubL + convL2I.
8715 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8716 match(Set dst (ConvL2I (SubL src1 src2)));
8717
8718 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
8719 size(4);
8720 ins_encode %{
8721 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8722 %}
8723 ins_pipe(pipe_class_default);
8724 %}
8725
8726 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8727 // positive longs and 0xF...F for negative ones.
8728 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8729 // no match-rule, false predicate
8730 effect(DEF dst, USE src);
8731 predicate(false);
8732
8733 format %{ "SRADI $dst, $src, #63" %}
8734 size(4);
8735 ins_encode %{
8736 __ sradi($dst$$Register, $src$$Register, 0x3f);
8737 %}
8738 ins_pipe(pipe_class_default);
8739 %}
8740
8741 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8742 // positive longs and 0xF...F for negative ones.
8743 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8744 // no match-rule, false predicate
8745 effect(DEF dst, USE src);
8746 predicate(false);
8747
8748 format %{ "SRADI $dst, $src, #63" %}
8749 size(4);
8750 ins_encode %{
8751 __ sradi($dst$$Register, $src$$Register, 0x3f);
8752 %}
8753 ins_pipe(pipe_class_default);
8754 %}
8755
8756 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{
8757 match(Set dst (AbsL src));
8758 ins_cost(DEFAULT_COST*3);
8759
8760 expand %{
8761 iRegLdst tmp1;
8762 iRegLdst tmp2;
8763 signmask64L_regL(tmp1, src);
8764 xorL_reg_reg(tmp2, tmp1, src);
8765 subL_reg_reg(dst, tmp2, tmp1);
8766 %}
8767 %}
8768
8769 // Long negation
8770 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8771 match(Set dst (SubL zero src2));
8772 format %{ "NEG $dst, $src2 \t// long" %}
8773 size(4);
8774 ins_encode %{
8775 __ neg($dst$$Register, $src2$$Register);
8776 %}
8777 ins_pipe(pipe_class_default);
8778 %}
8779
8780 // NegL + ConvL2I.
8781 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8782 match(Set dst (ConvL2I (SubL zero src2)));
8783
8784 format %{ "NEG $dst, $src2 \t// long + l2i" %}
8785 size(4);
8786 ins_encode %{
8787 __ neg($dst$$Register, $src2$$Register);
8788 %}
8789 ins_pipe(pipe_class_default);
8790 %}
8791
8792 // Multiplication Instructions
8793 // Integer Multiplication
8794
8795 // Register Multiplication
8796 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8797 match(Set dst (MulI src1 src2));
8798 ins_cost(DEFAULT_COST);
8799
8800 format %{ "MULLW $dst, $src1, $src2" %}
8801 size(4);
8802 ins_encode %{
8803 __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8804 %}
8805 ins_pipe(pipe_class_default);
8806 %}
8807
8808 // Immediate Multiplication
8809 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8810 match(Set dst (MulI src1 src2));
8811 ins_cost(DEFAULT_COST);
8812
8813 format %{ "MULLI $dst, $src1, $src2" %}
8814 size(4);
8815 ins_encode %{
8816 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8817 %}
8818 ins_pipe(pipe_class_default);
8819 %}
8820
8821 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8822 match(Set dst (MulL src1 src2));
8823 ins_cost(DEFAULT_COST);
8824
8825 format %{ "MULLD $dst $src1, $src2 \t// long" %}
8826 size(4);
8827 ins_encode %{
8828 __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8829 %}
8830 ins_pipe(pipe_class_default);
8831 %}
8832
8833 // Multiply high for optimized long division by constant.
8834 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8835 match(Set dst (MulHiL src1 src2));
8836 ins_cost(DEFAULT_COST);
8837
8838 format %{ "MULHD $dst $src1, $src2 \t// long" %}
8839 size(4);
8840 ins_encode %{
8841 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8842 %}
8843 ins_pipe(pipe_class_default);
8844 %}
8845
8846 // Immediate Multiplication
8847 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8848 match(Set dst (MulL src1 src2));
8849 ins_cost(DEFAULT_COST);
8850
8851 format %{ "MULLI $dst, $src1, $src2" %}
8852 size(4);
8853 ins_encode %{
8854 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8855 %}
8856 ins_pipe(pipe_class_default);
8857 %}
8858
8859 // Integer Division with Immediate -1: Negate.
8860 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8861 match(Set dst (DivI src1 src2));
8862 ins_cost(DEFAULT_COST);
8863
8864 format %{ "NEG $dst, $src1 \t// /-1" %}
8865 size(4);
8866 ins_encode %{
8867 __ neg($dst$$Register, $src1$$Register);
8868 %}
8869 ins_pipe(pipe_class_default);
8870 %}
8871
8872 // Integer Division with constant, but not -1.
8873 // We should be able to improve this by checking the type of src2.
8874 // It might well be that src2 is known to be positive.
8875 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8876 match(Set dst (DivI src1 src2));
8877 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8878 ins_cost(2*DEFAULT_COST);
8879
8880 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8881 size(4);
8882 ins_encode %{
8883 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8884 %}
8885 ins_pipe(pipe_class_default);
8886 %}
8887
8888 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8889 effect(USE_DEF dst, USE src1, USE crx);
8890 predicate(false);
8891
8892 ins_variable_size_depending_on_alignment(true);
8893
8894 format %{ "CMOVE $dst, neg($src1), $crx" %}
8895 // Worst case is branch + move + stop, no stop without scheduler.
8896 size(8);
8897 ins_encode %{
8898 Label done;
8899 __ bne($crx$$CondRegister, done);
8900 __ neg($dst$$Register, $src1$$Register);
8901 __ bind(done);
8902 %}
8903 ins_pipe(pipe_class_default);
8904 %}
8905
8906 // Integer Division with Registers not containing constants.
8907 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8908 match(Set dst (DivI src1 src2));
8909 ins_cost(10*DEFAULT_COST);
8910
8911 expand %{
8912 immI16 imm %{ (int)-1 %}
8913 flagsReg tmp1;
8914 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8915 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8916 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8917 %}
8918 %}
8919
8920 // Long Division with Immediate -1: Negate.
8921 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8922 match(Set dst (DivL src1 src2));
8923 ins_cost(DEFAULT_COST);
8924
8925 format %{ "NEG $dst, $src1 \t// /-1, long" %}
8926 size(4);
8927 ins_encode %{
8928 __ neg($dst$$Register, $src1$$Register);
8929 %}
8930 ins_pipe(pipe_class_default);
8931 %}
8932
8933 // Long Division with constant, but not -1.
8934 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8935 match(Set dst (DivL src1 src2));
8936 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8937 ins_cost(2*DEFAULT_COST);
8938
8939 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8940 size(4);
8941 ins_encode %{
8942 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8943 %}
8944 ins_pipe(pipe_class_default);
8945 %}
8946
8947 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8948 effect(USE_DEF dst, USE src1, USE crx);
8949 predicate(false);
8950
8951 ins_variable_size_depending_on_alignment(true);
8952
8953 format %{ "CMOVE $dst, neg($src1), $crx" %}
8954 // Worst case is branch + move + stop, no stop without scheduler.
8955 size(8);
8956 ins_encode %{
8957 Label done;
8958 __ bne($crx$$CondRegister, done);
8959 __ neg($dst$$Register, $src1$$Register);
8960 __ bind(done);
8961 %}
8962 ins_pipe(pipe_class_default);
8963 %}
8964
8965 // Long Division with Registers not containing constants.
8966 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8967 match(Set dst (DivL src1 src2));
8968 ins_cost(10*DEFAULT_COST);
8969
8970 expand %{
8971 immL16 imm %{ (int)-1 %}
8972 flagsReg tmp1;
8973 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8974 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8975 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8976 %}
8977 %}
8978
8979 // Integer Remainder with registers.
8980 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8981 match(Set dst (ModI src1 src2));
8982 ins_cost(10*DEFAULT_COST);
8983
8984 expand %{
8985 immI16 imm %{ (int)-1 %}
8986 flagsReg tmp1;
8987 iRegIdst tmp2;
8988 iRegIdst tmp3;
8989 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8990 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8991 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8992 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8993 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8994 %}
8995 %}
8996
8997 // Long Remainder with registers
8998 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8999 match(Set dst (ModL src1 src2));
9000 ins_cost(10*DEFAULT_COST);
9001
9002 expand %{
9003 immL16 imm %{ (int)-1 %}
9004 flagsReg tmp1;
9005 iRegLdst tmp2;
9006 iRegLdst tmp3;
9007 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
9008 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
9009 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
9010 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
9011 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
9012 %}
9013 %}
9014
9015 // Integer Shift Instructions
9016
9017 // Register Shift Left
9018
9019 // Clear all but the lowest #mask bits.
9020 // Used to normalize shift amounts in registers.
9021 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
9022 // no match-rule, false predicate
9023 effect(DEF dst, USE src, USE mask);
9024 predicate(false);
9025
9026 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %}
9027 size(4);
9028 ins_encode %{
9029 __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
9030 %}
9031 ins_pipe(pipe_class_default);
9032 %}
9033
9034 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9035 // no match-rule, false predicate
9036 effect(DEF dst, USE src1, USE src2);
9037 predicate(false);
9038
9039 format %{ "SLW $dst, $src1, $src2" %}
9040 size(4);
9041 ins_encode %{
9042 __ slw($dst$$Register, $src1$$Register, $src2$$Register);
9043 %}
9044 ins_pipe(pipe_class_default);
9045 %}
9046
9047 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9048 match(Set dst (LShiftI src1 src2));
9049 ins_cost(DEFAULT_COST*2);
9050 expand %{
9051 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
9052 iRegIdst tmpI;
9053 maskI_reg_imm(tmpI, src2, mask);
9054 lShiftI_reg_reg(dst, src1, tmpI);
9055 %}
9056 %}
9057
9058 // Register Shift Left Immediate
9059 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
9060 match(Set dst (LShiftI src1 src2));
9061
9062 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %}
9063 size(4);
9064 ins_encode %{
9065 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
9066 %}
9067 ins_pipe(pipe_class_default);
9068 %}
9069
9070 // AndI with negpow2-constant + LShiftI
9071 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
9072 match(Set dst (LShiftI (AndI src1 src2) src3));
9073 predicate(UseRotateAndMaskInstructionsPPC64);
9074
9075 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %}
9076 size(4);
9077 ins_encode %{
9078 long src3 = $src3$$constant;
9079 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
9080 if (maskbits >= 32) {
9081 __ li($dst$$Register, 0); // addi
9082 } else {
9083 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
9084 }
9085 %}
9086 ins_pipe(pipe_class_default);
9087 %}
9088
9089 // RShiftI + AndI with negpow2-constant + LShiftI
9090 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
9091 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
9092 predicate(UseRotateAndMaskInstructionsPPC64);
9093
9094 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
9095 size(4);
9096 ins_encode %{
9097 long src3 = $src3$$constant;
9098 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
9099 if (maskbits >= 32) {
9100 __ li($dst$$Register, 0); // addi
9101 } else {
9102 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
9103 }
9104 %}
9105 ins_pipe(pipe_class_default);
9106 %}
9107
9108 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9109 // no match-rule, false predicate
9110 effect(DEF dst, USE src1, USE src2);
9111 predicate(false);
9112
9113 format %{ "SLD $dst, $src1, $src2" %}
9114 size(4);
9115 ins_encode %{
9116 __ sld($dst$$Register, $src1$$Register, $src2$$Register);
9117 %}
9118 ins_pipe(pipe_class_default);
9119 %}
9120
9121 // Register Shift Left
9122 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9123 match(Set dst (LShiftL src1 src2));
9124 ins_cost(DEFAULT_COST*2);
9125 expand %{
9126 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
9127 iRegIdst tmpI;
9128 maskI_reg_imm(tmpI, src2, mask);
9129 lShiftL_regL_regI(dst, src1, tmpI);
9130 %}
9131 %}
9132
9133 // Register Shift Left Immediate
9134 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
9135 match(Set dst (LShiftL src1 src2));
9136 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %}
9137 size(4);
9138 ins_encode %{
9139 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9140 %}
9141 ins_pipe(pipe_class_default);
9142 %}
9143
9144 // If we shift more than 32 bits, we need not convert I2L.
9145 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
9146 match(Set dst (LShiftL (ConvI2L src1) src2));
9147 ins_cost(DEFAULT_COST);
9148
9149 size(4);
9150 format %{ "SLDI $dst, i2l($src1), $src2" %}
9151 ins_encode %{
9152 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9153 %}
9154 ins_pipe(pipe_class_default);
9155 %}
9156
9157 // Shift a postivie int to the left.
9158 // Clrlsldi clears the upper 32 bits and shifts.
9159 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
9160 match(Set dst (LShiftL (ConvI2L src1) src2));
9161 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
9162
9163 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %}
9164 size(4);
9165 ins_encode %{
9166 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
9167 %}
9168 ins_pipe(pipe_class_default);
9169 %}
9170
9171 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9172 // no match-rule, false predicate
9173 effect(DEF dst, USE src1, USE src2);
9174 predicate(false);
9175
9176 format %{ "SRAW $dst, $src1, $src2" %}
9177 size(4);
9178 ins_encode %{
9179 __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
9180 %}
9181 ins_pipe(pipe_class_default);
9182 %}
9183
9184 // Register Arithmetic Shift Right
9185 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9186 match(Set dst (RShiftI src1 src2));
9187 ins_cost(DEFAULT_COST*2);
9188 expand %{
9189 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
9190 iRegIdst tmpI;
9191 maskI_reg_imm(tmpI, src2, mask);
9192 arShiftI_reg_reg(dst, src1, tmpI);
9193 %}
9194 %}
9195
9196 // Register Arithmetic Shift Right Immediate
9197 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
9198 match(Set dst (RShiftI src1 src2));
9199
9200 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %}
9201 size(4);
9202 ins_encode %{
9203 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
9204 %}
9205 ins_pipe(pipe_class_default);
9206 %}
9207
9208 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9209 // no match-rule, false predicate
9210 effect(DEF dst, USE src1, USE src2);
9211 predicate(false);
9212
9213 format %{ "SRAD $dst, $src1, $src2" %}
9214 size(4);
9215 ins_encode %{
9216 __ srad($dst$$Register, $src1$$Register, $src2$$Register);
9217 %}
9218 ins_pipe(pipe_class_default);
9219 %}
9220
9221 // Register Shift Right Arithmetic Long
9222 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9223 match(Set dst (RShiftL src1 src2));
9224 ins_cost(DEFAULT_COST*2);
9225
9226 expand %{
9227 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
9228 iRegIdst tmpI;
9229 maskI_reg_imm(tmpI, src2, mask);
9230 arShiftL_regL_regI(dst, src1, tmpI);
9231 %}
9232 %}
9233
9234 // Register Shift Right Immediate
9235 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
9236 match(Set dst (RShiftL src1 src2));
9237
9238 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %}
9239 size(4);
9240 ins_encode %{
9241 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9242 %}
9243 ins_pipe(pipe_class_default);
9244 %}
9245
9246 // RShiftL + ConvL2I
9247 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
9248 match(Set dst (ConvL2I (RShiftL src1 src2)));
9249
9250 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
9251 size(4);
9252 ins_encode %{
9253 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9254 %}
9255 ins_pipe(pipe_class_default);
9256 %}
9257
9258 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9259 // no match-rule, false predicate
9260 effect(DEF dst, USE src1, USE src2);
9261 predicate(false);
9262
9263 format %{ "SRW $dst, $src1, $src2" %}
9264 size(4);
9265 ins_encode %{
9266 __ srw($dst$$Register, $src1$$Register, $src2$$Register);
9267 %}
9268 ins_pipe(pipe_class_default);
9269 %}
9270
9271 // Register Shift Right
9272 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9273 match(Set dst (URShiftI src1 src2));
9274 ins_cost(DEFAULT_COST*2);
9275
9276 expand %{
9277 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
9278 iRegIdst tmpI;
9279 maskI_reg_imm(tmpI, src2, mask);
9280 urShiftI_reg_reg(dst, src1, tmpI);
9281 %}
9282 %}
9283
9284 // Register Shift Right Immediate
9285 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
9286 match(Set dst (URShiftI src1 src2));
9287
9288 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %}
9289 size(4);
9290 ins_encode %{
9291 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
9292 %}
9293 ins_pipe(pipe_class_default);
9294 %}
9295
9296 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9297 // no match-rule, false predicate
9298 effect(DEF dst, USE src1, USE src2);
9299 predicate(false);
9300
9301 format %{ "SRD $dst, $src1, $src2" %}
9302 size(4);
9303 ins_encode %{
9304 __ srd($dst$$Register, $src1$$Register, $src2$$Register);
9305 %}
9306 ins_pipe(pipe_class_default);
9307 %}
9308
9309 // Register Shift Right
9310 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9311 match(Set dst (URShiftL src1 src2));
9312 ins_cost(DEFAULT_COST*2);
9313
9314 expand %{
9315 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
9316 iRegIdst tmpI;
9317 maskI_reg_imm(tmpI, src2, mask);
9318 urShiftL_regL_regI(dst, src1, tmpI);
9319 %}
9320 %}
9321
9322 // Register Shift Right Immediate
9323 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
9324 match(Set dst (URShiftL src1 src2));
9325
9326 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %}
9327 size(4);
9328 ins_encode %{
9329 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9330 %}
9331 ins_pipe(pipe_class_default);
9332 %}
9333
9334 // URShiftL + ConvL2I.
9335 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
9336 match(Set dst (ConvL2I (URShiftL src1 src2)));
9337
9338 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
9339 size(4);
9340 ins_encode %{
9341 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9342 %}
9343 ins_pipe(pipe_class_default);
9344 %}
9345
9346 // Register Shift Right Immediate with a CastP2X
9347 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
9348 match(Set dst (URShiftL (CastP2X src1) src2));
9349
9350 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
9351 size(4);
9352 ins_encode %{
9353 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9354 %}
9355 ins_pipe(pipe_class_default);
9356 %}
9357
9358 // Bitfield Extract: URShiftI + AndI
9359 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
9360 match(Set dst (AndI (URShiftI src1 src2) src3));
9361
9362 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
9363 size(4);
9364 ins_encode %{
9365 int rshift = ($src2$$constant) & 0x1f;
9366 int length = log2i_exact((juint)$src3$$constant + 1u);
9367 if (rshift + length > 32) {
9368 // if necessary, adjust mask to omit rotated bits.
9369 length = 32 - rshift;
9370 }
9371 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
9372 %}
9373 ins_pipe(pipe_class_default);
9374 %}
9375
9376 // Bitfield Extract: URShiftL + AndL
9377 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
9378 match(Set dst (AndL (URShiftL src1 src2) src3));
9379
9380 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
9381 size(4);
9382 ins_encode %{
9383 int rshift = ($src2$$constant) & 0x3f;
9384 int length = log2i_exact((julong)$src3$$constant + 1ull);
9385 if (rshift + length > 64) {
9386 // if necessary, adjust mask to omit rotated bits.
9387 length = 64 - rshift;
9388 }
9389 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
9390 %}
9391 ins_pipe(pipe_class_default);
9392 %}
9393
9394 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
9395 match(Set dst (ConvL2I (ConvI2L src)));
9396
9397 format %{ "EXTSW $dst, $src \t// int->int" %}
9398 size(4);
9399 ins_encode %{
9400 __ extsw($dst$$Register, $src$$Register);
9401 %}
9402 ins_pipe(pipe_class_default);
9403 %}
9404
9405 //----------Rotate Instructions------------------------------------------------
9406
9407 // Rotate Left by 8-bit immediate
9408 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
9409 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
9410 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9411
9412 format %{ "ROTLWI $dst, $src, $lshift" %}
9413 size(4);
9414 ins_encode %{
9415 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
9416 %}
9417 ins_pipe(pipe_class_default);
9418 %}
9419
9420 // Rotate Right by 8-bit immediate
9421 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
9422 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
9423 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9424
9425 format %{ "ROTRWI $dst, $rshift" %}
9426 size(4);
9427 ins_encode %{
9428 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
9429 %}
9430 ins_pipe(pipe_class_default);
9431 %}
9432
9433 //----------Floating Point Arithmetic Instructions-----------------------------
9434
9435 // Add float single precision
9436 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
9437 match(Set dst (AddF src1 src2));
9438
9439 format %{ "FADDS $dst, $src1, $src2" %}
9440 size(4);
9441 ins_encode %{
9442 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9443 %}
9444 ins_pipe(pipe_class_default);
9445 %}
9446
9447 // Add float double precision
9448 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
9449 match(Set dst (AddD src1 src2));
9450
9451 format %{ "FADD $dst, $src1, $src2" %}
9452 size(4);
9453 ins_encode %{
9454 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9455 %}
9456 ins_pipe(pipe_class_default);
9457 %}
9458
9459 // Sub float single precision
9460 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
9461 match(Set dst (SubF src1 src2));
9462
9463 format %{ "FSUBS $dst, $src1, $src2" %}
9464 size(4);
9465 ins_encode %{
9466 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9467 %}
9468 ins_pipe(pipe_class_default);
9469 %}
9470
9471 // Sub float double precision
9472 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
9473 match(Set dst (SubD src1 src2));
9474 format %{ "FSUB $dst, $src1, $src2" %}
9475 size(4);
9476 ins_encode %{
9477 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9478 %}
9479 ins_pipe(pipe_class_default);
9480 %}
9481
9482 // Mul float single precision
9483 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
9484 match(Set dst (MulF src1 src2));
9485 format %{ "FMULS $dst, $src1, $src2" %}
9486 size(4);
9487 ins_encode %{
9488 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9489 %}
9490 ins_pipe(pipe_class_default);
9491 %}
9492
9493 // Mul float double precision
9494 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
9495 match(Set dst (MulD src1 src2));
9496 format %{ "FMUL $dst, $src1, $src2" %}
9497 size(4);
9498 ins_encode %{
9499 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9500 %}
9501 ins_pipe(pipe_class_default);
9502 %}
9503
9504 // Div float single precision
9505 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
9506 match(Set dst (DivF src1 src2));
9507 format %{ "FDIVS $dst, $src1, $src2" %}
9508 size(4);
9509 ins_encode %{
9510 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9511 %}
9512 ins_pipe(pipe_class_default);
9513 %}
9514
9515 // Div float double precision
9516 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
9517 match(Set dst (DivD src1 src2));
9518 format %{ "FDIV $dst, $src1, $src2" %}
9519 size(4);
9520 ins_encode %{
9521 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9522 %}
9523 ins_pipe(pipe_class_default);
9524 %}
9525
9526 // Absolute float single precision
9527 instruct absF_reg(regF dst, regF src) %{
9528 match(Set dst (AbsF src));
9529 format %{ "FABS $dst, $src \t// float" %}
9530 size(4);
9531 ins_encode %{
9532 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
9533 %}
9534 ins_pipe(pipe_class_default);
9535 %}
9536
9537 // Absolute float double precision
9538 instruct absD_reg(regD dst, regD src) %{
9539 match(Set dst (AbsD src));
9540 format %{ "FABS $dst, $src \t// double" %}
9541 size(4);
9542 ins_encode %{
9543 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
9544 %}
9545 ins_pipe(pipe_class_default);
9546 %}
9547
9548 instruct negF_reg(regF dst, regF src) %{
9549 match(Set dst (NegF src));
9550 format %{ "FNEG $dst, $src \t// float" %}
9551 size(4);
9552 ins_encode %{
9553 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
9554 %}
9555 ins_pipe(pipe_class_default);
9556 %}
9557
9558 instruct negD_reg(regD dst, regD src) %{
9559 match(Set dst (NegD src));
9560 format %{ "FNEG $dst, $src \t// double" %}
9561 size(4);
9562 ins_encode %{
9563 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
9564 %}
9565 ins_pipe(pipe_class_default);
9566 %}
9567
9568 // AbsF + NegF.
9569 instruct negF_absF_reg(regF dst, regF src) %{
9570 match(Set dst (NegF (AbsF src)));
9571 format %{ "FNABS $dst, $src \t// float" %}
9572 size(4);
9573 ins_encode %{
9574 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9575 %}
9576 ins_pipe(pipe_class_default);
9577 %}
9578
9579 // AbsD + NegD.
9580 instruct negD_absD_reg(regD dst, regD src) %{
9581 match(Set dst (NegD (AbsD src)));
9582 format %{ "FNABS $dst, $src \t// double" %}
9583 size(4);
9584 ins_encode %{
9585 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9586 %}
9587 ins_pipe(pipe_class_default);
9588 %}
9589
9590 // VM_Version::has_fsqrt() decides if this node will be used.
9591 // Sqrt float double precision
9592 instruct sqrtD_reg(regD dst, regD src) %{
9593 match(Set dst (SqrtD src));
9594 format %{ "FSQRT $dst, $src" %}
9595 size(4);
9596 ins_encode %{
9597 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
9598 %}
9599 ins_pipe(pipe_class_default);
9600 %}
9601
9602 // Single-precision sqrt.
9603 instruct sqrtF_reg(regF dst, regF src) %{
9604 match(Set dst (SqrtF src));
9605 predicate(VM_Version::has_fsqrts());
9606 ins_cost(DEFAULT_COST);
9607
9608 format %{ "FSQRTS $dst, $src" %}
9609 size(4);
9610 ins_encode %{
9611 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
9612 %}
9613 ins_pipe(pipe_class_default);
9614 %}
9615
9616 instruct roundDouble_nop(regD dst) %{
9617 match(Set dst (RoundDouble dst));
9618 ins_cost(0);
9619
9620 format %{ " -- \t// RoundDouble not needed - empty" %}
9621 size(0);
9622 // PPC results are already "rounded" (i.e., normal-format IEEE).
9623 ins_encode( /*empty*/ );
9624 ins_pipe(pipe_class_default);
9625 %}
9626
9627 instruct roundFloat_nop(regF dst) %{
9628 match(Set dst (RoundFloat dst));
9629 ins_cost(0);
9630
9631 format %{ " -- \t// RoundFloat not needed - empty" %}
9632 size(0);
9633 // PPC results are already "rounded" (i.e., normal-format IEEE).
9634 ins_encode( /*empty*/ );
9635 ins_pipe(pipe_class_default);
9636 %}
9637
9638
9639 // Multiply-Accumulate
9640 // src1 * src2 + src3
9641 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9642 match(Set dst (FmaF src3 (Binary src1 src2)));
9643
9644 format %{ "FMADDS $dst, $src1, $src2, $src3" %}
9645 size(4);
9646 ins_encode %{
9647 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9648 %}
9649 ins_pipe(pipe_class_default);
9650 %}
9651
9652 // src1 * src2 + src3
9653 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9654 match(Set dst (FmaD src3 (Binary src1 src2)));
9655
9656 format %{ "FMADD $dst, $src1, $src2, $src3" %}
9657 size(4);
9658 ins_encode %{
9659 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9660 %}
9661 ins_pipe(pipe_class_default);
9662 %}
9663
9664 // -src1 * src2 + src3 = -(src1*src2-src3)
9665 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9666 match(Set dst (FmaF src3 (Binary (NegF src1) src2)));
9667 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
9668
9669 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
9670 size(4);
9671 ins_encode %{
9672 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9673 %}
9674 ins_pipe(pipe_class_default);
9675 %}
9676
9677 // -src1 * src2 + src3 = -(src1*src2-src3)
9678 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9679 match(Set dst (FmaD src3 (Binary (NegD src1) src2)));
9680 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
9681
9682 format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
9683 size(4);
9684 ins_encode %{
9685 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9686 %}
9687 ins_pipe(pipe_class_default);
9688 %}
9689
9690 // -src1 * src2 - src3 = -(src1*src2+src3)
9691 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9692 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2)));
9693 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
9694
9695 format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
9696 size(4);
9697 ins_encode %{
9698 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9699 %}
9700 ins_pipe(pipe_class_default);
9701 %}
9702
9703 // -src1 * src2 - src3 = -(src1*src2+src3)
9704 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9705 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2)));
9706 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9707
9708 format %{ "FNMADD $dst, $src1, $src2, $src3" %}
9709 size(4);
9710 ins_encode %{
9711 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9712 %}
9713 ins_pipe(pipe_class_default);
9714 %}
9715
9716 // src1 * src2 - src3
9717 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9718 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9719
9720 format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
9721 size(4);
9722 ins_encode %{
9723 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9724 %}
9725 ins_pipe(pipe_class_default);
9726 %}
9727
9728 // src1 * src2 - src3
9729 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9730 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9731
9732 format %{ "FMSUB $dst, $src1, $src2, $src3" %}
9733 size(4);
9734 ins_encode %{
9735 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9736 %}
9737 ins_pipe(pipe_class_default);
9738 %}
9739
9740
9741 //----------Logical Instructions-----------------------------------------------
9742
9743 // And Instructions
9744
9745 // Register And
9746 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9747 match(Set dst (AndI src1 src2));
9748 format %{ "AND $dst, $src1, $src2" %}
9749 size(4);
9750 ins_encode %{
9751 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9752 %}
9753 ins_pipe(pipe_class_default);
9754 %}
9755
9756 // Left shifted Immediate And
9757 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{
9758 match(Set dst (AndI src1 src2));
9759 effect(KILL cr0);
9760 format %{ "ANDIS $dst, $src1, $src2.hi" %}
9761 size(4);
9762 ins_encode %{
9763 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16)));
9764 %}
9765 ins_pipe(pipe_class_default);
9766 %}
9767
9768 // Immediate And
9769 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{
9770 match(Set dst (AndI src1 src2));
9771 effect(KILL cr0);
9772
9773 format %{ "ANDI $dst, $src1, $src2" %}
9774 size(4);
9775 ins_encode %{
9776 // FIXME: avoid andi_ ?
9777 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9778 %}
9779 ins_pipe(pipe_class_default);
9780 %}
9781
9782 // Immediate And where the immediate is a negative power of 2.
9783 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{
9784 match(Set dst (AndI src1 src2));
9785 format %{ "ANDWI $dst, $src1, $src2" %}
9786 size(4);
9787 ins_encode %{
9788 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant));
9789 %}
9790 ins_pipe(pipe_class_default);
9791 %}
9792
9793 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{
9794 match(Set dst (AndI src1 src2));
9795 format %{ "ANDWI $dst, $src1, $src2" %}
9796 size(4);
9797 ins_encode %{
9798 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u));
9799 %}
9800 ins_pipe(pipe_class_default);
9801 %}
9802
9803 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{
9804 match(Set dst (AndI src1 src2));
9805 predicate(UseRotateAndMaskInstructionsPPC64);
9806 format %{ "ANDWI $dst, $src1, $src2" %}
9807 size(4);
9808 ins_encode %{
9809 int bitpos = 31 - log2i_exact((juint)$src2$$constant);
9810 __ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos);
9811 %}
9812 ins_pipe(pipe_class_default);
9813 %}
9814
9815 // Register And Long
9816 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9817 match(Set dst (AndL src1 src2));
9818 ins_cost(DEFAULT_COST);
9819
9820 format %{ "AND $dst, $src1, $src2 \t// long" %}
9821 size(4);
9822 ins_encode %{
9823 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9824 %}
9825 ins_pipe(pipe_class_default);
9826 %}
9827
9828 // Immediate And long
9829 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
9830 match(Set dst (AndL src1 src2));
9831 effect(KILL cr0);
9832
9833 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9834 size(4);
9835 ins_encode %{
9836 // FIXME: avoid andi_ ?
9837 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9838 %}
9839 ins_pipe(pipe_class_default);
9840 %}
9841
9842 // Immediate And Long where the immediate is a negative power of 2.
9843 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
9844 match(Set dst (AndL src1 src2));
9845 format %{ "ANDDI $dst, $src1, $src2" %}
9846 size(4);
9847 ins_encode %{
9848 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant));
9849 %}
9850 ins_pipe(pipe_class_default);
9851 %}
9852
9853 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9854 match(Set dst (AndL src1 src2));
9855 format %{ "ANDDI $dst, $src1, $src2" %}
9856 size(4);
9857 ins_encode %{
9858 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9859 %}
9860 ins_pipe(pipe_class_default);
9861 %}
9862
9863 // AndL + ConvL2I.
9864 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9865 match(Set dst (ConvL2I (AndL src1 src2)));
9866 ins_cost(DEFAULT_COST);
9867
9868 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %}
9869 size(4);
9870 ins_encode %{
9871 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9872 %}
9873 ins_pipe(pipe_class_default);
9874 %}
9875
9876 // Or Instructions
9877
9878 // Register Or
9879 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9880 match(Set dst (OrI src1 src2));
9881 format %{ "OR $dst, $src1, $src2" %}
9882 size(4);
9883 ins_encode %{
9884 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9885 %}
9886 ins_pipe(pipe_class_default);
9887 %}
9888
9889 // Expand does not work with above instruct. (??)
9890 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9891 // no match-rule
9892 effect(DEF dst, USE src1, USE src2);
9893 format %{ "OR $dst, $src1, $src2" %}
9894 size(4);
9895 ins_encode %{
9896 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9897 %}
9898 ins_pipe(pipe_class_default);
9899 %}
9900
9901 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9902 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9903 ins_cost(DEFAULT_COST*3);
9904
9905 expand %{
9906 // FIXME: we should do this in the ideal world.
9907 iRegIdst tmp1;
9908 iRegIdst tmp2;
9909 orI_reg_reg(tmp1, src1, src2);
9910 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9911 orI_reg_reg(dst, tmp1, tmp2);
9912 %}
9913 %}
9914
9915 // Immediate Or
9916 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9917 match(Set dst (OrI src1 src2));
9918 format %{ "ORI $dst, $src1, $src2" %}
9919 size(4);
9920 ins_encode %{
9921 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9922 %}
9923 ins_pipe(pipe_class_default);
9924 %}
9925
9926 // Register Or Long
9927 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9928 match(Set dst (OrL src1 src2));
9929 ins_cost(DEFAULT_COST);
9930
9931 size(4);
9932 format %{ "OR $dst, $src1, $src2 \t// long" %}
9933 ins_encode %{
9934 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9935 %}
9936 ins_pipe(pipe_class_default);
9937 %}
9938
9939 // OrL + ConvL2I.
9940 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9941 match(Set dst (ConvL2I (OrL src1 src2)));
9942 ins_cost(DEFAULT_COST);
9943
9944 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %}
9945 size(4);
9946 ins_encode %{
9947 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9948 %}
9949 ins_pipe(pipe_class_default);
9950 %}
9951
9952 // Immediate Or long
9953 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9954 match(Set dst (OrL src1 con));
9955 ins_cost(DEFAULT_COST);
9956
9957 format %{ "ORI $dst, $src1, $con \t// long" %}
9958 size(4);
9959 ins_encode %{
9960 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9961 %}
9962 ins_pipe(pipe_class_default);
9963 %}
9964
9965 // Xor Instructions
9966
9967 // Register Xor
9968 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9969 match(Set dst (XorI src1 src2));
9970 format %{ "XOR $dst, $src1, $src2" %}
9971 size(4);
9972 ins_encode %{
9973 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9974 %}
9975 ins_pipe(pipe_class_default);
9976 %}
9977
9978 // Expand does not work with above instruct. (??)
9979 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9980 // no match-rule
9981 effect(DEF dst, USE src1, USE src2);
9982 format %{ "XOR $dst, $src1, $src2" %}
9983 size(4);
9984 ins_encode %{
9985 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9986 %}
9987 ins_pipe(pipe_class_default);
9988 %}
9989
9990 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9991 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
9992 ins_cost(DEFAULT_COST*3);
9993
9994 expand %{
9995 // FIXME: we should do this in the ideal world.
9996 iRegIdst tmp1;
9997 iRegIdst tmp2;
9998 xorI_reg_reg(tmp1, src1, src2);
9999 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
10000 xorI_reg_reg(dst, tmp1, tmp2);
10001 %}
10002 %}
10003
10004 // Immediate Xor
10005 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
10006 match(Set dst (XorI src1 src2));
10007 format %{ "XORI $dst, $src1, $src2" %}
10008 size(4);
10009 ins_encode %{
10010 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
10011 %}
10012 ins_pipe(pipe_class_default);
10013 %}
10014
10015 // Register Xor Long
10016 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
10017 match(Set dst (XorL src1 src2));
10018 ins_cost(DEFAULT_COST);
10019
10020 format %{ "XOR $dst, $src1, $src2 \t// long" %}
10021 size(4);
10022 ins_encode %{
10023 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
10024 %}
10025 ins_pipe(pipe_class_default);
10026 %}
10027
10028 // XorL + ConvL2I.
10029 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
10030 match(Set dst (ConvL2I (XorL src1 src2)));
10031 ins_cost(DEFAULT_COST);
10032
10033 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %}
10034 size(4);
10035 ins_encode %{
10036 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
10037 %}
10038 ins_pipe(pipe_class_default);
10039 %}
10040
10041 // Immediate Xor Long
10042 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
10043 match(Set dst (XorL src1 src2));
10044 ins_cost(DEFAULT_COST);
10045
10046 format %{ "XORI $dst, $src1, $src2 \t// long" %}
10047 size(4);
10048 ins_encode %{
10049 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
10050 %}
10051 ins_pipe(pipe_class_default);
10052 %}
10053
10054 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
10055 match(Set dst (XorI src1 src2));
10056 ins_cost(DEFAULT_COST);
10057
10058 format %{ "NOT $dst, $src1 ($src2)" %}
10059 size(4);
10060 ins_encode %{
10061 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
10062 %}
10063 ins_pipe(pipe_class_default);
10064 %}
10065
10066 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
10067 match(Set dst (XorL src1 src2));
10068 ins_cost(DEFAULT_COST);
10069
10070 format %{ "NOT $dst, $src1 ($src2) \t// long" %}
10071 size(4);
10072 ins_encode %{
10073 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
10074 %}
10075 ins_pipe(pipe_class_default);
10076 %}
10077
10078 // And-complement
10079 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
10080 match(Set dst (AndI (XorI src1 src2) src3));
10081 ins_cost(DEFAULT_COST);
10082
10083 format %{ "ANDW $dst, xori($src1, $src2), $src3" %}
10084 size(4);
10085 ins_encode( enc_andc(dst, src3, src1) );
10086 ins_pipe(pipe_class_default);
10087 %}
10088
10089 // And-complement
10090 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
10091 // no match-rule, false predicate
10092 effect(DEF dst, USE src1, USE src2);
10093 predicate(false);
10094
10095 format %{ "ANDC $dst, $src1, $src2" %}
10096 size(4);
10097 ins_encode %{
10098 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
10099 %}
10100 ins_pipe(pipe_class_default);
10101 %}
10102
10103 //----------Moves between int/long and float/double----------------------------
10104 //
10105 // The following rules move values from int/long registers/stack-locations
10106 // to float/double registers/stack-locations and vice versa, without doing any
10107 // conversions. These rules are used to implement the bit-conversion methods
10108 // of java.lang.Float etc., e.g.
10109 // int floatToIntBits(float value)
10110 // float intBitsToFloat(int bits)
10111 //
10112 // Notes on the implementation on ppc64:
10113 // For Power7 and earlier, the rules are limited to those which move between a
10114 // register and a stack-location, because we always have to go through memory
10115 // when moving between a float register and an integer register.
10116 // This restriction is removed in Power8 with the introduction of the mtfprd
10117 // and mffprd instructions.
10118
10119 instruct moveL2D_reg(regD dst, iRegLsrc src) %{
10120 match(Set dst (MoveL2D src));
10121 predicate(VM_Version::has_mtfprd());
10122
10123 format %{ "MTFPRD $dst, $src" %}
10124 size(4);
10125 ins_encode %{
10126 __ mtfprd($dst$$FloatRegister, $src$$Register);
10127 %}
10128 ins_pipe(pipe_class_default);
10129 %}
10130
10131 instruct moveI2D_reg(regD dst, iRegIsrc src) %{
10132 // no match-rule, false predicate
10133 effect(DEF dst, USE src);
10134 predicate(false);
10135
10136 format %{ "MTFPRWA $dst, $src" %}
10137 size(4);
10138 ins_encode %{
10139 __ mtfprwa($dst$$FloatRegister, $src$$Register);
10140 %}
10141 ins_pipe(pipe_class_default);
10142 %}
10143
10144 //---------- Chain stack slots between similar types --------
10145
10146 // These are needed so that the rules below can match.
10147
10148 // Load integer from stack slot
10149 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
10150 match(Set dst src);
10151 ins_cost(MEMORY_REF_COST);
10152
10153 format %{ "LWZ $dst, $src" %}
10154 size(4);
10155 ins_encode( enc_lwz(dst, src) );
10156 ins_pipe(pipe_class_memory);
10157 %}
10158
10159 // Store integer to stack slot
10160 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
10161 match(Set dst src);
10162 ins_cost(MEMORY_REF_COST);
10163
10164 format %{ "STW $src, $dst \t// stk" %}
10165 size(4);
10166 ins_encode( enc_stw(src, dst) ); // rs=rt
10167 ins_pipe(pipe_class_memory);
10168 %}
10169
10170 // Load long from stack slot
10171 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
10172 match(Set dst src);
10173 ins_cost(MEMORY_REF_COST);
10174
10175 format %{ "LD $dst, $src \t// long" %}
10176 size(4);
10177 ins_encode( enc_ld(dst, src) );
10178 ins_pipe(pipe_class_memory);
10179 %}
10180
10181 // Store long to stack slot
10182 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
10183 match(Set dst src);
10184 ins_cost(MEMORY_REF_COST);
10185
10186 format %{ "STD $src, $dst \t// long" %}
10187 size(4);
10188 ins_encode( enc_std(src, dst) ); // rs=rt
10189 ins_pipe(pipe_class_memory);
10190 %}
10191
10192 //----------Moves between int and float
10193
10194 // Move float value from float stack-location to integer register.
10195 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
10196 match(Set dst (MoveF2I src));
10197 ins_cost(MEMORY_REF_COST);
10198
10199 format %{ "LWZ $dst, $src \t// MoveF2I" %}
10200 size(4);
10201 ins_encode( enc_lwz(dst, src) );
10202 ins_pipe(pipe_class_memory);
10203 %}
10204
10205 // Move float value from float register to integer stack-location.
10206 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
10207 match(Set dst (MoveF2I src));
10208 ins_cost(MEMORY_REF_COST);
10209
10210 format %{ "STFS $src, $dst \t// MoveF2I" %}
10211 size(4);
10212 ins_encode( enc_stfs(src, dst) );
10213 ins_pipe(pipe_class_memory);
10214 %}
10215
10216 // Move integer value from integer stack-location to float register.
10217 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
10218 match(Set dst (MoveI2F src));
10219 ins_cost(MEMORY_REF_COST);
10220
10221 format %{ "LFS $dst, $src \t// MoveI2F" %}
10222 size(4);
10223 ins_encode %{
10224 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
10225 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
10226 %}
10227 ins_pipe(pipe_class_memory);
10228 %}
10229
10230 // Move integer value from integer register to float stack-location.
10231 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
10232 match(Set dst (MoveI2F src));
10233 ins_cost(MEMORY_REF_COST);
10234
10235 format %{ "STW $src, $dst \t// MoveI2F" %}
10236 size(4);
10237 ins_encode( enc_stw(src, dst) );
10238 ins_pipe(pipe_class_memory);
10239 %}
10240
10241 //----------Moves between long and float
10242
10243 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{
10244 // no match-rule, false predicate
10245 effect(DEF dst, USE src);
10246 predicate(false);
10247
10248 format %{ "storeD $src, $dst \t// STACK" %}
10249 size(4);
10250 ins_encode( enc_stfd(src, dst) );
10251 ins_pipe(pipe_class_default);
10252 %}
10253
10254 //----------Moves between long and double
10255
10256 // Move double value from double stack-location to long register.
10257 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
10258 match(Set dst (MoveD2L src));
10259 ins_cost(MEMORY_REF_COST);
10260 size(4);
10261 format %{ "LD $dst, $src \t// MoveD2L" %}
10262 ins_encode( enc_ld(dst, src) );
10263 ins_pipe(pipe_class_memory);
10264 %}
10265
10266 // Move double value from double register to long stack-location.
10267 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
10268 match(Set dst (MoveD2L src));
10269 effect(DEF dst, USE src);
10270 ins_cost(MEMORY_REF_COST);
10271
10272 format %{ "STFD $src, $dst \t// MoveD2L" %}
10273 size(4);
10274 ins_encode( enc_stfd(src, dst) );
10275 ins_pipe(pipe_class_memory);
10276 %}
10277
10278 // Move long value from long stack-location to double register.
10279 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{
10280 match(Set dst (MoveL2D src));
10281 ins_cost(MEMORY_REF_COST);
10282
10283 format %{ "LFD $dst, $src \t// MoveL2D" %}
10284 size(4);
10285 ins_encode( enc_lfd(dst, src) );
10286 ins_pipe(pipe_class_memory);
10287 %}
10288
10289 // Move long value from long register to double stack-location.
10290 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{
10291 match(Set dst (MoveL2D src));
10292 ins_cost(MEMORY_REF_COST);
10293
10294 format %{ "STD $src, $dst \t// MoveL2D" %}
10295 size(4);
10296 ins_encode( enc_std(src, dst) );
10297 ins_pipe(pipe_class_memory);
10298 %}
10299
10300 //----------Register Move Instructions-----------------------------------------
10301
10302 // Replicate for Superword
10303
10304 instruct moveReg(iRegLdst dst, iRegIsrc src) %{
10305 predicate(false);
10306 effect(DEF dst, USE src);
10307
10308 format %{ "MR $dst, $src \t// replicate " %}
10309 // variable size, 0 or 4.
10310 ins_encode %{
10311 __ mr_if_needed($dst$$Register, $src$$Register);
10312 %}
10313 ins_pipe(pipe_class_default);
10314 %}
10315
10316 //----------Cast instructions (Java-level type cast)---------------------------
10317
10318 // Cast Long to Pointer for unsafe natives.
10319 instruct castX2P(iRegPdst dst, iRegLsrc src) %{
10320 match(Set dst (CastX2P src));
10321
10322 format %{ "MR $dst, $src \t// Long->Ptr" %}
10323 // variable size, 0 or 4.
10324 ins_encode %{
10325 __ mr_if_needed($dst$$Register, $src$$Register);
10326 %}
10327 ins_pipe(pipe_class_default);
10328 %}
10329
10330 // Cast Pointer to Long for unsafe natives.
10331 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
10332 match(Set dst (CastP2X src));
10333
10334 format %{ "MR $dst, $src \t// Ptr->Long" %}
10335 // variable size, 0 or 4.
10336 ins_encode %{
10337 __ mr_if_needed($dst$$Register, $src$$Register);
10338 %}
10339 ins_pipe(pipe_class_default);
10340 %}
10341
10342 instruct castPP(iRegPdst dst) %{
10343 match(Set dst (CastPP dst));
10344 format %{ " -- \t// castPP of $dst" %}
10345 size(0);
10346 ins_encode( /*empty*/ );
10347 ins_pipe(pipe_class_default);
10348 %}
10349
10350 instruct castII(iRegIdst dst) %{
10351 match(Set dst (CastII dst));
10352 format %{ " -- \t// castII of $dst" %}
10353 size(0);
10354 ins_encode( /*empty*/ );
10355 ins_pipe(pipe_class_default);
10356 %}
10357
10358 instruct castLL(iRegLdst dst) %{
10359 match(Set dst (CastLL dst));
10360 format %{ " -- \t// castLL of $dst" %}
10361 size(0);
10362 ins_encode( /*empty*/ );
10363 ins_pipe(pipe_class_default);
10364 %}
10365
10366 instruct castFF(regF dst) %{
10367 match(Set dst (CastFF dst));
10368 format %{ " -- \t// castFF of $dst" %}
10369 size(0);
10370 ins_encode( /*empty*/ );
10371 ins_pipe(pipe_class_default);
10372 %}
10373
10374 instruct castDD(regD dst) %{
10375 match(Set dst (CastDD dst));
10376 format %{ " -- \t// castDD of $dst" %}
10377 size(0);
10378 ins_encode( /*empty*/ );
10379 ins_pipe(pipe_class_default);
10380 %}
10381
10382 instruct castVV8(iRegLdst dst) %{
10383 match(Set dst (CastVV dst));
10384 format %{ " -- \t// castVV of $dst" %}
10385 size(0);
10386 ins_encode( /*empty*/ );
10387 ins_pipe(pipe_class_default);
10388 %}
10389
10390 instruct castVV16(vecX dst) %{
10391 match(Set dst (CastVV dst));
10392 format %{ " -- \t// castVV of $dst" %}
10393 size(0);
10394 ins_encode( /*empty*/ );
10395 ins_pipe(pipe_class_default);
10396 %}
10397
10398 instruct checkCastPP(iRegPdst dst) %{
10399 match(Set dst (CheckCastPP dst));
10400 format %{ " -- \t// checkcastPP of $dst" %}
10401 size(0);
10402 ins_encode( /*empty*/ );
10403 ins_pipe(pipe_class_default);
10404 %}
10405
10406 //----------Convert instructions-----------------------------------------------
10407
10408 // Convert to boolean.
10409
10410 // int_to_bool(src) : { 1 if src != 0
10411 // { 0 else
10412 //
10413 // strategy:
10414 // 1) Count leading zeros of 32 bit-value src,
10415 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
10416 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
10417 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
10418
10419 // convI2Bool
10420 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
10421 match(Set dst (Conv2B src));
10422 predicate(UseCountLeadingZerosInstructionsPPC64);
10423 ins_cost(DEFAULT_COST);
10424
10425 expand %{
10426 immI shiftAmount %{ 0x5 %}
10427 uimmI16 mask %{ 0x1 %}
10428 iRegIdst tmp1;
10429 iRegIdst tmp2;
10430 countLeadingZerosI(tmp1, src);
10431 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
10432 xorI_reg_uimm16(dst, tmp2, mask);
10433 %}
10434 %}
10435
10436 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
10437 match(Set dst (Conv2B src));
10438 effect(TEMP crx);
10439 predicate(!UseCountLeadingZerosInstructionsPPC64);
10440 ins_cost(DEFAULT_COST);
10441
10442 format %{ "CMPWI $crx, $src, #0 \t// convI2B"
10443 "LI $dst, #0\n\t"
10444 "BEQ $crx, done\n\t"
10445 "LI $dst, #1\n"
10446 "done:" %}
10447 size(16);
10448 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
10449 ins_pipe(pipe_class_compare);
10450 %}
10451
10452 // ConvI2B + XorI
10453 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
10454 match(Set dst (XorI (Conv2B src) mask));
10455 predicate(UseCountLeadingZerosInstructionsPPC64);
10456 ins_cost(DEFAULT_COST);
10457
10458 expand %{
10459 immI shiftAmount %{ 0x5 %}
10460 iRegIdst tmp1;
10461 countLeadingZerosI(tmp1, src);
10462 urShiftI_reg_imm(dst, tmp1, shiftAmount);
10463 %}
10464 %}
10465
10466 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
10467 match(Set dst (XorI (Conv2B src) mask));
10468 effect(TEMP crx);
10469 predicate(!UseCountLeadingZerosInstructionsPPC64);
10470 ins_cost(DEFAULT_COST);
10471
10472 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
10473 "LI $dst, #1\n\t"
10474 "BEQ $crx, done\n\t"
10475 "LI $dst, #0\n"
10476 "done:" %}
10477 size(16);
10478 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
10479 ins_pipe(pipe_class_compare);
10480 %}
10481
10482 // AndI 0b0..010..0 + ConvI2B
10483 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
10484 match(Set dst (Conv2B (AndI src mask)));
10485 predicate(UseRotateAndMaskInstructionsPPC64);
10486 ins_cost(DEFAULT_COST);
10487
10488 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
10489 size(4);
10490 ins_encode %{
10491 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31);
10492 %}
10493 ins_pipe(pipe_class_default);
10494 %}
10495
10496 // Convert pointer to boolean.
10497 //
10498 // ptr_to_bool(src) : { 1 if src != 0
10499 // { 0 else
10500 //
10501 // strategy:
10502 // 1) Count leading zeros of 64 bit-value src,
10503 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
10504 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
10505 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
10506
10507 // ConvP2B
10508 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
10509 match(Set dst (Conv2B src));
10510 predicate(UseCountLeadingZerosInstructionsPPC64);
10511 ins_cost(DEFAULT_COST);
10512
10513 expand %{
10514 immI shiftAmount %{ 0x6 %}
10515 uimmI16 mask %{ 0x1 %}
10516 iRegIdst tmp1;
10517 iRegIdst tmp2;
10518 countLeadingZerosP(tmp1, src);
10519 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
10520 xorI_reg_uimm16(dst, tmp2, mask);
10521 %}
10522 %}
10523
10524 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
10525 match(Set dst (Conv2B src));
10526 effect(TEMP crx);
10527 predicate(!UseCountLeadingZerosInstructionsPPC64);
10528 ins_cost(DEFAULT_COST);
10529
10530 format %{ "CMPDI $crx, $src, #0 \t// convP2B"
10531 "LI $dst, #0\n\t"
10532 "BEQ $crx, done\n\t"
10533 "LI $dst, #1\n"
10534 "done:" %}
10535 size(16);
10536 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
10537 ins_pipe(pipe_class_compare);
10538 %}
10539
10540 // ConvP2B + XorI
10541 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
10542 match(Set dst (XorI (Conv2B src) mask));
10543 predicate(UseCountLeadingZerosInstructionsPPC64);
10544 ins_cost(DEFAULT_COST);
10545
10546 expand %{
10547 immI shiftAmount %{ 0x6 %}
10548 iRegIdst tmp1;
10549 countLeadingZerosP(tmp1, src);
10550 urShiftI_reg_imm(dst, tmp1, shiftAmount);
10551 %}
10552 %}
10553
10554 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
10555 match(Set dst (XorI (Conv2B src) mask));
10556 effect(TEMP crx);
10557 predicate(!UseCountLeadingZerosInstructionsPPC64);
10558 ins_cost(DEFAULT_COST);
10559
10560 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
10561 "LI $dst, #1\n\t"
10562 "BEQ $crx, done\n\t"
10563 "LI $dst, #0\n"
10564 "done:" %}
10565 size(16);
10566 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
10567 ins_pipe(pipe_class_compare);
10568 %}
10569
10570 // if src1 < src2, return -1 else return 0
10571 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
10572 match(Set dst (CmpLTMask src1 src2));
10573 ins_cost(DEFAULT_COST*4);
10574
10575 expand %{
10576 iRegLdst src1s;
10577 iRegLdst src2s;
10578 iRegLdst diff;
10579 convI2L_reg(src1s, src1); // Ensure proper sign extension.
10580 convI2L_reg(src2s, src2); // Ensure proper sign extension.
10581 subL_reg_reg(diff, src1s, src2s);
10582 // Need to consider >=33 bit result, therefore we need signmaskL.
10583 signmask64I_regL(dst, diff);
10584 %}
10585 %}
10586
10587 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
10588 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
10589 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %}
10590 size(4);
10591 ins_encode %{
10592 __ srawi($dst$$Register, $src1$$Register, 0x1f);
10593 %}
10594 ins_pipe(pipe_class_default);
10595 %}
10596
10597 //----------Arithmetic Conversion Instructions---------------------------------
10598
10599 // Convert to Byte -- nop
10600 // Convert to Short -- nop
10601
10602 // Convert to Int
10603
10604 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
10605 match(Set dst (RShiftI (LShiftI src amount) amount));
10606 format %{ "EXTSB $dst, $src \t// byte->int" %}
10607 size(4);
10608 ins_encode %{
10609 __ extsb($dst$$Register, $src$$Register);
10610 %}
10611 ins_pipe(pipe_class_default);
10612 %}
10613
10614 instruct extsh(iRegIdst dst, iRegIsrc src) %{
10615 effect(DEF dst, USE src);
10616
10617 size(4);
10618 ins_encode %{
10619 __ extsh($dst$$Register, $src$$Register);
10620 %}
10621 ins_pipe(pipe_class_default);
10622 %}
10623
10624 // LShiftI 16 + RShiftI 16 converts short to int.
10625 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
10626 match(Set dst (RShiftI (LShiftI src amount) amount));
10627 format %{ "EXTSH $dst, $src \t// short->int" %}
10628 size(4);
10629 ins_encode %{
10630 __ extsh($dst$$Register, $src$$Register);
10631 %}
10632 ins_pipe(pipe_class_default);
10633 %}
10634
10635 // ConvL2I + ConvI2L: Sign extend int in long register.
10636 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
10637 match(Set dst (ConvI2L (ConvL2I src)));
10638
10639 format %{ "EXTSW $dst, $src \t// long->long" %}
10640 size(4);
10641 ins_encode %{
10642 __ extsw($dst$$Register, $src$$Register);
10643 %}
10644 ins_pipe(pipe_class_default);
10645 %}
10646
10647 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
10648 match(Set dst (ConvL2I src));
10649 format %{ "MR $dst, $src \t// long->int" %}
10650 // variable size, 0 or 4
10651 ins_encode %{
10652 __ mr_if_needed($dst$$Register, $src$$Register);
10653 %}
10654 ins_pipe(pipe_class_default);
10655 %}
10656
10657 instruct convD2IRaw_regD(regD dst, regD src) %{
10658 // no match-rule, false predicate
10659 effect(DEF dst, USE src);
10660 predicate(false);
10661
10662 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
10663 size(4);
10664 ins_encode %{
10665 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10666 %}
10667 ins_pipe(pipe_class_default);
10668 %}
10669
10670 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
10671 // no match-rule, false predicate
10672 effect(DEF dst, USE crx, USE src);
10673 predicate(false);
10674
10675 ins_variable_size_depending_on_alignment(true);
10676
10677 format %{ "cmovI $crx, $dst, $src" %}
10678 // Worst case is branch + move + stop, no stop without scheduler.
10679 size(8);
10680 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10681 ins_pipe(pipe_class_default);
10682 %}
10683
10684 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
10685 // no match-rule, false predicate
10686 effect(DEF dst, USE crx, USE src);
10687 predicate(false);
10688
10689 ins_variable_size_depending_on_alignment(true);
10690
10691 format %{ "cmovI $crx, $dst, $src" %}
10692 // Worst case is branch + move + stop, no stop without scheduler.
10693 size(8);
10694 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10695 ins_pipe(pipe_class_default);
10696 %}
10697
10698 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{
10699 // no match-rule, false predicate
10700 effect(DEF dst, USE crx, USE mem);
10701 predicate(false);
10702
10703 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %}
10704 postalloc_expand %{
10705 //
10706 // replaces
10707 //
10708 // region dst crx mem
10709 // \ | | /
10710 // dst=cmovI_bso_stackSlotL_conLvalue0
10711 //
10712 // with
10713 //
10714 // region dst
10715 // \ /
10716 // dst=loadConI16(0)
10717 // |
10718 // ^ region dst crx mem
10719 // | \ | | /
10720 // dst=cmovI_bso_stackSlotL
10721 //
10722
10723 // Create new nodes.
10724 MachNode *m1 = new loadConI16Node();
10725 MachNode *m2 = new cmovI_bso_stackSlotLNode();
10726
10727 // inputs for new nodes
10728 m1->add_req(n_region);
10729 m2->add_req(n_region, n_crx, n_mem);
10730
10731 // precedences for new nodes
10732 m2->add_prec(m1);
10733
10734 // operands for new nodes
10735 m1->_opnds[0] = op_dst;
10736 m1->_opnds[1] = new immI16Oper(0);
10737
10738 m2->_opnds[0] = op_dst;
10739 m2->_opnds[1] = op_crx;
10740 m2->_opnds[2] = op_mem;
10741
10742 // registers for new nodes
10743 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10744 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10745
10746 // Insert new nodes.
10747 nodes->push(m1);
10748 nodes->push(m2);
10749 %}
10750 %}
10751
10752 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{
10753 // no match-rule, false predicate
10754 effect(DEF dst, USE crx, USE src);
10755 predicate(false);
10756
10757 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %}
10758 postalloc_expand %{
10759 //
10760 // replaces
10761 //
10762 // region dst crx src
10763 // \ | | /
10764 // dst=cmovI_bso_reg_conLvalue0
10765 //
10766 // with
10767 //
10768 // region dst
10769 // \ /
10770 // dst=loadConI16(0)
10771 // |
10772 // ^ region dst crx src
10773 // | \ | | /
10774 // dst=cmovI_bso_reg
10775 //
10776
10777 // Create new nodes.
10778 MachNode *m1 = new loadConI16Node();
10779 MachNode *m2 = new cmovI_bso_regNode();
10780
10781 // inputs for new nodes
10782 m1->add_req(n_region);
10783 m2->add_req(n_region, n_crx, n_src);
10784
10785 // precedences for new nodes
10786 m2->add_prec(m1);
10787
10788 // operands for new nodes
10789 m1->_opnds[0] = op_dst;
10790 m1->_opnds[1] = new immI16Oper(0);
10791
10792 m2->_opnds[0] = op_dst;
10793 m2->_opnds[1] = op_crx;
10794 m2->_opnds[2] = op_src;
10795
10796 // registers for new nodes
10797 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10798 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10799
10800 // Insert new nodes.
10801 nodes->push(m1);
10802 nodes->push(m2);
10803 %}
10804 %}
10805
10806 // Double to Int conversion, NaN is mapped to 0.
10807 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{
10808 match(Set dst (ConvD2I src));
10809 predicate(!VM_Version::has_mtfprd());
10810 ins_cost(DEFAULT_COST);
10811
10812 expand %{
10813 regD tmpD;
10814 stackSlotL tmpS;
10815 flagsReg crx;
10816 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10817 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
10818 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated).
10819 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
10820 %}
10821 %}
10822
10823 // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
10824 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
10825 match(Set dst (ConvD2I src));
10826 predicate(VM_Version::has_mtfprd());
10827 ins_cost(DEFAULT_COST);
10828
10829 expand %{
10830 regD tmpD;
10831 flagsReg crx;
10832 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10833 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
10834 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10835 %}
10836 %}
10837
10838 instruct convF2IRaw_regF(regF dst, regF src) %{
10839 // no match-rule, false predicate
10840 effect(DEF dst, USE src);
10841 predicate(false);
10842
10843 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
10844 size(4);
10845 ins_encode %{
10846 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10847 %}
10848 ins_pipe(pipe_class_default);
10849 %}
10850
10851 // Float to Int conversion, NaN is mapped to 0.
10852 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{
10853 match(Set dst (ConvF2I src));
10854 predicate(!VM_Version::has_mtfprd());
10855 ins_cost(DEFAULT_COST);
10856
10857 expand %{
10858 regF tmpF;
10859 stackSlotL tmpS;
10860 flagsReg crx;
10861 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10862 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10863 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated).
10864 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
10865 %}
10866 %}
10867
10868 // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
10869 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
10870 match(Set dst (ConvF2I src));
10871 predicate(VM_Version::has_mtfprd());
10872 ins_cost(DEFAULT_COST);
10873
10874 expand %{
10875 regF tmpF;
10876 flagsReg crx;
10877 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10878 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10879 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10880 %}
10881 %}
10882
10883 // Convert to Long
10884
10885 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
10886 match(Set dst (ConvI2L src));
10887 format %{ "EXTSW $dst, $src \t// int->long" %}
10888 size(4);
10889 ins_encode %{
10890 __ extsw($dst$$Register, $src$$Register);
10891 %}
10892 ins_pipe(pipe_class_default);
10893 %}
10894
10895 // Zero-extend: convert unsigned int to long (convUI2L).
10896 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
10897 match(Set dst (AndL (ConvI2L src) mask));
10898 ins_cost(DEFAULT_COST);
10899
10900 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10901 size(4);
10902 ins_encode %{
10903 __ clrldi($dst$$Register, $src$$Register, 32);
10904 %}
10905 ins_pipe(pipe_class_default);
10906 %}
10907
10908 // Zero-extend: convert unsigned int to long in long register.
10909 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
10910 match(Set dst (AndL src mask));
10911 ins_cost(DEFAULT_COST);
10912
10913 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10914 size(4);
10915 ins_encode %{
10916 __ clrldi($dst$$Register, $src$$Register, 32);
10917 %}
10918 ins_pipe(pipe_class_default);
10919 %}
10920
10921 instruct convF2LRaw_regF(regF dst, regF src) %{
10922 // no match-rule, false predicate
10923 effect(DEF dst, USE src);
10924 predicate(false);
10925
10926 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10927 size(4);
10928 ins_encode %{
10929 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10930 %}
10931 ins_pipe(pipe_class_default);
10932 %}
10933
10934 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
10935 // no match-rule, false predicate
10936 effect(DEF dst, USE crx, USE src);
10937 predicate(false);
10938
10939 ins_variable_size_depending_on_alignment(true);
10940
10941 format %{ "cmovL $crx, $dst, $src" %}
10942 // Worst case is branch + move + stop, no stop without scheduler.
10943 size(8);
10944 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10945 ins_pipe(pipe_class_default);
10946 %}
10947
10948 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
10949 // no match-rule, false predicate
10950 effect(DEF dst, USE crx, USE src);
10951 predicate(false);
10952
10953 ins_variable_size_depending_on_alignment(true);
10954
10955 format %{ "cmovL $crx, $dst, $src" %}
10956 // Worst case is branch + move + stop, no stop without scheduler.
10957 size(8);
10958 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10959 ins_pipe(pipe_class_default);
10960 %}
10961
10962 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{
10963 // no match-rule, false predicate
10964 effect(DEF dst, USE crx, USE mem);
10965 predicate(false);
10966
10967 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %}
10968 postalloc_expand %{
10969 //
10970 // replaces
10971 //
10972 // region dst crx mem
10973 // \ | | /
10974 // dst=cmovL_bso_stackSlotL_conLvalue0
10975 //
10976 // with
10977 //
10978 // region dst
10979 // \ /
10980 // dst=loadConL16(0)
10981 // |
10982 // ^ region dst crx mem
10983 // | \ | | /
10984 // dst=cmovL_bso_stackSlotL
10985 //
10986
10987 // Create new nodes.
10988 MachNode *m1 = new loadConL16Node();
10989 MachNode *m2 = new cmovL_bso_stackSlotLNode();
10990
10991 // inputs for new nodes
10992 m1->add_req(n_region);
10993 m2->add_req(n_region, n_crx, n_mem);
10994 m2->add_prec(m1);
10995
10996 // operands for new nodes
10997 m1->_opnds[0] = op_dst;
10998 m1->_opnds[1] = new immL16Oper(0);
10999 m2->_opnds[0] = op_dst;
11000 m2->_opnds[1] = op_crx;
11001 m2->_opnds[2] = op_mem;
11002
11003 // registers for new nodes
11004 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
11005 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
11006
11007 // Insert new nodes.
11008 nodes->push(m1);
11009 nodes->push(m2);
11010 %}
11011 %}
11012
11013 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{
11014 // no match-rule, false predicate
11015 effect(DEF dst, USE crx, USE src);
11016 predicate(false);
11017
11018 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %}
11019 postalloc_expand %{
11020 //
11021 // replaces
11022 //
11023 // region dst crx src
11024 // \ | | /
11025 // dst=cmovL_bso_reg_conLvalue0
11026 //
11027 // with
11028 //
11029 // region dst
11030 // \ /
11031 // dst=loadConL16(0)
11032 // |
11033 // ^ region dst crx src
11034 // | \ | | /
11035 // dst=cmovL_bso_reg
11036 //
11037
11038 // Create new nodes.
11039 MachNode *m1 = new loadConL16Node();
11040 MachNode *m2 = new cmovL_bso_regNode();
11041
11042 // inputs for new nodes
11043 m1->add_req(n_region);
11044 m2->add_req(n_region, n_crx, n_src);
11045 m2->add_prec(m1);
11046
11047 // operands for new nodes
11048 m1->_opnds[0] = op_dst;
11049 m1->_opnds[1] = new immL16Oper(0);
11050 m2->_opnds[0] = op_dst;
11051 m2->_opnds[1] = op_crx;
11052 m2->_opnds[2] = op_src;
11053
11054 // registers for new nodes
11055 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
11056 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
11057
11058 // Insert new nodes.
11059 nodes->push(m1);
11060 nodes->push(m2);
11061 %}
11062 %}
11063
11064 // Float to Long conversion, NaN is mapped to 0.
11065 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{
11066 match(Set dst (ConvF2L src));
11067 predicate(!VM_Version::has_mtfprd());
11068 ins_cost(DEFAULT_COST);
11069
11070 expand %{
11071 regF tmpF;
11072 stackSlotL tmpS;
11073 flagsReg crx;
11074 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
11075 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
11076 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated).
11077 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
11078 %}
11079 %}
11080
11081 // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
11082 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
11083 match(Set dst (ConvF2L src));
11084 predicate(VM_Version::has_mtfprd());
11085 ins_cost(DEFAULT_COST);
11086
11087 expand %{
11088 regF tmpF;
11089 flagsReg crx;
11090 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
11091 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
11092 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
11093 %}
11094 %}
11095
11096 instruct convD2LRaw_regD(regD dst, regD src) %{
11097 // no match-rule, false predicate
11098 effect(DEF dst, USE src);
11099 predicate(false);
11100
11101 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
11102 size(4);
11103 ins_encode %{
11104 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
11105 %}
11106 ins_pipe(pipe_class_default);
11107 %}
11108
11109 // Double to Long conversion, NaN is mapped to 0.
11110 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{
11111 match(Set dst (ConvD2L src));
11112 predicate(!VM_Version::has_mtfprd());
11113 ins_cost(DEFAULT_COST);
11114
11115 expand %{
11116 regD tmpD;
11117 stackSlotL tmpS;
11118 flagsReg crx;
11119 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
11120 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
11121 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated).
11122 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
11123 %}
11124 %}
11125
11126 // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
11127 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
11128 match(Set dst (ConvD2L src));
11129 predicate(VM_Version::has_mtfprd());
11130 ins_cost(DEFAULT_COST);
11131
11132 expand %{
11133 regD tmpD;
11134 flagsReg crx;
11135 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
11136 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
11137 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
11138 %}
11139 %}
11140
11141 // Convert to Float
11142
11143 // Placed here as needed in expand.
11144 instruct convL2DRaw_regD(regD dst, regD src) %{
11145 // no match-rule, false predicate
11146 effect(DEF dst, USE src);
11147 predicate(false);
11148
11149 format %{ "FCFID $dst, $src \t// convL2D" %}
11150 size(4);
11151 ins_encode %{
11152 __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
11153 %}
11154 ins_pipe(pipe_class_default);
11155 %}
11156
11157 // Placed here as needed in expand.
11158 instruct convD2F_reg(regF dst, regD src) %{
11159 match(Set dst (ConvD2F src));
11160 format %{ "FRSP $dst, $src \t// convD2F" %}
11161 size(4);
11162 ins_encode %{
11163 __ frsp($dst$$FloatRegister, $src$$FloatRegister);
11164 %}
11165 ins_pipe(pipe_class_default);
11166 %}
11167
11168 // Integer to Float conversion.
11169 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{
11170 match(Set dst (ConvI2F src));
11171 predicate(!VM_Version::has_fcfids());
11172 ins_cost(DEFAULT_COST);
11173
11174 expand %{
11175 iRegLdst tmpL;
11176 stackSlotL tmpS;
11177 regD tmpD;
11178 regD tmpD2;
11179 convI2L_reg(tmpL, src); // Sign-extension int to long.
11180 regL_to_stkL(tmpS, tmpL); // Store long to stack.
11181 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
11182 convL2DRaw_regD(tmpD2, tmpD); // Convert to double.
11183 convD2F_reg(dst, tmpD2); // Convert double to float.
11184 %}
11185 %}
11186
11187 instruct convL2FRaw_regF(regF dst, regD src) %{
11188 // no match-rule, false predicate
11189 effect(DEF dst, USE src);
11190 predicate(false);
11191
11192 format %{ "FCFIDS $dst, $src \t// convL2F" %}
11193 size(4);
11194 ins_encode %{
11195 __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
11196 %}
11197 ins_pipe(pipe_class_default);
11198 %}
11199
11200 // Integer to Float conversion. Special version for Power7.
11201 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{
11202 match(Set dst (ConvI2F src));
11203 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd());
11204 ins_cost(DEFAULT_COST);
11205
11206 expand %{
11207 iRegLdst tmpL;
11208 stackSlotL tmpS;
11209 regD tmpD;
11210 convI2L_reg(tmpL, src); // Sign-extension int to long.
11211 regL_to_stkL(tmpS, tmpL); // Store long to stack.
11212 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
11213 convL2FRaw_regF(dst, tmpD); // Convert to float.
11214 %}
11215 %}
11216
11217 // Integer to Float conversion. Special version for Power8.
11218 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
11219 match(Set dst (ConvI2F src));
11220 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd());
11221 ins_cost(DEFAULT_COST);
11222
11223 expand %{
11224 regD tmpD;
11225 moveI2D_reg(tmpD, src);
11226 convL2FRaw_regF(dst, tmpD); // Convert to float.
11227 %}
11228 %}
11229
11230 // L2F to avoid runtime call.
11231 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{
11232 match(Set dst (ConvL2F src));
11233 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd());
11234 ins_cost(DEFAULT_COST);
11235
11236 expand %{
11237 stackSlotL tmpS;
11238 regD tmpD;
11239 regL_to_stkL(tmpS, src); // Store long to stack.
11240 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
11241 convL2FRaw_regF(dst, tmpD); // Convert to float.
11242 %}
11243 %}
11244
11245 // L2F to avoid runtime call. Special version for Power8.
11246 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
11247 match(Set dst (ConvL2F src));
11248 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd());
11249 ins_cost(DEFAULT_COST);
11250
11251 expand %{
11252 regD tmpD;
11253 moveL2D_reg(tmpD, src);
11254 convL2FRaw_regF(dst, tmpD); // Convert to float.
11255 %}
11256 %}
11257
11258 // Moved up as used in expand.
11259 //instruct convD2F_reg(regF dst, regD src) %{%}
11260
11261 // Convert to Double
11262
11263 // Integer to Double conversion.
11264 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{
11265 match(Set dst (ConvI2D src));
11266 predicate(!VM_Version::has_mtfprd());
11267 ins_cost(DEFAULT_COST);
11268
11269 expand %{
11270 iRegLdst tmpL;
11271 stackSlotL tmpS;
11272 regD tmpD;
11273 convI2L_reg(tmpL, src); // Sign-extension int to long.
11274 regL_to_stkL(tmpS, tmpL); // Store long to stack.
11275 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
11276 convL2DRaw_regD(dst, tmpD); // Convert to double.
11277 %}
11278 %}
11279
11280 // Integer to Double conversion. Special version for Power8.
11281 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
11282 match(Set dst (ConvI2D src));
11283 predicate(VM_Version::has_mtfprd());
11284 ins_cost(DEFAULT_COST);
11285
11286 expand %{
11287 regD tmpD;
11288 moveI2D_reg(tmpD, src);
11289 convL2DRaw_regD(dst, tmpD); // Convert to double.
11290 %}
11291 %}
11292
11293 // Long to Double conversion
11294 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{
11295 match(Set dst (ConvL2D src));
11296 ins_cost(DEFAULT_COST + MEMORY_REF_COST);
11297
11298 expand %{
11299 regD tmpD;
11300 moveL2D_stack_reg(tmpD, src);
11301 convL2DRaw_regD(dst, tmpD);
11302 %}
11303 %}
11304
11305 // Long to Double conversion. Special version for Power8.
11306 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
11307 match(Set dst (ConvL2D src));
11308 predicate(VM_Version::has_mtfprd());
11309 ins_cost(DEFAULT_COST);
11310
11311 expand %{
11312 regD tmpD;
11313 moveL2D_reg(tmpD, src);
11314 convL2DRaw_regD(dst, tmpD); // Convert to double.
11315 %}
11316 %}
11317
11318 instruct convF2D_reg(regD dst, regF src) %{
11319 match(Set dst (ConvF2D src));
11320 format %{ "FMR $dst, $src \t// float->double" %}
11321 // variable size, 0 or 4
11322 ins_encode %{
11323 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
11324 %}
11325 ins_pipe(pipe_class_default);
11326 %}
11327
11328 //----------Control Flow Instructions------------------------------------------
11329 // Compare Instructions
11330
11331 // Compare Integers
11332 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
11333 match(Set crx (CmpI src1 src2));
11334 size(4);
11335 format %{ "CMPW $crx, $src1, $src2" %}
11336 ins_encode %{
11337 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
11338 %}
11339 ins_pipe(pipe_class_compare);
11340 %}
11341
11342 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
11343 match(Set crx (CmpI src1 src2));
11344 format %{ "CMPWI $crx, $src1, $src2" %}
11345 size(4);
11346 ins_encode %{
11347 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11348 %}
11349 ins_pipe(pipe_class_compare);
11350 %}
11351
11352 // (src1 & src2) == 0?
11353 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
11354 match(Set cr0 (CmpI (AndI src1 src2) zero));
11355 // r0 is killed
11356 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
11357 size(4);
11358 ins_encode %{
11359 __ andi_(R0, $src1$$Register, $src2$$constant);
11360 %}
11361 ins_pipe(pipe_class_compare);
11362 %}
11363
11364 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
11365 match(Set crx (CmpL src1 src2));
11366 format %{ "CMPD $crx, $src1, $src2" %}
11367 size(4);
11368 ins_encode %{
11369 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
11370 %}
11371 ins_pipe(pipe_class_compare);
11372 %}
11373
11374 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
11375 match(Set crx (CmpL src1 src2));
11376 format %{ "CMPDI $crx, $src1, $src2" %}
11377 size(4);
11378 ins_encode %{
11379 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11380 %}
11381 ins_pipe(pipe_class_compare);
11382 %}
11383
11384 // Added CmpUL for LoopPredicate.
11385 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
11386 match(Set crx (CmpUL src1 src2));
11387 format %{ "CMPLD $crx, $src1, $src2" %}
11388 size(4);
11389 ins_encode %{
11390 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
11391 %}
11392 ins_pipe(pipe_class_compare);
11393 %}
11394
11395 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
11396 match(Set crx (CmpUL src1 src2));
11397 format %{ "CMPLDI $crx, $src1, $src2" %}
11398 size(4);
11399 ins_encode %{
11400 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11401 %}
11402 ins_pipe(pipe_class_compare);
11403 %}
11404
11405 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
11406 match(Set cr0 (CmpL (AndL src1 src2) zero));
11407 // r0 is killed
11408 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
11409 size(4);
11410 ins_encode %{
11411 __ and_(R0, $src1$$Register, $src2$$Register);
11412 %}
11413 ins_pipe(pipe_class_compare);
11414 %}
11415
11416 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
11417 match(Set cr0 (CmpL (AndL src1 src2) zero));
11418 // r0 is killed
11419 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
11420 size(4);
11421 ins_encode %{
11422 __ andi_(R0, $src1$$Register, $src2$$constant);
11423 %}
11424 ins_pipe(pipe_class_compare);
11425 %}
11426
11427 // Manifest a CmpL3 result in an integer register.
11428 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
11429 match(Set dst (CmpL3 src1 src2));
11430 effect(KILL cr0);
11431 ins_cost(DEFAULT_COST * 5);
11432 size(VM_Version::has_brw() ? 16 : 20);
11433
11434 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %}
11435
11436 ins_encode %{
11437 __ cmpd(CCR0, $src1$$Register, $src2$$Register);
11438 __ set_cmp3($dst$$Register);
11439 %}
11440 ins_pipe(pipe_class_default);
11441 %}
11442
11443 // Implicit range checks.
11444 // A range check in the ideal world has one of the following shapes:
11445 // - (If le (CmpU length index)), (IfTrue throw exception)
11446 // - (If lt (CmpU index length)), (IfFalse throw exception)
11447 //
11448 // Match range check 'If le (CmpU length index)'.
11449 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
11450 match(If cmp (CmpU src_length index));
11451 effect(USE labl);
11452 predicate(TrapBasedRangeChecks &&
11453 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
11454 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
11455 (Matcher::branches_to_uncommon_trap(_leaf)));
11456
11457 ins_is_TrapBasedCheckNode(true);
11458
11459 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %}
11460 size(4);
11461 ins_encode %{
11462 if ($cmp$$cmpcode == 0x1 /* less_equal */) {
11463 __ trap_range_check_le($src_length$$Register, $index$$constant);
11464 } else {
11465 // Both successors are uncommon traps, probability is 0.
11466 // Node got flipped during fixup flow.
11467 assert($cmp$$cmpcode == 0x9, "must be greater");
11468 __ trap_range_check_g($src_length$$Register, $index$$constant);
11469 }
11470 %}
11471 ins_pipe(pipe_class_trap);
11472 %}
11473
11474 // Match range check 'If lt (CmpU index length)'.
11475 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
11476 match(If cmp (CmpU src_index src_length));
11477 effect(USE labl);
11478 predicate(TrapBasedRangeChecks &&
11479 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
11480 _leaf->as_If()->_prob >= PROB_ALWAYS &&
11481 (Matcher::branches_to_uncommon_trap(_leaf)));
11482
11483 ins_is_TrapBasedCheckNode(true);
11484
11485 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
11486 size(4);
11487 ins_encode %{
11488 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
11489 __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
11490 } else {
11491 // Both successors are uncommon traps, probability is 0.
11492 // Node got flipped during fixup flow.
11493 assert($cmp$$cmpcode == 0x8, "must be less");
11494 __ trap_range_check_l($src_index$$Register, $src_length$$Register);
11495 }
11496 %}
11497 ins_pipe(pipe_class_trap);
11498 %}
11499
11500 // Match range check 'If lt (CmpU index length)'.
11501 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
11502 match(If cmp (CmpU src_index length));
11503 effect(USE labl);
11504 predicate(TrapBasedRangeChecks &&
11505 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
11506 _leaf->as_If()->_prob >= PROB_ALWAYS &&
11507 (Matcher::branches_to_uncommon_trap(_leaf)));
11508
11509 ins_is_TrapBasedCheckNode(true);
11510
11511 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %}
11512 size(4);
11513 ins_encode %{
11514 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
11515 __ trap_range_check_ge($src_index$$Register, $length$$constant);
11516 } else {
11517 // Both successors are uncommon traps, probability is 0.
11518 // Node got flipped during fixup flow.
11519 assert($cmp$$cmpcode == 0x8, "must be less");
11520 __ trap_range_check_l($src_index$$Register, $length$$constant);
11521 }
11522 %}
11523 ins_pipe(pipe_class_trap);
11524 %}
11525
11526 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
11527 match(Set crx (CmpU src1 src2));
11528 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %}
11529 size(4);
11530 ins_encode %{
11531 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
11532 %}
11533 ins_pipe(pipe_class_compare);
11534 %}
11535
11536 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
11537 match(Set crx (CmpU src1 src2));
11538 size(4);
11539 format %{ "CMPLWI $crx, $src1, $src2" %}
11540 ins_encode %{
11541 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11542 %}
11543 ins_pipe(pipe_class_compare);
11544 %}
11545
11546 // Implicit zero checks (more implicit null checks).
11547 // No constant pool entries required.
11548 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
11549 match(If cmp (CmpN value zero));
11550 effect(USE labl);
11551 predicate(TrapBasedNullChecks &&
11552 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
11553 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
11554 Matcher::branches_to_uncommon_trap(_leaf));
11555 ins_cost(1);
11556
11557 ins_is_TrapBasedCheckNode(true);
11558
11559 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
11560 size(4);
11561 ins_encode %{
11562 if ($cmp$$cmpcode == 0xA) {
11563 __ trap_null_check($value$$Register);
11564 } else {
11565 // Both successors are uncommon traps, probability is 0.
11566 // Node got flipped during fixup flow.
11567 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
11568 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
11569 }
11570 %}
11571 ins_pipe(pipe_class_trap);
11572 %}
11573
11574 // Compare narrow oops.
11575 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
11576 match(Set crx (CmpN src1 src2));
11577
11578 size(4);
11579 ins_cost(2);
11580 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %}
11581 ins_encode %{
11582 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
11583 %}
11584 ins_pipe(pipe_class_compare);
11585 %}
11586
11587 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
11588 match(Set crx (CmpN src1 src2));
11589 // Make this more expensive than zeroCheckN_iReg_imm0.
11590 ins_cost(2);
11591
11592 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %}
11593 size(4);
11594 ins_encode %{
11595 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11596 %}
11597 ins_pipe(pipe_class_compare);
11598 %}
11599
11600 // Implicit zero checks (more implicit null checks).
11601 // No constant pool entries required.
11602 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
11603 match(If cmp (CmpP value zero));
11604 effect(USE labl);
11605 predicate(TrapBasedNullChecks &&
11606 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
11607 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
11608 Matcher::branches_to_uncommon_trap(_leaf));
11609 ins_cost(1); // Should not be cheaper than zeroCheckN.
11610
11611 ins_is_TrapBasedCheckNode(true);
11612
11613 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
11614 size(4);
11615 ins_encode %{
11616 if ($cmp$$cmpcode == 0xA) {
11617 __ trap_null_check($value$$Register);
11618 } else {
11619 // Both successors are uncommon traps, probability is 0.
11620 // Node got flipped during fixup flow.
11621 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
11622 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
11623 }
11624 %}
11625 ins_pipe(pipe_class_trap);
11626 %}
11627
11628 // Compare Pointers
11629 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
11630 match(Set crx (CmpP src1 src2));
11631 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %}
11632 size(4);
11633 ins_encode %{
11634 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
11635 %}
11636 ins_pipe(pipe_class_compare);
11637 %}
11638
11639 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
11640 match(Set crx (CmpP src1 src2));
11641 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %}
11642 size(4);
11643 ins_encode %{
11644 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
11645 %}
11646 ins_pipe(pipe_class_compare);
11647 %}
11648
11649 // Used in postalloc expand.
11650 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
11651 // This match rule prevents reordering of node before a safepoint.
11652 // This only makes sense if this instructions is used exclusively
11653 // for the expansion of EncodeP!
11654 match(Set crx (CmpP src1 src2));
11655 predicate(false);
11656
11657 format %{ "CMPDI $crx, $src1, $src2" %}
11658 size(4);
11659 ins_encode %{
11660 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11661 %}
11662 ins_pipe(pipe_class_compare);
11663 %}
11664
11665 //----------Float Compares----------------------------------------------------
11666
11667 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
11668 // Needs matchrule, see cmpDUnordered.
11669 match(Set crx (CmpF src1 src2));
11670 // no match-rule, false predicate
11671 predicate(false);
11672
11673 format %{ "cmpFUrd $crx, $src1, $src2" %}
11674 size(4);
11675 ins_encode %{
11676 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11677 %}
11678 ins_pipe(pipe_class_default);
11679 %}
11680
11681 instruct cmov_bns_less(flagsReg crx) %{
11682 // no match-rule, false predicate
11683 effect(DEF crx);
11684 predicate(false);
11685
11686 ins_variable_size_depending_on_alignment(true);
11687
11688 format %{ "cmov $crx" %}
11689 // Worst case is branch + move + stop, no stop without scheduler.
11690 size(12);
11691 ins_encode %{
11692 Label done;
11693 __ bns($crx$$CondRegister, done); // not unordered -> keep crx
11694 __ li(R0, 0);
11695 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less'
11696 __ bind(done);
11697 %}
11698 ins_pipe(pipe_class_default);
11699 %}
11700
11701 // Compare floating, generate condition code.
11702 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{
11703 // FIXME: should we match 'If cmp (CmpF src1 src2))' ??
11704 //
11705 // The following code sequence occurs a lot in mpegaudio:
11706 //
11707 // block BXX:
11708 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0):
11709 // cmpFUrd CCR6, F11, F9
11710 // 4: instruct cmov_bns_less (cmpF_reg_reg-1):
11711 // cmov CCR6
11712 // 8: instruct branchConSched:
11713 // B_FARle CCR6, B56 P=0.500000 C=-1.000000
11714 match(Set crx (CmpF src1 src2));
11715 ins_cost(DEFAULT_COST+BRANCH_COST);
11716
11717 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %}
11718 postalloc_expand %{
11719 //
11720 // replaces
11721 //
11722 // region src1 src2
11723 // \ | |
11724 // crx=cmpF_reg_reg
11725 //
11726 // with
11727 //
11728 // region src1 src2
11729 // \ | |
11730 // crx=cmpFUnordered_reg_reg
11731 // |
11732 // ^ region
11733 // | \
11734 // crx=cmov_bns_less
11735 //
11736
11737 // Create new nodes.
11738 MachNode *m1 = new cmpFUnordered_reg_regNode();
11739 MachNode *m2 = new cmov_bns_lessNode();
11740
11741 // inputs for new nodes
11742 m1->add_req(n_region, n_src1, n_src2);
11743 m2->add_req(n_region);
11744 m2->add_prec(m1);
11745
11746 // operands for new nodes
11747 m1->_opnds[0] = op_crx;
11748 m1->_opnds[1] = op_src1;
11749 m1->_opnds[2] = op_src2;
11750 m2->_opnds[0] = op_crx;
11751
11752 // registers for new nodes
11753 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11754 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11755
11756 // Insert new nodes.
11757 nodes->push(m1);
11758 nodes->push(m2);
11759 %}
11760 %}
11761
11762 // Compare float, generate -1,0,1
11763 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{
11764 match(Set dst (CmpF3 src1 src2));
11765 effect(KILL cr0);
11766 ins_cost(DEFAULT_COST * 6);
11767 size(VM_Version::has_brw() ? 20 : 24);
11768
11769 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %}
11770
11771 ins_encode %{
11772 __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister);
11773 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11774 %}
11775 ins_pipe(pipe_class_default);
11776 %}
11777
11778 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
11779 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
11780 // node right before the conditional move using it.
11781 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
11782 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
11783 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
11784 // conditional move was supposed to be spilled.
11785 match(Set crx (CmpD src1 src2));
11786 // False predicate, shall not be matched.
11787 predicate(false);
11788
11789 format %{ "cmpFUrd $crx, $src1, $src2" %}
11790 size(4);
11791 ins_encode %{
11792 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11793 %}
11794 ins_pipe(pipe_class_default);
11795 %}
11796
11797 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{
11798 match(Set crx (CmpD src1 src2));
11799 ins_cost(DEFAULT_COST+BRANCH_COST);
11800
11801 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %}
11802 postalloc_expand %{
11803 //
11804 // replaces
11805 //
11806 // region src1 src2
11807 // \ | |
11808 // crx=cmpD_reg_reg
11809 //
11810 // with
11811 //
11812 // region src1 src2
11813 // \ | |
11814 // crx=cmpDUnordered_reg_reg
11815 // |
11816 // ^ region
11817 // | \
11818 // crx=cmov_bns_less
11819 //
11820
11821 // create new nodes
11822 MachNode *m1 = new cmpDUnordered_reg_regNode();
11823 MachNode *m2 = new cmov_bns_lessNode();
11824
11825 // inputs for new nodes
11826 m1->add_req(n_region, n_src1, n_src2);
11827 m2->add_req(n_region);
11828 m2->add_prec(m1);
11829
11830 // operands for new nodes
11831 m1->_opnds[0] = op_crx;
11832 m1->_opnds[1] = op_src1;
11833 m1->_opnds[2] = op_src2;
11834 m2->_opnds[0] = op_crx;
11835
11836 // registers for new nodes
11837 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11838 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11839
11840 // Insert new nodes.
11841 nodes->push(m1);
11842 nodes->push(m2);
11843 %}
11844 %}
11845
11846 // Compare double, generate -1,0,1
11847 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{
11848 match(Set dst (CmpD3 src1 src2));
11849 effect(KILL cr0);
11850 ins_cost(DEFAULT_COST * 6);
11851 size(VM_Version::has_brw() ? 20 : 24);
11852
11853 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %}
11854
11855 ins_encode %{
11856 __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister);
11857 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11858 %}
11859 ins_pipe(pipe_class_default);
11860 %}
11861
11862 // Compare char
11863 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11864 match(Set dst (Digit src1));
11865 effect(TEMP src2, TEMP crx);
11866 ins_cost(3 * DEFAULT_COST);
11867
11868 format %{ "LI $src2, 0x3930\n\t"
11869 "CMPRB $crx, 0, $src1, $src2\n\t"
11870 "SETB $dst, $crx" %}
11871 size(12);
11872 ins_encode %{
11873 // 0x30: 0, 0x39: 9
11874 __ li($src2$$Register, 0x3930);
11875 // compare src1 with ranges 0x30 to 0x39
11876 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11877 __ setb($dst$$Register, $crx$$CondRegister);
11878 %}
11879 ins_pipe(pipe_class_default);
11880 %}
11881
11882 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11883 match(Set dst (LowerCase src1));
11884 effect(TEMP src2, TEMP crx);
11885 ins_cost(12 * DEFAULT_COST);
11886
11887 format %{ "LI $src2, 0x7A61\n\t"
11888 "CMPRB $crx, 0, $src1, $src2\n\t"
11889 "BGT $crx, done\n\t"
11890 "LIS $src2, (signed short)0xF6DF\n\t"
11891 "ORI $src2, $src2, 0xFFF8\n\t"
11892 "CMPRB $crx, 1, $src1, $src2\n\t"
11893 "BGT $crx, done\n\t"
11894 "LIS $src2, (signed short)0xAAB5\n\t"
11895 "ORI $src2, $src2, 0xBABA\n\t"
11896 "INSRDI $src2, $src2, 32, 0\n\t"
11897 "CMPEQB $crx, 1, $src1, $src2\n"
11898 "done:\n\t"
11899 "SETB $dst, $crx" %}
11900
11901 size(48);
11902 ins_encode %{
11903 Label done;
11904 // 0x61: a, 0x7A: z
11905 __ li($src2$$Register, 0x7A61);
11906 // compare src1 with ranges 0x61 to 0x7A
11907 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11908 __ bgt($crx$$CondRegister, done);
11909
11910 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
11911 __ lis($src2$$Register, (signed short)0xF6DF);
11912 __ ori($src2$$Register, $src2$$Register, 0xFFF8);
11913 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
11914 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11915 __ bgt($crx$$CondRegister, done);
11916
11917 // 0xAA: feminine ordinal indicator
11918 // 0xB5: micro sign
11919 // 0xBA: masculine ordinal indicator
11920 __ lis($src2$$Register, (signed short)0xAAB5);
11921 __ ori($src2$$Register, $src2$$Register, 0xBABA);
11922 __ insrdi($src2$$Register, $src2$$Register, 32, 0);
11923 // compare src1 with 0xAA, 0xB5, and 0xBA
11924 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
11925
11926 __ bind(done);
11927 __ setb($dst$$Register, $crx$$CondRegister);
11928 %}
11929 ins_pipe(pipe_class_default);
11930 %}
11931
11932 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11933 match(Set dst (UpperCase src1));
11934 effect(TEMP src2, TEMP crx);
11935 ins_cost(7 * DEFAULT_COST);
11936
11937 format %{ "LI $src2, 0x5A41\n\t"
11938 "CMPRB $crx, 0, $src1, $src2\n\t"
11939 "BGT $crx, done\n\t"
11940 "LIS $src2, (signed short)0xD6C0\n\t"
11941 "ORI $src2, $src2, 0xDED8\n\t"
11942 "CMPRB $crx, 1, $src1, $src2\n"
11943 "done:\n\t"
11944 "SETB $dst, $crx" %}
11945
11946 size(28);
11947 ins_encode %{
11948 Label done;
11949 // 0x41: A, 0x5A: Z
11950 __ li($src2$$Register, 0x5A41);
11951 // compare src1 with a range 0x41 to 0x5A
11952 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11953 __ bgt($crx$$CondRegister, done);
11954
11955 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
11956 __ lis($src2$$Register, (signed short)0xD6C0);
11957 __ ori($src2$$Register, $src2$$Register, 0xDED8);
11958 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
11959 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11960
11961 __ bind(done);
11962 __ setb($dst$$Register, $crx$$CondRegister);
11963 %}
11964 ins_pipe(pipe_class_default);
11965 %}
11966
11967 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11968 match(Set dst (Whitespace src1));
11969 predicate(PowerArchitecturePPC64 <= 9);
11970 effect(TEMP src2, TEMP crx);
11971 ins_cost(4 * DEFAULT_COST);
11972
11973 format %{ "LI $src2, 0x0D09\n\t"
11974 "ADDIS $src2, 0x201C\n\t"
11975 "CMPRB $crx, 1, $src1, $src2\n\t"
11976 "SETB $dst, $crx" %}
11977 size(16);
11978 ins_encode %{
11979 // 0x09 to 0x0D, 0x1C to 0x20
11980 __ li($src2$$Register, 0x0D09);
11981 __ addis($src2$$Register, $src2$$Register, 0x0201C);
11982 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
11983 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11984 __ setb($dst$$Register, $crx$$CondRegister);
11985 %}
11986 ins_pipe(pipe_class_default);
11987 %}
11988
11989 // Power 10 version, using prefixed addi to load 32-bit constant
11990 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11991 match(Set dst (Whitespace src1));
11992 predicate(PowerArchitecturePPC64 >= 10);
11993 effect(TEMP src2, TEMP crx);
11994 ins_cost(3 * DEFAULT_COST);
11995
11996 format %{ "PLI $src2, 0x201C0D09\n\t"
11997 "CMPRB $crx, 1, $src1, $src2\n\t"
11998 "SETB $dst, $crx" %}
11999 size(16);
12000 ins_encode %{
12001 // 0x09 to 0x0D, 0x1C to 0x20
12002 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
12003 __ pli($src2$$Register, 0x201C0D09);
12004 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
12005 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
12006 __ setb($dst$$Register, $crx$$CondRegister);
12007 %}
12008 ins_pipe(pipe_class_default);
12009 ins_alignment(2);
12010 %}
12011
12012 //----------Branches---------------------------------------------------------
12013 // Jump
12014
12015 // Direct Branch.
12016 instruct branch(label labl) %{
12017 match(Goto);
12018 effect(USE labl);
12019 ins_cost(BRANCH_COST);
12020
12021 format %{ "B $labl" %}
12022 size(4);
12023 ins_encode %{
12024 Label d; // dummy
12025 __ bind(d);
12026 Label* p = $labl$$label;
12027 // `p' is `NULL' when this encoding class is used only to
12028 // determine the size of the encoded instruction.
12029 Label& l = (NULL == p)? d : *(p);
12030 __ b(l);
12031 %}
12032 ins_pipe(pipe_class_default);
12033 %}
12034
12035 // Conditional Near Branch
12036 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
12037 // Same match rule as `branchConFar'.
12038 match(If cmp crx);
12039 effect(USE lbl);
12040 ins_cost(BRANCH_COST);
12041
12042 // If set to 1 this indicates that the current instruction is a
12043 // short variant of a long branch. This avoids using this
12044 // instruction in first-pass matching. It will then only be used in
12045 // the `Shorten_branches' pass.
12046 ins_short_branch(1);
12047
12048 format %{ "B$cmp $crx, $lbl" %}
12049 size(4);
12050 ins_encode( enc_bc(crx, cmp, lbl) );
12051 ins_pipe(pipe_class_default);
12052 %}
12053
12054 // This is for cases when the ppc64 `bc' instruction does not
12055 // reach far enough. So we emit a far branch here, which is more
12056 // expensive.
12057 //
12058 // Conditional Far Branch
12059 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
12060 // Same match rule as `branchCon'.
12061 match(If cmp crx);
12062 effect(USE crx, USE lbl);
12063 // Higher cost than `branchCon'.
12064 ins_cost(5*BRANCH_COST);
12065
12066 // This is not a short variant of a branch, but the long variant.
12067 ins_short_branch(0);
12068
12069 format %{ "B_FAR$cmp $crx, $lbl" %}
12070 size(8);
12071 ins_encode( enc_bc_far(crx, cmp, lbl) );
12072 ins_pipe(pipe_class_default);
12073 %}
12074
12075 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
12076 match(CountedLoopEnd cmp crx);
12077 effect(USE labl);
12078 ins_cost(BRANCH_COST);
12079
12080 // short variant.
12081 ins_short_branch(1);
12082
12083 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
12084 size(4);
12085 ins_encode( enc_bc(crx, cmp, labl) );
12086 ins_pipe(pipe_class_default);
12087 %}
12088
12089 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
12090 match(CountedLoopEnd cmp crx);
12091 effect(USE labl);
12092 ins_cost(BRANCH_COST);
12093
12094 // Long variant.
12095 ins_short_branch(0);
12096
12097 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
12098 size(8);
12099 ins_encode( enc_bc_far(crx, cmp, labl) );
12100 ins_pipe(pipe_class_default);
12101 %}
12102
12103 // ============================================================================
12104 // Java runtime operations, intrinsics and other complex operations.
12105
12106 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
12107 // array for an instance of the superklass. Set a hidden internal cache on a
12108 // hit (cache is checked with exposed code in gen_subtype_check()). Return
12109 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
12110 //
12111 // GL TODO: Improve this.
12112 // - result should not be a TEMP
12113 // - Add match rule as on sparc avoiding additional Cmp.
12114 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
12115 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
12116 match(Set result (PartialSubtypeCheck subklass superklass));
12117 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
12118 ins_cost(DEFAULT_COST*10);
12119
12120 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
12121 ins_encode %{
12122 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
12123 $tmp_klass$$Register, NULL, $result$$Register);
12124 %}
12125 ins_pipe(pipe_class_default);
12126 %}
12127
12128 // inlined locking and unlocking
12129
12130 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
12131 match(Set crx (FastLock oop box));
12132 effect(TEMP tmp1, TEMP tmp2);
12133 predicate(!Compile::current()->use_rtm());
12134
12135 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %}
12136 ins_encode %{
12137 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
12138 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0,
12139 UseBiasedLocking && !UseOptoBiasInlining);
12140 // If locking was successfull, crx should indicate 'EQ'.
12141 // The compiler generates a branch to the runtime call to
12142 // _complete_monitor_locking_Java for the case where crx is 'NE'.
12143 %}
12144 ins_pipe(pipe_class_compare);
12145 %}
12146
12147 // Separate version for TM. Use bound register for box to enable USE_KILL.
12148 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
12149 match(Set crx (FastLock oop box));
12150 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box);
12151 predicate(Compile::current()->use_rtm());
12152
12153 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %}
12154 ins_encode %{
12155 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
12156 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
12157 /*Biased Locking*/ false,
12158 _rtm_counters, _stack_rtm_counters,
12159 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(),
12160 /*TM*/ true, ra_->C->profile_rtm());
12161 // If locking was successfull, crx should indicate 'EQ'.
12162 // The compiler generates a branch to the runtime call to
12163 // _complete_monitor_locking_Java for the case where crx is 'NE'.
12164 %}
12165 ins_pipe(pipe_class_compare);
12166 %}
12167
12168 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
12169 match(Set crx (FastUnlock oop box));
12170 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
12171 predicate(!Compile::current()->use_rtm());
12172
12173 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
12174 ins_encode %{
12175 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
12176 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
12177 UseBiasedLocking && !UseOptoBiasInlining,
12178 false);
12179 // If unlocking was successfull, crx should indicate 'EQ'.
12180 // The compiler generates a branch to the runtime call to
12181 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
12182 %}
12183 ins_pipe(pipe_class_compare);
12184 %}
12185
12186 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
12187 match(Set crx (FastUnlock oop box));
12188 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
12189 predicate(Compile::current()->use_rtm());
12190
12191 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %}
12192 ins_encode %{
12193 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
12194 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
12195 /*Biased Locking*/ false, /*TM*/ true);
12196 // If unlocking was successfull, crx should indicate 'EQ'.
12197 // The compiler generates a branch to the runtime call to
12198 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
12199 %}
12200 ins_pipe(pipe_class_compare);
12201 %}
12202
12203 // Align address.
12204 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
12205 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
12206
12207 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
12208 size(4);
12209 ins_encode %{
12210 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant));
12211 %}
12212 ins_pipe(pipe_class_default);
12213 %}
12214
12215 // Array size computation.
12216 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
12217 match(Set dst (SubL (CastP2X end) (CastP2X start)));
12218
12219 format %{ "SUB $dst, $end, $start \t// array size in bytes" %}
12220 size(4);
12221 ins_encode %{
12222 __ subf($dst$$Register, $start$$Register, $end$$Register);
12223 %}
12224 ins_pipe(pipe_class_default);
12225 %}
12226
12227 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
12228 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
12229 match(Set dummy (ClearArray cnt base));
12230 effect(USE_KILL base, KILL ctr);
12231 ins_cost(2 * MEMORY_REF_COST);
12232
12233 format %{ "ClearArray $cnt, $base" %}
12234 ins_encode %{
12235 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
12236 %}
12237 ins_pipe(pipe_class_default);
12238 %}
12239
12240 // Clear-array with constant large array length.
12241 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{
12242 match(Set dummy (ClearArray cnt base));
12243 effect(USE_KILL base, TEMP tmp, KILL ctr);
12244 ins_cost(3 * MEMORY_REF_COST);
12245
12246 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
12247 ins_encode %{
12248 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
12249 %}
12250 ins_pipe(pipe_class_default);
12251 %}
12252
12253 // Clear-array with dynamic array length.
12254 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
12255 match(Set dummy (ClearArray cnt base));
12256 effect(USE_KILL cnt, USE_KILL base, KILL ctr);
12257 ins_cost(4 * MEMORY_REF_COST);
12258
12259 format %{ "ClearArray $cnt, $base" %}
12260 ins_encode %{
12261 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
12262 %}
12263 ins_pipe(pipe_class_default);
12264 %}
12265
12266 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
12267 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12268 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
12269 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
12270 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
12271 ins_cost(300);
12272 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
12273 ins_encode %{
12274 __ string_compare($str1$$Register, $str2$$Register,
12275 $cnt1$$Register, $cnt2$$Register,
12276 $tmp$$Register,
12277 $result$$Register, StrIntrinsicNode::LL);
12278 %}
12279 ins_pipe(pipe_class_default);
12280 %}
12281
12282 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
12283 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12284 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
12285 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
12286 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
12287 ins_cost(300);
12288 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
12289 ins_encode %{
12290 __ string_compare($str1$$Register, $str2$$Register,
12291 $cnt1$$Register, $cnt2$$Register,
12292 $tmp$$Register,
12293 $result$$Register, StrIntrinsicNode::UU);
12294 %}
12295 ins_pipe(pipe_class_default);
12296 %}
12297
12298 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
12299 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12300 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
12301 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
12302 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
12303 ins_cost(300);
12304 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
12305 ins_encode %{
12306 __ string_compare($str1$$Register, $str2$$Register,
12307 $cnt1$$Register, $cnt2$$Register,
12308 $tmp$$Register,
12309 $result$$Register, StrIntrinsicNode::LU);
12310 %}
12311 ins_pipe(pipe_class_default);
12312 %}
12313
12314 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
12315 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12316 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
12317 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
12318 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
12319 ins_cost(300);
12320 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
12321 ins_encode %{
12322 __ string_compare($str2$$Register, $str1$$Register,
12323 $cnt2$$Register, $cnt1$$Register,
12324 $tmp$$Register,
12325 $result$$Register, StrIntrinsicNode::UL);
12326 %}
12327 ins_pipe(pipe_class_default);
12328 %}
12329
12330 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
12331 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12332 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
12333 match(Set result (StrEquals (Binary str1 str2) cnt));
12334 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
12335 ins_cost(300);
12336 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
12337 ins_encode %{
12338 __ array_equals(false, $str1$$Register, $str2$$Register,
12339 $cnt$$Register, $tmp$$Register,
12340 $result$$Register, true /* byte */);
12341 %}
12342 ins_pipe(pipe_class_default);
12343 %}
12344
12345 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
12346 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12347 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
12348 match(Set result (StrEquals (Binary str1 str2) cnt));
12349 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
12350 ins_cost(300);
12351 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
12352 ins_encode %{
12353 __ array_equals(false, $str1$$Register, $str2$$Register,
12354 $cnt$$Register, $tmp$$Register,
12355 $result$$Register, false /* byte */);
12356 %}
12357 ins_pipe(pipe_class_default);
12358 %}
12359
12360 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
12361 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
12362 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
12363 match(Set result (AryEq ary1 ary2));
12364 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
12365 ins_cost(300);
12366 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
12367 ins_encode %{
12368 __ array_equals(true, $ary1$$Register, $ary2$$Register,
12369 $tmp1$$Register, $tmp2$$Register,
12370 $result$$Register, true /* byte */);
12371 %}
12372 ins_pipe(pipe_class_default);
12373 %}
12374
12375 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
12376 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
12377 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
12378 match(Set result (AryEq ary1 ary2));
12379 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
12380 ins_cost(300);
12381 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
12382 ins_encode %{
12383 __ array_equals(true, $ary1$$Register, $ary2$$Register,
12384 $tmp1$$Register, $tmp2$$Register,
12385 $result$$Register, false /* byte */);
12386 %}
12387 ins_pipe(pipe_class_default);
12388 %}
12389
12390 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12391 immP needleImm, immL offsetImm, immI_1 needlecntImm,
12392 iRegIdst tmp1, iRegIdst tmp2,
12393 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12394 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
12395 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12396 // Required for EA: check if it is still a type_array.
12397 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
12398 ins_cost(150);
12399
12400 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
12401 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12402
12403 ins_encode %{
12404 immPOper *needleOper = (immPOper *)$needleImm;
12405 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
12406 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
12407 jchar chr;
12408 #ifdef VM_LITTLE_ENDIAN
12409 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
12410 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
12411 #else
12412 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
12413 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
12414 #endif
12415 __ string_indexof_char($result$$Register,
12416 $haystack$$Register, $haycnt$$Register,
12417 R0, chr,
12418 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12419 %}
12420 ins_pipe(pipe_class_compare);
12421 %}
12422
12423 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12424 immP needleImm, immL offsetImm, immI_1 needlecntImm,
12425 iRegIdst tmp1, iRegIdst tmp2,
12426 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12427 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
12428 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12429 // Required for EA: check if it is still a type_array.
12430 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
12431 ins_cost(150);
12432
12433 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
12434 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12435
12436 ins_encode %{
12437 immPOper *needleOper = (immPOper *)$needleImm;
12438 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
12439 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
12440 jchar chr = (jchar)needle_values->element_value(0).as_byte();
12441 __ string_indexof_char($result$$Register,
12442 $haystack$$Register, $haycnt$$Register,
12443 R0, chr,
12444 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
12445 %}
12446 ins_pipe(pipe_class_compare);
12447 %}
12448
12449 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12450 immP needleImm, immL offsetImm, immI_1 needlecntImm,
12451 iRegIdst tmp1, iRegIdst tmp2,
12452 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12453 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
12454 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12455 // Required for EA: check if it is still a type_array.
12456 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
12457 ins_cost(150);
12458
12459 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
12460 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12461
12462 ins_encode %{
12463 immPOper *needleOper = (immPOper *)$needleImm;
12464 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
12465 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
12466 jchar chr = (jchar)needle_values->element_value(0).as_byte();
12467 __ string_indexof_char($result$$Register,
12468 $haystack$$Register, $haycnt$$Register,
12469 R0, chr,
12470 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12471 %}
12472 ins_pipe(pipe_class_compare);
12473 %}
12474
12475 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12476 rscratch2RegP needle, immI_1 needlecntImm,
12477 iRegIdst tmp1, iRegIdst tmp2,
12478 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12479 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12480 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12481 // Required for EA: check if it is still a type_array.
12482 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
12483 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12484 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12485 ins_cost(180);
12486
12487 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12488 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
12489 ins_encode %{
12490 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12491 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12492 guarantee(needle_values, "sanity");
12493 jchar chr;
12494 #ifdef VM_LITTLE_ENDIAN
12495 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
12496 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
12497 #else
12498 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
12499 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
12500 #endif
12501 __ string_indexof_char($result$$Register,
12502 $haystack$$Register, $haycnt$$Register,
12503 R0, chr,
12504 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12505 %}
12506 ins_pipe(pipe_class_compare);
12507 %}
12508
12509 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12510 rscratch2RegP needle, immI_1 needlecntImm,
12511 iRegIdst tmp1, iRegIdst tmp2,
12512 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12513 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12514 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12515 // Required for EA: check if it is still a type_array.
12516 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
12517 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12518 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12519 ins_cost(180);
12520
12521 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12522 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
12523 ins_encode %{
12524 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12525 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12526 guarantee(needle_values, "sanity");
12527 jchar chr = (jchar)needle_values->element_value(0).as_byte();
12528 __ string_indexof_char($result$$Register,
12529 $haystack$$Register, $haycnt$$Register,
12530 R0, chr,
12531 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
12532 %}
12533 ins_pipe(pipe_class_compare);
12534 %}
12535
12536 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12537 rscratch2RegP needle, immI_1 needlecntImm,
12538 iRegIdst tmp1, iRegIdst tmp2,
12539 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12540 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12541 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12542 // Required for EA: check if it is still a type_array.
12543 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
12544 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12545 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12546 ins_cost(180);
12547
12548 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12549 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
12550 ins_encode %{
12551 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12552 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12553 guarantee(needle_values, "sanity");
12554 jchar chr = (jchar)needle_values->element_value(0).as_byte();
12555 __ string_indexof_char($result$$Register,
12556 $haystack$$Register, $haycnt$$Register,
12557 R0, chr,
12558 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12559 %}
12560 ins_pipe(pipe_class_compare);
12561 %}
12562
12563 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12564 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
12565 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12566 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
12567 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12568 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
12569 ins_cost(180);
12570
12571 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch"
12572 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12573 ins_encode %{
12574 __ string_indexof_char($result$$Register,
12575 $haystack$$Register, $haycnt$$Register,
12576 $ch$$Register, 0 /* this is not used if the character is already in a register */,
12577 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12578 %}
12579 ins_pipe(pipe_class_compare);
12580 %}
12581
12582 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12583 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
12584 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12585 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
12586 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12587 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
12588 ins_cost(180);
12589
12590 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch"
12591 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12592 ins_encode %{
12593 __ string_indexof_char($result$$Register,
12594 $haystack$$Register, $haycnt$$Register,
12595 $ch$$Register, 0 /* this is not used if the character is already in a register */,
12596 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
12597 %}
12598 ins_pipe(pipe_class_compare);
12599 %}
12600
12601 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12602 iRegPsrc needle, uimmI15 needlecntImm,
12603 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12604 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12605 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12606 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12607 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12608 // Required for EA: check if it is still a type_array.
12609 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
12610 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12611 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12612 ins_cost(250);
12613
12614 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12615 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12616 ins_encode %{
12617 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12618 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12619
12620 __ string_indexof($result$$Register,
12621 $haystack$$Register, $haycnt$$Register,
12622 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12623 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
12624 %}
12625 ins_pipe(pipe_class_compare);
12626 %}
12627
12628 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12629 iRegPsrc needle, uimmI15 needlecntImm,
12630 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12631 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12632 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12633 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12634 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12635 // Required for EA: check if it is still a type_array.
12636 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
12637 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12638 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12639 ins_cost(250);
12640
12641 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12642 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12643 ins_encode %{
12644 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12645 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12646
12647 __ string_indexof($result$$Register,
12648 $haystack$$Register, $haycnt$$Register,
12649 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12650 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
12651 %}
12652 ins_pipe(pipe_class_compare);
12653 %}
12654
12655 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12656 iRegPsrc needle, uimmI15 needlecntImm,
12657 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12658 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12659 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12660 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12661 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12662 // Required for EA: check if it is still a type_array.
12663 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
12664 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12665 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12666 ins_cost(250);
12667
12668 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12669 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12670 ins_encode %{
12671 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12672 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12673
12674 __ string_indexof($result$$Register,
12675 $haystack$$Register, $haycnt$$Register,
12676 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12677 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
12678 %}
12679 ins_pipe(pipe_class_compare);
12680 %}
12681
12682 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12683 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12684 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12685 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12686 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12687 TEMP_DEF result,
12688 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12689 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
12690 ins_cost(300);
12691
12692 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12693 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12694 ins_encode %{
12695 __ string_indexof($result$$Register,
12696 $haystack$$Register, $haycnt$$Register,
12697 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
12698 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
12699 %}
12700 ins_pipe(pipe_class_compare);
12701 %}
12702
12703 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12704 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12705 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12706 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12707 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12708 TEMP_DEF result,
12709 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12710 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
12711 ins_cost(300);
12712
12713 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12714 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12715 ins_encode %{
12716 __ string_indexof($result$$Register,
12717 $haystack$$Register, $haycnt$$Register,
12718 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
12719 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
12720 %}
12721 ins_pipe(pipe_class_compare);
12722 %}
12723
12724 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12725 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12726 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12727 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12728 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12729 TEMP_DEF result,
12730 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12731 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
12732 ins_cost(300);
12733
12734 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12735 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12736 ins_encode %{
12737 __ string_indexof($result$$Register,
12738 $haystack$$Register, $haycnt$$Register,
12739 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
12740 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
12741 %}
12742 ins_pipe(pipe_class_compare);
12743 %}
12744
12745 // char[] to byte[] compression
12746 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12747 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12748 match(Set result (StrCompressedCopy src (Binary dst len)));
12749 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12750 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12751 ins_cost(300);
12752 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12753 ins_encode %{
12754 Label Lskip, Ldone;
12755 __ li($result$$Register, 0);
12756 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
12757 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone);
12758 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
12759 __ beq(CCR0, Lskip);
12760 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone);
12761 __ bind(Lskip);
12762 __ mr($result$$Register, $len$$Register);
12763 __ bind(Ldone);
12764 %}
12765 ins_pipe(pipe_class_default);
12766 %}
12767
12768 // byte[] to char[] inflation
12769 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
12770 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12771 match(Set dummy (StrInflatedCopy src (Binary dst len)));
12772 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12773 ins_cost(300);
12774 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12775 ins_encode %{
12776 Label Ldone;
12777 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
12778 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
12779 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
12780 __ beq(CCR0, Ldone);
12781 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
12782 __ bind(Ldone);
12783 %}
12784 ins_pipe(pipe_class_default);
12785 %}
12786
12787 // StringCoding.java intrinsics
12788 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
12789 regCTR ctr, flagsRegCR0 cr0)
12790 %{
12791 match(Set result (HasNegatives ary1 len));
12792 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
12793 ins_cost(300);
12794 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
12795 ins_encode %{
12796 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register,
12797 $tmp1$$Register, $tmp2$$Register);
12798 %}
12799 ins_pipe(pipe_class_default);
12800 %}
12801
12802 // encode char[] to byte[] in ISO_8859_1
12803 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12804 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12805 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
12806 match(Set result (EncodeISOArray src (Binary dst len)));
12807 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12808 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12809 ins_cost(300);
12810 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12811 ins_encode %{
12812 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12813 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
12814 %}
12815 ins_pipe(pipe_class_default);
12816 %}
12817
12818 // encode char[] to byte[] in ASCII
12819 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12820 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12821 predicate(((EncodeISOArrayNode*)n)->is_ascii());
12822 match(Set result (EncodeISOArray src (Binary dst len)));
12823 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12824 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12825 ins_cost(300);
12826 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12827 ins_encode %{
12828 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12829 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
12830 %}
12831 ins_pipe(pipe_class_default);
12832 %}
12833
12834
12835 //---------- Min/Max Instructions ---------------------------------------------
12836
12837 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
12838 match(Set dst (MinI src1 src2));
12839 ins_cost(DEFAULT_COST*6);
12840
12841 expand %{
12842 iRegLdst src1s;
12843 iRegLdst src2s;
12844 iRegLdst diff;
12845 iRegLdst sm;
12846 iRegLdst doz; // difference or zero
12847 convI2L_reg(src1s, src1); // Ensure proper sign extension.
12848 convI2L_reg(src2s, src2); // Ensure proper sign extension.
12849 subL_reg_reg(diff, src2s, src1s);
12850 // Need to consider >=33 bit result, therefore we need signmaskL.
12851 signmask64L_regL(sm, diff);
12852 andL_reg_reg(doz, diff, sm); // <=0
12853 addI_regL_regL(dst, doz, src1s);
12854 %}
12855 %}
12856
12857 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12858 match(Set dst (MinI src1 src2));
12859 effect(KILL cr0);
12860 predicate(VM_Version::has_isel());
12861 ins_cost(DEFAULT_COST*2);
12862
12863 ins_encode %{
12864 __ cmpw(CCR0, $src1$$Register, $src2$$Register);
12865 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
12866 %}
12867 ins_pipe(pipe_class_default);
12868 %}
12869
12870 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
12871 match(Set dst (MaxI src1 src2));
12872 ins_cost(DEFAULT_COST*6);
12873
12874 expand %{
12875 iRegLdst src1s;
12876 iRegLdst src2s;
12877 iRegLdst diff;
12878 iRegLdst sm;
12879 iRegLdst doz; // difference or zero
12880 convI2L_reg(src1s, src1); // Ensure proper sign extension.
12881 convI2L_reg(src2s, src2); // Ensure proper sign extension.
12882 subL_reg_reg(diff, src2s, src1s);
12883 // Need to consider >=33 bit result, therefore we need signmaskL.
12884 signmask64L_regL(sm, diff);
12885 andcL_reg_reg(doz, diff, sm); // >=0
12886 addI_regL_regL(dst, doz, src1s);
12887 %}
12888 %}
12889
12890 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12891 match(Set dst (MaxI src1 src2));
12892 effect(KILL cr0);
12893 predicate(VM_Version::has_isel());
12894 ins_cost(DEFAULT_COST*2);
12895
12896 ins_encode %{
12897 __ cmpw(CCR0, $src1$$Register, $src2$$Register);
12898 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
12899 %}
12900 ins_pipe(pipe_class_default);
12901 %}
12902
12903 //---------- Population Count Instructions ------------------------------------
12904
12905 // Popcnt for Power7.
12906 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
12907 match(Set dst (PopCountI src));
12908 predicate(UsePopCountInstruction && VM_Version::has_popcntw());
12909 ins_cost(DEFAULT_COST);
12910
12911 format %{ "POPCNTW $dst, $src" %}
12912 size(4);
12913 ins_encode %{
12914 __ popcntw($dst$$Register, $src$$Register);
12915 %}
12916 ins_pipe(pipe_class_default);
12917 %}
12918
12919 // Popcnt for Power7.
12920 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
12921 predicate(UsePopCountInstruction && VM_Version::has_popcntw());
12922 match(Set dst (PopCountL src));
12923 ins_cost(DEFAULT_COST);
12924
12925 format %{ "POPCNTD $dst, $src" %}
12926 size(4);
12927 ins_encode %{
12928 __ popcntd($dst$$Register, $src$$Register);
12929 %}
12930 ins_pipe(pipe_class_default);
12931 %}
12932
12933 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
12934 match(Set dst (CountLeadingZerosI src));
12935 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12936 ins_cost(DEFAULT_COST);
12937
12938 format %{ "CNTLZW $dst, $src" %}
12939 size(4);
12940 ins_encode %{
12941 __ cntlzw($dst$$Register, $src$$Register);
12942 %}
12943 ins_pipe(pipe_class_default);
12944 %}
12945
12946 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
12947 match(Set dst (CountLeadingZerosL src));
12948 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12949 ins_cost(DEFAULT_COST);
12950
12951 format %{ "CNTLZD $dst, $src" %}
12952 size(4);
12953 ins_encode %{
12954 __ cntlzd($dst$$Register, $src$$Register);
12955 %}
12956 ins_pipe(pipe_class_default);
12957 %}
12958
12959 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
12960 // no match-rule, false predicate
12961 effect(DEF dst, USE src);
12962 predicate(false);
12963
12964 format %{ "CNTLZD $dst, $src" %}
12965 size(4);
12966 ins_encode %{
12967 __ cntlzd($dst$$Register, $src$$Register);
12968 %}
12969 ins_pipe(pipe_class_default);
12970 %}
12971
12972 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
12973 match(Set dst (CountTrailingZerosI src));
12974 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12975 ins_cost(DEFAULT_COST);
12976
12977 expand %{
12978 immI16 imm1 %{ (int)-1 %}
12979 immI16 imm2 %{ (int)32 %}
12980 immI_minus1 m1 %{ -1 %}
12981 iRegIdst tmpI1;
12982 iRegIdst tmpI2;
12983 iRegIdst tmpI3;
12984 addI_reg_imm16(tmpI1, src, imm1);
12985 andcI_reg_reg(tmpI2, src, m1, tmpI1);
12986 countLeadingZerosI(tmpI3, tmpI2);
12987 subI_imm16_reg(dst, imm2, tmpI3);
12988 %}
12989 %}
12990
12991 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{
12992 match(Set dst (CountTrailingZerosI src));
12993 predicate(UseCountTrailingZerosInstructionsPPC64);
12994 ins_cost(DEFAULT_COST);
12995
12996 format %{ "CNTTZW $dst, $src" %}
12997 size(4);
12998 ins_encode %{
12999 __ cnttzw($dst$$Register, $src$$Register);
13000 %}
13001 ins_pipe(pipe_class_default);
13002 %}
13003
13004 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
13005 match(Set dst (CountTrailingZerosL src));
13006 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
13007 ins_cost(DEFAULT_COST);
13008
13009 expand %{
13010 immL16 imm1 %{ (long)-1 %}
13011 immI16 imm2 %{ (int)64 %}
13012 iRegLdst tmpL1;
13013 iRegLdst tmpL2;
13014 iRegIdst tmpL3;
13015 addL_reg_imm16(tmpL1, src, imm1);
13016 andcL_reg_reg(tmpL2, tmpL1, src);
13017 countLeadingZerosL(tmpL3, tmpL2);
13018 subI_imm16_reg(dst, imm2, tmpL3);
13019 %}
13020 %}
13021
13022 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{
13023 match(Set dst (CountTrailingZerosL src));
13024 predicate(UseCountTrailingZerosInstructionsPPC64);
13025 ins_cost(DEFAULT_COST);
13026
13027 format %{ "CNTTZD $dst, $src" %}
13028 size(4);
13029 ins_encode %{
13030 __ cnttzd($dst$$Register, $src$$Register);
13031 %}
13032 ins_pipe(pipe_class_default);
13033 %}
13034
13035 // Expand nodes for byte_reverse_int.
13036 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{
13037 effect(DEF dst, USE src, USE pos, USE shift);
13038 predicate(false);
13039
13040 format %{ "INSRWI $dst, $src, $pos, $shift" %}
13041 size(4);
13042 ins_encode %{
13043 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant);
13044 %}
13045 ins_pipe(pipe_class_default);
13046 %}
13047
13048 // As insrwi_a, but with USE_DEF.
13049 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{
13050 effect(USE_DEF dst, USE src, USE pos, USE shift);
13051 predicate(false);
13052
13053 format %{ "INSRWI $dst, $src, $pos, $shift" %}
13054 size(4);
13055 ins_encode %{
13056 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant);
13057 %}
13058 ins_pipe(pipe_class_default);
13059 %}
13060
13061 // Just slightly faster than java implementation.
13062 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
13063 match(Set dst (ReverseBytesI src));
13064 predicate(!UseByteReverseInstructions);
13065 ins_cost(7*DEFAULT_COST);
13066
13067 expand %{
13068 immI16 imm24 %{ (int) 24 %}
13069 immI16 imm16 %{ (int) 16 %}
13070 immI16 imm8 %{ (int) 8 %}
13071 immI16 imm4 %{ (int) 4 %}
13072 immI16 imm0 %{ (int) 0 %}
13073 iRegLdst tmpI1;
13074 iRegLdst tmpI2;
13075 iRegLdst tmpI3;
13076
13077 urShiftI_reg_imm(tmpI1, src, imm24);
13078 insrwi_a(dst, tmpI1, imm24, imm8);
13079 urShiftI_reg_imm(tmpI2, src, imm16);
13080 insrwi(dst, tmpI2, imm8, imm16);
13081 urShiftI_reg_imm(tmpI3, src, imm8);
13082 insrwi(dst, tmpI3, imm8, imm8);
13083 insrwi(dst, src, imm0, imm8);
13084 %}
13085 %}
13086
13087 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{
13088 match(Set dst (ReverseBytesI src));
13089 predicate(UseVectorByteReverseInstructionsPPC64);
13090 effect(TEMP tmpV);
13091 ins_cost(DEFAULT_COST*3);
13092 size(12);
13093 format %{ "MTVSRWZ $tmpV, $src\n"
13094 "\tXXBRW $tmpV, $tmpV\n"
13095 "\tMFVSRWZ $dst, $tmpV" %}
13096
13097 ins_encode %{
13098 __ mtvsrwz($tmpV$$VectorSRegister, $src$$Register);
13099 __ xxbrw($tmpV$$VectorSRegister, $tmpV$$VectorSRegister);
13100 __ mfvsrwz($dst$$Register, $tmpV$$VectorSRegister);
13101 %}
13102 ins_pipe(pipe_class_default);
13103 %}
13104
13105 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{
13106 match(Set dst (ReverseBytesI src));
13107 predicate(UseByteReverseInstructions);
13108 ins_cost(DEFAULT_COST);
13109 size(4);
13110
13111 format %{ "BRW $dst, $src" %}
13112
13113 ins_encode %{
13114 __ brw($dst$$Register, $src$$Register);
13115 %}
13116 ins_pipe(pipe_class_default);
13117 %}
13118
13119 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
13120 match(Set dst (ReverseBytesL src));
13121 predicate(!UseByteReverseInstructions);
13122 ins_cost(15*DEFAULT_COST);
13123
13124 expand %{
13125 immI16 imm56 %{ (int) 56 %}
13126 immI16 imm48 %{ (int) 48 %}
13127 immI16 imm40 %{ (int) 40 %}
13128 immI16 imm32 %{ (int) 32 %}
13129 immI16 imm24 %{ (int) 24 %}
13130 immI16 imm16 %{ (int) 16 %}
13131 immI16 imm8 %{ (int) 8 %}
13132 immI16 imm0 %{ (int) 0 %}
13133 iRegLdst tmpL1;
13134 iRegLdst tmpL2;
13135 iRegLdst tmpL3;
13136 iRegLdst tmpL4;
13137 iRegLdst tmpL5;
13138 iRegLdst tmpL6;
13139
13140 // src : |a|b|c|d|e|f|g|h|
13141 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
13142 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
13143 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
13144 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
13145 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
13146 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
13147 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
13148 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
13149 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
13150 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
13151 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
13152 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
13153 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
13154 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
13155 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
13156 %}
13157 %}
13158
13159 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{
13160 match(Set dst (ReverseBytesL src));
13161 predicate(UseVectorByteReverseInstructionsPPC64);
13162 effect(TEMP tmpV);
13163 ins_cost(DEFAULT_COST*3);
13164 size(12);
13165 format %{ "MTVSRD $tmpV, $src\n"
13166 "\tXXBRD $tmpV, $tmpV\n"
13167 "\tMFVSRD $dst, $tmpV" %}
13168
13169 ins_encode %{
13170 __ mtvsrd($tmpV$$VectorSRegister, $src$$Register);
13171 __ xxbrd($tmpV$$VectorSRegister, $tmpV$$VectorSRegister);
13172 __ mfvsrd($dst$$Register, $tmpV$$VectorSRegister);
13173 %}
13174 ins_pipe(pipe_class_default);
13175 %}
13176
13177 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{
13178 match(Set dst (ReverseBytesL src));
13179 predicate(UseByteReverseInstructions);
13180 ins_cost(DEFAULT_COST);
13181 size(4);
13182
13183 format %{ "BRD $dst, $src" %}
13184
13185 ins_encode %{
13186 __ brd($dst$$Register, $src$$Register);
13187 %}
13188 ins_pipe(pipe_class_default);
13189 %}
13190
13191 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
13192 match(Set dst (ReverseBytesUS src));
13193 predicate(!UseByteReverseInstructions);
13194 ins_cost(2*DEFAULT_COST);
13195
13196 expand %{
13197 immI16 imm16 %{ (int) 16 %}
13198 immI16 imm8 %{ (int) 8 %}
13199
13200 urShiftI_reg_imm(dst, src, imm8);
13201 insrwi(dst, src, imm16, imm8);
13202 %}
13203 %}
13204
13205 instruct bytes_reverse_ushort(iRegIdst dst, iRegIsrc src) %{
13206 match(Set dst (ReverseBytesUS src));
13207 predicate(UseByteReverseInstructions);
13208 ins_cost(DEFAULT_COST);
13209 size(4);
13210
13211 format %{ "BRH $dst, $src" %}
13212
13213 ins_encode %{
13214 __ brh($dst$$Register, $src$$Register);
13215 %}
13216 ins_pipe(pipe_class_default);
13217 %}
13218
13219 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
13220 match(Set dst (ReverseBytesS src));
13221 predicate(!UseByteReverseInstructions);
13222 ins_cost(3*DEFAULT_COST);
13223
13224 expand %{
13225 immI16 imm16 %{ (int) 16 %}
13226 immI16 imm8 %{ (int) 8 %}
13227 iRegLdst tmpI1;
13228
13229 urShiftI_reg_imm(tmpI1, src, imm8);
13230 insrwi(tmpI1, src, imm16, imm8);
13231 extsh(dst, tmpI1);
13232 %}
13233 %}
13234
13235 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{
13236 match(Set dst (ReverseBytesS src));
13237 predicate(UseByteReverseInstructions);
13238 ins_cost(DEFAULT_COST);
13239 size(8);
13240
13241 format %{ "BRH $dst, $src\n\t"
13242 "EXTSH $dst, $dst" %}
13243
13244 ins_encode %{
13245 __ brh($dst$$Register, $src$$Register);
13246 __ extsh($dst$$Register, $dst$$Register);
13247 %}
13248 ins_pipe(pipe_class_default);
13249 %}
13250
13251 // Load Integer reversed byte order
13252 instruct loadI_reversed(iRegIdst dst, indirect mem) %{
13253 match(Set dst (ReverseBytesI (LoadI mem)));
13254 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
13255 ins_cost(MEMORY_REF_COST);
13256
13257 size(4);
13258 ins_encode %{
13259 __ lwbrx($dst$$Register, $mem$$Register);
13260 %}
13261 ins_pipe(pipe_class_default);
13262 %}
13263
13264 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{
13265 match(Set dst (ReverseBytesI (LoadI mem)));
13266 ins_cost(2 * MEMORY_REF_COST);
13267
13268 size(12);
13269 ins_encode %{
13270 __ lwbrx($dst$$Register, $mem$$Register);
13271 __ twi_0($dst$$Register);
13272 __ isync();
13273 %}
13274 ins_pipe(pipe_class_default);
13275 %}
13276
13277 // Load Long - aligned and reversed
13278 instruct loadL_reversed(iRegLdst dst, indirect mem) %{
13279 match(Set dst (ReverseBytesL (LoadL mem)));
13280 predicate(VM_Version::has_ldbrx() && (n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))));
13281 ins_cost(MEMORY_REF_COST);
13282
13283 size(4);
13284 ins_encode %{
13285 __ ldbrx($dst$$Register, $mem$$Register);
13286 %}
13287 ins_pipe(pipe_class_default);
13288 %}
13289
13290 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{
13291 match(Set dst (ReverseBytesL (LoadL mem)));
13292 predicate(VM_Version::has_ldbrx());
13293 ins_cost(2 * MEMORY_REF_COST);
13294
13295 size(12);
13296 ins_encode %{
13297 __ ldbrx($dst$$Register, $mem$$Register);
13298 __ twi_0($dst$$Register);
13299 __ isync();
13300 %}
13301 ins_pipe(pipe_class_default);
13302 %}
13303
13304 // Load unsigned short / char reversed byte order
13305 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
13306 match(Set dst (ReverseBytesUS (LoadUS mem)));
13307 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
13308 ins_cost(MEMORY_REF_COST);
13309
13310 size(4);
13311 ins_encode %{
13312 __ lhbrx($dst$$Register, $mem$$Register);
13313 %}
13314 ins_pipe(pipe_class_default);
13315 %}
13316
13317 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{
13318 match(Set dst (ReverseBytesUS (LoadUS mem)));
13319 ins_cost(2 * MEMORY_REF_COST);
13320
13321 size(12);
13322 ins_encode %{
13323 __ lhbrx($dst$$Register, $mem$$Register);
13324 __ twi_0($dst$$Register);
13325 __ isync();
13326 %}
13327 ins_pipe(pipe_class_default);
13328 %}
13329
13330 // Load short reversed byte order
13331 instruct loadS_reversed(iRegIdst dst, indirect mem) %{
13332 match(Set dst (ReverseBytesS (LoadS mem)));
13333 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
13334 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
13335
13336 size(8);
13337 ins_encode %{
13338 __ lhbrx($dst$$Register, $mem$$Register);
13339 __ extsh($dst$$Register, $dst$$Register);
13340 %}
13341 ins_pipe(pipe_class_default);
13342 %}
13343
13344 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{
13345 match(Set dst (ReverseBytesS (LoadS mem)));
13346 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
13347
13348 size(16);
13349 ins_encode %{
13350 __ lhbrx($dst$$Register, $mem$$Register);
13351 __ twi_0($dst$$Register);
13352 __ extsh($dst$$Register, $dst$$Register);
13353 __ isync();
13354 %}
13355 ins_pipe(pipe_class_default);
13356 %}
13357
13358 // Store Integer reversed byte order
13359 instruct storeI_reversed(iRegIsrc src, indirect mem) %{
13360 match(Set mem (StoreI mem (ReverseBytesI src)));
13361 ins_cost(MEMORY_REF_COST);
13362
13363 size(4);
13364 ins_encode %{
13365 __ stwbrx($src$$Register, $mem$$Register);
13366 %}
13367 ins_pipe(pipe_class_default);
13368 %}
13369
13370 // Store Long reversed byte order
13371 instruct storeL_reversed(iRegLsrc src, indirect mem) %{
13372 match(Set mem (StoreL mem (ReverseBytesL src)));
13373 predicate(VM_Version::has_stdbrx());
13374 ins_cost(MEMORY_REF_COST);
13375
13376 size(4);
13377 ins_encode %{
13378 __ stdbrx($src$$Register, $mem$$Register);
13379 %}
13380 ins_pipe(pipe_class_default);
13381 %}
13382
13383 // Store unsigned short / char reversed byte order
13384 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
13385 match(Set mem (StoreC mem (ReverseBytesUS src)));
13386 ins_cost(MEMORY_REF_COST);
13387
13388 size(4);
13389 ins_encode %{
13390 __ sthbrx($src$$Register, $mem$$Register);
13391 %}
13392 ins_pipe(pipe_class_default);
13393 %}
13394
13395 // Store short reversed byte order
13396 instruct storeS_reversed(iRegIsrc src, indirect mem) %{
13397 match(Set mem (StoreC mem (ReverseBytesS src)));
13398 ins_cost(MEMORY_REF_COST);
13399
13400 size(4);
13401 ins_encode %{
13402 __ sthbrx($src$$Register, $mem$$Register);
13403 %}
13404 ins_pipe(pipe_class_default);
13405 %}
13406
13407 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
13408 effect(DEF temp1, USE src);
13409
13410 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %}
13411 size(4);
13412 ins_encode %{
13413 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register);
13414 %}
13415 ins_pipe(pipe_class_default);
13416 %}
13417
13418 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{
13419 effect(DEF dst, USE src, USE imm1);
13420
13421 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %}
13422 size(4);
13423 ins_encode %{
13424 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant);
13425 %}
13426 ins_pipe(pipe_class_default);
13427 %}
13428
13429 instruct xscvdpspn_regF(vecX dst, regF src) %{
13430 effect(DEF dst, USE src);
13431
13432 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %}
13433 size(4);
13434 ins_encode %{
13435 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr());
13436 %}
13437 ins_pipe(pipe_class_default);
13438 %}
13439
13440 //---------- Replicate Vector Instructions ------------------------------------
13441
13442 // Insrdi does replicate if src == dst.
13443 instruct repl32(iRegLdst dst) %{
13444 predicate(false);
13445 effect(USE_DEF dst);
13446
13447 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %}
13448 size(4);
13449 ins_encode %{
13450 __ insrdi($dst$$Register, $dst$$Register, 32, 0);
13451 %}
13452 ins_pipe(pipe_class_default);
13453 %}
13454
13455 // Insrdi does replicate if src == dst.
13456 instruct repl48(iRegLdst dst) %{
13457 predicate(false);
13458 effect(USE_DEF dst);
13459
13460 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %}
13461 size(4);
13462 ins_encode %{
13463 __ insrdi($dst$$Register, $dst$$Register, 48, 0);
13464 %}
13465 ins_pipe(pipe_class_default);
13466 %}
13467
13468 // Insrdi does replicate if src == dst.
13469 instruct repl56(iRegLdst dst) %{
13470 predicate(false);
13471 effect(USE_DEF dst);
13472
13473 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %}
13474 size(4);
13475 ins_encode %{
13476 __ insrdi($dst$$Register, $dst$$Register, 56, 0);
13477 %}
13478 ins_pipe(pipe_class_default);
13479 %}
13480
13481 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
13482 match(Set dst (ReplicateB src));
13483 predicate(n->as_Vector()->length() == 8);
13484 expand %{
13485 moveReg(dst, src);
13486 repl56(dst);
13487 repl48(dst);
13488 repl32(dst);
13489 %}
13490 %}
13491
13492 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
13493 match(Set dst (ReplicateB zero));
13494 predicate(n->as_Vector()->length() == 8);
13495 format %{ "LI $dst, #0 \t// replicate8B" %}
13496 size(4);
13497 ins_encode %{
13498 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
13499 %}
13500 ins_pipe(pipe_class_default);
13501 %}
13502
13503 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
13504 match(Set dst (ReplicateB src));
13505 predicate(n->as_Vector()->length() == 8);
13506 format %{ "LI $dst, #-1 \t// replicate8B" %}
13507 size(4);
13508 ins_encode %{
13509 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
13510 %}
13511 ins_pipe(pipe_class_default);
13512 %}
13513
13514 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{
13515 match(Set dst (ReplicateB src));
13516 predicate(n->as_Vector()->length() == 16);
13517
13518 expand %{
13519 iRegLdst tmpL;
13520 vecX tmpV;
13521 immI8 imm1 %{ (int) 1 %}
13522 moveReg(tmpL, src);
13523 repl56(tmpL);
13524 repl48(tmpL);
13525 mtvsrwz(tmpV, tmpL);
13526 xxspltw(dst, tmpV, imm1);
13527 %}
13528 %}
13529
13530 instruct repl16B_immI0(vecX dst, immI_0 zero) %{
13531 match(Set dst (ReplicateB zero));
13532 predicate(n->as_Vector()->length() == 16);
13533
13534 format %{ "XXLXOR $dst, $zero \t// replicate16B" %}
13535 size(4);
13536 ins_encode %{
13537 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13538 %}
13539 ins_pipe(pipe_class_default);
13540 %}
13541
13542 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{
13543 match(Set dst (ReplicateB src));
13544 predicate(n->as_Vector()->length() == 16);
13545
13546 format %{ "XXLEQV $dst, $src \t// replicate16B" %}
13547 size(4);
13548 ins_encode %{
13549 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13550 %}
13551 ins_pipe(pipe_class_default);
13552 %}
13553
13554 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
13555 match(Set dst (ReplicateS src));
13556 predicate(n->as_Vector()->length() == 4);
13557 expand %{
13558 moveReg(dst, src);
13559 repl48(dst);
13560 repl32(dst);
13561 %}
13562 %}
13563
13564 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
13565 match(Set dst (ReplicateS zero));
13566 predicate(n->as_Vector()->length() == 4);
13567 format %{ "LI $dst, #0 \t// replicate4S" %}
13568 size(4);
13569 ins_encode %{
13570 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
13571 %}
13572 ins_pipe(pipe_class_default);
13573 %}
13574
13575 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
13576 match(Set dst (ReplicateS src));
13577 predicate(n->as_Vector()->length() == 4);
13578 format %{ "LI $dst, -1 \t// replicate4S" %}
13579 size(4);
13580 ins_encode %{
13581 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
13582 %}
13583 ins_pipe(pipe_class_default);
13584 %}
13585
13586 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{
13587 match(Set dst (ReplicateS src));
13588 predicate(n->as_Vector()->length() == 8);
13589
13590 expand %{
13591 iRegLdst tmpL;
13592 vecX tmpV;
13593 immI8 zero %{ (int) 0 %}
13594 moveReg(tmpL, src);
13595 repl48(tmpL);
13596 repl32(tmpL);
13597 mtvsrd(tmpV, tmpL);
13598 xxpermdi(dst, tmpV, tmpV, zero);
13599 %}
13600 %}
13601
13602 instruct repl8S_immI0(vecX dst, immI_0 zero) %{
13603 match(Set dst (ReplicateS zero));
13604 predicate(n->as_Vector()->length() == 8);
13605
13606 format %{ "XXLXOR $dst, $zero \t// replicate8S" %}
13607 size(4);
13608 ins_encode %{
13609 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13610 %}
13611 ins_pipe(pipe_class_default);
13612 %}
13613
13614 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{
13615 match(Set dst (ReplicateS src));
13616 predicate(n->as_Vector()->length() == 8);
13617
13618 format %{ "XXLEQV $dst, $src \t// replicate8S" %}
13619 size(4);
13620 ins_encode %{
13621 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13622 %}
13623 ins_pipe(pipe_class_default);
13624 %}
13625
13626 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
13627 match(Set dst (ReplicateI src));
13628 predicate(n->as_Vector()->length() == 2);
13629 ins_cost(2 * DEFAULT_COST);
13630 expand %{
13631 moveReg(dst, src);
13632 repl32(dst);
13633 %}
13634 %}
13635
13636 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
13637 match(Set dst (ReplicateI zero));
13638 predicate(n->as_Vector()->length() == 2);
13639 format %{ "LI $dst, #0 \t// replicate2I" %}
13640 size(4);
13641 ins_encode %{
13642 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
13643 %}
13644 ins_pipe(pipe_class_default);
13645 %}
13646
13647 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
13648 match(Set dst (ReplicateI src));
13649 predicate(n->as_Vector()->length() == 2);
13650 format %{ "LI $dst, -1 \t// replicate2I" %}
13651 size(4);
13652 ins_encode %{
13653 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
13654 %}
13655 ins_pipe(pipe_class_default);
13656 %}
13657
13658 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{
13659 match(Set dst (ReplicateI src));
13660 predicate(n->as_Vector()->length() == 4);
13661 ins_cost(2 * DEFAULT_COST);
13662
13663 expand %{
13664 iRegLdst tmpL;
13665 vecX tmpV;
13666 immI8 zero %{ (int) 0 %}
13667 moveReg(tmpL, src);
13668 repl32(tmpL);
13669 mtvsrd(tmpV, tmpL);
13670 xxpermdi(dst, tmpV, tmpV, zero);
13671 %}
13672 %}
13673
13674 instruct repl4I_immI0(vecX dst, immI_0 zero) %{
13675 match(Set dst (ReplicateI zero));
13676 predicate(n->as_Vector()->length() == 4);
13677
13678 format %{ "XXLXOR $dst, $zero \t// replicate4I" %}
13679 size(4);
13680 ins_encode %{
13681 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13682 %}
13683 ins_pipe(pipe_class_default);
13684 %}
13685
13686 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{
13687 match(Set dst (ReplicateI src));
13688 predicate(n->as_Vector()->length() == 4);
13689
13690 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %}
13691 size(4);
13692 ins_encode %{
13693 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13694 %}
13695 ins_pipe(pipe_class_default);
13696 %}
13697
13698 // Move float to int register via stack, replicate.
13699 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
13700 match(Set dst (ReplicateF src));
13701 predicate(n->as_Vector()->length() == 2);
13702 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
13703 expand %{
13704 stackSlotL tmpS;
13705 iRegIdst tmpI;
13706 moveF2I_reg_stack(tmpS, src); // Move float to stack.
13707 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
13708 moveReg(dst, tmpI); // Move int to long reg.
13709 repl32(dst); // Replicate bitpattern.
13710 %}
13711 %}
13712
13713 // Replicate scalar constant to packed float values in Double register
13714 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
13715 match(Set dst (ReplicateF src));
13716 predicate(n->as_Vector()->length() == 2);
13717 ins_cost(5 * DEFAULT_COST);
13718
13719 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
13720 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
13721 %}
13722
13723 // Replicate scalar zero constant to packed float values in Double register
13724 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
13725 match(Set dst (ReplicateF zero));
13726 predicate(n->as_Vector()->length() == 2);
13727
13728 format %{ "LI $dst, #0 \t// replicate2F" %}
13729 ins_encode %{
13730 __ li($dst$$Register, 0x0);
13731 %}
13732 ins_pipe(pipe_class_default);
13733 %}
13734
13735
13736 //----------Vector Arithmetic Instructions--------------------------------------
13737
13738 // Vector Addition Instructions
13739
13740 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
13741 match(Set dst (AddVB src1 src2));
13742 predicate(n->as_Vector()->length() == 16);
13743 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %}
13744 size(4);
13745 ins_encode %{
13746 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13747 %}
13748 ins_pipe(pipe_class_default);
13749 %}
13750
13751 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
13752 match(Set dst (AddVS src1 src2));
13753 predicate(n->as_Vector()->length() == 8);
13754 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %}
13755 size(4);
13756 ins_encode %{
13757 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13758 %}
13759 ins_pipe(pipe_class_default);
13760 %}
13761
13762 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
13763 match(Set dst (AddVI src1 src2));
13764 predicate(n->as_Vector()->length() == 4);
13765 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %}
13766 size(4);
13767 ins_encode %{
13768 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13769 %}
13770 ins_pipe(pipe_class_default);
13771 %}
13772
13773 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
13774 match(Set dst (AddVF src1 src2));
13775 predicate(n->as_Vector()->length() == 4);
13776 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %}
13777 size(4);
13778 ins_encode %{
13779 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13780 %}
13781 ins_pipe(pipe_class_default);
13782 %}
13783
13784 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
13785 match(Set dst (AddVL src1 src2));
13786 predicate(n->as_Vector()->length() == 2);
13787 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %}
13788 size(4);
13789 ins_encode %{
13790 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13791 %}
13792 ins_pipe(pipe_class_default);
13793 %}
13794
13795 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
13796 match(Set dst (AddVD src1 src2));
13797 predicate(n->as_Vector()->length() == 2);
13798 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %}
13799 size(4);
13800 ins_encode %{
13801 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13802 %}
13803 ins_pipe(pipe_class_default);
13804 %}
13805
13806 // Vector Subtraction Instructions
13807
13808 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
13809 match(Set dst (SubVB src1 src2));
13810 predicate(n->as_Vector()->length() == 16);
13811 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %}
13812 size(4);
13813 ins_encode %{
13814 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13815 %}
13816 ins_pipe(pipe_class_default);
13817 %}
13818
13819 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
13820 match(Set dst (SubVS src1 src2));
13821 predicate(n->as_Vector()->length() == 8);
13822 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %}
13823 size(4);
13824 ins_encode %{
13825 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13826 %}
13827 ins_pipe(pipe_class_default);
13828 %}
13829
13830 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
13831 match(Set dst (SubVI src1 src2));
13832 predicate(n->as_Vector()->length() == 4);
13833 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %}
13834 size(4);
13835 ins_encode %{
13836 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13837 %}
13838 ins_pipe(pipe_class_default);
13839 %}
13840
13841 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
13842 match(Set dst (SubVF src1 src2));
13843 predicate(n->as_Vector()->length() == 4);
13844 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %}
13845 size(4);
13846 ins_encode %{
13847 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13848 %}
13849 ins_pipe(pipe_class_default);
13850 %}
13851
13852 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
13853 match(Set dst (SubVL src1 src2));
13854 predicate(n->as_Vector()->length() == 2);
13855 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %}
13856 size(4);
13857 ins_encode %{
13858 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13859 %}
13860 ins_pipe(pipe_class_default);
13861 %}
13862
13863 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
13864 match(Set dst (SubVD src1 src2));
13865 predicate(n->as_Vector()->length() == 2);
13866 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %}
13867 size(4);
13868 ins_encode %{
13869 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13870 %}
13871 ins_pipe(pipe_class_default);
13872 %}
13873
13874 // Vector Multiplication Instructions
13875
13876 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
13877 match(Set dst (MulVS src1 src2));
13878 predicate(n->as_Vector()->length() == 8);
13879 effect(TEMP tmp);
13880 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %}
13881 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %}
13882 size(8);
13883 ins_encode %{
13884 __ vspltish($tmp$$VectorSRegister->to_vr(), 0);
13885 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr());
13886 %}
13887 ins_pipe(pipe_class_default);
13888 %}
13889
13890 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
13891 match(Set dst (MulVI src1 src2));
13892 predicate(n->as_Vector()->length() == 4);
13893 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %}
13894 size(4);
13895 ins_encode %{
13896 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13897 %}
13898 ins_pipe(pipe_class_default);
13899 %}
13900
13901 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
13902 match(Set dst (MulVF src1 src2));
13903 predicate(n->as_Vector()->length() == 4);
13904 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %}
13905 size(4);
13906 ins_encode %{
13907 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13908 %}
13909 ins_pipe(pipe_class_default);
13910 %}
13911
13912 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
13913 match(Set dst (MulVD src1 src2));
13914 predicate(n->as_Vector()->length() == 2);
13915 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %}
13916 size(4);
13917 ins_encode %{
13918 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13919 %}
13920 ins_pipe(pipe_class_default);
13921 %}
13922
13923 // Vector Division Instructions
13924
13925 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
13926 match(Set dst (DivVF src1 src2));
13927 predicate(n->as_Vector()->length() == 4);
13928 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %}
13929 size(4);
13930 ins_encode %{
13931 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13932 %}
13933 ins_pipe(pipe_class_default);
13934 %}
13935
13936 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
13937 match(Set dst (DivVD src1 src2));
13938 predicate(n->as_Vector()->length() == 2);
13939 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %}
13940 size(4);
13941 ins_encode %{
13942 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13943 %}
13944 ins_pipe(pipe_class_default);
13945 %}
13946
13947 // Vector Absolute Instructions
13948
13949 instruct vabs4F_reg(vecX dst, vecX src) %{
13950 match(Set dst (AbsVF src));
13951 predicate(n->as_Vector()->length() == 4);
13952 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
13953 size(4);
13954 ins_encode %{
13955 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister);
13956 %}
13957 ins_pipe(pipe_class_default);
13958 %}
13959
13960 instruct vabs2D_reg(vecX dst, vecX src) %{
13961 match(Set dst (AbsVD src));
13962 predicate(n->as_Vector()->length() == 2);
13963 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
13964 size(4);
13965 ins_encode %{
13966 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister);
13967 %}
13968 ins_pipe(pipe_class_default);
13969 %}
13970
13971 // Round Instructions
13972 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{
13973 match(Set dst (RoundDoubleMode src rmode));
13974 format %{ "RoundDoubleMode $src,$rmode" %}
13975 size(4);
13976 ins_encode %{
13977 switch ($rmode$$constant) {
13978 case RoundDoubleModeNode::rmode_rint:
13979 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr());
13980 break;
13981 case RoundDoubleModeNode::rmode_floor:
13982 __ frim($dst$$FloatRegister, $src$$FloatRegister);
13983 break;
13984 case RoundDoubleModeNode::rmode_ceil:
13985 __ frip($dst$$FloatRegister, $src$$FloatRegister);
13986 break;
13987 default:
13988 ShouldNotReachHere();
13989 }
13990 %}
13991 ins_pipe(pipe_class_default);
13992 %}
13993
13994 // Vector Round Instructions
13995 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
13996 match(Set dst (RoundDoubleModeV src rmode));
13997 predicate(n->as_Vector()->length() == 2);
13998 format %{ "RoundDoubleModeV $src,$rmode" %}
13999 size(4);
14000 ins_encode %{
14001 switch ($rmode$$constant) {
14002 case RoundDoubleModeNode::rmode_rint:
14003 __ xvrdpic($dst$$VectorSRegister, $src$$VectorSRegister);
14004 break;
14005 case RoundDoubleModeNode::rmode_floor:
14006 __ xvrdpim($dst$$VectorSRegister, $src$$VectorSRegister);
14007 break;
14008 case RoundDoubleModeNode::rmode_ceil:
14009 __ xvrdpip($dst$$VectorSRegister, $src$$VectorSRegister);
14010 break;
14011 default:
14012 ShouldNotReachHere();
14013 }
14014 %}
14015 ins_pipe(pipe_class_default);
14016 %}
14017
14018 // Vector Negate Instructions
14019
14020 instruct vneg4F_reg(vecX dst, vecX src) %{
14021 match(Set dst (NegVF src));
14022 predicate(n->as_Vector()->length() == 4);
14023 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
14024 size(4);
14025 ins_encode %{
14026 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister);
14027 %}
14028 ins_pipe(pipe_class_default);
14029 %}
14030
14031 instruct vneg2D_reg(vecX dst, vecX src) %{
14032 match(Set dst (NegVD src));
14033 predicate(n->as_Vector()->length() == 2);
14034 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
14035 size(4);
14036 ins_encode %{
14037 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister);
14038 %}
14039 ins_pipe(pipe_class_default);
14040 %}
14041
14042 // Vector Square Root Instructions
14043
14044 instruct vsqrt4F_reg(vecX dst, vecX src) %{
14045 match(Set dst (SqrtVF src));
14046 predicate(n->as_Vector()->length() == 4);
14047 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
14048 size(4);
14049 ins_encode %{
14050 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister);
14051 %}
14052 ins_pipe(pipe_class_default);
14053 %}
14054
14055 instruct vsqrt2D_reg(vecX dst, vecX src) %{
14056 match(Set dst (SqrtVD src));
14057 predicate(n->as_Vector()->length() == 2);
14058 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %}
14059 size(4);
14060 ins_encode %{
14061 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister);
14062 %}
14063 ins_pipe(pipe_class_default);
14064 %}
14065
14066 // Vector Population Count Instructions
14067
14068 instruct vpopcnt4I_reg(vecX dst, vecX src) %{
14069 match(Set dst (PopCountVI src));
14070 predicate(n->as_Vector()->length() == 4);
14071 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %}
14072 size(4);
14073 ins_encode %{
14074 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr());
14075 %}
14076 ins_pipe(pipe_class_default);
14077 %}
14078
14079 // --------------------------------- FMA --------------------------------------
14080 // dst + src1 * src2
14081 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{
14082 match(Set dst (FmaVF dst (Binary src1 src2)));
14083 predicate(n->as_Vector()->length() == 4);
14084
14085 format %{ "XVMADDASP $dst, $src1, $src2" %}
14086
14087 size(4);
14088 ins_encode %{
14089 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14090 %}
14091 ins_pipe(pipe_class_default);
14092 %}
14093
14094 // dst - src1 * src2
14095 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{
14096 match(Set dst (FmaVF dst (Binary (NegVF src1) src2)));
14097 match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
14098 predicate(n->as_Vector()->length() == 4);
14099
14100 format %{ "XVNMSUBASP $dst, $src1, $src2" %}
14101
14102 size(4);
14103 ins_encode %{
14104 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14105 %}
14106 ins_pipe(pipe_class_default);
14107 %}
14108
14109 // - dst + src1 * src2
14110 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{
14111 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2)));
14112 predicate(n->as_Vector()->length() == 4);
14113
14114 format %{ "XVMSUBASP $dst, $src1, $src2" %}
14115
14116 size(4);
14117 ins_encode %{
14118 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14119 %}
14120 ins_pipe(pipe_class_default);
14121 %}
14122
14123 // dst + src1 * src2
14124 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{
14125 match(Set dst (FmaVD dst (Binary src1 src2)));
14126 predicate(n->as_Vector()->length() == 2);
14127
14128 format %{ "XVMADDADP $dst, $src1, $src2" %}
14129
14130 size(4);
14131 ins_encode %{
14132 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14133 %}
14134 ins_pipe(pipe_class_default);
14135 %}
14136
14137 // dst - src1 * src2
14138 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{
14139 match(Set dst (FmaVD dst (Binary (NegVD src1) src2)));
14140 match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
14141 predicate(n->as_Vector()->length() == 2);
14142
14143 format %{ "XVNMSUBADP $dst, $src1, $src2" %}
14144
14145 size(4);
14146 ins_encode %{
14147 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14148 %}
14149 ins_pipe(pipe_class_default);
14150 %}
14151
14152 // - dst + src1 * src2
14153 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
14154 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2)));
14155 predicate(n->as_Vector()->length() == 2);
14156
14157 format %{ "XVMSUBADP $dst, $src1, $src2" %}
14158
14159 size(4);
14160 ins_encode %{
14161 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14162 %}
14163 ins_pipe(pipe_class_default);
14164 %}
14165
14166 //----------Overflow Math Instructions-----------------------------------------
14167
14168 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
14169 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
14170 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
14171
14172 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
14173 match(Set cr0 (OverflowAddL op1 op2));
14174
14175 format %{ "add_ $op1, $op2\t# overflow check long" %}
14176 ins_encode %{
14177 __ li(R0, 0);
14178 __ mtxer(R0); // clear XER.SO
14179 __ addo_(R0, $op1$$Register, $op2$$Register);
14180 %}
14181 ins_pipe(pipe_class_default);
14182 %}
14183
14184 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
14185 match(Set cr0 (OverflowSubL op1 op2));
14186
14187 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %}
14188 ins_encode %{
14189 __ li(R0, 0);
14190 __ mtxer(R0); // clear XER.SO
14191 __ subfo_(R0, $op2$$Register, $op1$$Register);
14192 %}
14193 ins_pipe(pipe_class_default);
14194 %}
14195
14196 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
14197 match(Set cr0 (OverflowSubL zero op2));
14198
14199 format %{ "nego_ R0, $op2\t# overflow check long" %}
14200 ins_encode %{
14201 __ li(R0, 0);
14202 __ mtxer(R0); // clear XER.SO
14203 __ nego_(R0, $op2$$Register);
14204 %}
14205 ins_pipe(pipe_class_default);
14206 %}
14207
14208 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
14209 match(Set cr0 (OverflowMulL op1 op2));
14210
14211 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %}
14212 ins_encode %{
14213 __ li(R0, 0);
14214 __ mtxer(R0); // clear XER.SO
14215 __ mulldo_(R0, $op1$$Register, $op2$$Register);
14216 %}
14217 ins_pipe(pipe_class_default);
14218 %}
14219
14220 instruct repl4F_reg_Ex(vecX dst, regF src) %{
14221 match(Set dst (ReplicateF src));
14222 predicate(n->as_Vector()->length() == 4);
14223 ins_cost(DEFAULT_COST);
14224 expand %{
14225 vecX tmpV;
14226 immI8 zero %{ (int) 0 %}
14227
14228 xscvdpspn_regF(tmpV, src);
14229 xxspltw(dst, tmpV, zero);
14230 %}
14231 %}
14232
14233 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{
14234 match(Set dst (ReplicateF src));
14235 predicate(n->as_Vector()->length() == 4);
14236 effect(TEMP tmp);
14237 ins_cost(10 * DEFAULT_COST);
14238
14239 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) );
14240 %}
14241
14242 instruct repl4F_immF0(vecX dst, immF_0 zero) %{
14243 match(Set dst (ReplicateF zero));
14244 predicate(n->as_Vector()->length() == 4);
14245
14246 format %{ "XXLXOR $dst, $zero \t// replicate4F" %}
14247 ins_encode %{
14248 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
14249 %}
14250 ins_pipe(pipe_class_default);
14251 %}
14252
14253 instruct repl2D_reg_Ex(vecX dst, regD src) %{
14254 match(Set dst (ReplicateD src));
14255 predicate(n->as_Vector()->length() == 2);
14256
14257 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %}
14258 size(4);
14259 ins_encode %{
14260 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0);
14261 %}
14262 ins_pipe(pipe_class_default);
14263 %}
14264
14265 instruct repl2D_immD0(vecX dst, immD_0 zero) %{
14266 match(Set dst (ReplicateD zero));
14267 predicate(n->as_Vector()->length() == 2);
14268
14269 format %{ "XXLXOR $dst, $zero \t// replicate2D" %}
14270 size(4);
14271 ins_encode %{
14272 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
14273 %}
14274 ins_pipe(pipe_class_default);
14275 %}
14276
14277 instruct mtvsrd(vecX dst, iRegLsrc src) %{
14278 predicate(false);
14279 effect(DEF dst, USE src);
14280
14281 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %}
14282 size(4);
14283 ins_encode %{
14284 __ mtvsrd($dst$$VectorSRegister, $src$$Register);
14285 %}
14286 ins_pipe(pipe_class_default);
14287 %}
14288
14289 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{
14290 effect(DEF dst, USE src, USE zero);
14291
14292 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %}
14293 size(4);
14294 ins_encode %{
14295 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant);
14296 %}
14297 ins_pipe(pipe_class_default);
14298 %}
14299
14300 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{
14301 effect(DEF dst, USE src1, USE src2, USE zero);
14302
14303 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %}
14304 size(4);
14305 ins_encode %{
14306 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant);
14307 %}
14308 ins_pipe(pipe_class_default);
14309 %}
14310
14311 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{
14312 match(Set dst (ReplicateL src));
14313 predicate(n->as_Vector()->length() == 2);
14314 expand %{
14315 vecX tmpV;
14316 immI8 zero %{ (int) 0 %}
14317 mtvsrd(tmpV, src);
14318 xxpermdi(dst, tmpV, tmpV, zero);
14319 %}
14320 %}
14321
14322 instruct repl2L_immI0(vecX dst, immI_0 zero) %{
14323 match(Set dst (ReplicateL zero));
14324 predicate(n->as_Vector()->length() == 2);
14325
14326 format %{ "XXLXOR $dst, $zero \t// replicate2L" %}
14327 size(4);
14328 ins_encode %{
14329 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
14330 %}
14331 ins_pipe(pipe_class_default);
14332 %}
14333
14334 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{
14335 match(Set dst (ReplicateL src));
14336 predicate(n->as_Vector()->length() == 2);
14337
14338 format %{ "XXLEQV $dst, $src \t// replicate2L" %}
14339 size(4);
14340 ins_encode %{
14341 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
14342 %}
14343 ins_pipe(pipe_class_default);
14344 %}
14345
14346 // ============================================================================
14347 // Safepoint Instruction
14348
14349 instruct safePoint_poll(iRegPdst poll) %{
14350 match(SafePoint poll);
14351
14352 // It caused problems to add the effect that r0 is killed, but this
14353 // effect no longer needs to be mentioned, since r0 is not contained
14354 // in a reg_class.
14355
14356 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
14357 size(4);
14358 ins_encode( enc_poll(0x0, poll) );
14359 ins_pipe(pipe_class_default);
14360 %}
14361
14362 // ============================================================================
14363 // Call Instructions
14364
14365 // Call Java Static Instruction
14366
14367 // Schedulable version of call static node.
14368 instruct CallStaticJavaDirect(method meth) %{
14369 match(CallStaticJava);
14370 effect(USE meth);
14371 ins_cost(CALL_COST);
14372
14373 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
14374
14375 format %{ "CALL,static $meth \t// ==> " %}
14376 size(4);
14377 ins_encode( enc_java_static_call(meth) );
14378 ins_pipe(pipe_class_call);
14379 %}
14380
14381 // Call Java Dynamic Instruction
14382
14383 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call).
14384 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable
14385 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node.
14386 // The call destination must still be placed in the constant pool.
14387 instruct CallDynamicJavaDirectSched(method meth) %{
14388 match(CallDynamicJava); // To get all the data fields we need ...
14389 effect(USE meth);
14390 predicate(false); // ... but never match.
14391
14392 ins_field_load_ic_hi_node(loadConL_hiNode*);
14393 ins_field_load_ic_node(loadConLNode*);
14394 ins_num_consts(1 /* 1 patchable constant: call destination */);
14395
14396 format %{ "BL \t// dynamic $meth ==> " %}
14397 size(4);
14398 ins_encode( enc_java_dynamic_call_sched(meth) );
14399 ins_pipe(pipe_class_call);
14400 %}
14401
14402 // Schedulable (i.e. postalloc expanded) version of call dynamic java.
14403 // We use postalloc expanded calls if we use inline caches
14404 // and do not update method data.
14405 //
14406 // This instruction has two constants: inline cache (IC) and call destination.
14407 // Loading the inline cache will be postalloc expanded, thus leaving a call with
14408 // one constant.
14409 instruct CallDynamicJavaDirectSched_Ex(method meth) %{
14410 match(CallDynamicJava);
14411 effect(USE meth);
14412 predicate(UseInlineCaches);
14413 ins_cost(CALL_COST);
14414
14415 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */);
14416
14417 format %{ "CALL,dynamic $meth \t// postalloc expanded" %}
14418 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) );
14419 %}
14420
14421 // Compound version of call dynamic java
14422 // We use postalloc expanded calls if we use inline caches
14423 // and do not update method data.
14424 instruct CallDynamicJavaDirect(method meth) %{
14425 match(CallDynamicJava);
14426 effect(USE meth);
14427 predicate(!UseInlineCaches);
14428 ins_cost(CALL_COST);
14429
14430 // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
14431 ins_num_consts(4);
14432
14433 format %{ "CALL,dynamic $meth \t// ==> " %}
14434 ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
14435 ins_pipe(pipe_class_call);
14436 %}
14437
14438 // Call Runtime Instruction
14439
14440 instruct CallRuntimeDirect(method meth) %{
14441 match(CallRuntime);
14442 effect(USE meth);
14443 ins_cost(CALL_COST);
14444
14445 // Enc_java_to_runtime_call needs up to 3 constants: call target,
14446 // env for callee, C-toc.
14447 ins_num_consts(3);
14448
14449 format %{ "CALL,runtime" %}
14450 ins_encode( enc_java_to_runtime_call(meth) );
14451 ins_pipe(pipe_class_call);
14452 %}
14453
14454 // Call Leaf
14455
14456 // Used by postalloc expand of CallLeafDirect_Ex (mtctr).
14457 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
14458 effect(DEF dst, USE src);
14459
14460 ins_num_consts(1);
14461
14462 format %{ "MTCTR $src" %}
14463 size(4);
14464 ins_encode( enc_leaf_call_mtctr(src) );
14465 ins_pipe(pipe_class_default);
14466 %}
14467
14468 // Used by postalloc expand of CallLeafDirect_Ex (actual call).
14469 instruct CallLeafDirect(method meth) %{
14470 match(CallLeaf); // To get the data all the data fields we need ...
14471 effect(USE meth);
14472 predicate(false); // but never match.
14473
14474 format %{ "BCTRL \t// leaf call $meth ==> " %}
14475 size(4);
14476 ins_encode %{
14477 __ bctrl();
14478 %}
14479 ins_pipe(pipe_class_call);
14480 %}
14481
14482 // postalloc expand of CallLeafDirect.
14483 // Load adress to call from TOC, then bl to it.
14484 instruct CallLeafDirect_Ex(method meth) %{
14485 match(CallLeaf);
14486 effect(USE meth);
14487 ins_cost(CALL_COST);
14488
14489 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
14490 // env for callee, C-toc.
14491 ins_num_consts(3);
14492
14493 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
14494 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
14495 %}
14496
14497 // Call runtime without safepoint - same as CallLeaf.
14498 // postalloc expand of CallLeafNoFPDirect.
14499 // Load adress to call from TOC, then bl to it.
14500 instruct CallLeafNoFPDirect_Ex(method meth) %{
14501 match(CallLeafNoFP);
14502 effect(USE meth);
14503 ins_cost(CALL_COST);
14504
14505 // Enc_java_to_runtime_call needs up to 3 constants: call target,
14506 // env for callee, C-toc.
14507 ins_num_consts(3);
14508
14509 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
14510 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
14511 %}
14512
14513 // Tail Call; Jump from runtime stub to Java code.
14514 // Also known as an 'interprocedural jump'.
14515 // Target of jump will eventually return to caller.
14516 // TailJump below removes the return address.
14517 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{
14518 match(TailCall jump_target method_ptr);
14519 ins_cost(CALL_COST);
14520
14521 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t"
14522 "BCTR \t// tail call" %}
14523 size(8);
14524 ins_encode %{
14525 __ mtctr($jump_target$$Register);
14526 __ bctr();
14527 %}
14528 ins_pipe(pipe_class_call);
14529 %}
14530
14531 // Return Instruction
14532 instruct Ret() %{
14533 match(Return);
14534 format %{ "BLR \t// branch to link register" %}
14535 size(4);
14536 ins_encode %{
14537 // LR is restored in MachEpilogNode. Just do the RET here.
14538 __ blr();
14539 %}
14540 ins_pipe(pipe_class_default);
14541 %}
14542
14543 // Tail Jump; remove the return address; jump to target.
14544 // TailCall above leaves the return address around.
14545 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
14546 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
14547 // "restore" before this instruction (in Epilogue), we need to materialize it
14548 // in %i0.
14549 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
14550 match(TailJump jump_target ex_oop);
14551 ins_cost(CALL_COST);
14552
14553 format %{ "LD R4_ARG2 = LR\n\t"
14554 "MTCTR $jump_target\n\t"
14555 "BCTR \t// TailJump, exception oop: $ex_oop" %}
14556 size(12);
14557 ins_encode %{
14558 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP);
14559 __ mtctr($jump_target$$Register);
14560 __ bctr();
14561 %}
14562 ins_pipe(pipe_class_call);
14563 %}
14564
14565 // Create exception oop: created by stack-crawling runtime code.
14566 // Created exception is now available to this handler, and is setup
14567 // just prior to jumping to this handler. No code emitted.
14568 instruct CreateException(rarg1RegP ex_oop) %{
14569 match(Set ex_oop (CreateEx));
14570 ins_cost(0);
14571
14572 format %{ " -- \t// exception oop; no code emitted" %}
14573 size(0);
14574 ins_encode( /*empty*/ );
14575 ins_pipe(pipe_class_default);
14576 %}
14577
14578 // Rethrow exception: The exception oop will come in the first
14579 // argument position. Then JUMP (not call) to the rethrow stub code.
14580 instruct RethrowException() %{
14581 match(Rethrow);
14582 ins_cost(CALL_COST);
14583
14584 format %{ "Jmp rethrow_stub" %}
14585 ins_encode %{
14586 cbuf.set_insts_mark();
14587 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
14588 %}
14589 ins_pipe(pipe_class_call);
14590 %}
14591
14592 // Die now.
14593 instruct ShouldNotReachHere() %{
14594 match(Halt);
14595 ins_cost(CALL_COST);
14596
14597 format %{ "ShouldNotReachHere" %}
14598 ins_encode %{
14599 if (is_reachable()) {
14600 __ stop(_halt_reason);
14601 }
14602 %}
14603 ins_pipe(pipe_class_default);
14604 %}
14605
14606 // This name is KNOWN by the ADLC and cannot be changed. The ADLC
14607 // forces a 'TypeRawPtr::BOTTOM' output type for this guy.
14608 // Get a DEF on threadRegP, no costs, no encoding, use
14609 // 'ins_should_rematerialize(true)' to avoid spilling.
14610 instruct tlsLoadP(threadRegP dst) %{
14611 match(Set dst (ThreadLocal));
14612 ins_cost(0);
14613
14614 ins_should_rematerialize(true);
14615
14616 format %{ " -- \t// $dst=Thread::current(), empty" %}
14617 size(0);
14618 ins_encode( /*empty*/ );
14619 ins_pipe(pipe_class_empty);
14620 %}
14621
14622 //---Some PPC specific nodes---------------------------------------------------
14623
14624 // Stop a group.
14625 instruct endGroup() %{
14626 ins_cost(0);
14627
14628 ins_is_nop(true);
14629
14630 format %{ "End Bundle (ori r1, r1, 0)" %}
14631 size(4);
14632 ins_encode %{
14633 __ endgroup();
14634 %}
14635 ins_pipe(pipe_class_default);
14636 %}
14637
14638 // Nop instructions
14639
14640 instruct fxNop() %{
14641 ins_cost(0);
14642
14643 ins_is_nop(true);
14644
14645 format %{ "fxNop" %}
14646 size(4);
14647 ins_encode %{
14648 __ nop();
14649 %}
14650 ins_pipe(pipe_class_default);
14651 %}
14652
14653 instruct fpNop0() %{
14654 ins_cost(0);
14655
14656 ins_is_nop(true);
14657
14658 format %{ "fpNop0" %}
14659 size(4);
14660 ins_encode %{
14661 __ fpnop0();
14662 %}
14663 ins_pipe(pipe_class_default);
14664 %}
14665
14666 instruct fpNop1() %{
14667 ins_cost(0);
14668
14669 ins_is_nop(true);
14670
14671 format %{ "fpNop1" %}
14672 size(4);
14673 ins_encode %{
14674 __ fpnop1();
14675 %}
14676 ins_pipe(pipe_class_default);
14677 %}
14678
14679 instruct brNop0() %{
14680 ins_cost(0);
14681 size(4);
14682 format %{ "brNop0" %}
14683 ins_encode %{
14684 __ brnop0();
14685 %}
14686 ins_is_nop(true);
14687 ins_pipe(pipe_class_default);
14688 %}
14689
14690 instruct brNop1() %{
14691 ins_cost(0);
14692
14693 ins_is_nop(true);
14694
14695 format %{ "brNop1" %}
14696 size(4);
14697 ins_encode %{
14698 __ brnop1();
14699 %}
14700 ins_pipe(pipe_class_default);
14701 %}
14702
14703 instruct brNop2() %{
14704 ins_cost(0);
14705
14706 ins_is_nop(true);
14707
14708 format %{ "brNop2" %}
14709 size(4);
14710 ins_encode %{
14711 __ brnop2();
14712 %}
14713 ins_pipe(pipe_class_default);
14714 %}
14715
14716 instruct cacheWB(indirect addr)
14717 %{
14718 match(CacheWB addr);
14719
14720 ins_cost(100);
14721 format %{ "cache writeback, address = $addr" %}
14722 ins_encode %{
14723 assert($addr->index_position() < 0, "should be");
14724 assert($addr$$disp == 0, "should be");
14725 __ cache_wb(Address($addr$$base$$Register));
14726 %}
14727 ins_pipe(pipe_class_default);
14728 %}
14729
14730 instruct cacheWBPreSync()
14731 %{
14732 match(CacheWBPreSync);
14733
14734 ins_cost(0);
14735 format %{ "cache writeback presync" %}
14736 ins_encode %{
14737 __ cache_wbsync(true);
14738 %}
14739 ins_pipe(pipe_class_default);
14740 %}
14741
14742 instruct cacheWBPostSync()
14743 %{
14744 match(CacheWBPostSync);
14745
14746 ins_cost(100);
14747 format %{ "cache writeback postsync" %}
14748 ins_encode %{
14749 __ cache_wbsync(false);
14750 %}
14751 ins_pipe(pipe_class_default);
14752 %}
14753
14754 //----------PEEPHOLE RULES-----------------------------------------------------
14755 // These must follow all instruction definitions as they use the names
14756 // defined in the instructions definitions.
14757 //
14758 // peepmatch ( root_instr_name [preceeding_instruction]* );
14759 //
14760 // peepconstraint %{
14761 // (instruction_number.operand_name relational_op instruction_number.operand_name
14762 // [, ...] );
14763 // // instruction numbers are zero-based using left to right order in peepmatch
14764 //
14765 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14766 // // provide an instruction_number.operand_name for each operand that appears
14767 // // in the replacement instruction's match rule
14768 //
14769 // ---------VM FLAGS---------------------------------------------------------
14770 //
14771 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14772 //
14773 // Each peephole rule is given an identifying number starting with zero and
14774 // increasing by one in the order seen by the parser. An individual peephole
14775 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14776 // on the command-line.
14777 //
14778 // ---------CURRENT LIMITATIONS----------------------------------------------
14779 //
14780 // Only match adjacent instructions in same basic block
14781 // Only equality constraints
14782 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14783 // Only one replacement instruction
14784 //
14785 // ---------EXAMPLE----------------------------------------------------------
14786 //
14787 // // pertinent parts of existing instructions in architecture description
14788 // instruct movI(eRegI dst, eRegI src) %{
14789 // match(Set dst (CopyI src));
14790 // %}
14791 //
14792 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14793 // match(Set dst (AddI dst src));
14794 // effect(KILL cr);
14795 // %}
14796 //
14797 // // Change (inc mov) to lea
14798 // peephole %{
14799 // // increment preceeded by register-register move
14800 // peepmatch ( incI_eReg movI );
14801 // // require that the destination register of the increment
14802 // // match the destination register of the move
14803 // peepconstraint ( 0.dst == 1.dst );
14804 // // construct a replacement instruction that sets
14805 // // the destination to ( move's source register + one )
14806 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14807 // %}
14808 //
14809 // Implementation no longer uses movX instructions since
14810 // machine-independent system no longer uses CopyX nodes.
14811 //
14812 // peephole %{
14813 // peepmatch ( incI_eReg movI );
14814 // peepconstraint ( 0.dst == 1.dst );
14815 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14816 // %}
14817 //
14818 // peephole %{
14819 // peepmatch ( decI_eReg movI );
14820 // peepconstraint ( 0.dst == 1.dst );
14821 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14822 // %}
14823 //
14824 // peephole %{
14825 // peepmatch ( addI_eReg_imm movI );
14826 // peepconstraint ( 0.dst == 1.dst );
14827 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14828 // %}
14829 //
14830 // peephole %{
14831 // peepmatch ( addP_eReg_imm movP );
14832 // peepconstraint ( 0.dst == 1.dst );
14833 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
14834 // %}
14835
14836 // // Change load of spilled value to only a spill
14837 // instruct storeI(memory mem, eRegI src) %{
14838 // match(Set mem (StoreI mem src));
14839 // %}
14840 //
14841 // instruct loadI(eRegI dst, memory mem) %{
14842 // match(Set dst (LoadI mem));
14843 // %}
14844 //
14845 peephole %{
14846 peepmatch ( loadI storeI );
14847 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14848 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14849 %}
14850
14851 peephole %{
14852 peepmatch ( loadL storeL );
14853 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14854 peepreplace ( storeL( 1.mem 1.mem 1.src ) );
14855 %}
14856
14857 peephole %{
14858 peepmatch ( loadP storeP );
14859 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
14860 peepreplace ( storeP( 1.dst 1.dst 1.src ) );
14861 %}
14862
14863 //----------SMARTSPILL RULES---------------------------------------------------
14864 // These must follow all instruction definitions as they use the names
14865 // defined in the instructions definitions.