1 //
2 // Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
3 // Copyright (c) 2012, 2023 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 //=============================================================================
1132
1133 // condition code conversions
1134
1135 static int cc_to_boint(int cc) {
1136 return Assembler::bcondCRbiIs0 | (cc & 8);
1137 }
1138
1139 static int cc_to_inverse_boint(int cc) {
1140 return Assembler::bcondCRbiIs0 | (8-(cc & 8));
1141 }
1142
1143 static int cc_to_biint(int cc, int flags_reg) {
1144 return (flags_reg << 2) | (cc & 3);
1145 }
1146
1147 //=============================================================================
1148
1149 // Compute padding required for nodes which need alignment. The padding
1150 // is the number of bytes (not instructions) which will be inserted before
1151 // the instruction. The padding must match the size of a NOP instruction.
1152
1153 // Add nop if a prefixed (two-word) instruction is going to cross a 64-byte boundary.
1154 // (See Section 1.6 of Power ISA Version 3.1)
1155 static int compute_prefix_padding(int current_offset) {
1156 assert(PowerArchitecturePPC64 >= 10 && (CodeEntryAlignment & 63) == 0,
1157 "Code buffer must be aligned to a multiple of 64 bytes");
1158 if (is_aligned(current_offset + BytesPerInstWord, 64)) {
1159 return BytesPerInstWord;
1160 }
1161 return 0;
1162 }
1163
1164 int loadConI32Node::compute_padding(int current_offset) const {
1165 return compute_prefix_padding(current_offset);
1166 }
1167
1168 int loadConL34Node::compute_padding(int current_offset) const {
1169 return compute_prefix_padding(current_offset);
1170 }
1171
1172 int addI_reg_imm32Node::compute_padding(int current_offset) const {
1173 return compute_prefix_padding(current_offset);
1174 }
1175
1176 int addL_reg_imm34Node::compute_padding(int current_offset) const {
1177 return compute_prefix_padding(current_offset);
1178 }
1179
1180 int addP_reg_imm34Node::compute_padding(int current_offset) const {
1181 return compute_prefix_padding(current_offset);
1182 }
1183
1184 int cmprb_Whitespace_reg_reg_prefixedNode::compute_padding(int current_offset) const {
1185 return compute_prefix_padding(current_offset);
1186 }
1187
1188
1189 //=============================================================================
1190
1191 // Emit an interrupt that is caught by the debugger (for debugging compiler).
1192 void emit_break(CodeBuffer &cbuf) {
1193 C2_MacroAssembler _masm(&cbuf);
1194 __ illtrap();
1195 }
1196
1197 #ifndef PRODUCT
1198 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1199 st->print("BREAKPOINT");
1200 }
1201 #endif
1202
1203 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1204 emit_break(cbuf);
1205 }
1206
1207 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1208 return MachNode::size(ra_);
1209 }
1210
1211 //=============================================================================
1212
1213 void emit_nop(CodeBuffer &cbuf) {
1214 C2_MacroAssembler _masm(&cbuf);
1215 __ nop();
1216 }
1217
1218 static inline void emit_long(CodeBuffer &cbuf, int value) {
1219 *((int*)(cbuf.insts_end())) = value;
1220 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord);
1221 }
1222
1223 //=============================================================================
1224
1225 %} // interrupt source
1226
1227 source_hpp %{ // Header information of the source block.
1228
1229 //--------------------------------------------------------------
1230 //---< Used for optimization in Compile::Shorten_branches >---
1231 //--------------------------------------------------------------
1232
1233 class C2_MacroAssembler;
1234
1235 class CallStubImpl {
1236
1237 public:
1238
1239 // Emit call stub, compiled java to interpreter.
1240 static void emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset);
1241
1242 // Size of call trampoline stub.
1243 // This doesn't need to be accurate to the byte, but it
1244 // must be larger than or equal to the real size of the stub.
1245 static uint size_call_trampoline() {
1246 return MacroAssembler::trampoline_stub_size;
1247 }
1248
1249 // number of relocations needed by a call trampoline stub
1250 static uint reloc_call_trampoline() {
1251 return 5;
1252 }
1253
1254 };
1255
1256 %} // end source_hpp
1257
1258 source %{
1259
1260 // Emit a trampoline stub for a call to a target which is too far away.
1261 //
1262 // code sequences:
1263 //
1264 // call-site:
1265 // branch-and-link to <destination> or <trampoline stub>
1266 //
1267 // Related trampoline stub for this call-site in the stub section:
1268 // load the call target from the constant pool
1269 // branch via CTR (LR/link still points to the call-site above)
1270
1271 void CallStubImpl::emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) {
1272 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset);
1273 if (stub == NULL) {
1274 ciEnv::current()->record_out_of_memory_failure();
1275 }
1276 }
1277
1278 //=============================================================================
1279
1280 // Emit an inline branch-and-link call and a related trampoline stub.
1281 //
1282 // code sequences:
1283 //
1284 // call-site:
1285 // branch-and-link to <destination> or <trampoline stub>
1286 //
1287 // Related trampoline stub for this call-site in the stub section:
1288 // load the call target from the constant pool
1289 // branch via CTR (LR/link still points to the call-site above)
1290 //
1291
1292 typedef struct {
1293 int insts_call_instruction_offset;
1294 int ret_addr_offset;
1295 } EmitCallOffsets;
1296
1297 // Emit a branch-and-link instruction that branches to a trampoline.
1298 // - Remember the offset of the branch-and-link instruction.
1299 // - Add a relocation at the branch-and-link instruction.
1300 // - Emit a branch-and-link.
1301 // - Remember the return pc offset.
1302 EmitCallOffsets emit_call_with_trampoline_stub(C2_MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) {
1303 EmitCallOffsets offsets = { -1, -1 };
1304 const int start_offset = __ offset();
1305 offsets.insts_call_instruction_offset = __ offset();
1306
1307 // No entry point given, use the current pc.
1308 if (entry_point == NULL) entry_point = __ pc();
1309
1310 // Put the entry point as a constant into the constant pool.
1311 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
1312 if (entry_point_toc_addr == NULL) {
1313 ciEnv::current()->record_out_of_memory_failure();
1314 return offsets;
1315 }
1316 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
1317
1318 // Emit the trampoline stub which will be related to the branch-and-link below.
1319 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
1320 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
1321 __ relocate(rtype);
1322
1323 // Note: At this point we do not have the address of the trampoline
1324 // stub, and the entry point might be too far away for bl, so __ pc()
1325 // serves as dummy and the bl will be patched later.
1326 __ bl((address) __ pc());
1327
1328 offsets.ret_addr_offset = __ offset() - start_offset;
1329
1330 return offsets;
1331 }
1332
1333 //=============================================================================
1334
1335 // Factory for creating loadConL* nodes for large/small constant pool.
1336
1337 static inline jlong replicate_immF(float con) {
1338 // Replicate float con 2 times and pack into vector.
1339 int val = *((int*)&con);
1340 jlong lval = val;
1341 lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1342 return lval;
1343 }
1344
1345 //=============================================================================
1346
1347 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1348 int ConstantTable::calculate_table_base_offset() const {
1349 return 0; // absolute addressing, no offset
1350 }
1351
1352 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1353 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1354 iRegPdstOper *op_dst = new iRegPdstOper();
1355 MachNode *m1 = new loadToc_hiNode();
1356 MachNode *m2 = new loadToc_loNode();
1357
1358 m1->add_req(NULL);
1359 m2->add_req(NULL, m1);
1360 m1->_opnds[0] = op_dst;
1361 m2->_opnds[0] = op_dst;
1362 m2->_opnds[1] = op_dst;
1363 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1364 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1365 nodes->push(m1);
1366 nodes->push(m2);
1367 }
1368
1369 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1370 // Is postalloc expanded.
1371 ShouldNotReachHere();
1372 }
1373
1374 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1375 return 0;
1376 }
1377
1378 #ifndef PRODUCT
1379 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1380 st->print("-- \t// MachConstantBaseNode (empty encoding)");
1381 }
1382 #endif
1383
1384 //=============================================================================
1385
1386 #ifndef PRODUCT
1387 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1388 Compile* C = ra_->C;
1389 const long framesize = C->output()->frame_slots() << LogBytesPerInt;
1390
1391 st->print("PROLOG\n\t");
1392 if (C->output()->need_stack_bang(framesize)) {
1393 st->print("stack_overflow_check\n\t");
1394 }
1395
1396 if (!false /* TODO: PPC port C->is_frameless_method()*/) {
1397 st->print("save return pc\n\t");
1398 st->print("push frame %ld\n\t", -framesize);
1399 }
1400
1401 if (C->stub_function() == NULL) {
1402 st->print("nmethod entry barrier\n\t");
1403 }
1404 }
1405 #endif
1406
1407 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1408 Compile* C = ra_->C;
1409 C2_MacroAssembler _masm(&cbuf);
1410
1411 const long framesize = C->output()->frame_size_in_bytes();
1412 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment");
1413
1414 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1415
1416 const Register return_pc = R20; // Must match return_addr() in frame section.
1417 const Register callers_sp = R21;
1418 const Register push_frame_temp = R22;
1419 const Register toc_temp = R23;
1420 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp);
1421
1422 if (method_is_frameless) {
1423 // Add nop at beginning of all frameless methods to prevent any
1424 // oop instructions from getting overwritten by make_not_entrant
1425 // (patching attempt would fail).
1426 __ nop();
1427 } else {
1428 // Get return pc.
1429 __ mflr(return_pc);
1430 }
1431
1432 if (C->clinit_barrier_on_entry()) {
1433 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
1434
1435 Label L_skip_barrier;
1436 Register klass = toc_temp;
1437
1438 // Notify OOP recorder (don't need the relocation)
1439 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding());
1440 __ load_const_optimized(klass, md.value(), R0);
1441 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/);
1442
1443 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0);
1444 __ mtctr(klass);
1445 __ bctr();
1446
1447 __ bind(L_skip_barrier);
1448 }
1449
1450 // Calls to C2R adapters often do not accept exceptional returns.
1451 // We require that their callers must bang for them. But be
1452 // careful, because some VM calls (such as call site linkage) can
1453 // use several kilobytes of stack. But the stack safety zone should
1454 // account for that. See bugs 4446381, 4468289, 4497237.
1455
1456 int bangsize = C->output()->bang_size_in_bytes();
1457 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect");
1458 if (C->output()->need_stack_bang(bangsize)) {
1459 // Unfortunately we cannot use the function provided in
1460 // assembler.cpp as we have to emulate the pipes. So I had to
1461 // insert the code of generate_stack_overflow_check(), see
1462 // assembler.cpp for some illuminative comments.
1463 const int page_size = os::vm_page_size();
1464 int bang_end = StackOverflow::stack_shadow_zone_size();
1465
1466 // This is how far the previous frame's stack banging extended.
1467 const int bang_end_safe = bang_end;
1468
1469 if (bangsize > page_size) {
1470 bang_end += bangsize;
1471 }
1472
1473 int bang_offset = bang_end_safe;
1474
1475 while (bang_offset <= bang_end) {
1476 // Need at least one stack bang at end of shadow zone.
1477
1478 // Again I had to copy code, this time from assembler_ppc.cpp,
1479 // bang_stack_with_offset - see there for comments.
1480
1481 // Stack grows down, caller passes positive offset.
1482 assert(bang_offset > 0, "must bang with positive offset");
1483
1484 long stdoffset = -bang_offset;
1485
1486 if (Assembler::is_simm(stdoffset, 16)) {
1487 // Signed 16 bit offset, a simple std is ok.
1488 if (UseLoadInstructionsForStackBangingPPC64) {
1489 __ ld(R0, (int)(signed short)stdoffset, R1_SP);
1490 } else {
1491 __ std(R0, (int)(signed short)stdoffset, R1_SP);
1492 }
1493 } else if (Assembler::is_simm(stdoffset, 31)) {
1494 // Use largeoffset calculations for addis & ld/std.
1495 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset);
1496 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset);
1497
1498 Register tmp = R11;
1499 __ addis(tmp, R1_SP, hi);
1500 if (UseLoadInstructionsForStackBangingPPC64) {
1501 __ ld(R0, lo, tmp);
1502 } else {
1503 __ std(R0, lo, tmp);
1504 }
1505 } else {
1506 ShouldNotReachHere();
1507 }
1508
1509 bang_offset += page_size;
1510 }
1511 // R11 trashed
1512 } // C->output()->need_stack_bang(framesize)
1513
1514 unsigned int bytes = (unsigned int)framesize;
1515 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
1516 ciMethod *currMethod = C->method();
1517
1518 if (!method_is_frameless) {
1519 // Get callers sp.
1520 __ mr(callers_sp, R1_SP);
1521
1522 // Push method's frame, modifies SP.
1523 assert(Assembler::is_uimm(framesize, 32U), "wrong type");
1524 // The ABI is already accounted for in 'framesize' via the
1525 // 'out_preserve' area.
1526 Register tmp = push_frame_temp;
1527 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp).
1528 if (Assembler::is_simm(-offset, 16)) {
1529 __ stdu(R1_SP, -offset, R1_SP);
1530 } else {
1531 long x = -offset;
1532 // Had to insert load_const(tmp, -offset).
1533 __ lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16)));
1534 __ ori( tmp, tmp, ((x >> 32) & 0x0000ffff));
1535 __ sldi(tmp, tmp, 32);
1536 __ oris(tmp, tmp, (x & 0xffff0000) >> 16);
1537 __ ori( tmp, tmp, (x & 0x0000ffff));
1538
1539 __ stdux(R1_SP, R1_SP, tmp);
1540 }
1541 }
1542 #if 0 // TODO: PPC port
1543 // For testing large constant pools, emit a lot of constants to constant pool.
1544 // "Randomize" const_size.
1545 if (ConstantsALot) {
1546 const int num_consts = const_size();
1547 for (int i = 0; i < num_consts; i++) {
1548 __ long_constant(0xB0B5B00BBABE);
1549 }
1550 }
1551 #endif
1552 if (!method_is_frameless) {
1553 // Save return pc.
1554 __ std(return_pc, _abi0(lr), callers_sp);
1555 }
1556
1557 if (C->stub_function() == NULL) {
1558 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
1559 bs->nmethod_entry_barrier(&_masm, push_frame_temp);
1560 }
1561
1562 C->output()->set_frame_complete(cbuf.insts_size());
1563 }
1564
1565 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1566 // Variable size. determine dynamically.
1567 return MachNode::size(ra_);
1568 }
1569
1570 int MachPrologNode::reloc() const {
1571 // Return number of relocatable values contained in this instruction.
1572 return 1; // 1 reloc entry for load_const(toc).
1573 }
1574
1575 //=============================================================================
1576
1577 #ifndef PRODUCT
1578 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1579 Compile* C = ra_->C;
1580
1581 st->print("EPILOG\n\t");
1582 st->print("restore return pc\n\t");
1583 st->print("pop frame\n\t");
1584
1585 if (do_polling() && C->is_method_compilation()) {
1586 st->print("safepoint poll\n\t");
1587 }
1588 }
1589 #endif
1590
1591 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1592 Compile* C = ra_->C;
1593 C2_MacroAssembler _masm(&cbuf);
1594
1595 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt;
1596 assert(framesize >= 0, "negative frame-size?");
1597
1598 const bool method_needs_polling = do_polling() && C->is_method_compilation();
1599 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/;
1600 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone().
1601 const Register temp = R12;
1602
1603 if (!method_is_frameless) {
1604 // Restore return pc relative to callers' sp.
1605 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP);
1606 // Move return pc to LR.
1607 __ mtlr(return_pc);
1608 // Pop frame (fixed frame-size).
1609 __ addi(R1_SP, R1_SP, (int)framesize);
1610 }
1611
1612 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1613 __ reserved_stack_check(return_pc);
1614 }
1615
1616 if (method_needs_polling) {
1617 Label dummy_label;
1618 Label* code_stub = &dummy_label;
1619 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) {
1620 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1621 C->output()->add_stub(stub);
1622 code_stub = &stub->entry();
1623 __ relocate(relocInfo::poll_return_type);
1624 }
1625 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */);
1626 }
1627 }
1628
1629 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1630 // Variable size. Determine dynamically.
1631 return MachNode::size(ra_);
1632 }
1633
1634 int MachEpilogNode::reloc() const {
1635 // Return number of relocatable values contained in this instruction.
1636 return 1; // 1 for load_from_polling_page.
1637 }
1638
1639 const Pipeline * MachEpilogNode::pipeline() const {
1640 return MachNode::pipeline_class();
1641 }
1642
1643 // =============================================================================
1644
1645 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or
1646 // rc_stack.
1647 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack };
1648
1649 static enum RC rc_class(OptoReg::Name reg) {
1650 // Return the register class for the given register. The given register
1651 // reg is a <register>_num value, which is an index into the MachRegisterNumbers
1652 // enumeration in adGlobals_ppc.hpp.
1653
1654 if (reg == OptoReg::Bad) return rc_bad;
1655
1656 // We have 64 integer register halves, starting at index 0.
1657 if (reg < 64) return rc_int;
1658
1659 // We have 64 floating-point register halves, starting at index 64.
1660 if (reg < 64+64) return rc_float;
1661
1662 // We have 64 vector-scalar registers, starting at index 128.
1663 if (reg < 64+64+64) return rc_vs;
1664
1665 // Between float regs & stack are the flags regs.
1666 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags");
1667
1668 return rc_stack;
1669 }
1670
1671 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset,
1672 bool do_print, Compile* C, outputStream *st) {
1673
1674 assert(opcode == Assembler::LD_OPCODE ||
1675 opcode == Assembler::STD_OPCODE ||
1676 opcode == Assembler::LWZ_OPCODE ||
1677 opcode == Assembler::STW_OPCODE ||
1678 opcode == Assembler::LFD_OPCODE ||
1679 opcode == Assembler::STFD_OPCODE ||
1680 opcode == Assembler::LFS_OPCODE ||
1681 opcode == Assembler::STFS_OPCODE,
1682 "opcode not supported");
1683
1684 if (cbuf) {
1685 int d =
1686 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ?
1687 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/)
1688 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build.
1689 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP));
1690 }
1691 #ifndef PRODUCT
1692 else if (do_print) {
1693 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy",
1694 op_str,
1695 Matcher::regName[reg],
1696 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/);
1697 }
1698 #endif
1699 return 4; // size
1700 }
1701
1702 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1703 Compile* C = ra_->C;
1704
1705 // Get registers to move.
1706 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1707 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1708 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1709 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1710
1711 enum RC src_hi_rc = rc_class(src_hi);
1712 enum RC src_lo_rc = rc_class(src_lo);
1713 enum RC dst_hi_rc = rc_class(dst_hi);
1714 enum RC dst_lo_rc = rc_class(dst_lo);
1715
1716 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1717 if (src_hi != OptoReg::Bad)
1718 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1719 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1720 "expected aligned-adjacent pairs");
1721 // Generate spill code!
1722 int size = 0;
1723
1724 if (src_lo == dst_lo && src_hi == dst_hi)
1725 return size; // Self copy, no move.
1726
1727 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) {
1728 // Memory->Memory Spill.
1729 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1730 int src_offset = ra_->reg2offset(src_lo);
1731 int dst_offset = ra_->reg2offset(dst_lo);
1732 if (cbuf) {
1733 C2_MacroAssembler _masm(cbuf);
1734 __ ld(R0, src_offset, R1_SP);
1735 __ std(R0, dst_offset, R1_SP);
1736 __ ld(R0, src_offset+8, R1_SP);
1737 __ std(R0, dst_offset+8, R1_SP);
1738 }
1739 size += 16;
1740 }
1741 // VectorSRegister->Memory Spill.
1742 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) {
1743 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]);
1744 int dst_offset = ra_->reg2offset(dst_lo);
1745 if (cbuf) {
1746 C2_MacroAssembler _masm(cbuf);
1747 __ addi(R0, R1_SP, dst_offset);
1748 __ stxvd2x(Rsrc, R0);
1749 }
1750 size += 8;
1751 }
1752 // Memory->VectorSRegister Spill.
1753 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) {
1754 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]);
1755 int src_offset = ra_->reg2offset(src_lo);
1756 if (cbuf) {
1757 C2_MacroAssembler _masm(cbuf);
1758 __ addi(R0, R1_SP, src_offset);
1759 __ lxvd2x(Rdst, R0);
1760 }
1761 size += 8;
1762 }
1763 // VectorSRegister->VectorSRegister.
1764 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) {
1765 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]);
1766 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]);
1767 if (cbuf) {
1768 C2_MacroAssembler _masm(cbuf);
1769 __ xxlor(Rdst, Rsrc, Rsrc);
1770 }
1771 size += 4;
1772 }
1773 else {
1774 ShouldNotReachHere(); // No VSR spill.
1775 }
1776 return size;
1777 }
1778
1779 // --------------------------------------
1780 // Memory->Memory Spill. Use R0 to hold the value.
1781 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1782 int src_offset = ra_->reg2offset(src_lo);
1783 int dst_offset = ra_->reg2offset(dst_lo);
1784 if (src_hi != OptoReg::Bad) {
1785 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack,
1786 "expected same type of move for high parts");
1787 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st);
1788 if (!cbuf && !do_size) st->print("\n\t");
1789 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st);
1790 } else {
1791 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st);
1792 if (!cbuf && !do_size) st->print("\n\t");
1793 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st);
1794 }
1795 return size;
1796 }
1797
1798 // --------------------------------------
1799 // Check for float->int copy; requires a trip through memory.
1800 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1801 Unimplemented();
1802 }
1803
1804 // --------------------------------------
1805 // Check for integer reg-reg copy.
1806 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1807 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1808 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1809 size = (Rsrc != Rdst) ? 4 : 0;
1810
1811 if (cbuf) {
1812 C2_MacroAssembler _masm(cbuf);
1813 if (size) {
1814 __ mr(Rdst, Rsrc);
1815 }
1816 }
1817 #ifndef PRODUCT
1818 else if (!do_size) {
1819 if (size) {
1820 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1821 } else {
1822 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1823 }
1824 }
1825 #endif
1826 return size;
1827 }
1828
1829 // Check for integer store.
1830 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1831 int dst_offset = ra_->reg2offset(dst_lo);
1832 if (src_hi != OptoReg::Bad) {
1833 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack,
1834 "expected same type of move for high parts");
1835 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1836 } else {
1837 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st);
1838 }
1839 return size;
1840 }
1841
1842 // Check for integer load.
1843 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1844 int src_offset = ra_->reg2offset(src_lo);
1845 if (src_hi != OptoReg::Bad) {
1846 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack,
1847 "expected same type of move for high parts");
1848 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1849 } else {
1850 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st);
1851 }
1852 return size;
1853 }
1854
1855 // Check for float reg-reg copy.
1856 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1857 if (cbuf) {
1858 C2_MacroAssembler _masm(cbuf);
1859 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]);
1860 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]);
1861 __ fmr(Rdst, Rsrc);
1862 }
1863 #ifndef PRODUCT
1864 else if (!do_size) {
1865 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1866 }
1867 #endif
1868 return 4;
1869 }
1870
1871 // Check for float store.
1872 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1873 int dst_offset = ra_->reg2offset(dst_lo);
1874 if (src_hi != OptoReg::Bad) {
1875 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack,
1876 "expected same type of move for high parts");
1877 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1878 } else {
1879 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st);
1880 }
1881 return size;
1882 }
1883
1884 // Check for float load.
1885 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1886 int src_offset = ra_->reg2offset(src_lo);
1887 if (src_hi != OptoReg::Bad) {
1888 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack,
1889 "expected same type of move for high parts");
1890 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1891 } else {
1892 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st);
1893 }
1894 return size;
1895 }
1896
1897 // --------------------------------------------------------------------
1898 // Check for hi bits still needing moving. Only happens for misaligned
1899 // arguments to native calls.
1900 if (src_hi == dst_hi)
1901 return size; // Self copy; no move.
1902
1903 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad");
1904 ShouldNotReachHere(); // Unimplemented
1905 return 0;
1906 }
1907
1908 #ifndef PRODUCT
1909 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1910 if (!ra_)
1911 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1912 else
1913 implementation(NULL, ra_, false, st);
1914 }
1915 #endif
1916
1917 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1918 implementation(&cbuf, ra_, false, NULL);
1919 }
1920
1921 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1922 return implementation(NULL, ra_, true, NULL);
1923 }
1924
1925 #ifndef PRODUCT
1926 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1927 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count);
1928 }
1929 #endif
1930
1931 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const {
1932 C2_MacroAssembler _masm(&cbuf);
1933 // _count contains the number of nops needed for padding.
1934 for (int i = 0; i < _count; i++) {
1935 __ nop();
1936 }
1937 }
1938
1939 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
1940 return _count * 4;
1941 }
1942
1943 #ifndef PRODUCT
1944 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1945 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1946 char reg_str[128];
1947 ra_->dump_register(this, reg_str, sizeof(reg_str));
1948 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset);
1949 }
1950 #endif
1951
1952 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1953 C2_MacroAssembler _masm(&cbuf);
1954
1955 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1956 int reg = ra_->get_encode(this);
1957
1958 if (Assembler::is_simm(offset, 16)) {
1959 __ addi(as_Register(reg), R1, offset);
1960 } else {
1961 ShouldNotReachHere();
1962 }
1963 }
1964
1965 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1966 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1967 return 4;
1968 }
1969
1970 #ifndef PRODUCT
1971 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1972 st->print_cr("---- MachUEPNode ----");
1973 st->print_cr("...");
1974 }
1975 #endif
1976
1977 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1978 // This is the unverified entry point.
1979 C2_MacroAssembler _masm(&cbuf);
1980
1981 // Inline_cache contains a klass.
1982 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode());
1983 Register receiver_klass = R12_scratch2; // tmp
1984
1985 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1);
1986 assert(R11_scratch1 == R11, "need prologue scratch register");
1987
1988 // Check for NULL argument if we don't have implicit null checks.
1989 if (!ImplicitNullChecks || !os::zero_page_read_protected()) {
1990 if (TrapBasedNullChecks) {
1991 __ trap_null_check(R3_ARG1);
1992 } else {
1993 Label valid;
1994 __ cmpdi(CCR0, R3_ARG1, 0);
1995 __ bne_predict_taken(CCR0, valid);
1996 // We have a null argument, branch to ic_miss_stub.
1997 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(),
1998 relocInfo::runtime_call_type);
1999 __ bind(valid);
2000 }
2001 }
2002 // Assume argument is not NULL, load klass from receiver.
2003 __ load_klass(receiver_klass, R3_ARG1);
2004
2005 if (TrapBasedICMissChecks) {
2006 __ trap_ic_miss_check(receiver_klass, ic_klass);
2007 } else {
2008 Label valid;
2009 __ cmpd(CCR0, receiver_klass, ic_klass);
2010 __ beq_predict_taken(CCR0, valid);
2011 // We have an unexpected klass, branch to ic_miss_stub.
2012 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(),
2013 relocInfo::runtime_call_type);
2014 __ bind(valid);
2015 }
2016
2017 // Argument is valid and klass is as expected, continue.
2018 }
2019
2020 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
2021 // Variable size. Determine dynamically.
2022 return MachNode::size(ra_);
2023 }
2024
2025 //=============================================================================
2026
2027 %} // interrupt source
2028
2029 source_hpp %{ // Header information of the source block.
2030
2031 class HandlerImpl {
2032
2033 public:
2034
2035 static int emit_exception_handler(CodeBuffer &cbuf);
2036 static int emit_deopt_handler(CodeBuffer& cbuf);
2037
2038 static uint size_exception_handler() {
2039 // The exception_handler is a b64_patchable.
2040 return MacroAssembler::b64_patchable_size;
2041 }
2042
2043 static uint size_deopt_handler() {
2044 // The deopt_handler is a bl64_patchable.
2045 return MacroAssembler::bl64_patchable_size;
2046 }
2047
2048 };
2049
2050 class Node::PD {
2051 public:
2052 enum NodeFlags {
2053 _last_flag = Node::_last_flag
2054 };
2055 };
2056
2057 %} // end source_hpp
2058
2059 source %{
2060
2061 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) {
2062 C2_MacroAssembler _masm(&cbuf);
2063
2064 address base = __ start_a_stub(size_exception_handler());
2065 if (base == nullptr) {
2066 ciEnv::current()->record_failure("CodeCache is full");
2067 return 0; // CodeBuffer::expand failed
2068 }
2069
2070 int offset = __ offset();
2071 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(),
2072 relocInfo::runtime_call_type);
2073 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size");
2074 __ end_a_stub();
2075
2076 return offset;
2077 }
2078
2079 // The deopt_handler is like the exception handler, but it calls to
2080 // the deoptimization blob instead of jumping to the exception blob.
2081 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
2082 C2_MacroAssembler _masm(&cbuf);
2083
2084 address base = __ start_a_stub(size_deopt_handler());
2085 if (base == nullptr) {
2086 ciEnv::current()->record_failure("CodeCache is full");
2087 return 0; // CodeBuffer::expand failed
2088 }
2089
2090 int offset = __ offset();
2091 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
2092 relocInfo::runtime_call_type);
2093 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
2094 __ end_a_stub();
2095
2096 return offset;
2097 }
2098
2099 //=============================================================================
2100
2101 // Use a frame slots bias for frameless methods if accessing the stack.
2102 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) {
2103 if (as_Register(reg_enc) == R1_SP) {
2104 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes();
2105 }
2106 return 0;
2107 }
2108
2109 const bool Matcher::match_rule_supported(int opcode) {
2110 if (!has_match_rule(opcode)) {
2111 return false; // no match rule present
2112 }
2113
2114 switch (opcode) {
2115 case Op_SqrtD:
2116 return VM_Version::has_fsqrt();
2117 case Op_RoundDoubleMode:
2118 return VM_Version::has_vsx();
2119 case Op_CountLeadingZerosI:
2120 case Op_CountLeadingZerosL:
2121 return UseCountLeadingZerosInstructionsPPC64;
2122 case Op_CountTrailingZerosI:
2123 case Op_CountTrailingZerosL:
2124 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64);
2125 case Op_PopCountI:
2126 case Op_PopCountL:
2127 return (UsePopCountInstruction && VM_Version::has_popcntw());
2128
2129 case Op_AddVB:
2130 case Op_AddVS:
2131 case Op_AddVI:
2132 case Op_AddVF:
2133 case Op_AddVD:
2134 case Op_SubVB:
2135 case Op_SubVS:
2136 case Op_SubVI:
2137 case Op_SubVF:
2138 case Op_SubVD:
2139 case Op_MulVS:
2140 case Op_MulVF:
2141 case Op_MulVD:
2142 case Op_DivVF:
2143 case Op_DivVD:
2144 case Op_AbsVF:
2145 case Op_AbsVD:
2146 case Op_NegVF:
2147 case Op_NegVD:
2148 case Op_SqrtVF:
2149 case Op_SqrtVD:
2150 case Op_AddVL:
2151 case Op_SubVL:
2152 case Op_MulVI:
2153 case Op_RoundDoubleModeV:
2154 return SuperwordUseVSX;
2155 case Op_PopCountVI:
2156 return (SuperwordUseVSX && UsePopCountInstruction);
2157 case Op_FmaVF:
2158 case Op_FmaVD:
2159 return (SuperwordUseVSX && UseFMA);
2160
2161 case Op_Digit:
2162 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit);
2163 case Op_LowerCase:
2164 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase);
2165 case Op_UpperCase:
2166 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase);
2167 case Op_Whitespace:
2168 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace);
2169
2170 case Op_CacheWB:
2171 case Op_CacheWBPreSync:
2172 case Op_CacheWBPostSync:
2173 return VM_Version::supports_data_cache_line_flush();
2174 }
2175
2176 return true; // Per default match rules are supported.
2177 }
2178
2179 const bool Matcher::match_rule_supported_superword(int opcode, int vlen, BasicType bt) {
2180 return match_rule_supported_vector(opcode, vlen, bt);
2181 }
2182
2183 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
2184 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
2185 return false;
2186 }
2187 return true; // Per default match rules are supported.
2188 }
2189
2190 const bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
2191 return false;
2192 }
2193
2194 const bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
2195 return false;
2196 }
2197
2198 const RegMask* Matcher::predicate_reg_mask(void) {
2199 return NULL;
2200 }
2201
2202 const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) {
2203 return NULL;
2204 }
2205
2206 // Vector calling convention not yet implemented.
2207 const bool Matcher::supports_vector_calling_convention(void) {
2208 return false;
2209 }
2210
2211 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2212 Unimplemented();
2213 return OptoRegPair(0, 0);
2214 }
2215
2216 // Vector width in bytes.
2217 const int Matcher::vector_width_in_bytes(BasicType bt) {
2218 if (SuperwordUseVSX) {
2219 assert(MaxVectorSize == 16, "");
2220 return 16;
2221 } else {
2222 assert(MaxVectorSize == 8, "");
2223 return 8;
2224 }
2225 }
2226
2227 // Vector ideal reg.
2228 const uint Matcher::vector_ideal_reg(int size) {
2229 if (SuperwordUseVSX) {
2230 assert(MaxVectorSize == 16 && size == 16, "");
2231 return Op_VecX;
2232 } else {
2233 assert(MaxVectorSize == 8 && size == 8, "");
2234 return Op_RegL;
2235 }
2236 }
2237
2238 // Limits on vector size (number of elements) loaded into vector.
2239 const int Matcher::max_vector_size(const BasicType bt) {
2240 assert(is_java_primitive(bt), "only primitive type vectors");
2241 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2242 }
2243
2244 const int Matcher::min_vector_size(const BasicType bt) {
2245 return max_vector_size(bt); // Same as max.
2246 }
2247
2248 const int Matcher::superword_max_vector_size(const BasicType bt) {
2249 return Matcher::max_vector_size(bt);
2250 }
2251
2252 const int Matcher::scalable_vector_reg_size(const BasicType bt) {
2253 return -1;
2254 }
2255
2256 // RETURNS: whether this branch offset is short enough that a short
2257 // branch can be used.
2258 //
2259 // If the platform does not provide any short branch variants, then
2260 // this method should return `false' for offset 0.
2261 //
2262 // `Compile::Fill_buffer' will decide on basis of this information
2263 // whether to do the pass `Compile::Shorten_branches' at all.
2264 //
2265 // And `Compile::Shorten_branches' will decide on basis of this
2266 // information whether to replace particular branch sites by short
2267 // ones.
2268 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2269 // Is the offset within the range of a ppc64 pc relative branch?
2270 bool b;
2271
2272 const int safety_zone = 3 * BytesPerInstWord;
2273 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2274 29 - 16 + 1 + 2);
2275 return b;
2276 }
2277
2278 /* TODO: PPC port
2279 // Make a new machine dependent decode node (with its operands).
2280 MachTypeNode *Matcher::make_decode_node() {
2281 assert(CompressedOops::base() == NULL && CompressedOops::shift() == 0,
2282 "This method is only implemented for unscaled cOops mode so far");
2283 MachTypeNode *decode = new decodeN_unscaledNode();
2284 decode->set_opnd_array(0, new iRegPdstOper());
2285 decode->set_opnd_array(1, new iRegNsrcOper());
2286 return decode;
2287 }
2288 */
2289
2290 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
2291 ShouldNotReachHere(); // generic vector operands not supported
2292 return NULL;
2293 }
2294
2295 bool Matcher::is_reg2reg_move(MachNode* m) {
2296 ShouldNotReachHere(); // generic vector operands not supported
2297 return false;
2298 }
2299
2300 bool Matcher::is_generic_vector(MachOper* opnd) {
2301 ShouldNotReachHere(); // generic vector operands not supported
2302 return false;
2303 }
2304
2305 // Constants for c2c and c calling conventions.
2306
2307 const MachRegisterNumbers iarg_reg[8] = {
2308 R3_num, R4_num, R5_num, R6_num,
2309 R7_num, R8_num, R9_num, R10_num
2310 };
2311
2312 const MachRegisterNumbers farg_reg[13] = {
2313 F1_num, F2_num, F3_num, F4_num,
2314 F5_num, F6_num, F7_num, F8_num,
2315 F9_num, F10_num, F11_num, F12_num,
2316 F13_num
2317 };
2318
2319 const MachRegisterNumbers vsarg_reg[64] = {
2320 VSR0_num, VSR1_num, VSR2_num, VSR3_num,
2321 VSR4_num, VSR5_num, VSR6_num, VSR7_num,
2322 VSR8_num, VSR9_num, VSR10_num, VSR11_num,
2323 VSR12_num, VSR13_num, VSR14_num, VSR15_num,
2324 VSR16_num, VSR17_num, VSR18_num, VSR19_num,
2325 VSR20_num, VSR21_num, VSR22_num, VSR23_num,
2326 VSR24_num, VSR23_num, VSR24_num, VSR25_num,
2327 VSR28_num, VSR29_num, VSR30_num, VSR31_num,
2328 VSR32_num, VSR33_num, VSR34_num, VSR35_num,
2329 VSR36_num, VSR37_num, VSR38_num, VSR39_num,
2330 VSR40_num, VSR41_num, VSR42_num, VSR43_num,
2331 VSR44_num, VSR45_num, VSR46_num, VSR47_num,
2332 VSR48_num, VSR49_num, VSR50_num, VSR51_num,
2333 VSR52_num, VSR53_num, VSR54_num, VSR55_num,
2334 VSR56_num, VSR57_num, VSR58_num, VSR59_num,
2335 VSR60_num, VSR61_num, VSR62_num, VSR63_num
2336 };
2337
2338 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]);
2339
2340 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]);
2341
2342 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]);
2343
2344 // Return whether or not this register is ever used as an argument. This
2345 // function is used on startup to build the trampoline stubs in generateOptoStub.
2346 // Registers not mentioned will be killed by the VM call in the trampoline, and
2347 // arguments in those registers not be available to the callee.
2348 bool Matcher::can_be_java_arg(int reg) {
2349 // We return true for all registers contained in iarg_reg[] and
2350 // farg_reg[] and their virtual halves.
2351 // We must include the virtual halves in order to get STDs and LDs
2352 // instead of STWs and LWs in the trampoline stubs.
2353
2354 if ( reg == R3_num || reg == R3_H_num
2355 || reg == R4_num || reg == R4_H_num
2356 || reg == R5_num || reg == R5_H_num
2357 || reg == R6_num || reg == R6_H_num
2358 || reg == R7_num || reg == R7_H_num
2359 || reg == R8_num || reg == R8_H_num
2360 || reg == R9_num || reg == R9_H_num
2361 || reg == R10_num || reg == R10_H_num)
2362 return true;
2363
2364 if ( reg == F1_num || reg == F1_H_num
2365 || reg == F2_num || reg == F2_H_num
2366 || reg == F3_num || reg == F3_H_num
2367 || reg == F4_num || reg == F4_H_num
2368 || reg == F5_num || reg == F5_H_num
2369 || reg == F6_num || reg == F6_H_num
2370 || reg == F7_num || reg == F7_H_num
2371 || reg == F8_num || reg == F8_H_num
2372 || reg == F9_num || reg == F9_H_num
2373 || reg == F10_num || reg == F10_H_num
2374 || reg == F11_num || reg == F11_H_num
2375 || reg == F12_num || reg == F12_H_num
2376 || reg == F13_num || reg == F13_H_num)
2377 return true;
2378
2379 return false;
2380 }
2381
2382 bool Matcher::is_spillable_arg(int reg) {
2383 return can_be_java_arg(reg);
2384 }
2385
2386 uint Matcher::int_pressure_limit()
2387 {
2388 return (INTPRESSURE == -1) ? 26 : INTPRESSURE;
2389 }
2390
2391 uint Matcher::float_pressure_limit()
2392 {
2393 return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE;
2394 }
2395
2396 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
2397 return false;
2398 }
2399
2400 // Register for DIVI projection of divmodI.
2401 RegMask Matcher::divI_proj_mask() {
2402 ShouldNotReachHere();
2403 return RegMask();
2404 }
2405
2406 // Register for MODI projection of divmodI.
2407 RegMask Matcher::modI_proj_mask() {
2408 ShouldNotReachHere();
2409 return RegMask();
2410 }
2411
2412 // Register for DIVL projection of divmodL.
2413 RegMask Matcher::divL_proj_mask() {
2414 ShouldNotReachHere();
2415 return RegMask();
2416 }
2417
2418 // Register for MODL projection of divmodL.
2419 RegMask Matcher::modL_proj_mask() {
2420 ShouldNotReachHere();
2421 return RegMask();
2422 }
2423
2424 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
2425 return RegMask();
2426 }
2427
2428 %}
2429
2430 //----------ENCODING BLOCK-----------------------------------------------------
2431 // This block specifies the encoding classes used by the compiler to output
2432 // byte streams. Encoding classes are parameterized macros used by
2433 // Machine Instruction Nodes in order to generate the bit encoding of the
2434 // instruction. Operands specify their base encoding interface with the
2435 // interface keyword. There are currently supported four interfaces,
2436 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
2437 // operand to generate a function which returns its register number when
2438 // queried. CONST_INTER causes an operand to generate a function which
2439 // returns the value of the constant when queried. MEMORY_INTER causes an
2440 // operand to generate four functions which return the Base Register, the
2441 // Index Register, the Scale Value, and the Offset Value of the operand when
2442 // queried. COND_INTER causes an operand to generate six functions which
2443 // return the encoding code (ie - encoding bits for the instruction)
2444 // associated with each basic boolean condition for a conditional instruction.
2445 //
2446 // Instructions specify two basic values for encoding. Again, a function
2447 // is available to check if the constant displacement is an oop. They use the
2448 // ins_encode keyword to specify their encoding classes (which must be
2449 // a sequence of enc_class names, and their parameters, specified in
2450 // the encoding block), and they use the
2451 // opcode keyword to specify, in order, their primary, secondary, and
2452 // tertiary opcode. Only the opcode sections which a particular instruction
2453 // needs for encoding need to be specified.
2454 encode %{
2455 enc_class enc_unimplemented %{
2456 C2_MacroAssembler _masm(&cbuf);
2457 __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
2458 %}
2459
2460 enc_class enc_untested %{
2461 #ifdef ASSERT
2462 C2_MacroAssembler _masm(&cbuf);
2463 __ untested("Untested mach node encoding in AD file.");
2464 #else
2465 #endif
2466 %}
2467
2468 enc_class enc_lbz(iRegIdst dst, memory mem) %{
2469 C2_MacroAssembler _masm(&cbuf);
2470 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2471 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2472 %}
2473
2474 // Load acquire.
2475 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
2476 C2_MacroAssembler _masm(&cbuf);
2477 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2478 __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2479 __ twi_0($dst$$Register);
2480 __ isync();
2481 %}
2482
2483 enc_class enc_lhz(iRegIdst dst, memory mem) %{
2484
2485 C2_MacroAssembler _masm(&cbuf);
2486 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2487 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2488 %}
2489
2490 // Load acquire.
2491 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
2492
2493 C2_MacroAssembler _masm(&cbuf);
2494 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2495 __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2496 __ twi_0($dst$$Register);
2497 __ isync();
2498 %}
2499
2500 enc_class enc_lwz(iRegIdst dst, memory mem) %{
2501
2502 C2_MacroAssembler _masm(&cbuf);
2503 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2504 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2505 %}
2506
2507 // Load acquire.
2508 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
2509
2510 C2_MacroAssembler _masm(&cbuf);
2511 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2512 __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2513 __ twi_0($dst$$Register);
2514 __ isync();
2515 %}
2516
2517 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
2518 C2_MacroAssembler _masm(&cbuf);
2519 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2520 // Operand 'ds' requires 4-alignment.
2521 assert((Idisp & 0x3) == 0, "unaligned offset");
2522 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2523 %}
2524
2525 // Load acquire.
2526 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
2527 C2_MacroAssembler _masm(&cbuf);
2528 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2529 // Operand 'ds' requires 4-alignment.
2530 assert((Idisp & 0x3) == 0, "unaligned offset");
2531 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2532 __ twi_0($dst$$Register);
2533 __ isync();
2534 %}
2535
2536 enc_class enc_lfd(RegF dst, memory mem) %{
2537 C2_MacroAssembler _masm(&cbuf);
2538 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2539 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2540 %}
2541
2542 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2543
2544 C2_MacroAssembler _masm(&cbuf);
2545 int toc_offset = 0;
2546
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 toc_offset = __ offset_to_method_toc(const_toc_addr);
2558
2559 // Keep the current instruction offset in mind.
2560 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2561
2562 __ ld($dst$$Register, toc_offset, $toc$$Register);
2563 %}
2564
2565 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2566
2567 C2_MacroAssembler _masm(&cbuf);
2568
2569 if (!ra_->C->output()->in_scratch_emit_size()) {
2570 address const_toc_addr;
2571 // Create a non-oop constant, no relocation needed.
2572 // If it is an IC, it has a virtual_call_Relocation.
2573 const_toc_addr = __ long_constant((jlong)$src$$constant);
2574 if (const_toc_addr == NULL) {
2575 ciEnv::current()->record_out_of_memory_failure();
2576 return;
2577 }
2578
2579 // Get the constant's TOC offset.
2580 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2581 // Store the toc offset of the constant.
2582 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2583
2584 // Also keep the current instruction offset in mind.
2585 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2586 }
2587
2588 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2589 %}
2590
2591 %} // encode
2592
2593 source %{
2594
2595 typedef struct {
2596 loadConL_hiNode *_large_hi;
2597 loadConL_loNode *_large_lo;
2598 loadConLNode *_small;
2599 MachNode *_last;
2600 } loadConLNodesTuple;
2601
2602 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2603 OptoReg::Name reg_second, OptoReg::Name reg_first) {
2604 loadConLNodesTuple nodes;
2605
2606 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2607 if (large_constant_pool) {
2608 // Create new nodes.
2609 loadConL_hiNode *m1 = new loadConL_hiNode();
2610 loadConL_loNode *m2 = new loadConL_loNode();
2611
2612 // inputs for new nodes
2613 m1->add_req(NULL, toc);
2614 m2->add_req(NULL, m1);
2615
2616 // operands for new nodes
2617 m1->_opnds[0] = new iRegLdstOper(); // dst
2618 m1->_opnds[1] = immSrc; // src
2619 m1->_opnds[2] = new iRegPdstOper(); // toc
2620 m2->_opnds[0] = new iRegLdstOper(); // dst
2621 m2->_opnds[1] = immSrc; // src
2622 m2->_opnds[2] = new iRegLdstOper(); // base
2623
2624 // Initialize ins_attrib TOC fields.
2625 m1->_const_toc_offset = -1;
2626 m2->_const_toc_offset_hi_node = m1;
2627
2628 // Initialize ins_attrib instruction offset.
2629 m1->_cbuf_insts_offset = -1;
2630
2631 // register allocation for new nodes
2632 ra_->set_pair(m1->_idx, reg_second, reg_first);
2633 ra_->set_pair(m2->_idx, reg_second, reg_first);
2634
2635 // Create result.
2636 nodes._large_hi = m1;
2637 nodes._large_lo = m2;
2638 nodes._small = NULL;
2639 nodes._last = nodes._large_lo;
2640 assert(m2->bottom_type()->isa_long(), "must be long");
2641 } else {
2642 loadConLNode *m2 = new loadConLNode();
2643
2644 // inputs for new nodes
2645 m2->add_req(NULL, toc);
2646
2647 // operands for new nodes
2648 m2->_opnds[0] = new iRegLdstOper(); // dst
2649 m2->_opnds[1] = immSrc; // src
2650 m2->_opnds[2] = new iRegPdstOper(); // toc
2651
2652 // Initialize ins_attrib instruction offset.
2653 m2->_cbuf_insts_offset = -1;
2654
2655 // register allocation for new nodes
2656 ra_->set_pair(m2->_idx, reg_second, reg_first);
2657
2658 // Create result.
2659 nodes._large_hi = NULL;
2660 nodes._large_lo = NULL;
2661 nodes._small = m2;
2662 nodes._last = nodes._small;
2663 assert(m2->bottom_type()->isa_long(), "must be long");
2664 }
2665
2666 return nodes;
2667 }
2668
2669 typedef struct {
2670 loadConL_hiNode *_large_hi;
2671 loadConL_loNode *_large_lo;
2672 mtvsrdNode *_moved;
2673 xxspltdNode *_replicated;
2674 loadConLNode *_small;
2675 MachNode *_last;
2676 } loadConLReplicatedNodesTuple;
2677
2678 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2679 vecXOper *dst, immI_0Oper *zero,
2680 OptoReg::Name reg_second, OptoReg::Name reg_first,
2681 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) {
2682 loadConLReplicatedNodesTuple nodes;
2683
2684 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2685 if (large_constant_pool) {
2686 // Create new nodes.
2687 loadConL_hiNode *m1 = new loadConL_hiNode();
2688 loadConL_loNode *m2 = new loadConL_loNode();
2689 mtvsrdNode *m3 = new mtvsrdNode();
2690 xxspltdNode *m4 = new xxspltdNode();
2691
2692 // inputs for new nodes
2693 m1->add_req(NULL, toc);
2694 m2->add_req(NULL, m1);
2695 m3->add_req(NULL, m2);
2696 m4->add_req(NULL, m3);
2697
2698 // operands for new nodes
2699 m1->_opnds[0] = new iRegLdstOper(); // dst
2700 m1->_opnds[1] = immSrc; // src
2701 m1->_opnds[2] = new iRegPdstOper(); // toc
2702
2703 m2->_opnds[0] = new iRegLdstOper(); // dst
2704 m2->_opnds[1] = immSrc; // src
2705 m2->_opnds[2] = new iRegLdstOper(); // base
2706
2707 m3->_opnds[0] = new vecXOper(); // dst
2708 m3->_opnds[1] = new iRegLdstOper(); // src
2709
2710 m4->_opnds[0] = new vecXOper(); // dst
2711 m4->_opnds[1] = new vecXOper(); // src
2712 m4->_opnds[2] = zero;
2713
2714 // Initialize ins_attrib TOC fields.
2715 m1->_const_toc_offset = -1;
2716 m2->_const_toc_offset_hi_node = m1;
2717
2718 // Initialize ins_attrib instruction offset.
2719 m1->_cbuf_insts_offset = -1;
2720
2721 // register allocation for new nodes
2722 ra_->set_pair(m1->_idx, reg_second, reg_first);
2723 ra_->set_pair(m2->_idx, reg_second, reg_first);
2724 ra_->set1(m3->_idx, reg_second);
2725 ra_->set2(m3->_idx, reg_vec_first);
2726 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2727
2728 // Create result.
2729 nodes._large_hi = m1;
2730 nodes._large_lo = m2;
2731 nodes._moved = m3;
2732 nodes._replicated = m4;
2733 nodes._small = NULL;
2734 nodes._last = nodes._replicated;
2735 assert(m2->bottom_type()->isa_long(), "must be long");
2736 } else {
2737 loadConLNode *m2 = new loadConLNode();
2738 mtvsrdNode *m3 = new mtvsrdNode();
2739 xxspltdNode *m4 = new xxspltdNode();
2740
2741 // inputs for new nodes
2742 m2->add_req(NULL, toc);
2743
2744 // operands for new nodes
2745 m2->_opnds[0] = new iRegLdstOper(); // dst
2746 m2->_opnds[1] = immSrc; // src
2747 m2->_opnds[2] = new iRegPdstOper(); // toc
2748
2749 m3->_opnds[0] = new vecXOper(); // dst
2750 m3->_opnds[1] = new iRegLdstOper(); // src
2751
2752 m4->_opnds[0] = new vecXOper(); // dst
2753 m4->_opnds[1] = new vecXOper(); // src
2754 m4->_opnds[2] = zero;
2755
2756 // Initialize ins_attrib instruction offset.
2757 m2->_cbuf_insts_offset = -1;
2758 ra_->set1(m3->_idx, reg_second);
2759 ra_->set2(m3->_idx, reg_vec_first);
2760 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first);
2761
2762 // register allocation for new nodes
2763 ra_->set_pair(m2->_idx, reg_second, reg_first);
2764
2765 // Create result.
2766 nodes._large_hi = NULL;
2767 nodes._large_lo = NULL;
2768 nodes._small = m2;
2769 nodes._moved = m3;
2770 nodes._replicated = m4;
2771 nodes._last = nodes._replicated;
2772 assert(m2->bottom_type()->isa_long(), "must be long");
2773 }
2774
2775 return nodes;
2776 }
2777
2778 %} // source
2779
2780 encode %{
2781 // Postalloc expand emitter for loading a long constant from the method's TOC.
2782 // Enc_class needed as consttanttablebase is not supported by postalloc
2783 // expand.
2784 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2785 // Create new nodes.
2786 loadConLNodesTuple loadConLNodes =
2787 loadConLNodesTuple_create(ra_, n_toc, op_src,
2788 ra_->get_reg_second(this), ra_->get_reg_first(this));
2789
2790 // Push new nodes.
2791 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2792 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2793
2794 // some asserts
2795 assert(nodes->length() >= 1, "must have created at least 1 node");
2796 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2797 %}
2798
2799 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2800
2801 C2_MacroAssembler _masm(&cbuf);
2802 int toc_offset = 0;
2803
2804 intptr_t val = $src$$constant;
2805 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2806 address const_toc_addr;
2807 RelocationHolder r; // Initializes type to none.
2808 if (constant_reloc == relocInfo::oop_type) {
2809 // Create an oop constant and a corresponding relocation.
2810 AddressLiteral a = __ constant_oop_address((jobject)val);
2811 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2812 r = a.rspec();
2813 } else if (constant_reloc == relocInfo::metadata_type) {
2814 // Notify OOP recorder (don't need the relocation)
2815 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2816 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2817 } else {
2818 // Create a non-oop constant, no relocation needed.
2819 const_toc_addr = __ long_constant((jlong)$src$$constant);
2820 }
2821
2822 if (const_toc_addr == NULL) {
2823 ciEnv::current()->record_out_of_memory_failure();
2824 return;
2825 }
2826 __ relocate(r); // If set above.
2827 // Get the constant's TOC offset.
2828 toc_offset = __ offset_to_method_toc(const_toc_addr);
2829
2830 __ ld($dst$$Register, toc_offset, $toc$$Register);
2831 %}
2832
2833 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2834
2835 C2_MacroAssembler _masm(&cbuf);
2836 if (!ra_->C->output()->in_scratch_emit_size()) {
2837 intptr_t val = $src$$constant;
2838 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2839 address const_toc_addr;
2840 RelocationHolder r; // Initializes type to none.
2841 if (constant_reloc == relocInfo::oop_type) {
2842 // Create an oop constant and a corresponding relocation.
2843 AddressLiteral a = __ constant_oop_address((jobject)val);
2844 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2845 r = a.rspec();
2846 } else if (constant_reloc == relocInfo::metadata_type) {
2847 // Notify OOP recorder (don't need the relocation)
2848 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2849 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2850 } else { // non-oop pointers, e.g. card mark base, heap top
2851 // Create a non-oop constant, no relocation needed.
2852 const_toc_addr = __ long_constant((jlong)$src$$constant);
2853 }
2854
2855 if (const_toc_addr == NULL) {
2856 ciEnv::current()->record_out_of_memory_failure();
2857 return;
2858 }
2859 __ relocate(r); // If set above.
2860 // Get the constant's TOC offset.
2861 const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2862 // Store the toc offset of the constant.
2863 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2864 }
2865
2866 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2867 %}
2868
2869 // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2870 // Enc_class needed as consttanttablebase is not supported by postalloc
2871 // expand.
2872 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2873 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2874 if (large_constant_pool) {
2875 // Create new nodes.
2876 loadConP_hiNode *m1 = new loadConP_hiNode();
2877 loadConP_loNode *m2 = new loadConP_loNode();
2878
2879 // inputs for new nodes
2880 m1->add_req(NULL, n_toc);
2881 m2->add_req(NULL, m1);
2882
2883 // operands for new nodes
2884 m1->_opnds[0] = new iRegPdstOper(); // dst
2885 m1->_opnds[1] = op_src; // src
2886 m1->_opnds[2] = new iRegPdstOper(); // toc
2887 m2->_opnds[0] = new iRegPdstOper(); // dst
2888 m2->_opnds[1] = op_src; // src
2889 m2->_opnds[2] = new iRegLdstOper(); // base
2890
2891 // Initialize ins_attrib TOC fields.
2892 m1->_const_toc_offset = -1;
2893 m2->_const_toc_offset_hi_node = m1;
2894
2895 // Register allocation for new nodes.
2896 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2897 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2898
2899 nodes->push(m1);
2900 nodes->push(m2);
2901 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2902 } else {
2903 loadConPNode *m2 = new loadConPNode();
2904
2905 // inputs for new nodes
2906 m2->add_req(NULL, n_toc);
2907
2908 // operands for new nodes
2909 m2->_opnds[0] = new iRegPdstOper(); // dst
2910 m2->_opnds[1] = op_src; // src
2911 m2->_opnds[2] = new iRegPdstOper(); // toc
2912
2913 // Register allocation for new nodes.
2914 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2915
2916 nodes->push(m2);
2917 assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2918 }
2919 %}
2920
2921 // Enc_class needed as consttanttablebase is not supported by postalloc
2922 // expand.
2923 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2924 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2925
2926 MachNode *m2;
2927 if (large_constant_pool) {
2928 m2 = new loadConFCompNode();
2929 } else {
2930 m2 = new loadConFNode();
2931 }
2932 // inputs for new nodes
2933 m2->add_req(NULL, n_toc);
2934
2935 // operands for new nodes
2936 m2->_opnds[0] = op_dst;
2937 m2->_opnds[1] = op_src;
2938 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase
2939
2940 // register allocation for new nodes
2941 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2942 nodes->push(m2);
2943 %}
2944
2945 // Enc_class needed as consttanttablebase is not supported by postalloc
2946 // expand.
2947 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2948 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2949
2950 MachNode *m2;
2951 if (large_constant_pool) {
2952 m2 = new loadConDCompNode();
2953 } else {
2954 m2 = new loadConDNode();
2955 }
2956 // inputs for new nodes
2957 m2->add_req(NULL, n_toc);
2958
2959 // operands for new nodes
2960 m2->_opnds[0] = op_dst;
2961 m2->_opnds[1] = op_src;
2962 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase
2963
2964 // register allocation for new nodes
2965 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2966 nodes->push(m2);
2967 %}
2968
2969 enc_class enc_stw(iRegIsrc src, memory mem) %{
2970 C2_MacroAssembler _masm(&cbuf);
2971 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2972 __ stw($src$$Register, Idisp, $mem$$base$$Register);
2973 %}
2974
2975 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2976 C2_MacroAssembler _masm(&cbuf);
2977 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2978 // Operand 'ds' requires 4-alignment.
2979 assert((Idisp & 0x3) == 0, "unaligned offset");
2980 __ std($src$$Register, Idisp, $mem$$base$$Register);
2981 %}
2982
2983 enc_class enc_stfs(RegF src, memory mem) %{
2984 C2_MacroAssembler _masm(&cbuf);
2985 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2986 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2987 %}
2988
2989 enc_class enc_stfd(RegF src, memory mem) %{
2990 C2_MacroAssembler _masm(&cbuf);
2991 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2992 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2993 %}
2994
2995 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2996
2997 if (VM_Version::has_isel()) {
2998 // use isel instruction with Power 7
2999 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
3000 encodeP_subNode *n_sub_base = new encodeP_subNode();
3001 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
3002 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode();
3003
3004 n_compare->add_req(n_region, n_src);
3005 n_compare->_opnds[0] = op_crx;
3006 n_compare->_opnds[1] = op_src;
3007 n_compare->_opnds[2] = new immL16Oper(0);
3008
3009 n_sub_base->add_req(n_region, n_src);
3010 n_sub_base->_opnds[0] = op_dst;
3011 n_sub_base->_opnds[1] = op_src;
3012 n_sub_base->_bottom_type = _bottom_type;
3013
3014 n_shift->add_req(n_region, n_sub_base);
3015 n_shift->_opnds[0] = op_dst;
3016 n_shift->_opnds[1] = op_dst;
3017 n_shift->_bottom_type = _bottom_type;
3018
3019 n_cond_set->add_req(n_region, n_compare, n_shift);
3020 n_cond_set->_opnds[0] = op_dst;
3021 n_cond_set->_opnds[1] = op_crx;
3022 n_cond_set->_opnds[2] = op_dst;
3023 n_cond_set->_bottom_type = _bottom_type;
3024
3025 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3026 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3027 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3028 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3029
3030 nodes->push(n_compare);
3031 nodes->push(n_sub_base);
3032 nodes->push(n_shift);
3033 nodes->push(n_cond_set);
3034
3035 } else {
3036 // before Power 7
3037 moveRegNode *n_move = new moveRegNode();
3038 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node();
3039 encodeP_shiftNode *n_shift = new encodeP_shiftNode();
3040 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode();
3041
3042 n_move->add_req(n_region, n_src);
3043 n_move->_opnds[0] = op_dst;
3044 n_move->_opnds[1] = op_src;
3045 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop.
3046
3047 n_compare->add_req(n_region, n_src);
3048 n_compare->add_prec(n_move);
3049
3050 n_compare->_opnds[0] = op_crx;
3051 n_compare->_opnds[1] = op_src;
3052 n_compare->_opnds[2] = new immL16Oper(0);
3053
3054 n_sub_base->add_req(n_region, n_compare, n_src);
3055 n_sub_base->_opnds[0] = op_dst;
3056 n_sub_base->_opnds[1] = op_crx;
3057 n_sub_base->_opnds[2] = op_src;
3058 n_sub_base->_bottom_type = _bottom_type;
3059
3060 n_shift->add_req(n_region, n_sub_base);
3061 n_shift->_opnds[0] = op_dst;
3062 n_shift->_opnds[1] = op_dst;
3063 n_shift->_bottom_type = _bottom_type;
3064
3065 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3066 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3067 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3068 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3069
3070 nodes->push(n_move);
3071 nodes->push(n_compare);
3072 nodes->push(n_sub_base);
3073 nodes->push(n_shift);
3074 }
3075
3076 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
3077 %}
3078
3079 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
3080
3081 encodeP_subNode *n1 = new encodeP_subNode();
3082 n1->add_req(n_region, n_src);
3083 n1->_opnds[0] = op_dst;
3084 n1->_opnds[1] = op_src;
3085 n1->_bottom_type = _bottom_type;
3086
3087 encodeP_shiftNode *n2 = new encodeP_shiftNode();
3088 n2->add_req(n_region, n1);
3089 n2->_opnds[0] = op_dst;
3090 n2->_opnds[1] = op_dst;
3091 n2->_bottom_type = _bottom_type;
3092 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3093 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3094
3095 nodes->push(n1);
3096 nodes->push(n2);
3097 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
3098 %}
3099
3100 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
3101 decodeN_shiftNode *n_shift = new decodeN_shiftNode();
3102 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
3103
3104 n_compare->add_req(n_region, n_src);
3105 n_compare->_opnds[0] = op_crx;
3106 n_compare->_opnds[1] = op_src;
3107 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
3108
3109 n_shift->add_req(n_region, n_src);
3110 n_shift->_opnds[0] = op_dst;
3111 n_shift->_opnds[1] = op_src;
3112 n_shift->_bottom_type = _bottom_type;
3113
3114 if (VM_Version::has_isel()) {
3115 // use isel instruction with Power 7
3116
3117 decodeN_addNode *n_add_base = new decodeN_addNode();
3118 n_add_base->add_req(n_region, n_shift);
3119 n_add_base->_opnds[0] = op_dst;
3120 n_add_base->_opnds[1] = op_dst;
3121 n_add_base->_bottom_type = _bottom_type;
3122
3123 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
3124 n_cond_set->add_req(n_region, n_compare, n_add_base);
3125 n_cond_set->_opnds[0] = op_dst;
3126 n_cond_set->_opnds[1] = op_crx;
3127 n_cond_set->_opnds[2] = op_dst;
3128 n_cond_set->_bottom_type = _bottom_type;
3129
3130 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3131 ra_->set_oop(n_cond_set, true);
3132
3133 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3134 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3135 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3136 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3137
3138 nodes->push(n_compare);
3139 nodes->push(n_shift);
3140 nodes->push(n_add_base);
3141 nodes->push(n_cond_set);
3142
3143 } else {
3144 // before Power 7
3145 cond_add_baseNode *n_add_base = new cond_add_baseNode();
3146
3147 n_add_base->add_req(n_region, n_compare, n_shift);
3148 n_add_base->_opnds[0] = op_dst;
3149 n_add_base->_opnds[1] = op_crx;
3150 n_add_base->_opnds[2] = op_dst;
3151 n_add_base->_bottom_type = _bottom_type;
3152
3153 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3154 ra_->set_oop(n_add_base, true);
3155
3156 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3157 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
3158 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3159
3160 nodes->push(n_compare);
3161 nodes->push(n_shift);
3162 nodes->push(n_add_base);
3163 }
3164 %}
3165
3166 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
3167 decodeN_shiftNode *n1 = new decodeN_shiftNode();
3168 n1->add_req(n_region, n_src);
3169 n1->_opnds[0] = op_dst;
3170 n1->_opnds[1] = op_src;
3171 n1->_bottom_type = _bottom_type;
3172
3173 decodeN_addNode *n2 = new decodeN_addNode();
3174 n2->add_req(n_region, n1);
3175 n2->_opnds[0] = op_dst;
3176 n2->_opnds[1] = op_dst;
3177 n2->_bottom_type = _bottom_type;
3178 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3179 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3180
3181 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3182 ra_->set_oop(n2, true);
3183
3184 nodes->push(n1);
3185 nodes->push(n2);
3186 %}
3187
3188 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{
3189
3190 C2_MacroAssembler _masm(&cbuf);
3191 int cc = $cmp$$cmpcode;
3192 int flags_reg = $crx$$reg;
3193 Label done;
3194 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3195 // Branch if not (cmp crx).
3196 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done);
3197 __ mr($dst$$Register, $src$$Register);
3198 __ bind(done);
3199 %}
3200
3201 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{
3202
3203 C2_MacroAssembler _masm(&cbuf);
3204 Label done;
3205 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3206 // Branch if not (cmp crx).
3207 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
3208 __ li($dst$$Register, $src$$constant);
3209 __ bind(done);
3210 %}
3211
3212 // This enc_class is needed so that scheduler gets proper
3213 // input mapping for latency computation.
3214 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
3215 C2_MacroAssembler _masm(&cbuf);
3216 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
3217 %}
3218
3219 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3220
3221 C2_MacroAssembler _masm(&cbuf);
3222
3223 Label done;
3224 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3225 __ li($dst$$Register, $zero$$constant);
3226 __ beq($crx$$CondRegister, done);
3227 __ li($dst$$Register, $notzero$$constant);
3228 __ bind(done);
3229 %}
3230
3231 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3232
3233 C2_MacroAssembler _masm(&cbuf);
3234
3235 Label done;
3236 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3237 __ li($dst$$Register, $zero$$constant);
3238 __ beq($crx$$CondRegister, done);
3239 __ li($dst$$Register, $notzero$$constant);
3240 __ bind(done);
3241 %}
3242
3243 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3244
3245 C2_MacroAssembler _masm(&cbuf);
3246 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3247 Label done;
3248 __ bso($crx$$CondRegister, done);
3249 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3250 __ bind(done);
3251 %}
3252
3253 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
3254
3255 C2_MacroAssembler _masm(&cbuf);
3256 Label done;
3257 __ bso($crx$$CondRegister, done);
3258 __ mffprd($dst$$Register, $src$$FloatRegister);
3259 __ bind(done);
3260 %}
3261
3262 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3263
3264 C2_MacroAssembler _masm(&cbuf);
3265 Label d; // dummy
3266 __ bind(d);
3267 Label* p = ($lbl$$label);
3268 // `p' is `NULL' when this encoding class is used only to
3269 // determine the size of the encoded instruction.
3270 Label& l = (NULL == p)? d : *(p);
3271 int cc = $cmp$$cmpcode;
3272 int flags_reg = $crx$$reg;
3273 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3274 int bhint = Assembler::bhintNoHint;
3275
3276 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3277 if (_prob <= PROB_NEVER) {
3278 bhint = Assembler::bhintIsNotTaken;
3279 } else if (_prob >= PROB_ALWAYS) {
3280 bhint = Assembler::bhintIsTaken;
3281 }
3282 }
3283
3284 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3285 cc_to_biint(cc, flags_reg),
3286 l);
3287 %}
3288
3289 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3290 // The scheduler doesn't know about branch shortening, so we set the opcode
3291 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3292
3293 C2_MacroAssembler _masm(&cbuf);
3294 Label d; // dummy
3295 __ bind(d);
3296 Label* p = ($lbl$$label);
3297 // `p' is `NULL' when this encoding class is used only to
3298 // determine the size of the encoded instruction.
3299 Label& l = (NULL == p)? d : *(p);
3300 int cc = $cmp$$cmpcode;
3301 int flags_reg = $crx$$reg;
3302 int bhint = Assembler::bhintNoHint;
3303
3304 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3305 if (_prob <= PROB_NEVER) {
3306 bhint = Assembler::bhintIsNotTaken;
3307 } else if (_prob >= PROB_ALWAYS) {
3308 bhint = Assembler::bhintIsTaken;
3309 }
3310 }
3311
3312 // Tell the conditional far branch to optimize itself when being relocated.
3313 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3314 cc_to_biint(cc, flags_reg),
3315 l,
3316 MacroAssembler::bc_far_optimize_on_relocate);
3317 %}
3318
3319 // Postalloc expand emitter for loading a replicatef float constant from
3320 // the method's TOC.
3321 // Enc_class needed as consttanttablebase is not supported by postalloc
3322 // expand.
3323 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3324 // Create new nodes.
3325
3326 // Make an operand with the bit pattern to load as float.
3327 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3328
3329 loadConLNodesTuple loadConLNodes =
3330 loadConLNodesTuple_create(ra_, n_toc, op_repl,
3331 ra_->get_reg_second(this), ra_->get_reg_first(this));
3332
3333 // Push new nodes.
3334 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3335 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
3336
3337 assert(nodes->length() >= 1, "must have created at least 1 node");
3338 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3339 %}
3340
3341 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{
3342 // Create new nodes.
3343
3344 // Make an operand with the bit pattern to load as float.
3345 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3346 immI_0Oper *op_zero = new immI_0Oper(0);
3347
3348 loadConLReplicatedNodesTuple loadConLNodes =
3349 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero,
3350 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp),
3351 ra_->get_reg_second(this), ra_->get_reg_first(this));
3352
3353 // Push new nodes.
3354 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); }
3355 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); }
3356 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); }
3357 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); }
3358
3359 assert(nodes->length() >= 1, "must have created at least 1 node");
3360 %}
3361
3362 // This enc_class is needed so that scheduler gets proper
3363 // input mapping for latency computation.
3364 enc_class enc_poll(immI dst, iRegLdst poll) %{
3365 // Fake operand dst needed for PPC scheduler.
3366 assert($dst$$constant == 0x0, "dst must be 0x0");
3367
3368 C2_MacroAssembler _masm(&cbuf);
3369 // Mark the code position where the load from the safepoint
3370 // polling page was emitted as relocInfo::poll_type.
3371 __ relocate(relocInfo::poll_type);
3372 __ load_from_polling_page($poll$$Register);
3373 %}
3374
3375 // A Java static call or a runtime call.
3376 //
3377 // Branch-and-link relative to a trampoline.
3378 // The trampoline loads the target address and does a long branch to there.
3379 // In case we call java, the trampoline branches to a interpreter_stub
3380 // which loads the inline cache and the real call target from the constant pool.
3381 //
3382 // This basically looks like this:
3383 //
3384 // >>>> consts -+ -+
3385 // | |- offset1
3386 // [call target1] | <-+
3387 // [IC cache] |- offset2
3388 // [call target2] <--+
3389 //
3390 // <<<< consts
3391 // >>>> insts
3392 //
3393 // bl offset16 -+ -+ ??? // How many bits available?
3394 // | |
3395 // <<<< insts | |
3396 // >>>> stubs | |
3397 // | |- trampoline_stub_Reloc
3398 // trampoline stub: | <-+
3399 // r2 = toc |
3400 // r2 = [r2 + offset1] | // Load call target1 from const section
3401 // mtctr r2 |
3402 // bctr |- static_stub_Reloc
3403 // comp_to_interp_stub: <---+
3404 // r1 = toc
3405 // ICreg = [r1 + IC_offset] // Load IC from const section
3406 // r1 = [r1 + offset2] // Load call target2 from const section
3407 // mtctr r1
3408 // bctr
3409 //
3410 // <<<< stubs
3411 //
3412 // The call instruction in the code either
3413 // - Branches directly to a compiled method if the offset is encodable in instruction.
3414 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3415 // - Branches to the compiled_to_interp stub if the target is interpreted.
3416 //
3417 // Further there are three relocations from the loads to the constants in
3418 // the constant section.
3419 //
3420 // Usage of r1 and r2 in the stubs allows to distinguish them.
3421 enc_class enc_java_static_call(method meth) %{
3422
3423 C2_MacroAssembler _masm(&cbuf);
3424 address entry_point = (address)$meth$$method;
3425
3426 if (!_method) {
3427 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3428 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type);
3429 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3430 } else {
3431 // Remember the offset not the address.
3432 const int start_offset = __ offset();
3433
3434 // The trampoline stub.
3435 // No entry point given, use the current pc.
3436 // Make sure branch fits into
3437 if (entry_point == 0) entry_point = __ pc();
3438
3439 // Put the entry point as a constant into the constant pool.
3440 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
3441 if (entry_point_toc_addr == NULL) {
3442 ciEnv::current()->record_out_of_memory_failure();
3443 return;
3444 }
3445 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
3446
3447 // Emit the trampoline stub which will be related to the branch-and-link below.
3448 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
3449 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3450 int method_index = resolved_method_index(cbuf);
3451 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3452 : static_call_Relocation::spec(method_index));
3453
3454 // The real call.
3455 // Note: At this point we do not have the address of the trampoline
3456 // stub, and the entry point might be too far away for bl, so __ pc()
3457 // serves as dummy and the bl will be patched later.
3458 cbuf.set_insts_mark();
3459 __ bl(__ pc()); // Emits a relocation.
3460
3461 // The stub for call to interpreter.
3462 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
3463 if (stub == NULL) {
3464 ciEnv::current()->record_failure("CodeCache is full");
3465 return;
3466 }
3467 }
3468 __ post_call_nop();
3469 %}
3470
3471 // Second node of expanded dynamic call - the call.
3472 enc_class enc_java_dynamic_call_sched(method meth) %{
3473
3474 C2_MacroAssembler _masm(&cbuf);
3475
3476 if (!ra_->C->output()->in_scratch_emit_size()) {
3477 // Create a call trampoline stub for the given method.
3478 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method;
3479 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none);
3480 if (entry_point_const == NULL) {
3481 ciEnv::current()->record_out_of_memory_failure();
3482 return;
3483 }
3484 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const);
3485 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset());
3486 if (ra_->C->env()->failing()) { return; } // Code cache may be full.
3487
3488 // Build relocation at call site with ic position as data.
3489 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) ||
3490 (_load_ic_hi_node == NULL && _load_ic_node != NULL),
3491 "must have one, but can't have both");
3492 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) ||
3493 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1),
3494 "must contain instruction offset");
3495 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL
3496 ? _load_ic_hi_node->_cbuf_insts_offset
3497 : _load_ic_node->_cbuf_insts_offset;
3498 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset);
3499 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr),
3500 "should be load from TOC");
3501 int method_index = resolved_method_index(cbuf);
3502 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
3503 }
3504
3505 // At this point I do not have the address of the trampoline stub,
3506 // and the entry point might be too far away for bl. Pc() serves
3507 // as dummy and bl will be patched later.
3508 __ bl((address) __ pc());
3509 __ post_call_nop();
3510 %}
3511
3512 // postalloc expand emitter for virtual calls.
3513 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{
3514
3515 // Create the nodes for loading the IC from the TOC.
3516 loadConLNodesTuple loadConLNodes_IC =
3517 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()),
3518 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num));
3519
3520 // Create the call node.
3521 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode();
3522 call->_method_handle_invoke = _method_handle_invoke;
3523 call->_vtable_index = _vtable_index;
3524 call->_method = _method;
3525 call->_optimized_virtual = _optimized_virtual;
3526 call->_tf = _tf;
3527 call->_entry_point = _entry_point;
3528 call->_cnt = _cnt;
3529 call->_guaranteed_safepoint = true;
3530 call->_oop_map = _oop_map;
3531 call->_jvms = _jvms;
3532 call->_jvmadj = _jvmadj;
3533 call->_in_rms = _in_rms;
3534 call->_nesting = _nesting;
3535 call->_override_symbolic_info = _override_symbolic_info;
3536 call->_arg_escape = _arg_escape;
3537
3538 // New call needs all inputs of old call.
3539 // Req...
3540 for (uint i = 0; i < req(); ++i) {
3541 // The expanded node does not need toc any more.
3542 // Add the inline cache constant here instead. This expresses the
3543 // register of the inline cache must be live at the call.
3544 // Else we would have to adapt JVMState by -1.
3545 if (i == mach_constant_base_node_input()) {
3546 call->add_req(loadConLNodes_IC._last);
3547 } else {
3548 call->add_req(in(i));
3549 }
3550 }
3551 // ...as well as prec
3552 for (uint i = req(); i < len(); ++i) {
3553 call->add_prec(in(i));
3554 }
3555
3556 // Remember nodes loading the inline cache into r19.
3557 call->_load_ic_hi_node = loadConLNodes_IC._large_hi;
3558 call->_load_ic_node = loadConLNodes_IC._small;
3559
3560 // Operands for new nodes.
3561 call->_opnds[0] = _opnds[0];
3562 call->_opnds[1] = _opnds[1];
3563
3564 // Only the inline cache is associated with a register.
3565 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19");
3566
3567 // Push new nodes.
3568 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi);
3569 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last);
3570 nodes->push(call);
3571 %}
3572
3573 // Compound version of call dynamic
3574 // Toc is only passed so that it can be used in ins_encode statement.
3575 // In the code we have to use $constanttablebase.
3576 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
3577 C2_MacroAssembler _masm(&cbuf);
3578 int start_offset = __ offset();
3579
3580 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC;
3581
3582 int vtable_index = this->_vtable_index;
3583 if (vtable_index < 0) {
3584 // Must be invalid_vtable_index, not nonvirtual_vtable_index.
3585 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value");
3586 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode());
3587
3588 // Virtual call relocation will point to ic load.
3589 address virtual_call_meta_addr = __ pc();
3590 // Load a clear inline cache.
3591 AddressLiteral empty_ic((address) Universe::non_oop_word());
3592 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true);
3593 if (!success) {
3594 ciEnv::current()->record_out_of_memory_failure();
3595 return;
3596 }
3597 // CALL to fixup routine. Fixup routine uses ScopeDesc info
3598 // to determine who we intended to call.
3599 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr));
3600 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none);
3601 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3602 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3603 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3604 } else {
3605 assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
3606 // Go thru the vtable. Get receiver klass. Receiver already
3607 // checked for non-null. If we'll go thru a C2I adapter, the
3608 // interpreter expects method in R19_method.
3609
3610 __ load_klass(R11_scratch1, R3);
3611
3612 int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index * vtableEntry::size_in_bytes();
3613 int v_off = entry_offset + in_bytes(vtableEntry::method_offset());
3614 __ li(R19_method, v_off);
3615 __ ldx(R19_method/*method*/, R19_method/*method offset*/, R11_scratch1/*class*/);
3616 // NOTE: for vtable dispatches, the vtable entry will never be
3617 // null. However it may very well end up in handle_wrong_method
3618 // if the method is abstract for the particular class.
3619 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method);
3620 // Call target. Either compiled code or C2I adapter.
3621 __ mtctr(R11_scratch1);
3622 __ bctrl();
3623 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3624 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
3625 }
3626 __ post_call_nop();
3627 %}
3628
3629 // a runtime call
3630 enc_class enc_java_to_runtime_call (method meth) %{
3631
3632 C2_MacroAssembler _masm(&cbuf);
3633 const address start_pc = __ pc();
3634
3635 #if defined(ABI_ELFv2)
3636 address entry= !($meth$$method) ? NULL : (address)$meth$$method;
3637 __ call_c(entry, relocInfo::runtime_call_type);
3638 __ post_call_nop();
3639 #else
3640 // The function we're going to call.
3641 FunctionDescriptor fdtemp;
3642 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3643
3644 Register Rtoc = R12_scratch2;
3645 // Calculate the method's TOC.
3646 __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3647 // Put entry, env, toc into the constant pool, this needs up to 3 constant
3648 // pool entries; call_c_using_toc will optimize the call.
3649 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3650 if (!success) {
3651 ciEnv::current()->record_out_of_memory_failure();
3652 return;
3653 }
3654 __ post_call_nop();
3655 #endif
3656
3657 // Check the ret_addr_offset.
3658 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc,
3659 "Fix constant in ret_addr_offset()");
3660 %}
3661
3662 // Move to ctr for leaf call.
3663 // This enc_class is needed so that scheduler gets proper
3664 // input mapping for latency computation.
3665 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3666 C2_MacroAssembler _masm(&cbuf);
3667 __ mtctr($src$$Register);
3668 %}
3669
3670 // Postalloc expand emitter for runtime leaf calls.
3671 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3672 loadConLNodesTuple loadConLNodes_Entry;
3673 #if defined(ABI_ELFv2)
3674 jlong entry_address = (jlong) this->entry_point();
3675 assert(entry_address, "need address here");
3676 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3677 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3678 #else
3679 // Get the struct that describes the function we are about to call.
3680 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3681 assert(fd, "need fd here");
3682 jlong entry_address = (jlong) fd->entry();
3683 // new nodes
3684 loadConLNodesTuple loadConLNodes_Env;
3685 loadConLNodesTuple loadConLNodes_Toc;
3686
3687 // Create nodes and operands for loading the entry point.
3688 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3689 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3690
3691
3692 // Create nodes and operands for loading the env pointer.
3693 if (fd->env() != NULL) {
3694 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3695 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3696 } else {
3697 loadConLNodes_Env._large_hi = NULL;
3698 loadConLNodes_Env._large_lo = NULL;
3699 loadConLNodes_Env._small = NULL;
3700 loadConLNodes_Env._last = new loadConL16Node();
3701 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3702 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3703 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3704 }
3705
3706 // Create nodes and operands for loading the Toc point.
3707 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3708 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3709 #endif // ABI_ELFv2
3710 // mtctr node
3711 MachNode *mtctr = new CallLeafDirect_mtctrNode();
3712
3713 assert(loadConLNodes_Entry._last != NULL, "entry must exist");
3714 mtctr->add_req(0, loadConLNodes_Entry._last);
3715
3716 mtctr->_opnds[0] = new iRegLdstOper();
3717 mtctr->_opnds[1] = new iRegLdstOper();
3718
3719 // call node
3720 MachCallLeafNode *call = new CallLeafDirectNode();
3721
3722 call->_opnds[0] = _opnds[0];
3723 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3724
3725 // Make the new call node look like the old one.
3726 call->_name = _name;
3727 call->_tf = _tf;
3728 call->_entry_point = _entry_point;
3729 call->_cnt = _cnt;
3730 call->_guaranteed_safepoint = false;
3731 call->_oop_map = _oop_map;
3732 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3733 call->_jvms = NULL;
3734 call->_jvmadj = _jvmadj;
3735 call->_in_rms = _in_rms;
3736 call->_nesting = _nesting;
3737
3738 // New call needs all inputs of old call.
3739 // Req...
3740 for (uint i = 0; i < req(); ++i) {
3741 if (i != mach_constant_base_node_input()) {
3742 call->add_req(in(i));
3743 }
3744 }
3745
3746 // These must be reqired edges, as the registers are live up to
3747 // the call. Else the constants are handled as kills.
3748 call->add_req(mtctr);
3749 #if !defined(ABI_ELFv2)
3750 call->add_req(loadConLNodes_Env._last);
3751 call->add_req(loadConLNodes_Toc._last);
3752 #endif
3753
3754 // ...as well as prec
3755 for (uint i = req(); i < len(); ++i) {
3756 call->add_prec(in(i));
3757 }
3758
3759 // registers
3760 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3761
3762 // Insert the new nodes.
3763 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3764 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last);
3765 #if !defined(ABI_ELFv2)
3766 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi);
3767 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last);
3768 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi);
3769 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last);
3770 #endif
3771 nodes->push(mtctr);
3772 nodes->push(call);
3773 %}
3774 %}
3775
3776 //----------FRAME--------------------------------------------------------------
3777 // Definition of frame structure and management information.
3778
3779 frame %{
3780 // These two registers define part of the calling convention between
3781 // compiled code and the interpreter.
3782
3783 // Inline Cache Register or method for I2C.
3784 inline_cache_reg(R19); // R19_method
3785
3786 // Optional: name the operand used by cisc-spilling to access
3787 // [stack_pointer + offset].
3788 cisc_spilling_operand_name(indOffset);
3789
3790 // Number of stack slots consumed by a Monitor enter.
3791 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size));
3792
3793 // Compiled code's Frame Pointer.
3794 frame_pointer(R1); // R1_SP
3795
3796 // Interpreter stores its frame pointer in a register which is
3797 // stored to the stack by I2CAdaptors. I2CAdaptors convert from
3798 // interpreted java to compiled java.
3799 //
3800 // R14_state holds pointer to caller's cInterpreter.
3801 interpreter_frame_pointer(R14); // R14_state
3802
3803 stack_alignment(frame::alignment_in_bytes);
3804
3805 // Number of outgoing stack slots killed above the
3806 // out_preserve_stack_slots for calls to C. Supports the var-args
3807 // backing area for register parms.
3808 //
3809 varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3810
3811 // The after-PROLOG location of the return address. Location of
3812 // return address specifies a type (REG or STACK) and a number
3813 // representing the register number (i.e. - use a register name) or
3814 // stack slot.
3815 //
3816 // A: Link register is stored in stack slot ...
3817 // M: ... but it's in the caller's frame according to PPC-64 ABI.
3818 // J: Therefore, we make sure that the link register is also in R11_scratch1
3819 // at the end of the prolog.
3820 // B: We use R20, now.
3821 //return_addr(REG R20);
3822
3823 // G: After reading the comments made by all the luminaries on their
3824 // failure to tell the compiler where the return address really is,
3825 // I hardly dare to try myself. However, I'm convinced it's in slot
3826 // 4 what apparently works and saves us some spills.
3827 return_addr(STACK 4);
3828
3829 // Location of native (C/C++) and interpreter return values. This
3830 // is specified to be the same as Java. In the 32-bit VM, long
3831 // values are actually returned from native calls in O0:O1 and
3832 // returned to the interpreter in I0:I1. The copying to and from
3833 // the register pairs is done by the appropriate call and epilog
3834 // opcodes. This simplifies the register allocator.
3835 c_return_value %{
3836 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3837 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0),
3838 "only return normal values");
3839 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3840 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3841 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3842 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3843 %}
3844
3845 // Location of compiled Java return values. Same as C
3846 return_value %{
3847 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3848 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0),
3849 "only return normal values");
3850 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL
3851 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num };
3852 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3853 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3854 %}
3855 %}
3856
3857
3858 //----------ATTRIBUTES---------------------------------------------------------
3859
3860 //----------Operand Attributes-------------------------------------------------
3861 op_attrib op_cost(1); // Required cost attribute.
3862
3863 //----------Instruction Attributes---------------------------------------------
3864
3865 // Cost attribute. required.
3866 ins_attrib ins_cost(DEFAULT_COST);
3867
3868 // Is this instruction a non-matching short branch variant of some
3869 // long branch? Not required.
3870 ins_attrib ins_short_branch(0);
3871
3872 ins_attrib ins_is_TrapBasedCheckNode(true);
3873
3874 // Number of constants.
3875 // This instruction uses the given number of constants
3876 // (optional attribute).
3877 // This is needed to determine in time whether the constant pool will
3878 // exceed 4000 entries. Before postalloc_expand the overall number of constants
3879 // is determined. It's also used to compute the constant pool size
3880 // in Output().
3881 ins_attrib ins_num_consts(0);
3882
3883 // Required alignment attribute (must be a power of 2) specifies the
3884 // alignment that some part of the instruction (not necessarily the
3885 // start) requires. If > 1, a compute_padding() function must be
3886 // provided for the instruction.
3887 ins_attrib ins_alignment(1);
3888
3889 // Enforce/prohibit rematerializations.
3890 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3891 // then rematerialization of that instruction is prohibited and the
3892 // instruction's value will be spilled if necessary.
3893 // Causes that MachNode::rematerialize() returns false.
3894 // - If an instruction is attributed with 'ins_should_rematerialize(true)'
3895 // then rematerialization should be enforced and a copy of the instruction
3896 // should be inserted if possible; rematerialization is not guaranteed.
3897 // Note: this may result in rematerializations in front of every use.
3898 // Causes that MachNode::rematerialize() can return true.
3899 // (optional attribute)
3900 ins_attrib ins_cannot_rematerialize(false);
3901 ins_attrib ins_should_rematerialize(false);
3902
3903 // Instruction has variable size depending on alignment.
3904 ins_attrib ins_variable_size_depending_on_alignment(false);
3905
3906 // Instruction is a nop.
3907 ins_attrib ins_is_nop(false);
3908
3909 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock).
3910 ins_attrib ins_use_mach_if_fast_lock_node(false);
3911
3912 // Field for the toc offset of a constant.
3913 //
3914 // This is needed if the toc offset is not encodable as an immediate in
3915 // the PPC load instruction. If so, the upper (hi) bits of the offset are
3916 // added to the toc, and from this a load with immediate is performed.
3917 // With postalloc expand, we get two nodes that require the same offset
3918 // but which don't know about each other. The offset is only known
3919 // when the constant is added to the constant pool during emitting.
3920 // It is generated in the 'hi'-node adding the upper bits, and saved
3921 // in this node. The 'lo'-node has a link to the 'hi'-node and reads
3922 // the offset from there when it gets encoded.
3923 ins_attrib ins_field_const_toc_offset(0);
3924 ins_attrib ins_field_const_toc_offset_hi_node(0);
3925
3926 // A field that can hold the instructions offset in the code buffer.
3927 // Set in the nodes emitter.
3928 ins_attrib ins_field_cbuf_insts_offset(-1);
3929
3930 // Fields for referencing a call's load-IC-node.
3931 // If the toc offset can not be encoded as an immediate in a load, we
3932 // use two nodes.
3933 ins_attrib ins_field_load_ic_hi_node(0);
3934 ins_attrib ins_field_load_ic_node(0);
3935
3936 //----------OPERANDS-----------------------------------------------------------
3937 // Operand definitions must precede instruction definitions for correct
3938 // parsing in the ADLC because operands constitute user defined types
3939 // which are used in instruction definitions.
3940 //
3941 // Formats are generated automatically for constants and base registers.
3942
3943 operand vecX() %{
3944 constraint(ALLOC_IN_RC(vs_reg));
3945 match(VecX);
3946
3947 format %{ %}
3948 interface(REG_INTER);
3949 %}
3950
3951 //----------Simple Operands----------------------------------------------------
3952 // Immediate Operands
3953
3954 // Integer Immediate: 32-bit
3955 operand immI() %{
3956 match(ConI);
3957 op_cost(40);
3958 format %{ %}
3959 interface(CONST_INTER);
3960 %}
3961
3962 operand immI8() %{
3963 predicate(Assembler::is_simm(n->get_int(), 8));
3964 op_cost(0);
3965 match(ConI);
3966 format %{ %}
3967 interface(CONST_INTER);
3968 %}
3969
3970 // Integer Immediate: 16-bit
3971 operand immI16() %{
3972 predicate(Assembler::is_simm(n->get_int(), 16));
3973 op_cost(0);
3974 match(ConI);
3975 format %{ %}
3976 interface(CONST_INTER);
3977 %}
3978
3979 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000.
3980 operand immIhi16() %{
3981 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0));
3982 match(ConI);
3983 op_cost(0);
3984 format %{ %}
3985 interface(CONST_INTER);
3986 %}
3987
3988 // Integer Immediate: 32-bit immediate for prefixed addi and load/store.
3989 operand immI32() %{
3990 predicate(PowerArchitecturePPC64 >= 10);
3991 op_cost(0);
3992 match(ConI);
3993 format %{ %}
3994 interface(CONST_INTER);
3995 %}
3996
3997 operand immInegpow2() %{
3998 predicate(is_power_of_2(-(juint)(n->get_int())));
3999 match(ConI);
4000 op_cost(0);
4001 format %{ %}
4002 interface(CONST_INTER);
4003 %}
4004
4005 operand immIpow2minus1() %{
4006 predicate(is_power_of_2((juint)(n->get_int()) + 1u));
4007 match(ConI);
4008 op_cost(0);
4009 format %{ %}
4010 interface(CONST_INTER);
4011 %}
4012
4013 operand immIpowerOf2() %{
4014 predicate(is_power_of_2((juint)(n->get_int())));
4015 match(ConI);
4016 op_cost(0);
4017 format %{ %}
4018 interface(CONST_INTER);
4019 %}
4020
4021 // Unsigned Integer Immediate: the values 0-31
4022 operand uimmI5() %{
4023 predicate(Assembler::is_uimm(n->get_int(), 5));
4024 match(ConI);
4025 op_cost(0);
4026 format %{ %}
4027 interface(CONST_INTER);
4028 %}
4029
4030 // Unsigned Integer Immediate: 6-bit
4031 operand uimmI6() %{
4032 predicate(Assembler::is_uimm(n->get_int(), 6));
4033 match(ConI);
4034 op_cost(0);
4035 format %{ %}
4036 interface(CONST_INTER);
4037 %}
4038
4039 // Unsigned Integer Immediate: 6-bit int, greater than 32
4040 operand uimmI6_ge32() %{
4041 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32);
4042 match(ConI);
4043 op_cost(0);
4044 format %{ %}
4045 interface(CONST_INTER);
4046 %}
4047
4048 // Unsigned Integer Immediate: 15-bit
4049 operand uimmI15() %{
4050 predicate(Assembler::is_uimm(n->get_int(), 15));
4051 match(ConI);
4052 op_cost(0);
4053 format %{ %}
4054 interface(CONST_INTER);
4055 %}
4056
4057 // Unsigned Integer Immediate: 16-bit
4058 operand uimmI16() %{
4059 predicate(Assembler::is_uimm(n->get_int(), 16));
4060 match(ConI);
4061 op_cost(0);
4062 format %{ %}
4063 interface(CONST_INTER);
4064 %}
4065
4066 // constant 'int 0'.
4067 operand immI_0() %{
4068 predicate(n->get_int() == 0);
4069 match(ConI);
4070 op_cost(0);
4071 format %{ %}
4072 interface(CONST_INTER);
4073 %}
4074
4075 // constant 'int 1'.
4076 operand immI_1() %{
4077 predicate(n->get_int() == 1);
4078 match(ConI);
4079 op_cost(0);
4080 format %{ %}
4081 interface(CONST_INTER);
4082 %}
4083
4084 // constant 'int -1'.
4085 operand immI_minus1() %{
4086 predicate(n->get_int() == -1);
4087 match(ConI);
4088 op_cost(0);
4089 format %{ %}
4090 interface(CONST_INTER);
4091 %}
4092
4093 // int value 16.
4094 operand immI_16() %{
4095 predicate(n->get_int() == 16);
4096 match(ConI);
4097 op_cost(0);
4098 format %{ %}
4099 interface(CONST_INTER);
4100 %}
4101
4102 // int value 24.
4103 operand immI_24() %{
4104 predicate(n->get_int() == 24);
4105 match(ConI);
4106 op_cost(0);
4107 format %{ %}
4108 interface(CONST_INTER);
4109 %}
4110
4111 // Compressed oops constants
4112 // Pointer Immediate
4113 operand immN() %{
4114 match(ConN);
4115
4116 op_cost(10);
4117 format %{ %}
4118 interface(CONST_INTER);
4119 %}
4120
4121 // NULL Pointer Immediate
4122 operand immN_0() %{
4123 predicate(n->get_narrowcon() == 0);
4124 match(ConN);
4125
4126 op_cost(0);
4127 format %{ %}
4128 interface(CONST_INTER);
4129 %}
4130
4131 // Compressed klass constants
4132 operand immNKlass() %{
4133 match(ConNKlass);
4134
4135 op_cost(0);
4136 format %{ %}
4137 interface(CONST_INTER);
4138 %}
4139
4140 // This operand can be used to avoid matching of an instruct
4141 // with chain rule.
4142 operand immNKlass_NM() %{
4143 match(ConNKlass);
4144 predicate(false);
4145 op_cost(0);
4146 format %{ %}
4147 interface(CONST_INTER);
4148 %}
4149
4150 // Pointer Immediate: 64-bit
4151 operand immP() %{
4152 match(ConP);
4153 op_cost(0);
4154 format %{ %}
4155 interface(CONST_INTER);
4156 %}
4157
4158 // Operand to avoid match of loadConP.
4159 // This operand can be used to avoid matching of an instruct
4160 // with chain rule.
4161 operand immP_NM() %{
4162 match(ConP);
4163 predicate(false);
4164 op_cost(0);
4165 format %{ %}
4166 interface(CONST_INTER);
4167 %}
4168
4169 // constant 'pointer 0'.
4170 operand immP_0() %{
4171 predicate(n->get_ptr() == 0);
4172 match(ConP);
4173 op_cost(0);
4174 format %{ %}
4175 interface(CONST_INTER);
4176 %}
4177
4178 // pointer 0x0 or 0x1
4179 operand immP_0or1() %{
4180 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
4181 match(ConP);
4182 op_cost(0);
4183 format %{ %}
4184 interface(CONST_INTER);
4185 %}
4186
4187 operand immL() %{
4188 match(ConL);
4189 op_cost(40);
4190 format %{ %}
4191 interface(CONST_INTER);
4192 %}
4193
4194 operand immLmax30() %{
4195 predicate((n->get_long() <= 30));
4196 match(ConL);
4197 op_cost(0);
4198 format %{ %}
4199 interface(CONST_INTER);
4200 %}
4201
4202 // Long Immediate: 16-bit
4203 operand immL16() %{
4204 predicate(Assembler::is_simm(n->get_long(), 16));
4205 match(ConL);
4206 op_cost(0);
4207 format %{ %}
4208 interface(CONST_INTER);
4209 %}
4210
4211 // Long Immediate: 16-bit, 4-aligned
4212 operand immL16Alg4() %{
4213 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
4214 match(ConL);
4215 op_cost(0);
4216 format %{ %}
4217 interface(CONST_INTER);
4218 %}
4219
4220 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
4221 operand immL32hi16() %{
4222 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L));
4223 match(ConL);
4224 op_cost(0);
4225 format %{ %}
4226 interface(CONST_INTER);
4227 %}
4228
4229 // Long Immediate: 32-bit
4230 operand immL32() %{
4231 predicate(Assembler::is_simm(n->get_long(), 32));
4232 match(ConL);
4233 op_cost(0);
4234 format %{ %}
4235 interface(CONST_INTER);
4236 %}
4237
4238 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store.
4239 operand immL34() %{
4240 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34));
4241 match(ConL);
4242 op_cost(0);
4243 format %{ %}
4244 interface(CONST_INTER);
4245 %}
4246
4247 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000.
4248 operand immLhighest16() %{
4249 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L);
4250 match(ConL);
4251 op_cost(0);
4252 format %{ %}
4253 interface(CONST_INTER);
4254 %}
4255
4256 operand immLnegpow2() %{
4257 predicate(is_power_of_2(-(julong)(n->get_long())));
4258 match(ConL);
4259 op_cost(0);
4260 format %{ %}
4261 interface(CONST_INTER);
4262 %}
4263
4264 operand immLpow2minus1() %{
4265 predicate(is_power_of_2((julong)(n->get_long()) + 1ull));
4266 match(ConL);
4267 op_cost(0);
4268 format %{ %}
4269 interface(CONST_INTER);
4270 %}
4271
4272 // constant 'long 0'.
4273 operand immL_0() %{
4274 predicate(n->get_long() == 0L);
4275 match(ConL);
4276 op_cost(0);
4277 format %{ %}
4278 interface(CONST_INTER);
4279 %}
4280
4281 // constat ' long -1'.
4282 operand immL_minus1() %{
4283 predicate(n->get_long() == -1L);
4284 match(ConL);
4285 op_cost(0);
4286 format %{ %}
4287 interface(CONST_INTER);
4288 %}
4289
4290 // Long Immediate: low 32-bit mask
4291 operand immL_32bits() %{
4292 predicate(n->get_long() == 0xFFFFFFFFL);
4293 match(ConL);
4294 op_cost(0);
4295 format %{ %}
4296 interface(CONST_INTER);
4297 %}
4298
4299 // Unsigned Long Immediate: 16-bit
4300 operand uimmL16() %{
4301 predicate(Assembler::is_uimm(n->get_long(), 16));
4302 match(ConL);
4303 op_cost(0);
4304 format %{ %}
4305 interface(CONST_INTER);
4306 %}
4307
4308 // Float Immediate
4309 operand immF() %{
4310 match(ConF);
4311 op_cost(40);
4312 format %{ %}
4313 interface(CONST_INTER);
4314 %}
4315
4316 // Float Immediate: +0.0f.
4317 operand immF_0() %{
4318 predicate(jint_cast(n->getf()) == 0);
4319 match(ConF);
4320
4321 op_cost(0);
4322 format %{ %}
4323 interface(CONST_INTER);
4324 %}
4325
4326 // Double Immediate
4327 operand immD() %{
4328 match(ConD);
4329 op_cost(40);
4330 format %{ %}
4331 interface(CONST_INTER);
4332 %}
4333
4334 // Double Immediate: +0.0d.
4335 operand immD_0() %{
4336 predicate(jlong_cast(n->getd()) == 0);
4337 match(ConD);
4338
4339 op_cost(0);
4340 format %{ %}
4341 interface(CONST_INTER);
4342 %}
4343
4344 // Integer Register Operands
4345 // Integer Destination Register
4346 // See definition of reg_class bits32_reg_rw.
4347 operand iRegIdst() %{
4348 constraint(ALLOC_IN_RC(bits32_reg_rw));
4349 match(RegI);
4350 match(rscratch1RegI);
4351 match(rscratch2RegI);
4352 match(rarg1RegI);
4353 match(rarg2RegI);
4354 match(rarg3RegI);
4355 match(rarg4RegI);
4356 format %{ %}
4357 interface(REG_INTER);
4358 %}
4359
4360 // Integer Source Register
4361 // See definition of reg_class bits32_reg_ro.
4362 operand iRegIsrc() %{
4363 constraint(ALLOC_IN_RC(bits32_reg_ro));
4364 match(RegI);
4365 match(rscratch1RegI);
4366 match(rscratch2RegI);
4367 match(rarg1RegI);
4368 match(rarg2RegI);
4369 match(rarg3RegI);
4370 match(rarg4RegI);
4371 format %{ %}
4372 interface(REG_INTER);
4373 %}
4374
4375 operand rscratch1RegI() %{
4376 constraint(ALLOC_IN_RC(rscratch1_bits32_reg));
4377 match(iRegIdst);
4378 format %{ %}
4379 interface(REG_INTER);
4380 %}
4381
4382 operand rscratch2RegI() %{
4383 constraint(ALLOC_IN_RC(rscratch2_bits32_reg));
4384 match(iRegIdst);
4385 format %{ %}
4386 interface(REG_INTER);
4387 %}
4388
4389 operand rarg1RegI() %{
4390 constraint(ALLOC_IN_RC(rarg1_bits32_reg));
4391 match(iRegIdst);
4392 format %{ %}
4393 interface(REG_INTER);
4394 %}
4395
4396 operand rarg2RegI() %{
4397 constraint(ALLOC_IN_RC(rarg2_bits32_reg));
4398 match(iRegIdst);
4399 format %{ %}
4400 interface(REG_INTER);
4401 %}
4402
4403 operand rarg3RegI() %{
4404 constraint(ALLOC_IN_RC(rarg3_bits32_reg));
4405 match(iRegIdst);
4406 format %{ %}
4407 interface(REG_INTER);
4408 %}
4409
4410 operand rarg4RegI() %{
4411 constraint(ALLOC_IN_RC(rarg4_bits32_reg));
4412 match(iRegIdst);
4413 format %{ %}
4414 interface(REG_INTER);
4415 %}
4416
4417 operand rarg1RegL() %{
4418 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4419 match(iRegLdst);
4420 format %{ %}
4421 interface(REG_INTER);
4422 %}
4423
4424 operand rarg2RegL() %{
4425 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4426 match(iRegLdst);
4427 format %{ %}
4428 interface(REG_INTER);
4429 %}
4430
4431 operand rarg3RegL() %{
4432 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4433 match(iRegLdst);
4434 format %{ %}
4435 interface(REG_INTER);
4436 %}
4437
4438 operand rarg4RegL() %{
4439 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4440 match(iRegLdst);
4441 format %{ %}
4442 interface(REG_INTER);
4443 %}
4444
4445 // Pointer Destination Register
4446 // See definition of reg_class bits64_reg_rw.
4447 operand iRegPdst() %{
4448 constraint(ALLOC_IN_RC(bits64_reg_rw));
4449 match(RegP);
4450 match(rscratch1RegP);
4451 match(rscratch2RegP);
4452 match(rarg1RegP);
4453 match(rarg2RegP);
4454 match(rarg3RegP);
4455 match(rarg4RegP);
4456 format %{ %}
4457 interface(REG_INTER);
4458 %}
4459
4460 // Pointer Destination Register
4461 // Operand not using r11 and r12 (killed in epilog).
4462 operand iRegPdstNoScratch() %{
4463 constraint(ALLOC_IN_RC(bits64_reg_leaf_call));
4464 match(RegP);
4465 match(rarg1RegP);
4466 match(rarg2RegP);
4467 match(rarg3RegP);
4468 match(rarg4RegP);
4469 format %{ %}
4470 interface(REG_INTER);
4471 %}
4472
4473 // Pointer Source Register
4474 // See definition of reg_class bits64_reg_ro.
4475 operand iRegPsrc() %{
4476 constraint(ALLOC_IN_RC(bits64_reg_ro));
4477 match(RegP);
4478 match(iRegPdst);
4479 match(rscratch1RegP);
4480 match(rscratch2RegP);
4481 match(rarg1RegP);
4482 match(rarg2RegP);
4483 match(rarg3RegP);
4484 match(rarg4RegP);
4485 match(threadRegP);
4486 format %{ %}
4487 interface(REG_INTER);
4488 %}
4489
4490 // Thread operand.
4491 operand threadRegP() %{
4492 constraint(ALLOC_IN_RC(thread_bits64_reg));
4493 match(iRegPdst);
4494 format %{ "R16" %}
4495 interface(REG_INTER);
4496 %}
4497
4498 operand rscratch1RegP() %{
4499 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4500 match(iRegPdst);
4501 format %{ "R11" %}
4502 interface(REG_INTER);
4503 %}
4504
4505 operand rscratch2RegP() %{
4506 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4507 match(iRegPdst);
4508 format %{ %}
4509 interface(REG_INTER);
4510 %}
4511
4512 operand rarg1RegP() %{
4513 constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4514 match(iRegPdst);
4515 format %{ %}
4516 interface(REG_INTER);
4517 %}
4518
4519 operand rarg2RegP() %{
4520 constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4521 match(iRegPdst);
4522 format %{ %}
4523 interface(REG_INTER);
4524 %}
4525
4526 operand rarg3RegP() %{
4527 constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4528 match(iRegPdst);
4529 format %{ %}
4530 interface(REG_INTER);
4531 %}
4532
4533 operand rarg4RegP() %{
4534 constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4535 match(iRegPdst);
4536 format %{ %}
4537 interface(REG_INTER);
4538 %}
4539
4540 operand iRegNsrc() %{
4541 constraint(ALLOC_IN_RC(bits32_reg_ro));
4542 match(RegN);
4543 match(iRegNdst);
4544
4545 format %{ %}
4546 interface(REG_INTER);
4547 %}
4548
4549 operand iRegNdst() %{
4550 constraint(ALLOC_IN_RC(bits32_reg_rw));
4551 match(RegN);
4552
4553 format %{ %}
4554 interface(REG_INTER);
4555 %}
4556
4557 // Long Destination Register
4558 // See definition of reg_class bits64_reg_rw.
4559 operand iRegLdst() %{
4560 constraint(ALLOC_IN_RC(bits64_reg_rw));
4561 match(RegL);
4562 match(rscratch1RegL);
4563 match(rscratch2RegL);
4564 format %{ %}
4565 interface(REG_INTER);
4566 %}
4567
4568 // Long Source Register
4569 // See definition of reg_class bits64_reg_ro.
4570 operand iRegLsrc() %{
4571 constraint(ALLOC_IN_RC(bits64_reg_ro));
4572 match(RegL);
4573 match(iRegLdst);
4574 match(rscratch1RegL);
4575 match(rscratch2RegL);
4576 format %{ %}
4577 interface(REG_INTER);
4578 %}
4579
4580 // Special operand for ConvL2I.
4581 operand iRegL2Isrc(iRegLsrc reg) %{
4582 constraint(ALLOC_IN_RC(bits64_reg_ro));
4583 match(ConvL2I reg);
4584 format %{ "ConvL2I($reg)" %}
4585 interface(REG_INTER)
4586 %}
4587
4588 operand rscratch1RegL() %{
4589 constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4590 match(RegL);
4591 format %{ %}
4592 interface(REG_INTER);
4593 %}
4594
4595 operand rscratch2RegL() %{
4596 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4597 match(RegL);
4598 format %{ %}
4599 interface(REG_INTER);
4600 %}
4601
4602 // Condition Code Flag Registers
4603 operand flagsReg() %{
4604 constraint(ALLOC_IN_RC(int_flags));
4605 match(RegFlags);
4606 format %{ %}
4607 interface(REG_INTER);
4608 %}
4609
4610 operand flagsRegSrc() %{
4611 constraint(ALLOC_IN_RC(int_flags_ro));
4612 match(RegFlags);
4613 match(flagsReg);
4614 match(flagsRegCR0);
4615 format %{ %}
4616 interface(REG_INTER);
4617 %}
4618
4619 // Condition Code Flag Register CR0
4620 operand flagsRegCR0() %{
4621 constraint(ALLOC_IN_RC(int_flags_CR0));
4622 match(RegFlags);
4623 format %{ "CR0" %}
4624 interface(REG_INTER);
4625 %}
4626
4627 operand flagsRegCR1() %{
4628 constraint(ALLOC_IN_RC(int_flags_CR1));
4629 match(RegFlags);
4630 format %{ "CR1" %}
4631 interface(REG_INTER);
4632 %}
4633
4634 operand flagsRegCR6() %{
4635 constraint(ALLOC_IN_RC(int_flags_CR6));
4636 match(RegFlags);
4637 format %{ "CR6" %}
4638 interface(REG_INTER);
4639 %}
4640
4641 operand regCTR() %{
4642 constraint(ALLOC_IN_RC(ctr_reg));
4643 // RegFlags should work. Introducing a RegSpecial type would cause a
4644 // lot of changes.
4645 match(RegFlags);
4646 format %{"SR_CTR" %}
4647 interface(REG_INTER);
4648 %}
4649
4650 operand regD() %{
4651 constraint(ALLOC_IN_RC(dbl_reg));
4652 match(RegD);
4653 format %{ %}
4654 interface(REG_INTER);
4655 %}
4656
4657 operand regF() %{
4658 constraint(ALLOC_IN_RC(flt_reg));
4659 match(RegF);
4660 format %{ %}
4661 interface(REG_INTER);
4662 %}
4663
4664 // Special Registers
4665
4666 // Method Register
4667 operand inline_cache_regP(iRegPdst reg) %{
4668 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg
4669 match(reg);
4670 format %{ %}
4671 interface(REG_INTER);
4672 %}
4673
4674 // Operands to remove register moves in unscaled mode.
4675 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4676 operand iRegP2N(iRegPsrc reg) %{
4677 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0);
4678 constraint(ALLOC_IN_RC(bits64_reg_ro));
4679 match(EncodeP reg);
4680 format %{ "$reg" %}
4681 interface(REG_INTER)
4682 %}
4683
4684 operand iRegN2P(iRegNsrc reg) %{
4685 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4686 constraint(ALLOC_IN_RC(bits32_reg_ro));
4687 match(DecodeN reg);
4688 format %{ "$reg" %}
4689 interface(REG_INTER)
4690 %}
4691
4692 operand iRegN2P_klass(iRegNsrc reg) %{
4693 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0);
4694 constraint(ALLOC_IN_RC(bits32_reg_ro));
4695 match(DecodeNKlass reg);
4696 format %{ "$reg" %}
4697 interface(REG_INTER)
4698 %}
4699
4700 //----------Complex Operands---------------------------------------------------
4701 // Indirect Memory Reference
4702 operand indirect(iRegPsrc reg) %{
4703 constraint(ALLOC_IN_RC(bits64_reg_ro));
4704 match(reg);
4705 op_cost(100);
4706 format %{ "[$reg]" %}
4707 interface(MEMORY_INTER) %{
4708 base($reg);
4709 index(0x0);
4710 scale(0x0);
4711 disp(0x0);
4712 %}
4713 %}
4714
4715 // Indirect with Offset
4716 operand indOffset16(iRegPsrc reg, immL16 offset) %{
4717 constraint(ALLOC_IN_RC(bits64_reg_ro));
4718 match(AddP reg offset);
4719 op_cost(100);
4720 format %{ "[$reg + $offset]" %}
4721 interface(MEMORY_INTER) %{
4722 base($reg);
4723 index(0x0);
4724 scale(0x0);
4725 disp($offset);
4726 %}
4727 %}
4728
4729 // Indirect with 4-aligned Offset
4730 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{
4731 constraint(ALLOC_IN_RC(bits64_reg_ro));
4732 match(AddP reg offset);
4733 op_cost(100);
4734 format %{ "[$reg + $offset]" %}
4735 interface(MEMORY_INTER) %{
4736 base($reg);
4737 index(0x0);
4738 scale(0x0);
4739 disp($offset);
4740 %}
4741 %}
4742
4743 //----------Complex Operands for Compressed OOPs-------------------------------
4744 // Compressed OOPs with narrow_oop_shift == 0.
4745
4746 // Indirect Memory Reference, compressed OOP
4747 operand indirectNarrow(iRegNsrc reg) %{
4748 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4749 constraint(ALLOC_IN_RC(bits64_reg_ro));
4750 match(DecodeN reg);
4751 op_cost(100);
4752 format %{ "[$reg]" %}
4753 interface(MEMORY_INTER) %{
4754 base($reg);
4755 index(0x0);
4756 scale(0x0);
4757 disp(0x0);
4758 %}
4759 %}
4760
4761 operand indirectNarrow_klass(iRegNsrc reg) %{
4762 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0);
4763 constraint(ALLOC_IN_RC(bits64_reg_ro));
4764 match(DecodeNKlass reg);
4765 op_cost(100);
4766 format %{ "[$reg]" %}
4767 interface(MEMORY_INTER) %{
4768 base($reg);
4769 index(0x0);
4770 scale(0x0);
4771 disp(0x0);
4772 %}
4773 %}
4774
4775 // Indirect with Offset, compressed OOP
4776 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4777 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4778 constraint(ALLOC_IN_RC(bits64_reg_ro));
4779 match(AddP (DecodeN reg) offset);
4780 op_cost(100);
4781 format %{ "[$reg + $offset]" %}
4782 interface(MEMORY_INTER) %{
4783 base($reg);
4784 index(0x0);
4785 scale(0x0);
4786 disp($offset);
4787 %}
4788 %}
4789
4790 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4791 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0);
4792 constraint(ALLOC_IN_RC(bits64_reg_ro));
4793 match(AddP (DecodeNKlass reg) offset);
4794 op_cost(100);
4795 format %{ "[$reg + $offset]" %}
4796 interface(MEMORY_INTER) %{
4797 base($reg);
4798 index(0x0);
4799 scale(0x0);
4800 disp($offset);
4801 %}
4802 %}
4803
4804 // Indirect with 4-aligned Offset, compressed OOP
4805 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4806 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4807 constraint(ALLOC_IN_RC(bits64_reg_ro));
4808 match(AddP (DecodeN reg) offset);
4809 op_cost(100);
4810 format %{ "[$reg + $offset]" %}
4811 interface(MEMORY_INTER) %{
4812 base($reg);
4813 index(0x0);
4814 scale(0x0);
4815 disp($offset);
4816 %}
4817 %}
4818
4819 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4820 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0);
4821 constraint(ALLOC_IN_RC(bits64_reg_ro));
4822 match(AddP (DecodeNKlass reg) offset);
4823 op_cost(100);
4824 format %{ "[$reg + $offset]" %}
4825 interface(MEMORY_INTER) %{
4826 base($reg);
4827 index(0x0);
4828 scale(0x0);
4829 disp($offset);
4830 %}
4831 %}
4832
4833 //----------Special Memory Operands--------------------------------------------
4834 // Stack Slot Operand
4835 //
4836 // This operand is used for loading and storing temporary values on
4837 // the stack where a match requires a value to flow through memory.
4838 operand stackSlotI(sRegI reg) %{
4839 constraint(ALLOC_IN_RC(stack_slots));
4840 op_cost(100);
4841 //match(RegI);
4842 format %{ "[sp+$reg]" %}
4843 interface(MEMORY_INTER) %{
4844 base(0x1); // R1_SP
4845 index(0x0);
4846 scale(0x0);
4847 disp($reg); // Stack Offset
4848 %}
4849 %}
4850
4851 operand stackSlotL(sRegL reg) %{
4852 constraint(ALLOC_IN_RC(stack_slots));
4853 op_cost(100);
4854 //match(RegL);
4855 format %{ "[sp+$reg]" %}
4856 interface(MEMORY_INTER) %{
4857 base(0x1); // R1_SP
4858 index(0x0);
4859 scale(0x0);
4860 disp($reg); // Stack Offset
4861 %}
4862 %}
4863
4864 operand stackSlotP(sRegP reg) %{
4865 constraint(ALLOC_IN_RC(stack_slots));
4866 op_cost(100);
4867 //match(RegP);
4868 format %{ "[sp+$reg]" %}
4869 interface(MEMORY_INTER) %{
4870 base(0x1); // R1_SP
4871 index(0x0);
4872 scale(0x0);
4873 disp($reg); // Stack Offset
4874 %}
4875 %}
4876
4877 operand stackSlotF(sRegF reg) %{
4878 constraint(ALLOC_IN_RC(stack_slots));
4879 op_cost(100);
4880 //match(RegF);
4881 format %{ "[sp+$reg]" %}
4882 interface(MEMORY_INTER) %{
4883 base(0x1); // R1_SP
4884 index(0x0);
4885 scale(0x0);
4886 disp($reg); // Stack Offset
4887 %}
4888 %}
4889
4890 operand stackSlotD(sRegD reg) %{
4891 constraint(ALLOC_IN_RC(stack_slots));
4892 op_cost(100);
4893 //match(RegD);
4894 format %{ "[sp+$reg]" %}
4895 interface(MEMORY_INTER) %{
4896 base(0x1); // R1_SP
4897 index(0x0);
4898 scale(0x0);
4899 disp($reg); // Stack Offset
4900 %}
4901 %}
4902
4903 // Operands for expressing Control Flow
4904 // NOTE: Label is a predefined operand which should not be redefined in
4905 // the AD file. It is generically handled within the ADLC.
4906
4907 //----------Conditional Branch Operands----------------------------------------
4908 // Comparison Op
4909 //
4910 // This is the operation of the comparison, and is limited to the
4911 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE
4912 // (!=).
4913 //
4914 // Other attributes of the comparison, such as unsignedness, are specified
4915 // by the comparison instruction that sets a condition code flags register.
4916 // That result is represented by a flags operand whose subtype is appropriate
4917 // to the unsignedness (etc.) of the comparison.
4918 //
4919 // Later, the instruction which matches both the Comparison Op (a Bool) and
4920 // the flags (produced by the Cmp) specifies the coding of the comparison op
4921 // by matching a specific subtype of Bool operand below.
4922
4923 // When used for floating point comparisons: unordered same as less.
4924 operand cmpOp() %{
4925 match(Bool);
4926 format %{ "" %}
4927 interface(COND_INTER) %{
4928 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'.
4929 // BO & BI
4930 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4931 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4932 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4933 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4934 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4935 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4936 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4937 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4938 %}
4939 %}
4940
4941 //----------OPERAND CLASSES----------------------------------------------------
4942 // Operand Classes are groups of operands that are used to simplify
4943 // instruction definitions by not requiring the AD writer to specify
4944 // separate instructions for every form of operand when the
4945 // instruction accepts multiple operand types with the same basic
4946 // encoding and format. The classic case of this is memory operands.
4947 // Indirect is not included since its use is limited to Compare & Swap.
4948
4949 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4950 // Memory operand where offsets are 4-aligned. Required for ld, std.
4951 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4952 opclass indirectMemory(indirect, indirectNarrow);
4953
4954 // Special opclass for I and ConvL2I.
4955 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4956
4957 // Operand classes to match encode and decode. iRegN_P2N is only used
4958 // for storeN. I have never seen an encode node elsewhere.
4959 opclass iRegN_P2N(iRegNsrc, iRegP2N);
4960 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4961
4962 //----------PIPELINE-----------------------------------------------------------
4963
4964 pipeline %{
4965
4966 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4967 // J. Res. & Dev., No. 1, Jan. 2002.
4968
4969 //----------ATTRIBUTES---------------------------------------------------------
4970 attributes %{
4971
4972 // Power4 instructions are of fixed length.
4973 fixed_size_instructions;
4974
4975 // TODO: if `bundle' means number of instructions fetched
4976 // per cycle, this is 8. If `bundle' means Power4 `group', that is
4977 // max instructions issued per cycle, this is 5.
4978 max_instructions_per_bundle = 8;
4979
4980 // A Power4 instruction is 4 bytes long.
4981 instruction_unit_size = 4;
4982
4983 // The Power4 processor fetches 64 bytes...
4984 instruction_fetch_unit_size = 64;
4985
4986 // ...in one line
4987 instruction_fetch_units = 1
4988
4989 // Unused, list one so that array generated by adlc is not empty.
4990 // Aix compiler chokes if _nop_count = 0.
4991 nops(fxNop);
4992 %}
4993
4994 //----------RESOURCES----------------------------------------------------------
4995 // Resources are the functional units available to the machine
4996 resources(
4997 PPC_BR, // branch unit
4998 PPC_CR, // condition unit
4999 PPC_FX1, // integer arithmetic unit 1
5000 PPC_FX2, // integer arithmetic unit 2
5001 PPC_LDST1, // load/store unit 1
5002 PPC_LDST2, // load/store unit 2
5003 PPC_FP1, // float arithmetic unit 1
5004 PPC_FP2, // float arithmetic unit 2
5005 PPC_LDST = PPC_LDST1 | PPC_LDST2,
5006 PPC_FX = PPC_FX1 | PPC_FX2,
5007 PPC_FP = PPC_FP1 | PPC_FP2
5008 );
5009
5010 //----------PIPELINE DESCRIPTION-----------------------------------------------
5011 // Pipeline Description specifies the stages in the machine's pipeline
5012 pipe_desc(
5013 // Power4 longest pipeline path
5014 PPC_IF, // instruction fetch
5015 PPC_IC,
5016 //PPC_BP, // branch prediction
5017 PPC_D0, // decode
5018 PPC_D1, // decode
5019 PPC_D2, // decode
5020 PPC_D3, // decode
5021 PPC_Xfer1,
5022 PPC_GD, // group definition
5023 PPC_MP, // map
5024 PPC_ISS, // issue
5025 PPC_RF, // resource fetch
5026 PPC_EX1, // execute (all units)
5027 PPC_EX2, // execute (FP, LDST)
5028 PPC_EX3, // execute (FP, LDST)
5029 PPC_EX4, // execute (FP)
5030 PPC_EX5, // execute (FP)
5031 PPC_EX6, // execute (FP)
5032 PPC_WB, // write back
5033 PPC_Xfer2,
5034 PPC_CP
5035 );
5036
5037 //----------PIPELINE CLASSES---------------------------------------------------
5038 // Pipeline Classes describe the stages in which input and output are
5039 // referenced by the hardware pipeline.
5040
5041 // Simple pipeline classes.
5042
5043 // Default pipeline class.
5044 pipe_class pipe_class_default() %{
5045 single_instruction;
5046 fixed_latency(2);
5047 %}
5048
5049 // Pipeline class for empty instructions.
5050 pipe_class pipe_class_empty() %{
5051 single_instruction;
5052 fixed_latency(0);
5053 %}
5054
5055 // Pipeline class for compares.
5056 pipe_class pipe_class_compare() %{
5057 single_instruction;
5058 fixed_latency(16);
5059 %}
5060
5061 // Pipeline class for traps.
5062 pipe_class pipe_class_trap() %{
5063 single_instruction;
5064 fixed_latency(100);
5065 %}
5066
5067 // Pipeline class for memory operations.
5068 pipe_class pipe_class_memory() %{
5069 single_instruction;
5070 fixed_latency(16);
5071 %}
5072
5073 // Pipeline class for call.
5074 pipe_class pipe_class_call() %{
5075 single_instruction;
5076 fixed_latency(100);
5077 %}
5078
5079 // Define the class for the Nop node.
5080 define %{
5081 MachNop = pipe_class_default;
5082 %}
5083
5084 %}
5085
5086 //----------INSTRUCTIONS-------------------------------------------------------
5087
5088 // Naming of instructions:
5089 // opA_operB / opA_operB_operC:
5090 // Operation 'op' with one or two source operands 'oper'. Result
5091 // type is A, source operand types are B and C.
5092 // Iff A == B == C, B and C are left out.
5093 //
5094 // The instructions are ordered according to the following scheme:
5095 // - loads
5096 // - load constants
5097 // - prefetch
5098 // - store
5099 // - encode/decode
5100 // - membar
5101 // - conditional moves
5102 // - compare & swap
5103 // - arithmetic and logic operations
5104 // * int: Add, Sub, Mul, Div, Mod
5105 // * int: lShift, arShift, urShift, rot
5106 // * float: Add, Sub, Mul, Div
5107 // * and, or, xor ...
5108 // - register moves: float <-> int, reg <-> stack, repl
5109 // - cast (high level type cast, XtoP, castPP, castII, not_null etc.
5110 // - conv (low level type cast requiring bit changes (sign extend etc)
5111 // - compares, range & zero checks.
5112 // - branches
5113 // - complex operations, intrinsics, min, max, replicate
5114 // - lock
5115 // - Calls
5116 //
5117 // If there are similar instructions with different types they are sorted:
5118 // int before float
5119 // small before big
5120 // signed before unsigned
5121 // e.g., loadS before loadUS before loadI before loadF.
5122
5123
5124 //----------Load/Store Instructions--------------------------------------------
5125
5126 //----------Load Instructions--------------------------------------------------
5127
5128 // Converts byte to int.
5129 // As convB2I_reg, but without match rule. The match rule of convB2I_reg
5130 // reuses the 'amount' operand, but adlc expects that operand specification
5131 // and operands in match rule are equivalent.
5132 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
5133 effect(DEF dst, USE src);
5134 format %{ "EXTSB $dst, $src \t// byte->int" %}
5135 size(4);
5136 ins_encode %{
5137 __ extsb($dst$$Register, $src$$Register);
5138 %}
5139 ins_pipe(pipe_class_default);
5140 %}
5141
5142 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{
5143 // match-rule, false predicate
5144 match(Set dst (LoadB mem));
5145 predicate(false);
5146
5147 format %{ "LBZ $dst, $mem" %}
5148 size(4);
5149 ins_encode( enc_lbz(dst, mem) );
5150 ins_pipe(pipe_class_memory);
5151 %}
5152
5153 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{
5154 // match-rule, false predicate
5155 match(Set dst (LoadB mem));
5156 predicate(false);
5157
5158 format %{ "LBZ $dst, $mem\n\t"
5159 "TWI $dst\n\t"
5160 "ISYNC" %}
5161 size(12);
5162 ins_encode( enc_lbz_ac(dst, mem) );
5163 ins_pipe(pipe_class_memory);
5164 %}
5165
5166 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
5167 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{
5168 match(Set dst (LoadB mem));
5169 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5170 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5171 expand %{
5172 iRegIdst tmp;
5173 loadUB_indirect(tmp, mem);
5174 convB2I_reg_2(dst, tmp);
5175 %}
5176 %}
5177
5178 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{
5179 match(Set dst (LoadB mem));
5180 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
5181 expand %{
5182 iRegIdst tmp;
5183 loadUB_indirect_ac(tmp, mem);
5184 convB2I_reg_2(dst, tmp);
5185 %}
5186 %}
5187
5188 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{
5189 // match-rule, false predicate
5190 match(Set dst (LoadB mem));
5191 predicate(false);
5192
5193 format %{ "LBZ $dst, $mem" %}
5194 size(4);
5195 ins_encode( enc_lbz(dst, mem) );
5196 ins_pipe(pipe_class_memory);
5197 %}
5198
5199 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{
5200 // match-rule, false predicate
5201 match(Set dst (LoadB mem));
5202 predicate(false);
5203
5204 format %{ "LBZ $dst, $mem\n\t"
5205 "TWI $dst\n\t"
5206 "ISYNC" %}
5207 size(12);
5208 ins_encode( enc_lbz_ac(dst, mem) );
5209 ins_pipe(pipe_class_memory);
5210 %}
5211
5212 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
5213 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{
5214 match(Set dst (LoadB mem));
5215 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5216 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5217
5218 expand %{
5219 iRegIdst tmp;
5220 loadUB_indOffset16(tmp, mem);
5221 convB2I_reg_2(dst, tmp);
5222 %}
5223 %}
5224
5225 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{
5226 match(Set dst (LoadB mem));
5227 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
5228
5229 expand %{
5230 iRegIdst tmp;
5231 loadUB_indOffset16_ac(tmp, mem);
5232 convB2I_reg_2(dst, tmp);
5233 %}
5234 %}
5235
5236 // Load Unsigned Byte (8bit UNsigned) into an int reg.
5237 instruct loadUB(iRegIdst dst, memory mem) %{
5238 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5239 match(Set dst (LoadUB mem));
5240 ins_cost(MEMORY_REF_COST);
5241
5242 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %}
5243 size(4);
5244 ins_encode( enc_lbz(dst, mem) );
5245 ins_pipe(pipe_class_memory);
5246 %}
5247
5248 // Load Unsigned Byte (8bit UNsigned) acquire.
5249 instruct loadUB_ac(iRegIdst dst, memory mem) %{
5250 match(Set dst (LoadUB mem));
5251 ins_cost(3*MEMORY_REF_COST);
5252
5253 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t"
5254 "TWI $dst\n\t"
5255 "ISYNC" %}
5256 size(12);
5257 ins_encode( enc_lbz_ac(dst, mem) );
5258 ins_pipe(pipe_class_memory);
5259 %}
5260
5261 // Load Unsigned Byte (8bit UNsigned) into a Long Register.
5262 instruct loadUB2L(iRegLdst dst, memory mem) %{
5263 match(Set dst (ConvI2L (LoadUB mem)));
5264 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5265 ins_cost(MEMORY_REF_COST);
5266
5267 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %}
5268 size(4);
5269 ins_encode( enc_lbz(dst, mem) );
5270 ins_pipe(pipe_class_memory);
5271 %}
5272
5273 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{
5274 match(Set dst (ConvI2L (LoadUB mem)));
5275 ins_cost(3*MEMORY_REF_COST);
5276
5277 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t"
5278 "TWI $dst\n\t"
5279 "ISYNC" %}
5280 size(12);
5281 ins_encode( enc_lbz_ac(dst, mem) );
5282 ins_pipe(pipe_class_memory);
5283 %}
5284
5285 // Load Short (16bit signed)
5286 instruct loadS(iRegIdst dst, memory mem) %{
5287 match(Set dst (LoadS mem));
5288 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5289 ins_cost(MEMORY_REF_COST);
5290
5291 format %{ "LHA $dst, $mem" %}
5292 size(4);
5293 ins_encode %{
5294 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5295 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
5296 %}
5297 ins_pipe(pipe_class_memory);
5298 %}
5299
5300 // Load Short (16bit signed) acquire.
5301 instruct loadS_ac(iRegIdst dst, memory mem) %{
5302 match(Set dst (LoadS mem));
5303 ins_cost(3*MEMORY_REF_COST);
5304
5305 format %{ "LHA $dst, $mem\t acquire\n\t"
5306 "TWI $dst\n\t"
5307 "ISYNC" %}
5308 size(12);
5309 ins_encode %{
5310 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5311 __ lha($dst$$Register, Idisp, $mem$$base$$Register);
5312 __ twi_0($dst$$Register);
5313 __ isync();
5314 %}
5315 ins_pipe(pipe_class_memory);
5316 %}
5317
5318 // Load Char (16bit unsigned)
5319 instruct loadUS(iRegIdst dst, memory mem) %{
5320 match(Set dst (LoadUS mem));
5321 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5322 ins_cost(MEMORY_REF_COST);
5323
5324 format %{ "LHZ $dst, $mem" %}
5325 size(4);
5326 ins_encode( enc_lhz(dst, mem) );
5327 ins_pipe(pipe_class_memory);
5328 %}
5329
5330 // Load Char (16bit unsigned) acquire.
5331 instruct loadUS_ac(iRegIdst dst, memory mem) %{
5332 match(Set dst (LoadUS mem));
5333 ins_cost(3*MEMORY_REF_COST);
5334
5335 format %{ "LHZ $dst, $mem \t// acquire\n\t"
5336 "TWI $dst\n\t"
5337 "ISYNC" %}
5338 size(12);
5339 ins_encode( enc_lhz_ac(dst, mem) );
5340 ins_pipe(pipe_class_memory);
5341 %}
5342
5343 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register.
5344 instruct loadUS2L(iRegLdst dst, memory mem) %{
5345 match(Set dst (ConvI2L (LoadUS mem)));
5346 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5347 ins_cost(MEMORY_REF_COST);
5348
5349 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %}
5350 size(4);
5351 ins_encode( enc_lhz(dst, mem) );
5352 ins_pipe(pipe_class_memory);
5353 %}
5354
5355 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire.
5356 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{
5357 match(Set dst (ConvI2L (LoadUS mem)));
5358 ins_cost(3*MEMORY_REF_COST);
5359
5360 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t"
5361 "TWI $dst\n\t"
5362 "ISYNC" %}
5363 size(12);
5364 ins_encode( enc_lhz_ac(dst, mem) );
5365 ins_pipe(pipe_class_memory);
5366 %}
5367
5368 // Load Integer.
5369 instruct loadI(iRegIdst dst, memory mem) %{
5370 match(Set dst (LoadI mem));
5371 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5372 ins_cost(MEMORY_REF_COST);
5373
5374 format %{ "LWZ $dst, $mem" %}
5375 size(4);
5376 ins_encode( enc_lwz(dst, mem) );
5377 ins_pipe(pipe_class_memory);
5378 %}
5379
5380 // Load Integer acquire.
5381 instruct loadI_ac(iRegIdst dst, memory mem) %{
5382 match(Set dst (LoadI mem));
5383 ins_cost(3*MEMORY_REF_COST);
5384
5385 format %{ "LWZ $dst, $mem \t// load acquire\n\t"
5386 "TWI $dst\n\t"
5387 "ISYNC" %}
5388 size(12);
5389 ins_encode( enc_lwz_ac(dst, mem) );
5390 ins_pipe(pipe_class_memory);
5391 %}
5392
5393 // Match loading integer and casting it to unsigned int in
5394 // long register.
5395 // LoadI + ConvI2L + AndL 0xffffffff.
5396 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
5397 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5398 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered());
5399 ins_cost(MEMORY_REF_COST);
5400
5401 format %{ "LWZ $dst, $mem \t// zero-extend to long" %}
5402 size(4);
5403 ins_encode( enc_lwz(dst, mem) );
5404 ins_pipe(pipe_class_memory);
5405 %}
5406
5407 // Match loading integer and casting it to long.
5408 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
5409 match(Set dst (ConvI2L (LoadI mem)));
5410 predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5411 ins_cost(MEMORY_REF_COST);
5412
5413 format %{ "LWA $dst, $mem \t// loadI2L" %}
5414 size(4);
5415 ins_encode %{
5416 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5417 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5418 %}
5419 ins_pipe(pipe_class_memory);
5420 %}
5421
5422 // Match loading integer and casting it to long - acquire.
5423 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
5424 match(Set dst (ConvI2L (LoadI mem)));
5425 ins_cost(3*MEMORY_REF_COST);
5426
5427 format %{ "LWA $dst, $mem \t// loadI2L acquire"
5428 "TWI $dst\n\t"
5429 "ISYNC" %}
5430 size(12);
5431 ins_encode %{
5432 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5433 __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5434 __ twi_0($dst$$Register);
5435 __ isync();
5436 %}
5437 ins_pipe(pipe_class_memory);
5438 %}
5439
5440 // Load Long - aligned
5441 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{
5442 match(Set dst (LoadL mem));
5443 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5444 ins_cost(MEMORY_REF_COST);
5445
5446 format %{ "LD $dst, $mem \t// long" %}
5447 size(4);
5448 ins_encode( enc_ld(dst, mem) );
5449 ins_pipe(pipe_class_memory);
5450 %}
5451
5452 // Load Long - aligned acquire.
5453 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{
5454 match(Set dst (LoadL mem));
5455 ins_cost(3*MEMORY_REF_COST);
5456
5457 format %{ "LD $dst, $mem \t// long acquire\n\t"
5458 "TWI $dst\n\t"
5459 "ISYNC" %}
5460 size(12);
5461 ins_encode( enc_ld_ac(dst, mem) );
5462 ins_pipe(pipe_class_memory);
5463 %}
5464
5465 // Load Long - UNaligned
5466 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{
5467 match(Set dst (LoadL_unaligned mem));
5468 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5469 ins_cost(MEMORY_REF_COST);
5470
5471 format %{ "LD $dst, $mem \t// unaligned long" %}
5472 size(4);
5473 ins_encode( enc_ld(dst, mem) );
5474 ins_pipe(pipe_class_memory);
5475 %}
5476
5477 // Load nodes for superwords
5478
5479 // Load Aligned Packed Byte
5480 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{
5481 predicate(n->as_LoadVector()->memory_size() == 8);
5482 match(Set dst (LoadVector mem));
5483 ins_cost(MEMORY_REF_COST);
5484
5485 format %{ "LD $dst, $mem \t// load 8-byte Vector" %}
5486 size(4);
5487 ins_encode( enc_ld(dst, mem) );
5488 ins_pipe(pipe_class_memory);
5489 %}
5490
5491 // Load Aligned Packed Byte
5492 instruct loadV16(vecX dst, indirect mem) %{
5493 predicate(n->as_LoadVector()->memory_size() == 16);
5494 match(Set dst (LoadVector mem));
5495 ins_cost(MEMORY_REF_COST);
5496
5497 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %}
5498 size(4);
5499 ins_encode %{
5500 __ lxvd2x($dst$$VectorSRegister, $mem$$Register);
5501 %}
5502 ins_pipe(pipe_class_default);
5503 %}
5504
5505 // Load Range, range = array length (=jint)
5506 instruct loadRange(iRegIdst dst, memory mem) %{
5507 match(Set dst (LoadRange mem));
5508 ins_cost(MEMORY_REF_COST);
5509
5510 format %{ "LWZ $dst, $mem \t// range" %}
5511 size(4);
5512 ins_encode( enc_lwz(dst, mem) );
5513 ins_pipe(pipe_class_memory);
5514 %}
5515
5516 // Load Compressed Pointer
5517 instruct loadN(iRegNdst dst, memory mem) %{
5518 match(Set dst (LoadN mem));
5519 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5520 ins_cost(MEMORY_REF_COST);
5521
5522 format %{ "LWZ $dst, $mem \t// load compressed ptr" %}
5523 size(4);
5524 ins_encode( enc_lwz(dst, mem) );
5525 ins_pipe(pipe_class_memory);
5526 %}
5527
5528 // Load Compressed Pointer acquire.
5529 instruct loadN_ac(iRegNdst dst, memory mem) %{
5530 match(Set dst (LoadN mem));
5531 ins_cost(3*MEMORY_REF_COST);
5532
5533 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5534 "TWI $dst\n\t"
5535 "ISYNC" %}
5536 size(12);
5537 ins_encode( enc_lwz_ac(dst, mem) );
5538 ins_pipe(pipe_class_memory);
5539 %}
5540
5541 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5542 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5543 match(Set dst (DecodeN (LoadN mem)));
5544 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0);
5545 ins_cost(MEMORY_REF_COST);
5546
5547 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5548 size(4);
5549 ins_encode( enc_lwz(dst, mem) );
5550 ins_pipe(pipe_class_memory);
5551 %}
5552
5553 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5554 match(Set dst (DecodeNKlass (LoadNKlass mem)));
5555 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0 &&
5556 _kids[0]->_leaf->as_Load()->is_unordered());
5557 ins_cost(MEMORY_REF_COST);
5558
5559 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5560 size(4);
5561 ins_encode( enc_lwz(dst, mem) );
5562 ins_pipe(pipe_class_memory);
5563 %}
5564
5565 // Load Pointer
5566 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5567 match(Set dst (LoadP mem));
5568 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0);
5569 ins_cost(MEMORY_REF_COST);
5570
5571 format %{ "LD $dst, $mem \t// ptr" %}
5572 size(4);
5573 ins_encode( enc_ld(dst, mem) );
5574 ins_pipe(pipe_class_memory);
5575 %}
5576
5577 // Load Pointer acquire.
5578 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5579 match(Set dst (LoadP mem));
5580 ins_cost(3*MEMORY_REF_COST);
5581
5582 predicate(n->as_Load()->barrier_data() == 0);
5583
5584 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5585 "TWI $dst\n\t"
5586 "ISYNC" %}
5587 size(12);
5588 ins_encode( enc_ld_ac(dst, mem) );
5589 ins_pipe(pipe_class_memory);
5590 %}
5591
5592 // LoadP + CastP2L
5593 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
5594 match(Set dst (CastP2X (LoadP mem)));
5595 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0);
5596 ins_cost(MEMORY_REF_COST);
5597
5598 format %{ "LD $dst, $mem \t// ptr + p2x" %}
5599 size(4);
5600 ins_encode( enc_ld(dst, mem) );
5601 ins_pipe(pipe_class_memory);
5602 %}
5603
5604 // Load compressed klass pointer.
5605 instruct loadNKlass(iRegNdst dst, memory mem) %{
5606 match(Set dst (LoadNKlass mem));
5607 ins_cost(MEMORY_REF_COST);
5608
5609 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %}
5610 size(4);
5611 ins_encode( enc_lwz(dst, mem) );
5612 ins_pipe(pipe_class_memory);
5613 %}
5614
5615 // Load Klass Pointer
5616 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
5617 match(Set dst (LoadKlass mem));
5618 ins_cost(MEMORY_REF_COST);
5619
5620 format %{ "LD $dst, $mem \t// klass ptr" %}
5621 size(4);
5622 ins_encode( enc_ld(dst, mem) );
5623 ins_pipe(pipe_class_memory);
5624 %}
5625
5626 // Load Float
5627 instruct loadF(regF dst, memory mem) %{
5628 match(Set dst (LoadF mem));
5629 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5630 ins_cost(MEMORY_REF_COST);
5631
5632 format %{ "LFS $dst, $mem" %}
5633 size(4);
5634 ins_encode %{
5635 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5636 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5637 %}
5638 ins_pipe(pipe_class_memory);
5639 %}
5640
5641 // Load Float acquire.
5642 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5643 match(Set dst (LoadF mem));
5644 effect(TEMP cr0);
5645 ins_cost(3*MEMORY_REF_COST);
5646
5647 format %{ "LFS $dst, $mem \t// acquire\n\t"
5648 "FCMPU cr0, $dst, $dst\n\t"
5649 "BNE cr0, next\n"
5650 "next:\n\t"
5651 "ISYNC" %}
5652 size(16);
5653 ins_encode %{
5654 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5655 Label next;
5656 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5657 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister);
5658 __ bne(CCR0, next);
5659 __ bind(next);
5660 __ isync();
5661 %}
5662 ins_pipe(pipe_class_memory);
5663 %}
5664
5665 // Load Double - aligned
5666 instruct loadD(regD dst, memory mem) %{
5667 match(Set dst (LoadD mem));
5668 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5669 ins_cost(MEMORY_REF_COST);
5670
5671 format %{ "LFD $dst, $mem" %}
5672 size(4);
5673 ins_encode( enc_lfd(dst, mem) );
5674 ins_pipe(pipe_class_memory);
5675 %}
5676
5677 // Load Double - aligned acquire.
5678 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5679 match(Set dst (LoadD mem));
5680 effect(TEMP cr0);
5681 ins_cost(3*MEMORY_REF_COST);
5682
5683 format %{ "LFD $dst, $mem \t// acquire\n\t"
5684 "FCMPU cr0, $dst, $dst\n\t"
5685 "BNE cr0, next\n"
5686 "next:\n\t"
5687 "ISYNC" %}
5688 size(16);
5689 ins_encode %{
5690 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5691 Label next;
5692 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5693 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister);
5694 __ bne(CCR0, next);
5695 __ bind(next);
5696 __ isync();
5697 %}
5698 ins_pipe(pipe_class_memory);
5699 %}
5700
5701 // Load Double - UNaligned
5702 instruct loadD_unaligned(regD dst, memory mem) %{
5703 match(Set dst (LoadD_unaligned mem));
5704 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5705 ins_cost(MEMORY_REF_COST);
5706
5707 format %{ "LFD $dst, $mem" %}
5708 size(4);
5709 ins_encode( enc_lfd(dst, mem) );
5710 ins_pipe(pipe_class_memory);
5711 %}
5712
5713 //----------Constants--------------------------------------------------------
5714
5715 // Load MachConstantTableBase: add hi offset to global toc.
5716 // TODO: Handle hidden register r29 in bundler!
5717 instruct loadToc_hi(iRegLdst dst) %{
5718 effect(DEF dst);
5719 ins_cost(DEFAULT_COST);
5720
5721 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %}
5722 size(4);
5723 ins_encode %{
5724 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
5725 %}
5726 ins_pipe(pipe_class_default);
5727 %}
5728
5729 // Load MachConstantTableBase: add lo offset to global toc.
5730 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
5731 effect(DEF dst, USE src);
5732 ins_cost(DEFAULT_COST);
5733
5734 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %}
5735 size(4);
5736 ins_encode %{
5737 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
5738 %}
5739 ins_pipe(pipe_class_default);
5740 %}
5741
5742 // Load 16-bit integer constant 0xssss????
5743 instruct loadConI16(iRegIdst dst, immI16 src) %{
5744 match(Set dst src);
5745
5746 format %{ "LI $dst, $src" %}
5747 size(4);
5748 ins_encode %{
5749 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5750 %}
5751 ins_pipe(pipe_class_default);
5752 %}
5753
5754 // Load integer constant 0x????0000
5755 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
5756 match(Set dst src);
5757 ins_cost(DEFAULT_COST);
5758
5759 format %{ "LIS $dst, $src.hi" %}
5760 size(4);
5761 ins_encode %{
5762 // Lis sign extends 16-bit src then shifts it 16 bit to the left.
5763 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5764 %}
5765 ins_pipe(pipe_class_default);
5766 %}
5767
5768 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted
5769 // and sign extended), this adds the low 16 bits.
5770 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
5771 // no match-rule, false predicate
5772 effect(DEF dst, USE src1, USE src2);
5773 predicate(false);
5774
5775 format %{ "ORI $dst, $src1.hi, $src2.lo" %}
5776 size(4);
5777 ins_encode %{
5778 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5779 %}
5780 ins_pipe(pipe_class_default);
5781 %}
5782
5783 instruct loadConI32(iRegIdst dst, immI32 src) %{
5784 match(Set dst src);
5785 // This macro is valid only in Power 10 and up, but adding the following predicate here
5786 // caused a build error, so we comment it out for now.
5787 // predicate(PowerArchitecturePPC64 >= 10);
5788 ins_cost(DEFAULT_COST+1);
5789
5790 format %{ "PLI $dst, $src" %}
5791 size(8);
5792 ins_encode %{
5793 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5794 __ pli($dst$$Register, $src$$constant);
5795 %}
5796 ins_pipe(pipe_class_default);
5797 ins_alignment(2);
5798 %}
5799
5800 instruct loadConI_Ex(iRegIdst dst, immI src) %{
5801 match(Set dst src);
5802 ins_cost(DEFAULT_COST*2);
5803
5804 expand %{
5805 // Would like to use $src$$constant.
5806 immI16 srcLo %{ _opnds[1]->constant() %}
5807 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5808 immIhi16 srcHi %{ _opnds[1]->constant() %}
5809 iRegIdst tmpI;
5810 loadConIhi16(tmpI, srcHi);
5811 loadConI32_lo16(dst, tmpI, srcLo);
5812 %}
5813 %}
5814
5815 // No constant pool entries required.
5816 instruct loadConL16(iRegLdst dst, immL16 src) %{
5817 match(Set dst src);
5818
5819 format %{ "LI $dst, $src \t// long" %}
5820 size(4);
5821 ins_encode %{
5822 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
5823 %}
5824 ins_pipe(pipe_class_default);
5825 %}
5826
5827 // Load long constant 0xssssssss????0000
5828 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
5829 match(Set dst src);
5830 ins_cost(DEFAULT_COST);
5831
5832 format %{ "LIS $dst, $src.hi \t// long" %}
5833 size(4);
5834 ins_encode %{
5835 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5836 %}
5837 ins_pipe(pipe_class_default);
5838 %}
5839
5840 // To load a 32 bit constant: merge lower 16 bits into already loaded
5841 // high 16 bits.
5842 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
5843 // no match-rule, false predicate
5844 effect(DEF dst, USE src1, USE src2);
5845 predicate(false);
5846
5847 format %{ "ORI $dst, $src1, $src2.lo" %}
5848 size(4);
5849 ins_encode %{
5850 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5851 %}
5852 ins_pipe(pipe_class_default);
5853 %}
5854
5855 // Load 32-bit long constant
5856 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{
5857 match(Set dst src);
5858 ins_cost(DEFAULT_COST*2);
5859
5860 expand %{
5861 // Would like to use $src$$constant.
5862 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%}
5863 // srcHi can be 0000 if srcLo sign-extends to a negative number.
5864 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%}
5865 iRegLdst tmpL;
5866 loadConL32hi16(tmpL, srcHi);
5867 loadConL32_lo16(dst, tmpL, srcLo);
5868 %}
5869 %}
5870
5871 // Load 34-bit long constant using prefixed addi. No constant pool entries required.
5872 instruct loadConL34(iRegLdst dst, immL34 src) %{
5873 match(Set dst src);
5874 // This macro is valid only in Power 10 and up, but adding the following predicate here
5875 // caused a build error, so we comment it out for now.
5876 // predicate(PowerArchitecturePPC64 >= 10);
5877 ins_cost(DEFAULT_COST+1);
5878
5879 format %{ "PLI $dst, $src \t// long" %}
5880 size(8);
5881 ins_encode %{
5882 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
5883 __ pli($dst$$Register, $src$$constant);
5884 %}
5885 ins_pipe(pipe_class_default);
5886 ins_alignment(2);
5887 %}
5888
5889 // Load long constant 0x????000000000000.
5890 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{
5891 match(Set dst src);
5892 ins_cost(DEFAULT_COST);
5893
5894 expand %{
5895 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%}
5896 immI shift32 %{ 32 %}
5897 iRegLdst tmpL;
5898 loadConL32hi16(tmpL, srcHi);
5899 lshiftL_regL_immI(dst, tmpL, shift32);
5900 %}
5901 %}
5902
5903 // Expand node for constant pool load: small offset.
5904 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{
5905 effect(DEF dst, USE src, USE toc);
5906 ins_cost(MEMORY_REF_COST);
5907
5908 ins_num_consts(1);
5909 // Needed so that CallDynamicJavaDirect can compute the address of this
5910 // instruction for relocation.
5911 ins_field_cbuf_insts_offset(int);
5912
5913 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %}
5914 size(4);
5915 ins_encode( enc_load_long_constL(dst, src, toc) );
5916 ins_pipe(pipe_class_memory);
5917 %}
5918
5919 // Expand node for constant pool load: large offset.
5920 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{
5921 effect(DEF dst, USE src, USE toc);
5922 predicate(false);
5923
5924 ins_num_consts(1);
5925 ins_field_const_toc_offset(int);
5926 // Needed so that CallDynamicJavaDirect can compute the address of this
5927 // instruction for relocation.
5928 ins_field_cbuf_insts_offset(int);
5929
5930 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %}
5931 size(4);
5932 ins_encode( enc_load_long_constL_hi(dst, toc, src) );
5933 ins_pipe(pipe_class_default);
5934 %}
5935
5936 // Expand node for constant pool load: large offset.
5937 // No constant pool entries required.
5938 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
5939 effect(DEF dst, USE src, USE base);
5940 predicate(false);
5941
5942 ins_field_const_toc_offset_hi_node(loadConL_hiNode*);
5943
5944 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %}
5945 size(4);
5946 ins_encode %{
5947 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5948 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5949 %}
5950 ins_pipe(pipe_class_memory);
5951 %}
5952
5953 // Load long constant from constant table. Expand in case of
5954 // offset > 16 bit is needed.
5955 // Adlc adds toc node MachConstantTableBase.
5956 instruct loadConL_Ex(iRegLdst dst, immL src) %{
5957 match(Set dst src);
5958 ins_cost(MEMORY_REF_COST);
5959
5960 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %}
5961 // We can not inline the enc_class for the expand as that does not support constanttablebase.
5962 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) );
5963 %}
5964
5965 // Load NULL as compressed oop.
5966 instruct loadConN0(iRegNdst dst, immN_0 src) %{
5967 match(Set dst src);
5968 ins_cost(DEFAULT_COST);
5969
5970 format %{ "LI $dst, $src \t// compressed ptr" %}
5971 size(4);
5972 ins_encode %{
5973 __ li($dst$$Register, 0);
5974 %}
5975 ins_pipe(pipe_class_default);
5976 %}
5977
5978 // Load hi part of compressed oop constant.
5979 instruct loadConN_hi(iRegNdst dst, immN src) %{
5980 effect(DEF dst, USE src);
5981 ins_cost(DEFAULT_COST);
5982
5983 format %{ "LIS $dst, $src \t// narrow oop hi" %}
5984 size(4);
5985 ins_encode %{
5986 __ lis($dst$$Register, 0); // Will get patched.
5987 %}
5988 ins_pipe(pipe_class_default);
5989 %}
5990
5991 // Add lo part of compressed oop constant to already loaded hi part.
5992 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
5993 effect(DEF dst, USE src1, USE src2);
5994 ins_cost(DEFAULT_COST);
5995
5996 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %}
5997 size(4);
5998 ins_encode %{
5999 AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant);
6000 __ relocate(addrlit.rspec(), /*compressed format*/ 1);
6001 __ ori($dst$$Register, $src1$$Register, 0); // Will get patched.
6002 %}
6003 ins_pipe(pipe_class_default);
6004 %}
6005
6006 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
6007 effect(DEF dst, USE src, USE shift, USE mask_begin);
6008
6009 size(4);
6010 ins_encode %{
6011 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
6012 %}
6013 ins_pipe(pipe_class_default);
6014 %}
6015
6016 // Needed to postalloc expand loadConN: ConN is loaded as ConI
6017 // leaving the upper 32 bits with sign-extension bits.
6018 // This clears these bits: dst = src & 0xFFFFFFFF.
6019 // TODO: Eventually call this maskN_regN_FFFFFFFF.
6020 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
6021 effect(DEF dst, USE src);
6022 predicate(false);
6023
6024 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
6025 size(4);
6026 ins_encode %{
6027 __ clrldi($dst$$Register, $src$$Register, 0x20);
6028 %}
6029 ins_pipe(pipe_class_default);
6030 %}
6031
6032 // Optimize DecodeN for disjoint base.
6033 // Load base of compressed oops into a register
6034 instruct loadBase(iRegLdst dst) %{
6035 effect(DEF dst);
6036
6037 format %{ "LoadConst $dst, heapbase" %}
6038 ins_encode %{
6039 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0);
6040 %}
6041 ins_pipe(pipe_class_default);
6042 %}
6043
6044 // Loading ConN must be postalloc expanded so that edges between
6045 // the nodes are safe. They may not interfere with a safepoint.
6046 // GL TODO: This needs three instructions: better put this into the constant pool.
6047 instruct loadConN_Ex(iRegNdst dst, immN src) %{
6048 match(Set dst src);
6049 ins_cost(DEFAULT_COST*2);
6050
6051 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6052 postalloc_expand %{
6053 MachNode *m1 = new loadConN_hiNode();
6054 MachNode *m2 = new loadConN_loNode();
6055 MachNode *m3 = new clearMs32bNode();
6056 m1->add_req(NULL);
6057 m2->add_req(NULL, m1);
6058 m3->add_req(NULL, m2);
6059 m1->_opnds[0] = op_dst;
6060 m1->_opnds[1] = op_src;
6061 m2->_opnds[0] = op_dst;
6062 m2->_opnds[1] = op_dst;
6063 m2->_opnds[2] = op_src;
6064 m3->_opnds[0] = op_dst;
6065 m3->_opnds[1] = op_dst;
6066 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6067 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6068 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6069 nodes->push(m1);
6070 nodes->push(m2);
6071 nodes->push(m3);
6072 %}
6073 %}
6074
6075 // We have seen a safepoint between the hi and lo parts, and this node was handled
6076 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is
6077 // not a narrow oop.
6078 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
6079 match(Set dst src);
6080 effect(DEF dst, USE src);
6081 ins_cost(DEFAULT_COST);
6082
6083 format %{ "LIS $dst, $src \t// narrow klass hi" %}
6084 size(4);
6085 ins_encode %{
6086 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant);
6087 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
6088 %}
6089 ins_pipe(pipe_class_default);
6090 %}
6091
6092 // As loadConNKlass_hi this must be recognized as narrow klass, not oop!
6093 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
6094 match(Set dst src1);
6095 effect(TEMP src2);
6096 ins_cost(DEFAULT_COST);
6097
6098 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
6099 size(4);
6100 ins_encode %{
6101 __ clrldi($dst$$Register, $src2$$Register, 0x20);
6102 %}
6103 ins_pipe(pipe_class_default);
6104 %}
6105
6106 // This needs a match rule so that build_oop_map knows this is
6107 // not a narrow oop.
6108 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
6109 match(Set dst src1);
6110 effect(TEMP src2);
6111 ins_cost(DEFAULT_COST);
6112
6113 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
6114 size(4);
6115 ins_encode %{
6116 // Notify OOP recorder (don't need the relocation)
6117 AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant);
6118 intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value());
6119 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
6120 %}
6121 ins_pipe(pipe_class_default);
6122 %}
6123
6124 // Loading ConNKlass must be postalloc expanded so that edges between
6125 // the nodes are safe. They may not interfere with a safepoint.
6126 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
6127 match(Set dst src);
6128 ins_cost(DEFAULT_COST*2);
6129
6130 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6131 postalloc_expand %{
6132 // Load high bits into register. Sign extended.
6133 MachNode *m1 = new loadConNKlass_hiNode();
6134 m1->add_req(NULL);
6135 m1->_opnds[0] = op_dst;
6136 m1->_opnds[1] = op_src;
6137 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6138 nodes->push(m1);
6139
6140 MachNode *m2 = m1;
6141 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) {
6142 // Value might be 1-extended. Mask out these bits.
6143 m2 = new loadConNKlass_maskNode();
6144 m2->add_req(NULL, m1);
6145 m2->_opnds[0] = op_dst;
6146 m2->_opnds[1] = op_src;
6147 m2->_opnds[2] = op_dst;
6148 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6149 nodes->push(m2);
6150 }
6151
6152 MachNode *m3 = new loadConNKlass_loNode();
6153 m3->add_req(NULL, m2);
6154 m3->_opnds[0] = op_dst;
6155 m3->_opnds[1] = op_src;
6156 m3->_opnds[2] = op_dst;
6157 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6158 nodes->push(m3);
6159 %}
6160 %}
6161
6162 // 0x1 is used in object initialization (initial object header).
6163 // No constant pool entries required.
6164 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
6165 match(Set dst src);
6166
6167 format %{ "LI $dst, $src \t// ptr" %}
6168 size(4);
6169 ins_encode %{
6170 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
6171 %}
6172 ins_pipe(pipe_class_default);
6173 %}
6174
6175 // Expand node for constant pool load: small offset.
6176 // The match rule is needed to generate the correct bottom_type(),
6177 // however this node should never match. The use of predicate is not
6178 // possible since ADLC forbids predicates for chain rules. The higher
6179 // costs do not prevent matching in this case. For that reason the
6180 // operand immP_NM with predicate(false) is used.
6181 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{
6182 match(Set dst src);
6183 effect(TEMP toc);
6184
6185 ins_num_consts(1);
6186
6187 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %}
6188 size(4);
6189 ins_encode( enc_load_long_constP(dst, src, toc) );
6190 ins_pipe(pipe_class_memory);
6191 %}
6192
6193 // Expand node for constant pool load: large offset.
6194 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{
6195 effect(DEF dst, USE src, USE toc);
6196 predicate(false);
6197
6198 ins_num_consts(1);
6199 ins_field_const_toc_offset(int);
6200
6201 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %}
6202 size(4);
6203 ins_encode( enc_load_long_constP_hi(dst, src, toc) );
6204 ins_pipe(pipe_class_default);
6205 %}
6206
6207 // Expand node for constant pool load: large offset.
6208 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
6209 match(Set dst src);
6210 effect(TEMP base);
6211
6212 ins_field_const_toc_offset_hi_node(loadConP_hiNode*);
6213
6214 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
6215 size(4);
6216 ins_encode %{
6217 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
6218 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
6219 %}
6220 ins_pipe(pipe_class_memory);
6221 %}
6222
6223 // Load pointer constant from constant table. Expand in case an
6224 // offset > 16 bit is needed.
6225 // Adlc adds toc node MachConstantTableBase.
6226 instruct loadConP_Ex(iRegPdst dst, immP src) %{
6227 match(Set dst src);
6228 ins_cost(MEMORY_REF_COST);
6229
6230 // This rule does not use "expand" because then
6231 // the result type is not known to be an Oop. An ADLC
6232 // enhancement will be needed to make that work - not worth it!
6233
6234 // If this instruction rematerializes, it prolongs the live range
6235 // of the toc node, causing illegal graphs.
6236 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule().
6237 ins_cannot_rematerialize(true);
6238
6239 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %}
6240 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) );
6241 %}
6242
6243 // Expand node for constant pool load: small offset.
6244 instruct loadConF(regF dst, immF src, iRegLdst toc) %{
6245 effect(DEF dst, USE src, USE toc);
6246 ins_cost(MEMORY_REF_COST);
6247
6248 ins_num_consts(1);
6249
6250 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %}
6251 size(4);
6252 ins_encode %{
6253 address float_address = __ float_constant($src$$constant);
6254 if (float_address == NULL) {
6255 ciEnv::current()->record_out_of_memory_failure();
6256 return;
6257 }
6258 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register);
6259 %}
6260 ins_pipe(pipe_class_memory);
6261 %}
6262
6263 // Expand node for constant pool load: large offset.
6264 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
6265 effect(DEF dst, USE src, USE toc);
6266 ins_cost(MEMORY_REF_COST);
6267
6268 ins_num_consts(1);
6269
6270 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6271 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t"
6272 "ADDIS $toc, $toc, -offset_hi"%}
6273 size(12);
6274 ins_encode %{
6275 FloatRegister Rdst = $dst$$FloatRegister;
6276 Register Rtoc = $toc$$Register;
6277 address float_address = __ float_constant($src$$constant);
6278 if (float_address == NULL) {
6279 ciEnv::current()->record_out_of_memory_failure();
6280 return;
6281 }
6282 int offset = __ offset_to_method_toc(float_address);
6283 int hi = (offset + (1<<15))>>16;
6284 int lo = offset - hi * (1<<16);
6285
6286 __ addis(Rtoc, Rtoc, hi);
6287 __ lfs(Rdst, lo, Rtoc);
6288 __ addis(Rtoc, Rtoc, -hi);
6289 %}
6290 ins_pipe(pipe_class_memory);
6291 %}
6292
6293 // Adlc adds toc node MachConstantTableBase.
6294 instruct loadConF_Ex(regF dst, immF src) %{
6295 match(Set dst src);
6296 ins_cost(MEMORY_REF_COST);
6297
6298 // See loadConP.
6299 ins_cannot_rematerialize(true);
6300
6301 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6302 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) );
6303 %}
6304
6305 // Expand node for constant pool load: small offset.
6306 instruct loadConD(regD dst, immD src, iRegLdst toc) %{
6307 effect(DEF dst, USE src, USE toc);
6308 ins_cost(MEMORY_REF_COST);
6309
6310 ins_num_consts(1);
6311
6312 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %}
6313 size(4);
6314 ins_encode %{
6315 address float_address = __ double_constant($src$$constant);
6316 if (float_address == NULL) {
6317 ciEnv::current()->record_out_of_memory_failure();
6318 return;
6319 }
6320 int offset = __ offset_to_method_toc(float_address);
6321 __ lfd($dst$$FloatRegister, offset, $toc$$Register);
6322 %}
6323 ins_pipe(pipe_class_memory);
6324 %}
6325
6326 // Expand node for constant pool load: large offset.
6327 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
6328 effect(DEF dst, USE src, USE toc);
6329 ins_cost(MEMORY_REF_COST);
6330
6331 ins_num_consts(1);
6332
6333 format %{ "ADDIS $toc, $toc, offset_hi\n\t"
6334 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t"
6335 "ADDIS $toc, $toc, -offset_hi" %}
6336 size(12);
6337 ins_encode %{
6338 FloatRegister Rdst = $dst$$FloatRegister;
6339 Register Rtoc = $toc$$Register;
6340 address float_address = __ double_constant($src$$constant);
6341 if (float_address == NULL) {
6342 ciEnv::current()->record_out_of_memory_failure();
6343 return;
6344 }
6345 int offset = __ offset_to_method_toc(float_address);
6346 int hi = (offset + (1<<15))>>16;
6347 int lo = offset - hi * (1<<16);
6348
6349 __ addis(Rtoc, Rtoc, hi);
6350 __ lfd(Rdst, lo, Rtoc);
6351 __ addis(Rtoc, Rtoc, -hi);
6352 %}
6353 ins_pipe(pipe_class_memory);
6354 %}
6355
6356 // Adlc adds toc node MachConstantTableBase.
6357 instruct loadConD_Ex(regD dst, immD src) %{
6358 match(Set dst src);
6359 ins_cost(MEMORY_REF_COST);
6360
6361 // See loadConP.
6362 ins_cannot_rematerialize(true);
6363
6364 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6365 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) );
6366 %}
6367
6368 // Prefetch instructions.
6369 // Must be safe to execute with invalid address (cannot fault).
6370
6371 // Special prefetch versions which use the dcbz instruction.
6372 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{
6373 match(PrefetchAllocation (AddP mem src));
6374 predicate(AllocatePrefetchStyle == 3);
6375 ins_cost(MEMORY_REF_COST);
6376
6377 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %}
6378 size(4);
6379 ins_encode %{
6380 __ dcbz($src$$Register, $mem$$base$$Register);
6381 %}
6382 ins_pipe(pipe_class_memory);
6383 %}
6384
6385 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{
6386 match(PrefetchAllocation mem);
6387 predicate(AllocatePrefetchStyle == 3);
6388 ins_cost(MEMORY_REF_COST);
6389
6390 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %}
6391 size(4);
6392 ins_encode %{
6393 __ dcbz($mem$$base$$Register);
6394 %}
6395 ins_pipe(pipe_class_memory);
6396 %}
6397
6398 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
6399 match(PrefetchAllocation (AddP mem src));
6400 predicate(AllocatePrefetchStyle != 3);
6401 ins_cost(MEMORY_REF_COST);
6402
6403 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
6404 size(4);
6405 ins_encode %{
6406 __ dcbtst($src$$Register, $mem$$base$$Register);
6407 %}
6408 ins_pipe(pipe_class_memory);
6409 %}
6410
6411 instruct prefetch_alloc_no_offset(indirectMemory mem) %{
6412 match(PrefetchAllocation mem);
6413 predicate(AllocatePrefetchStyle != 3);
6414 ins_cost(MEMORY_REF_COST);
6415
6416 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
6417 size(4);
6418 ins_encode %{
6419 __ dcbtst($mem$$base$$Register);
6420 %}
6421 ins_pipe(pipe_class_memory);
6422 %}
6423
6424 //----------Store Instructions-------------------------------------------------
6425
6426 // Store Byte
6427 instruct storeB(memory mem, iRegIsrc src) %{
6428 match(Set mem (StoreB mem src));
6429 ins_cost(MEMORY_REF_COST);
6430
6431 format %{ "STB $src, $mem \t// byte" %}
6432 size(4);
6433 ins_encode %{
6434 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6435 __ stb($src$$Register, Idisp, $mem$$base$$Register);
6436 %}
6437 ins_pipe(pipe_class_memory);
6438 %}
6439
6440 // Store Char/Short
6441 instruct storeC(memory mem, iRegIsrc src) %{
6442 match(Set mem (StoreC mem src));
6443 ins_cost(MEMORY_REF_COST);
6444
6445 format %{ "STH $src, $mem \t// short" %}
6446 size(4);
6447 ins_encode %{
6448 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6449 __ sth($src$$Register, Idisp, $mem$$base$$Register);
6450 %}
6451 ins_pipe(pipe_class_memory);
6452 %}
6453
6454 // Store Integer
6455 instruct storeI(memory mem, iRegIsrc src) %{
6456 match(Set mem (StoreI mem src));
6457 ins_cost(MEMORY_REF_COST);
6458
6459 format %{ "STW $src, $mem" %}
6460 size(4);
6461 ins_encode( enc_stw(src, mem) );
6462 ins_pipe(pipe_class_memory);
6463 %}
6464
6465 // ConvL2I + StoreI.
6466 instruct storeI_convL2I(memory mem, iRegLsrc src) %{
6467 match(Set mem (StoreI mem (ConvL2I src)));
6468 ins_cost(MEMORY_REF_COST);
6469
6470 format %{ "STW l2i($src), $mem" %}
6471 size(4);
6472 ins_encode( enc_stw(src, mem) );
6473 ins_pipe(pipe_class_memory);
6474 %}
6475
6476 // Store Long
6477 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{
6478 match(Set mem (StoreL mem src));
6479 ins_cost(MEMORY_REF_COST);
6480
6481 format %{ "STD $src, $mem \t// long" %}
6482 size(4);
6483 ins_encode( enc_std(src, mem) );
6484 ins_pipe(pipe_class_memory);
6485 %}
6486
6487 // Store super word nodes.
6488
6489 // Store Aligned Packed Byte long register to memory
6490 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{
6491 predicate(n->as_StoreVector()->memory_size() == 8);
6492 match(Set mem (StoreVector mem src));
6493 ins_cost(MEMORY_REF_COST);
6494
6495 format %{ "STD $mem, $src \t// packed8B" %}
6496 size(4);
6497 ins_encode( enc_std(src, mem) );
6498 ins_pipe(pipe_class_memory);
6499 %}
6500
6501 // Store Packed Byte long register to memory
6502 instruct storeV16(indirect mem, vecX src) %{
6503 predicate(n->as_StoreVector()->memory_size() == 16);
6504 match(Set mem (StoreVector mem src));
6505 ins_cost(MEMORY_REF_COST);
6506
6507 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %}
6508 size(4);
6509 ins_encode %{
6510 __ stxvd2x($src$$VectorSRegister, $mem$$Register);
6511 %}
6512 ins_pipe(pipe_class_default);
6513 %}
6514
6515 // Reinterpret: only one vector size used: either L or X
6516 instruct reinterpretL(iRegLdst dst) %{
6517 match(Set dst (VectorReinterpret dst));
6518 ins_cost(0);
6519 format %{ "reinterpret $dst" %}
6520 ins_encode( /*empty*/ );
6521 ins_pipe(pipe_class_empty);
6522 %}
6523
6524 instruct reinterpretX(vecX dst) %{
6525 match(Set dst (VectorReinterpret dst));
6526 ins_cost(0);
6527 format %{ "reinterpret $dst" %}
6528 ins_encode( /*empty*/ );
6529 ins_pipe(pipe_class_empty);
6530 %}
6531
6532 // Store Compressed Oop
6533 instruct storeN(memory dst, iRegN_P2N src) %{
6534 match(Set dst (StoreN dst src));
6535 ins_cost(MEMORY_REF_COST);
6536
6537 format %{ "STW $src, $dst \t// compressed oop" %}
6538 size(4);
6539 ins_encode( enc_stw(src, dst) );
6540 ins_pipe(pipe_class_memory);
6541 %}
6542
6543 // Store Compressed KLass
6544 instruct storeNKlass(memory dst, iRegN_P2N src) %{
6545 match(Set dst (StoreNKlass dst src));
6546 ins_cost(MEMORY_REF_COST);
6547
6548 format %{ "STW $src, $dst \t// compressed klass" %}
6549 size(4);
6550 ins_encode( enc_stw(src, dst) );
6551 ins_pipe(pipe_class_memory);
6552 %}
6553
6554 // Store Pointer
6555 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{
6556 match(Set dst (StoreP dst src));
6557 predicate(n->as_Store()->barrier_data() == 0);
6558 ins_cost(MEMORY_REF_COST);
6559
6560 format %{ "STD $src, $dst \t// ptr" %}
6561 size(4);
6562 ins_encode( enc_std(src, dst) );
6563 ins_pipe(pipe_class_memory);
6564 %}
6565
6566 // Store Float
6567 instruct storeF(memory mem, regF src) %{
6568 match(Set mem (StoreF mem src));
6569 ins_cost(MEMORY_REF_COST);
6570
6571 format %{ "STFS $src, $mem" %}
6572 size(4);
6573 ins_encode( enc_stfs(src, mem) );
6574 ins_pipe(pipe_class_memory);
6575 %}
6576
6577 // Store Double
6578 instruct storeD(memory mem, regD src) %{
6579 match(Set mem (StoreD mem src));
6580 ins_cost(MEMORY_REF_COST);
6581
6582 format %{ "STFD $src, $mem" %}
6583 size(4);
6584 ins_encode( enc_stfd(src, mem) );
6585 ins_pipe(pipe_class_memory);
6586 %}
6587
6588 //----------Store Instructions With Zeros--------------------------------------
6589
6590 instruct storeCM(memory mem, immI_0 zero) %{
6591 match(Set mem (StoreCM mem zero));
6592 ins_cost(MEMORY_REF_COST);
6593
6594 format %{ "STB #0, $mem \t// CMS card-mark byte store" %}
6595 size(8);
6596 ins_encode %{
6597 __ li(R0, 0);
6598 // No release barrier: Oops are allowed to get visible after marking.
6599 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias");
6600 __ stb(R0, $mem$$disp, $mem$$base$$Register);
6601 %}
6602 ins_pipe(pipe_class_memory);
6603 %}
6604
6605 // Convert oop pointer into compressed form.
6606
6607 // Nodes for postalloc expand.
6608
6609 // Shift node for expand.
6610 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
6611 // The match rule is needed to make it a 'MachTypeNode'!
6612 match(Set dst (EncodeP src));
6613 predicate(false);
6614
6615 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6616 size(4);
6617 ins_encode %{
6618 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6619 %}
6620 ins_pipe(pipe_class_default);
6621 %}
6622
6623 // Add node for expand.
6624 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6625 // The match rule is needed to make it a 'MachTypeNode'!
6626 match(Set dst (EncodeP src));
6627 predicate(false);
6628
6629 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6630 ins_encode %{
6631 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6632 %}
6633 ins_pipe(pipe_class_default);
6634 %}
6635
6636 // Conditional sub base.
6637 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6638 // The match rule is needed to make it a 'MachTypeNode'!
6639 match(Set dst (EncodeP (Binary crx src1)));
6640 predicate(false);
6641
6642 format %{ "BEQ $crx, done\n\t"
6643 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n"
6644 "done:" %}
6645 ins_encode %{
6646 Label done;
6647 __ beq($crx$$CondRegister, done);
6648 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0);
6649 __ bind(done);
6650 %}
6651 ins_pipe(pipe_class_default);
6652 %}
6653
6654 // Power 7 can use isel instruction
6655 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6656 // The match rule is needed to make it a 'MachTypeNode'!
6657 match(Set dst (EncodeP (Binary crx src1)));
6658 predicate(false);
6659
6660 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6661 size(4);
6662 ins_encode %{
6663 // This is a Power7 instruction for which no machine description exists.
6664 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6665 %}
6666 ins_pipe(pipe_class_default);
6667 %}
6668
6669 // Disjoint narrow oop base.
6670 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6671 match(Set dst (EncodeP src));
6672 predicate(CompressedOops::base_disjoint());
6673
6674 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6675 size(4);
6676 ins_encode %{
6677 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32);
6678 %}
6679 ins_pipe(pipe_class_default);
6680 %}
6681
6682 // shift != 0, base != 0
6683 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6684 match(Set dst (EncodeP src));
6685 effect(TEMP crx);
6686 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6687 CompressedOops::shift() != 0 &&
6688 CompressedOops::base_overlaps());
6689
6690 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6691 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6692 %}
6693
6694 // shift != 0, base != 0
6695 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6696 match(Set dst (EncodeP src));
6697 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6698 CompressedOops::shift() != 0 &&
6699 CompressedOops::base_overlaps());
6700
6701 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6702 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6703 %}
6704
6705 // shift != 0, base == 0
6706 // TODO: This is the same as encodeP_shift. Merge!
6707 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6708 match(Set dst (EncodeP src));
6709 predicate(CompressedOops::shift() != 0 &&
6710 CompressedOops::base() ==0);
6711
6712 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %}
6713 size(4);
6714 ins_encode %{
6715 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
6716 %}
6717 ins_pipe(pipe_class_default);
6718 %}
6719
6720 // Compressed OOPs with narrow_oop_shift == 0.
6721 // shift == 0, base == 0
6722 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
6723 match(Set dst (EncodeP src));
6724 predicate(CompressedOops::shift() == 0);
6725
6726 format %{ "MR $dst, $src \t// Ptr->Narrow" %}
6727 // variable size, 0 or 4.
6728 ins_encode %{
6729 __ mr_if_needed($dst$$Register, $src$$Register);
6730 %}
6731 ins_pipe(pipe_class_default);
6732 %}
6733
6734 // Decode nodes.
6735
6736 // Shift node for expand.
6737 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6738 // The match rule is needed to make it a 'MachTypeNode'!
6739 match(Set dst (DecodeN src));
6740 predicate(false);
6741
6742 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6743 size(4);
6744 ins_encode %{
6745 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6746 %}
6747 ins_pipe(pipe_class_default);
6748 %}
6749
6750 // Add node for expand.
6751 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6752 // The match rule is needed to make it a 'MachTypeNode'!
6753 match(Set dst (DecodeN src));
6754 predicate(false);
6755
6756 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %}
6757 ins_encode %{
6758 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6759 %}
6760 ins_pipe(pipe_class_default);
6761 %}
6762
6763 // conditianal add base for expand
6764 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6765 // The match rule is needed to make it a 'MachTypeNode'!
6766 // NOTICE that the rule is nonsense - we just have to make sure that:
6767 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6768 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6769 match(Set dst (DecodeN (Binary crx src)));
6770 predicate(false);
6771
6772 format %{ "BEQ $crx, done\n\t"
6773 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n"
6774 "done:" %}
6775 ins_encode %{
6776 Label done;
6777 __ beq($crx$$CondRegister, done);
6778 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
6779 __ bind(done);
6780 %}
6781 ins_pipe(pipe_class_default);
6782 %}
6783
6784 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6785 // The match rule is needed to make it a 'MachTypeNode'!
6786 // NOTICE that the rule is nonsense - we just have to make sure that:
6787 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6788 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6789 match(Set dst (DecodeN (Binary crx src1)));
6790 predicate(false);
6791
6792 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6793 size(4);
6794 ins_encode %{
6795 // This is a Power7 instruction for which no machine description exists.
6796 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6797 %}
6798 ins_pipe(pipe_class_default);
6799 %}
6800
6801 // shift != 0, base != 0
6802 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6803 match(Set dst (DecodeN src));
6804 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6805 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6806 CompressedOops::shift() != 0 &&
6807 CompressedOops::base() != 0);
6808 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6809 effect(TEMP crx);
6810
6811 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6812 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6813 %}
6814
6815 // shift != 0, base == 0
6816 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6817 match(Set dst (DecodeN src));
6818 predicate(CompressedOops::shift() != 0 &&
6819 CompressedOops::base() == 0);
6820
6821 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %}
6822 size(4);
6823 ins_encode %{
6824 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
6825 %}
6826 ins_pipe(pipe_class_default);
6827 %}
6828
6829 // Optimize DecodeN for disjoint base.
6830 // Shift narrow oop and or it into register that already contains the heap base.
6831 // Base == dst must hold, and is assured by construction in postaloc_expand.
6832 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6833 match(Set dst (DecodeN src));
6834 effect(TEMP base);
6835 predicate(false);
6836
6837 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6838 size(4);
6839 ins_encode %{
6840 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift());
6841 %}
6842 ins_pipe(pipe_class_default);
6843 %}
6844
6845 // Optimize DecodeN for disjoint base.
6846 // This node requires only one cycle on the critical path.
6847 // We must postalloc_expand as we can not express use_def effects where
6848 // the used register is L and the def'ed register P.
6849 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6850 match(Set dst (DecodeN src));
6851 effect(TEMP_DEF dst);
6852 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6853 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6854 CompressedOops::base_disjoint());
6855 ins_cost(DEFAULT_COST);
6856
6857 format %{ "MOV $dst, heapbase \t\n"
6858 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6859 postalloc_expand %{
6860 loadBaseNode *n1 = new loadBaseNode();
6861 n1->add_req(NULL);
6862 n1->_opnds[0] = op_dst;
6863
6864 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6865 n2->add_req(n_region, n_src, n1);
6866 n2->_opnds[0] = op_dst;
6867 n2->_opnds[1] = op_src;
6868 n2->_opnds[2] = op_dst;
6869 n2->_bottom_type = _bottom_type;
6870
6871 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6872 ra_->set_oop(n2, true);
6873
6874 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6875 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6876
6877 nodes->push(n1);
6878 nodes->push(n2);
6879 %}
6880 %}
6881
6882 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6883 match(Set dst (DecodeN src));
6884 effect(TEMP_DEF dst, TEMP crx);
6885 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6886 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6887 CompressedOops::base_disjoint() && VM_Version::has_isel());
6888 ins_cost(3 * DEFAULT_COST);
6889
6890 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %}
6891 postalloc_expand %{
6892 loadBaseNode *n1 = new loadBaseNode();
6893 n1->add_req(NULL);
6894 n1->_opnds[0] = op_dst;
6895
6896 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node();
6897 n_compare->add_req(n_region, n_src);
6898 n_compare->_opnds[0] = op_crx;
6899 n_compare->_opnds[1] = op_src;
6900 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6901
6902 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6903 n2->add_req(n_region, n_src, n1);
6904 n2->_opnds[0] = op_dst;
6905 n2->_opnds[1] = op_src;
6906 n2->_opnds[2] = op_dst;
6907 n2->_bottom_type = _bottom_type;
6908
6909 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6910 n_cond_set->add_req(n_region, n_compare, n2);
6911 n_cond_set->_opnds[0] = op_dst;
6912 n_cond_set->_opnds[1] = op_crx;
6913 n_cond_set->_opnds[2] = op_dst;
6914 n_cond_set->_bottom_type = _bottom_type;
6915
6916 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6917 ra_->set_oop(n_cond_set, true);
6918
6919 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6920 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
6921 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6922 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6923
6924 nodes->push(n1);
6925 nodes->push(n_compare);
6926 nodes->push(n2);
6927 nodes->push(n_cond_set);
6928 %}
6929 %}
6930
6931 // src != 0, shift != 0, base != 0
6932 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6933 match(Set dst (DecodeN src));
6934 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6935 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6936 CompressedOops::shift() != 0 &&
6937 CompressedOops::base() != 0);
6938 ins_cost(2 * DEFAULT_COST);
6939
6940 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %}
6941 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6942 %}
6943
6944 // Compressed OOPs with narrow_oop_shift == 0.
6945 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6946 match(Set dst (DecodeN src));
6947 predicate(CompressedOops::shift() == 0);
6948 ins_cost(DEFAULT_COST);
6949
6950 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %}
6951 // variable size, 0 or 4.
6952 ins_encode %{
6953 __ mr_if_needed($dst$$Register, $src$$Register);
6954 %}
6955 ins_pipe(pipe_class_default);
6956 %}
6957
6958 // Convert compressed oop into int for vectors alignment masking.
6959 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
6960 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6961 predicate(CompressedOops::shift() == 0);
6962 ins_cost(DEFAULT_COST);
6963
6964 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %}
6965 // variable size, 0 or 4.
6966 ins_encode %{
6967 __ mr_if_needed($dst$$Register, $src$$Register);
6968 %}
6969 ins_pipe(pipe_class_default);
6970 %}
6971
6972 // Convert klass pointer into compressed form.
6973
6974 // Nodes for postalloc expand.
6975
6976 // Shift node for expand.
6977 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
6978 // The match rule is needed to make it a 'MachTypeNode'!
6979 match(Set dst (EncodePKlass src));
6980 predicate(false);
6981
6982 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6983 size(4);
6984 ins_encode %{
6985 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
6986 %}
6987 ins_pipe(pipe_class_default);
6988 %}
6989
6990 // Add node for expand.
6991 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6992 // The match rule is needed to make it a 'MachTypeNode'!
6993 match(Set dst (EncodePKlass (Binary base src)));
6994 predicate(false);
6995
6996 format %{ "SUB $dst, $base, $src \t// encode" %}
6997 size(4);
6998 ins_encode %{
6999 __ subf($dst$$Register, $base$$Register, $src$$Register);
7000 %}
7001 ins_pipe(pipe_class_default);
7002 %}
7003
7004 // Disjoint narrow oop base.
7005 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
7006 match(Set dst (EncodePKlass src));
7007 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/);
7008
7009 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
7010 size(4);
7011 ins_encode %{
7012 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
7013 %}
7014 ins_pipe(pipe_class_default);
7015 %}
7016
7017 // shift != 0, base != 0
7018 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
7019 match(Set dst (EncodePKlass (Binary base src)));
7020 predicate(false);
7021
7022 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
7023 postalloc_expand %{
7024 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
7025 n1->add_req(n_region, n_base, n_src);
7026 n1->_opnds[0] = op_dst;
7027 n1->_opnds[1] = op_base;
7028 n1->_opnds[2] = op_src;
7029 n1->_bottom_type = _bottom_type;
7030
7031 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode();
7032 n2->add_req(n_region, n1);
7033 n2->_opnds[0] = op_dst;
7034 n2->_opnds[1] = op_dst;
7035 n2->_bottom_type = _bottom_type;
7036 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7037 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7038
7039 nodes->push(n1);
7040 nodes->push(n2);
7041 %}
7042 %}
7043
7044 // shift != 0, base != 0
7045 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
7046 match(Set dst (EncodePKlass src));
7047 //predicate(CompressedKlassPointers::shift() != 0 &&
7048 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/);
7049
7050 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
7051 ins_cost(DEFAULT_COST*2); // Don't count constant.
7052 expand %{
7053 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %}
7054 iRegLdst base;
7055 loadConL_Ex(base, baseImm);
7056 encodePKlass_not_null_Ex(dst, base, src);
7057 %}
7058 %}
7059
7060 // Decode nodes.
7061
7062 // Shift node for expand.
7063 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
7064 // The match rule is needed to make it a 'MachTypeNode'!
7065 match(Set dst (DecodeNKlass src));
7066 predicate(false);
7067
7068 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %}
7069 size(4);
7070 ins_encode %{
7071 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
7072 %}
7073 ins_pipe(pipe_class_default);
7074 %}
7075
7076 // Add node for expand.
7077
7078 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
7079 // The match rule is needed to make it a 'MachTypeNode'!
7080 match(Set dst (DecodeNKlass (Binary base src)));
7081 predicate(false);
7082
7083 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %}
7084 size(4);
7085 ins_encode %{
7086 __ add($dst$$Register, $base$$Register, $src$$Register);
7087 %}
7088 ins_pipe(pipe_class_default);
7089 %}
7090
7091 // src != 0, shift != 0, base != 0
7092 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
7093 match(Set dst (DecodeNKlass (Binary base src)));
7094 //effect(kill src); // We need a register for the immediate result after shifting.
7095 predicate(false);
7096
7097 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %}
7098 postalloc_expand %{
7099 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode();
7100 n1->add_req(n_region, n_base, n_src);
7101 n1->_opnds[0] = op_dst;
7102 n1->_opnds[1] = op_base;
7103 n1->_opnds[2] = op_src;
7104 n1->_bottom_type = _bottom_type;
7105
7106 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode();
7107 n2->add_req(n_region, n1);
7108 n2->_opnds[0] = op_dst;
7109 n2->_opnds[1] = op_dst;
7110 n2->_bottom_type = _bottom_type;
7111
7112 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7113 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7114
7115 nodes->push(n1);
7116 nodes->push(n2);
7117 %}
7118 %}
7119
7120 // src != 0, shift != 0, base != 0
7121 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
7122 match(Set dst (DecodeNKlass src));
7123 // predicate(CompressedKlassPointers::shift() != 0 &&
7124 // CompressedKlassPointers::base() != 0);
7125
7126 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %}
7127
7128 ins_cost(DEFAULT_COST*2); // Don't count constant.
7129 expand %{
7130 // We add first, then we shift. Like this, we can get along with one register less.
7131 // But we have to load the base pre-shifted.
7132 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %}
7133 iRegLdst base;
7134 loadConL_Ex(base, baseImm);
7135 decodeNKlass_notNull_addBase_Ex(dst, base, src);
7136 %}
7137 %}
7138
7139 //----------MemBar Instructions-----------------------------------------------
7140 // Memory barrier flavors
7141
7142 instruct membar_acquire() %{
7143 match(LoadFence);
7144 ins_cost(4*MEMORY_REF_COST);
7145
7146 format %{ "MEMBAR-acquire" %}
7147 size(4);
7148 ins_encode %{
7149 __ acquire();
7150 %}
7151 ins_pipe(pipe_class_default);
7152 %}
7153
7154 instruct unnecessary_membar_acquire() %{
7155 match(MemBarAcquire);
7156 ins_cost(0);
7157
7158 format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
7159 size(0);
7160 ins_encode( /*empty*/ );
7161 ins_pipe(pipe_class_default);
7162 %}
7163
7164 instruct membar_acquire_lock() %{
7165 match(MemBarAcquireLock);
7166 ins_cost(0);
7167
7168 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
7169 size(0);
7170 ins_encode( /*empty*/ );
7171 ins_pipe(pipe_class_default);
7172 %}
7173
7174 instruct membar_release() %{
7175 match(MemBarRelease);
7176 match(StoreFence);
7177 ins_cost(4*MEMORY_REF_COST);
7178
7179 format %{ "MEMBAR-release" %}
7180 size(4);
7181 ins_encode %{
7182 __ release();
7183 %}
7184 ins_pipe(pipe_class_default);
7185 %}
7186
7187 instruct membar_storestore() %{
7188 match(MemBarStoreStore);
7189 match(StoreStoreFence);
7190 ins_cost(4*MEMORY_REF_COST);
7191
7192 format %{ "MEMBAR-store-store" %}
7193 size(4);
7194 ins_encode %{
7195 __ membar(Assembler::StoreStore);
7196 %}
7197 ins_pipe(pipe_class_default);
7198 %}
7199
7200 instruct membar_release_lock() %{
7201 match(MemBarReleaseLock);
7202 ins_cost(0);
7203
7204 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
7205 size(0);
7206 ins_encode( /*empty*/ );
7207 ins_pipe(pipe_class_default);
7208 %}
7209
7210 instruct membar_volatile() %{
7211 match(MemBarVolatile);
7212 ins_cost(4*MEMORY_REF_COST);
7213
7214 format %{ "MEMBAR-volatile" %}
7215 size(4);
7216 ins_encode %{
7217 __ fence();
7218 %}
7219 ins_pipe(pipe_class_default);
7220 %}
7221
7222 // This optimization is wrong on PPC. The following pattern is not supported:
7223 // MemBarVolatile
7224 // ^ ^
7225 // | |
7226 // CtrlProj MemProj
7227 // ^ ^
7228 // | |
7229 // | Load
7230 // |
7231 // MemBarVolatile
7232 //
7233 // The first MemBarVolatile could get optimized out! According to
7234 // Vladimir, this pattern can not occur on Oracle platforms.
7235 // However, it does occur on PPC64 (because of membars in
7236 // inline_unsafe_load_store).
7237 //
7238 // Add this node again if we found a good solution for inline_unsafe_load_store().
7239 // Don't forget to look at the implementation of post_store_load_barrier again,
7240 // we did other fixes in that method.
7241 //instruct unnecessary_membar_volatile() %{
7242 // match(MemBarVolatile);
7243 // predicate(Matcher::post_store_load_barrier(n));
7244 // ins_cost(0);
7245 //
7246 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
7247 // size(0);
7248 // ins_encode( /*empty*/ );
7249 // ins_pipe(pipe_class_default);
7250 //%}
7251
7252 instruct membar_CPUOrder() %{
7253 match(MemBarCPUOrder);
7254 ins_cost(0);
7255
7256 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
7257 size(0);
7258 ins_encode( /*empty*/ );
7259 ins_pipe(pipe_class_default);
7260 %}
7261
7262 //----------Conditional Move---------------------------------------------------
7263
7264 // Cmove using isel.
7265 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
7266 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7267 predicate(VM_Version::has_isel());
7268 ins_cost(DEFAULT_COST);
7269
7270 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7271 size(4);
7272 ins_encode %{
7273 // This is a Power7 instruction for which no machine description
7274 // exists. Anyways, the scheduler should be off on Power7.
7275 int cc = $cmp$$cmpcode;
7276 __ isel($dst$$Register, $crx$$CondRegister,
7277 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7278 %}
7279 ins_pipe(pipe_class_default);
7280 %}
7281
7282 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
7283 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7284 predicate(!VM_Version::has_isel());
7285 ins_cost(DEFAULT_COST+BRANCH_COST);
7286
7287 ins_variable_size_depending_on_alignment(true);
7288
7289 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7290 // Worst case is branch + move + stop, no stop without scheduler
7291 size(8);
7292 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7293 ins_pipe(pipe_class_default);
7294 %}
7295
7296 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{
7297 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7298 ins_cost(DEFAULT_COST+BRANCH_COST);
7299
7300 ins_variable_size_depending_on_alignment(true);
7301
7302 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7303 // Worst case is branch + move + stop, no stop without scheduler
7304 size(8);
7305 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7306 ins_pipe(pipe_class_default);
7307 %}
7308
7309 // Cmove using isel.
7310 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
7311 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7312 predicate(VM_Version::has_isel());
7313 ins_cost(DEFAULT_COST);
7314
7315 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7316 size(4);
7317 ins_encode %{
7318 // This is a Power7 instruction for which no machine description
7319 // exists. Anyways, the scheduler should be off on Power7.
7320 int cc = $cmp$$cmpcode;
7321 __ isel($dst$$Register, $crx$$CondRegister,
7322 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7323 %}
7324 ins_pipe(pipe_class_default);
7325 %}
7326
7327 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
7328 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7329 predicate(!VM_Version::has_isel());
7330 ins_cost(DEFAULT_COST+BRANCH_COST);
7331
7332 ins_variable_size_depending_on_alignment(true);
7333
7334 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7335 // Worst case is branch + move + stop, no stop without scheduler.
7336 size(8);
7337 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7338 ins_pipe(pipe_class_default);
7339 %}
7340
7341 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{
7342 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7343 ins_cost(DEFAULT_COST+BRANCH_COST);
7344
7345 ins_variable_size_depending_on_alignment(true);
7346
7347 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7348 // Worst case is branch + move + stop, no stop without scheduler.
7349 size(8);
7350 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7351 ins_pipe(pipe_class_default);
7352 %}
7353
7354 // Cmove using isel.
7355 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
7356 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7357 predicate(VM_Version::has_isel());
7358 ins_cost(DEFAULT_COST);
7359
7360 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7361 size(4);
7362 ins_encode %{
7363 // This is a Power7 instruction for which no machine description
7364 // exists. Anyways, the scheduler should be off on Power7.
7365 int cc = $cmp$$cmpcode;
7366 __ isel($dst$$Register, $crx$$CondRegister,
7367 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7368 %}
7369 ins_pipe(pipe_class_default);
7370 %}
7371
7372 // Conditional move for RegN. Only cmov(reg, reg).
7373 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
7374 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7375 predicate(!VM_Version::has_isel());
7376 ins_cost(DEFAULT_COST+BRANCH_COST);
7377
7378 ins_variable_size_depending_on_alignment(true);
7379
7380 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7381 // Worst case is branch + move + stop, no stop without scheduler.
7382 size(8);
7383 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7384 ins_pipe(pipe_class_default);
7385 %}
7386
7387 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{
7388 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7389 ins_cost(DEFAULT_COST+BRANCH_COST);
7390
7391 ins_variable_size_depending_on_alignment(true);
7392
7393 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7394 // Worst case is branch + move + stop, no stop without scheduler.
7395 size(8);
7396 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7397 ins_pipe(pipe_class_default);
7398 %}
7399
7400 // Cmove using isel.
7401 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
7402 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7403 predicate(VM_Version::has_isel());
7404 ins_cost(DEFAULT_COST);
7405
7406 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7407 size(4);
7408 ins_encode %{
7409 // This is a Power7 instruction for which no machine description
7410 // exists. Anyways, the scheduler should be off on Power7.
7411 int cc = $cmp$$cmpcode;
7412 __ isel($dst$$Register, $crx$$CondRegister,
7413 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7414 %}
7415 ins_pipe(pipe_class_default);
7416 %}
7417
7418 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{
7419 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7420 predicate(!VM_Version::has_isel());
7421 ins_cost(DEFAULT_COST+BRANCH_COST);
7422
7423 ins_variable_size_depending_on_alignment(true);
7424
7425 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7426 // Worst case is branch + move + stop, no stop without scheduler.
7427 size(8);
7428 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7429 ins_pipe(pipe_class_default);
7430 %}
7431
7432 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{
7433 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7434 ins_cost(DEFAULT_COST+BRANCH_COST);
7435
7436 ins_variable_size_depending_on_alignment(true);
7437
7438 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7439 // Worst case is branch + move + stop, no stop without scheduler.
7440 size(8);
7441 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7442 ins_pipe(pipe_class_default);
7443 %}
7444
7445 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
7446 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
7447 ins_cost(DEFAULT_COST+BRANCH_COST);
7448
7449 ins_variable_size_depending_on_alignment(true);
7450
7451 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7452 // Worst case is branch + move + stop, no stop without scheduler.
7453 size(8);
7454 ins_encode %{
7455 Label done;
7456 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7457 // Branch if not (cmp crx).
7458 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7459 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7460 __ bind(done);
7461 %}
7462 ins_pipe(pipe_class_default);
7463 %}
7464
7465 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7466 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7467 ins_cost(DEFAULT_COST+BRANCH_COST);
7468
7469 ins_variable_size_depending_on_alignment(true);
7470
7471 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7472 // Worst case is branch + move + stop, no stop without scheduler.
7473 size(8);
7474 ins_encode %{
7475 Label done;
7476 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7477 // Branch if not (cmp crx).
7478 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7479 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7480 __ bind(done);
7481 %}
7482 ins_pipe(pipe_class_default);
7483 %}
7484
7485 //----------Compare-And-Swap---------------------------------------------------
7486
7487 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7488 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7489 // matched.
7490
7491 // Strong versions:
7492
7493 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7494 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7495 predicate(VM_Version::has_lqarx());
7496 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7497 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7498 ins_encode %{
7499 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7500 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7501 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7502 $res$$Register, true);
7503 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7504 __ isync();
7505 } else {
7506 __ sync();
7507 }
7508 %}
7509 ins_pipe(pipe_class_default);
7510 %}
7511
7512 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7513 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7514 predicate(!VM_Version::has_lqarx());
7515 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7516 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7517 ins_encode %{
7518 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7519 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7520 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7521 $res$$Register, true);
7522 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7523 __ isync();
7524 } else {
7525 __ sync();
7526 }
7527 %}
7528 ins_pipe(pipe_class_default);
7529 %}
7530
7531 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7532 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7533 predicate(VM_Version::has_lqarx());
7534 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7535 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7536 ins_encode %{
7537 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7538 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7539 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7540 $res$$Register, true);
7541 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7542 __ isync();
7543 } else {
7544 __ sync();
7545 }
7546 %}
7547 ins_pipe(pipe_class_default);
7548 %}
7549
7550 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7551 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7552 predicate(!VM_Version::has_lqarx());
7553 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7554 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7555 ins_encode %{
7556 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7557 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7558 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7559 $res$$Register, true);
7560 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7561 __ isync();
7562 } else {
7563 __ sync();
7564 }
7565 %}
7566 ins_pipe(pipe_class_default);
7567 %}
7568
7569 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7570 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7571 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7572 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7573 ins_encode %{
7574 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7575 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7576 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7577 $res$$Register, true);
7578 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7579 __ isync();
7580 } else {
7581 __ sync();
7582 }
7583 %}
7584 ins_pipe(pipe_class_default);
7585 %}
7586
7587 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7588 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7589 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7590 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7591 ins_encode %{
7592 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7593 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7594 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7595 $res$$Register, true);
7596 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7597 __ isync();
7598 } else {
7599 __ sync();
7600 }
7601 %}
7602 ins_pipe(pipe_class_default);
7603 %}
7604
7605 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7606 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7607 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7608 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7609 ins_encode %{
7610 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7611 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7612 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7613 $res$$Register, NULL, true);
7614 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7615 __ isync();
7616 } else {
7617 __ sync();
7618 }
7619 %}
7620 ins_pipe(pipe_class_default);
7621 %}
7622
7623 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7624 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7625 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7626 predicate(n->as_LoadStore()->barrier_data() == 0);
7627 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7628 ins_encode %{
7629 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7630 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7631 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7632 $res$$Register, NULL, true);
7633 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7634 __ isync();
7635 } else {
7636 __ sync();
7637 }
7638 %}
7639 ins_pipe(pipe_class_default);
7640 %}
7641
7642 // Weak versions:
7643
7644 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7645 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7646 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7647 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7648 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7649 ins_encode %{
7650 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7651 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7652 MacroAssembler::MemBarNone,
7653 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7654 %}
7655 ins_pipe(pipe_class_default);
7656 %}
7657
7658 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7659 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7660 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7661 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7662 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7663 ins_encode %{
7664 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7665 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7666 MacroAssembler::MemBarNone,
7667 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7668 %}
7669 ins_pipe(pipe_class_default);
7670 %}
7671
7672 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7673 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7674 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7675 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7676 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7677 ins_encode %{
7678 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7679 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7680 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7681 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7682 %}
7683 ins_pipe(pipe_class_default);
7684 %}
7685
7686 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7687 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7688 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7689 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7690 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7691 ins_encode %{
7692 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7693 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7694 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7695 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7696 %}
7697 ins_pipe(pipe_class_default);
7698 %}
7699
7700 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7701 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7702 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7703 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7704 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7705 ins_encode %{
7706 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7707 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7708 MacroAssembler::MemBarNone,
7709 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7710 %}
7711 ins_pipe(pipe_class_default);
7712 %}
7713
7714 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7715 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7716 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7717 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7718 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7719 ins_encode %{
7720 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7721 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7722 MacroAssembler::MemBarNone,
7723 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7724 %}
7725 ins_pipe(pipe_class_default);
7726 %}
7727
7728 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7729 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7730 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7731 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7732 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7733 ins_encode %{
7734 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7735 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7736 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7737 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7738 %}
7739 ins_pipe(pipe_class_default);
7740 %}
7741
7742 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7743 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7744 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7745 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7746 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7747 ins_encode %{
7748 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7749 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7750 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7751 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7752 %}
7753 ins_pipe(pipe_class_default);
7754 %}
7755
7756 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7757 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7758 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7759 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7760 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7761 ins_encode %{
7762 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7763 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7764 MacroAssembler::MemBarNone,
7765 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7766 %}
7767 ins_pipe(pipe_class_default);
7768 %}
7769
7770 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7771 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7772 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7773 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7774 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7775 ins_encode %{
7776 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7777 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7778 // value is never passed to caller.
7779 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7780 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7781 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7782 %}
7783 ins_pipe(pipe_class_default);
7784 %}
7785
7786 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7787 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7788 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7789 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7790 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7791 ins_encode %{
7792 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7793 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7794 MacroAssembler::MemBarNone,
7795 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7796 %}
7797 ins_pipe(pipe_class_default);
7798 %}
7799
7800 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7801 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7802 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7803 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7804 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7805 ins_encode %{
7806 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7807 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7808 // value is never passed to caller.
7809 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7810 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7811 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7812 %}
7813 ins_pipe(pipe_class_default);
7814 %}
7815
7816 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7817 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7818 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7819 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7820 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7821 ins_encode %{
7822 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7823 // value is never passed to caller.
7824 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7825 MacroAssembler::MemBarNone,
7826 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7827 %}
7828 ins_pipe(pipe_class_default);
7829 %}
7830
7831 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7832 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7833 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7834 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7835 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7836 ins_encode %{
7837 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7838 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7839 // value is never passed to caller.
7840 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7841 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7842 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7843 %}
7844 ins_pipe(pipe_class_default);
7845 %}
7846
7847 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7848 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7849 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7850 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7851 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7852 ins_encode %{
7853 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7854 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7855 MacroAssembler::MemBarNone,
7856 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7857 %}
7858 ins_pipe(pipe_class_default);
7859 %}
7860
7861 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7862 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7863 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0);
7864 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7865 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7866 ins_encode %{
7867 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7868 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7869 // value is never passed to caller.
7870 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7871 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7872 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7873 %}
7874 ins_pipe(pipe_class_default);
7875 %}
7876
7877 // CompareAndExchange
7878
7879 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7880 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7881 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7882 effect(TEMP_DEF res, TEMP cr0);
7883 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7884 ins_encode %{
7885 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7886 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7887 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7888 noreg, true);
7889 %}
7890 ins_pipe(pipe_class_default);
7891 %}
7892
7893 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7894 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7895 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7896 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7897 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7898 ins_encode %{
7899 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7900 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
7901 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7902 noreg, true);
7903 %}
7904 ins_pipe(pipe_class_default);
7905 %}
7906
7907 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7908 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7909 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7910 effect(TEMP_DEF res, TEMP cr0);
7911 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7912 ins_encode %{
7913 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7914 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7915 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7916 noreg, true);
7917 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7918 __ isync();
7919 } else {
7920 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7921 __ sync();
7922 }
7923 %}
7924 ins_pipe(pipe_class_default);
7925 %}
7926
7927 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7928 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7929 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7930 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7931 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7932 ins_encode %{
7933 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7934 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
7935 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7936 noreg, true);
7937 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7938 __ isync();
7939 } else {
7940 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7941 __ sync();
7942 }
7943 %}
7944 ins_pipe(pipe_class_default);
7945 %}
7946
7947 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7948 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7949 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7950 effect(TEMP_DEF res, TEMP cr0);
7951 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7952 ins_encode %{
7953 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7954 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7955 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7956 noreg, true);
7957 %}
7958 ins_pipe(pipe_class_default);
7959 %}
7960
7961 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7962 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7963 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7964 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7965 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7966 ins_encode %{
7967 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7968 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
7969 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7970 noreg, true);
7971 %}
7972 ins_pipe(pipe_class_default);
7973 %}
7974
7975 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7976 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7977 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7978 effect(TEMP_DEF res, TEMP cr0);
7979 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7980 ins_encode %{
7981 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7982 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7983 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7984 noreg, true);
7985 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7986 __ isync();
7987 } else {
7988 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7989 __ sync();
7990 }
7991 %}
7992 ins_pipe(pipe_class_default);
7993 %}
7994
7995 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7996 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7997 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7998 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7999 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
8000 ins_encode %{
8001 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8002 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
8003 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8004 noreg, true);
8005 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8006 __ isync();
8007 } else {
8008 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8009 __ sync();
8010 }
8011 %}
8012 ins_pipe(pipe_class_default);
8013 %}
8014
8015 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8016 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
8017 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8018 effect(TEMP_DEF res, TEMP cr0);
8019 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
8020 ins_encode %{
8021 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8022 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8023 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8024 noreg, true);
8025 %}
8026 ins_pipe(pipe_class_default);
8027 %}
8028
8029 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8030 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
8031 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8032 effect(TEMP_DEF res, TEMP cr0);
8033 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
8034 ins_encode %{
8035 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8036 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8037 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8038 noreg, true);
8039 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8040 __ isync();
8041 } else {
8042 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8043 __ sync();
8044 }
8045 %}
8046 ins_pipe(pipe_class_default);
8047 %}
8048
8049 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8050 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
8051 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8052 effect(TEMP_DEF res, TEMP cr0);
8053 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
8054 ins_encode %{
8055 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8056 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8057 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8058 noreg, true);
8059 %}
8060 ins_pipe(pipe_class_default);
8061 %}
8062
8063 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8064 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
8065 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8066 effect(TEMP_DEF res, TEMP cr0);
8067 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
8068 ins_encode %{
8069 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8070 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8071 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8072 noreg, true);
8073 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8074 __ isync();
8075 } else {
8076 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8077 __ sync();
8078 }
8079 %}
8080 ins_pipe(pipe_class_default);
8081 %}
8082
8083 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8084 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
8085 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8086 effect(TEMP_DEF res, TEMP cr0);
8087 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
8088 ins_encode %{
8089 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8090 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8091 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8092 noreg, NULL, true);
8093 %}
8094 ins_pipe(pipe_class_default);
8095 %}
8096
8097 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8098 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
8099 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8100 effect(TEMP_DEF res, TEMP cr0);
8101 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
8102 ins_encode %{
8103 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8104 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8105 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8106 noreg, NULL, true);
8107 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8108 __ isync();
8109 } else {
8110 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8111 __ sync();
8112 }
8113 %}
8114 ins_pipe(pipe_class_default);
8115 %}
8116
8117 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8118 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
8119 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst)
8120 && n->as_LoadStore()->barrier_data() == 0);
8121 effect(TEMP_DEF res, TEMP cr0);
8122 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
8123 ins_encode %{
8124 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8125 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8126 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8127 noreg, NULL, true);
8128 %}
8129 ins_pipe(pipe_class_default);
8130 %}
8131
8132 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8133 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
8134 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst)
8135 && n->as_LoadStore()->barrier_data() == 0);
8136 effect(TEMP_DEF res, TEMP cr0);
8137 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
8138 ins_encode %{
8139 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8140 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8141 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8142 noreg, NULL, true);
8143 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8144 __ isync();
8145 } else {
8146 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8147 __ sync();
8148 }
8149 %}
8150 ins_pipe(pipe_class_default);
8151 %}
8152
8153 // Special RMW
8154
8155 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8156 match(Set res (GetAndAddB mem_ptr src));
8157 predicate(VM_Version::has_lqarx());
8158 effect(TEMP_DEF res, TEMP cr0);
8159 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
8160 ins_encode %{
8161 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
8162 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8163 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8164 __ isync();
8165 } else {
8166 __ sync();
8167 }
8168 %}
8169 ins_pipe(pipe_class_default);
8170 %}
8171
8172 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8173 match(Set res (GetAndAddB mem_ptr src));
8174 predicate(!VM_Version::has_lqarx());
8175 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8176 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
8177 ins_encode %{
8178 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
8179 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8180 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8181 __ isync();
8182 } else {
8183 __ sync();
8184 }
8185 %}
8186 ins_pipe(pipe_class_default);
8187 %}
8188
8189 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8190 match(Set res (GetAndAddS mem_ptr src));
8191 predicate(VM_Version::has_lqarx());
8192 effect(TEMP_DEF res, TEMP cr0);
8193 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
8194 ins_encode %{
8195 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
8196 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8197 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8198 __ isync();
8199 } else {
8200 __ sync();
8201 }
8202 %}
8203 ins_pipe(pipe_class_default);
8204 %}
8205
8206 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8207 match(Set res (GetAndAddS mem_ptr src));
8208 predicate(!VM_Version::has_lqarx());
8209 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8210 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
8211 ins_encode %{
8212 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
8213 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8214 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8215 __ isync();
8216 } else {
8217 __ sync();
8218 }
8219 %}
8220 ins_pipe(pipe_class_default);
8221 %}
8222
8223 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8224 match(Set res (GetAndAddI mem_ptr src));
8225 effect(TEMP_DEF res, TEMP cr0);
8226 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
8227 ins_encode %{
8228 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
8229 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
8230 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8231 __ isync();
8232 } else {
8233 __ sync();
8234 }
8235 %}
8236 ins_pipe(pipe_class_default);
8237 %}
8238
8239 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
8240 match(Set res (GetAndAddL mem_ptr src));
8241 effect(TEMP_DEF res, TEMP cr0);
8242 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
8243 ins_encode %{
8244 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
8245 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
8246 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8247 __ isync();
8248 } else {
8249 __ sync();
8250 }
8251 %}
8252 ins_pipe(pipe_class_default);
8253 %}
8254
8255 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8256 match(Set res (GetAndSetB mem_ptr src));
8257 predicate(VM_Version::has_lqarx());
8258 effect(TEMP_DEF res, TEMP cr0);
8259 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
8260 ins_encode %{
8261 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
8262 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8263 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8264 __ isync();
8265 } else {
8266 __ sync();
8267 }
8268 %}
8269 ins_pipe(pipe_class_default);
8270 %}
8271
8272 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8273 match(Set res (GetAndSetB mem_ptr src));
8274 predicate(!VM_Version::has_lqarx());
8275 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8276 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
8277 ins_encode %{
8278 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
8279 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8280 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8281 __ isync();
8282 } else {
8283 __ sync();
8284 }
8285 %}
8286 ins_pipe(pipe_class_default);
8287 %}
8288
8289 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8290 match(Set res (GetAndSetS mem_ptr src));
8291 predicate(VM_Version::has_lqarx());
8292 effect(TEMP_DEF res, TEMP cr0);
8293 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
8294 ins_encode %{
8295 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
8296 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8297 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8298 __ isync();
8299 } else {
8300 __ sync();
8301 }
8302 %}
8303 ins_pipe(pipe_class_default);
8304 %}
8305
8306 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8307 match(Set res (GetAndSetS mem_ptr src));
8308 predicate(!VM_Version::has_lqarx());
8309 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8310 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
8311 ins_encode %{
8312 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
8313 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8314 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8315 __ isync();
8316 } else {
8317 __ sync();
8318 }
8319 %}
8320 ins_pipe(pipe_class_default);
8321 %}
8322
8323 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8324 match(Set res (GetAndSetI mem_ptr src));
8325 effect(TEMP_DEF res, TEMP cr0);
8326 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
8327 ins_encode %{
8328 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
8329 MacroAssembler::cmpxchgx_hint_atomic_update());
8330 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8331 __ isync();
8332 } else {
8333 __ sync();
8334 }
8335 %}
8336 ins_pipe(pipe_class_default);
8337 %}
8338
8339 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
8340 match(Set res (GetAndSetL mem_ptr src));
8341 effect(TEMP_DEF res, TEMP cr0);
8342 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
8343 ins_encode %{
8344 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
8345 MacroAssembler::cmpxchgx_hint_atomic_update());
8346 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8347 __ isync();
8348 } else {
8349 __ sync();
8350 }
8351 %}
8352 ins_pipe(pipe_class_default);
8353 %}
8354
8355 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
8356 match(Set res (GetAndSetP mem_ptr src));
8357 predicate(n->as_LoadStore()->barrier_data() == 0);
8358 effect(TEMP_DEF res, TEMP cr0);
8359 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
8360 ins_encode %{
8361 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
8362 MacroAssembler::cmpxchgx_hint_atomic_update());
8363 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8364 __ isync();
8365 } else {
8366 __ sync();
8367 }
8368 %}
8369 ins_pipe(pipe_class_default);
8370 %}
8371
8372 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
8373 match(Set res (GetAndSetN mem_ptr src));
8374 effect(TEMP_DEF res, TEMP cr0);
8375 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
8376 ins_encode %{
8377 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
8378 MacroAssembler::cmpxchgx_hint_atomic_update());
8379 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8380 __ isync();
8381 } else {
8382 __ sync();
8383 }
8384 %}
8385 ins_pipe(pipe_class_default);
8386 %}
8387
8388 //----------Arithmetic Instructions--------------------------------------------
8389 // Addition Instructions
8390
8391 // Register Addition
8392 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
8393 match(Set dst (AddI src1 src2));
8394 format %{ "ADD $dst, $src1, $src2" %}
8395 size(4);
8396 ins_encode %{
8397 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8398 %}
8399 ins_pipe(pipe_class_default);
8400 %}
8401
8402 // Expand does not work with above instruct. (??)
8403 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8404 // no match-rule
8405 effect(DEF dst, USE src1, USE src2);
8406 format %{ "ADD $dst, $src1, $src2" %}
8407 size(4);
8408 ins_encode %{
8409 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8410 %}
8411 ins_pipe(pipe_class_default);
8412 %}
8413
8414 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
8415 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
8416 ins_cost(DEFAULT_COST*3);
8417
8418 expand %{
8419 // FIXME: we should do this in the ideal world.
8420 iRegIdst tmp1;
8421 iRegIdst tmp2;
8422 addI_reg_reg(tmp1, src1, src2);
8423 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
8424 addI_reg_reg(dst, tmp1, tmp2);
8425 %}
8426 %}
8427
8428 // Immediate Addition
8429 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8430 match(Set dst (AddI src1 src2));
8431 format %{ "ADDI $dst, $src1, $src2" %}
8432 size(4);
8433 ins_encode %{
8434 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8435 %}
8436 ins_pipe(pipe_class_default);
8437 %}
8438
8439 // Immediate Addition with 16-bit shifted operand
8440 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
8441 match(Set dst (AddI src1 src2));
8442 format %{ "ADDIS $dst, $src1, $src2" %}
8443 size(4);
8444 ins_encode %{
8445 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8446 %}
8447 ins_pipe(pipe_class_default);
8448 %}
8449
8450 // Immediate Addition using prefixed addi
8451 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{
8452 match(Set dst (AddI src1 src2));
8453 predicate(PowerArchitecturePPC64 >= 10);
8454 ins_cost(DEFAULT_COST+1);
8455 format %{ "PADDI $dst, $src1, $src2" %}
8456 size(8);
8457 ins_encode %{
8458 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8459 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8460 %}
8461 ins_pipe(pipe_class_default);
8462 ins_alignment(2);
8463 %}
8464
8465 // Long Addition
8466 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8467 match(Set dst (AddL src1 src2));
8468 format %{ "ADD $dst, $src1, $src2 \t// long" %}
8469 size(4);
8470 ins_encode %{
8471 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8472 %}
8473 ins_pipe(pipe_class_default);
8474 %}
8475
8476 // Expand does not work with above instruct. (??)
8477 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8478 // no match-rule
8479 effect(DEF dst, USE src1, USE src2);
8480 format %{ "ADD $dst, $src1, $src2 \t// long" %}
8481 size(4);
8482 ins_encode %{
8483 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8484 %}
8485 ins_pipe(pipe_class_default);
8486 %}
8487
8488 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
8489 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
8490 ins_cost(DEFAULT_COST*3);
8491
8492 expand %{
8493 // FIXME: we should do this in the ideal world.
8494 iRegLdst tmp1;
8495 iRegLdst tmp2;
8496 addL_reg_reg(tmp1, src1, src2);
8497 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
8498 addL_reg_reg(dst, tmp1, tmp2);
8499 %}
8500 %}
8501
8502 // AddL + ConvL2I.
8503 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8504 match(Set dst (ConvL2I (AddL src1 src2)));
8505
8506 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %}
8507 size(4);
8508 ins_encode %{
8509 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8510 %}
8511 ins_pipe(pipe_class_default);
8512 %}
8513
8514 // No constant pool entries required.
8515 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8516 match(Set dst (AddL src1 src2));
8517
8518 format %{ "ADDI $dst, $src1, $src2" %}
8519 size(4);
8520 ins_encode %{
8521 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8522 %}
8523 ins_pipe(pipe_class_default);
8524 %}
8525
8526 // Long Immediate Addition with 16-bit shifted operand.
8527 // No constant pool entries required.
8528 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
8529 match(Set dst (AddL src1 src2));
8530
8531 format %{ "ADDIS $dst, $src1, $src2" %}
8532 size(4);
8533 ins_encode %{
8534 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8535 %}
8536 ins_pipe(pipe_class_default);
8537 %}
8538
8539 // Long Immediate Addition using prefixed addi
8540 // No constant pool entries required.
8541 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{
8542 match(Set dst (AddL src1 src2));
8543 predicate(PowerArchitecturePPC64 >= 10);
8544 ins_cost(DEFAULT_COST+1);
8545
8546 format %{ "PADDI $dst, $src1, $src2" %}
8547 size(8);
8548 ins_encode %{
8549 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8550 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8551 %}
8552 ins_pipe(pipe_class_default);
8553 ins_alignment(2);
8554 %}
8555
8556 // Pointer Register Addition
8557 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
8558 match(Set dst (AddP src1 src2));
8559 format %{ "ADD $dst, $src1, $src2" %}
8560 size(4);
8561 ins_encode %{
8562 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8563 %}
8564 ins_pipe(pipe_class_default);
8565 %}
8566
8567 // Pointer Immediate Addition
8568 // No constant pool entries required.
8569 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
8570 match(Set dst (AddP src1 src2));
8571
8572 format %{ "ADDI $dst, $src1, $src2" %}
8573 size(4);
8574 ins_encode %{
8575 __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8576 %}
8577 ins_pipe(pipe_class_default);
8578 %}
8579
8580 // Pointer Immediate Addition with 16-bit shifted operand.
8581 // No constant pool entries required.
8582 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
8583 match(Set dst (AddP src1 src2));
8584
8585 format %{ "ADDIS $dst, $src1, $src2" %}
8586 size(4);
8587 ins_encode %{
8588 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8589 %}
8590 ins_pipe(pipe_class_default);
8591 %}
8592
8593 // Pointer Immediate Addition using prefixed addi
8594 // No constant pool entries required.
8595 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{
8596 match(Set dst (AddP src1 src2));
8597 predicate(PowerArchitecturePPC64 >= 10);
8598 ins_cost(DEFAULT_COST+1);
8599
8600 format %{ "PADDI $dst, $src1, $src2" %}
8601 size(8);
8602 ins_encode %{
8603 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
8604 __ paddi($dst$$Register, $src1$$Register, $src2$$constant);
8605 %}
8606 ins_pipe(pipe_class_default);
8607 ins_alignment(2);
8608 %}
8609
8610 //---------------------
8611 // Subtraction Instructions
8612
8613 // Register Subtraction
8614 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8615 match(Set dst (SubI src1 src2));
8616 format %{ "SUBF $dst, $src2, $src1" %}
8617 size(4);
8618 ins_encode %{
8619 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8620 %}
8621 ins_pipe(pipe_class_default);
8622 %}
8623
8624 // Immediate Subtraction
8625 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
8626 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
8627
8628 // SubI from constant (using subfic).
8629 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
8630 match(Set dst (SubI src1 src2));
8631 format %{ "SUBI $dst, $src1, $src2" %}
8632
8633 size(4);
8634 ins_encode %{
8635 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
8636 %}
8637 ins_pipe(pipe_class_default);
8638 %}
8639
8640 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
8641 // positive integers and 0xF...F for negative ones.
8642 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
8643 // no match-rule, false predicate
8644 effect(DEF dst, USE src);
8645 predicate(false);
8646
8647 format %{ "SRAWI $dst, $src, #31" %}
8648 size(4);
8649 ins_encode %{
8650 __ srawi($dst$$Register, $src$$Register, 0x1f);
8651 %}
8652 ins_pipe(pipe_class_default);
8653 %}
8654
8655 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
8656 match(Set dst (AbsI src));
8657 ins_cost(DEFAULT_COST*3);
8658
8659 expand %{
8660 iRegIdst tmp1;
8661 iRegIdst tmp2;
8662 signmask32I_regI(tmp1, src);
8663 xorI_reg_reg(tmp2, tmp1, src);
8664 subI_reg_reg(dst, tmp2, tmp1);
8665 %}
8666 %}
8667
8668 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
8669 match(Set dst (SubI zero src2));
8670 format %{ "NEG $dst, $src2" %}
8671 size(4);
8672 ins_encode %{
8673 __ neg($dst$$Register, $src2$$Register);
8674 %}
8675 ins_pipe(pipe_class_default);
8676 %}
8677
8678 // Long subtraction
8679 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8680 match(Set dst (SubL src1 src2));
8681 format %{ "SUBF $dst, $src2, $src1 \t// long" %}
8682 size(4);
8683 ins_encode %{
8684 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8685 %}
8686 ins_pipe(pipe_class_default);
8687 %}
8688
8689 // SubL + convL2I.
8690 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8691 match(Set dst (ConvL2I (SubL src1 src2)));
8692
8693 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
8694 size(4);
8695 ins_encode %{
8696 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8697 %}
8698 ins_pipe(pipe_class_default);
8699 %}
8700
8701 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8702 // positive longs and 0xF...F for negative ones.
8703 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8704 // no match-rule, false predicate
8705 effect(DEF dst, USE src);
8706 predicate(false);
8707
8708 format %{ "SRADI $dst, $src, #63" %}
8709 size(4);
8710 ins_encode %{
8711 __ sradi($dst$$Register, $src$$Register, 0x3f);
8712 %}
8713 ins_pipe(pipe_class_default);
8714 %}
8715
8716 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8717 // positive longs and 0xF...F for negative ones.
8718 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8719 // no match-rule, false predicate
8720 effect(DEF dst, USE src);
8721 predicate(false);
8722
8723 format %{ "SRADI $dst, $src, #63" %}
8724 size(4);
8725 ins_encode %{
8726 __ sradi($dst$$Register, $src$$Register, 0x3f);
8727 %}
8728 ins_pipe(pipe_class_default);
8729 %}
8730
8731 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{
8732 match(Set dst (AbsL src));
8733 ins_cost(DEFAULT_COST*3);
8734
8735 expand %{
8736 iRegLdst tmp1;
8737 iRegLdst tmp2;
8738 signmask64L_regL(tmp1, src);
8739 xorL_reg_reg(tmp2, tmp1, src);
8740 subL_reg_reg(dst, tmp2, tmp1);
8741 %}
8742 %}
8743
8744 // Long negation
8745 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8746 match(Set dst (SubL zero src2));
8747 format %{ "NEG $dst, $src2 \t// long" %}
8748 size(4);
8749 ins_encode %{
8750 __ neg($dst$$Register, $src2$$Register);
8751 %}
8752 ins_pipe(pipe_class_default);
8753 %}
8754
8755 // NegL + ConvL2I.
8756 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8757 match(Set dst (ConvL2I (SubL zero src2)));
8758
8759 format %{ "NEG $dst, $src2 \t// long + l2i" %}
8760 size(4);
8761 ins_encode %{
8762 __ neg($dst$$Register, $src2$$Register);
8763 %}
8764 ins_pipe(pipe_class_default);
8765 %}
8766
8767 // Multiplication Instructions
8768 // Integer Multiplication
8769
8770 // Register Multiplication
8771 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8772 match(Set dst (MulI src1 src2));
8773 ins_cost(DEFAULT_COST);
8774
8775 format %{ "MULLW $dst, $src1, $src2" %}
8776 size(4);
8777 ins_encode %{
8778 __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8779 %}
8780 ins_pipe(pipe_class_default);
8781 %}
8782
8783 // Immediate Multiplication
8784 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8785 match(Set dst (MulI src1 src2));
8786 ins_cost(DEFAULT_COST);
8787
8788 format %{ "MULLI $dst, $src1, $src2" %}
8789 size(4);
8790 ins_encode %{
8791 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8792 %}
8793 ins_pipe(pipe_class_default);
8794 %}
8795
8796 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8797 match(Set dst (MulL src1 src2));
8798 ins_cost(DEFAULT_COST);
8799
8800 format %{ "MULLD $dst $src1, $src2 \t// long" %}
8801 size(4);
8802 ins_encode %{
8803 __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8804 %}
8805 ins_pipe(pipe_class_default);
8806 %}
8807
8808 // Multiply high for optimized long division by constant.
8809 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8810 match(Set dst (MulHiL src1 src2));
8811 ins_cost(DEFAULT_COST);
8812
8813 format %{ "MULHD $dst $src1, $src2 \t// long" %}
8814 size(4);
8815 ins_encode %{
8816 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8817 %}
8818 ins_pipe(pipe_class_default);
8819 %}
8820
8821 // Immediate Multiplication
8822 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8823 match(Set dst (MulL src1 src2));
8824 ins_cost(DEFAULT_COST);
8825
8826 format %{ "MULLI $dst, $src1, $src2" %}
8827 size(4);
8828 ins_encode %{
8829 __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8830 %}
8831 ins_pipe(pipe_class_default);
8832 %}
8833
8834 // Integer Division with Immediate -1: Negate.
8835 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8836 match(Set dst (DivI src1 src2));
8837 ins_cost(DEFAULT_COST);
8838
8839 format %{ "NEG $dst, $src1 \t// /-1" %}
8840 size(4);
8841 ins_encode %{
8842 __ neg($dst$$Register, $src1$$Register);
8843 %}
8844 ins_pipe(pipe_class_default);
8845 %}
8846
8847 // Integer Division with constant, but not -1.
8848 // We should be able to improve this by checking the type of src2.
8849 // It might well be that src2 is known to be positive.
8850 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8851 match(Set dst (DivI src1 src2));
8852 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8853 ins_cost(2*DEFAULT_COST);
8854
8855 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8856 size(4);
8857 ins_encode %{
8858 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8859 %}
8860 ins_pipe(pipe_class_default);
8861 %}
8862
8863 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8864 effect(USE_DEF dst, USE src1, USE crx);
8865 predicate(false);
8866
8867 ins_variable_size_depending_on_alignment(true);
8868
8869 format %{ "CMOVE $dst, neg($src1), $crx" %}
8870 // Worst case is branch + move + stop, no stop without scheduler.
8871 size(8);
8872 ins_encode %{
8873 Label done;
8874 __ bne($crx$$CondRegister, done);
8875 __ neg($dst$$Register, $src1$$Register);
8876 __ bind(done);
8877 %}
8878 ins_pipe(pipe_class_default);
8879 %}
8880
8881 // Integer Division with Registers not containing constants.
8882 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8883 match(Set dst (DivI src1 src2));
8884 ins_cost(10*DEFAULT_COST);
8885
8886 expand %{
8887 immI16 imm %{ (int)-1 %}
8888 flagsReg tmp1;
8889 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8890 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8891 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8892 %}
8893 %}
8894
8895 // Long Division with Immediate -1: Negate.
8896 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8897 match(Set dst (DivL src1 src2));
8898 ins_cost(DEFAULT_COST);
8899
8900 format %{ "NEG $dst, $src1 \t// /-1, long" %}
8901 size(4);
8902 ins_encode %{
8903 __ neg($dst$$Register, $src1$$Register);
8904 %}
8905 ins_pipe(pipe_class_default);
8906 %}
8907
8908 // Long Division with constant, but not -1.
8909 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8910 match(Set dst (DivL src1 src2));
8911 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8912 ins_cost(2*DEFAULT_COST);
8913
8914 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8915 size(4);
8916 ins_encode %{
8917 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8918 %}
8919 ins_pipe(pipe_class_default);
8920 %}
8921
8922 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8923 effect(USE_DEF dst, USE src1, USE crx);
8924 predicate(false);
8925
8926 ins_variable_size_depending_on_alignment(true);
8927
8928 format %{ "CMOVE $dst, neg($src1), $crx" %}
8929 // Worst case is branch + move + stop, no stop without scheduler.
8930 size(8);
8931 ins_encode %{
8932 Label done;
8933 __ bne($crx$$CondRegister, done);
8934 __ neg($dst$$Register, $src1$$Register);
8935 __ bind(done);
8936 %}
8937 ins_pipe(pipe_class_default);
8938 %}
8939
8940 // Long Division with Registers not containing constants.
8941 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8942 match(Set dst (DivL src1 src2));
8943 ins_cost(10*DEFAULT_COST);
8944
8945 expand %{
8946 immL16 imm %{ (int)-1 %}
8947 flagsReg tmp1;
8948 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8949 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2
8950 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1
8951 %}
8952 %}
8953
8954 // Integer Remainder with registers.
8955 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8956 match(Set dst (ModI src1 src2));
8957 ins_cost(10*DEFAULT_COST);
8958
8959 expand %{
8960 immI16 imm %{ (int)-1 %}
8961 flagsReg tmp1;
8962 iRegIdst tmp2;
8963 iRegIdst tmp3;
8964 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8965 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8966 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8967 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8968 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8969 %}
8970 %}
8971
8972 // Long Remainder with registers
8973 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8974 match(Set dst (ModL src1 src2));
8975 ins_cost(10*DEFAULT_COST);
8976
8977 expand %{
8978 immL16 imm %{ (int)-1 %}
8979 flagsReg tmp1;
8980 iRegLdst tmp2;
8981 iRegLdst tmp3;
8982 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8983 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8984 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8985 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8986 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8987 %}
8988 %}
8989
8990 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8991 match(Set dst (UDivI src1 src2));
8992 format %{ "DIVWU $dst, $src1, $src2" %}
8993 size(4);
8994 ins_encode %{
8995 __ divwu($dst$$Register, $src1$$Register, $src2$$Register);
8996 %}
8997 ins_pipe(pipe_class_default);
8998 %}
8999
9000 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9001 match(Set dst (UModI src1 src2));
9002 expand %{
9003 iRegIdst tmp1;
9004 iRegIdst tmp2;
9005 udivI_reg_reg(tmp1, src1, src2);
9006 // Compute lower 32 bit result using signed instructions as suggested by ISA.
9007 // Upper 32 bit will contain garbage.
9008 mulI_reg_reg(tmp2, src2, tmp1);
9009 subI_reg_reg(dst, src1, tmp2);
9010 %}
9011 %}
9012
9013 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9014 match(Set dst (UDivL src1 src2));
9015 format %{ "DIVDU $dst, $src1, $src2" %}
9016 size(4);
9017 ins_encode %{
9018 __ divdu($dst$$Register, $src1$$Register, $src2$$Register);
9019 %}
9020 ins_pipe(pipe_class_default);
9021 %}
9022
9023 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9024 match(Set dst (UModL src1 src2));
9025 expand %{
9026 iRegLdst tmp1;
9027 iRegLdst tmp2;
9028 udivL_reg_reg(tmp1, src1, src2);
9029 mulL_reg_reg(tmp2, src2, tmp1);
9030 subL_reg_reg(dst, src1, tmp2);
9031 %}
9032 %}
9033
9034 // Integer Shift Instructions
9035
9036 // Register Shift Left
9037
9038 // Clear all but the lowest #mask bits.
9039 // Used to normalize shift amounts in registers.
9040 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
9041 // no match-rule, false predicate
9042 effect(DEF dst, USE src, USE mask);
9043 predicate(false);
9044
9045 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %}
9046 size(4);
9047 ins_encode %{
9048 __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
9049 %}
9050 ins_pipe(pipe_class_default);
9051 %}
9052
9053 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9054 // no match-rule, false predicate
9055 effect(DEF dst, USE src1, USE src2);
9056 predicate(false);
9057
9058 format %{ "SLW $dst, $src1, $src2" %}
9059 size(4);
9060 ins_encode %{
9061 __ slw($dst$$Register, $src1$$Register, $src2$$Register);
9062 %}
9063 ins_pipe(pipe_class_default);
9064 %}
9065
9066 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9067 match(Set dst (LShiftI src1 src2));
9068 ins_cost(DEFAULT_COST*2);
9069 expand %{
9070 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
9071 iRegIdst tmpI;
9072 maskI_reg_imm(tmpI, src2, mask);
9073 lShiftI_reg_reg(dst, src1, tmpI);
9074 %}
9075 %}
9076
9077 // Register Shift Left Immediate
9078 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
9079 match(Set dst (LShiftI src1 src2));
9080
9081 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %}
9082 size(4);
9083 ins_encode %{
9084 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
9085 %}
9086 ins_pipe(pipe_class_default);
9087 %}
9088
9089 // AndI with negpow2-constant + LShiftI
9090 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
9091 match(Set dst (LShiftI (AndI src1 src2) src3));
9092 predicate(UseRotateAndMaskInstructionsPPC64);
9093
9094 format %{ "RLWINM $dst, lShiftI(AndI($src1, $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, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
9103 }
9104 %}
9105 ins_pipe(pipe_class_default);
9106 %}
9107
9108 // RShiftI + AndI with negpow2-constant + LShiftI
9109 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
9110 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
9111 predicate(UseRotateAndMaskInstructionsPPC64);
9112
9113 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
9114 size(4);
9115 ins_encode %{
9116 long src3 = $src3$$constant;
9117 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant);
9118 if (maskbits >= 32) {
9119 __ li($dst$$Register, 0); // addi
9120 } else {
9121 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
9122 }
9123 %}
9124 ins_pipe(pipe_class_default);
9125 %}
9126
9127 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9128 // no match-rule, false predicate
9129 effect(DEF dst, USE src1, USE src2);
9130 predicate(false);
9131
9132 format %{ "SLD $dst, $src1, $src2" %}
9133 size(4);
9134 ins_encode %{
9135 __ sld($dst$$Register, $src1$$Register, $src2$$Register);
9136 %}
9137 ins_pipe(pipe_class_default);
9138 %}
9139
9140 // Register Shift Left
9141 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9142 match(Set dst (LShiftL src1 src2));
9143 ins_cost(DEFAULT_COST*2);
9144 expand %{
9145 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
9146 iRegIdst tmpI;
9147 maskI_reg_imm(tmpI, src2, mask);
9148 lShiftL_regL_regI(dst, src1, tmpI);
9149 %}
9150 %}
9151
9152 // Register Shift Left Immediate
9153 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
9154 match(Set dst (LShiftL src1 src2));
9155 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %}
9156 size(4);
9157 ins_encode %{
9158 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9159 %}
9160 ins_pipe(pipe_class_default);
9161 %}
9162
9163 // If we shift more than 32 bits, we need not convert I2L.
9164 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
9165 match(Set dst (LShiftL (ConvI2L src1) src2));
9166 ins_cost(DEFAULT_COST);
9167
9168 size(4);
9169 format %{ "SLDI $dst, i2l($src1), $src2" %}
9170 ins_encode %{
9171 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9172 %}
9173 ins_pipe(pipe_class_default);
9174 %}
9175
9176 // Shift a postivie int to the left.
9177 // Clrlsldi clears the upper 32 bits and shifts.
9178 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
9179 match(Set dst (LShiftL (ConvI2L src1) src2));
9180 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
9181
9182 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %}
9183 size(4);
9184 ins_encode %{
9185 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
9186 %}
9187 ins_pipe(pipe_class_default);
9188 %}
9189
9190 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9191 // no match-rule, false predicate
9192 effect(DEF dst, USE src1, USE src2);
9193 predicate(false);
9194
9195 format %{ "SRAW $dst, $src1, $src2" %}
9196 size(4);
9197 ins_encode %{
9198 __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
9199 %}
9200 ins_pipe(pipe_class_default);
9201 %}
9202
9203 // Register Arithmetic Shift Right
9204 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9205 match(Set dst (RShiftI src1 src2));
9206 ins_cost(DEFAULT_COST*2);
9207 expand %{
9208 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
9209 iRegIdst tmpI;
9210 maskI_reg_imm(tmpI, src2, mask);
9211 arShiftI_reg_reg(dst, src1, tmpI);
9212 %}
9213 %}
9214
9215 // Register Arithmetic Shift Right Immediate
9216 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
9217 match(Set dst (RShiftI src1 src2));
9218
9219 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %}
9220 size(4);
9221 ins_encode %{
9222 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
9223 %}
9224 ins_pipe(pipe_class_default);
9225 %}
9226
9227 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9228 // no match-rule, false predicate
9229 effect(DEF dst, USE src1, USE src2);
9230 predicate(false);
9231
9232 format %{ "SRAD $dst, $src1, $src2" %}
9233 size(4);
9234 ins_encode %{
9235 __ srad($dst$$Register, $src1$$Register, $src2$$Register);
9236 %}
9237 ins_pipe(pipe_class_default);
9238 %}
9239
9240 // Register Shift Right Arithmetic Long
9241 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9242 match(Set dst (RShiftL src1 src2));
9243 ins_cost(DEFAULT_COST*2);
9244
9245 expand %{
9246 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
9247 iRegIdst tmpI;
9248 maskI_reg_imm(tmpI, src2, mask);
9249 arShiftL_regL_regI(dst, src1, tmpI);
9250 %}
9251 %}
9252
9253 // Register Shift Right Immediate
9254 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
9255 match(Set dst (RShiftL src1 src2));
9256
9257 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %}
9258 size(4);
9259 ins_encode %{
9260 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9261 %}
9262 ins_pipe(pipe_class_default);
9263 %}
9264
9265 // RShiftL + ConvL2I
9266 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
9267 match(Set dst (ConvL2I (RShiftL src1 src2)));
9268
9269 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
9270 size(4);
9271 ins_encode %{
9272 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9273 %}
9274 ins_pipe(pipe_class_default);
9275 %}
9276
9277 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9278 // no match-rule, false predicate
9279 effect(DEF dst, USE src1, USE src2);
9280 predicate(false);
9281
9282 format %{ "SRW $dst, $src1, $src2" %}
9283 size(4);
9284 ins_encode %{
9285 __ srw($dst$$Register, $src1$$Register, $src2$$Register);
9286 %}
9287 ins_pipe(pipe_class_default);
9288 %}
9289
9290 // Register Shift Right
9291 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9292 match(Set dst (URShiftI src1 src2));
9293 ins_cost(DEFAULT_COST*2);
9294
9295 expand %{
9296 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
9297 iRegIdst tmpI;
9298 maskI_reg_imm(tmpI, src2, mask);
9299 urShiftI_reg_reg(dst, src1, tmpI);
9300 %}
9301 %}
9302
9303 // Register Shift Right Immediate
9304 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
9305 match(Set dst (URShiftI src1 src2));
9306
9307 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %}
9308 size(4);
9309 ins_encode %{
9310 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
9311 %}
9312 ins_pipe(pipe_class_default);
9313 %}
9314
9315 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9316 // no match-rule, false predicate
9317 effect(DEF dst, USE src1, USE src2);
9318 predicate(false);
9319
9320 format %{ "SRD $dst, $src1, $src2" %}
9321 size(4);
9322 ins_encode %{
9323 __ srd($dst$$Register, $src1$$Register, $src2$$Register);
9324 %}
9325 ins_pipe(pipe_class_default);
9326 %}
9327
9328 // Register Shift Right
9329 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9330 match(Set dst (URShiftL src1 src2));
9331 ins_cost(DEFAULT_COST*2);
9332
9333 expand %{
9334 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
9335 iRegIdst tmpI;
9336 maskI_reg_imm(tmpI, src2, mask);
9337 urShiftL_regL_regI(dst, src1, tmpI);
9338 %}
9339 %}
9340
9341 // Register Shift Right Immediate
9342 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
9343 match(Set dst (URShiftL src1 src2));
9344
9345 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %}
9346 size(4);
9347 ins_encode %{
9348 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9349 %}
9350 ins_pipe(pipe_class_default);
9351 %}
9352
9353 // URShiftL + ConvL2I.
9354 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
9355 match(Set dst (ConvL2I (URShiftL src1 src2)));
9356
9357 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
9358 size(4);
9359 ins_encode %{
9360 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9361 %}
9362 ins_pipe(pipe_class_default);
9363 %}
9364
9365 // Register Shift Right Immediate with a CastP2X
9366 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
9367 match(Set dst (URShiftL (CastP2X src1) src2));
9368
9369 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
9370 size(4);
9371 ins_encode %{
9372 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9373 %}
9374 ins_pipe(pipe_class_default);
9375 %}
9376
9377 // Bitfield Extract: URShiftI + AndI
9378 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
9379 match(Set dst (AndI (URShiftI src1 src2) src3));
9380
9381 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
9382 size(4);
9383 ins_encode %{
9384 int rshift = ($src2$$constant) & 0x1f;
9385 int length = log2i_exact((juint)$src3$$constant + 1u);
9386 if (rshift + length > 32) {
9387 // if necessary, adjust mask to omit rotated bits.
9388 length = 32 - rshift;
9389 }
9390 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
9391 %}
9392 ins_pipe(pipe_class_default);
9393 %}
9394
9395 // Bitfield Extract: URShiftL + AndL
9396 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
9397 match(Set dst (AndL (URShiftL src1 src2) src3));
9398
9399 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
9400 size(4);
9401 ins_encode %{
9402 int rshift = ($src2$$constant) & 0x3f;
9403 int length = log2i_exact((julong)$src3$$constant + 1ull);
9404 if (rshift + length > 64) {
9405 // if necessary, adjust mask to omit rotated bits.
9406 length = 64 - rshift;
9407 }
9408 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
9409 %}
9410 ins_pipe(pipe_class_default);
9411 %}
9412
9413 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
9414 match(Set dst (ConvL2I (ConvI2L src)));
9415
9416 format %{ "EXTSW $dst, $src \t// int->int" %}
9417 size(4);
9418 ins_encode %{
9419 __ extsw($dst$$Register, $src$$Register);
9420 %}
9421 ins_pipe(pipe_class_default);
9422 %}
9423
9424 //----------Rotate Instructions------------------------------------------------
9425
9426 // Rotate Left by 8-bit immediate
9427 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
9428 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
9429 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9430
9431 format %{ "ROTLWI $dst, $src, $lshift" %}
9432 size(4);
9433 ins_encode %{
9434 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
9435 %}
9436 ins_pipe(pipe_class_default);
9437 %}
9438
9439 // Rotate Right by 8-bit immediate
9440 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
9441 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
9442 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9443
9444 format %{ "ROTRWI $dst, $rshift" %}
9445 size(4);
9446 ins_encode %{
9447 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
9448 %}
9449 ins_pipe(pipe_class_default);
9450 %}
9451
9452 //----------Floating Point Arithmetic Instructions-----------------------------
9453
9454 // Add float single precision
9455 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
9456 match(Set dst (AddF src1 src2));
9457
9458 format %{ "FADDS $dst, $src1, $src2" %}
9459 size(4);
9460 ins_encode %{
9461 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9462 %}
9463 ins_pipe(pipe_class_default);
9464 %}
9465
9466 // Add float double precision
9467 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
9468 match(Set dst (AddD src1 src2));
9469
9470 format %{ "FADD $dst, $src1, $src2" %}
9471 size(4);
9472 ins_encode %{
9473 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9474 %}
9475 ins_pipe(pipe_class_default);
9476 %}
9477
9478 // Sub float single precision
9479 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
9480 match(Set dst (SubF src1 src2));
9481
9482 format %{ "FSUBS $dst, $src1, $src2" %}
9483 size(4);
9484 ins_encode %{
9485 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9486 %}
9487 ins_pipe(pipe_class_default);
9488 %}
9489
9490 // Sub float double precision
9491 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
9492 match(Set dst (SubD src1 src2));
9493 format %{ "FSUB $dst, $src1, $src2" %}
9494 size(4);
9495 ins_encode %{
9496 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9497 %}
9498 ins_pipe(pipe_class_default);
9499 %}
9500
9501 // Mul float single precision
9502 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
9503 match(Set dst (MulF src1 src2));
9504 format %{ "FMULS $dst, $src1, $src2" %}
9505 size(4);
9506 ins_encode %{
9507 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9508 %}
9509 ins_pipe(pipe_class_default);
9510 %}
9511
9512 // Mul float double precision
9513 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
9514 match(Set dst (MulD src1 src2));
9515 format %{ "FMUL $dst, $src1, $src2" %}
9516 size(4);
9517 ins_encode %{
9518 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9519 %}
9520 ins_pipe(pipe_class_default);
9521 %}
9522
9523 // Div float single precision
9524 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
9525 match(Set dst (DivF src1 src2));
9526 format %{ "FDIVS $dst, $src1, $src2" %}
9527 size(4);
9528 ins_encode %{
9529 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9530 %}
9531 ins_pipe(pipe_class_default);
9532 %}
9533
9534 // Div float double precision
9535 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
9536 match(Set dst (DivD src1 src2));
9537 format %{ "FDIV $dst, $src1, $src2" %}
9538 size(4);
9539 ins_encode %{
9540 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9541 %}
9542 ins_pipe(pipe_class_default);
9543 %}
9544
9545 // Absolute float single precision
9546 instruct absF_reg(regF dst, regF src) %{
9547 match(Set dst (AbsF src));
9548 format %{ "FABS $dst, $src \t// float" %}
9549 size(4);
9550 ins_encode %{
9551 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
9552 %}
9553 ins_pipe(pipe_class_default);
9554 %}
9555
9556 // Absolute float double precision
9557 instruct absD_reg(regD dst, regD src) %{
9558 match(Set dst (AbsD src));
9559 format %{ "FABS $dst, $src \t// double" %}
9560 size(4);
9561 ins_encode %{
9562 __ fabs($dst$$FloatRegister, $src$$FloatRegister);
9563 %}
9564 ins_pipe(pipe_class_default);
9565 %}
9566
9567 instruct negF_reg(regF dst, regF src) %{
9568 match(Set dst (NegF src));
9569 format %{ "FNEG $dst, $src \t// float" %}
9570 size(4);
9571 ins_encode %{
9572 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
9573 %}
9574 ins_pipe(pipe_class_default);
9575 %}
9576
9577 instruct negD_reg(regD dst, regD src) %{
9578 match(Set dst (NegD src));
9579 format %{ "FNEG $dst, $src \t// double" %}
9580 size(4);
9581 ins_encode %{
9582 __ fneg($dst$$FloatRegister, $src$$FloatRegister);
9583 %}
9584 ins_pipe(pipe_class_default);
9585 %}
9586
9587 // AbsF + NegF.
9588 instruct negF_absF_reg(regF dst, regF src) %{
9589 match(Set dst (NegF (AbsF src)));
9590 format %{ "FNABS $dst, $src \t// float" %}
9591 size(4);
9592 ins_encode %{
9593 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9594 %}
9595 ins_pipe(pipe_class_default);
9596 %}
9597
9598 // AbsD + NegD.
9599 instruct negD_absD_reg(regD dst, regD src) %{
9600 match(Set dst (NegD (AbsD src)));
9601 format %{ "FNABS $dst, $src \t// double" %}
9602 size(4);
9603 ins_encode %{
9604 __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9605 %}
9606 ins_pipe(pipe_class_default);
9607 %}
9608
9609 // VM_Version::has_fsqrt() decides if this node will be used.
9610 // Sqrt float double precision
9611 instruct sqrtD_reg(regD dst, regD src) %{
9612 match(Set dst (SqrtD src));
9613 format %{ "FSQRT $dst, $src" %}
9614 size(4);
9615 ins_encode %{
9616 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
9617 %}
9618 ins_pipe(pipe_class_default);
9619 %}
9620
9621 // Single-precision sqrt.
9622 instruct sqrtF_reg(regF dst, regF src) %{
9623 match(Set dst (SqrtF src));
9624 predicate(VM_Version::has_fsqrts());
9625 ins_cost(DEFAULT_COST);
9626
9627 format %{ "FSQRTS $dst, $src" %}
9628 size(4);
9629 ins_encode %{
9630 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
9631 %}
9632 ins_pipe(pipe_class_default);
9633 %}
9634
9635 instruct roundDouble_nop(regD dst) %{
9636 match(Set dst (RoundDouble dst));
9637 ins_cost(0);
9638
9639 format %{ " -- \t// RoundDouble not needed - empty" %}
9640 size(0);
9641 // PPC results are already "rounded" (i.e., normal-format IEEE).
9642 ins_encode( /*empty*/ );
9643 ins_pipe(pipe_class_default);
9644 %}
9645
9646 instruct roundFloat_nop(regF dst) %{
9647 match(Set dst (RoundFloat dst));
9648 ins_cost(0);
9649
9650 format %{ " -- \t// RoundFloat not needed - empty" %}
9651 size(0);
9652 // PPC results are already "rounded" (i.e., normal-format IEEE).
9653 ins_encode( /*empty*/ );
9654 ins_pipe(pipe_class_default);
9655 %}
9656
9657
9658 // Multiply-Accumulate
9659 // src1 * src2 + src3
9660 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9661 match(Set dst (FmaF src3 (Binary src1 src2)));
9662
9663 format %{ "FMADDS $dst, $src1, $src2, $src3" %}
9664 size(4);
9665 ins_encode %{
9666 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9667 %}
9668 ins_pipe(pipe_class_default);
9669 %}
9670
9671 // src1 * src2 + src3
9672 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9673 match(Set dst (FmaD src3 (Binary src1 src2)));
9674
9675 format %{ "FMADD $dst, $src1, $src2, $src3" %}
9676 size(4);
9677 ins_encode %{
9678 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9679 %}
9680 ins_pipe(pipe_class_default);
9681 %}
9682
9683 // -src1 * src2 + src3 = -(src1*src2-src3)
9684 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9685 match(Set dst (FmaF src3 (Binary (NegF src1) src2)));
9686 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
9687
9688 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
9689 size(4);
9690 ins_encode %{
9691 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9692 %}
9693 ins_pipe(pipe_class_default);
9694 %}
9695
9696 // -src1 * src2 + src3 = -(src1*src2-src3)
9697 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9698 match(Set dst (FmaD src3 (Binary (NegD src1) src2)));
9699 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
9700
9701 format %{ "FNMSUB $dst, $src1, $src2, $src3" %}
9702 size(4);
9703 ins_encode %{
9704 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9705 %}
9706 ins_pipe(pipe_class_default);
9707 %}
9708
9709 // -src1 * src2 - src3 = -(src1*src2+src3)
9710 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9711 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2)));
9712 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
9713
9714 format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
9715 size(4);
9716 ins_encode %{
9717 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9718 %}
9719 ins_pipe(pipe_class_default);
9720 %}
9721
9722 // -src1 * src2 - src3 = -(src1*src2+src3)
9723 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9724 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2)));
9725 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9726
9727 format %{ "FNMADD $dst, $src1, $src2, $src3" %}
9728 size(4);
9729 ins_encode %{
9730 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9731 %}
9732 ins_pipe(pipe_class_default);
9733 %}
9734
9735 // src1 * src2 - src3
9736 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9737 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9738
9739 format %{ "FMSUBS $dst, $src1, $src2, $src3" %}
9740 size(4);
9741 ins_encode %{
9742 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9743 %}
9744 ins_pipe(pipe_class_default);
9745 %}
9746
9747 // src1 * src2 - src3
9748 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9749 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9750
9751 format %{ "FMSUB $dst, $src1, $src2, $src3" %}
9752 size(4);
9753 ins_encode %{
9754 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9755 %}
9756 ins_pipe(pipe_class_default);
9757 %}
9758
9759
9760 //----------Logical Instructions-----------------------------------------------
9761
9762 // And Instructions
9763
9764 // Register And
9765 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9766 match(Set dst (AndI src1 src2));
9767 format %{ "AND $dst, $src1, $src2" %}
9768 size(4);
9769 ins_encode %{
9770 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9771 %}
9772 ins_pipe(pipe_class_default);
9773 %}
9774
9775 // Left shifted Immediate And
9776 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{
9777 match(Set dst (AndI src1 src2));
9778 effect(KILL cr0);
9779 format %{ "ANDIS $dst, $src1, $src2.hi" %}
9780 size(4);
9781 ins_encode %{
9782 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16)));
9783 %}
9784 ins_pipe(pipe_class_default);
9785 %}
9786
9787 // Immediate And
9788 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{
9789 match(Set dst (AndI src1 src2));
9790 effect(KILL cr0);
9791
9792 format %{ "ANDI $dst, $src1, $src2" %}
9793 size(4);
9794 ins_encode %{
9795 // FIXME: avoid andi_ ?
9796 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9797 %}
9798 ins_pipe(pipe_class_default);
9799 %}
9800
9801 // Immediate And where the immediate is a negative power of 2.
9802 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{
9803 match(Set dst (AndI src1 src2));
9804 format %{ "ANDWI $dst, $src1, $src2" %}
9805 size(4);
9806 ins_encode %{
9807 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant));
9808 %}
9809 ins_pipe(pipe_class_default);
9810 %}
9811
9812 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{
9813 match(Set dst (AndI src1 src2));
9814 format %{ "ANDWI $dst, $src1, $src2" %}
9815 size(4);
9816 ins_encode %{
9817 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u));
9818 %}
9819 ins_pipe(pipe_class_default);
9820 %}
9821
9822 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{
9823 match(Set dst (AndI src1 src2));
9824 predicate(UseRotateAndMaskInstructionsPPC64);
9825 format %{ "ANDWI $dst, $src1, $src2" %}
9826 size(4);
9827 ins_encode %{
9828 int bitpos = 31 - log2i_exact((juint)$src2$$constant);
9829 __ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos);
9830 %}
9831 ins_pipe(pipe_class_default);
9832 %}
9833
9834 // Register And Long
9835 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9836 match(Set dst (AndL src1 src2));
9837 ins_cost(DEFAULT_COST);
9838
9839 format %{ "AND $dst, $src1, $src2 \t// long" %}
9840 size(4);
9841 ins_encode %{
9842 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9843 %}
9844 ins_pipe(pipe_class_default);
9845 %}
9846
9847 // Immediate And long
9848 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
9849 match(Set dst (AndL src1 src2));
9850 effect(KILL cr0);
9851
9852 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9853 size(4);
9854 ins_encode %{
9855 // FIXME: avoid andi_ ?
9856 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9857 %}
9858 ins_pipe(pipe_class_default);
9859 %}
9860
9861 // Immediate And Long where the immediate is a negative power of 2.
9862 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
9863 match(Set dst (AndL src1 src2));
9864 format %{ "ANDDI $dst, $src1, $src2" %}
9865 size(4);
9866 ins_encode %{
9867 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant));
9868 %}
9869 ins_pipe(pipe_class_default);
9870 %}
9871
9872 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9873 match(Set dst (AndL src1 src2));
9874 format %{ "ANDDI $dst, $src1, $src2" %}
9875 size(4);
9876 ins_encode %{
9877 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9878 %}
9879 ins_pipe(pipe_class_default);
9880 %}
9881
9882 // AndL + ConvL2I.
9883 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9884 match(Set dst (ConvL2I (AndL src1 src2)));
9885 ins_cost(DEFAULT_COST);
9886
9887 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %}
9888 size(4);
9889 ins_encode %{
9890 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
9891 %}
9892 ins_pipe(pipe_class_default);
9893 %}
9894
9895 // Or Instructions
9896
9897 // Register Or
9898 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9899 match(Set dst (OrI src1 src2));
9900 format %{ "OR $dst, $src1, $src2" %}
9901 size(4);
9902 ins_encode %{
9903 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9904 %}
9905 ins_pipe(pipe_class_default);
9906 %}
9907
9908 // Expand does not work with above instruct. (??)
9909 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9910 // no match-rule
9911 effect(DEF dst, USE src1, USE src2);
9912 format %{ "OR $dst, $src1, $src2" %}
9913 size(4);
9914 ins_encode %{
9915 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9916 %}
9917 ins_pipe(pipe_class_default);
9918 %}
9919
9920 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9921 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9922 ins_cost(DEFAULT_COST*3);
9923
9924 expand %{
9925 // FIXME: we should do this in the ideal world.
9926 iRegIdst tmp1;
9927 iRegIdst tmp2;
9928 orI_reg_reg(tmp1, src1, src2);
9929 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9930 orI_reg_reg(dst, tmp1, tmp2);
9931 %}
9932 %}
9933
9934 // Immediate Or
9935 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9936 match(Set dst (OrI src1 src2));
9937 format %{ "ORI $dst, $src1, $src2" %}
9938 size(4);
9939 ins_encode %{
9940 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9941 %}
9942 ins_pipe(pipe_class_default);
9943 %}
9944
9945 // Register Or Long
9946 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9947 match(Set dst (OrL src1 src2));
9948 ins_cost(DEFAULT_COST);
9949
9950 size(4);
9951 format %{ "OR $dst, $src1, $src2 \t// long" %}
9952 ins_encode %{
9953 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9954 %}
9955 ins_pipe(pipe_class_default);
9956 %}
9957
9958 // OrL + ConvL2I.
9959 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9960 match(Set dst (ConvL2I (OrL src1 src2)));
9961 ins_cost(DEFAULT_COST);
9962
9963 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %}
9964 size(4);
9965 ins_encode %{
9966 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9967 %}
9968 ins_pipe(pipe_class_default);
9969 %}
9970
9971 // Immediate Or long
9972 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9973 match(Set dst (OrL src1 con));
9974 ins_cost(DEFAULT_COST);
9975
9976 format %{ "ORI $dst, $src1, $con \t// long" %}
9977 size(4);
9978 ins_encode %{
9979 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9980 %}
9981 ins_pipe(pipe_class_default);
9982 %}
9983
9984 // Xor Instructions
9985
9986 // Register Xor
9987 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9988 match(Set dst (XorI src1 src2));
9989 format %{ "XOR $dst, $src1, $src2" %}
9990 size(4);
9991 ins_encode %{
9992 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9993 %}
9994 ins_pipe(pipe_class_default);
9995 %}
9996
9997 // Expand does not work with above instruct. (??)
9998 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9999 // no match-rule
10000 effect(DEF dst, USE src1, USE src2);
10001 format %{ "XOR $dst, $src1, $src2" %}
10002 size(4);
10003 ins_encode %{
10004 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
10005 %}
10006 ins_pipe(pipe_class_default);
10007 %}
10008
10009 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
10010 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
10011 ins_cost(DEFAULT_COST*3);
10012
10013 expand %{
10014 // FIXME: we should do this in the ideal world.
10015 iRegIdst tmp1;
10016 iRegIdst tmp2;
10017 xorI_reg_reg(tmp1, src1, src2);
10018 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
10019 xorI_reg_reg(dst, tmp1, tmp2);
10020 %}
10021 %}
10022
10023 // Immediate Xor
10024 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
10025 match(Set dst (XorI src1 src2));
10026 format %{ "XORI $dst, $src1, $src2" %}
10027 size(4);
10028 ins_encode %{
10029 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
10030 %}
10031 ins_pipe(pipe_class_default);
10032 %}
10033
10034 // Register Xor Long
10035 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
10036 match(Set dst (XorL src1 src2));
10037 ins_cost(DEFAULT_COST);
10038
10039 format %{ "XOR $dst, $src1, $src2 \t// long" %}
10040 size(4);
10041 ins_encode %{
10042 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
10043 %}
10044 ins_pipe(pipe_class_default);
10045 %}
10046
10047 // XorL + ConvL2I.
10048 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
10049 match(Set dst (ConvL2I (XorL src1 src2)));
10050 ins_cost(DEFAULT_COST);
10051
10052 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %}
10053 size(4);
10054 ins_encode %{
10055 __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
10056 %}
10057 ins_pipe(pipe_class_default);
10058 %}
10059
10060 // Immediate Xor Long
10061 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
10062 match(Set dst (XorL src1 src2));
10063 ins_cost(DEFAULT_COST);
10064
10065 format %{ "XORI $dst, $src1, $src2 \t// long" %}
10066 size(4);
10067 ins_encode %{
10068 __ xori($dst$$Register, $src1$$Register, $src2$$constant);
10069 %}
10070 ins_pipe(pipe_class_default);
10071 %}
10072
10073 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
10074 match(Set dst (XorI src1 src2));
10075 ins_cost(DEFAULT_COST);
10076
10077 format %{ "NOT $dst, $src1 ($src2)" %}
10078 size(4);
10079 ins_encode %{
10080 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
10081 %}
10082 ins_pipe(pipe_class_default);
10083 %}
10084
10085 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
10086 match(Set dst (XorL src1 src2));
10087 ins_cost(DEFAULT_COST);
10088
10089 format %{ "NOT $dst, $src1 ($src2) \t// long" %}
10090 size(4);
10091 ins_encode %{
10092 __ nor($dst$$Register, $src1$$Register, $src1$$Register);
10093 %}
10094 ins_pipe(pipe_class_default);
10095 %}
10096
10097 // And-complement
10098 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
10099 match(Set dst (AndI (XorI src1 src2) src3));
10100 ins_cost(DEFAULT_COST);
10101
10102 format %{ "ANDW $dst, xori($src1, $src2), $src3" %}
10103 size(4);
10104 ins_encode( enc_andc(dst, src3, src1) );
10105 ins_pipe(pipe_class_default);
10106 %}
10107
10108 // And-complement
10109 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
10110 // no match-rule, false predicate
10111 effect(DEF dst, USE src1, USE src2);
10112 predicate(false);
10113
10114 format %{ "ANDC $dst, $src1, $src2" %}
10115 size(4);
10116 ins_encode %{
10117 __ andc($dst$$Register, $src1$$Register, $src2$$Register);
10118 %}
10119 ins_pipe(pipe_class_default);
10120 %}
10121
10122 //----------Moves between int/long and float/double----------------------------
10123 //
10124 // The following rules move values from int/long registers/stack-locations
10125 // to float/double registers/stack-locations and vice versa, without doing any
10126 // conversions. These rules are used to implement the bit-conversion methods
10127 // of java.lang.Float etc., e.g.
10128 // int floatToIntBits(float value)
10129 // float intBitsToFloat(int bits)
10130 //
10131 // Notes on the implementation on ppc64:
10132 // For Power7 and earlier, the rules are limited to those which move between a
10133 // register and a stack-location, because we always have to go through memory
10134 // when moving between a float register and an integer register.
10135 // This restriction is removed in Power8 with the introduction of the mtfprd
10136 // and mffprd instructions.
10137
10138 instruct moveL2D_reg(regD dst, iRegLsrc src) %{
10139 match(Set dst (MoveL2D src));
10140 predicate(VM_Version::has_mtfprd());
10141
10142 format %{ "MTFPRD $dst, $src" %}
10143 size(4);
10144 ins_encode %{
10145 __ mtfprd($dst$$FloatRegister, $src$$Register);
10146 %}
10147 ins_pipe(pipe_class_default);
10148 %}
10149
10150 instruct moveI2D_reg(regD dst, iRegIsrc src) %{
10151 // no match-rule, false predicate
10152 effect(DEF dst, USE src);
10153 predicate(false);
10154
10155 format %{ "MTFPRWA $dst, $src" %}
10156 size(4);
10157 ins_encode %{
10158 __ mtfprwa($dst$$FloatRegister, $src$$Register);
10159 %}
10160 ins_pipe(pipe_class_default);
10161 %}
10162
10163 //---------- Chain stack slots between similar types --------
10164
10165 // These are needed so that the rules below can match.
10166
10167 // Load integer from stack slot
10168 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
10169 match(Set dst src);
10170 ins_cost(MEMORY_REF_COST);
10171
10172 format %{ "LWZ $dst, $src" %}
10173 size(4);
10174 ins_encode( enc_lwz(dst, src) );
10175 ins_pipe(pipe_class_memory);
10176 %}
10177
10178 // Store integer to stack slot
10179 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
10180 match(Set dst src);
10181 ins_cost(MEMORY_REF_COST);
10182
10183 format %{ "STW $src, $dst \t// stk" %}
10184 size(4);
10185 ins_encode( enc_stw(src, dst) ); // rs=rt
10186 ins_pipe(pipe_class_memory);
10187 %}
10188
10189 // Load long from stack slot
10190 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
10191 match(Set dst src);
10192 ins_cost(MEMORY_REF_COST);
10193
10194 format %{ "LD $dst, $src \t// long" %}
10195 size(4);
10196 ins_encode( enc_ld(dst, src) );
10197 ins_pipe(pipe_class_memory);
10198 %}
10199
10200 // Store long to stack slot
10201 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
10202 match(Set dst src);
10203 ins_cost(MEMORY_REF_COST);
10204
10205 format %{ "STD $src, $dst \t// long" %}
10206 size(4);
10207 ins_encode( enc_std(src, dst) ); // rs=rt
10208 ins_pipe(pipe_class_memory);
10209 %}
10210
10211 //----------Moves between int and float
10212
10213 // Move float value from float stack-location to integer register.
10214 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
10215 match(Set dst (MoveF2I src));
10216 ins_cost(MEMORY_REF_COST);
10217
10218 format %{ "LWZ $dst, $src \t// MoveF2I" %}
10219 size(4);
10220 ins_encode( enc_lwz(dst, src) );
10221 ins_pipe(pipe_class_memory);
10222 %}
10223
10224 // Move float value from float register to integer stack-location.
10225 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
10226 match(Set dst (MoveF2I src));
10227 ins_cost(MEMORY_REF_COST);
10228
10229 format %{ "STFS $src, $dst \t// MoveF2I" %}
10230 size(4);
10231 ins_encode( enc_stfs(src, dst) );
10232 ins_pipe(pipe_class_memory);
10233 %}
10234
10235 // Move integer value from integer stack-location to float register.
10236 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
10237 match(Set dst (MoveI2F src));
10238 ins_cost(MEMORY_REF_COST);
10239
10240 format %{ "LFS $dst, $src \t// MoveI2F" %}
10241 size(4);
10242 ins_encode %{
10243 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
10244 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
10245 %}
10246 ins_pipe(pipe_class_memory);
10247 %}
10248
10249 // Move integer value from integer register to float stack-location.
10250 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
10251 match(Set dst (MoveI2F src));
10252 ins_cost(MEMORY_REF_COST);
10253
10254 format %{ "STW $src, $dst \t// MoveI2F" %}
10255 size(4);
10256 ins_encode( enc_stw(src, dst) );
10257 ins_pipe(pipe_class_memory);
10258 %}
10259
10260 //----------Moves between long and float
10261
10262 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{
10263 // no match-rule, false predicate
10264 effect(DEF dst, USE src);
10265 predicate(false);
10266
10267 format %{ "storeD $src, $dst \t// STACK" %}
10268 size(4);
10269 ins_encode( enc_stfd(src, dst) );
10270 ins_pipe(pipe_class_default);
10271 %}
10272
10273 //----------Moves between long and double
10274
10275 // Move double value from double stack-location to long register.
10276 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
10277 match(Set dst (MoveD2L src));
10278 ins_cost(MEMORY_REF_COST);
10279 size(4);
10280 format %{ "LD $dst, $src \t// MoveD2L" %}
10281 ins_encode( enc_ld(dst, src) );
10282 ins_pipe(pipe_class_memory);
10283 %}
10284
10285 // Move double value from double register to long stack-location.
10286 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
10287 match(Set dst (MoveD2L src));
10288 effect(DEF dst, USE src);
10289 ins_cost(MEMORY_REF_COST);
10290
10291 format %{ "STFD $src, $dst \t// MoveD2L" %}
10292 size(4);
10293 ins_encode( enc_stfd(src, dst) );
10294 ins_pipe(pipe_class_memory);
10295 %}
10296
10297 // Move long value from long stack-location to double register.
10298 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{
10299 match(Set dst (MoveL2D src));
10300 ins_cost(MEMORY_REF_COST);
10301
10302 format %{ "LFD $dst, $src \t// MoveL2D" %}
10303 size(4);
10304 ins_encode( enc_lfd(dst, src) );
10305 ins_pipe(pipe_class_memory);
10306 %}
10307
10308 // Move long value from long register to double stack-location.
10309 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{
10310 match(Set dst (MoveL2D src));
10311 ins_cost(MEMORY_REF_COST);
10312
10313 format %{ "STD $src, $dst \t// MoveL2D" %}
10314 size(4);
10315 ins_encode( enc_std(src, dst) );
10316 ins_pipe(pipe_class_memory);
10317 %}
10318
10319 //----------Register Move Instructions-----------------------------------------
10320
10321 // Replicate for Superword
10322
10323 instruct moveReg(iRegLdst dst, iRegIsrc src) %{
10324 predicate(false);
10325 effect(DEF dst, USE src);
10326
10327 format %{ "MR $dst, $src \t// replicate " %}
10328 // variable size, 0 or 4.
10329 ins_encode %{
10330 __ mr_if_needed($dst$$Register, $src$$Register);
10331 %}
10332 ins_pipe(pipe_class_default);
10333 %}
10334
10335 //----------Cast instructions (Java-level type cast)---------------------------
10336
10337 // Cast Long to Pointer for unsafe natives.
10338 instruct castX2P(iRegPdst dst, iRegLsrc src) %{
10339 match(Set dst (CastX2P src));
10340
10341 format %{ "MR $dst, $src \t// Long->Ptr" %}
10342 // variable size, 0 or 4.
10343 ins_encode %{
10344 __ mr_if_needed($dst$$Register, $src$$Register);
10345 %}
10346 ins_pipe(pipe_class_default);
10347 %}
10348
10349 // Cast Pointer to Long for unsafe natives.
10350 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
10351 match(Set dst (CastP2X src));
10352
10353 format %{ "MR $dst, $src \t// Ptr->Long" %}
10354 // variable size, 0 or 4.
10355 ins_encode %{
10356 __ mr_if_needed($dst$$Register, $src$$Register);
10357 %}
10358 ins_pipe(pipe_class_default);
10359 %}
10360
10361 instruct castPP(iRegPdst dst) %{
10362 match(Set dst (CastPP dst));
10363 format %{ " -- \t// castPP of $dst" %}
10364 size(0);
10365 ins_encode( /*empty*/ );
10366 ins_pipe(pipe_class_default);
10367 %}
10368
10369 instruct castII(iRegIdst dst) %{
10370 match(Set dst (CastII dst));
10371 format %{ " -- \t// castII of $dst" %}
10372 size(0);
10373 ins_encode( /*empty*/ );
10374 ins_pipe(pipe_class_default);
10375 %}
10376
10377 instruct castLL(iRegLdst dst) %{
10378 match(Set dst (CastLL dst));
10379 format %{ " -- \t// castLL of $dst" %}
10380 size(0);
10381 ins_encode( /*empty*/ );
10382 ins_pipe(pipe_class_default);
10383 %}
10384
10385 instruct castFF(regF dst) %{
10386 match(Set dst (CastFF dst));
10387 format %{ " -- \t// castFF of $dst" %}
10388 size(0);
10389 ins_encode( /*empty*/ );
10390 ins_pipe(pipe_class_default);
10391 %}
10392
10393 instruct castDD(regD dst) %{
10394 match(Set dst (CastDD dst));
10395 format %{ " -- \t// castDD of $dst" %}
10396 size(0);
10397 ins_encode( /*empty*/ );
10398 ins_pipe(pipe_class_default);
10399 %}
10400
10401 instruct castVV8(iRegLdst dst) %{
10402 match(Set dst (CastVV dst));
10403 format %{ " -- \t// castVV of $dst" %}
10404 size(0);
10405 ins_encode( /*empty*/ );
10406 ins_pipe(pipe_class_default);
10407 %}
10408
10409 instruct castVV16(vecX dst) %{
10410 match(Set dst (CastVV dst));
10411 format %{ " -- \t// castVV of $dst" %}
10412 size(0);
10413 ins_encode( /*empty*/ );
10414 ins_pipe(pipe_class_default);
10415 %}
10416
10417 instruct checkCastPP(iRegPdst dst) %{
10418 match(Set dst (CheckCastPP dst));
10419 format %{ " -- \t// checkcastPP of $dst" %}
10420 size(0);
10421 ins_encode( /*empty*/ );
10422 ins_pipe(pipe_class_default);
10423 %}
10424
10425 //----------Convert instructions-----------------------------------------------
10426
10427 // Convert to boolean.
10428
10429 // int_to_bool(src) : { 1 if src != 0
10430 // { 0 else
10431 //
10432 // strategy:
10433 // 1) Count leading zeros of 32 bit-value src,
10434 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
10435 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
10436 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
10437
10438 // convI2Bool
10439 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
10440 match(Set dst (Conv2B src));
10441 predicate(UseCountLeadingZerosInstructionsPPC64);
10442 ins_cost(DEFAULT_COST);
10443
10444 expand %{
10445 immI shiftAmount %{ 0x5 %}
10446 uimmI16 mask %{ 0x1 %}
10447 iRegIdst tmp1;
10448 iRegIdst tmp2;
10449 countLeadingZerosI(tmp1, src);
10450 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
10451 xorI_reg_uimm16(dst, tmp2, mask);
10452 %}
10453 %}
10454
10455 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
10456 match(Set dst (Conv2B src));
10457 effect(TEMP crx);
10458 predicate(!UseCountLeadingZerosInstructionsPPC64);
10459 ins_cost(DEFAULT_COST);
10460
10461 format %{ "CMPWI $crx, $src, #0 \t// convI2B"
10462 "LI $dst, #0\n\t"
10463 "BEQ $crx, done\n\t"
10464 "LI $dst, #1\n"
10465 "done:" %}
10466 size(16);
10467 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
10468 ins_pipe(pipe_class_compare);
10469 %}
10470
10471 // ConvI2B + XorI
10472 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
10473 match(Set dst (XorI (Conv2B src) mask));
10474 predicate(UseCountLeadingZerosInstructionsPPC64);
10475 ins_cost(DEFAULT_COST);
10476
10477 expand %{
10478 immI shiftAmount %{ 0x5 %}
10479 iRegIdst tmp1;
10480 countLeadingZerosI(tmp1, src);
10481 urShiftI_reg_imm(dst, tmp1, shiftAmount);
10482 %}
10483 %}
10484
10485 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
10486 match(Set dst (XorI (Conv2B src) mask));
10487 effect(TEMP crx);
10488 predicate(!UseCountLeadingZerosInstructionsPPC64);
10489 ins_cost(DEFAULT_COST);
10490
10491 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
10492 "LI $dst, #1\n\t"
10493 "BEQ $crx, done\n\t"
10494 "LI $dst, #0\n"
10495 "done:" %}
10496 size(16);
10497 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
10498 ins_pipe(pipe_class_compare);
10499 %}
10500
10501 // AndI 0b0..010..0 + ConvI2B
10502 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
10503 match(Set dst (Conv2B (AndI src mask)));
10504 predicate(UseRotateAndMaskInstructionsPPC64);
10505 ins_cost(DEFAULT_COST);
10506
10507 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
10508 size(4);
10509 ins_encode %{
10510 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31);
10511 %}
10512 ins_pipe(pipe_class_default);
10513 %}
10514
10515 // Convert pointer to boolean.
10516 //
10517 // ptr_to_bool(src) : { 1 if src != 0
10518 // { 0 else
10519 //
10520 // strategy:
10521 // 1) Count leading zeros of 64 bit-value src,
10522 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
10523 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
10524 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
10525
10526 // ConvP2B
10527 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
10528 match(Set dst (Conv2B src));
10529 predicate(UseCountLeadingZerosInstructionsPPC64);
10530 ins_cost(DEFAULT_COST);
10531
10532 expand %{
10533 immI shiftAmount %{ 0x6 %}
10534 uimmI16 mask %{ 0x1 %}
10535 iRegIdst tmp1;
10536 iRegIdst tmp2;
10537 countLeadingZerosP(tmp1, src);
10538 urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
10539 xorI_reg_uimm16(dst, tmp2, mask);
10540 %}
10541 %}
10542
10543 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
10544 match(Set dst (Conv2B src));
10545 effect(TEMP crx);
10546 predicate(!UseCountLeadingZerosInstructionsPPC64);
10547 ins_cost(DEFAULT_COST);
10548
10549 format %{ "CMPDI $crx, $src, #0 \t// convP2B"
10550 "LI $dst, #0\n\t"
10551 "BEQ $crx, done\n\t"
10552 "LI $dst, #1\n"
10553 "done:" %}
10554 size(16);
10555 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
10556 ins_pipe(pipe_class_compare);
10557 %}
10558
10559 // ConvP2B + XorI
10560 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
10561 match(Set dst (XorI (Conv2B src) mask));
10562 predicate(UseCountLeadingZerosInstructionsPPC64);
10563 ins_cost(DEFAULT_COST);
10564
10565 expand %{
10566 immI shiftAmount %{ 0x6 %}
10567 iRegIdst tmp1;
10568 countLeadingZerosP(tmp1, src);
10569 urShiftI_reg_imm(dst, tmp1, shiftAmount);
10570 %}
10571 %}
10572
10573 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
10574 match(Set dst (XorI (Conv2B src) mask));
10575 effect(TEMP crx);
10576 predicate(!UseCountLeadingZerosInstructionsPPC64);
10577 ins_cost(DEFAULT_COST);
10578
10579 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
10580 "LI $dst, #1\n\t"
10581 "BEQ $crx, done\n\t"
10582 "LI $dst, #0\n"
10583 "done:" %}
10584 size(16);
10585 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
10586 ins_pipe(pipe_class_compare);
10587 %}
10588
10589 // if src1 < src2, return -1 else return 0
10590 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
10591 match(Set dst (CmpLTMask src1 src2));
10592 ins_cost(DEFAULT_COST*4);
10593
10594 expand %{
10595 iRegLdst src1s;
10596 iRegLdst src2s;
10597 iRegLdst diff;
10598 convI2L_reg(src1s, src1); // Ensure proper sign extension.
10599 convI2L_reg(src2s, src2); // Ensure proper sign extension.
10600 subL_reg_reg(diff, src1s, src2s);
10601 // Need to consider >=33 bit result, therefore we need signmaskL.
10602 signmask64I_regL(dst, diff);
10603 %}
10604 %}
10605
10606 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
10607 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
10608 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %}
10609 size(4);
10610 ins_encode %{
10611 __ srawi($dst$$Register, $src1$$Register, 0x1f);
10612 %}
10613 ins_pipe(pipe_class_default);
10614 %}
10615
10616 //----------Arithmetic Conversion Instructions---------------------------------
10617
10618 // Convert to Byte -- nop
10619 // Convert to Short -- nop
10620
10621 // Convert to Int
10622
10623 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
10624 match(Set dst (RShiftI (LShiftI src amount) amount));
10625 format %{ "EXTSB $dst, $src \t// byte->int" %}
10626 size(4);
10627 ins_encode %{
10628 __ extsb($dst$$Register, $src$$Register);
10629 %}
10630 ins_pipe(pipe_class_default);
10631 %}
10632
10633 instruct extsh(iRegIdst dst, iRegIsrc src) %{
10634 effect(DEF dst, USE src);
10635
10636 size(4);
10637 ins_encode %{
10638 __ extsh($dst$$Register, $src$$Register);
10639 %}
10640 ins_pipe(pipe_class_default);
10641 %}
10642
10643 // LShiftI 16 + RShiftI 16 converts short to int.
10644 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
10645 match(Set dst (RShiftI (LShiftI src amount) amount));
10646 format %{ "EXTSH $dst, $src \t// short->int" %}
10647 size(4);
10648 ins_encode %{
10649 __ extsh($dst$$Register, $src$$Register);
10650 %}
10651 ins_pipe(pipe_class_default);
10652 %}
10653
10654 // ConvL2I + ConvI2L: Sign extend int in long register.
10655 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
10656 match(Set dst (ConvI2L (ConvL2I src)));
10657
10658 format %{ "EXTSW $dst, $src \t// long->long" %}
10659 size(4);
10660 ins_encode %{
10661 __ extsw($dst$$Register, $src$$Register);
10662 %}
10663 ins_pipe(pipe_class_default);
10664 %}
10665
10666 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
10667 match(Set dst (ConvL2I src));
10668 format %{ "MR $dst, $src \t// long->int" %}
10669 // variable size, 0 or 4
10670 ins_encode %{
10671 __ mr_if_needed($dst$$Register, $src$$Register);
10672 %}
10673 ins_pipe(pipe_class_default);
10674 %}
10675
10676 instruct convD2IRaw_regD(regD dst, regD src) %{
10677 // no match-rule, false predicate
10678 effect(DEF dst, USE src);
10679 predicate(false);
10680
10681 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
10682 size(4);
10683 ins_encode %{
10684 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10685 %}
10686 ins_pipe(pipe_class_default);
10687 %}
10688
10689 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
10690 // no match-rule, false predicate
10691 effect(DEF dst, USE crx, USE src);
10692 predicate(false);
10693
10694 ins_variable_size_depending_on_alignment(true);
10695
10696 format %{ "cmovI $crx, $dst, $src" %}
10697 // Worst case is branch + move + stop, no stop without scheduler.
10698 size(8);
10699 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10700 ins_pipe(pipe_class_default);
10701 %}
10702
10703 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
10704 // no match-rule, false predicate
10705 effect(DEF dst, USE crx, USE src);
10706 predicate(false);
10707
10708 ins_variable_size_depending_on_alignment(true);
10709
10710 format %{ "cmovI $crx, $dst, $src" %}
10711 // Worst case is branch + move + stop, no stop without scheduler.
10712 size(8);
10713 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10714 ins_pipe(pipe_class_default);
10715 %}
10716
10717 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{
10718 // no match-rule, false predicate
10719 effect(DEF dst, USE crx, USE mem);
10720 predicate(false);
10721
10722 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %}
10723 postalloc_expand %{
10724 //
10725 // replaces
10726 //
10727 // region dst crx mem
10728 // \ | | /
10729 // dst=cmovI_bso_stackSlotL_conLvalue0
10730 //
10731 // with
10732 //
10733 // region dst
10734 // \ /
10735 // dst=loadConI16(0)
10736 // |
10737 // ^ region dst crx mem
10738 // | \ | | /
10739 // dst=cmovI_bso_stackSlotL
10740 //
10741
10742 // Create new nodes.
10743 MachNode *m1 = new loadConI16Node();
10744 MachNode *m2 = new cmovI_bso_stackSlotLNode();
10745
10746 // inputs for new nodes
10747 m1->add_req(n_region);
10748 m2->add_req(n_region, n_crx, n_mem);
10749
10750 // precedences for new nodes
10751 m2->add_prec(m1);
10752
10753 // operands for new nodes
10754 m1->_opnds[0] = op_dst;
10755 m1->_opnds[1] = new immI16Oper(0);
10756
10757 m2->_opnds[0] = op_dst;
10758 m2->_opnds[1] = op_crx;
10759 m2->_opnds[2] = op_mem;
10760
10761 // registers for new nodes
10762 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10763 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10764
10765 // Insert new nodes.
10766 nodes->push(m1);
10767 nodes->push(m2);
10768 %}
10769 %}
10770
10771 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{
10772 // no match-rule, false predicate
10773 effect(DEF dst, USE crx, USE src);
10774 predicate(false);
10775
10776 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %}
10777 postalloc_expand %{
10778 //
10779 // replaces
10780 //
10781 // region dst crx src
10782 // \ | | /
10783 // dst=cmovI_bso_reg_conLvalue0
10784 //
10785 // with
10786 //
10787 // region dst
10788 // \ /
10789 // dst=loadConI16(0)
10790 // |
10791 // ^ region dst crx src
10792 // | \ | | /
10793 // dst=cmovI_bso_reg
10794 //
10795
10796 // Create new nodes.
10797 MachNode *m1 = new loadConI16Node();
10798 MachNode *m2 = new cmovI_bso_regNode();
10799
10800 // inputs for new nodes
10801 m1->add_req(n_region);
10802 m2->add_req(n_region, n_crx, n_src);
10803
10804 // precedences for new nodes
10805 m2->add_prec(m1);
10806
10807 // operands for new nodes
10808 m1->_opnds[0] = op_dst;
10809 m1->_opnds[1] = new immI16Oper(0);
10810
10811 m2->_opnds[0] = op_dst;
10812 m2->_opnds[1] = op_crx;
10813 m2->_opnds[2] = op_src;
10814
10815 // registers for new nodes
10816 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10817 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10818
10819 // Insert new nodes.
10820 nodes->push(m1);
10821 nodes->push(m2);
10822 %}
10823 %}
10824
10825 // Double to Int conversion, NaN is mapped to 0.
10826 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{
10827 match(Set dst (ConvD2I src));
10828 predicate(!VM_Version::has_mtfprd());
10829 ins_cost(DEFAULT_COST);
10830
10831 expand %{
10832 regD tmpD;
10833 stackSlotL tmpS;
10834 flagsReg crx;
10835 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10836 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
10837 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated).
10838 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
10839 %}
10840 %}
10841
10842 // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
10843 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
10844 match(Set dst (ConvD2I src));
10845 predicate(VM_Version::has_mtfprd());
10846 ins_cost(DEFAULT_COST);
10847
10848 expand %{
10849 regD tmpD;
10850 flagsReg crx;
10851 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10852 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
10853 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
10854 %}
10855 %}
10856
10857 instruct convF2IRaw_regF(regF dst, regF src) %{
10858 // no match-rule, false predicate
10859 effect(DEF dst, USE src);
10860 predicate(false);
10861
10862 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
10863 size(4);
10864 ins_encode %{
10865 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10866 %}
10867 ins_pipe(pipe_class_default);
10868 %}
10869
10870 // Float to Int conversion, NaN is mapped to 0.
10871 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{
10872 match(Set dst (ConvF2I src));
10873 predicate(!VM_Version::has_mtfprd());
10874 ins_cost(DEFAULT_COST);
10875
10876 expand %{
10877 regF tmpF;
10878 stackSlotL tmpS;
10879 flagsReg crx;
10880 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10881 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10882 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated).
10883 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
10884 %}
10885 %}
10886
10887 // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
10888 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
10889 match(Set dst (ConvF2I src));
10890 predicate(VM_Version::has_mtfprd());
10891 ins_cost(DEFAULT_COST);
10892
10893 expand %{
10894 regF tmpF;
10895 flagsReg crx;
10896 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
10897 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
10898 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
10899 %}
10900 %}
10901
10902 // Convert to Long
10903
10904 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
10905 match(Set dst (ConvI2L src));
10906 format %{ "EXTSW $dst, $src \t// int->long" %}
10907 size(4);
10908 ins_encode %{
10909 __ extsw($dst$$Register, $src$$Register);
10910 %}
10911 ins_pipe(pipe_class_default);
10912 %}
10913
10914 // Zero-extend: convert unsigned int to long (convUI2L).
10915 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
10916 match(Set dst (AndL (ConvI2L src) mask));
10917 ins_cost(DEFAULT_COST);
10918
10919 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10920 size(4);
10921 ins_encode %{
10922 __ clrldi($dst$$Register, $src$$Register, 32);
10923 %}
10924 ins_pipe(pipe_class_default);
10925 %}
10926
10927 // Zero-extend: convert unsigned int to long in long register.
10928 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
10929 match(Set dst (AndL src mask));
10930 ins_cost(DEFAULT_COST);
10931
10932 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %}
10933 size(4);
10934 ins_encode %{
10935 __ clrldi($dst$$Register, $src$$Register, 32);
10936 %}
10937 ins_pipe(pipe_class_default);
10938 %}
10939
10940 instruct convF2LRaw_regF(regF dst, regF src) %{
10941 // no match-rule, false predicate
10942 effect(DEF dst, USE src);
10943 predicate(false);
10944
10945 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10946 size(4);
10947 ins_encode %{
10948 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10949 %}
10950 ins_pipe(pipe_class_default);
10951 %}
10952
10953 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
10954 // no match-rule, false predicate
10955 effect(DEF dst, USE crx, USE src);
10956 predicate(false);
10957
10958 ins_variable_size_depending_on_alignment(true);
10959
10960 format %{ "cmovL $crx, $dst, $src" %}
10961 // Worst case is branch + move + stop, no stop without scheduler.
10962 size(8);
10963 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10964 ins_pipe(pipe_class_default);
10965 %}
10966
10967 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
10968 // no match-rule, false predicate
10969 effect(DEF dst, USE crx, USE src);
10970 predicate(false);
10971
10972 ins_variable_size_depending_on_alignment(true);
10973
10974 format %{ "cmovL $crx, $dst, $src" %}
10975 // Worst case is branch + move + stop, no stop without scheduler.
10976 size(8);
10977 ins_encode( enc_cmove_bso_reg(dst, crx, src) );
10978 ins_pipe(pipe_class_default);
10979 %}
10980
10981 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{
10982 // no match-rule, false predicate
10983 effect(DEF dst, USE crx, USE mem);
10984 predicate(false);
10985
10986 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %}
10987 postalloc_expand %{
10988 //
10989 // replaces
10990 //
10991 // region dst crx mem
10992 // \ | | /
10993 // dst=cmovL_bso_stackSlotL_conLvalue0
10994 //
10995 // with
10996 //
10997 // region dst
10998 // \ /
10999 // dst=loadConL16(0)
11000 // |
11001 // ^ region dst crx mem
11002 // | \ | | /
11003 // dst=cmovL_bso_stackSlotL
11004 //
11005
11006 // Create new nodes.
11007 MachNode *m1 = new loadConL16Node();
11008 MachNode *m2 = new cmovL_bso_stackSlotLNode();
11009
11010 // inputs for new nodes
11011 m1->add_req(n_region);
11012 m2->add_req(n_region, n_crx, n_mem);
11013 m2->add_prec(m1);
11014
11015 // operands for new nodes
11016 m1->_opnds[0] = op_dst;
11017 m1->_opnds[1] = new immL16Oper(0);
11018 m2->_opnds[0] = op_dst;
11019 m2->_opnds[1] = op_crx;
11020 m2->_opnds[2] = op_mem;
11021
11022 // registers for new nodes
11023 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
11024 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
11025
11026 // Insert new nodes.
11027 nodes->push(m1);
11028 nodes->push(m2);
11029 %}
11030 %}
11031
11032 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{
11033 // no match-rule, false predicate
11034 effect(DEF dst, USE crx, USE src);
11035 predicate(false);
11036
11037 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %}
11038 postalloc_expand %{
11039 //
11040 // replaces
11041 //
11042 // region dst crx src
11043 // \ | | /
11044 // dst=cmovL_bso_reg_conLvalue0
11045 //
11046 // with
11047 //
11048 // region dst
11049 // \ /
11050 // dst=loadConL16(0)
11051 // |
11052 // ^ region dst crx src
11053 // | \ | | /
11054 // dst=cmovL_bso_reg
11055 //
11056
11057 // Create new nodes.
11058 MachNode *m1 = new loadConL16Node();
11059 MachNode *m2 = new cmovL_bso_regNode();
11060
11061 // inputs for new nodes
11062 m1->add_req(n_region);
11063 m2->add_req(n_region, n_crx, n_src);
11064 m2->add_prec(m1);
11065
11066 // operands for new nodes
11067 m1->_opnds[0] = op_dst;
11068 m1->_opnds[1] = new immL16Oper(0);
11069 m2->_opnds[0] = op_dst;
11070 m2->_opnds[1] = op_crx;
11071 m2->_opnds[2] = op_src;
11072
11073 // registers for new nodes
11074 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
11075 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
11076
11077 // Insert new nodes.
11078 nodes->push(m1);
11079 nodes->push(m2);
11080 %}
11081 %}
11082
11083 // Float to Long conversion, NaN is mapped to 0.
11084 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{
11085 match(Set dst (ConvF2L src));
11086 predicate(!VM_Version::has_mtfprd());
11087 ins_cost(DEFAULT_COST);
11088
11089 expand %{
11090 regF tmpF;
11091 stackSlotL tmpS;
11092 flagsReg crx;
11093 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
11094 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
11095 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated).
11096 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
11097 %}
11098 %}
11099
11100 // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
11101 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
11102 match(Set dst (ConvF2L src));
11103 predicate(VM_Version::has_mtfprd());
11104 ins_cost(DEFAULT_COST);
11105
11106 expand %{
11107 regF tmpF;
11108 flagsReg crx;
11109 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
11110 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
11111 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
11112 %}
11113 %}
11114
11115 instruct convD2LRaw_regD(regD dst, regD src) %{
11116 // no match-rule, false predicate
11117 effect(DEF dst, USE src);
11118 predicate(false);
11119
11120 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
11121 size(4);
11122 ins_encode %{
11123 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
11124 %}
11125 ins_pipe(pipe_class_default);
11126 %}
11127
11128 // Double to Long conversion, NaN is mapped to 0.
11129 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{
11130 match(Set dst (ConvD2L src));
11131 predicate(!VM_Version::has_mtfprd());
11132 ins_cost(DEFAULT_COST);
11133
11134 expand %{
11135 regD tmpD;
11136 stackSlotL tmpS;
11137 flagsReg crx;
11138 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
11139 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
11140 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated).
11141 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
11142 %}
11143 %}
11144
11145 // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
11146 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
11147 match(Set dst (ConvD2L src));
11148 predicate(VM_Version::has_mtfprd());
11149 ins_cost(DEFAULT_COST);
11150
11151 expand %{
11152 regD tmpD;
11153 flagsReg crx;
11154 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
11155 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
11156 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
11157 %}
11158 %}
11159
11160 // Convert to Float
11161
11162 // Placed here as needed in expand.
11163 instruct convL2DRaw_regD(regD dst, regD src) %{
11164 // no match-rule, false predicate
11165 effect(DEF dst, USE src);
11166 predicate(false);
11167
11168 format %{ "FCFID $dst, $src \t// convL2D" %}
11169 size(4);
11170 ins_encode %{
11171 __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
11172 %}
11173 ins_pipe(pipe_class_default);
11174 %}
11175
11176 // Placed here as needed in expand.
11177 instruct convD2F_reg(regF dst, regD src) %{
11178 match(Set dst (ConvD2F src));
11179 format %{ "FRSP $dst, $src \t// convD2F" %}
11180 size(4);
11181 ins_encode %{
11182 __ frsp($dst$$FloatRegister, $src$$FloatRegister);
11183 %}
11184 ins_pipe(pipe_class_default);
11185 %}
11186
11187 // Integer to Float conversion.
11188 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{
11189 match(Set dst (ConvI2F src));
11190 predicate(!VM_Version::has_fcfids());
11191 ins_cost(DEFAULT_COST);
11192
11193 expand %{
11194 iRegLdst tmpL;
11195 stackSlotL tmpS;
11196 regD tmpD;
11197 regD tmpD2;
11198 convI2L_reg(tmpL, src); // Sign-extension int to long.
11199 regL_to_stkL(tmpS, tmpL); // Store long to stack.
11200 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
11201 convL2DRaw_regD(tmpD2, tmpD); // Convert to double.
11202 convD2F_reg(dst, tmpD2); // Convert double to float.
11203 %}
11204 %}
11205
11206 instruct convL2FRaw_regF(regF dst, regD src) %{
11207 // no match-rule, false predicate
11208 effect(DEF dst, USE src);
11209 predicate(false);
11210
11211 format %{ "FCFIDS $dst, $src \t// convL2F" %}
11212 size(4);
11213 ins_encode %{
11214 __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
11215 %}
11216 ins_pipe(pipe_class_default);
11217 %}
11218
11219 // Integer to Float conversion. Special version for Power7.
11220 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{
11221 match(Set dst (ConvI2F src));
11222 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd());
11223 ins_cost(DEFAULT_COST);
11224
11225 expand %{
11226 iRegLdst tmpL;
11227 stackSlotL tmpS;
11228 regD tmpD;
11229 convI2L_reg(tmpL, src); // Sign-extension int to long.
11230 regL_to_stkL(tmpS, tmpL); // Store long to stack.
11231 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
11232 convL2FRaw_regF(dst, tmpD); // Convert to float.
11233 %}
11234 %}
11235
11236 // Integer to Float conversion. Special version for Power8.
11237 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
11238 match(Set dst (ConvI2F src));
11239 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd());
11240 ins_cost(DEFAULT_COST);
11241
11242 expand %{
11243 regD tmpD;
11244 moveI2D_reg(tmpD, src);
11245 convL2FRaw_regF(dst, tmpD); // Convert to float.
11246 %}
11247 %}
11248
11249 // L2F to avoid runtime call.
11250 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{
11251 match(Set dst (ConvL2F src));
11252 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd());
11253 ins_cost(DEFAULT_COST);
11254
11255 expand %{
11256 stackSlotL tmpS;
11257 regD tmpD;
11258 regL_to_stkL(tmpS, src); // Store long to stack.
11259 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
11260 convL2FRaw_regF(dst, tmpD); // Convert to float.
11261 %}
11262 %}
11263
11264 // L2F to avoid runtime call. Special version for Power8.
11265 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
11266 match(Set dst (ConvL2F src));
11267 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd());
11268 ins_cost(DEFAULT_COST);
11269
11270 expand %{
11271 regD tmpD;
11272 moveL2D_reg(tmpD, src);
11273 convL2FRaw_regF(dst, tmpD); // Convert to float.
11274 %}
11275 %}
11276
11277 // Moved up as used in expand.
11278 //instruct convD2F_reg(regF dst, regD src) %{%}
11279
11280 // Convert to Double
11281
11282 // Integer to Double conversion.
11283 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{
11284 match(Set dst (ConvI2D src));
11285 predicate(!VM_Version::has_mtfprd());
11286 ins_cost(DEFAULT_COST);
11287
11288 expand %{
11289 iRegLdst tmpL;
11290 stackSlotL tmpS;
11291 regD tmpD;
11292 convI2L_reg(tmpL, src); // Sign-extension int to long.
11293 regL_to_stkL(tmpS, tmpL); // Store long to stack.
11294 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
11295 convL2DRaw_regD(dst, tmpD); // Convert to double.
11296 %}
11297 %}
11298
11299 // Integer to Double conversion. Special version for Power8.
11300 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
11301 match(Set dst (ConvI2D src));
11302 predicate(VM_Version::has_mtfprd());
11303 ins_cost(DEFAULT_COST);
11304
11305 expand %{
11306 regD tmpD;
11307 moveI2D_reg(tmpD, src);
11308 convL2DRaw_regD(dst, tmpD); // Convert to double.
11309 %}
11310 %}
11311
11312 // Long to Double conversion
11313 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{
11314 match(Set dst (ConvL2D src));
11315 ins_cost(DEFAULT_COST + MEMORY_REF_COST);
11316
11317 expand %{
11318 regD tmpD;
11319 moveL2D_stack_reg(tmpD, src);
11320 convL2DRaw_regD(dst, tmpD);
11321 %}
11322 %}
11323
11324 // Long to Double conversion. Special version for Power8.
11325 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
11326 match(Set dst (ConvL2D src));
11327 predicate(VM_Version::has_mtfprd());
11328 ins_cost(DEFAULT_COST);
11329
11330 expand %{
11331 regD tmpD;
11332 moveL2D_reg(tmpD, src);
11333 convL2DRaw_regD(dst, tmpD); // Convert to double.
11334 %}
11335 %}
11336
11337 instruct convF2D_reg(regD dst, regF src) %{
11338 match(Set dst (ConvF2D src));
11339 format %{ "FMR $dst, $src \t// float->double" %}
11340 // variable size, 0 or 4
11341 ins_encode %{
11342 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
11343 %}
11344 ins_pipe(pipe_class_default);
11345 %}
11346
11347 //----------Control Flow Instructions------------------------------------------
11348 // Compare Instructions
11349
11350 // Compare Integers
11351 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
11352 match(Set crx (CmpI src1 src2));
11353 size(4);
11354 format %{ "CMPW $crx, $src1, $src2" %}
11355 ins_encode %{
11356 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
11357 %}
11358 ins_pipe(pipe_class_compare);
11359 %}
11360
11361 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
11362 match(Set crx (CmpI src1 src2));
11363 format %{ "CMPWI $crx, $src1, $src2" %}
11364 size(4);
11365 ins_encode %{
11366 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11367 %}
11368 ins_pipe(pipe_class_compare);
11369 %}
11370
11371 // (src1 & src2) == 0?
11372 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
11373 match(Set cr0 (CmpI (AndI src1 src2) zero));
11374 // r0 is killed
11375 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
11376 size(4);
11377 ins_encode %{
11378 __ andi_(R0, $src1$$Register, $src2$$constant);
11379 %}
11380 ins_pipe(pipe_class_compare);
11381 %}
11382
11383 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
11384 match(Set crx (CmpL src1 src2));
11385 format %{ "CMPD $crx, $src1, $src2" %}
11386 size(4);
11387 ins_encode %{
11388 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
11389 %}
11390 ins_pipe(pipe_class_compare);
11391 %}
11392
11393 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
11394 match(Set crx (CmpL src1 src2));
11395 format %{ "CMPDI $crx, $src1, $src2" %}
11396 size(4);
11397 ins_encode %{
11398 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11399 %}
11400 ins_pipe(pipe_class_compare);
11401 %}
11402
11403 // Added CmpUL for LoopPredicate.
11404 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
11405 match(Set crx (CmpUL src1 src2));
11406 format %{ "CMPLD $crx, $src1, $src2" %}
11407 size(4);
11408 ins_encode %{
11409 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
11410 %}
11411 ins_pipe(pipe_class_compare);
11412 %}
11413
11414 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
11415 match(Set crx (CmpUL src1 src2));
11416 format %{ "CMPLDI $crx, $src1, $src2" %}
11417 size(4);
11418 ins_encode %{
11419 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11420 %}
11421 ins_pipe(pipe_class_compare);
11422 %}
11423
11424 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
11425 match(Set cr0 (CmpL (AndL src1 src2) zero));
11426 // r0 is killed
11427 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
11428 size(4);
11429 ins_encode %{
11430 __ and_(R0, $src1$$Register, $src2$$Register);
11431 %}
11432 ins_pipe(pipe_class_compare);
11433 %}
11434
11435 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
11436 match(Set cr0 (CmpL (AndL src1 src2) zero));
11437 // r0 is killed
11438 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
11439 size(4);
11440 ins_encode %{
11441 __ andi_(R0, $src1$$Register, $src2$$constant);
11442 %}
11443 ins_pipe(pipe_class_compare);
11444 %}
11445
11446 // Manifest a CmpL3 result in an integer register.
11447 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
11448 match(Set dst (CmpL3 src1 src2));
11449 effect(KILL cr0);
11450 ins_cost(DEFAULT_COST * 5);
11451 size((VM_Version::has_brw() ? 16 : 20));
11452
11453 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %}
11454
11455 ins_encode %{
11456 __ cmpd(CCR0, $src1$$Register, $src2$$Register);
11457 __ set_cmp3($dst$$Register);
11458 %}
11459 ins_pipe(pipe_class_default);
11460 %}
11461
11462 // Implicit range checks.
11463 // A range check in the ideal world has one of the following shapes:
11464 // - (If le (CmpU length index)), (IfTrue throw exception)
11465 // - (If lt (CmpU index length)), (IfFalse throw exception)
11466 //
11467 // Match range check 'If le (CmpU length index)'.
11468 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
11469 match(If cmp (CmpU src_length index));
11470 effect(USE labl);
11471 predicate(TrapBasedRangeChecks &&
11472 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
11473 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
11474 (Matcher::branches_to_uncommon_trap(_leaf)));
11475
11476 ins_is_TrapBasedCheckNode(true);
11477
11478 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %}
11479 size(4);
11480 ins_encode %{
11481 if ($cmp$$cmpcode == 0x1 /* less_equal */) {
11482 __ trap_range_check_le($src_length$$Register, $index$$constant);
11483 } else {
11484 // Both successors are uncommon traps, probability is 0.
11485 // Node got flipped during fixup flow.
11486 assert($cmp$$cmpcode == 0x9, "must be greater");
11487 __ trap_range_check_g($src_length$$Register, $index$$constant);
11488 }
11489 %}
11490 ins_pipe(pipe_class_trap);
11491 %}
11492
11493 // Match range check 'If lt (CmpU index length)'.
11494 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
11495 match(If cmp (CmpU src_index src_length));
11496 effect(USE labl);
11497 predicate(TrapBasedRangeChecks &&
11498 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
11499 _leaf->as_If()->_prob >= PROB_ALWAYS &&
11500 (Matcher::branches_to_uncommon_trap(_leaf)));
11501
11502 ins_is_TrapBasedCheckNode(true);
11503
11504 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
11505 size(4);
11506 ins_encode %{
11507 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
11508 __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
11509 } else {
11510 // Both successors are uncommon traps, probability is 0.
11511 // Node got flipped during fixup flow.
11512 assert($cmp$$cmpcode == 0x8, "must be less");
11513 __ trap_range_check_l($src_index$$Register, $src_length$$Register);
11514 }
11515 %}
11516 ins_pipe(pipe_class_trap);
11517 %}
11518
11519 // Match range check 'If lt (CmpU index length)'.
11520 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
11521 match(If cmp (CmpU src_index length));
11522 effect(USE labl);
11523 predicate(TrapBasedRangeChecks &&
11524 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
11525 _leaf->as_If()->_prob >= PROB_ALWAYS &&
11526 (Matcher::branches_to_uncommon_trap(_leaf)));
11527
11528 ins_is_TrapBasedCheckNode(true);
11529
11530 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %}
11531 size(4);
11532 ins_encode %{
11533 if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
11534 __ trap_range_check_ge($src_index$$Register, $length$$constant);
11535 } else {
11536 // Both successors are uncommon traps, probability is 0.
11537 // Node got flipped during fixup flow.
11538 assert($cmp$$cmpcode == 0x8, "must be less");
11539 __ trap_range_check_l($src_index$$Register, $length$$constant);
11540 }
11541 %}
11542 ins_pipe(pipe_class_trap);
11543 %}
11544
11545 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
11546 match(Set crx (CmpU src1 src2));
11547 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %}
11548 size(4);
11549 ins_encode %{
11550 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
11551 %}
11552 ins_pipe(pipe_class_compare);
11553 %}
11554
11555 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
11556 match(Set crx (CmpU src1 src2));
11557 size(4);
11558 format %{ "CMPLWI $crx, $src1, $src2" %}
11559 ins_encode %{
11560 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11561 %}
11562 ins_pipe(pipe_class_compare);
11563 %}
11564
11565 // Implicit zero checks (more implicit null checks).
11566 // No constant pool entries required.
11567 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
11568 match(If cmp (CmpN value zero));
11569 effect(USE labl);
11570 predicate(TrapBasedNullChecks &&
11571 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
11572 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
11573 Matcher::branches_to_uncommon_trap(_leaf));
11574 ins_cost(1);
11575
11576 ins_is_TrapBasedCheckNode(true);
11577
11578 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
11579 size(4);
11580 ins_encode %{
11581 if ($cmp$$cmpcode == 0xA) {
11582 __ trap_null_check($value$$Register);
11583 } else {
11584 // Both successors are uncommon traps, probability is 0.
11585 // Node got flipped during fixup flow.
11586 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
11587 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
11588 }
11589 %}
11590 ins_pipe(pipe_class_trap);
11591 %}
11592
11593 // Compare narrow oops.
11594 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
11595 match(Set crx (CmpN src1 src2));
11596
11597 size(4);
11598 ins_cost(2);
11599 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %}
11600 ins_encode %{
11601 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
11602 %}
11603 ins_pipe(pipe_class_compare);
11604 %}
11605
11606 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
11607 match(Set crx (CmpN src1 src2));
11608 // Make this more expensive than zeroCheckN_iReg_imm0.
11609 ins_cost(2);
11610
11611 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %}
11612 size(4);
11613 ins_encode %{
11614 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11615 %}
11616 ins_pipe(pipe_class_compare);
11617 %}
11618
11619 // Implicit zero checks (more implicit null checks).
11620 // No constant pool entries required.
11621 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
11622 match(If cmp (CmpP value zero));
11623 effect(USE labl);
11624 predicate(TrapBasedNullChecks &&
11625 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
11626 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
11627 Matcher::branches_to_uncommon_trap(_leaf));
11628 ins_cost(1); // Should not be cheaper than zeroCheckN.
11629
11630 ins_is_TrapBasedCheckNode(true);
11631
11632 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
11633 size(4);
11634 ins_encode %{
11635 if ($cmp$$cmpcode == 0xA) {
11636 __ trap_null_check($value$$Register);
11637 } else {
11638 // Both successors are uncommon traps, probability is 0.
11639 // Node got flipped during fixup flow.
11640 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
11641 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
11642 }
11643 %}
11644 ins_pipe(pipe_class_trap);
11645 %}
11646
11647 // Compare Pointers
11648 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
11649 match(Set crx (CmpP src1 src2));
11650 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %}
11651 size(4);
11652 ins_encode %{
11653 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
11654 %}
11655 ins_pipe(pipe_class_compare);
11656 %}
11657
11658 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
11659 match(Set crx (CmpP src1 src2));
11660 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %}
11661 size(4);
11662 ins_encode %{
11663 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
11664 %}
11665 ins_pipe(pipe_class_compare);
11666 %}
11667
11668 // Used in postalloc expand.
11669 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
11670 // This match rule prevents reordering of node before a safepoint.
11671 // This only makes sense if this instructions is used exclusively
11672 // for the expansion of EncodeP!
11673 match(Set crx (CmpP src1 src2));
11674 predicate(false);
11675
11676 format %{ "CMPDI $crx, $src1, $src2" %}
11677 size(4);
11678 ins_encode %{
11679 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11680 %}
11681 ins_pipe(pipe_class_compare);
11682 %}
11683
11684 //----------Float Compares----------------------------------------------------
11685
11686 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
11687 // Needs matchrule, see cmpDUnordered.
11688 match(Set crx (CmpF src1 src2));
11689 // no match-rule, false predicate
11690 predicate(false);
11691
11692 format %{ "cmpFUrd $crx, $src1, $src2" %}
11693 size(4);
11694 ins_encode %{
11695 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11696 %}
11697 ins_pipe(pipe_class_default);
11698 %}
11699
11700 instruct cmov_bns_less(flagsReg crx) %{
11701 // no match-rule, false predicate
11702 effect(DEF crx);
11703 predicate(false);
11704
11705 ins_variable_size_depending_on_alignment(true);
11706
11707 format %{ "cmov $crx" %}
11708 // Worst case is branch + move + stop, no stop without scheduler.
11709 size(12);
11710 ins_encode %{
11711 Label done;
11712 __ bns($crx$$CondRegister, done); // not unordered -> keep crx
11713 __ li(R0, 0);
11714 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less'
11715 __ bind(done);
11716 %}
11717 ins_pipe(pipe_class_default);
11718 %}
11719
11720 // Compare floating, generate condition code.
11721 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{
11722 // FIXME: should we match 'If cmp (CmpF src1 src2))' ??
11723 //
11724 // The following code sequence occurs a lot in mpegaudio:
11725 //
11726 // block BXX:
11727 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0):
11728 // cmpFUrd CCR6, F11, F9
11729 // 4: instruct cmov_bns_less (cmpF_reg_reg-1):
11730 // cmov CCR6
11731 // 8: instruct branchConSched:
11732 // B_FARle CCR6, B56 P=0.500000 C=-1.000000
11733 match(Set crx (CmpF src1 src2));
11734 ins_cost(DEFAULT_COST+BRANCH_COST);
11735
11736 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %}
11737 postalloc_expand %{
11738 //
11739 // replaces
11740 //
11741 // region src1 src2
11742 // \ | |
11743 // crx=cmpF_reg_reg
11744 //
11745 // with
11746 //
11747 // region src1 src2
11748 // \ | |
11749 // crx=cmpFUnordered_reg_reg
11750 // |
11751 // ^ region
11752 // | \
11753 // crx=cmov_bns_less
11754 //
11755
11756 // Create new nodes.
11757 MachNode *m1 = new cmpFUnordered_reg_regNode();
11758 MachNode *m2 = new cmov_bns_lessNode();
11759
11760 // inputs for new nodes
11761 m1->add_req(n_region, n_src1, n_src2);
11762 m2->add_req(n_region);
11763 m2->add_prec(m1);
11764
11765 // operands for new nodes
11766 m1->_opnds[0] = op_crx;
11767 m1->_opnds[1] = op_src1;
11768 m1->_opnds[2] = op_src2;
11769 m2->_opnds[0] = op_crx;
11770
11771 // registers for new nodes
11772 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11773 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11774
11775 // Insert new nodes.
11776 nodes->push(m1);
11777 nodes->push(m2);
11778 %}
11779 %}
11780
11781 // Compare float, generate -1,0,1
11782 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{
11783 match(Set dst (CmpF3 src1 src2));
11784 effect(KILL cr0);
11785 ins_cost(DEFAULT_COST * 6);
11786 size((VM_Version::has_brw() ? 20 : 24));
11787
11788 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %}
11789
11790 ins_encode %{
11791 __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister);
11792 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11793 %}
11794 ins_pipe(pipe_class_default);
11795 %}
11796
11797 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
11798 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
11799 // node right before the conditional move using it.
11800 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
11801 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
11802 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
11803 // conditional move was supposed to be spilled.
11804 match(Set crx (CmpD src1 src2));
11805 // False predicate, shall not be matched.
11806 predicate(false);
11807
11808 format %{ "cmpFUrd $crx, $src1, $src2" %}
11809 size(4);
11810 ins_encode %{
11811 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11812 %}
11813 ins_pipe(pipe_class_default);
11814 %}
11815
11816 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{
11817 match(Set crx (CmpD src1 src2));
11818 ins_cost(DEFAULT_COST+BRANCH_COST);
11819
11820 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %}
11821 postalloc_expand %{
11822 //
11823 // replaces
11824 //
11825 // region src1 src2
11826 // \ | |
11827 // crx=cmpD_reg_reg
11828 //
11829 // with
11830 //
11831 // region src1 src2
11832 // \ | |
11833 // crx=cmpDUnordered_reg_reg
11834 // |
11835 // ^ region
11836 // | \
11837 // crx=cmov_bns_less
11838 //
11839
11840 // create new nodes
11841 MachNode *m1 = new cmpDUnordered_reg_regNode();
11842 MachNode *m2 = new cmov_bns_lessNode();
11843
11844 // inputs for new nodes
11845 m1->add_req(n_region, n_src1, n_src2);
11846 m2->add_req(n_region);
11847 m2->add_prec(m1);
11848
11849 // operands for new nodes
11850 m1->_opnds[0] = op_crx;
11851 m1->_opnds[1] = op_src1;
11852 m1->_opnds[2] = op_src2;
11853 m2->_opnds[0] = op_crx;
11854
11855 // registers for new nodes
11856 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11857 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11858
11859 // Insert new nodes.
11860 nodes->push(m1);
11861 nodes->push(m2);
11862 %}
11863 %}
11864
11865 // Compare double, generate -1,0,1
11866 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{
11867 match(Set dst (CmpD3 src1 src2));
11868 effect(KILL cr0);
11869 ins_cost(DEFAULT_COST * 6);
11870 size((VM_Version::has_brw() ? 20 : 24));
11871
11872 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %}
11873
11874 ins_encode %{
11875 __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister);
11876 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less
11877 %}
11878 ins_pipe(pipe_class_default);
11879 %}
11880
11881 // Compare char
11882 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11883 match(Set dst (Digit src1));
11884 effect(TEMP src2, TEMP crx);
11885 ins_cost(3 * DEFAULT_COST);
11886
11887 format %{ "LI $src2, 0x3930\n\t"
11888 "CMPRB $crx, 0, $src1, $src2\n\t"
11889 "SETB $dst, $crx" %}
11890 size(12);
11891 ins_encode %{
11892 // 0x30: 0, 0x39: 9
11893 __ li($src2$$Register, 0x3930);
11894 // compare src1 with ranges 0x30 to 0x39
11895 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11896 __ setb($dst$$Register, $crx$$CondRegister);
11897 %}
11898 ins_pipe(pipe_class_default);
11899 %}
11900
11901 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11902 match(Set dst (LowerCase src1));
11903 effect(TEMP src2, TEMP crx);
11904 ins_cost(12 * DEFAULT_COST);
11905
11906 format %{ "LI $src2, 0x7A61\n\t"
11907 "CMPRB $crx, 0, $src1, $src2\n\t"
11908 "BGT $crx, done\n\t"
11909 "LIS $src2, (signed short)0xF6DF\n\t"
11910 "ORI $src2, $src2, 0xFFF8\n\t"
11911 "CMPRB $crx, 1, $src1, $src2\n\t"
11912 "BGT $crx, done\n\t"
11913 "LIS $src2, (signed short)0xAAB5\n\t"
11914 "ORI $src2, $src2, 0xBABA\n\t"
11915 "INSRDI $src2, $src2, 32, 0\n\t"
11916 "CMPEQB $crx, 1, $src1, $src2\n"
11917 "done:\n\t"
11918 "SETB $dst, $crx" %}
11919
11920 size(48);
11921 ins_encode %{
11922 Label done;
11923 // 0x61: a, 0x7A: z
11924 __ li($src2$$Register, 0x7A61);
11925 // compare src1 with ranges 0x61 to 0x7A
11926 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11927 __ bgt($crx$$CondRegister, done);
11928
11929 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
11930 __ lis($src2$$Register, (signed short)0xF6DF);
11931 __ ori($src2$$Register, $src2$$Register, 0xFFF8);
11932 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
11933 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11934 __ bgt($crx$$CondRegister, done);
11935
11936 // 0xAA: feminine ordinal indicator
11937 // 0xB5: micro sign
11938 // 0xBA: masculine ordinal indicator
11939 __ lis($src2$$Register, (signed short)0xAAB5);
11940 __ ori($src2$$Register, $src2$$Register, 0xBABA);
11941 __ insrdi($src2$$Register, $src2$$Register, 32, 0);
11942 // compare src1 with 0xAA, 0xB5, and 0xBA
11943 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
11944
11945 __ bind(done);
11946 __ setb($dst$$Register, $crx$$CondRegister);
11947 %}
11948 ins_pipe(pipe_class_default);
11949 %}
11950
11951 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11952 match(Set dst (UpperCase src1));
11953 effect(TEMP src2, TEMP crx);
11954 ins_cost(7 * DEFAULT_COST);
11955
11956 format %{ "LI $src2, 0x5A41\n\t"
11957 "CMPRB $crx, 0, $src1, $src2\n\t"
11958 "BGT $crx, done\n\t"
11959 "LIS $src2, (signed short)0xD6C0\n\t"
11960 "ORI $src2, $src2, 0xDED8\n\t"
11961 "CMPRB $crx, 1, $src1, $src2\n"
11962 "done:\n\t"
11963 "SETB $dst, $crx" %}
11964
11965 size(28);
11966 ins_encode %{
11967 Label done;
11968 // 0x41: A, 0x5A: Z
11969 __ li($src2$$Register, 0x5A41);
11970 // compare src1 with a range 0x41 to 0x5A
11971 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
11972 __ bgt($crx$$CondRegister, done);
11973
11974 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
11975 __ lis($src2$$Register, (signed short)0xD6C0);
11976 __ ori($src2$$Register, $src2$$Register, 0xDED8);
11977 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
11978 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
11979
11980 __ bind(done);
11981 __ setb($dst$$Register, $crx$$CondRegister);
11982 %}
11983 ins_pipe(pipe_class_default);
11984 %}
11985
11986 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
11987 match(Set dst (Whitespace src1));
11988 predicate(PowerArchitecturePPC64 <= 9);
11989 effect(TEMP src2, TEMP crx);
11990 ins_cost(4 * DEFAULT_COST);
11991
11992 format %{ "LI $src2, 0x0D09\n\t"
11993 "ADDIS $src2, 0x201C\n\t"
11994 "CMPRB $crx, 1, $src1, $src2\n\t"
11995 "SETB $dst, $crx" %}
11996 size(16);
11997 ins_encode %{
11998 // 0x09 to 0x0D, 0x1C to 0x20
11999 __ li($src2$$Register, 0x0D09);
12000 __ addis($src2$$Register, $src2$$Register, 0x0201C);
12001 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
12002 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
12003 __ setb($dst$$Register, $crx$$CondRegister);
12004 %}
12005 ins_pipe(pipe_class_default);
12006 %}
12007
12008 // Power 10 version, using prefixed addi to load 32-bit constant
12009 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
12010 match(Set dst (Whitespace src1));
12011 predicate(PowerArchitecturePPC64 >= 10);
12012 effect(TEMP src2, TEMP crx);
12013 ins_cost(3 * DEFAULT_COST);
12014
12015 format %{ "PLI $src2, 0x201C0D09\n\t"
12016 "CMPRB $crx, 1, $src1, $src2\n\t"
12017 "SETB $dst, $crx" %}
12018 size(16);
12019 ins_encode %{
12020 // 0x09 to 0x0D, 0x1C to 0x20
12021 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc()));
12022 __ pli($src2$$Register, 0x201C0D09);
12023 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
12024 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
12025 __ setb($dst$$Register, $crx$$CondRegister);
12026 %}
12027 ins_pipe(pipe_class_default);
12028 ins_alignment(2);
12029 %}
12030
12031 //----------Branches---------------------------------------------------------
12032 // Jump
12033
12034 // Direct Branch.
12035 instruct branch(label labl) %{
12036 match(Goto);
12037 effect(USE labl);
12038 ins_cost(BRANCH_COST);
12039
12040 format %{ "B $labl" %}
12041 size(4);
12042 ins_encode %{
12043 Label d; // dummy
12044 __ bind(d);
12045 Label* p = $labl$$label;
12046 // `p' is `NULL' when this encoding class is used only to
12047 // determine the size of the encoded instruction.
12048 Label& l = (NULL == p)? d : *(p);
12049 __ b(l);
12050 %}
12051 ins_pipe(pipe_class_default);
12052 %}
12053
12054 // Conditional Near Branch
12055 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
12056 // Same match rule as `branchConFar'.
12057 match(If cmp crx);
12058 effect(USE lbl);
12059 ins_cost(BRANCH_COST);
12060
12061 // If set to 1 this indicates that the current instruction is a
12062 // short variant of a long branch. This avoids using this
12063 // instruction in first-pass matching. It will then only be used in
12064 // the `Shorten_branches' pass.
12065 ins_short_branch(1);
12066
12067 format %{ "B$cmp $crx, $lbl" %}
12068 size(4);
12069 ins_encode( enc_bc(crx, cmp, lbl) );
12070 ins_pipe(pipe_class_default);
12071 %}
12072
12073 // This is for cases when the ppc64 `bc' instruction does not
12074 // reach far enough. So we emit a far branch here, which is more
12075 // expensive.
12076 //
12077 // Conditional Far Branch
12078 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
12079 // Same match rule as `branchCon'.
12080 match(If cmp crx);
12081 effect(USE crx, USE lbl);
12082 // Higher cost than `branchCon'.
12083 ins_cost(5*BRANCH_COST);
12084
12085 // This is not a short variant of a branch, but the long variant.
12086 ins_short_branch(0);
12087
12088 format %{ "B_FAR$cmp $crx, $lbl" %}
12089 size(8);
12090 ins_encode( enc_bc_far(crx, cmp, lbl) );
12091 ins_pipe(pipe_class_default);
12092 %}
12093
12094 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
12095 match(CountedLoopEnd cmp crx);
12096 effect(USE labl);
12097 ins_cost(BRANCH_COST);
12098
12099 // short variant.
12100 ins_short_branch(1);
12101
12102 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
12103 size(4);
12104 ins_encode( enc_bc(crx, cmp, labl) );
12105 ins_pipe(pipe_class_default);
12106 %}
12107
12108 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
12109 match(CountedLoopEnd cmp crx);
12110 effect(USE labl);
12111 ins_cost(BRANCH_COST);
12112
12113 // Long variant.
12114 ins_short_branch(0);
12115
12116 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
12117 size(8);
12118 ins_encode( enc_bc_far(crx, cmp, labl) );
12119 ins_pipe(pipe_class_default);
12120 %}
12121
12122 // ============================================================================
12123 // Java runtime operations, intrinsics and other complex operations.
12124
12125 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
12126 // array for an instance of the superklass. Set a hidden internal cache on a
12127 // hit (cache is checked with exposed code in gen_subtype_check()). Return
12128 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
12129 //
12130 // GL TODO: Improve this.
12131 // - result should not be a TEMP
12132 // - Add match rule as on sparc avoiding additional Cmp.
12133 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
12134 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
12135 match(Set result (PartialSubtypeCheck subklass superklass));
12136 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
12137 ins_cost(DEFAULT_COST*10);
12138
12139 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
12140 ins_encode %{
12141 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
12142 $tmp_klass$$Register, NULL, $result$$Register);
12143 %}
12144 ins_pipe(pipe_class_default);
12145 %}
12146
12147 // inlined locking and unlocking
12148
12149 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
12150 match(Set crx (FastLock oop box));
12151 effect(TEMP tmp1, TEMP tmp2);
12152 predicate(!Compile::current()->use_rtm());
12153
12154 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %}
12155 ins_encode %{
12156 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
12157 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0);
12158 // If locking was successful, crx should indicate 'EQ'.
12159 // The compiler generates a branch to the runtime call to
12160 // _complete_monitor_locking_Java for the case where crx is 'NE'.
12161 %}
12162 ins_pipe(pipe_class_compare);
12163 %}
12164
12165 // Separate version for TM. Use bound register for box to enable USE_KILL.
12166 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
12167 match(Set crx (FastLock oop box));
12168 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box);
12169 predicate(Compile::current()->use_rtm());
12170
12171 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %}
12172 ins_encode %{
12173 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
12174 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
12175 _rtm_counters, _stack_rtm_counters,
12176 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(),
12177 /*RTM*/ true, ra_->C->profile_rtm());
12178 // If locking was successful, crx should indicate 'EQ'.
12179 // The compiler generates a branch to the runtime call to
12180 // _complete_monitor_locking_Java for the case where crx is 'NE'.
12181 %}
12182 ins_pipe(pipe_class_compare);
12183 %}
12184
12185 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
12186 match(Set crx (FastUnlock oop box));
12187 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
12188 predicate(!Compile::current()->use_rtm());
12189
12190 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
12191 ins_encode %{
12192 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
12193 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
12194 false);
12195 // If unlocking was successful, crx should indicate 'EQ'.
12196 // The compiler generates a branch to the runtime call to
12197 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
12198 %}
12199 ins_pipe(pipe_class_compare);
12200 %}
12201
12202 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
12203 match(Set crx (FastUnlock oop box));
12204 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
12205 predicate(Compile::current()->use_rtm());
12206
12207 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %}
12208 ins_encode %{
12209 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
12210 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
12211 /*RTM*/ true);
12212 // If unlocking was successful, crx should indicate 'EQ'.
12213 // The compiler generates a branch to the runtime call to
12214 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
12215 %}
12216 ins_pipe(pipe_class_compare);
12217 %}
12218
12219 // Align address.
12220 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
12221 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
12222
12223 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
12224 size(4);
12225 ins_encode %{
12226 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant));
12227 %}
12228 ins_pipe(pipe_class_default);
12229 %}
12230
12231 // Array size computation.
12232 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
12233 match(Set dst (SubL (CastP2X end) (CastP2X start)));
12234
12235 format %{ "SUB $dst, $end, $start \t// array size in bytes" %}
12236 size(4);
12237 ins_encode %{
12238 __ subf($dst$$Register, $start$$Register, $end$$Register);
12239 %}
12240 ins_pipe(pipe_class_default);
12241 %}
12242
12243 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
12244 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
12245 match(Set dummy (ClearArray cnt base));
12246 effect(USE_KILL base, KILL ctr);
12247 ins_cost(2 * MEMORY_REF_COST);
12248
12249 format %{ "ClearArray $cnt, $base" %}
12250 ins_encode %{
12251 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
12252 %}
12253 ins_pipe(pipe_class_default);
12254 %}
12255
12256 // Clear-array with constant large array length.
12257 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{
12258 match(Set dummy (ClearArray cnt base));
12259 effect(USE_KILL base, TEMP tmp, KILL ctr);
12260 ins_cost(3 * MEMORY_REF_COST);
12261
12262 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
12263 ins_encode %{
12264 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
12265 %}
12266 ins_pipe(pipe_class_default);
12267 %}
12268
12269 // Clear-array with dynamic array length.
12270 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
12271 match(Set dummy (ClearArray cnt base));
12272 effect(USE_KILL cnt, USE_KILL base, KILL ctr);
12273 ins_cost(4 * MEMORY_REF_COST);
12274
12275 format %{ "ClearArray $cnt, $base" %}
12276 ins_encode %{
12277 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
12278 %}
12279 ins_pipe(pipe_class_default);
12280 %}
12281
12282 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
12283 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12284 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
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 byte[] $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::LL);
12294 %}
12295 ins_pipe(pipe_class_default);
12296 %}
12297
12298 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
12299 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12300 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
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 char[] $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::UU);
12310 %}
12311 ins_pipe(pipe_class_default);
12312 %}
12313
12314 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
12315 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12316 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
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($str1$$Register, $str2$$Register,
12323 $cnt1$$Register, $cnt2$$Register,
12324 $tmp$$Register,
12325 $result$$Register, StrIntrinsicNode::LU);
12326 %}
12327 ins_pipe(pipe_class_default);
12328 %}
12329
12330 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
12331 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12332 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
12333 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
12334 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
12335 ins_cost(300);
12336 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
12337 ins_encode %{
12338 __ string_compare($str2$$Register, $str1$$Register,
12339 $cnt2$$Register, $cnt1$$Register,
12340 $tmp$$Register,
12341 $result$$Register, StrIntrinsicNode::UL);
12342 %}
12343 ins_pipe(pipe_class_default);
12344 %}
12345
12346 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
12347 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12348 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
12349 match(Set result (StrEquals (Binary str1 str2) cnt));
12350 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
12351 ins_cost(300);
12352 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
12353 ins_encode %{
12354 __ array_equals(false, $str1$$Register, $str2$$Register,
12355 $cnt$$Register, $tmp$$Register,
12356 $result$$Register, true /* byte */);
12357 %}
12358 ins_pipe(pipe_class_default);
12359 %}
12360
12361 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
12362 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12363 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
12364 match(Set result (StrEquals (Binary str1 str2) cnt));
12365 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
12366 ins_cost(300);
12367 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
12368 ins_encode %{
12369 __ array_equals(false, $str1$$Register, $str2$$Register,
12370 $cnt$$Register, $tmp$$Register,
12371 $result$$Register, false /* byte */);
12372 %}
12373 ins_pipe(pipe_class_default);
12374 %}
12375
12376 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
12377 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
12378 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
12379 match(Set result (AryEq ary1 ary2));
12380 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
12381 ins_cost(300);
12382 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
12383 ins_encode %{
12384 __ array_equals(true, $ary1$$Register, $ary2$$Register,
12385 $tmp1$$Register, $tmp2$$Register,
12386 $result$$Register, true /* byte */);
12387 %}
12388 ins_pipe(pipe_class_default);
12389 %}
12390
12391 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
12392 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
12393 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
12394 match(Set result (AryEq ary1 ary2));
12395 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
12396 ins_cost(300);
12397 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
12398 ins_encode %{
12399 __ array_equals(true, $ary1$$Register, $ary2$$Register,
12400 $tmp1$$Register, $tmp2$$Register,
12401 $result$$Register, false /* byte */);
12402 %}
12403 ins_pipe(pipe_class_default);
12404 %}
12405
12406 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12407 immP needleImm, immL offsetImm, immI_1 needlecntImm,
12408 iRegIdst tmp1, iRegIdst tmp2,
12409 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12410 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
12411 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12412 // Required for EA: check if it is still a type_array.
12413 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
12414 ins_cost(150);
12415
12416 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
12417 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12418
12419 ins_encode %{
12420 immPOper *needleOper = (immPOper *)$needleImm;
12421 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
12422 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
12423 jchar chr;
12424 #ifdef VM_LITTLE_ENDIAN
12425 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
12426 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
12427 #else
12428 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
12429 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
12430 #endif
12431 __ string_indexof_char($result$$Register,
12432 $haystack$$Register, $haycnt$$Register,
12433 R0, chr,
12434 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12435 %}
12436 ins_pipe(pipe_class_compare);
12437 %}
12438
12439 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12440 immP needleImm, immL offsetImm, immI_1 needlecntImm,
12441 iRegIdst tmp1, iRegIdst tmp2,
12442 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12443 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
12444 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12445 // Required for EA: check if it is still a type_array.
12446 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
12447 ins_cost(150);
12448
12449 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
12450 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12451
12452 ins_encode %{
12453 immPOper *needleOper = (immPOper *)$needleImm;
12454 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
12455 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
12456 jchar chr = (jchar)needle_values->element_value(0).as_byte();
12457 __ string_indexof_char($result$$Register,
12458 $haystack$$Register, $haycnt$$Register,
12459 R0, chr,
12460 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
12461 %}
12462 ins_pipe(pipe_class_compare);
12463 %}
12464
12465 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12466 immP needleImm, immL offsetImm, immI_1 needlecntImm,
12467 iRegIdst tmp1, iRegIdst tmp2,
12468 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12469 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
12470 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12471 // Required for EA: check if it is still a type_array.
12472 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
12473 ins_cost(150);
12474
12475 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
12476 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12477
12478 ins_encode %{
12479 immPOper *needleOper = (immPOper *)$needleImm;
12480 const TypeOopPtr *t = needleOper->type()->isa_oopptr();
12481 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
12482 jchar chr = (jchar)needle_values->element_value(0).as_byte();
12483 __ string_indexof_char($result$$Register,
12484 $haystack$$Register, $haycnt$$Register,
12485 R0, chr,
12486 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12487 %}
12488 ins_pipe(pipe_class_compare);
12489 %}
12490
12491 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12492 rscratch2RegP needle, immI_1 needlecntImm,
12493 iRegIdst tmp1, iRegIdst tmp2,
12494 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12495 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12496 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12497 // Required for EA: check if it is still a type_array.
12498 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
12499 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12500 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12501 ins_cost(180);
12502
12503 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12504 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
12505 ins_encode %{
12506 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12507 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12508 guarantee(needle_values, "sanity");
12509 jchar chr;
12510 #ifdef VM_LITTLE_ENDIAN
12511 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
12512 ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
12513 #else
12514 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
12515 ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
12516 #endif
12517 __ string_indexof_char($result$$Register,
12518 $haystack$$Register, $haycnt$$Register,
12519 R0, chr,
12520 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12521 %}
12522 ins_pipe(pipe_class_compare);
12523 %}
12524
12525 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12526 rscratch2RegP needle, immI_1 needlecntImm,
12527 iRegIdst tmp1, iRegIdst tmp2,
12528 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12529 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12530 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12531 // Required for EA: check if it is still a type_array.
12532 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
12533 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12534 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12535 ins_cost(180);
12536
12537 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12538 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
12539 ins_encode %{
12540 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12541 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12542 guarantee(needle_values, "sanity");
12543 jchar chr = (jchar)needle_values->element_value(0).as_byte();
12544 __ string_indexof_char($result$$Register,
12545 $haystack$$Register, $haycnt$$Register,
12546 R0, chr,
12547 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
12548 %}
12549 ins_pipe(pipe_class_compare);
12550 %}
12551
12552 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12553 rscratch2RegP needle, immI_1 needlecntImm,
12554 iRegIdst tmp1, iRegIdst tmp2,
12555 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12556 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12557 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12558 // Required for EA: check if it is still a type_array.
12559 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
12560 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12561 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12562 ins_cost(180);
12563
12564 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12565 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
12566 ins_encode %{
12567 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12568 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12569 guarantee(needle_values, "sanity");
12570 jchar chr = (jchar)needle_values->element_value(0).as_byte();
12571 __ string_indexof_char($result$$Register,
12572 $haystack$$Register, $haycnt$$Register,
12573 R0, chr,
12574 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12575 %}
12576 ins_pipe(pipe_class_compare);
12577 %}
12578
12579 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12580 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
12581 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12582 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
12583 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12584 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
12585 ins_cost(180);
12586
12587 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch"
12588 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12589 ins_encode %{
12590 __ string_indexof_char($result$$Register,
12591 $haystack$$Register, $haycnt$$Register,
12592 $ch$$Register, 0 /* this is not used if the character is already in a register */,
12593 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12594 %}
12595 ins_pipe(pipe_class_compare);
12596 %}
12597
12598 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12599 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
12600 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12601 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
12602 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12603 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
12604 ins_cost(180);
12605
12606 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch"
12607 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12608 ins_encode %{
12609 __ string_indexof_char($result$$Register,
12610 $haystack$$Register, $haycnt$$Register,
12611 $ch$$Register, 0 /* this is not used if the character is already in a register */,
12612 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
12613 %}
12614 ins_pipe(pipe_class_compare);
12615 %}
12616
12617 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12618 iRegPsrc needle, uimmI15 needlecntImm,
12619 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12620 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12621 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12622 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12623 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12624 // Required for EA: check if it is still a type_array.
12625 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
12626 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12627 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12628 ins_cost(250);
12629
12630 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12631 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12632 ins_encode %{
12633 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12634 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12635
12636 __ string_indexof($result$$Register,
12637 $haystack$$Register, $haycnt$$Register,
12638 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12639 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
12640 %}
12641 ins_pipe(pipe_class_compare);
12642 %}
12643
12644 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12645 iRegPsrc needle, uimmI15 needlecntImm,
12646 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12647 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12648 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12649 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12650 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12651 // Required for EA: check if it is still a type_array.
12652 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
12653 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12654 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12655 ins_cost(250);
12656
12657 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12658 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12659 ins_encode %{
12660 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12661 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12662
12663 __ string_indexof($result$$Register,
12664 $haystack$$Register, $haycnt$$Register,
12665 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12666 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
12667 %}
12668 ins_pipe(pipe_class_compare);
12669 %}
12670
12671 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12672 iRegPsrc needle, uimmI15 needlecntImm,
12673 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12674 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12675 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12676 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12677 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12678 // Required for EA: check if it is still a type_array.
12679 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
12680 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12681 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12682 ins_cost(250);
12683
12684 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12685 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12686 ins_encode %{
12687 Node *ndl = in(operand_index($needle)); // The node that defines needle.
12688 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12689
12690 __ string_indexof($result$$Register,
12691 $haystack$$Register, $haycnt$$Register,
12692 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12693 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
12694 %}
12695 ins_pipe(pipe_class_compare);
12696 %}
12697
12698 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12699 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12700 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12701 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12702 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12703 TEMP_DEF result,
12704 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12705 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
12706 ins_cost(300);
12707
12708 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12709 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12710 ins_encode %{
12711 __ string_indexof($result$$Register,
12712 $haystack$$Register, $haycnt$$Register,
12713 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
12714 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
12715 %}
12716 ins_pipe(pipe_class_compare);
12717 %}
12718
12719 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12720 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12721 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12722 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12723 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12724 TEMP_DEF result,
12725 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12726 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
12727 ins_cost(300);
12728
12729 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12730 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12731 ins_encode %{
12732 __ string_indexof($result$$Register,
12733 $haystack$$Register, $haycnt$$Register,
12734 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
12735 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
12736 %}
12737 ins_pipe(pipe_class_compare);
12738 %}
12739
12740 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12741 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12742 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12743 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12744 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12745 TEMP_DEF result,
12746 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12747 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
12748 ins_cost(300);
12749
12750 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12751 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12752 ins_encode %{
12753 __ string_indexof($result$$Register,
12754 $haystack$$Register, $haycnt$$Register,
12755 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
12756 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
12757 %}
12758 ins_pipe(pipe_class_compare);
12759 %}
12760
12761 // char[] to byte[] compression
12762 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12763 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12764 match(Set result (StrCompressedCopy src (Binary dst len)));
12765 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12766 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12767 ins_cost(300);
12768 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12769 ins_encode %{
12770 Label Lskip, Ldone;
12771 __ li($result$$Register, 0);
12772 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
12773 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone);
12774 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
12775 __ beq(CCR0, Lskip);
12776 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone);
12777 __ bind(Lskip);
12778 __ mr($result$$Register, $len$$Register);
12779 __ bind(Ldone);
12780 %}
12781 ins_pipe(pipe_class_default);
12782 %}
12783
12784 // byte[] to char[] inflation
12785 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
12786 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12787 match(Set dummy (StrInflatedCopy src (Binary dst len)));
12788 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12789 ins_cost(300);
12790 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12791 ins_encode %{
12792 Label Ldone;
12793 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
12794 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
12795 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
12796 __ beq(CCR0, Ldone);
12797 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
12798 __ bind(Ldone);
12799 %}
12800 ins_pipe(pipe_class_default);
12801 %}
12802
12803 // StringCoding.java intrinsics
12804 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
12805 regCTR ctr, flagsRegCR0 cr0)
12806 %{
12807 match(Set result (CountPositives ary1 len));
12808 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
12809 ins_cost(300);
12810 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
12811 ins_encode %{
12812 __ count_positives($ary1$$Register, $len$$Register, $result$$Register,
12813 $tmp1$$Register, $tmp2$$Register);
12814 %}
12815 ins_pipe(pipe_class_default);
12816 %}
12817
12818 // encode char[] to byte[] in ISO_8859_1
12819 instruct encode_iso_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 iso 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, false);
12830 %}
12831 ins_pipe(pipe_class_default);
12832 %}
12833
12834 // encode char[] to byte[] in ASCII
12835 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12836 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12837 predicate(((EncodeISOArrayNode*)n)->is_ascii());
12838 match(Set result (EncodeISOArray src (Binary dst len)));
12839 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12840 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12841 ins_cost(300);
12842 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12843 ins_encode %{
12844 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
12845 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
12846 %}
12847 ins_pipe(pipe_class_default);
12848 %}
12849
12850
12851 //---------- Min/Max Instructions ---------------------------------------------
12852
12853 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
12854 match(Set dst (MinI src1 src2));
12855 ins_cost(DEFAULT_COST*6);
12856
12857 expand %{
12858 iRegLdst src1s;
12859 iRegLdst src2s;
12860 iRegLdst diff;
12861 iRegLdst sm;
12862 iRegLdst doz; // difference or zero
12863 convI2L_reg(src1s, src1); // Ensure proper sign extension.
12864 convI2L_reg(src2s, src2); // Ensure proper sign extension.
12865 subL_reg_reg(diff, src2s, src1s);
12866 // Need to consider >=33 bit result, therefore we need signmaskL.
12867 signmask64L_regL(sm, diff);
12868 andL_reg_reg(doz, diff, sm); // <=0
12869 addI_regL_regL(dst, doz, src1s);
12870 %}
12871 %}
12872
12873 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12874 match(Set dst (MinI src1 src2));
12875 effect(KILL cr0);
12876 predicate(VM_Version::has_isel());
12877 ins_cost(DEFAULT_COST*2);
12878
12879 ins_encode %{
12880 __ cmpw(CCR0, $src1$$Register, $src2$$Register);
12881 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
12882 %}
12883 ins_pipe(pipe_class_default);
12884 %}
12885
12886 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
12887 match(Set dst (MaxI src1 src2));
12888 ins_cost(DEFAULT_COST*6);
12889
12890 expand %{
12891 iRegLdst src1s;
12892 iRegLdst src2s;
12893 iRegLdst diff;
12894 iRegLdst sm;
12895 iRegLdst doz; // difference or zero
12896 convI2L_reg(src1s, src1); // Ensure proper sign extension.
12897 convI2L_reg(src2s, src2); // Ensure proper sign extension.
12898 subL_reg_reg(diff, src2s, src1s);
12899 // Need to consider >=33 bit result, therefore we need signmaskL.
12900 signmask64L_regL(sm, diff);
12901 andcL_reg_reg(doz, diff, sm); // >=0
12902 addI_regL_regL(dst, doz, src1s);
12903 %}
12904 %}
12905
12906 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12907 match(Set dst (MaxI src1 src2));
12908 effect(KILL cr0);
12909 predicate(VM_Version::has_isel());
12910 ins_cost(DEFAULT_COST*2);
12911
12912 ins_encode %{
12913 __ cmpw(CCR0, $src1$$Register, $src2$$Register);
12914 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
12915 %}
12916 ins_pipe(pipe_class_default);
12917 %}
12918
12919 //---------- Population Count Instructions ------------------------------------
12920
12921 // Popcnt for Power7.
12922 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
12923 match(Set dst (PopCountI src));
12924 predicate(UsePopCountInstruction && VM_Version::has_popcntw());
12925 ins_cost(DEFAULT_COST);
12926
12927 format %{ "POPCNTW $dst, $src" %}
12928 size(4);
12929 ins_encode %{
12930 __ popcntw($dst$$Register, $src$$Register);
12931 %}
12932 ins_pipe(pipe_class_default);
12933 %}
12934
12935 // Popcnt for Power7.
12936 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
12937 predicate(UsePopCountInstruction && VM_Version::has_popcntw());
12938 match(Set dst (PopCountL src));
12939 ins_cost(DEFAULT_COST);
12940
12941 format %{ "POPCNTD $dst, $src" %}
12942 size(4);
12943 ins_encode %{
12944 __ popcntd($dst$$Register, $src$$Register);
12945 %}
12946 ins_pipe(pipe_class_default);
12947 %}
12948
12949 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
12950 match(Set dst (CountLeadingZerosI src));
12951 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12952 ins_cost(DEFAULT_COST);
12953
12954 format %{ "CNTLZW $dst, $src" %}
12955 size(4);
12956 ins_encode %{
12957 __ cntlzw($dst$$Register, $src$$Register);
12958 %}
12959 ins_pipe(pipe_class_default);
12960 %}
12961
12962 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
12963 match(Set dst (CountLeadingZerosL src));
12964 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported.
12965 ins_cost(DEFAULT_COST);
12966
12967 format %{ "CNTLZD $dst, $src" %}
12968 size(4);
12969 ins_encode %{
12970 __ cntlzd($dst$$Register, $src$$Register);
12971 %}
12972 ins_pipe(pipe_class_default);
12973 %}
12974
12975 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
12976 // no match-rule, false predicate
12977 effect(DEF dst, USE src);
12978 predicate(false);
12979
12980 format %{ "CNTLZD $dst, $src" %}
12981 size(4);
12982 ins_encode %{
12983 __ cntlzd($dst$$Register, $src$$Register);
12984 %}
12985 ins_pipe(pipe_class_default);
12986 %}
12987
12988 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
12989 match(Set dst (CountTrailingZerosI src));
12990 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
12991 ins_cost(DEFAULT_COST);
12992
12993 expand %{
12994 immI16 imm1 %{ (int)-1 %}
12995 immI16 imm2 %{ (int)32 %}
12996 immI_minus1 m1 %{ -1 %}
12997 iRegIdst tmpI1;
12998 iRegIdst tmpI2;
12999 iRegIdst tmpI3;
13000 addI_reg_imm16(tmpI1, src, imm1);
13001 andcI_reg_reg(tmpI2, src, m1, tmpI1);
13002 countLeadingZerosI(tmpI3, tmpI2);
13003 subI_imm16_reg(dst, imm2, tmpI3);
13004 %}
13005 %}
13006
13007 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{
13008 match(Set dst (CountTrailingZerosI src));
13009 predicate(UseCountTrailingZerosInstructionsPPC64);
13010 ins_cost(DEFAULT_COST);
13011
13012 format %{ "CNTTZW $dst, $src" %}
13013 size(4);
13014 ins_encode %{
13015 __ cnttzw($dst$$Register, $src$$Register);
13016 %}
13017 ins_pipe(pipe_class_default);
13018 %}
13019
13020 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
13021 match(Set dst (CountTrailingZerosL src));
13022 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64);
13023 ins_cost(DEFAULT_COST);
13024
13025 expand %{
13026 immL16 imm1 %{ (long)-1 %}
13027 immI16 imm2 %{ (int)64 %}
13028 iRegLdst tmpL1;
13029 iRegLdst tmpL2;
13030 iRegIdst tmpL3;
13031 addL_reg_imm16(tmpL1, src, imm1);
13032 andcL_reg_reg(tmpL2, tmpL1, src);
13033 countLeadingZerosL(tmpL3, tmpL2);
13034 subI_imm16_reg(dst, imm2, tmpL3);
13035 %}
13036 %}
13037
13038 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{
13039 match(Set dst (CountTrailingZerosL src));
13040 predicate(UseCountTrailingZerosInstructionsPPC64);
13041 ins_cost(DEFAULT_COST);
13042
13043 format %{ "CNTTZD $dst, $src" %}
13044 size(4);
13045 ins_encode %{
13046 __ cnttzd($dst$$Register, $src$$Register);
13047 %}
13048 ins_pipe(pipe_class_default);
13049 %}
13050
13051 // Expand nodes for byte_reverse_int.
13052 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{
13053 effect(DEF dst, USE src, USE pos, USE shift);
13054 predicate(false);
13055
13056 format %{ "INSRWI $dst, $src, $pos, $shift" %}
13057 size(4);
13058 ins_encode %{
13059 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant);
13060 %}
13061 ins_pipe(pipe_class_default);
13062 %}
13063
13064 // As insrwi_a, but with USE_DEF.
13065 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{
13066 effect(USE_DEF dst, USE src, USE pos, USE shift);
13067 predicate(false);
13068
13069 format %{ "INSRWI $dst, $src, $pos, $shift" %}
13070 size(4);
13071 ins_encode %{
13072 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant);
13073 %}
13074 ins_pipe(pipe_class_default);
13075 %}
13076
13077 // Just slightly faster than java implementation.
13078 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
13079 match(Set dst (ReverseBytesI src));
13080 predicate(!UseByteReverseInstructions);
13081 ins_cost(7*DEFAULT_COST);
13082
13083 expand %{
13084 immI16 imm24 %{ (int) 24 %}
13085 immI16 imm16 %{ (int) 16 %}
13086 immI16 imm8 %{ (int) 8 %}
13087 immI16 imm4 %{ (int) 4 %}
13088 immI16 imm0 %{ (int) 0 %}
13089 iRegLdst tmpI1;
13090 iRegLdst tmpI2;
13091 iRegLdst tmpI3;
13092
13093 urShiftI_reg_imm(tmpI1, src, imm24);
13094 insrwi_a(dst, tmpI1, imm24, imm8);
13095 urShiftI_reg_imm(tmpI2, src, imm16);
13096 insrwi(dst, tmpI2, imm8, imm16);
13097 urShiftI_reg_imm(tmpI3, src, imm8);
13098 insrwi(dst, tmpI3, imm8, imm8);
13099 insrwi(dst, src, imm0, imm8);
13100 %}
13101 %}
13102
13103 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{
13104 match(Set dst (ReverseBytesI src));
13105 predicate(UseVectorByteReverseInstructionsPPC64);
13106 effect(TEMP tmpV);
13107 ins_cost(DEFAULT_COST*3);
13108 size(12);
13109 format %{ "MTVSRWZ $tmpV, $src\n"
13110 "\tXXBRW $tmpV, $tmpV\n"
13111 "\tMFVSRWZ $dst, $tmpV" %}
13112
13113 ins_encode %{
13114 __ mtvsrwz($tmpV$$VectorSRegister, $src$$Register);
13115 __ xxbrw($tmpV$$VectorSRegister, $tmpV$$VectorSRegister);
13116 __ mfvsrwz($dst$$Register, $tmpV$$VectorSRegister);
13117 %}
13118 ins_pipe(pipe_class_default);
13119 %}
13120
13121 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{
13122 match(Set dst (ReverseBytesI src));
13123 predicate(UseByteReverseInstructions);
13124 ins_cost(DEFAULT_COST);
13125 size(4);
13126
13127 format %{ "BRW $dst, $src" %}
13128
13129 ins_encode %{
13130 __ brw($dst$$Register, $src$$Register);
13131 %}
13132 ins_pipe(pipe_class_default);
13133 %}
13134
13135 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
13136 match(Set dst (ReverseBytesL src));
13137 predicate(!UseByteReverseInstructions);
13138 ins_cost(15*DEFAULT_COST);
13139
13140 expand %{
13141 immI16 imm56 %{ (int) 56 %}
13142 immI16 imm48 %{ (int) 48 %}
13143 immI16 imm40 %{ (int) 40 %}
13144 immI16 imm32 %{ (int) 32 %}
13145 immI16 imm24 %{ (int) 24 %}
13146 immI16 imm16 %{ (int) 16 %}
13147 immI16 imm8 %{ (int) 8 %}
13148 immI16 imm0 %{ (int) 0 %}
13149 iRegLdst tmpL1;
13150 iRegLdst tmpL2;
13151 iRegLdst tmpL3;
13152 iRegLdst tmpL4;
13153 iRegLdst tmpL5;
13154 iRegLdst tmpL6;
13155
13156 // src : |a|b|c|d|e|f|g|h|
13157 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
13158 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
13159 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
13160 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
13161 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
13162 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
13163 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
13164 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
13165 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
13166 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
13167 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
13168 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
13169 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
13170 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
13171 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
13172 %}
13173 %}
13174
13175 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{
13176 match(Set dst (ReverseBytesL src));
13177 predicate(UseVectorByteReverseInstructionsPPC64);
13178 effect(TEMP tmpV);
13179 ins_cost(DEFAULT_COST*3);
13180 size(12);
13181 format %{ "MTVSRD $tmpV, $src\n"
13182 "\tXXBRD $tmpV, $tmpV\n"
13183 "\tMFVSRD $dst, $tmpV" %}
13184
13185 ins_encode %{
13186 __ mtvsrd($tmpV$$VectorSRegister, $src$$Register);
13187 __ xxbrd($tmpV$$VectorSRegister, $tmpV$$VectorSRegister);
13188 __ mfvsrd($dst$$Register, $tmpV$$VectorSRegister);
13189 %}
13190 ins_pipe(pipe_class_default);
13191 %}
13192
13193 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{
13194 match(Set dst (ReverseBytesL src));
13195 predicate(UseByteReverseInstructions);
13196 ins_cost(DEFAULT_COST);
13197 size(4);
13198
13199 format %{ "BRD $dst, $src" %}
13200
13201 ins_encode %{
13202 __ brd($dst$$Register, $src$$Register);
13203 %}
13204 ins_pipe(pipe_class_default);
13205 %}
13206
13207 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
13208 match(Set dst (ReverseBytesUS src));
13209 predicate(!UseByteReverseInstructions);
13210 ins_cost(2*DEFAULT_COST);
13211
13212 expand %{
13213 immI16 imm16 %{ (int) 16 %}
13214 immI16 imm8 %{ (int) 8 %}
13215
13216 urShiftI_reg_imm(dst, src, imm8);
13217 insrwi(dst, src, imm16, imm8);
13218 %}
13219 %}
13220
13221 instruct bytes_reverse_ushort(iRegIdst dst, iRegIsrc src) %{
13222 match(Set dst (ReverseBytesUS src));
13223 predicate(UseByteReverseInstructions);
13224 ins_cost(DEFAULT_COST);
13225 size(4);
13226
13227 format %{ "BRH $dst, $src" %}
13228
13229 ins_encode %{
13230 __ brh($dst$$Register, $src$$Register);
13231 %}
13232 ins_pipe(pipe_class_default);
13233 %}
13234
13235 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
13236 match(Set dst (ReverseBytesS src));
13237 predicate(!UseByteReverseInstructions);
13238 ins_cost(3*DEFAULT_COST);
13239
13240 expand %{
13241 immI16 imm16 %{ (int) 16 %}
13242 immI16 imm8 %{ (int) 8 %}
13243 iRegLdst tmpI1;
13244
13245 urShiftI_reg_imm(tmpI1, src, imm8);
13246 insrwi(tmpI1, src, imm16, imm8);
13247 extsh(dst, tmpI1);
13248 %}
13249 %}
13250
13251 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{
13252 match(Set dst (ReverseBytesS src));
13253 predicate(UseByteReverseInstructions);
13254 ins_cost(DEFAULT_COST);
13255 size(8);
13256
13257 format %{ "BRH $dst, $src\n\t"
13258 "EXTSH $dst, $dst" %}
13259
13260 ins_encode %{
13261 __ brh($dst$$Register, $src$$Register);
13262 __ extsh($dst$$Register, $dst$$Register);
13263 %}
13264 ins_pipe(pipe_class_default);
13265 %}
13266
13267 // Load Integer reversed byte order
13268 instruct loadI_reversed(iRegIdst dst, indirect mem) %{
13269 match(Set dst (ReverseBytesI (LoadI mem)));
13270 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
13271 ins_cost(MEMORY_REF_COST);
13272
13273 size(4);
13274 ins_encode %{
13275 __ lwbrx($dst$$Register, $mem$$Register);
13276 %}
13277 ins_pipe(pipe_class_default);
13278 %}
13279
13280 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{
13281 match(Set dst (ReverseBytesI (LoadI mem)));
13282 ins_cost(2 * MEMORY_REF_COST);
13283
13284 size(12);
13285 ins_encode %{
13286 __ lwbrx($dst$$Register, $mem$$Register);
13287 __ twi_0($dst$$Register);
13288 __ isync();
13289 %}
13290 ins_pipe(pipe_class_default);
13291 %}
13292
13293 // Load Long - aligned and reversed
13294 instruct loadL_reversed(iRegLdst dst, indirect mem) %{
13295 match(Set dst (ReverseBytesL (LoadL mem)));
13296 predicate(VM_Version::has_ldbrx() && (n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))));
13297 ins_cost(MEMORY_REF_COST);
13298
13299 size(4);
13300 ins_encode %{
13301 __ ldbrx($dst$$Register, $mem$$Register);
13302 %}
13303 ins_pipe(pipe_class_default);
13304 %}
13305
13306 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{
13307 match(Set dst (ReverseBytesL (LoadL mem)));
13308 predicate(VM_Version::has_ldbrx());
13309 ins_cost(2 * MEMORY_REF_COST);
13310
13311 size(12);
13312 ins_encode %{
13313 __ ldbrx($dst$$Register, $mem$$Register);
13314 __ twi_0($dst$$Register);
13315 __ isync();
13316 %}
13317 ins_pipe(pipe_class_default);
13318 %}
13319
13320 // Load unsigned short / char reversed byte order
13321 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
13322 match(Set dst (ReverseBytesUS (LoadUS mem)));
13323 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
13324 ins_cost(MEMORY_REF_COST);
13325
13326 size(4);
13327 ins_encode %{
13328 __ lhbrx($dst$$Register, $mem$$Register);
13329 %}
13330 ins_pipe(pipe_class_default);
13331 %}
13332
13333 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{
13334 match(Set dst (ReverseBytesUS (LoadUS mem)));
13335 ins_cost(2 * MEMORY_REF_COST);
13336
13337 size(12);
13338 ins_encode %{
13339 __ lhbrx($dst$$Register, $mem$$Register);
13340 __ twi_0($dst$$Register);
13341 __ isync();
13342 %}
13343 ins_pipe(pipe_class_default);
13344 %}
13345
13346 // Load short reversed byte order
13347 instruct loadS_reversed(iRegIdst dst, indirect mem) %{
13348 match(Set dst (ReverseBytesS (LoadS mem)));
13349 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)));
13350 ins_cost(MEMORY_REF_COST + DEFAULT_COST);
13351
13352 size(8);
13353 ins_encode %{
13354 __ lhbrx($dst$$Register, $mem$$Register);
13355 __ extsh($dst$$Register, $dst$$Register);
13356 %}
13357 ins_pipe(pipe_class_default);
13358 %}
13359
13360 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{
13361 match(Set dst (ReverseBytesS (LoadS mem)));
13362 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
13363
13364 size(16);
13365 ins_encode %{
13366 __ lhbrx($dst$$Register, $mem$$Register);
13367 __ twi_0($dst$$Register);
13368 __ extsh($dst$$Register, $dst$$Register);
13369 __ isync();
13370 %}
13371 ins_pipe(pipe_class_default);
13372 %}
13373
13374 // Store Integer reversed byte order
13375 instruct storeI_reversed(iRegIsrc src, indirect mem) %{
13376 match(Set mem (StoreI mem (ReverseBytesI src)));
13377 ins_cost(MEMORY_REF_COST);
13378
13379 size(4);
13380 ins_encode %{
13381 __ stwbrx($src$$Register, $mem$$Register);
13382 %}
13383 ins_pipe(pipe_class_default);
13384 %}
13385
13386 // Store Long reversed byte order
13387 instruct storeL_reversed(iRegLsrc src, indirect mem) %{
13388 match(Set mem (StoreL mem (ReverseBytesL src)));
13389 predicate(VM_Version::has_stdbrx());
13390 ins_cost(MEMORY_REF_COST);
13391
13392 size(4);
13393 ins_encode %{
13394 __ stdbrx($src$$Register, $mem$$Register);
13395 %}
13396 ins_pipe(pipe_class_default);
13397 %}
13398
13399 // Store unsigned short / char reversed byte order
13400 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
13401 match(Set mem (StoreC mem (ReverseBytesUS src)));
13402 ins_cost(MEMORY_REF_COST);
13403
13404 size(4);
13405 ins_encode %{
13406 __ sthbrx($src$$Register, $mem$$Register);
13407 %}
13408 ins_pipe(pipe_class_default);
13409 %}
13410
13411 // Store short reversed byte order
13412 instruct storeS_reversed(iRegIsrc src, indirect mem) %{
13413 match(Set mem (StoreC mem (ReverseBytesS src)));
13414 ins_cost(MEMORY_REF_COST);
13415
13416 size(4);
13417 ins_encode %{
13418 __ sthbrx($src$$Register, $mem$$Register);
13419 %}
13420 ins_pipe(pipe_class_default);
13421 %}
13422
13423 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{
13424 effect(DEF temp1, USE src);
13425
13426 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %}
13427 size(4);
13428 ins_encode %{
13429 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register);
13430 %}
13431 ins_pipe(pipe_class_default);
13432 %}
13433
13434 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{
13435 effect(DEF dst, USE src, USE imm1);
13436
13437 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %}
13438 size(4);
13439 ins_encode %{
13440 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant);
13441 %}
13442 ins_pipe(pipe_class_default);
13443 %}
13444
13445 instruct xscvdpspn_regF(vecX dst, regF src) %{
13446 effect(DEF dst, USE src);
13447
13448 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %}
13449 size(4);
13450 ins_encode %{
13451 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr());
13452 %}
13453 ins_pipe(pipe_class_default);
13454 %}
13455
13456 //---------- Replicate Vector Instructions ------------------------------------
13457
13458 // Insrdi does replicate if src == dst.
13459 instruct repl32(iRegLdst dst) %{
13460 predicate(false);
13461 effect(USE_DEF dst);
13462
13463 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %}
13464 size(4);
13465 ins_encode %{
13466 __ insrdi($dst$$Register, $dst$$Register, 32, 0);
13467 %}
13468 ins_pipe(pipe_class_default);
13469 %}
13470
13471 // Insrdi does replicate if src == dst.
13472 instruct repl48(iRegLdst dst) %{
13473 predicate(false);
13474 effect(USE_DEF dst);
13475
13476 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %}
13477 size(4);
13478 ins_encode %{
13479 __ insrdi($dst$$Register, $dst$$Register, 48, 0);
13480 %}
13481 ins_pipe(pipe_class_default);
13482 %}
13483
13484 // Insrdi does replicate if src == dst.
13485 instruct repl56(iRegLdst dst) %{
13486 predicate(false);
13487 effect(USE_DEF dst);
13488
13489 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %}
13490 size(4);
13491 ins_encode %{
13492 __ insrdi($dst$$Register, $dst$$Register, 56, 0);
13493 %}
13494 ins_pipe(pipe_class_default);
13495 %}
13496
13497 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
13498 match(Set dst (ReplicateB src));
13499 predicate(n->as_Vector()->length() == 8);
13500 expand %{
13501 moveReg(dst, src);
13502 repl56(dst);
13503 repl48(dst);
13504 repl32(dst);
13505 %}
13506 %}
13507
13508 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
13509 match(Set dst (ReplicateB zero));
13510 predicate(n->as_Vector()->length() == 8);
13511 format %{ "LI $dst, #0 \t// replicate8B" %}
13512 size(4);
13513 ins_encode %{
13514 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
13515 %}
13516 ins_pipe(pipe_class_default);
13517 %}
13518
13519 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
13520 match(Set dst (ReplicateB src));
13521 predicate(n->as_Vector()->length() == 8);
13522 format %{ "LI $dst, #-1 \t// replicate8B" %}
13523 size(4);
13524 ins_encode %{
13525 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
13526 %}
13527 ins_pipe(pipe_class_default);
13528 %}
13529
13530 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{
13531 match(Set dst (ReplicateB src));
13532 predicate(n->as_Vector()->length() == 16);
13533
13534 expand %{
13535 iRegLdst tmpL;
13536 vecX tmpV;
13537 immI8 imm1 %{ (int) 1 %}
13538 moveReg(tmpL, src);
13539 repl56(tmpL);
13540 repl48(tmpL);
13541 mtvsrwz(tmpV, tmpL);
13542 xxspltw(dst, tmpV, imm1);
13543 %}
13544 %}
13545
13546 instruct repl16B_immI0(vecX dst, immI_0 zero) %{
13547 match(Set dst (ReplicateB zero));
13548 predicate(n->as_Vector()->length() == 16);
13549
13550 format %{ "XXLXOR $dst, $zero \t// replicate16B" %}
13551 size(4);
13552 ins_encode %{
13553 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13554 %}
13555 ins_pipe(pipe_class_default);
13556 %}
13557
13558 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{
13559 match(Set dst (ReplicateB src));
13560 predicate(n->as_Vector()->length() == 16);
13561
13562 format %{ "XXLEQV $dst, $src \t// replicate16B" %}
13563 size(4);
13564 ins_encode %{
13565 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13566 %}
13567 ins_pipe(pipe_class_default);
13568 %}
13569
13570 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
13571 match(Set dst (ReplicateS src));
13572 predicate(n->as_Vector()->length() == 4);
13573 expand %{
13574 moveReg(dst, src);
13575 repl48(dst);
13576 repl32(dst);
13577 %}
13578 %}
13579
13580 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
13581 match(Set dst (ReplicateS zero));
13582 predicate(n->as_Vector()->length() == 4);
13583 format %{ "LI $dst, #0 \t// replicate4S" %}
13584 size(4);
13585 ins_encode %{
13586 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
13587 %}
13588 ins_pipe(pipe_class_default);
13589 %}
13590
13591 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
13592 match(Set dst (ReplicateS src));
13593 predicate(n->as_Vector()->length() == 4);
13594 format %{ "LI $dst, -1 \t// replicate4S" %}
13595 size(4);
13596 ins_encode %{
13597 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
13598 %}
13599 ins_pipe(pipe_class_default);
13600 %}
13601
13602 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{
13603 match(Set dst (ReplicateS src));
13604 predicate(n->as_Vector()->length() == 8);
13605
13606 expand %{
13607 iRegLdst tmpL;
13608 vecX tmpV;
13609 immI8 zero %{ (int) 0 %}
13610 moveReg(tmpL, src);
13611 repl48(tmpL);
13612 repl32(tmpL);
13613 mtvsrd(tmpV, tmpL);
13614 xxpermdi(dst, tmpV, tmpV, zero);
13615 %}
13616 %}
13617
13618 instruct repl8S_immI0(vecX dst, immI_0 zero) %{
13619 match(Set dst (ReplicateS zero));
13620 predicate(n->as_Vector()->length() == 8);
13621
13622 format %{ "XXLXOR $dst, $zero \t// replicate8S" %}
13623 size(4);
13624 ins_encode %{
13625 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13626 %}
13627 ins_pipe(pipe_class_default);
13628 %}
13629
13630 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{
13631 match(Set dst (ReplicateS src));
13632 predicate(n->as_Vector()->length() == 8);
13633
13634 format %{ "XXLEQV $dst, $src \t// replicate8S" %}
13635 size(4);
13636 ins_encode %{
13637 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13638 %}
13639 ins_pipe(pipe_class_default);
13640 %}
13641
13642 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
13643 match(Set dst (ReplicateI src));
13644 predicate(n->as_Vector()->length() == 2);
13645 ins_cost(2 * DEFAULT_COST);
13646 expand %{
13647 moveReg(dst, src);
13648 repl32(dst);
13649 %}
13650 %}
13651
13652 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
13653 match(Set dst (ReplicateI zero));
13654 predicate(n->as_Vector()->length() == 2);
13655 format %{ "LI $dst, #0 \t// replicate2I" %}
13656 size(4);
13657 ins_encode %{
13658 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
13659 %}
13660 ins_pipe(pipe_class_default);
13661 %}
13662
13663 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
13664 match(Set dst (ReplicateI src));
13665 predicate(n->as_Vector()->length() == 2);
13666 format %{ "LI $dst, -1 \t// replicate2I" %}
13667 size(4);
13668 ins_encode %{
13669 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
13670 %}
13671 ins_pipe(pipe_class_default);
13672 %}
13673
13674 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{
13675 match(Set dst (ReplicateI src));
13676 predicate(n->as_Vector()->length() == 4);
13677 ins_cost(2 * DEFAULT_COST);
13678
13679 expand %{
13680 iRegLdst tmpL;
13681 vecX tmpV;
13682 immI8 zero %{ (int) 0 %}
13683 moveReg(tmpL, src);
13684 repl32(tmpL);
13685 mtvsrd(tmpV, tmpL);
13686 xxpermdi(dst, tmpV, tmpV, zero);
13687 %}
13688 %}
13689
13690 instruct repl4I_immI0(vecX dst, immI_0 zero) %{
13691 match(Set dst (ReplicateI zero));
13692 predicate(n->as_Vector()->length() == 4);
13693
13694 format %{ "XXLXOR $dst, $zero \t// replicate4I" %}
13695 size(4);
13696 ins_encode %{
13697 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13698 %}
13699 ins_pipe(pipe_class_default);
13700 %}
13701
13702 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{
13703 match(Set dst (ReplicateI src));
13704 predicate(n->as_Vector()->length() == 4);
13705
13706 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %}
13707 size(4);
13708 ins_encode %{
13709 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
13710 %}
13711 ins_pipe(pipe_class_default);
13712 %}
13713
13714 // Move float to int register via stack, replicate.
13715 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
13716 match(Set dst (ReplicateF src));
13717 predicate(n->as_Vector()->length() == 2);
13718 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
13719 expand %{
13720 stackSlotL tmpS;
13721 iRegIdst tmpI;
13722 moveF2I_reg_stack(tmpS, src); // Move float to stack.
13723 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg.
13724 moveReg(dst, tmpI); // Move int to long reg.
13725 repl32(dst); // Replicate bitpattern.
13726 %}
13727 %}
13728
13729 // Replicate scalar constant to packed float values in Double register
13730 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
13731 match(Set dst (ReplicateF src));
13732 predicate(n->as_Vector()->length() == 2);
13733 ins_cost(5 * DEFAULT_COST);
13734
13735 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
13736 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
13737 %}
13738
13739 // Replicate scalar zero constant to packed float values in Double register
13740 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
13741 match(Set dst (ReplicateF zero));
13742 predicate(n->as_Vector()->length() == 2);
13743
13744 format %{ "LI $dst, #0 \t// replicate2F" %}
13745 ins_encode %{
13746 __ li($dst$$Register, 0x0);
13747 %}
13748 ins_pipe(pipe_class_default);
13749 %}
13750
13751
13752 //----------Vector Arithmetic Instructions--------------------------------------
13753
13754 // Vector Addition Instructions
13755
13756 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
13757 match(Set dst (AddVB src1 src2));
13758 predicate(n->as_Vector()->length() == 16);
13759 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %}
13760 size(4);
13761 ins_encode %{
13762 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13763 %}
13764 ins_pipe(pipe_class_default);
13765 %}
13766
13767 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
13768 match(Set dst (AddVS src1 src2));
13769 predicate(n->as_Vector()->length() == 8);
13770 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %}
13771 size(4);
13772 ins_encode %{
13773 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13774 %}
13775 ins_pipe(pipe_class_default);
13776 %}
13777
13778 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
13779 match(Set dst (AddVI src1 src2));
13780 predicate(n->as_Vector()->length() == 4);
13781 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %}
13782 size(4);
13783 ins_encode %{
13784 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13785 %}
13786 ins_pipe(pipe_class_default);
13787 %}
13788
13789 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
13790 match(Set dst (AddVF src1 src2));
13791 predicate(n->as_Vector()->length() == 4);
13792 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %}
13793 size(4);
13794 ins_encode %{
13795 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13796 %}
13797 ins_pipe(pipe_class_default);
13798 %}
13799
13800 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
13801 match(Set dst (AddVL src1 src2));
13802 predicate(n->as_Vector()->length() == 2);
13803 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %}
13804 size(4);
13805 ins_encode %{
13806 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13807 %}
13808 ins_pipe(pipe_class_default);
13809 %}
13810
13811 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
13812 match(Set dst (AddVD src1 src2));
13813 predicate(n->as_Vector()->length() == 2);
13814 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %}
13815 size(4);
13816 ins_encode %{
13817 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13818 %}
13819 ins_pipe(pipe_class_default);
13820 %}
13821
13822 // Vector Subtraction Instructions
13823
13824 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
13825 match(Set dst (SubVB src1 src2));
13826 predicate(n->as_Vector()->length() == 16);
13827 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %}
13828 size(4);
13829 ins_encode %{
13830 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13831 %}
13832 ins_pipe(pipe_class_default);
13833 %}
13834
13835 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
13836 match(Set dst (SubVS src1 src2));
13837 predicate(n->as_Vector()->length() == 8);
13838 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %}
13839 size(4);
13840 ins_encode %{
13841 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13842 %}
13843 ins_pipe(pipe_class_default);
13844 %}
13845
13846 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
13847 match(Set dst (SubVI src1 src2));
13848 predicate(n->as_Vector()->length() == 4);
13849 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %}
13850 size(4);
13851 ins_encode %{
13852 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13853 %}
13854 ins_pipe(pipe_class_default);
13855 %}
13856
13857 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
13858 match(Set dst (SubVF src1 src2));
13859 predicate(n->as_Vector()->length() == 4);
13860 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %}
13861 size(4);
13862 ins_encode %{
13863 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13864 %}
13865 ins_pipe(pipe_class_default);
13866 %}
13867
13868 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
13869 match(Set dst (SubVL src1 src2));
13870 predicate(n->as_Vector()->length() == 2);
13871 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %}
13872 size(4);
13873 ins_encode %{
13874 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13875 %}
13876 ins_pipe(pipe_class_default);
13877 %}
13878
13879 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
13880 match(Set dst (SubVD src1 src2));
13881 predicate(n->as_Vector()->length() == 2);
13882 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %}
13883 size(4);
13884 ins_encode %{
13885 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13886 %}
13887 ins_pipe(pipe_class_default);
13888 %}
13889
13890 // Vector Multiplication Instructions
13891
13892 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
13893 match(Set dst (MulVS src1 src2));
13894 predicate(n->as_Vector()->length() == 8);
13895 effect(TEMP tmp);
13896 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %}
13897 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %}
13898 size(8);
13899 ins_encode %{
13900 __ vspltish($tmp$$VectorSRegister->to_vr(), 0);
13901 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr());
13902 %}
13903 ins_pipe(pipe_class_default);
13904 %}
13905
13906 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
13907 match(Set dst (MulVI src1 src2));
13908 predicate(n->as_Vector()->length() == 4);
13909 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %}
13910 size(4);
13911 ins_encode %{
13912 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
13913 %}
13914 ins_pipe(pipe_class_default);
13915 %}
13916
13917 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
13918 match(Set dst (MulVF src1 src2));
13919 predicate(n->as_Vector()->length() == 4);
13920 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %}
13921 size(4);
13922 ins_encode %{
13923 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13924 %}
13925 ins_pipe(pipe_class_default);
13926 %}
13927
13928 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
13929 match(Set dst (MulVD src1 src2));
13930 predicate(n->as_Vector()->length() == 2);
13931 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %}
13932 size(4);
13933 ins_encode %{
13934 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13935 %}
13936 ins_pipe(pipe_class_default);
13937 %}
13938
13939 // Vector Division Instructions
13940
13941 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
13942 match(Set dst (DivVF src1 src2));
13943 predicate(n->as_Vector()->length() == 4);
13944 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %}
13945 size(4);
13946 ins_encode %{
13947 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13948 %}
13949 ins_pipe(pipe_class_default);
13950 %}
13951
13952 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
13953 match(Set dst (DivVD src1 src2));
13954 predicate(n->as_Vector()->length() == 2);
13955 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %}
13956 size(4);
13957 ins_encode %{
13958 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
13959 %}
13960 ins_pipe(pipe_class_default);
13961 %}
13962
13963 // Vector Absolute Instructions
13964
13965 instruct vabs4F_reg(vecX dst, vecX src) %{
13966 match(Set dst (AbsVF src));
13967 predicate(n->as_Vector()->length() == 4);
13968 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
13969 size(4);
13970 ins_encode %{
13971 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister);
13972 %}
13973 ins_pipe(pipe_class_default);
13974 %}
13975
13976 instruct vabs2D_reg(vecX dst, vecX src) %{
13977 match(Set dst (AbsVD src));
13978 predicate(n->as_Vector()->length() == 2);
13979 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
13980 size(4);
13981 ins_encode %{
13982 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister);
13983 %}
13984 ins_pipe(pipe_class_default);
13985 %}
13986
13987 // Round Instructions
13988 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{
13989 match(Set dst (RoundDoubleMode src rmode));
13990 format %{ "RoundDoubleMode $src,$rmode" %}
13991 size(4);
13992 ins_encode %{
13993 switch ($rmode$$constant) {
13994 case RoundDoubleModeNode::rmode_rint:
13995 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr());
13996 break;
13997 case RoundDoubleModeNode::rmode_floor:
13998 __ frim($dst$$FloatRegister, $src$$FloatRegister);
13999 break;
14000 case RoundDoubleModeNode::rmode_ceil:
14001 __ frip($dst$$FloatRegister, $src$$FloatRegister);
14002 break;
14003 default:
14004 ShouldNotReachHere();
14005 }
14006 %}
14007 ins_pipe(pipe_class_default);
14008 %}
14009
14010 // Vector Round Instructions
14011 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
14012 match(Set dst (RoundDoubleModeV src rmode));
14013 predicate(n->as_Vector()->length() == 2);
14014 format %{ "RoundDoubleModeV $src,$rmode" %}
14015 size(4);
14016 ins_encode %{
14017 switch ($rmode$$constant) {
14018 case RoundDoubleModeNode::rmode_rint:
14019 __ xvrdpic($dst$$VectorSRegister, $src$$VectorSRegister);
14020 break;
14021 case RoundDoubleModeNode::rmode_floor:
14022 __ xvrdpim($dst$$VectorSRegister, $src$$VectorSRegister);
14023 break;
14024 case RoundDoubleModeNode::rmode_ceil:
14025 __ xvrdpip($dst$$VectorSRegister, $src$$VectorSRegister);
14026 break;
14027 default:
14028 ShouldNotReachHere();
14029 }
14030 %}
14031 ins_pipe(pipe_class_default);
14032 %}
14033
14034 // Vector Negate Instructions
14035
14036 instruct vneg4F_reg(vecX dst, vecX src) %{
14037 match(Set dst (NegVF src));
14038 predicate(n->as_Vector()->length() == 4);
14039 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
14040 size(4);
14041 ins_encode %{
14042 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister);
14043 %}
14044 ins_pipe(pipe_class_default);
14045 %}
14046
14047 instruct vneg2D_reg(vecX dst, vecX src) %{
14048 match(Set dst (NegVD src));
14049 predicate(n->as_Vector()->length() == 2);
14050 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
14051 size(4);
14052 ins_encode %{
14053 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister);
14054 %}
14055 ins_pipe(pipe_class_default);
14056 %}
14057
14058 // Vector Square Root Instructions
14059
14060 instruct vsqrt4F_reg(vecX dst, vecX src) %{
14061 match(Set dst (SqrtVF src));
14062 predicate(n->as_Vector()->length() == 4);
14063 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
14064 size(4);
14065 ins_encode %{
14066 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister);
14067 %}
14068 ins_pipe(pipe_class_default);
14069 %}
14070
14071 instruct vsqrt2D_reg(vecX dst, vecX src) %{
14072 match(Set dst (SqrtVD src));
14073 predicate(n->as_Vector()->length() == 2);
14074 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %}
14075 size(4);
14076 ins_encode %{
14077 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister);
14078 %}
14079 ins_pipe(pipe_class_default);
14080 %}
14081
14082 // Vector Population Count Instructions
14083
14084 instruct vpopcnt_reg(vecX dst, vecX src) %{
14085 match(Set dst (PopCountVI src));
14086 format %{ "VPOPCNT $dst,$src\t// pop count packed" %}
14087 size(4);
14088 ins_encode %{
14089 BasicType bt = Matcher::vector_element_basic_type(this);
14090 switch (bt) {
14091 case T_BYTE:
14092 __ vpopcntb($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr());
14093 break;
14094 case T_SHORT:
14095 __ vpopcnth($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr());
14096 break;
14097 case T_INT:
14098 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr());
14099 break;
14100 case T_LONG:
14101 __ vpopcntd($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr());
14102 break;
14103 default:
14104 ShouldNotReachHere();
14105 }
14106 %}
14107 ins_pipe(pipe_class_default);
14108 %}
14109
14110 // --------------------------------- FMA --------------------------------------
14111 // dst + src1 * src2
14112 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{
14113 match(Set dst (FmaVF dst (Binary src1 src2)));
14114 predicate(n->as_Vector()->length() == 4);
14115
14116 format %{ "XVMADDASP $dst, $src1, $src2" %}
14117
14118 size(4);
14119 ins_encode %{
14120 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14121 %}
14122 ins_pipe(pipe_class_default);
14123 %}
14124
14125 // dst - src1 * src2
14126 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{
14127 match(Set dst (FmaVF dst (Binary (NegVF src1) src2)));
14128 match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
14129 predicate(n->as_Vector()->length() == 4);
14130
14131 format %{ "XVNMSUBASP $dst, $src1, $src2" %}
14132
14133 size(4);
14134 ins_encode %{
14135 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14136 %}
14137 ins_pipe(pipe_class_default);
14138 %}
14139
14140 // - dst + src1 * src2
14141 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{
14142 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2)));
14143 predicate(n->as_Vector()->length() == 4);
14144
14145 format %{ "XVMSUBASP $dst, $src1, $src2" %}
14146
14147 size(4);
14148 ins_encode %{
14149 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14150 %}
14151 ins_pipe(pipe_class_default);
14152 %}
14153
14154 // dst + src1 * src2
14155 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{
14156 match(Set dst (FmaVD dst (Binary src1 src2)));
14157 predicate(n->as_Vector()->length() == 2);
14158
14159 format %{ "XVMADDADP $dst, $src1, $src2" %}
14160
14161 size(4);
14162 ins_encode %{
14163 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14164 %}
14165 ins_pipe(pipe_class_default);
14166 %}
14167
14168 // dst - src1 * src2
14169 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{
14170 match(Set dst (FmaVD dst (Binary (NegVD src1) src2)));
14171 match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
14172 predicate(n->as_Vector()->length() == 2);
14173
14174 format %{ "XVNMSUBADP $dst, $src1, $src2" %}
14175
14176 size(4);
14177 ins_encode %{
14178 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14179 %}
14180 ins_pipe(pipe_class_default);
14181 %}
14182
14183 // - dst + src1 * src2
14184 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
14185 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2)));
14186 predicate(n->as_Vector()->length() == 2);
14187
14188 format %{ "XVMSUBADP $dst, $src1, $src2" %}
14189
14190 size(4);
14191 ins_encode %{
14192 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
14193 %}
14194 ins_pipe(pipe_class_default);
14195 %}
14196
14197 //----------Overflow Math Instructions-----------------------------------------
14198
14199 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
14200 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
14201 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
14202
14203 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
14204 match(Set cr0 (OverflowAddL op1 op2));
14205
14206 format %{ "add_ $op1, $op2\t# overflow check long" %}
14207 ins_encode %{
14208 __ li(R0, 0);
14209 __ mtxer(R0); // clear XER.SO
14210 __ addo_(R0, $op1$$Register, $op2$$Register);
14211 %}
14212 ins_pipe(pipe_class_default);
14213 %}
14214
14215 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
14216 match(Set cr0 (OverflowSubL op1 op2));
14217
14218 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %}
14219 ins_encode %{
14220 __ li(R0, 0);
14221 __ mtxer(R0); // clear XER.SO
14222 __ subfo_(R0, $op2$$Register, $op1$$Register);
14223 %}
14224 ins_pipe(pipe_class_default);
14225 %}
14226
14227 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
14228 match(Set cr0 (OverflowSubL zero op2));
14229
14230 format %{ "nego_ R0, $op2\t# overflow check long" %}
14231 ins_encode %{
14232 __ li(R0, 0);
14233 __ mtxer(R0); // clear XER.SO
14234 __ nego_(R0, $op2$$Register);
14235 %}
14236 ins_pipe(pipe_class_default);
14237 %}
14238
14239 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
14240 match(Set cr0 (OverflowMulL op1 op2));
14241
14242 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %}
14243 ins_encode %{
14244 __ li(R0, 0);
14245 __ mtxer(R0); // clear XER.SO
14246 __ mulldo_(R0, $op1$$Register, $op2$$Register);
14247 %}
14248 ins_pipe(pipe_class_default);
14249 %}
14250
14251 instruct repl4F_reg_Ex(vecX dst, regF src) %{
14252 match(Set dst (ReplicateF src));
14253 predicate(n->as_Vector()->length() == 4);
14254 ins_cost(DEFAULT_COST);
14255 expand %{
14256 vecX tmpV;
14257 immI8 zero %{ (int) 0 %}
14258
14259 xscvdpspn_regF(tmpV, src);
14260 xxspltw(dst, tmpV, zero);
14261 %}
14262 %}
14263
14264 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{
14265 match(Set dst (ReplicateF src));
14266 predicate(n->as_Vector()->length() == 4);
14267 effect(TEMP tmp);
14268 ins_cost(10 * DEFAULT_COST);
14269
14270 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) );
14271 %}
14272
14273 instruct repl4F_immF0(vecX dst, immF_0 zero) %{
14274 match(Set dst (ReplicateF zero));
14275 predicate(n->as_Vector()->length() == 4);
14276
14277 format %{ "XXLXOR $dst, $zero \t// replicate4F" %}
14278 ins_encode %{
14279 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
14280 %}
14281 ins_pipe(pipe_class_default);
14282 %}
14283
14284 instruct repl2D_reg_Ex(vecX dst, regD src) %{
14285 match(Set dst (ReplicateD src));
14286 predicate(n->as_Vector()->length() == 2);
14287
14288 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %}
14289 size(4);
14290 ins_encode %{
14291 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0);
14292 %}
14293 ins_pipe(pipe_class_default);
14294 %}
14295
14296 instruct repl2D_immD0(vecX dst, immD_0 zero) %{
14297 match(Set dst (ReplicateD zero));
14298 predicate(n->as_Vector()->length() == 2);
14299
14300 format %{ "XXLXOR $dst, $zero \t// replicate2D" %}
14301 size(4);
14302 ins_encode %{
14303 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
14304 %}
14305 ins_pipe(pipe_class_default);
14306 %}
14307
14308 instruct mtvsrd(vecX dst, iRegLsrc src) %{
14309 predicate(false);
14310 effect(DEF dst, USE src);
14311
14312 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %}
14313 size(4);
14314 ins_encode %{
14315 __ mtvsrd($dst$$VectorSRegister, $src$$Register);
14316 %}
14317 ins_pipe(pipe_class_default);
14318 %}
14319
14320 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{
14321 effect(DEF dst, USE src, USE zero);
14322
14323 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %}
14324 size(4);
14325 ins_encode %{
14326 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant);
14327 %}
14328 ins_pipe(pipe_class_default);
14329 %}
14330
14331 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{
14332 effect(DEF dst, USE src1, USE src2, USE zero);
14333
14334 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %}
14335 size(4);
14336 ins_encode %{
14337 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant);
14338 %}
14339 ins_pipe(pipe_class_default);
14340 %}
14341
14342 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{
14343 match(Set dst (ReplicateL src));
14344 predicate(n->as_Vector()->length() == 2);
14345 expand %{
14346 vecX tmpV;
14347 immI8 zero %{ (int) 0 %}
14348 mtvsrd(tmpV, src);
14349 xxpermdi(dst, tmpV, tmpV, zero);
14350 %}
14351 %}
14352
14353 instruct repl2L_immI0(vecX dst, immI_0 zero) %{
14354 match(Set dst (ReplicateL zero));
14355 predicate(n->as_Vector()->length() == 2);
14356
14357 format %{ "XXLXOR $dst, $zero \t// replicate2L" %}
14358 size(4);
14359 ins_encode %{
14360 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
14361 %}
14362 ins_pipe(pipe_class_default);
14363 %}
14364
14365 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{
14366 match(Set dst (ReplicateL src));
14367 predicate(n->as_Vector()->length() == 2);
14368
14369 format %{ "XXLEQV $dst, $src \t// replicate2L" %}
14370 size(4);
14371 ins_encode %{
14372 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister);
14373 %}
14374 ins_pipe(pipe_class_default);
14375 %}
14376
14377 // ============================================================================
14378 // Safepoint Instruction
14379
14380 instruct safePoint_poll(iRegPdst poll) %{
14381 match(SafePoint poll);
14382
14383 // It caused problems to add the effect that r0 is killed, but this
14384 // effect no longer needs to be mentioned, since r0 is not contained
14385 // in a reg_class.
14386
14387 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
14388 size(4);
14389 ins_encode( enc_poll(0x0, poll) );
14390 ins_pipe(pipe_class_default);
14391 %}
14392
14393 // ============================================================================
14394 // Call Instructions
14395
14396 // Call Java Static Instruction
14397
14398 source %{
14399
14400 #include "runtime/continuation.hpp"
14401
14402 %}
14403
14404 // Schedulable version of call static node.
14405 instruct CallStaticJavaDirect(method meth) %{
14406 match(CallStaticJava);
14407 effect(USE meth);
14408 ins_cost(CALL_COST);
14409
14410 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
14411
14412 format %{ "CALL,static $meth \t// ==> " %}
14413 size((Continuations::enabled() ? 8 : 4));
14414 ins_encode( enc_java_static_call(meth) );
14415 ins_pipe(pipe_class_call);
14416 %}
14417
14418 // Call Java Dynamic Instruction
14419
14420 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call).
14421 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable
14422 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node.
14423 // The call destination must still be placed in the constant pool.
14424 instruct CallDynamicJavaDirectSched(method meth) %{
14425 match(CallDynamicJava); // To get all the data fields we need ...
14426 effect(USE meth);
14427 predicate(false); // ... but never match.
14428
14429 ins_field_load_ic_hi_node(loadConL_hiNode*);
14430 ins_field_load_ic_node(loadConLNode*);
14431 ins_num_consts(1 /* 1 patchable constant: call destination */);
14432
14433 format %{ "BL \t// dynamic $meth ==> " %}
14434 size((Continuations::enabled() ? 8 : 4));
14435 ins_encode( enc_java_dynamic_call_sched(meth) );
14436 ins_pipe(pipe_class_call);
14437 %}
14438
14439 // Schedulable (i.e. postalloc expanded) version of call dynamic java.
14440 // We use postalloc expanded calls if we use inline caches
14441 // and do not update method data.
14442 //
14443 // This instruction has two constants: inline cache (IC) and call destination.
14444 // Loading the inline cache will be postalloc expanded, thus leaving a call with
14445 // one constant.
14446 instruct CallDynamicJavaDirectSched_Ex(method meth) %{
14447 match(CallDynamicJava);
14448 effect(USE meth);
14449 predicate(UseInlineCaches);
14450 ins_cost(CALL_COST);
14451
14452 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */);
14453
14454 format %{ "CALL,dynamic $meth \t// postalloc expanded" %}
14455 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) );
14456 %}
14457
14458 // Compound version of call dynamic java
14459 // We use postalloc expanded calls if we use inline caches
14460 // and do not update method data.
14461 instruct CallDynamicJavaDirect(method meth) %{
14462 match(CallDynamicJava);
14463 effect(USE meth);
14464 predicate(!UseInlineCaches);
14465 ins_cost(CALL_COST);
14466
14467 // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
14468 ins_num_consts(4);
14469
14470 format %{ "CALL,dynamic $meth \t// ==> " %}
14471 ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
14472 ins_pipe(pipe_class_call);
14473 %}
14474
14475 // Call Runtime Instruction
14476
14477 instruct CallRuntimeDirect(method meth) %{
14478 match(CallRuntime);
14479 effect(USE meth);
14480 ins_cost(CALL_COST);
14481
14482 // Enc_java_to_runtime_call needs up to 3 constants: call target,
14483 // env for callee, C-toc.
14484 ins_num_consts(3);
14485
14486 format %{ "CALL,runtime" %}
14487 ins_encode( enc_java_to_runtime_call(meth) );
14488 ins_pipe(pipe_class_call);
14489 %}
14490
14491 // Call Leaf
14492
14493 // Used by postalloc expand of CallLeafDirect_Ex (mtctr).
14494 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
14495 effect(DEF dst, USE src);
14496
14497 ins_num_consts(1);
14498
14499 format %{ "MTCTR $src" %}
14500 size(4);
14501 ins_encode( enc_leaf_call_mtctr(src) );
14502 ins_pipe(pipe_class_default);
14503 %}
14504
14505 // Used by postalloc expand of CallLeafDirect_Ex (actual call).
14506 instruct CallLeafDirect(method meth) %{
14507 match(CallLeaf); // To get the data all the data fields we need ...
14508 effect(USE meth);
14509 predicate(false); // but never match.
14510
14511 format %{ "BCTRL \t// leaf call $meth ==> " %}
14512 size((Continuations::enabled() ? 8 : 4));
14513 ins_encode %{
14514 __ bctrl();
14515 __ post_call_nop();
14516 %}
14517 ins_pipe(pipe_class_call);
14518 %}
14519
14520 // postalloc expand of CallLeafDirect.
14521 // Load address to call from TOC, then bl to it.
14522 instruct CallLeafDirect_Ex(method meth) %{
14523 match(CallLeaf);
14524 effect(USE meth);
14525 ins_cost(CALL_COST);
14526
14527 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
14528 // env for callee, C-toc.
14529 ins_num_consts(3);
14530
14531 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
14532 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
14533 %}
14534
14535 // Call runtime without safepoint - same as CallLeaf.
14536 // postalloc expand of CallLeafNoFPDirect.
14537 // Load address to call from TOC, then bl to it.
14538 instruct CallLeafNoFPDirect_Ex(method meth) %{
14539 match(CallLeafNoFP);
14540 effect(USE meth);
14541 ins_cost(CALL_COST);
14542
14543 // Enc_java_to_runtime_call needs up to 3 constants: call target,
14544 // env for callee, C-toc.
14545 ins_num_consts(3);
14546
14547 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
14548 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
14549 %}
14550
14551 // Tail Call; Jump from runtime stub to Java code.
14552 // Also known as an 'interprocedural jump'.
14553 // Target of jump will eventually return to caller.
14554 // TailJump below removes the return address.
14555 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{
14556 match(TailCall jump_target method_ptr);
14557 ins_cost(CALL_COST);
14558
14559 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t"
14560 "BCTR \t// tail call" %}
14561 size(8);
14562 ins_encode %{
14563 __ mtctr($jump_target$$Register);
14564 __ bctr();
14565 %}
14566 ins_pipe(pipe_class_call);
14567 %}
14568
14569 // Return Instruction
14570 instruct Ret() %{
14571 match(Return);
14572 format %{ "BLR \t// branch to link register" %}
14573 size(4);
14574 ins_encode %{
14575 // LR is restored in MachEpilogNode. Just do the RET here.
14576 __ blr();
14577 %}
14578 ins_pipe(pipe_class_default);
14579 %}
14580
14581 // Tail Jump; remove the return address; jump to target.
14582 // TailCall above leaves the return address around.
14583 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
14584 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
14585 // "restore" before this instruction (in Epilogue), we need to materialize it
14586 // in %i0.
14587 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
14588 match(TailJump jump_target ex_oop);
14589 ins_cost(CALL_COST);
14590
14591 format %{ "LD R4_ARG2 = LR\n\t"
14592 "MTCTR $jump_target\n\t"
14593 "BCTR \t// TailJump, exception oop: $ex_oop" %}
14594 size(12);
14595 ins_encode %{
14596 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP);
14597 __ mtctr($jump_target$$Register);
14598 __ bctr();
14599 %}
14600 ins_pipe(pipe_class_call);
14601 %}
14602
14603 // Create exception oop: created by stack-crawling runtime code.
14604 // Created exception is now available to this handler, and is setup
14605 // just prior to jumping to this handler. No code emitted.
14606 instruct CreateException(rarg1RegP ex_oop) %{
14607 match(Set ex_oop (CreateEx));
14608 ins_cost(0);
14609
14610 format %{ " -- \t// exception oop; no code emitted" %}
14611 size(0);
14612 ins_encode( /*empty*/ );
14613 ins_pipe(pipe_class_default);
14614 %}
14615
14616 // Rethrow exception: The exception oop will come in the first
14617 // argument position. Then JUMP (not call) to the rethrow stub code.
14618 instruct RethrowException() %{
14619 match(Rethrow);
14620 ins_cost(CALL_COST);
14621
14622 format %{ "Jmp rethrow_stub" %}
14623 ins_encode %{
14624 cbuf.set_insts_mark();
14625 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
14626 %}
14627 ins_pipe(pipe_class_call);
14628 %}
14629
14630 // Die now.
14631 instruct ShouldNotReachHere() %{
14632 match(Halt);
14633 ins_cost(CALL_COST);
14634
14635 format %{ "ShouldNotReachHere" %}
14636 ins_encode %{
14637 if (is_reachable()) {
14638 __ stop(_halt_reason);
14639 }
14640 %}
14641 ins_pipe(pipe_class_default);
14642 %}
14643
14644 // This name is KNOWN by the ADLC and cannot be changed. The ADLC
14645 // forces a 'TypeRawPtr::BOTTOM' output type for this guy.
14646 // Get a DEF on threadRegP, no costs, no encoding, use
14647 // 'ins_should_rematerialize(true)' to avoid spilling.
14648 instruct tlsLoadP(threadRegP dst) %{
14649 match(Set dst (ThreadLocal));
14650 ins_cost(0);
14651
14652 ins_should_rematerialize(true);
14653
14654 format %{ " -- \t// $dst=Thread::current(), empty" %}
14655 size(0);
14656 ins_encode( /*empty*/ );
14657 ins_pipe(pipe_class_empty);
14658 %}
14659
14660 //---Some PPC specific nodes---------------------------------------------------
14661
14662 // Stop a group.
14663 instruct endGroup() %{
14664 ins_cost(0);
14665
14666 ins_is_nop(true);
14667
14668 format %{ "End Bundle (ori r1, r1, 0)" %}
14669 size(4);
14670 ins_encode %{
14671 __ endgroup();
14672 %}
14673 ins_pipe(pipe_class_default);
14674 %}
14675
14676 // Nop instructions
14677
14678 instruct fxNop() %{
14679 ins_cost(0);
14680
14681 ins_is_nop(true);
14682
14683 format %{ "fxNop" %}
14684 size(4);
14685 ins_encode %{
14686 __ nop();
14687 %}
14688 ins_pipe(pipe_class_default);
14689 %}
14690
14691 instruct fpNop0() %{
14692 ins_cost(0);
14693
14694 ins_is_nop(true);
14695
14696 format %{ "fpNop0" %}
14697 size(4);
14698 ins_encode %{
14699 __ fpnop0();
14700 %}
14701 ins_pipe(pipe_class_default);
14702 %}
14703
14704 instruct fpNop1() %{
14705 ins_cost(0);
14706
14707 ins_is_nop(true);
14708
14709 format %{ "fpNop1" %}
14710 size(4);
14711 ins_encode %{
14712 __ fpnop1();
14713 %}
14714 ins_pipe(pipe_class_default);
14715 %}
14716
14717 instruct brNop0() %{
14718 ins_cost(0);
14719 size(4);
14720 format %{ "brNop0" %}
14721 ins_encode %{
14722 __ brnop0();
14723 %}
14724 ins_is_nop(true);
14725 ins_pipe(pipe_class_default);
14726 %}
14727
14728 instruct brNop1() %{
14729 ins_cost(0);
14730
14731 ins_is_nop(true);
14732
14733 format %{ "brNop1" %}
14734 size(4);
14735 ins_encode %{
14736 __ brnop1();
14737 %}
14738 ins_pipe(pipe_class_default);
14739 %}
14740
14741 instruct brNop2() %{
14742 ins_cost(0);
14743
14744 ins_is_nop(true);
14745
14746 format %{ "brNop2" %}
14747 size(4);
14748 ins_encode %{
14749 __ brnop2();
14750 %}
14751 ins_pipe(pipe_class_default);
14752 %}
14753
14754 instruct cacheWB(indirect addr)
14755 %{
14756 match(CacheWB addr);
14757
14758 ins_cost(100);
14759 format %{ "cache writeback, address = $addr" %}
14760 ins_encode %{
14761 assert($addr->index_position() < 0, "should be");
14762 assert($addr$$disp == 0, "should be");
14763 __ cache_wb(Address($addr$$base$$Register));
14764 %}
14765 ins_pipe(pipe_class_default);
14766 %}
14767
14768 instruct cacheWBPreSync()
14769 %{
14770 match(CacheWBPreSync);
14771
14772 ins_cost(0);
14773 format %{ "cache writeback presync" %}
14774 ins_encode %{
14775 __ cache_wbsync(true);
14776 %}
14777 ins_pipe(pipe_class_default);
14778 %}
14779
14780 instruct cacheWBPostSync()
14781 %{
14782 match(CacheWBPostSync);
14783
14784 ins_cost(100);
14785 format %{ "cache writeback postsync" %}
14786 ins_encode %{
14787 __ cache_wbsync(false);
14788 %}
14789 ins_pipe(pipe_class_default);
14790 %}
14791
14792 //----------PEEPHOLE RULES-----------------------------------------------------
14793 // These must follow all instruction definitions as they use the names
14794 // defined in the instructions definitions.
14795 //
14796 // peepmatch ( root_instr_name [preceeding_instruction]* );
14797 //
14798 // peepconstraint %{
14799 // (instruction_number.operand_name relational_op instruction_number.operand_name
14800 // [, ...] );
14801 // // instruction numbers are zero-based using left to right order in peepmatch
14802 //
14803 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14804 // // provide an instruction_number.operand_name for each operand that appears
14805 // // in the replacement instruction's match rule
14806 //
14807 // ---------VM FLAGS---------------------------------------------------------
14808 //
14809 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14810 //
14811 // Each peephole rule is given an identifying number starting with zero and
14812 // increasing by one in the order seen by the parser. An individual peephole
14813 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14814 // on the command-line.
14815 //
14816 // ---------CURRENT LIMITATIONS----------------------------------------------
14817 //
14818 // Only match adjacent instructions in same basic block
14819 // Only equality constraints
14820 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14821 // Only one replacement instruction
14822 //
14823 // ---------EXAMPLE----------------------------------------------------------
14824 //
14825 // // pertinent parts of existing instructions in architecture description
14826 // instruct movI(eRegI dst, eRegI src) %{
14827 // match(Set dst (CopyI src));
14828 // %}
14829 //
14830 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14831 // match(Set dst (AddI dst src));
14832 // effect(KILL cr);
14833 // %}
14834 //
14835 // // Change (inc mov) to lea
14836 // peephole %{
14837 // // increment preceded by register-register move
14838 // peepmatch ( incI_eReg movI );
14839 // // require that the destination register of the increment
14840 // // match the destination register of the move
14841 // peepconstraint ( 0.dst == 1.dst );
14842 // // construct a replacement instruction that sets
14843 // // the destination to ( move's source register + one )
14844 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14845 // %}
14846 //
14847 // Implementation no longer uses movX instructions since
14848 // machine-independent system no longer uses CopyX nodes.
14849 //
14850 // peephole %{
14851 // peepmatch ( incI_eReg movI );
14852 // peepconstraint ( 0.dst == 1.dst );
14853 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14854 // %}
14855 //
14856 // peephole %{
14857 // peepmatch ( decI_eReg movI );
14858 // peepconstraint ( 0.dst == 1.dst );
14859 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14860 // %}
14861 //
14862 // peephole %{
14863 // peepmatch ( addI_eReg_imm movI );
14864 // peepconstraint ( 0.dst == 1.dst );
14865 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14866 // %}
14867 //
14868 // peephole %{
14869 // peepmatch ( addP_eReg_imm movP );
14870 // peepconstraint ( 0.dst == 1.dst );
14871 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
14872 // %}
14873
14874 // // Change load of spilled value to only a spill
14875 // instruct storeI(memory mem, eRegI src) %{
14876 // match(Set mem (StoreI mem src));
14877 // %}
14878 //
14879 // instruct loadI(eRegI dst, memory mem) %{
14880 // match(Set dst (LoadI mem));
14881 // %}
14882 //
14883 peephole %{
14884 peepmatch ( loadI storeI );
14885 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14886 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14887 %}
14888
14889 peephole %{
14890 peepmatch ( loadL storeL );
14891 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14892 peepreplace ( storeL( 1.mem 1.mem 1.src ) );
14893 %}
14894
14895 peephole %{
14896 peepmatch ( loadP storeP );
14897 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
14898 peepreplace ( storeP( 1.dst 1.dst 1.src ) );
14899 %}
14900
14901 //----------SMARTSPILL RULES---------------------------------------------------
14902 // These must follow all instruction definitions as they use the names
14903 // defined in the instructions definitions.