Print this page
rev 1838 : 6961690: load oops from constant table on SPARC
Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence.
Reviewed-by:
Split |
Close |
Expand all |
Collapse all |
--- old/src/cpu/x86/vm/x86_64.ad
+++ new/src/cpu/x86/vm/x86_64.ad
1 1 //
2 2 // Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 //
5 5 // This code is free software; you can redistribute it and/or modify it
6 6 // under the terms of the GNU General Public License version 2 only, as
7 7 // published by the Free Software Foundation.
8 8 //
9 9 // This code is distributed in the hope that it will be useful, but WITHOUT
10 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 12 // version 2 for more details (a copy is included in the LICENSE file that
13 13 // accompanied this code).
14 14 //
15 15 // You should have received a copy of the GNU General Public License version
16 16 // 2 along with this work; if not, write to the Free Software Foundation,
17 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 18 //
19 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 20 // or visit www.oracle.com if you need additional information or have any
21 21 // questions.
22 22 //
23 23 //
24 24
25 25 // AMD64 Architecture Description File
26 26
27 27 //----------REGISTER DEFINITION BLOCK------------------------------------------
28 28 // This information is used by the matcher and the register allocator to
29 29 // describe individual registers and classes of registers within the target
30 30 // archtecture.
31 31
32 32 register %{
33 33 //----------Architecture Description Register Definitions----------------------
34 34 // General Registers
35 35 // "reg_def" name ( register save type, C convention save type,
36 36 // ideal register type, encoding );
37 37 // Register Save Types:
38 38 //
39 39 // NS = No-Save: The register allocator assumes that these registers
40 40 // can be used without saving upon entry to the method, &
41 41 // that they do not need to be saved at call sites.
42 42 //
43 43 // SOC = Save-On-Call: The register allocator assumes that these registers
44 44 // can be used without saving upon entry to the method,
45 45 // but that they must be saved at call sites.
46 46 //
47 47 // SOE = Save-On-Entry: The register allocator assumes that these registers
48 48 // must be saved before using them upon entry to the
49 49 // method, but they do not need to be saved at call
50 50 // sites.
51 51 //
52 52 // AS = Always-Save: The register allocator assumes that these registers
53 53 // must be saved before using them upon entry to the
54 54 // method, & that they must be saved at call sites.
55 55 //
56 56 // Ideal Register Type is used to determine how to save & restore a
57 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
58 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
59 59 //
60 60 // The encoding number is the actual bit-pattern placed into the opcodes.
61 61
62 62 // General Registers
63 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when
64 64 // used as byte registers)
65 65
66 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code
67 67 // Turn off SOE in java-code due to frequent use of uncommon-traps.
68 68 // Now that allocator is better, turn on RSI and RDI as SOE registers.
69 69
70 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg());
71 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next());
72 72
73 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg());
74 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next());
75 75
76 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg());
77 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next());
78 78
79 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg());
80 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next());
81 81
82 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg());
83 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next());
84 84
85 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code
86 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg());
87 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next());
88 88
89 89 #ifdef _WIN64
90 90
91 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg());
92 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next());
93 93
94 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg());
95 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next());
96 96
97 97 #else
98 98
99 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg());
100 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next());
101 101
102 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg());
103 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next());
104 104
105 105 #endif
106 106
107 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg());
108 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next());
109 109
110 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg());
111 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next());
112 112
113 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg());
114 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
115 115
116 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg());
117 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
118 118
119 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg());
120 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next());
121 121
122 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg());
123 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next());
124 124
125 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg());
126 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next());
127 127
128 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg());
129 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next());
130 130
131 131
132 132 // Floating Point Registers
133 133
134 134 // XMM registers. 128-bit registers or 4 words each, labeled (a)-d.
135 135 // Word a in each register holds a Float, words ab hold a Double. We
136 136 // currently do not use the SIMD capabilities, so registers cd are
137 137 // unused at the moment.
138 138 // XMM8-XMM15 must be encoded with REX.
139 139 // Linux ABI: No register preserved across function calls
140 140 // XMM0-XMM7 might hold parameters
141 141 // Windows ABI: XMM6-XMM15 preserved across function calls
142 142 // XMM0-XMM3 might hold parameters
143 143
144 144 reg_def XMM0 (SOC, SOC, Op_RegF, 0, xmm0->as_VMReg());
145 145 reg_def XMM0_H (SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next());
146 146
147 147 reg_def XMM1 (SOC, SOC, Op_RegF, 1, xmm1->as_VMReg());
148 148 reg_def XMM1_H (SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next());
149 149
150 150 reg_def XMM2 (SOC, SOC, Op_RegF, 2, xmm2->as_VMReg());
151 151 reg_def XMM2_H (SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next());
152 152
153 153 reg_def XMM3 (SOC, SOC, Op_RegF, 3, xmm3->as_VMReg());
154 154 reg_def XMM3_H (SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next());
155 155
156 156 reg_def XMM4 (SOC, SOC, Op_RegF, 4, xmm4->as_VMReg());
157 157 reg_def XMM4_H (SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next());
158 158
159 159 reg_def XMM5 (SOC, SOC, Op_RegF, 5, xmm5->as_VMReg());
160 160 reg_def XMM5_H (SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next());
161 161
162 162 #ifdef _WIN64
163 163
164 164 reg_def XMM6 (SOC, SOE, Op_RegF, 6, xmm6->as_VMReg());
165 165 reg_def XMM6_H (SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next());
166 166
167 167 reg_def XMM7 (SOC, SOE, Op_RegF, 7, xmm7->as_VMReg());
168 168 reg_def XMM7_H (SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next());
169 169
170 170 reg_def XMM8 (SOC, SOE, Op_RegF, 8, xmm8->as_VMReg());
171 171 reg_def XMM8_H (SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next());
172 172
173 173 reg_def XMM9 (SOC, SOE, Op_RegF, 9, xmm9->as_VMReg());
174 174 reg_def XMM9_H (SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next());
175 175
176 176 reg_def XMM10 (SOC, SOE, Op_RegF, 10, xmm10->as_VMReg());
177 177 reg_def XMM10_H(SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next());
178 178
179 179 reg_def XMM11 (SOC, SOE, Op_RegF, 11, xmm11->as_VMReg());
180 180 reg_def XMM11_H(SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next());
181 181
182 182 reg_def XMM12 (SOC, SOE, Op_RegF, 12, xmm12->as_VMReg());
183 183 reg_def XMM12_H(SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next());
184 184
185 185 reg_def XMM13 (SOC, SOE, Op_RegF, 13, xmm13->as_VMReg());
186 186 reg_def XMM13_H(SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next());
187 187
188 188 reg_def XMM14 (SOC, SOE, Op_RegF, 14, xmm14->as_VMReg());
189 189 reg_def XMM14_H(SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next());
190 190
191 191 reg_def XMM15 (SOC, SOE, Op_RegF, 15, xmm15->as_VMReg());
192 192 reg_def XMM15_H(SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next());
193 193
194 194 #else
195 195
196 196 reg_def XMM6 (SOC, SOC, Op_RegF, 6, xmm6->as_VMReg());
197 197 reg_def XMM6_H (SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next());
198 198
199 199 reg_def XMM7 (SOC, SOC, Op_RegF, 7, xmm7->as_VMReg());
200 200 reg_def XMM7_H (SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next());
201 201
202 202 reg_def XMM8 (SOC, SOC, Op_RegF, 8, xmm8->as_VMReg());
203 203 reg_def XMM8_H (SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next());
204 204
205 205 reg_def XMM9 (SOC, SOC, Op_RegF, 9, xmm9->as_VMReg());
206 206 reg_def XMM9_H (SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next());
207 207
208 208 reg_def XMM10 (SOC, SOC, Op_RegF, 10, xmm10->as_VMReg());
209 209 reg_def XMM10_H(SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next());
210 210
211 211 reg_def XMM11 (SOC, SOC, Op_RegF, 11, xmm11->as_VMReg());
212 212 reg_def XMM11_H(SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next());
213 213
214 214 reg_def XMM12 (SOC, SOC, Op_RegF, 12, xmm12->as_VMReg());
215 215 reg_def XMM12_H(SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next());
216 216
217 217 reg_def XMM13 (SOC, SOC, Op_RegF, 13, xmm13->as_VMReg());
218 218 reg_def XMM13_H(SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next());
219 219
220 220 reg_def XMM14 (SOC, SOC, Op_RegF, 14, xmm14->as_VMReg());
221 221 reg_def XMM14_H(SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next());
222 222
223 223 reg_def XMM15 (SOC, SOC, Op_RegF, 15, xmm15->as_VMReg());
224 224 reg_def XMM15_H(SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next());
225 225
226 226 #endif // _WIN64
227 227
228 228 reg_def RFLAGS(SOC, SOC, 0, 16, VMRegImpl::Bad());
229 229
230 230 // Specify priority of register selection within phases of register
231 231 // allocation. Highest priority is first. A useful heuristic is to
232 232 // give registers a low priority when they are required by machine
233 233 // instructions, like EAX and EDX on I486, and choose no-save registers
234 234 // before save-on-call, & save-on-call before save-on-entry. Registers
235 235 // which participate in fixed calling sequences should come last.
236 236 // Registers which are used as pairs must fall on an even boundary.
237 237
238 238 alloc_class chunk0(R10, R10_H,
239 239 R11, R11_H,
240 240 R8, R8_H,
241 241 R9, R9_H,
242 242 R12, R12_H,
243 243 RCX, RCX_H,
244 244 RBX, RBX_H,
245 245 RDI, RDI_H,
246 246 RDX, RDX_H,
247 247 RSI, RSI_H,
248 248 RAX, RAX_H,
249 249 RBP, RBP_H,
250 250 R13, R13_H,
251 251 R14, R14_H,
252 252 R15, R15_H,
253 253 RSP, RSP_H);
254 254
255 255 // XXX probably use 8-15 first on Linux
256 256 alloc_class chunk1(XMM0, XMM0_H,
257 257 XMM1, XMM1_H,
258 258 XMM2, XMM2_H,
259 259 XMM3, XMM3_H,
260 260 XMM4, XMM4_H,
261 261 XMM5, XMM5_H,
262 262 XMM6, XMM6_H,
263 263 XMM7, XMM7_H,
264 264 XMM8, XMM8_H,
265 265 XMM9, XMM9_H,
266 266 XMM10, XMM10_H,
267 267 XMM11, XMM11_H,
268 268 XMM12, XMM12_H,
269 269 XMM13, XMM13_H,
270 270 XMM14, XMM14_H,
271 271 XMM15, XMM15_H);
272 272
273 273 alloc_class chunk2(RFLAGS);
274 274
275 275
276 276 //----------Architecture Description Register Classes--------------------------
277 277 // Several register classes are automatically defined based upon information in
278 278 // this architecture description.
279 279 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ )
280 280 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ )
281 281 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
282 282 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
283 283 //
284 284
285 285 // Class for all pointer registers (including RSP)
286 286 reg_class any_reg(RAX, RAX_H,
287 287 RDX, RDX_H,
288 288 RBP, RBP_H,
289 289 RDI, RDI_H,
290 290 RSI, RSI_H,
291 291 RCX, RCX_H,
292 292 RBX, RBX_H,
293 293 RSP, RSP_H,
294 294 R8, R8_H,
295 295 R9, R9_H,
296 296 R10, R10_H,
297 297 R11, R11_H,
298 298 R12, R12_H,
299 299 R13, R13_H,
300 300 R14, R14_H,
301 301 R15, R15_H);
302 302
303 303 // Class for all pointer registers except RSP
304 304 reg_class ptr_reg(RAX, RAX_H,
305 305 RDX, RDX_H,
306 306 RBP, RBP_H,
307 307 RDI, RDI_H,
308 308 RSI, RSI_H,
309 309 RCX, RCX_H,
310 310 RBX, RBX_H,
311 311 R8, R8_H,
312 312 R9, R9_H,
313 313 R10, R10_H,
314 314 R11, R11_H,
315 315 R13, R13_H,
316 316 R14, R14_H);
317 317
318 318 // Class for all pointer registers except RAX and RSP
319 319 reg_class ptr_no_rax_reg(RDX, RDX_H,
320 320 RBP, RBP_H,
321 321 RDI, RDI_H,
322 322 RSI, RSI_H,
323 323 RCX, RCX_H,
324 324 RBX, RBX_H,
325 325 R8, R8_H,
326 326 R9, R9_H,
327 327 R10, R10_H,
328 328 R11, R11_H,
329 329 R13, R13_H,
330 330 R14, R14_H);
331 331
332 332 reg_class ptr_no_rbp_reg(RDX, RDX_H,
333 333 RAX, RAX_H,
334 334 RDI, RDI_H,
335 335 RSI, RSI_H,
336 336 RCX, RCX_H,
337 337 RBX, RBX_H,
338 338 R8, R8_H,
339 339 R9, R9_H,
340 340 R10, R10_H,
341 341 R11, R11_H,
342 342 R13, R13_H,
343 343 R14, R14_H);
344 344
345 345 // Class for all pointer registers except RAX, RBX and RSP
346 346 reg_class ptr_no_rax_rbx_reg(RDX, RDX_H,
347 347 RBP, RBP_H,
348 348 RDI, RDI_H,
349 349 RSI, RSI_H,
350 350 RCX, RCX_H,
351 351 R8, R8_H,
352 352 R9, R9_H,
353 353 R10, R10_H,
354 354 R11, R11_H,
355 355 R13, R13_H,
356 356 R14, R14_H);
357 357
358 358 // Singleton class for RAX pointer register
359 359 reg_class ptr_rax_reg(RAX, RAX_H);
360 360
361 361 // Singleton class for RBX pointer register
362 362 reg_class ptr_rbx_reg(RBX, RBX_H);
363 363
364 364 // Singleton class for RSI pointer register
365 365 reg_class ptr_rsi_reg(RSI, RSI_H);
366 366
367 367 // Singleton class for RDI pointer register
368 368 reg_class ptr_rdi_reg(RDI, RDI_H);
369 369
370 370 // Singleton class for RBP pointer register
371 371 reg_class ptr_rbp_reg(RBP, RBP_H);
372 372
373 373 // Singleton class for stack pointer
374 374 reg_class ptr_rsp_reg(RSP, RSP_H);
375 375
376 376 // Singleton class for TLS pointer
377 377 reg_class ptr_r15_reg(R15, R15_H);
378 378
379 379 // Class for all long registers (except RSP)
380 380 reg_class long_reg(RAX, RAX_H,
381 381 RDX, RDX_H,
382 382 RBP, RBP_H,
383 383 RDI, RDI_H,
384 384 RSI, RSI_H,
385 385 RCX, RCX_H,
386 386 RBX, RBX_H,
387 387 R8, R8_H,
388 388 R9, R9_H,
389 389 R10, R10_H,
390 390 R11, R11_H,
391 391 R13, R13_H,
392 392 R14, R14_H);
393 393
394 394 // Class for all long registers except RAX, RDX (and RSP)
395 395 reg_class long_no_rax_rdx_reg(RBP, RBP_H,
396 396 RDI, RDI_H,
397 397 RSI, RSI_H,
398 398 RCX, RCX_H,
399 399 RBX, RBX_H,
400 400 R8, R8_H,
401 401 R9, R9_H,
402 402 R10, R10_H,
403 403 R11, R11_H,
404 404 R13, R13_H,
405 405 R14, R14_H);
406 406
407 407 // Class for all long registers except RCX (and RSP)
408 408 reg_class long_no_rcx_reg(RBP, RBP_H,
409 409 RDI, RDI_H,
410 410 RSI, RSI_H,
411 411 RAX, RAX_H,
412 412 RDX, RDX_H,
413 413 RBX, RBX_H,
414 414 R8, R8_H,
415 415 R9, R9_H,
416 416 R10, R10_H,
417 417 R11, R11_H,
418 418 R13, R13_H,
419 419 R14, R14_H);
420 420
421 421 // Class for all long registers except RAX (and RSP)
422 422 reg_class long_no_rax_reg(RBP, RBP_H,
423 423 RDX, RDX_H,
424 424 RDI, RDI_H,
425 425 RSI, RSI_H,
426 426 RCX, RCX_H,
427 427 RBX, RBX_H,
428 428 R8, R8_H,
429 429 R9, R9_H,
430 430 R10, R10_H,
431 431 R11, R11_H,
432 432 R13, R13_H,
433 433 R14, R14_H);
434 434
435 435 // Singleton class for RAX long register
436 436 reg_class long_rax_reg(RAX, RAX_H);
437 437
438 438 // Singleton class for RCX long register
439 439 reg_class long_rcx_reg(RCX, RCX_H);
440 440
441 441 // Singleton class for RDX long register
442 442 reg_class long_rdx_reg(RDX, RDX_H);
443 443
444 444 // Class for all int registers (except RSP)
445 445 reg_class int_reg(RAX,
446 446 RDX,
447 447 RBP,
448 448 RDI,
449 449 RSI,
450 450 RCX,
451 451 RBX,
452 452 R8,
453 453 R9,
454 454 R10,
455 455 R11,
456 456 R13,
457 457 R14);
458 458
459 459 // Class for all int registers except RCX (and RSP)
460 460 reg_class int_no_rcx_reg(RAX,
461 461 RDX,
462 462 RBP,
463 463 RDI,
464 464 RSI,
465 465 RBX,
466 466 R8,
467 467 R9,
468 468 R10,
469 469 R11,
470 470 R13,
471 471 R14);
472 472
473 473 // Class for all int registers except RAX, RDX (and RSP)
474 474 reg_class int_no_rax_rdx_reg(RBP,
475 475 RDI,
476 476 RSI,
477 477 RCX,
478 478 RBX,
479 479 R8,
480 480 R9,
481 481 R10,
482 482 R11,
483 483 R13,
484 484 R14);
485 485
486 486 // Singleton class for RAX int register
487 487 reg_class int_rax_reg(RAX);
488 488
489 489 // Singleton class for RBX int register
490 490 reg_class int_rbx_reg(RBX);
491 491
492 492 // Singleton class for RCX int register
493 493 reg_class int_rcx_reg(RCX);
494 494
495 495 // Singleton class for RCX int register
496 496 reg_class int_rdx_reg(RDX);
497 497
498 498 // Singleton class for RCX int register
499 499 reg_class int_rdi_reg(RDI);
500 500
501 501 // Singleton class for instruction pointer
502 502 // reg_class ip_reg(RIP);
503 503
504 504 // Singleton class for condition codes
505 505 reg_class int_flags(RFLAGS);
506 506
507 507 // Class for all float registers
508 508 reg_class float_reg(XMM0,
509 509 XMM1,
510 510 XMM2,
511 511 XMM3,
512 512 XMM4,
513 513 XMM5,
514 514 XMM6,
515 515 XMM7,
516 516 XMM8,
517 517 XMM9,
518 518 XMM10,
519 519 XMM11,
520 520 XMM12,
521 521 XMM13,
522 522 XMM14,
523 523 XMM15);
524 524
525 525 // Class for all double registers
526 526 reg_class double_reg(XMM0, XMM0_H,
527 527 XMM1, XMM1_H,
528 528 XMM2, XMM2_H,
529 529 XMM3, XMM3_H,
530 530 XMM4, XMM4_H,
531 531 XMM5, XMM5_H,
532 532 XMM6, XMM6_H,
533 533 XMM7, XMM7_H,
534 534 XMM8, XMM8_H,
535 535 XMM9, XMM9_H,
536 536 XMM10, XMM10_H,
537 537 XMM11, XMM11_H,
538 538 XMM12, XMM12_H,
539 539 XMM13, XMM13_H,
540 540 XMM14, XMM14_H,
541 541 XMM15, XMM15_H);
542 542 %}
543 543
544 544
545 545 //----------SOURCE BLOCK-------------------------------------------------------
546 546 // This is a block of C++ code which provides values, functions, and
547 547 // definitions necessary in the rest of the architecture description
548 548 source %{
549 549 #define RELOC_IMM64 Assembler::imm_operand
550 550 #define RELOC_DISP32 Assembler::disp32_operand
551 551
552 552 #define __ _masm.
553 553
554 554 static int preserve_SP_size() {
555 555 return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg)
556 556 }
557 557
558 558 // !!!!! Special hack to get all types of calls to specify the byte offset
559 559 // from the start of the call to the point where the return address
560 560 // will point.
561 561 int MachCallStaticJavaNode::ret_addr_offset()
562 562 {
563 563 int offset = 5; // 5 bytes from start of call to where return address points
564 564 if (_method_handle_invoke)
565 565 offset += preserve_SP_size();
566 566 return offset;
567 567 }
568 568
569 569 int MachCallDynamicJavaNode::ret_addr_offset()
570 570 {
571 571 return 15; // 15 bytes from start of call to where return address points
572 572 }
573 573
574 574 // In os_cpu .ad file
575 575 // int MachCallRuntimeNode::ret_addr_offset()
576 576
577 577 // Indicate if the safepoint node needs the polling page as an input.
578 578 // Since amd64 does not have absolute addressing but RIP-relative
579 579 // addressing and the polling page is within 2G, it doesn't.
580 580 bool SafePointNode::needs_polling_address_input()
581 581 {
582 582 return false;
583 583 }
584 584
585 585 //
586 586 // Compute padding required for nodes which need alignment
587 587 //
588 588
589 589 // The address of the call instruction needs to be 4-byte aligned to
590 590 // ensure that it does not span a cache line so that it can be patched.
591 591 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
592 592 {
593 593 current_offset += 1; // skip call opcode byte
594 594 return round_to(current_offset, alignment_required()) - current_offset;
595 595 }
596 596
597 597 // The address of the call instruction needs to be 4-byte aligned to
598 598 // ensure that it does not span a cache line so that it can be patched.
599 599 int CallStaticJavaHandleNode::compute_padding(int current_offset) const
600 600 {
601 601 current_offset += preserve_SP_size(); // skip mov rbp, rsp
602 602 current_offset += 1; // skip call opcode byte
603 603 return round_to(current_offset, alignment_required()) - current_offset;
604 604 }
605 605
606 606 // The address of the call instruction needs to be 4-byte aligned to
607 607 // ensure that it does not span a cache line so that it can be patched.
608 608 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
609 609 {
610 610 current_offset += 11; // skip movq instruction + call opcode byte
611 611 return round_to(current_offset, alignment_required()) - current_offset;
612 612 }
613 613
614 614 #ifndef PRODUCT
615 615 void MachBreakpointNode::format(PhaseRegAlloc*, outputStream* st) const
616 616 {
617 617 st->print("INT3");
618 618 }
619 619 #endif
620 620
621 621 // EMIT_RM()
622 622 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
623 623 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
624 624 cbuf.insts()->emit_int8(c);
625 625 }
626 626
627 627 // EMIT_CC()
628 628 void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
629 629 unsigned char c = (unsigned char) (f1 | f2);
630 630 cbuf.insts()->emit_int8(c);
631 631 }
632 632
633 633 // EMIT_OPCODE()
634 634 void emit_opcode(CodeBuffer &cbuf, int code) {
635 635 cbuf.insts()->emit_int8((unsigned char) code);
636 636 }
637 637
638 638 // EMIT_OPCODE() w/ relocation information
639 639 void emit_opcode(CodeBuffer &cbuf,
640 640 int code, relocInfo::relocType reloc, int offset, int format)
641 641 {
642 642 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format);
643 643 emit_opcode(cbuf, code);
644 644 }
645 645
646 646 // EMIT_D8()
647 647 void emit_d8(CodeBuffer &cbuf, int d8) {
648 648 cbuf.insts()->emit_int8((unsigned char) d8);
649 649 }
650 650
651 651 // EMIT_D16()
652 652 void emit_d16(CodeBuffer &cbuf, int d16) {
653 653 cbuf.insts()->emit_int16(d16);
654 654 }
655 655
656 656 // EMIT_D32()
657 657 void emit_d32(CodeBuffer &cbuf, int d32) {
658 658 cbuf.insts()->emit_int32(d32);
659 659 }
660 660
661 661 // EMIT_D64()
662 662 void emit_d64(CodeBuffer &cbuf, int64_t d64) {
663 663 cbuf.insts()->emit_int64(d64);
664 664 }
665 665
666 666 // emit 32 bit value and construct relocation entry from relocInfo::relocType
667 667 void emit_d32_reloc(CodeBuffer& cbuf,
668 668 int d32,
669 669 relocInfo::relocType reloc,
670 670 int format)
671 671 {
672 672 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
673 673 cbuf.relocate(cbuf.insts_mark(), reloc, format);
674 674 cbuf.insts()->emit_int32(d32);
675 675 }
676 676
677 677 // emit 32 bit value and construct relocation entry from RelocationHolder
678 678 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) {
679 679 #ifdef ASSERT
680 680 if (rspec.reloc()->type() == relocInfo::oop_type &&
681 681 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
682 682 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
683 683 }
684 684 #endif
685 685 cbuf.relocate(cbuf.insts_mark(), rspec, format);
686 686 cbuf.insts()->emit_int32(d32);
687 687 }
688 688
689 689 void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
690 690 address next_ip = cbuf.insts_end() + 4;
691 691 emit_d32_reloc(cbuf, (int) (addr - next_ip),
692 692 external_word_Relocation::spec(addr),
693 693 RELOC_DISP32);
694 694 }
695 695
696 696
697 697 // emit 64 bit value and construct relocation entry from relocInfo::relocType
698 698 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) {
699 699 cbuf.relocate(cbuf.insts_mark(), reloc, format);
700 700 cbuf.insts()->emit_int64(d64);
701 701 }
702 702
703 703 // emit 64 bit value and construct relocation entry from RelocationHolder
704 704 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) {
705 705 #ifdef ASSERT
706 706 if (rspec.reloc()->type() == relocInfo::oop_type &&
707 707 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
708 708 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()),
709 709 "cannot embed scavengable oops in code");
710 710 }
711 711 #endif
712 712 cbuf.relocate(cbuf.insts_mark(), rspec, format);
713 713 cbuf.insts()->emit_int64(d64);
714 714 }
715 715
716 716 // Access stack slot for load or store
717 717 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp)
718 718 {
719 719 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src])
720 720 if (-0x80 <= disp && disp < 0x80) {
721 721 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte
722 722 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
723 723 emit_d8(cbuf, disp); // Displacement // R/M byte
724 724 } else {
725 725 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte
726 726 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
727 727 emit_d32(cbuf, disp); // Displacement // R/M byte
728 728 }
729 729 }
730 730
731 731 // rRegI ereg, memory mem) %{ // emit_reg_mem
732 732 void encode_RegMem(CodeBuffer &cbuf,
733 733 int reg,
734 734 int base, int index, int scale, int disp, bool disp_is_oop)
735 735 {
736 736 assert(!disp_is_oop, "cannot have disp");
737 737 int regenc = reg & 7;
738 738 int baseenc = base & 7;
739 739 int indexenc = index & 7;
740 740
741 741 // There is no index & no scale, use form without SIB byte
742 742 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) {
743 743 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
744 744 if (disp == 0 && base != RBP_enc && base != R13_enc) {
745 745 emit_rm(cbuf, 0x0, regenc, baseenc); // *
746 746 } else if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) {
747 747 // If 8-bit displacement, mode 0x1
748 748 emit_rm(cbuf, 0x1, regenc, baseenc); // *
749 749 emit_d8(cbuf, disp);
750 750 } else {
751 751 // If 32-bit displacement
752 752 if (base == -1) { // Special flag for absolute address
753 753 emit_rm(cbuf, 0x0, regenc, 0x5); // *
754 754 if (disp_is_oop) {
755 755 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
756 756 } else {
757 757 emit_d32(cbuf, disp);
758 758 }
759 759 } else {
760 760 // Normal base + offset
761 761 emit_rm(cbuf, 0x2, regenc, baseenc); // *
762 762 if (disp_is_oop) {
763 763 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
764 764 } else {
765 765 emit_d32(cbuf, disp);
766 766 }
767 767 }
768 768 }
769 769 } else {
770 770 // Else, encode with the SIB byte
771 771 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
772 772 if (disp == 0 && base != RBP_enc && base != R13_enc) {
773 773 // If no displacement
774 774 emit_rm(cbuf, 0x0, regenc, 0x4); // *
775 775 emit_rm(cbuf, scale, indexenc, baseenc);
776 776 } else {
777 777 if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) {
778 778 // If 8-bit displacement, mode 0x1
779 779 emit_rm(cbuf, 0x1, regenc, 0x4); // *
780 780 emit_rm(cbuf, scale, indexenc, baseenc);
781 781 emit_d8(cbuf, disp);
782 782 } else {
783 783 // If 32-bit displacement
784 784 if (base == 0x04 ) {
785 785 emit_rm(cbuf, 0x2, regenc, 0x4);
786 786 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
787 787 } else {
788 788 emit_rm(cbuf, 0x2, regenc, 0x4);
789 789 emit_rm(cbuf, scale, indexenc, baseenc); // *
790 790 }
791 791 if (disp_is_oop) {
792 792 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
793 793 } else {
794 794 emit_d32(cbuf, disp);
795 795 }
796 796 }
797 797 }
798 798 }
799 799 }
800 800
801 801 void encode_copy(CodeBuffer &cbuf, int dstenc, int srcenc)
802 802 {
803 803 if (dstenc != srcenc) {
804 804 if (dstenc < 8) {
805 805 if (srcenc >= 8) {
806 806 emit_opcode(cbuf, Assembler::REX_B);
807 807 srcenc -= 8;
808 808 }
809 809 } else {
810 810 if (srcenc < 8) {
811 811 emit_opcode(cbuf, Assembler::REX_R);
812 812 } else {
813 813 emit_opcode(cbuf, Assembler::REX_RB);
814 814 srcenc -= 8;
815 815 }
816 816 dstenc -= 8;
817 817 }
818 818
819 819 emit_opcode(cbuf, 0x8B);
820 820 emit_rm(cbuf, 0x3, dstenc, srcenc);
821 821 }
822 822 }
823 823
824 824 void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
825 825 if( dst_encoding == src_encoding ) {
↓ open down ↓ |
825 lines elided |
↑ open up ↑ |
826 826 // reg-reg copy, use an empty encoding
827 827 } else {
828 828 MacroAssembler _masm(&cbuf);
829 829
830 830 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
831 831 }
832 832 }
833 833
834 834
835 835 //=============================================================================
836 +const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
837 +
838 +void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
839 + emit_constant_table(cbuf);
840 + set_table_base_offset(0);
841 + // Empty encoding
842 +}
843 +
844 +uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
845 + // Compute the size (even if it's zero) since
846 + // Compile::Shorten_branches needs the table to be emitted (which
847 + // happens in Compile::scratch_emit_size) to calculate the size for
848 + // MachConstantNodes.
849 + return MachNode::size(ra_);
850 +}
851 +
852 +#ifndef PRODUCT
853 +void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
854 + st->print("# MachConstantBase (empty encoding)");
855 +}
856 +#endif
857 +
858 +
859 +//=============================================================================
836 860 #ifndef PRODUCT
837 861 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const
838 862 {
839 863 Compile* C = ra_->C;
840 864
841 865 int framesize = C->frame_slots() << LogBytesPerInt;
842 866 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
843 867 // Remove wordSize for return adr already pushed
844 868 // and another for the RBP we are going to save
845 869 framesize -= 2*wordSize;
846 870 bool need_nop = true;
847 871
848 872 // Calls to C2R adapters often do not accept exceptional returns.
849 873 // We require that their callers must bang for them. But be
850 874 // careful, because some VM calls (such as call site linkage) can
851 875 // use several kilobytes of stack. But the stack safety zone should
852 876 // account for that. See bugs 4446381, 4468289, 4497237.
853 877 if (C->need_stack_bang(framesize)) {
854 878 st->print_cr("# stack bang"); st->print("\t");
855 879 need_nop = false;
856 880 }
857 881 st->print_cr("pushq rbp"); st->print("\t");
858 882
859 883 if (VerifyStackAtCalls) {
860 884 // Majik cookie to verify stack depth
861 885 st->print_cr("pushq 0xffffffffbadb100d"
862 886 "\t# Majik cookie for stack depth check");
863 887 st->print("\t");
864 888 framesize -= wordSize; // Remove 2 for cookie
865 889 need_nop = false;
866 890 }
867 891
868 892 if (framesize) {
869 893 st->print("subq rsp, #%d\t# Create frame", framesize);
870 894 if (framesize < 0x80 && need_nop) {
871 895 st->print("\n\tnop\t# nop for patch_verified_entry");
872 896 }
873 897 }
874 898 }
875 899 #endif
876 900
877 901 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const
878 902 {
879 903 Compile* C = ra_->C;
880 904
881 905 // WARNING: Initial instruction MUST be 5 bytes or longer so that
882 906 // NativeJump::patch_verified_entry will be able to patch out the entry
883 907 // code safely. The fldcw is ok at 6 bytes, the push to verify stack
884 908 // depth is ok at 5 bytes, the frame allocation can be either 3 or
885 909 // 6 bytes. So if we don't do the fldcw or the push then we must
886 910 // use the 6 byte frame allocation even if we have no frame. :-(
887 911 // If method sets FPU control word do it now
888 912
889 913 int framesize = C->frame_slots() << LogBytesPerInt;
890 914 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
891 915 // Remove wordSize for return adr already pushed
892 916 // and another for the RBP we are going to save
893 917 framesize -= 2*wordSize;
894 918 bool need_nop = true;
895 919
896 920 // Calls to C2R adapters often do not accept exceptional returns.
897 921 // We require that their callers must bang for them. But be
898 922 // careful, because some VM calls (such as call site linkage) can
899 923 // use several kilobytes of stack. But the stack safety zone should
900 924 // account for that. See bugs 4446381, 4468289, 4497237.
901 925 if (C->need_stack_bang(framesize)) {
902 926 MacroAssembler masm(&cbuf);
903 927 masm.generate_stack_overflow_check(framesize);
904 928 need_nop = false;
905 929 }
906 930
907 931 // We always push rbp so that on return to interpreter rbp will be
908 932 // restored correctly and we can correct the stack.
909 933 emit_opcode(cbuf, 0x50 | RBP_enc);
910 934
911 935 if (VerifyStackAtCalls) {
912 936 // Majik cookie to verify stack depth
913 937 emit_opcode(cbuf, 0x68); // pushq (sign-extended) 0xbadb100d
914 938 emit_d32(cbuf, 0xbadb100d);
915 939 framesize -= wordSize; // Remove 2 for cookie
916 940 need_nop = false;
917 941 }
918 942
919 943 if (framesize) {
920 944 emit_opcode(cbuf, Assembler::REX_W);
921 945 if (framesize < 0x80) {
922 946 emit_opcode(cbuf, 0x83); // sub SP,#framesize
923 947 emit_rm(cbuf, 0x3, 0x05, RSP_enc);
924 948 emit_d8(cbuf, framesize);
925 949 if (need_nop) {
926 950 emit_opcode(cbuf, 0x90); // nop
927 951 }
928 952 } else {
929 953 emit_opcode(cbuf, 0x81); // sub SP,#framesize
930 954 emit_rm(cbuf, 0x3, 0x05, RSP_enc);
931 955 emit_d32(cbuf, framesize);
932 956 }
933 957 }
934 958
935 959 C->set_frame_complete(cbuf.insts_size());
936 960
937 961 #ifdef ASSERT
938 962 if (VerifyStackAtCalls) {
939 963 Label L;
940 964 MacroAssembler masm(&cbuf);
941 965 masm.push(rax);
942 966 masm.mov(rax, rsp);
943 967 masm.andptr(rax, StackAlignmentInBytes-1);
944 968 masm.cmpptr(rax, StackAlignmentInBytes-wordSize);
945 969 masm.pop(rax);
946 970 masm.jcc(Assembler::equal, L);
947 971 masm.stop("Stack is not properly aligned!");
948 972 masm.bind(L);
949 973 }
950 974 #endif
951 975 }
952 976
953 977 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
954 978 {
955 979 return MachNode::size(ra_); // too many variables; just compute it
956 980 // the hard way
957 981 }
958 982
959 983 int MachPrologNode::reloc() const
960 984 {
961 985 return 0; // a large enough number
962 986 }
963 987
964 988 //=============================================================================
965 989 #ifndef PRODUCT
966 990 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
967 991 {
968 992 Compile* C = ra_->C;
969 993 int framesize = C->frame_slots() << LogBytesPerInt;
970 994 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
971 995 // Remove word for return adr already pushed
972 996 // and RBP
973 997 framesize -= 2*wordSize;
974 998
975 999 if (framesize) {
976 1000 st->print_cr("addq\trsp, %d\t# Destroy frame", framesize);
977 1001 st->print("\t");
978 1002 }
979 1003
980 1004 st->print_cr("popq\trbp");
981 1005 if (do_polling() && C->is_method_compilation()) {
982 1006 st->print_cr("\ttestl\trax, [rip + #offset_to_poll_page]\t"
983 1007 "# Safepoint: poll for GC");
984 1008 st->print("\t");
985 1009 }
986 1010 }
987 1011 #endif
988 1012
989 1013 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
990 1014 {
991 1015 Compile* C = ra_->C;
992 1016 int framesize = C->frame_slots() << LogBytesPerInt;
993 1017 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
994 1018 // Remove word for return adr already pushed
995 1019 // and RBP
996 1020 framesize -= 2*wordSize;
997 1021
998 1022 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here
999 1023
1000 1024 if (framesize) {
1001 1025 emit_opcode(cbuf, Assembler::REX_W);
1002 1026 if (framesize < 0x80) {
1003 1027 emit_opcode(cbuf, 0x83); // addq rsp, #framesize
1004 1028 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
1005 1029 emit_d8(cbuf, framesize);
1006 1030 } else {
1007 1031 emit_opcode(cbuf, 0x81); // addq rsp, #framesize
1008 1032 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
1009 1033 emit_d32(cbuf, framesize);
1010 1034 }
1011 1035 }
1012 1036
1013 1037 // popq rbp
1014 1038 emit_opcode(cbuf, 0x58 | RBP_enc);
1015 1039
1016 1040 if (do_polling() && C->is_method_compilation()) {
1017 1041 // testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
1018 1042 // XXX reg_mem doesn't support RIP-relative addressing yet
1019 1043 cbuf.set_insts_mark();
1020 1044 cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_return_type, 0); // XXX
1021 1045 emit_opcode(cbuf, 0x85); // testl
1022 1046 emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
1023 1047 // cbuf.insts_mark() is beginning of instruction
1024 1048 emit_d32_reloc(cbuf, os::get_polling_page());
1025 1049 // relocInfo::poll_return_type,
1026 1050 }
1027 1051 }
1028 1052
1029 1053 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
1030 1054 {
1031 1055 Compile* C = ra_->C;
1032 1056 int framesize = C->frame_slots() << LogBytesPerInt;
1033 1057 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1034 1058 // Remove word for return adr already pushed
1035 1059 // and RBP
1036 1060 framesize -= 2*wordSize;
1037 1061
1038 1062 uint size = 0;
1039 1063
1040 1064 if (do_polling() && C->is_method_compilation()) {
1041 1065 size += 6;
1042 1066 }
1043 1067
1044 1068 // count popq rbp
1045 1069 size++;
1046 1070
1047 1071 if (framesize) {
1048 1072 if (framesize < 0x80) {
1049 1073 size += 4;
1050 1074 } else if (framesize) {
1051 1075 size += 7;
1052 1076 }
1053 1077 }
1054 1078
1055 1079 return size;
1056 1080 }
1057 1081
1058 1082 int MachEpilogNode::reloc() const
1059 1083 {
1060 1084 return 2; // a large enough number
1061 1085 }
1062 1086
1063 1087 const Pipeline* MachEpilogNode::pipeline() const
1064 1088 {
1065 1089 return MachNode::pipeline_class();
1066 1090 }
1067 1091
1068 1092 int MachEpilogNode::safepoint_offset() const
1069 1093 {
1070 1094 return 0;
1071 1095 }
1072 1096
1073 1097 //=============================================================================
1074 1098
1075 1099 enum RC {
1076 1100 rc_bad,
1077 1101 rc_int,
1078 1102 rc_float,
1079 1103 rc_stack
1080 1104 };
1081 1105
1082 1106 static enum RC rc_class(OptoReg::Name reg)
1083 1107 {
1084 1108 if( !OptoReg::is_valid(reg) ) return rc_bad;
1085 1109
1086 1110 if (OptoReg::is_stack(reg)) return rc_stack;
1087 1111
1088 1112 VMReg r = OptoReg::as_VMReg(reg);
1089 1113
1090 1114 if (r->is_Register()) return rc_int;
1091 1115
1092 1116 assert(r->is_XMMRegister(), "must be");
1093 1117 return rc_float;
1094 1118 }
1095 1119
1096 1120 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
1097 1121 PhaseRegAlloc* ra_,
1098 1122 bool do_size,
1099 1123 outputStream* st) const
1100 1124 {
1101 1125
1102 1126 // Get registers to move
1103 1127 OptoReg::Name src_second = ra_->get_reg_second(in(1));
1104 1128 OptoReg::Name src_first = ra_->get_reg_first(in(1));
1105 1129 OptoReg::Name dst_second = ra_->get_reg_second(this);
1106 1130 OptoReg::Name dst_first = ra_->get_reg_first(this);
1107 1131
1108 1132 enum RC src_second_rc = rc_class(src_second);
1109 1133 enum RC src_first_rc = rc_class(src_first);
1110 1134 enum RC dst_second_rc = rc_class(dst_second);
1111 1135 enum RC dst_first_rc = rc_class(dst_first);
1112 1136
1113 1137 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
1114 1138 "must move at least 1 register" );
1115 1139
1116 1140 if (src_first == dst_first && src_second == dst_second) {
1117 1141 // Self copy, no move
1118 1142 return 0;
1119 1143 } else if (src_first_rc == rc_stack) {
1120 1144 // mem ->
1121 1145 if (dst_first_rc == rc_stack) {
1122 1146 // mem -> mem
1123 1147 assert(src_second != dst_first, "overlap");
1124 1148 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1125 1149 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1126 1150 // 64-bit
1127 1151 int src_offset = ra_->reg2offset(src_first);
1128 1152 int dst_offset = ra_->reg2offset(dst_first);
1129 1153 if (cbuf) {
1130 1154 emit_opcode(*cbuf, 0xFF);
1131 1155 encode_RegMem(*cbuf, RSI_enc, RSP_enc, 0x4, 0, src_offset, false);
1132 1156
1133 1157 emit_opcode(*cbuf, 0x8F);
1134 1158 encode_RegMem(*cbuf, RAX_enc, RSP_enc, 0x4, 0, dst_offset, false);
1135 1159
1136 1160 #ifndef PRODUCT
1137 1161 } else if (!do_size) {
1138 1162 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1139 1163 "popq [rsp + #%d]",
1140 1164 src_offset,
1141 1165 dst_offset);
1142 1166 #endif
1143 1167 }
1144 1168 return
1145 1169 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) +
1146 1170 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4));
1147 1171 } else {
1148 1172 // 32-bit
1149 1173 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1150 1174 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1151 1175 // No pushl/popl, so:
1152 1176 int src_offset = ra_->reg2offset(src_first);
1153 1177 int dst_offset = ra_->reg2offset(dst_first);
1154 1178 if (cbuf) {
1155 1179 emit_opcode(*cbuf, Assembler::REX_W);
1156 1180 emit_opcode(*cbuf, 0x89);
1157 1181 emit_opcode(*cbuf, 0x44);
1158 1182 emit_opcode(*cbuf, 0x24);
1159 1183 emit_opcode(*cbuf, 0xF8);
1160 1184
1161 1185 emit_opcode(*cbuf, 0x8B);
1162 1186 encode_RegMem(*cbuf,
1163 1187 RAX_enc,
1164 1188 RSP_enc, 0x4, 0, src_offset,
1165 1189 false);
1166 1190
1167 1191 emit_opcode(*cbuf, 0x89);
1168 1192 encode_RegMem(*cbuf,
1169 1193 RAX_enc,
1170 1194 RSP_enc, 0x4, 0, dst_offset,
1171 1195 false);
1172 1196
1173 1197 emit_opcode(*cbuf, Assembler::REX_W);
1174 1198 emit_opcode(*cbuf, 0x8B);
1175 1199 emit_opcode(*cbuf, 0x44);
1176 1200 emit_opcode(*cbuf, 0x24);
1177 1201 emit_opcode(*cbuf, 0xF8);
1178 1202
1179 1203 #ifndef PRODUCT
1180 1204 } else if (!do_size) {
1181 1205 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1182 1206 "movl rax, [rsp + #%d]\n\t"
1183 1207 "movl [rsp + #%d], rax\n\t"
1184 1208 "movq rax, [rsp - #8]",
1185 1209 src_offset,
1186 1210 dst_offset);
1187 1211 #endif
1188 1212 }
1189 1213 return
1190 1214 5 + // movq
1191 1215 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + // movl
1192 1216 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)) + // movl
1193 1217 5; // movq
1194 1218 }
1195 1219 } else if (dst_first_rc == rc_int) {
1196 1220 // mem -> gpr
1197 1221 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1198 1222 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1199 1223 // 64-bit
1200 1224 int offset = ra_->reg2offset(src_first);
1201 1225 if (cbuf) {
1202 1226 if (Matcher::_regEncode[dst_first] < 8) {
1203 1227 emit_opcode(*cbuf, Assembler::REX_W);
1204 1228 } else {
1205 1229 emit_opcode(*cbuf, Assembler::REX_WR);
1206 1230 }
1207 1231 emit_opcode(*cbuf, 0x8B);
1208 1232 encode_RegMem(*cbuf,
1209 1233 Matcher::_regEncode[dst_first],
1210 1234 RSP_enc, 0x4, 0, offset,
1211 1235 false);
1212 1236 #ifndef PRODUCT
1213 1237 } else if (!do_size) {
1214 1238 st->print("movq %s, [rsp + #%d]\t# spill",
1215 1239 Matcher::regName[dst_first],
1216 1240 offset);
1217 1241 #endif
1218 1242 }
1219 1243 return
1220 1244 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX
1221 1245 } else {
1222 1246 // 32-bit
1223 1247 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1224 1248 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1225 1249 int offset = ra_->reg2offset(src_first);
1226 1250 if (cbuf) {
1227 1251 if (Matcher::_regEncode[dst_first] >= 8) {
1228 1252 emit_opcode(*cbuf, Assembler::REX_R);
1229 1253 }
1230 1254 emit_opcode(*cbuf, 0x8B);
1231 1255 encode_RegMem(*cbuf,
1232 1256 Matcher::_regEncode[dst_first],
1233 1257 RSP_enc, 0x4, 0, offset,
1234 1258 false);
1235 1259 #ifndef PRODUCT
1236 1260 } else if (!do_size) {
1237 1261 st->print("movl %s, [rsp + #%d]\t# spill",
1238 1262 Matcher::regName[dst_first],
1239 1263 offset);
1240 1264 #endif
1241 1265 }
1242 1266 return
1243 1267 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1244 1268 ((Matcher::_regEncode[dst_first] < 8)
1245 1269 ? 3
1246 1270 : 4); // REX
1247 1271 }
1248 1272 } else if (dst_first_rc == rc_float) {
1249 1273 // mem-> xmm
1250 1274 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1251 1275 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1252 1276 // 64-bit
1253 1277 int offset = ra_->reg2offset(src_first);
1254 1278 if (cbuf) {
1255 1279 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
1256 1280 if (Matcher::_regEncode[dst_first] >= 8) {
1257 1281 emit_opcode(*cbuf, Assembler::REX_R);
1258 1282 }
1259 1283 emit_opcode(*cbuf, 0x0F);
1260 1284 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
1261 1285 encode_RegMem(*cbuf,
1262 1286 Matcher::_regEncode[dst_first],
1263 1287 RSP_enc, 0x4, 0, offset,
1264 1288 false);
1265 1289 #ifndef PRODUCT
1266 1290 } else if (!do_size) {
1267 1291 st->print("%s %s, [rsp + #%d]\t# spill",
1268 1292 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1269 1293 Matcher::regName[dst_first],
1270 1294 offset);
1271 1295 #endif
1272 1296 }
1273 1297 return
1274 1298 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1275 1299 ((Matcher::_regEncode[dst_first] < 8)
1276 1300 ? 5
1277 1301 : 6); // REX
1278 1302 } else {
1279 1303 // 32-bit
1280 1304 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1281 1305 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1282 1306 int offset = ra_->reg2offset(src_first);
1283 1307 if (cbuf) {
1284 1308 emit_opcode(*cbuf, 0xF3);
1285 1309 if (Matcher::_regEncode[dst_first] >= 8) {
1286 1310 emit_opcode(*cbuf, Assembler::REX_R);
1287 1311 }
1288 1312 emit_opcode(*cbuf, 0x0F);
1289 1313 emit_opcode(*cbuf, 0x10);
1290 1314 encode_RegMem(*cbuf,
1291 1315 Matcher::_regEncode[dst_first],
1292 1316 RSP_enc, 0x4, 0, offset,
1293 1317 false);
1294 1318 #ifndef PRODUCT
1295 1319 } else if (!do_size) {
1296 1320 st->print("movss %s, [rsp + #%d]\t# spill",
1297 1321 Matcher::regName[dst_first],
1298 1322 offset);
1299 1323 #endif
1300 1324 }
1301 1325 return
1302 1326 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1303 1327 ((Matcher::_regEncode[dst_first] < 8)
1304 1328 ? 5
1305 1329 : 6); // REX
1306 1330 }
1307 1331 }
1308 1332 } else if (src_first_rc == rc_int) {
1309 1333 // gpr ->
1310 1334 if (dst_first_rc == rc_stack) {
1311 1335 // gpr -> mem
1312 1336 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1313 1337 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1314 1338 // 64-bit
1315 1339 int offset = ra_->reg2offset(dst_first);
1316 1340 if (cbuf) {
1317 1341 if (Matcher::_regEncode[src_first] < 8) {
1318 1342 emit_opcode(*cbuf, Assembler::REX_W);
1319 1343 } else {
1320 1344 emit_opcode(*cbuf, Assembler::REX_WR);
1321 1345 }
1322 1346 emit_opcode(*cbuf, 0x89);
1323 1347 encode_RegMem(*cbuf,
1324 1348 Matcher::_regEncode[src_first],
1325 1349 RSP_enc, 0x4, 0, offset,
1326 1350 false);
1327 1351 #ifndef PRODUCT
1328 1352 } else if (!do_size) {
1329 1353 st->print("movq [rsp + #%d], %s\t# spill",
1330 1354 offset,
1331 1355 Matcher::regName[src_first]);
1332 1356 #endif
1333 1357 }
1334 1358 return ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX
1335 1359 } else {
1336 1360 // 32-bit
1337 1361 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1338 1362 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1339 1363 int offset = ra_->reg2offset(dst_first);
1340 1364 if (cbuf) {
1341 1365 if (Matcher::_regEncode[src_first] >= 8) {
1342 1366 emit_opcode(*cbuf, Assembler::REX_R);
1343 1367 }
1344 1368 emit_opcode(*cbuf, 0x89);
1345 1369 encode_RegMem(*cbuf,
1346 1370 Matcher::_regEncode[src_first],
1347 1371 RSP_enc, 0x4, 0, offset,
1348 1372 false);
1349 1373 #ifndef PRODUCT
1350 1374 } else if (!do_size) {
1351 1375 st->print("movl [rsp + #%d], %s\t# spill",
1352 1376 offset,
1353 1377 Matcher::regName[src_first]);
1354 1378 #endif
1355 1379 }
1356 1380 return
1357 1381 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1358 1382 ((Matcher::_regEncode[src_first] < 8)
1359 1383 ? 3
1360 1384 : 4); // REX
1361 1385 }
1362 1386 } else if (dst_first_rc == rc_int) {
1363 1387 // gpr -> gpr
1364 1388 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1365 1389 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1366 1390 // 64-bit
1367 1391 if (cbuf) {
1368 1392 if (Matcher::_regEncode[dst_first] < 8) {
1369 1393 if (Matcher::_regEncode[src_first] < 8) {
1370 1394 emit_opcode(*cbuf, Assembler::REX_W);
1371 1395 } else {
1372 1396 emit_opcode(*cbuf, Assembler::REX_WB);
1373 1397 }
1374 1398 } else {
1375 1399 if (Matcher::_regEncode[src_first] < 8) {
1376 1400 emit_opcode(*cbuf, Assembler::REX_WR);
1377 1401 } else {
1378 1402 emit_opcode(*cbuf, Assembler::REX_WRB);
1379 1403 }
1380 1404 }
1381 1405 emit_opcode(*cbuf, 0x8B);
1382 1406 emit_rm(*cbuf, 0x3,
1383 1407 Matcher::_regEncode[dst_first] & 7,
1384 1408 Matcher::_regEncode[src_first] & 7);
1385 1409 #ifndef PRODUCT
1386 1410 } else if (!do_size) {
1387 1411 st->print("movq %s, %s\t# spill",
1388 1412 Matcher::regName[dst_first],
1389 1413 Matcher::regName[src_first]);
1390 1414 #endif
1391 1415 }
1392 1416 return 3; // REX
1393 1417 } else {
1394 1418 // 32-bit
1395 1419 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1396 1420 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1397 1421 if (cbuf) {
1398 1422 if (Matcher::_regEncode[dst_first] < 8) {
1399 1423 if (Matcher::_regEncode[src_first] >= 8) {
1400 1424 emit_opcode(*cbuf, Assembler::REX_B);
1401 1425 }
1402 1426 } else {
1403 1427 if (Matcher::_regEncode[src_first] < 8) {
1404 1428 emit_opcode(*cbuf, Assembler::REX_R);
1405 1429 } else {
1406 1430 emit_opcode(*cbuf, Assembler::REX_RB);
1407 1431 }
1408 1432 }
1409 1433 emit_opcode(*cbuf, 0x8B);
1410 1434 emit_rm(*cbuf, 0x3,
1411 1435 Matcher::_regEncode[dst_first] & 7,
1412 1436 Matcher::_regEncode[src_first] & 7);
1413 1437 #ifndef PRODUCT
1414 1438 } else if (!do_size) {
1415 1439 st->print("movl %s, %s\t# spill",
1416 1440 Matcher::regName[dst_first],
1417 1441 Matcher::regName[src_first]);
1418 1442 #endif
1419 1443 }
1420 1444 return
1421 1445 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1422 1446 ? 2
1423 1447 : 3; // REX
1424 1448 }
1425 1449 } else if (dst_first_rc == rc_float) {
1426 1450 // gpr -> xmm
1427 1451 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1428 1452 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1429 1453 // 64-bit
1430 1454 if (cbuf) {
1431 1455 emit_opcode(*cbuf, 0x66);
1432 1456 if (Matcher::_regEncode[dst_first] < 8) {
1433 1457 if (Matcher::_regEncode[src_first] < 8) {
1434 1458 emit_opcode(*cbuf, Assembler::REX_W);
1435 1459 } else {
1436 1460 emit_opcode(*cbuf, Assembler::REX_WB);
1437 1461 }
1438 1462 } else {
1439 1463 if (Matcher::_regEncode[src_first] < 8) {
1440 1464 emit_opcode(*cbuf, Assembler::REX_WR);
1441 1465 } else {
1442 1466 emit_opcode(*cbuf, Assembler::REX_WRB);
1443 1467 }
1444 1468 }
1445 1469 emit_opcode(*cbuf, 0x0F);
1446 1470 emit_opcode(*cbuf, 0x6E);
1447 1471 emit_rm(*cbuf, 0x3,
1448 1472 Matcher::_regEncode[dst_first] & 7,
1449 1473 Matcher::_regEncode[src_first] & 7);
1450 1474 #ifndef PRODUCT
1451 1475 } else if (!do_size) {
1452 1476 st->print("movdq %s, %s\t# spill",
1453 1477 Matcher::regName[dst_first],
1454 1478 Matcher::regName[src_first]);
1455 1479 #endif
1456 1480 }
1457 1481 return 5; // REX
1458 1482 } else {
1459 1483 // 32-bit
1460 1484 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1461 1485 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1462 1486 if (cbuf) {
1463 1487 emit_opcode(*cbuf, 0x66);
1464 1488 if (Matcher::_regEncode[dst_first] < 8) {
1465 1489 if (Matcher::_regEncode[src_first] >= 8) {
1466 1490 emit_opcode(*cbuf, Assembler::REX_B);
1467 1491 }
1468 1492 } else {
1469 1493 if (Matcher::_regEncode[src_first] < 8) {
1470 1494 emit_opcode(*cbuf, Assembler::REX_R);
1471 1495 } else {
1472 1496 emit_opcode(*cbuf, Assembler::REX_RB);
1473 1497 }
1474 1498 }
1475 1499 emit_opcode(*cbuf, 0x0F);
1476 1500 emit_opcode(*cbuf, 0x6E);
1477 1501 emit_rm(*cbuf, 0x3,
1478 1502 Matcher::_regEncode[dst_first] & 7,
1479 1503 Matcher::_regEncode[src_first] & 7);
1480 1504 #ifndef PRODUCT
1481 1505 } else if (!do_size) {
1482 1506 st->print("movdl %s, %s\t# spill",
1483 1507 Matcher::regName[dst_first],
1484 1508 Matcher::regName[src_first]);
1485 1509 #endif
1486 1510 }
1487 1511 return
1488 1512 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1489 1513 ? 4
1490 1514 : 5; // REX
1491 1515 }
1492 1516 }
1493 1517 } else if (src_first_rc == rc_float) {
1494 1518 // xmm ->
1495 1519 if (dst_first_rc == rc_stack) {
1496 1520 // xmm -> mem
1497 1521 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1498 1522 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1499 1523 // 64-bit
1500 1524 int offset = ra_->reg2offset(dst_first);
1501 1525 if (cbuf) {
1502 1526 emit_opcode(*cbuf, 0xF2);
1503 1527 if (Matcher::_regEncode[src_first] >= 8) {
1504 1528 emit_opcode(*cbuf, Assembler::REX_R);
1505 1529 }
1506 1530 emit_opcode(*cbuf, 0x0F);
1507 1531 emit_opcode(*cbuf, 0x11);
1508 1532 encode_RegMem(*cbuf,
1509 1533 Matcher::_regEncode[src_first],
1510 1534 RSP_enc, 0x4, 0, offset,
1511 1535 false);
1512 1536 #ifndef PRODUCT
1513 1537 } else if (!do_size) {
1514 1538 st->print("movsd [rsp + #%d], %s\t# spill",
1515 1539 offset,
1516 1540 Matcher::regName[src_first]);
1517 1541 #endif
1518 1542 }
1519 1543 return
1520 1544 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1521 1545 ((Matcher::_regEncode[src_first] < 8)
1522 1546 ? 5
1523 1547 : 6); // REX
1524 1548 } else {
1525 1549 // 32-bit
1526 1550 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1527 1551 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1528 1552 int offset = ra_->reg2offset(dst_first);
1529 1553 if (cbuf) {
1530 1554 emit_opcode(*cbuf, 0xF3);
1531 1555 if (Matcher::_regEncode[src_first] >= 8) {
1532 1556 emit_opcode(*cbuf, Assembler::REX_R);
1533 1557 }
1534 1558 emit_opcode(*cbuf, 0x0F);
1535 1559 emit_opcode(*cbuf, 0x11);
1536 1560 encode_RegMem(*cbuf,
1537 1561 Matcher::_regEncode[src_first],
1538 1562 RSP_enc, 0x4, 0, offset,
1539 1563 false);
1540 1564 #ifndef PRODUCT
1541 1565 } else if (!do_size) {
1542 1566 st->print("movss [rsp + #%d], %s\t# spill",
1543 1567 offset,
1544 1568 Matcher::regName[src_first]);
1545 1569 #endif
1546 1570 }
1547 1571 return
1548 1572 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1549 1573 ((Matcher::_regEncode[src_first] < 8)
1550 1574 ? 5
1551 1575 : 6); // REX
1552 1576 }
1553 1577 } else if (dst_first_rc == rc_int) {
1554 1578 // xmm -> gpr
1555 1579 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1556 1580 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1557 1581 // 64-bit
1558 1582 if (cbuf) {
1559 1583 emit_opcode(*cbuf, 0x66);
1560 1584 if (Matcher::_regEncode[dst_first] < 8) {
1561 1585 if (Matcher::_regEncode[src_first] < 8) {
1562 1586 emit_opcode(*cbuf, Assembler::REX_W);
1563 1587 } else {
1564 1588 emit_opcode(*cbuf, Assembler::REX_WR); // attention!
1565 1589 }
1566 1590 } else {
1567 1591 if (Matcher::_regEncode[src_first] < 8) {
1568 1592 emit_opcode(*cbuf, Assembler::REX_WB); // attention!
1569 1593 } else {
1570 1594 emit_opcode(*cbuf, Assembler::REX_WRB);
1571 1595 }
1572 1596 }
1573 1597 emit_opcode(*cbuf, 0x0F);
1574 1598 emit_opcode(*cbuf, 0x7E);
1575 1599 emit_rm(*cbuf, 0x3,
1576 1600 Matcher::_regEncode[src_first] & 7,
1577 1601 Matcher::_regEncode[dst_first] & 7);
1578 1602 #ifndef PRODUCT
1579 1603 } else if (!do_size) {
1580 1604 st->print("movdq %s, %s\t# spill",
1581 1605 Matcher::regName[dst_first],
1582 1606 Matcher::regName[src_first]);
1583 1607 #endif
1584 1608 }
1585 1609 return 5; // REX
1586 1610 } else {
1587 1611 // 32-bit
1588 1612 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1589 1613 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1590 1614 if (cbuf) {
1591 1615 emit_opcode(*cbuf, 0x66);
1592 1616 if (Matcher::_regEncode[dst_first] < 8) {
1593 1617 if (Matcher::_regEncode[src_first] >= 8) {
1594 1618 emit_opcode(*cbuf, Assembler::REX_R); // attention!
1595 1619 }
1596 1620 } else {
1597 1621 if (Matcher::_regEncode[src_first] < 8) {
1598 1622 emit_opcode(*cbuf, Assembler::REX_B); // attention!
1599 1623 } else {
1600 1624 emit_opcode(*cbuf, Assembler::REX_RB);
1601 1625 }
1602 1626 }
1603 1627 emit_opcode(*cbuf, 0x0F);
1604 1628 emit_opcode(*cbuf, 0x7E);
1605 1629 emit_rm(*cbuf, 0x3,
1606 1630 Matcher::_regEncode[src_first] & 7,
1607 1631 Matcher::_regEncode[dst_first] & 7);
1608 1632 #ifndef PRODUCT
1609 1633 } else if (!do_size) {
1610 1634 st->print("movdl %s, %s\t# spill",
1611 1635 Matcher::regName[dst_first],
1612 1636 Matcher::regName[src_first]);
1613 1637 #endif
1614 1638 }
1615 1639 return
1616 1640 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1617 1641 ? 4
1618 1642 : 5; // REX
1619 1643 }
1620 1644 } else if (dst_first_rc == rc_float) {
1621 1645 // xmm -> xmm
1622 1646 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1623 1647 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1624 1648 // 64-bit
1625 1649 if (cbuf) {
1626 1650 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2);
1627 1651 if (Matcher::_regEncode[dst_first] < 8) {
1628 1652 if (Matcher::_regEncode[src_first] >= 8) {
1629 1653 emit_opcode(*cbuf, Assembler::REX_B);
1630 1654 }
1631 1655 } else {
1632 1656 if (Matcher::_regEncode[src_first] < 8) {
1633 1657 emit_opcode(*cbuf, Assembler::REX_R);
1634 1658 } else {
1635 1659 emit_opcode(*cbuf, Assembler::REX_RB);
1636 1660 }
1637 1661 }
1638 1662 emit_opcode(*cbuf, 0x0F);
1639 1663 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
1640 1664 emit_rm(*cbuf, 0x3,
1641 1665 Matcher::_regEncode[dst_first] & 7,
1642 1666 Matcher::_regEncode[src_first] & 7);
1643 1667 #ifndef PRODUCT
1644 1668 } else if (!do_size) {
1645 1669 st->print("%s %s, %s\t# spill",
1646 1670 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
1647 1671 Matcher::regName[dst_first],
1648 1672 Matcher::regName[src_first]);
1649 1673 #endif
1650 1674 }
1651 1675 return
1652 1676 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1653 1677 ? 4
1654 1678 : 5; // REX
1655 1679 } else {
1656 1680 // 32-bit
1657 1681 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1658 1682 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1659 1683 if (cbuf) {
1660 1684 if (!UseXmmRegToRegMoveAll)
1661 1685 emit_opcode(*cbuf, 0xF3);
1662 1686 if (Matcher::_regEncode[dst_first] < 8) {
1663 1687 if (Matcher::_regEncode[src_first] >= 8) {
1664 1688 emit_opcode(*cbuf, Assembler::REX_B);
1665 1689 }
1666 1690 } else {
1667 1691 if (Matcher::_regEncode[src_first] < 8) {
1668 1692 emit_opcode(*cbuf, Assembler::REX_R);
1669 1693 } else {
1670 1694 emit_opcode(*cbuf, Assembler::REX_RB);
1671 1695 }
1672 1696 }
1673 1697 emit_opcode(*cbuf, 0x0F);
1674 1698 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
1675 1699 emit_rm(*cbuf, 0x3,
1676 1700 Matcher::_regEncode[dst_first] & 7,
1677 1701 Matcher::_regEncode[src_first] & 7);
1678 1702 #ifndef PRODUCT
1679 1703 } else if (!do_size) {
1680 1704 st->print("%s %s, %s\t# spill",
1681 1705 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1682 1706 Matcher::regName[dst_first],
1683 1707 Matcher::regName[src_first]);
1684 1708 #endif
1685 1709 }
1686 1710 return
1687 1711 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1688 1712 ? (UseXmmRegToRegMoveAll ? 3 : 4)
1689 1713 : (UseXmmRegToRegMoveAll ? 4 : 5); // REX
1690 1714 }
1691 1715 }
1692 1716 }
1693 1717
1694 1718 assert(0," foo ");
1695 1719 Unimplemented();
1696 1720
1697 1721 return 0;
1698 1722 }
1699 1723
1700 1724 #ifndef PRODUCT
1701 1725 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const
1702 1726 {
1703 1727 implementation(NULL, ra_, false, st);
1704 1728 }
1705 1729 #endif
1706 1730
1707 1731 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const
1708 1732 {
1709 1733 implementation(&cbuf, ra_, false, NULL);
1710 1734 }
1711 1735
1712 1736 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const
1713 1737 {
1714 1738 return implementation(NULL, ra_, true, NULL);
1715 1739 }
1716 1740
1717 1741 //=============================================================================
1718 1742 #ifndef PRODUCT
1719 1743 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const
1720 1744 {
1721 1745 st->print("nop \t# %d bytes pad for loops and calls", _count);
1722 1746 }
1723 1747 #endif
1724 1748
1725 1749 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const
1726 1750 {
1727 1751 MacroAssembler _masm(&cbuf);
1728 1752 __ nop(_count);
1729 1753 }
1730 1754
1731 1755 uint MachNopNode::size(PhaseRegAlloc*) const
1732 1756 {
1733 1757 return _count;
1734 1758 }
1735 1759
1736 1760
1737 1761 //=============================================================================
1738 1762 #ifndef PRODUCT
1739 1763 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1740 1764 {
1741 1765 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1742 1766 int reg = ra_->get_reg_first(this);
1743 1767 st->print("leaq %s, [rsp + #%d]\t# box lock",
1744 1768 Matcher::regName[reg], offset);
1745 1769 }
1746 1770 #endif
1747 1771
1748 1772 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1749 1773 {
1750 1774 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1751 1775 int reg = ra_->get_encode(this);
1752 1776 if (offset >= 0x80) {
1753 1777 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1754 1778 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1755 1779 emit_rm(cbuf, 0x2, reg & 7, 0x04);
1756 1780 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1757 1781 emit_d32(cbuf, offset);
1758 1782 } else {
1759 1783 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1760 1784 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1761 1785 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1762 1786 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1763 1787 emit_d8(cbuf, offset);
1764 1788 }
1765 1789 }
1766 1790
1767 1791 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1768 1792 {
1769 1793 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1770 1794 return (offset < 0x80) ? 5 : 8; // REX
1771 1795 }
1772 1796
1773 1797 //=============================================================================
1774 1798
1775 1799 // emit call stub, compiled java to interpreter
1776 1800 void emit_java_to_interp(CodeBuffer& cbuf)
1777 1801 {
1778 1802 // Stub is fixed up when the corresponding call is converted from
1779 1803 // calling compiled code to calling interpreted code.
1780 1804 // movq rbx, 0
1781 1805 // jmp -5 # to self
1782 1806
1783 1807 address mark = cbuf.insts_mark(); // get mark within main instrs section
1784 1808
1785 1809 // Note that the code buffer's insts_mark is always relative to insts.
1786 1810 // That's why we must use the macroassembler to generate a stub.
1787 1811 MacroAssembler _masm(&cbuf);
1788 1812
1789 1813 address base =
1790 1814 __ start_a_stub(Compile::MAX_stubs_size);
1791 1815 if (base == NULL) return; // CodeBuffer::expand failed
1792 1816 // static stub relocation stores the instruction address of the call
1793 1817 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64);
1794 1818 // static stub relocation also tags the methodOop in the code-stream.
1795 1819 __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time
1796 1820 // This is recognized as unresolved by relocs/nativeinst/ic code
1797 1821 __ jump(RuntimeAddress(__ pc()));
1798 1822
1799 1823 // Update current stubs pointer and restore insts_end.
1800 1824 __ end_a_stub();
1801 1825 }
1802 1826
1803 1827 // size of call stub, compiled java to interpretor
1804 1828 uint size_java_to_interp()
1805 1829 {
1806 1830 return 15; // movq (1+1+8); jmp (1+4)
1807 1831 }
1808 1832
1809 1833 // relocation entries for call stub, compiled java to interpretor
1810 1834 uint reloc_java_to_interp()
1811 1835 {
1812 1836 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call
1813 1837 }
1814 1838
1815 1839 //=============================================================================
1816 1840 #ifndef PRODUCT
1817 1841 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1818 1842 {
1819 1843 if (UseCompressedOops) {
1820 1844 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1821 1845 if (Universe::narrow_oop_shift() != 0) {
1822 1846 st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1");
1823 1847 }
1824 1848 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1825 1849 } else {
1826 1850 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1827 1851 "# Inline cache check");
1828 1852 }
1829 1853 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1830 1854 st->print_cr("\tnop\t# nops to align entry point");
1831 1855 }
1832 1856 #endif
1833 1857
1834 1858 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1835 1859 {
1836 1860 MacroAssembler masm(&cbuf);
1837 1861 uint insts_size = cbuf.insts_size();
1838 1862 if (UseCompressedOops) {
1839 1863 masm.load_klass(rscratch1, j_rarg0);
1840 1864 masm.cmpptr(rax, rscratch1);
1841 1865 } else {
1842 1866 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1843 1867 }
1844 1868
1845 1869 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1846 1870
1847 1871 /* WARNING these NOPs are critical so that verified entry point is properly
1848 1872 4 bytes aligned for patching by NativeJump::patch_verified_entry() */
1849 1873 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
1850 1874 if (OptoBreakpoint) {
1851 1875 // Leave space for int3
1852 1876 nops_cnt -= 1;
1853 1877 }
1854 1878 nops_cnt &= 0x3; // Do not add nops if code is aligned.
1855 1879 if (nops_cnt > 0)
1856 1880 masm.nop(nops_cnt);
1857 1881 }
1858 1882
1859 1883 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1860 1884 {
1861 1885 return MachNode::size(ra_); // too many variables; just compute it
1862 1886 // the hard way
1863 1887 }
1864 1888
1865 1889
1866 1890 //=============================================================================
1867 1891 uint size_exception_handler()
1868 1892 {
1869 1893 // NativeCall instruction size is the same as NativeJump.
1870 1894 // Note that this value is also credited (in output.cpp) to
1871 1895 // the size of the code section.
1872 1896 return NativeJump::instruction_size;
1873 1897 }
1874 1898
1875 1899 // Emit exception handler code.
1876 1900 int emit_exception_handler(CodeBuffer& cbuf)
1877 1901 {
1878 1902
1879 1903 // Note that the code buffer's insts_mark is always relative to insts.
1880 1904 // That's why we must use the macroassembler to generate a handler.
1881 1905 MacroAssembler _masm(&cbuf);
1882 1906 address base =
1883 1907 __ start_a_stub(size_exception_handler());
1884 1908 if (base == NULL) return 0; // CodeBuffer::expand failed
1885 1909 int offset = __ offset();
1886 1910 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
1887 1911 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
1888 1912 __ end_a_stub();
1889 1913 return offset;
1890 1914 }
1891 1915
1892 1916 uint size_deopt_handler()
1893 1917 {
1894 1918 // three 5 byte instructions
1895 1919 return 15;
1896 1920 }
1897 1921
1898 1922 // Emit deopt handler code.
1899 1923 int emit_deopt_handler(CodeBuffer& cbuf)
1900 1924 {
1901 1925
1902 1926 // Note that the code buffer's insts_mark is always relative to insts.
1903 1927 // That's why we must use the macroassembler to generate a handler.
1904 1928 MacroAssembler _masm(&cbuf);
1905 1929 address base =
1906 1930 __ start_a_stub(size_deopt_handler());
1907 1931 if (base == NULL) return 0; // CodeBuffer::expand failed
1908 1932 int offset = __ offset();
1909 1933 address the_pc = (address) __ pc();
1910 1934 Label next;
1911 1935 // push a "the_pc" on the stack without destroying any registers
1912 1936 // as they all may be live.
1913 1937
1914 1938 // push address of "next"
↓ open down ↓ |
1069 lines elided |
↑ open up ↑ |
1915 1939 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
1916 1940 __ bind(next);
1917 1941 // adjust it so it matches "the_pc"
1918 1942 __ subptr(Address(rsp, 0), __ offset() - offset);
1919 1943 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1920 1944 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1921 1945 __ end_a_stub();
1922 1946 return offset;
1923 1947 }
1924 1948
1925 -static void emit_double_constant(CodeBuffer& cbuf, double x) {
1926 - int mark = cbuf.insts()->mark_off();
1927 - MacroAssembler _masm(&cbuf);
1928 - address double_address = __ double_constant(x);
1929 - cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
1930 - emit_d32_reloc(cbuf,
1931 - (int) (double_address - cbuf.insts_end() - 4),
1932 - internal_word_Relocation::spec(double_address),
1933 - RELOC_DISP32);
1934 -}
1935 -
1936 -static void emit_float_constant(CodeBuffer& cbuf, float x) {
1937 - int mark = cbuf.insts()->mark_off();
1938 - MacroAssembler _masm(&cbuf);
1939 - address float_address = __ float_constant(x);
1940 - cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
1941 - emit_d32_reloc(cbuf,
1942 - (int) (float_address - cbuf.insts_end() - 4),
1943 - internal_word_Relocation::spec(float_address),
1944 - RELOC_DISP32);
1945 -}
1946 -
1947 1949
1948 1950 const bool Matcher::match_rule_supported(int opcode) {
1949 1951 if (!has_match_rule(opcode))
1950 1952 return false;
1951 1953
1952 1954 return true; // Per default match rules are supported.
1953 1955 }
1954 1956
1955 1957 int Matcher::regnum_to_fpu_offset(int regnum)
1956 1958 {
1957 1959 return regnum - 32; // The FP registers are in the second chunk
1958 1960 }
1959 1961
1960 1962 // This is UltraSparc specific, true just means we have fast l2f conversion
1961 1963 const bool Matcher::convL2FSupported(void) {
1962 1964 return true;
1963 1965 }
1964 1966
1965 1967 // Vector width in bytes
1966 1968 const uint Matcher::vector_width_in_bytes(void) {
1967 1969 return 8;
1968 1970 }
1969 1971
1970 1972 // Vector ideal reg
1971 1973 const uint Matcher::vector_ideal_reg(void) {
1972 1974 return Op_RegD;
1973 1975 }
1974 1976
1975 1977 // Is this branch offset short enough that a short branch can be used?
1976 1978 //
1977 1979 // NOTE: If the platform does not provide any short branch variants, then
1978 1980 // this method should return false for offset 0.
1979 1981 bool Matcher::is_short_branch_offset(int rule, int offset) {
1980 1982 // the short version of jmpConUCF2 contains multiple branches,
1981 1983 // making the reach slightly less
1982 1984 if (rule == jmpConUCF2_rule)
1983 1985 return (-126 <= offset && offset <= 125);
1984 1986 return (-128 <= offset && offset <= 127);
1985 1987 }
1986 1988
1987 1989 const bool Matcher::isSimpleConstant64(jlong value) {
1988 1990 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1989 1991 //return value == (int) value; // Cf. storeImmL and immL32.
1990 1992
1991 1993 // Probably always true, even if a temp register is required.
1992 1994 return true;
1993 1995 }
1994 1996
1995 1997 // The ecx parameter to rep stosq for the ClearArray node is in words.
1996 1998 const bool Matcher::init_array_count_is_in_bytes = false;
1997 1999
1998 2000 // Threshold size for cleararray.
1999 2001 const int Matcher::init_array_short_size = 8 * BytesPerLong;
2000 2002
2001 2003 // Should the Matcher clone shifts on addressing modes, expecting them
2002 2004 // to be subsumed into complex addressing expressions or compute them
2003 2005 // into registers? True for Intel but false for most RISCs
2004 2006 const bool Matcher::clone_shift_expressions = true;
2005 2007
2006 2008 bool Matcher::narrow_oop_use_complex_address() {
2007 2009 assert(UseCompressedOops, "only for compressed oops code");
2008 2010 return (LogMinObjAlignmentInBytes <= 3);
2009 2011 }
2010 2012
2011 2013 // Is it better to copy float constants, or load them directly from
2012 2014 // memory? Intel can load a float constant from a direct address,
2013 2015 // requiring no extra registers. Most RISCs will have to materialize
2014 2016 // an address into a register first, so they would do better to copy
2015 2017 // the constant from stack.
2016 2018 const bool Matcher::rematerialize_float_constants = true; // XXX
2017 2019
2018 2020 // If CPU can load and store mis-aligned doubles directly then no
2019 2021 // fixup is needed. Else we split the double into 2 integer pieces
2020 2022 // and move it piece-by-piece. Only happens when passing doubles into
2021 2023 // C code as the Java calling convention forces doubles to be aligned.
2022 2024 const bool Matcher::misaligned_doubles_ok = true;
2023 2025
2024 2026 // No-op on amd64
2025 2027 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {}
2026 2028
2027 2029 // Advertise here if the CPU requires explicit rounding operations to
2028 2030 // implement the UseStrictFP mode.
2029 2031 const bool Matcher::strict_fp_requires_explicit_rounding = true;
2030 2032
2031 2033 // Are floats conerted to double when stored to stack during deoptimization?
2032 2034 // On x64 it is stored without convertion so we can use normal access.
2033 2035 bool Matcher::float_in_double() { return false; }
2034 2036
2035 2037 // Do ints take an entire long register or just half?
2036 2038 const bool Matcher::int_in_long = true;
2037 2039
2038 2040 // Return whether or not this register is ever used as an argument.
2039 2041 // This function is used on startup to build the trampoline stubs in
2040 2042 // generateOptoStub. Registers not mentioned will be killed by the VM
2041 2043 // call in the trampoline, and arguments in those registers not be
2042 2044 // available to the callee.
2043 2045 bool Matcher::can_be_java_arg(int reg)
2044 2046 {
2045 2047 return
2046 2048 reg == RDI_num || reg == RDI_H_num ||
2047 2049 reg == RSI_num || reg == RSI_H_num ||
2048 2050 reg == RDX_num || reg == RDX_H_num ||
2049 2051 reg == RCX_num || reg == RCX_H_num ||
2050 2052 reg == R8_num || reg == R8_H_num ||
2051 2053 reg == R9_num || reg == R9_H_num ||
2052 2054 reg == R12_num || reg == R12_H_num ||
2053 2055 reg == XMM0_num || reg == XMM0_H_num ||
2054 2056 reg == XMM1_num || reg == XMM1_H_num ||
2055 2057 reg == XMM2_num || reg == XMM2_H_num ||
2056 2058 reg == XMM3_num || reg == XMM3_H_num ||
2057 2059 reg == XMM4_num || reg == XMM4_H_num ||
2058 2060 reg == XMM5_num || reg == XMM5_H_num ||
2059 2061 reg == XMM6_num || reg == XMM6_H_num ||
2060 2062 reg == XMM7_num || reg == XMM7_H_num;
2061 2063 }
2062 2064
2063 2065 bool Matcher::is_spillable_arg(int reg)
2064 2066 {
2065 2067 return can_be_java_arg(reg);
2066 2068 }
2067 2069
2068 2070 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
2069 2071 // In 64 bit mode a code which use multiply when
2070 2072 // devisor is constant is faster than hardware
2071 2073 // DIV instruction (it uses MulHiL).
2072 2074 return false;
2073 2075 }
2074 2076
2075 2077 // Register for DIVI projection of divmodI
2076 2078 RegMask Matcher::divI_proj_mask() {
2077 2079 return INT_RAX_REG_mask;
2078 2080 }
2079 2081
2080 2082 // Register for MODI projection of divmodI
2081 2083 RegMask Matcher::modI_proj_mask() {
2082 2084 return INT_RDX_REG_mask;
2083 2085 }
2084 2086
2085 2087 // Register for DIVL projection of divmodL
2086 2088 RegMask Matcher::divL_proj_mask() {
2087 2089 return LONG_RAX_REG_mask;
2088 2090 }
2089 2091
2090 2092 // Register for MODL projection of divmodL
2091 2093 RegMask Matcher::modL_proj_mask() {
2092 2094 return LONG_RDX_REG_mask;
2093 2095 }
2094 2096
2095 2097 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
2096 2098 return PTR_RBP_REG_mask;
2097 2099 }
2098 2100
2099 2101 static Address build_address(int b, int i, int s, int d) {
2100 2102 Register index = as_Register(i);
2101 2103 Address::ScaleFactor scale = (Address::ScaleFactor)s;
2102 2104 if (index == rsp) {
2103 2105 index = noreg;
2104 2106 scale = Address::no_scale;
2105 2107 }
2106 2108 Address addr(as_Register(b), index, scale, d);
2107 2109 return addr;
2108 2110 }
2109 2111
2110 2112 %}
2111 2113
2112 2114 //----------ENCODING BLOCK-----------------------------------------------------
2113 2115 // This block specifies the encoding classes used by the compiler to
2114 2116 // output byte streams. Encoding classes are parameterized macros
2115 2117 // used by Machine Instruction Nodes in order to generate the bit
2116 2118 // encoding of the instruction. Operands specify their base encoding
2117 2119 // interface with the interface keyword. There are currently
2118 2120 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
2119 2121 // COND_INTER. REG_INTER causes an operand to generate a function
2120 2122 // which returns its register number when queried. CONST_INTER causes
2121 2123 // an operand to generate a function which returns the value of the
2122 2124 // constant when queried. MEMORY_INTER causes an operand to generate
2123 2125 // four functions which return the Base Register, the Index Register,
2124 2126 // the Scale Value, and the Offset Value of the operand when queried.
2125 2127 // COND_INTER causes an operand to generate six functions which return
2126 2128 // the encoding code (ie - encoding bits for the instruction)
2127 2129 // associated with each basic boolean condition for a conditional
2128 2130 // instruction.
2129 2131 //
2130 2132 // Instructions specify two basic values for encoding. Again, a
2131 2133 // function is available to check if the constant displacement is an
2132 2134 // oop. They use the ins_encode keyword to specify their encoding
2133 2135 // classes (which must be a sequence of enc_class names, and their
2134 2136 // parameters, specified in the encoding block), and they use the
2135 2137 // opcode keyword to specify, in order, their primary, secondary, and
2136 2138 // tertiary opcode. Only the opcode sections which a particular
2137 2139 // instruction needs for encoding need to be specified.
2138 2140 encode %{
2139 2141 // Build emit functions for each basic byte or larger field in the
2140 2142 // intel encoding scheme (opcode, rm, sib, immediate), and call them
2141 2143 // from C++ code in the enc_class source block. Emit functions will
2142 2144 // live in the main source block for now. In future, we can
2143 2145 // generalize this by adding a syntax that specifies the sizes of
2144 2146 // fields in an order, so that the adlc can build the emit functions
2145 2147 // automagically
2146 2148
2147 2149 // Emit primary opcode
2148 2150 enc_class OpcP
2149 2151 %{
2150 2152 emit_opcode(cbuf, $primary);
2151 2153 %}
2152 2154
2153 2155 // Emit secondary opcode
2154 2156 enc_class OpcS
2155 2157 %{
2156 2158 emit_opcode(cbuf, $secondary);
2157 2159 %}
2158 2160
2159 2161 // Emit tertiary opcode
2160 2162 enc_class OpcT
2161 2163 %{
2162 2164 emit_opcode(cbuf, $tertiary);
2163 2165 %}
2164 2166
2165 2167 // Emit opcode directly
2166 2168 enc_class Opcode(immI d8)
2167 2169 %{
2168 2170 emit_opcode(cbuf, $d8$$constant);
2169 2171 %}
2170 2172
2171 2173 // Emit size prefix
2172 2174 enc_class SizePrefix
2173 2175 %{
2174 2176 emit_opcode(cbuf, 0x66);
2175 2177 %}
2176 2178
2177 2179 enc_class reg(rRegI reg)
2178 2180 %{
2179 2181 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
2180 2182 %}
2181 2183
2182 2184 enc_class reg_reg(rRegI dst, rRegI src)
2183 2185 %{
2184 2186 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2185 2187 %}
2186 2188
2187 2189 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
2188 2190 %{
2189 2191 emit_opcode(cbuf, $opcode$$constant);
2190 2192 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2191 2193 %}
2192 2194
2193 2195 enc_class cmpfp_fixup()
2194 2196 %{
2195 2197 // jnp,s exit
2196 2198 emit_opcode(cbuf, 0x7B);
2197 2199 emit_d8(cbuf, 0x0A);
2198 2200
2199 2201 // pushfq
2200 2202 emit_opcode(cbuf, 0x9C);
2201 2203
2202 2204 // andq $0xffffff2b, (%rsp)
2203 2205 emit_opcode(cbuf, Assembler::REX_W);
2204 2206 emit_opcode(cbuf, 0x81);
2205 2207 emit_opcode(cbuf, 0x24);
2206 2208 emit_opcode(cbuf, 0x24);
2207 2209 emit_d32(cbuf, 0xffffff2b);
2208 2210
2209 2211 // popfq
2210 2212 emit_opcode(cbuf, 0x9D);
2211 2213
2212 2214 // nop (target for branch to avoid branch to branch)
2213 2215 emit_opcode(cbuf, 0x90);
2214 2216 %}
2215 2217
2216 2218 enc_class cmpfp3(rRegI dst)
2217 2219 %{
2218 2220 int dstenc = $dst$$reg;
2219 2221
2220 2222 // movl $dst, -1
2221 2223 if (dstenc >= 8) {
2222 2224 emit_opcode(cbuf, Assembler::REX_B);
2223 2225 }
2224 2226 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
2225 2227 emit_d32(cbuf, -1);
2226 2228
2227 2229 // jp,s done
2228 2230 emit_opcode(cbuf, 0x7A);
2229 2231 emit_d8(cbuf, dstenc < 4 ? 0x08 : 0x0A);
2230 2232
2231 2233 // jb,s done
2232 2234 emit_opcode(cbuf, 0x72);
2233 2235 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
2234 2236
2235 2237 // setne $dst
2236 2238 if (dstenc >= 4) {
2237 2239 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
2238 2240 }
2239 2241 emit_opcode(cbuf, 0x0F);
2240 2242 emit_opcode(cbuf, 0x95);
2241 2243 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
2242 2244
2243 2245 // movzbl $dst, $dst
2244 2246 if (dstenc >= 4) {
2245 2247 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
2246 2248 }
2247 2249 emit_opcode(cbuf, 0x0F);
2248 2250 emit_opcode(cbuf, 0xB6);
2249 2251 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
2250 2252 %}
2251 2253
2252 2254 enc_class cdql_enc(no_rax_rdx_RegI div)
2253 2255 %{
2254 2256 // Full implementation of Java idiv and irem; checks for
2255 2257 // special case as described in JVM spec., p.243 & p.271.
2256 2258 //
2257 2259 // normal case special case
2258 2260 //
2259 2261 // input : rax: dividend min_int
2260 2262 // reg: divisor -1
2261 2263 //
2262 2264 // output: rax: quotient (= rax idiv reg) min_int
2263 2265 // rdx: remainder (= rax irem reg) 0
2264 2266 //
2265 2267 // Code sequnce:
2266 2268 //
2267 2269 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax
2268 2270 // 5: 75 07/08 jne e <normal>
2269 2271 // 7: 33 d2 xor %edx,%edx
2270 2272 // [div >= 8 -> offset + 1]
2271 2273 // [REX_B]
2272 2274 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div
2273 2275 // c: 74 03/04 je 11 <done>
2274 2276 // 000000000000000e <normal>:
2275 2277 // e: 99 cltd
2276 2278 // [div >= 8 -> offset + 1]
2277 2279 // [REX_B]
2278 2280 // f: f7 f9 idiv $div
2279 2281 // 0000000000000011 <done>:
2280 2282
2281 2283 // cmp $0x80000000,%eax
2282 2284 emit_opcode(cbuf, 0x3d);
2283 2285 emit_d8(cbuf, 0x00);
2284 2286 emit_d8(cbuf, 0x00);
2285 2287 emit_d8(cbuf, 0x00);
2286 2288 emit_d8(cbuf, 0x80);
2287 2289
2288 2290 // jne e <normal>
2289 2291 emit_opcode(cbuf, 0x75);
2290 2292 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08);
2291 2293
2292 2294 // xor %edx,%edx
2293 2295 emit_opcode(cbuf, 0x33);
2294 2296 emit_d8(cbuf, 0xD2);
2295 2297
2296 2298 // cmp $0xffffffffffffffff,%ecx
2297 2299 if ($div$$reg >= 8) {
2298 2300 emit_opcode(cbuf, Assembler::REX_B);
2299 2301 }
2300 2302 emit_opcode(cbuf, 0x83);
2301 2303 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
2302 2304 emit_d8(cbuf, 0xFF);
2303 2305
2304 2306 // je 11 <done>
2305 2307 emit_opcode(cbuf, 0x74);
2306 2308 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04);
2307 2309
2308 2310 // <normal>
2309 2311 // cltd
2310 2312 emit_opcode(cbuf, 0x99);
2311 2313
2312 2314 // idivl (note: must be emitted by the user of this rule)
2313 2315 // <done>
2314 2316 %}
2315 2317
2316 2318 enc_class cdqq_enc(no_rax_rdx_RegL div)
2317 2319 %{
2318 2320 // Full implementation of Java ldiv and lrem; checks for
2319 2321 // special case as described in JVM spec., p.243 & p.271.
2320 2322 //
2321 2323 // normal case special case
2322 2324 //
2323 2325 // input : rax: dividend min_long
2324 2326 // reg: divisor -1
2325 2327 //
2326 2328 // output: rax: quotient (= rax idiv reg) min_long
2327 2329 // rdx: remainder (= rax irem reg) 0
2328 2330 //
2329 2331 // Code sequnce:
2330 2332 //
2331 2333 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx
2332 2334 // 7: 00 00 80
2333 2335 // a: 48 39 d0 cmp %rdx,%rax
2334 2336 // d: 75 08 jne 17 <normal>
2335 2337 // f: 33 d2 xor %edx,%edx
2336 2338 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div
2337 2339 // 15: 74 05 je 1c <done>
2338 2340 // 0000000000000017 <normal>:
2339 2341 // 17: 48 99 cqto
2340 2342 // 19: 48 f7 f9 idiv $div
2341 2343 // 000000000000001c <done>:
2342 2344
2343 2345 // mov $0x8000000000000000,%rdx
2344 2346 emit_opcode(cbuf, Assembler::REX_W);
2345 2347 emit_opcode(cbuf, 0xBA);
2346 2348 emit_d8(cbuf, 0x00);
2347 2349 emit_d8(cbuf, 0x00);
2348 2350 emit_d8(cbuf, 0x00);
2349 2351 emit_d8(cbuf, 0x00);
2350 2352 emit_d8(cbuf, 0x00);
2351 2353 emit_d8(cbuf, 0x00);
2352 2354 emit_d8(cbuf, 0x00);
2353 2355 emit_d8(cbuf, 0x80);
2354 2356
2355 2357 // cmp %rdx,%rax
2356 2358 emit_opcode(cbuf, Assembler::REX_W);
2357 2359 emit_opcode(cbuf, 0x39);
2358 2360 emit_d8(cbuf, 0xD0);
2359 2361
2360 2362 // jne 17 <normal>
2361 2363 emit_opcode(cbuf, 0x75);
2362 2364 emit_d8(cbuf, 0x08);
2363 2365
2364 2366 // xor %edx,%edx
2365 2367 emit_opcode(cbuf, 0x33);
2366 2368 emit_d8(cbuf, 0xD2);
2367 2369
2368 2370 // cmp $0xffffffffffffffff,$div
2369 2371 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB);
2370 2372 emit_opcode(cbuf, 0x83);
2371 2373 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
2372 2374 emit_d8(cbuf, 0xFF);
2373 2375
2374 2376 // je 1e <done>
2375 2377 emit_opcode(cbuf, 0x74);
2376 2378 emit_d8(cbuf, 0x05);
2377 2379
2378 2380 // <normal>
2379 2381 // cqto
2380 2382 emit_opcode(cbuf, Assembler::REX_W);
2381 2383 emit_opcode(cbuf, 0x99);
2382 2384
2383 2385 // idivq (note: must be emitted by the user of this rule)
2384 2386 // <done>
2385 2387 %}
2386 2388
2387 2389 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
2388 2390 enc_class OpcSE(immI imm)
2389 2391 %{
2390 2392 // Emit primary opcode and set sign-extend bit
2391 2393 // Check for 8-bit immediate, and set sign extend bit in opcode
2392 2394 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2393 2395 emit_opcode(cbuf, $primary | 0x02);
2394 2396 } else {
2395 2397 // 32-bit immediate
2396 2398 emit_opcode(cbuf, $primary);
2397 2399 }
2398 2400 %}
2399 2401
2400 2402 enc_class OpcSErm(rRegI dst, immI imm)
2401 2403 %{
2402 2404 // OpcSEr/m
2403 2405 int dstenc = $dst$$reg;
2404 2406 if (dstenc >= 8) {
2405 2407 emit_opcode(cbuf, Assembler::REX_B);
2406 2408 dstenc -= 8;
2407 2409 }
2408 2410 // Emit primary opcode and set sign-extend bit
2409 2411 // Check for 8-bit immediate, and set sign extend bit in opcode
2410 2412 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2411 2413 emit_opcode(cbuf, $primary | 0x02);
2412 2414 } else {
2413 2415 // 32-bit immediate
2414 2416 emit_opcode(cbuf, $primary);
2415 2417 }
2416 2418 // Emit r/m byte with secondary opcode, after primary opcode.
2417 2419 emit_rm(cbuf, 0x3, $secondary, dstenc);
2418 2420 %}
2419 2421
2420 2422 enc_class OpcSErm_wide(rRegL dst, immI imm)
2421 2423 %{
2422 2424 // OpcSEr/m
2423 2425 int dstenc = $dst$$reg;
2424 2426 if (dstenc < 8) {
2425 2427 emit_opcode(cbuf, Assembler::REX_W);
2426 2428 } else {
2427 2429 emit_opcode(cbuf, Assembler::REX_WB);
2428 2430 dstenc -= 8;
2429 2431 }
2430 2432 // Emit primary opcode and set sign-extend bit
2431 2433 // Check for 8-bit immediate, and set sign extend bit in opcode
2432 2434 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2433 2435 emit_opcode(cbuf, $primary | 0x02);
2434 2436 } else {
2435 2437 // 32-bit immediate
2436 2438 emit_opcode(cbuf, $primary);
2437 2439 }
2438 2440 // Emit r/m byte with secondary opcode, after primary opcode.
2439 2441 emit_rm(cbuf, 0x3, $secondary, dstenc);
2440 2442 %}
2441 2443
2442 2444 enc_class Con8or32(immI imm)
2443 2445 %{
2444 2446 // Check for 8-bit immediate, and set sign extend bit in opcode
2445 2447 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2446 2448 $$$emit8$imm$$constant;
2447 2449 } else {
2448 2450 // 32-bit immediate
2449 2451 $$$emit32$imm$$constant;
2450 2452 }
2451 2453 %}
2452 2454
2453 2455 enc_class Lbl(label labl)
2454 2456 %{
2455 2457 // JMP, CALL
2456 2458 Label* l = $labl$$label;
2457 2459 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0);
2458 2460 %}
2459 2461
2460 2462 enc_class LblShort(label labl)
2461 2463 %{
2462 2464 // JMP, CALL
2463 2465 Label* l = $labl$$label;
2464 2466 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
2465 2467 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
2466 2468 emit_d8(cbuf, disp);
2467 2469 %}
2468 2470
2469 2471 enc_class opc2_reg(rRegI dst)
2470 2472 %{
2471 2473 // BSWAP
2472 2474 emit_cc(cbuf, $secondary, $dst$$reg);
2473 2475 %}
2474 2476
2475 2477 enc_class opc3_reg(rRegI dst)
2476 2478 %{
2477 2479 // BSWAP
2478 2480 emit_cc(cbuf, $tertiary, $dst$$reg);
2479 2481 %}
2480 2482
2481 2483 enc_class reg_opc(rRegI div)
2482 2484 %{
2483 2485 // INC, DEC, IDIV, IMOD, JMP indirect, ...
2484 2486 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
2485 2487 %}
2486 2488
2487 2489 enc_class Jcc(cmpOp cop, label labl)
2488 2490 %{
2489 2491 // JCC
2490 2492 Label* l = $labl$$label;
2491 2493 $$$emit8$primary;
2492 2494 emit_cc(cbuf, $secondary, $cop$$cmpcode);
2493 2495 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0);
2494 2496 %}
2495 2497
2496 2498 enc_class JccShort (cmpOp cop, label labl)
2497 2499 %{
2498 2500 // JCC
2499 2501 Label *l = $labl$$label;
2500 2502 emit_cc(cbuf, $primary, $cop$$cmpcode);
2501 2503 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
2502 2504 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
2503 2505 emit_d8(cbuf, disp);
2504 2506 %}
2505 2507
2506 2508 enc_class enc_cmov(cmpOp cop)
2507 2509 %{
2508 2510 // CMOV
2509 2511 $$$emit8$primary;
2510 2512 emit_cc(cbuf, $secondary, $cop$$cmpcode);
2511 2513 %}
2512 2514
2513 2515 enc_class enc_cmovf_branch(cmpOp cop, regF dst, regF src)
2514 2516 %{
2515 2517 // Invert sense of branch from sense of cmov
2516 2518 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1);
2517 2519 emit_d8(cbuf, ($dst$$reg < 8 && $src$$reg < 8)
2518 2520 ? (UseXmmRegToRegMoveAll ? 3 : 4)
2519 2521 : (UseXmmRegToRegMoveAll ? 4 : 5) ); // REX
2520 2522 // UseXmmRegToRegMoveAll ? movaps(dst, src) : movss(dst, src)
2521 2523 if (!UseXmmRegToRegMoveAll) emit_opcode(cbuf, 0xF3);
2522 2524 if ($dst$$reg < 8) {
2523 2525 if ($src$$reg >= 8) {
2524 2526 emit_opcode(cbuf, Assembler::REX_B);
2525 2527 }
2526 2528 } else {
2527 2529 if ($src$$reg < 8) {
2528 2530 emit_opcode(cbuf, Assembler::REX_R);
2529 2531 } else {
2530 2532 emit_opcode(cbuf, Assembler::REX_RB);
2531 2533 }
2532 2534 }
2533 2535 emit_opcode(cbuf, 0x0F);
2534 2536 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
2535 2537 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2536 2538 %}
2537 2539
2538 2540 enc_class enc_cmovd_branch(cmpOp cop, regD dst, regD src)
2539 2541 %{
2540 2542 // Invert sense of branch from sense of cmov
2541 2543 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1);
2542 2544 emit_d8(cbuf, $dst$$reg < 8 && $src$$reg < 8 ? 4 : 5); // REX
2543 2545
2544 2546 // UseXmmRegToRegMoveAll ? movapd(dst, src) : movsd(dst, src)
2545 2547 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2);
2546 2548 if ($dst$$reg < 8) {
2547 2549 if ($src$$reg >= 8) {
2548 2550 emit_opcode(cbuf, Assembler::REX_B);
2549 2551 }
2550 2552 } else {
2551 2553 if ($src$$reg < 8) {
2552 2554 emit_opcode(cbuf, Assembler::REX_R);
2553 2555 } else {
2554 2556 emit_opcode(cbuf, Assembler::REX_RB);
2555 2557 }
2556 2558 }
2557 2559 emit_opcode(cbuf, 0x0F);
2558 2560 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
2559 2561 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2560 2562 %}
2561 2563
2562 2564 enc_class enc_PartialSubtypeCheck()
2563 2565 %{
2564 2566 Register Rrdi = as_Register(RDI_enc); // result register
2565 2567 Register Rrax = as_Register(RAX_enc); // super class
2566 2568 Register Rrcx = as_Register(RCX_enc); // killed
2567 2569 Register Rrsi = as_Register(RSI_enc); // sub class
2568 2570 Label miss;
2569 2571 const bool set_cond_codes = true;
2570 2572
2571 2573 MacroAssembler _masm(&cbuf);
2572 2574 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
2573 2575 NULL, &miss,
2574 2576 /*set_cond_codes:*/ true);
2575 2577 if ($primary) {
2576 2578 __ xorptr(Rrdi, Rrdi);
2577 2579 }
2578 2580 __ bind(miss);
2579 2581 %}
2580 2582
2581 2583 enc_class Java_To_Interpreter(method meth)
2582 2584 %{
2583 2585 // CALL Java_To_Interpreter
2584 2586 // This is the instruction starting address for relocation info.
2585 2587 cbuf.set_insts_mark();
2586 2588 $$$emit8$primary;
2587 2589 // CALL directly to the runtime
2588 2590 emit_d32_reloc(cbuf,
2589 2591 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2590 2592 runtime_call_Relocation::spec(),
2591 2593 RELOC_DISP32);
2592 2594 %}
2593 2595
2594 2596 enc_class preserve_SP %{
2595 2597 debug_only(int off0 = cbuf.insts_size());
2596 2598 MacroAssembler _masm(&cbuf);
2597 2599 // RBP is preserved across all calls, even compiled calls.
2598 2600 // Use it to preserve RSP in places where the callee might change the SP.
2599 2601 __ movptr(rbp_mh_SP_save, rsp);
2600 2602 debug_only(int off1 = cbuf.insts_size());
2601 2603 assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
2602 2604 %}
2603 2605
2604 2606 enc_class restore_SP %{
2605 2607 MacroAssembler _masm(&cbuf);
2606 2608 __ movptr(rsp, rbp_mh_SP_save);
2607 2609 %}
2608 2610
2609 2611 enc_class Java_Static_Call(method meth)
2610 2612 %{
2611 2613 // JAVA STATIC CALL
2612 2614 // CALL to fixup routine. Fixup routine uses ScopeDesc info to
2613 2615 // determine who we intended to call.
2614 2616 cbuf.set_insts_mark();
2615 2617 $$$emit8$primary;
2616 2618
2617 2619 if (!_method) {
2618 2620 emit_d32_reloc(cbuf,
2619 2621 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2620 2622 runtime_call_Relocation::spec(),
2621 2623 RELOC_DISP32);
2622 2624 } else if (_optimized_virtual) {
2623 2625 emit_d32_reloc(cbuf,
2624 2626 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2625 2627 opt_virtual_call_Relocation::spec(),
2626 2628 RELOC_DISP32);
2627 2629 } else {
2628 2630 emit_d32_reloc(cbuf,
2629 2631 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2630 2632 static_call_Relocation::spec(),
2631 2633 RELOC_DISP32);
2632 2634 }
2633 2635 if (_method) {
2634 2636 // Emit stub for static call
2635 2637 emit_java_to_interp(cbuf);
2636 2638 }
2637 2639 %}
2638 2640
2639 2641 enc_class Java_Dynamic_Call(method meth)
2640 2642 %{
2641 2643 // JAVA DYNAMIC CALL
2642 2644 // !!!!!
2643 2645 // Generate "movq rax, -1", placeholder instruction to load oop-info
2644 2646 // emit_call_dynamic_prologue( cbuf );
2645 2647 cbuf.set_insts_mark();
2646 2648
2647 2649 // movq rax, -1
2648 2650 emit_opcode(cbuf, Assembler::REX_W);
2649 2651 emit_opcode(cbuf, 0xB8 | RAX_enc);
2650 2652 emit_d64_reloc(cbuf,
2651 2653 (int64_t) Universe::non_oop_word(),
2652 2654 oop_Relocation::spec_for_immediate(), RELOC_IMM64);
2653 2655 address virtual_call_oop_addr = cbuf.insts_mark();
2654 2656 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
2655 2657 // who we intended to call.
2656 2658 cbuf.set_insts_mark();
2657 2659 $$$emit8$primary;
2658 2660 emit_d32_reloc(cbuf,
2659 2661 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2660 2662 virtual_call_Relocation::spec(virtual_call_oop_addr),
2661 2663 RELOC_DISP32);
2662 2664 %}
2663 2665
2664 2666 enc_class Java_Compiled_Call(method meth)
2665 2667 %{
2666 2668 // JAVA COMPILED CALL
2667 2669 int disp = in_bytes(methodOopDesc:: from_compiled_offset());
2668 2670
2669 2671 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
2670 2672 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
2671 2673
2672 2674 // callq *disp(%rax)
2673 2675 cbuf.set_insts_mark();
2674 2676 $$$emit8$primary;
2675 2677 if (disp < 0x80) {
2676 2678 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
2677 2679 emit_d8(cbuf, disp); // Displacement
2678 2680 } else {
2679 2681 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte
2680 2682 emit_d32(cbuf, disp); // Displacement
2681 2683 }
2682 2684 %}
2683 2685
2684 2686 enc_class reg_opc_imm(rRegI dst, immI8 shift)
2685 2687 %{
2686 2688 // SAL, SAR, SHR
2687 2689 int dstenc = $dst$$reg;
2688 2690 if (dstenc >= 8) {
2689 2691 emit_opcode(cbuf, Assembler::REX_B);
2690 2692 dstenc -= 8;
2691 2693 }
2692 2694 $$$emit8$primary;
2693 2695 emit_rm(cbuf, 0x3, $secondary, dstenc);
2694 2696 $$$emit8$shift$$constant;
2695 2697 %}
2696 2698
2697 2699 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift)
2698 2700 %{
2699 2701 // SAL, SAR, SHR
2700 2702 int dstenc = $dst$$reg;
2701 2703 if (dstenc < 8) {
2702 2704 emit_opcode(cbuf, Assembler::REX_W);
2703 2705 } else {
2704 2706 emit_opcode(cbuf, Assembler::REX_WB);
2705 2707 dstenc -= 8;
2706 2708 }
2707 2709 $$$emit8$primary;
2708 2710 emit_rm(cbuf, 0x3, $secondary, dstenc);
2709 2711 $$$emit8$shift$$constant;
2710 2712 %}
2711 2713
2712 2714 enc_class load_immI(rRegI dst, immI src)
2713 2715 %{
2714 2716 int dstenc = $dst$$reg;
2715 2717 if (dstenc >= 8) {
2716 2718 emit_opcode(cbuf, Assembler::REX_B);
2717 2719 dstenc -= 8;
2718 2720 }
2719 2721 emit_opcode(cbuf, 0xB8 | dstenc);
2720 2722 $$$emit32$src$$constant;
2721 2723 %}
2722 2724
2723 2725 enc_class load_immL(rRegL dst, immL src)
2724 2726 %{
2725 2727 int dstenc = $dst$$reg;
2726 2728 if (dstenc < 8) {
2727 2729 emit_opcode(cbuf, Assembler::REX_W);
2728 2730 } else {
2729 2731 emit_opcode(cbuf, Assembler::REX_WB);
2730 2732 dstenc -= 8;
2731 2733 }
2732 2734 emit_opcode(cbuf, 0xB8 | dstenc);
2733 2735 emit_d64(cbuf, $src$$constant);
2734 2736 %}
2735 2737
2736 2738 enc_class load_immUL32(rRegL dst, immUL32 src)
2737 2739 %{
2738 2740 // same as load_immI, but this time we care about zeroes in the high word
2739 2741 int dstenc = $dst$$reg;
2740 2742 if (dstenc >= 8) {
2741 2743 emit_opcode(cbuf, Assembler::REX_B);
2742 2744 dstenc -= 8;
2743 2745 }
2744 2746 emit_opcode(cbuf, 0xB8 | dstenc);
2745 2747 $$$emit32$src$$constant;
2746 2748 %}
2747 2749
2748 2750 enc_class load_immL32(rRegL dst, immL32 src)
2749 2751 %{
2750 2752 int dstenc = $dst$$reg;
2751 2753 if (dstenc < 8) {
2752 2754 emit_opcode(cbuf, Assembler::REX_W);
2753 2755 } else {
2754 2756 emit_opcode(cbuf, Assembler::REX_WB);
2755 2757 dstenc -= 8;
2756 2758 }
2757 2759 emit_opcode(cbuf, 0xC7);
2758 2760 emit_rm(cbuf, 0x03, 0x00, dstenc);
2759 2761 $$$emit32$src$$constant;
2760 2762 %}
2761 2763
2762 2764 enc_class load_immP31(rRegP dst, immP32 src)
2763 2765 %{
2764 2766 // same as load_immI, but this time we care about zeroes in the high word
2765 2767 int dstenc = $dst$$reg;
2766 2768 if (dstenc >= 8) {
2767 2769 emit_opcode(cbuf, Assembler::REX_B);
2768 2770 dstenc -= 8;
2769 2771 }
2770 2772 emit_opcode(cbuf, 0xB8 | dstenc);
2771 2773 $$$emit32$src$$constant;
2772 2774 %}
2773 2775
2774 2776 enc_class load_immP(rRegP dst, immP src)
2775 2777 %{
2776 2778 int dstenc = $dst$$reg;
2777 2779 if (dstenc < 8) {
2778 2780 emit_opcode(cbuf, Assembler::REX_W);
2779 2781 } else {
2780 2782 emit_opcode(cbuf, Assembler::REX_WB);
2781 2783 dstenc -= 8;
↓ open down ↓ |
825 lines elided |
↑ open up ↑ |
2782 2784 }
2783 2785 emit_opcode(cbuf, 0xB8 | dstenc);
2784 2786 // This next line should be generated from ADLC
2785 2787 if ($src->constant_is_oop()) {
2786 2788 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64);
2787 2789 } else {
2788 2790 emit_d64(cbuf, $src$$constant);
2789 2791 }
2790 2792 %}
2791 2793
2792 - enc_class load_immF(regF dst, immF con)
2793 - %{
2794 - // XXX reg_mem doesn't support RIP-relative addressing yet
2795 - emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2796 - emit_float_constant(cbuf, $con$$constant);
2797 - %}
2798 -
2799 - enc_class load_immD(regD dst, immD con)
2800 - %{
2801 - // XXX reg_mem doesn't support RIP-relative addressing yet
2802 - emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2803 - emit_double_constant(cbuf, $con$$constant);
2804 - %}
2805 -
2806 - enc_class load_conF (regF dst, immF con) %{ // Load float constant
2807 - emit_opcode(cbuf, 0xF3);
2808 - if ($dst$$reg >= 8) {
2809 - emit_opcode(cbuf, Assembler::REX_R);
2810 - }
2811 - emit_opcode(cbuf, 0x0F);
2812 - emit_opcode(cbuf, 0x10);
2813 - emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2814 - emit_float_constant(cbuf, $con$$constant);
2815 - %}
2816 -
2817 - enc_class load_conD (regD dst, immD con) %{ // Load double constant
2818 - // UseXmmLoadAndClearUpper ? movsd(dst, con) : movlpd(dst, con)
2819 - emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
2820 - if ($dst$$reg >= 8) {
2821 - emit_opcode(cbuf, Assembler::REX_R);
2822 - }
2823 - emit_opcode(cbuf, 0x0F);
2824 - emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
2825 - emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2826 - emit_double_constant(cbuf, $con$$constant);
2827 - %}
2828 -
2829 2794 // Encode a reg-reg copy. If it is useless, then empty encoding.
2830 2795 enc_class enc_copy(rRegI dst, rRegI src)
2831 2796 %{
2832 2797 encode_copy(cbuf, $dst$$reg, $src$$reg);
2833 2798 %}
2834 2799
2835 2800 // Encode xmm reg-reg copy. If it is useless, then empty encoding.
2836 2801 enc_class enc_CopyXD( RegD dst, RegD src ) %{
2837 2802 encode_CopyXD( cbuf, $dst$$reg, $src$$reg );
2838 2803 %}
2839 2804
2840 2805 enc_class enc_copy_always(rRegI dst, rRegI src)
2841 2806 %{
2842 2807 int srcenc = $src$$reg;
2843 2808 int dstenc = $dst$$reg;
2844 2809
2845 2810 if (dstenc < 8) {
2846 2811 if (srcenc >= 8) {
2847 2812 emit_opcode(cbuf, Assembler::REX_B);
2848 2813 srcenc -= 8;
2849 2814 }
2850 2815 } else {
2851 2816 if (srcenc < 8) {
2852 2817 emit_opcode(cbuf, Assembler::REX_R);
2853 2818 } else {
2854 2819 emit_opcode(cbuf, Assembler::REX_RB);
2855 2820 srcenc -= 8;
2856 2821 }
2857 2822 dstenc -= 8;
2858 2823 }
2859 2824
2860 2825 emit_opcode(cbuf, 0x8B);
2861 2826 emit_rm(cbuf, 0x3, dstenc, srcenc);
2862 2827 %}
2863 2828
2864 2829 enc_class enc_copy_wide(rRegL dst, rRegL src)
2865 2830 %{
2866 2831 int srcenc = $src$$reg;
2867 2832 int dstenc = $dst$$reg;
2868 2833
2869 2834 if (dstenc != srcenc) {
2870 2835 if (dstenc < 8) {
2871 2836 if (srcenc < 8) {
2872 2837 emit_opcode(cbuf, Assembler::REX_W);
2873 2838 } else {
2874 2839 emit_opcode(cbuf, Assembler::REX_WB);
2875 2840 srcenc -= 8;
2876 2841 }
2877 2842 } else {
2878 2843 if (srcenc < 8) {
2879 2844 emit_opcode(cbuf, Assembler::REX_WR);
2880 2845 } else {
2881 2846 emit_opcode(cbuf, Assembler::REX_WRB);
2882 2847 srcenc -= 8;
2883 2848 }
2884 2849 dstenc -= 8;
2885 2850 }
2886 2851 emit_opcode(cbuf, 0x8B);
2887 2852 emit_rm(cbuf, 0x3, dstenc, srcenc);
2888 2853 }
2889 2854 %}
2890 2855
2891 2856 enc_class Con32(immI src)
2892 2857 %{
2893 2858 // Output immediate
2894 2859 $$$emit32$src$$constant;
2895 2860 %}
2896 2861
2897 2862 enc_class Con64(immL src)
2898 2863 %{
2899 2864 // Output immediate
2900 2865 emit_d64($src$$constant);
2901 2866 %}
2902 2867
2903 2868 enc_class Con32F_as_bits(immF src)
2904 2869 %{
2905 2870 // Output Float immediate bits
2906 2871 jfloat jf = $src$$constant;
2907 2872 jint jf_as_bits = jint_cast(jf);
2908 2873 emit_d32(cbuf, jf_as_bits);
2909 2874 %}
2910 2875
2911 2876 enc_class Con16(immI src)
2912 2877 %{
2913 2878 // Output immediate
2914 2879 $$$emit16$src$$constant;
2915 2880 %}
2916 2881
2917 2882 // How is this different from Con32??? XXX
2918 2883 enc_class Con_d32(immI src)
↓ open down ↓ |
80 lines elided |
↑ open up ↑ |
2919 2884 %{
2920 2885 emit_d32(cbuf,$src$$constant);
2921 2886 %}
2922 2887
2923 2888 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
2924 2889 // Output immediate memory reference
2925 2890 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2926 2891 emit_d32(cbuf, 0x00);
2927 2892 %}
2928 2893
2929 - enc_class jump_enc(rRegL switch_val, rRegI dest) %{
2930 - MacroAssembler masm(&cbuf);
2931 -
2932 - Register switch_reg = as_Register($switch_val$$reg);
2933 - Register dest_reg = as_Register($dest$$reg);
2934 - address table_base = masm.address_table_constant(_index2label);
2935 -
2936 - // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2937 - // to do that and the compiler is using that register as one it can allocate.
2938 - // So we build it all by hand.
2939 - // Address index(noreg, switch_reg, Address::times_1);
2940 - // ArrayAddress dispatch(table, index);
2941 -
2942 - Address dispatch(dest_reg, switch_reg, Address::times_1);
2943 -
2944 - masm.lea(dest_reg, InternalAddress(table_base));
2945 - masm.jmp(dispatch);
2946 - %}
2947 -
2948 - enc_class jump_enc_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
2949 - MacroAssembler masm(&cbuf);
2950 -
2951 - Register switch_reg = as_Register($switch_val$$reg);
2952 - Register dest_reg = as_Register($dest$$reg);
2953 - address table_base = masm.address_table_constant(_index2label);
2954 -
2955 - // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2956 - // to do that and the compiler is using that register as one it can allocate.
2957 - // So we build it all by hand.
2958 - // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant);
2959 - // ArrayAddress dispatch(table, index);
2960 -
2961 - Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant);
2962 -
2963 - masm.lea(dest_reg, InternalAddress(table_base));
2964 - masm.jmp(dispatch);
2965 - %}
2966 -
2967 - enc_class jump_enc_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
2968 - MacroAssembler masm(&cbuf);
2969 -
2970 - Register switch_reg = as_Register($switch_val$$reg);
2971 - Register dest_reg = as_Register($dest$$reg);
2972 - address table_base = masm.address_table_constant(_index2label);
2973 -
2974 - // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2975 - // to do that and the compiler is using that register as one it can allocate.
2976 - // So we build it all by hand.
2977 - // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
2978 - // ArrayAddress dispatch(table, index);
2979 -
2980 - Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant);
2981 - masm.lea(dest_reg, InternalAddress(table_base));
2982 - masm.jmp(dispatch);
2983 -
2984 - %}
2985 -
2986 2894 enc_class lock_prefix()
2987 2895 %{
2988 2896 if (os::is_MP()) {
2989 2897 emit_opcode(cbuf, 0xF0); // lock
2990 2898 }
2991 2899 %}
2992 2900
2993 2901 enc_class REX_mem(memory mem)
2994 2902 %{
2995 2903 if ($mem$$base >= 8) {
2996 2904 if ($mem$$index < 8) {
2997 2905 emit_opcode(cbuf, Assembler::REX_B);
2998 2906 } else {
2999 2907 emit_opcode(cbuf, Assembler::REX_XB);
3000 2908 }
3001 2909 } else {
3002 2910 if ($mem$$index >= 8) {
3003 2911 emit_opcode(cbuf, Assembler::REX_X);
3004 2912 }
3005 2913 }
3006 2914 %}
3007 2915
3008 2916 enc_class REX_mem_wide(memory mem)
3009 2917 %{
3010 2918 if ($mem$$base >= 8) {
3011 2919 if ($mem$$index < 8) {
3012 2920 emit_opcode(cbuf, Assembler::REX_WB);
3013 2921 } else {
3014 2922 emit_opcode(cbuf, Assembler::REX_WXB);
3015 2923 }
3016 2924 } else {
3017 2925 if ($mem$$index < 8) {
3018 2926 emit_opcode(cbuf, Assembler::REX_W);
3019 2927 } else {
3020 2928 emit_opcode(cbuf, Assembler::REX_WX);
3021 2929 }
3022 2930 }
3023 2931 %}
3024 2932
3025 2933 // for byte regs
3026 2934 enc_class REX_breg(rRegI reg)
3027 2935 %{
3028 2936 if ($reg$$reg >= 4) {
3029 2937 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B);
3030 2938 }
3031 2939 %}
3032 2940
3033 2941 // for byte regs
3034 2942 enc_class REX_reg_breg(rRegI dst, rRegI src)
3035 2943 %{
3036 2944 if ($dst$$reg < 8) {
3037 2945 if ($src$$reg >= 4) {
3038 2946 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B);
3039 2947 }
3040 2948 } else {
3041 2949 if ($src$$reg < 8) {
3042 2950 emit_opcode(cbuf, Assembler::REX_R);
3043 2951 } else {
3044 2952 emit_opcode(cbuf, Assembler::REX_RB);
3045 2953 }
3046 2954 }
3047 2955 %}
3048 2956
3049 2957 // for byte regs
3050 2958 enc_class REX_breg_mem(rRegI reg, memory mem)
3051 2959 %{
3052 2960 if ($reg$$reg < 8) {
3053 2961 if ($mem$$base < 8) {
3054 2962 if ($mem$$index >= 8) {
3055 2963 emit_opcode(cbuf, Assembler::REX_X);
3056 2964 } else if ($reg$$reg >= 4) {
3057 2965 emit_opcode(cbuf, Assembler::REX);
3058 2966 }
3059 2967 } else {
3060 2968 if ($mem$$index < 8) {
3061 2969 emit_opcode(cbuf, Assembler::REX_B);
3062 2970 } else {
3063 2971 emit_opcode(cbuf, Assembler::REX_XB);
3064 2972 }
3065 2973 }
3066 2974 } else {
3067 2975 if ($mem$$base < 8) {
3068 2976 if ($mem$$index < 8) {
3069 2977 emit_opcode(cbuf, Assembler::REX_R);
3070 2978 } else {
3071 2979 emit_opcode(cbuf, Assembler::REX_RX);
3072 2980 }
3073 2981 } else {
3074 2982 if ($mem$$index < 8) {
3075 2983 emit_opcode(cbuf, Assembler::REX_RB);
3076 2984 } else {
3077 2985 emit_opcode(cbuf, Assembler::REX_RXB);
3078 2986 }
3079 2987 }
3080 2988 }
3081 2989 %}
3082 2990
3083 2991 enc_class REX_reg(rRegI reg)
3084 2992 %{
3085 2993 if ($reg$$reg >= 8) {
3086 2994 emit_opcode(cbuf, Assembler::REX_B);
3087 2995 }
3088 2996 %}
3089 2997
3090 2998 enc_class REX_reg_wide(rRegI reg)
3091 2999 %{
3092 3000 if ($reg$$reg < 8) {
3093 3001 emit_opcode(cbuf, Assembler::REX_W);
3094 3002 } else {
3095 3003 emit_opcode(cbuf, Assembler::REX_WB);
3096 3004 }
3097 3005 %}
3098 3006
3099 3007 enc_class REX_reg_reg(rRegI dst, rRegI src)
3100 3008 %{
3101 3009 if ($dst$$reg < 8) {
3102 3010 if ($src$$reg >= 8) {
3103 3011 emit_opcode(cbuf, Assembler::REX_B);
3104 3012 }
3105 3013 } else {
3106 3014 if ($src$$reg < 8) {
3107 3015 emit_opcode(cbuf, Assembler::REX_R);
3108 3016 } else {
3109 3017 emit_opcode(cbuf, Assembler::REX_RB);
3110 3018 }
3111 3019 }
3112 3020 %}
3113 3021
3114 3022 enc_class REX_reg_reg_wide(rRegI dst, rRegI src)
3115 3023 %{
3116 3024 if ($dst$$reg < 8) {
3117 3025 if ($src$$reg < 8) {
3118 3026 emit_opcode(cbuf, Assembler::REX_W);
3119 3027 } else {
3120 3028 emit_opcode(cbuf, Assembler::REX_WB);
3121 3029 }
3122 3030 } else {
3123 3031 if ($src$$reg < 8) {
3124 3032 emit_opcode(cbuf, Assembler::REX_WR);
3125 3033 } else {
3126 3034 emit_opcode(cbuf, Assembler::REX_WRB);
3127 3035 }
3128 3036 }
3129 3037 %}
3130 3038
3131 3039 enc_class REX_reg_mem(rRegI reg, memory mem)
3132 3040 %{
3133 3041 if ($reg$$reg < 8) {
3134 3042 if ($mem$$base < 8) {
3135 3043 if ($mem$$index >= 8) {
3136 3044 emit_opcode(cbuf, Assembler::REX_X);
3137 3045 }
3138 3046 } else {
3139 3047 if ($mem$$index < 8) {
3140 3048 emit_opcode(cbuf, Assembler::REX_B);
3141 3049 } else {
3142 3050 emit_opcode(cbuf, Assembler::REX_XB);
3143 3051 }
3144 3052 }
3145 3053 } else {
3146 3054 if ($mem$$base < 8) {
3147 3055 if ($mem$$index < 8) {
3148 3056 emit_opcode(cbuf, Assembler::REX_R);
3149 3057 } else {
3150 3058 emit_opcode(cbuf, Assembler::REX_RX);
3151 3059 }
3152 3060 } else {
3153 3061 if ($mem$$index < 8) {
3154 3062 emit_opcode(cbuf, Assembler::REX_RB);
3155 3063 } else {
3156 3064 emit_opcode(cbuf, Assembler::REX_RXB);
3157 3065 }
3158 3066 }
3159 3067 }
3160 3068 %}
3161 3069
3162 3070 enc_class REX_reg_mem_wide(rRegL reg, memory mem)
3163 3071 %{
3164 3072 if ($reg$$reg < 8) {
3165 3073 if ($mem$$base < 8) {
3166 3074 if ($mem$$index < 8) {
3167 3075 emit_opcode(cbuf, Assembler::REX_W);
3168 3076 } else {
3169 3077 emit_opcode(cbuf, Assembler::REX_WX);
3170 3078 }
3171 3079 } else {
3172 3080 if ($mem$$index < 8) {
3173 3081 emit_opcode(cbuf, Assembler::REX_WB);
3174 3082 } else {
3175 3083 emit_opcode(cbuf, Assembler::REX_WXB);
3176 3084 }
3177 3085 }
3178 3086 } else {
3179 3087 if ($mem$$base < 8) {
3180 3088 if ($mem$$index < 8) {
3181 3089 emit_opcode(cbuf, Assembler::REX_WR);
3182 3090 } else {
3183 3091 emit_opcode(cbuf, Assembler::REX_WRX);
3184 3092 }
3185 3093 } else {
3186 3094 if ($mem$$index < 8) {
3187 3095 emit_opcode(cbuf, Assembler::REX_WRB);
3188 3096 } else {
3189 3097 emit_opcode(cbuf, Assembler::REX_WRXB);
3190 3098 }
3191 3099 }
3192 3100 }
3193 3101 %}
3194 3102
3195 3103 enc_class reg_mem(rRegI ereg, memory mem)
3196 3104 %{
3197 3105 // High registers handle in encode_RegMem
3198 3106 int reg = $ereg$$reg;
3199 3107 int base = $mem$$base;
3200 3108 int index = $mem$$index;
3201 3109 int scale = $mem$$scale;
3202 3110 int disp = $mem$$disp;
3203 3111 bool disp_is_oop = $mem->disp_is_oop();
3204 3112
3205 3113 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_is_oop);
3206 3114 %}
3207 3115
3208 3116 enc_class RM_opc_mem(immI rm_opcode, memory mem)
3209 3117 %{
3210 3118 int rm_byte_opcode = $rm_opcode$$constant;
3211 3119
3212 3120 // High registers handle in encode_RegMem
3213 3121 int base = $mem$$base;
3214 3122 int index = $mem$$index;
3215 3123 int scale = $mem$$scale;
3216 3124 int displace = $mem$$disp;
3217 3125
3218 3126 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when
3219 3127 // working with static
3220 3128 // globals
3221 3129 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace,
3222 3130 disp_is_oop);
3223 3131 %}
3224 3132
3225 3133 enc_class reg_lea(rRegI dst, rRegI src0, immI src1)
3226 3134 %{
3227 3135 int reg_encoding = $dst$$reg;
3228 3136 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
3229 3137 int index = 0x04; // 0x04 indicates no index
3230 3138 int scale = 0x00; // 0x00 indicates no scale
3231 3139 int displace = $src1$$constant; // 0x00 indicates no displacement
3232 3140 bool disp_is_oop = false;
3233 3141 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace,
3234 3142 disp_is_oop);
3235 3143 %}
3236 3144
3237 3145 enc_class neg_reg(rRegI dst)
3238 3146 %{
3239 3147 int dstenc = $dst$$reg;
3240 3148 if (dstenc >= 8) {
3241 3149 emit_opcode(cbuf, Assembler::REX_B);
3242 3150 dstenc -= 8;
3243 3151 }
3244 3152 // NEG $dst
3245 3153 emit_opcode(cbuf, 0xF7);
3246 3154 emit_rm(cbuf, 0x3, 0x03, dstenc);
3247 3155 %}
3248 3156
3249 3157 enc_class neg_reg_wide(rRegI dst)
3250 3158 %{
3251 3159 int dstenc = $dst$$reg;
3252 3160 if (dstenc < 8) {
3253 3161 emit_opcode(cbuf, Assembler::REX_W);
3254 3162 } else {
3255 3163 emit_opcode(cbuf, Assembler::REX_WB);
3256 3164 dstenc -= 8;
3257 3165 }
3258 3166 // NEG $dst
3259 3167 emit_opcode(cbuf, 0xF7);
3260 3168 emit_rm(cbuf, 0x3, 0x03, dstenc);
3261 3169 %}
3262 3170
3263 3171 enc_class setLT_reg(rRegI dst)
3264 3172 %{
3265 3173 int dstenc = $dst$$reg;
3266 3174 if (dstenc >= 8) {
3267 3175 emit_opcode(cbuf, Assembler::REX_B);
3268 3176 dstenc -= 8;
3269 3177 } else if (dstenc >= 4) {
3270 3178 emit_opcode(cbuf, Assembler::REX);
3271 3179 }
3272 3180 // SETLT $dst
3273 3181 emit_opcode(cbuf, 0x0F);
3274 3182 emit_opcode(cbuf, 0x9C);
3275 3183 emit_rm(cbuf, 0x3, 0x0, dstenc);
3276 3184 %}
3277 3185
3278 3186 enc_class setNZ_reg(rRegI dst)
3279 3187 %{
3280 3188 int dstenc = $dst$$reg;
3281 3189 if (dstenc >= 8) {
3282 3190 emit_opcode(cbuf, Assembler::REX_B);
3283 3191 dstenc -= 8;
3284 3192 } else if (dstenc >= 4) {
3285 3193 emit_opcode(cbuf, Assembler::REX);
3286 3194 }
3287 3195 // SETNZ $dst
3288 3196 emit_opcode(cbuf, 0x0F);
3289 3197 emit_opcode(cbuf, 0x95);
3290 3198 emit_rm(cbuf, 0x3, 0x0, dstenc);
3291 3199 %}
3292 3200
3293 3201 enc_class enc_cmpLTP(no_rcx_RegI p, no_rcx_RegI q, no_rcx_RegI y,
3294 3202 rcx_RegI tmp)
3295 3203 %{
3296 3204 // cadd_cmpLT
3297 3205
3298 3206 int tmpReg = $tmp$$reg;
3299 3207
3300 3208 int penc = $p$$reg;
3301 3209 int qenc = $q$$reg;
3302 3210 int yenc = $y$$reg;
3303 3211
3304 3212 // subl $p,$q
3305 3213 if (penc < 8) {
3306 3214 if (qenc >= 8) {
3307 3215 emit_opcode(cbuf, Assembler::REX_B);
3308 3216 }
3309 3217 } else {
3310 3218 if (qenc < 8) {
3311 3219 emit_opcode(cbuf, Assembler::REX_R);
3312 3220 } else {
3313 3221 emit_opcode(cbuf, Assembler::REX_RB);
3314 3222 }
3315 3223 }
3316 3224 emit_opcode(cbuf, 0x2B);
3317 3225 emit_rm(cbuf, 0x3, penc & 7, qenc & 7);
3318 3226
3319 3227 // sbbl $tmp, $tmp
3320 3228 emit_opcode(cbuf, 0x1B);
3321 3229 emit_rm(cbuf, 0x3, tmpReg, tmpReg);
3322 3230
3323 3231 // andl $tmp, $y
3324 3232 if (yenc >= 8) {
3325 3233 emit_opcode(cbuf, Assembler::REX_B);
3326 3234 }
3327 3235 emit_opcode(cbuf, 0x23);
3328 3236 emit_rm(cbuf, 0x3, tmpReg, yenc & 7);
3329 3237
3330 3238 // addl $p,$tmp
3331 3239 if (penc >= 8) {
3332 3240 emit_opcode(cbuf, Assembler::REX_R);
3333 3241 }
3334 3242 emit_opcode(cbuf, 0x03);
3335 3243 emit_rm(cbuf, 0x3, penc & 7, tmpReg);
3336 3244 %}
3337 3245
3338 3246 // Compare the lonogs and set -1, 0, or 1 into dst
3339 3247 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst)
3340 3248 %{
3341 3249 int src1enc = $src1$$reg;
3342 3250 int src2enc = $src2$$reg;
3343 3251 int dstenc = $dst$$reg;
3344 3252
3345 3253 // cmpq $src1, $src2
3346 3254 if (src1enc < 8) {
3347 3255 if (src2enc < 8) {
3348 3256 emit_opcode(cbuf, Assembler::REX_W);
3349 3257 } else {
3350 3258 emit_opcode(cbuf, Assembler::REX_WB);
3351 3259 }
3352 3260 } else {
3353 3261 if (src2enc < 8) {
3354 3262 emit_opcode(cbuf, Assembler::REX_WR);
3355 3263 } else {
3356 3264 emit_opcode(cbuf, Assembler::REX_WRB);
3357 3265 }
3358 3266 }
3359 3267 emit_opcode(cbuf, 0x3B);
3360 3268 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7);
3361 3269
3362 3270 // movl $dst, -1
3363 3271 if (dstenc >= 8) {
3364 3272 emit_opcode(cbuf, Assembler::REX_B);
3365 3273 }
3366 3274 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
3367 3275 emit_d32(cbuf, -1);
3368 3276
3369 3277 // jl,s done
3370 3278 emit_opcode(cbuf, 0x7C);
3371 3279 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
3372 3280
3373 3281 // setne $dst
3374 3282 if (dstenc >= 4) {
3375 3283 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
3376 3284 }
3377 3285 emit_opcode(cbuf, 0x0F);
3378 3286 emit_opcode(cbuf, 0x95);
3379 3287 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
3380 3288
3381 3289 // movzbl $dst, $dst
3382 3290 if (dstenc >= 4) {
3383 3291 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
3384 3292 }
3385 3293 emit_opcode(cbuf, 0x0F);
3386 3294 emit_opcode(cbuf, 0xB6);
3387 3295 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
3388 3296 %}
3389 3297
3390 3298 enc_class Push_ResultXD(regD dst) %{
3391 3299 int dstenc = $dst$$reg;
3392 3300
3393 3301 store_to_stackslot( cbuf, 0xDD, 0x03, 0 ); //FSTP [RSP]
3394 3302
3395 3303 // UseXmmLoadAndClearUpper ? movsd dst,[rsp] : movlpd dst,[rsp]
3396 3304 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
3397 3305 if (dstenc >= 8) {
3398 3306 emit_opcode(cbuf, Assembler::REX_R);
3399 3307 }
3400 3308 emit_opcode (cbuf, 0x0F );
3401 3309 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12 );
3402 3310 encode_RegMem(cbuf, dstenc, RSP_enc, 0x4, 0, 0, false);
3403 3311
3404 3312 // add rsp,8
3405 3313 emit_opcode(cbuf, Assembler::REX_W);
3406 3314 emit_opcode(cbuf,0x83);
3407 3315 emit_rm(cbuf,0x3, 0x0, RSP_enc);
3408 3316 emit_d8(cbuf,0x08);
3409 3317 %}
3410 3318
3411 3319 enc_class Push_SrcXD(regD src) %{
3412 3320 int srcenc = $src$$reg;
3413 3321
3414 3322 // subq rsp,#8
3415 3323 emit_opcode(cbuf, Assembler::REX_W);
3416 3324 emit_opcode(cbuf, 0x83);
3417 3325 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3418 3326 emit_d8(cbuf, 0x8);
3419 3327
3420 3328 // movsd [rsp],src
3421 3329 emit_opcode(cbuf, 0xF2);
3422 3330 if (srcenc >= 8) {
3423 3331 emit_opcode(cbuf, Assembler::REX_R);
3424 3332 }
3425 3333 emit_opcode(cbuf, 0x0F);
3426 3334 emit_opcode(cbuf, 0x11);
3427 3335 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false);
3428 3336
3429 3337 // fldd [rsp]
3430 3338 emit_opcode(cbuf, 0x66);
3431 3339 emit_opcode(cbuf, 0xDD);
3432 3340 encode_RegMem(cbuf, 0x0, RSP_enc, 0x4, 0, 0, false);
3433 3341 %}
3434 3342
3435 3343
3436 3344 enc_class movq_ld(regD dst, memory mem) %{
3437 3345 MacroAssembler _masm(&cbuf);
3438 3346 __ movq($dst$$XMMRegister, $mem$$Address);
3439 3347 %}
3440 3348
3441 3349 enc_class movq_st(memory mem, regD src) %{
3442 3350 MacroAssembler _masm(&cbuf);
3443 3351 __ movq($mem$$Address, $src$$XMMRegister);
3444 3352 %}
3445 3353
3446 3354 enc_class pshufd_8x8(regF dst, regF src) %{
3447 3355 MacroAssembler _masm(&cbuf);
3448 3356
3449 3357 encode_CopyXD(cbuf, $dst$$reg, $src$$reg);
3450 3358 __ punpcklbw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg));
3451 3359 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg), 0x00);
3452 3360 %}
3453 3361
3454 3362 enc_class pshufd_4x16(regF dst, regF src) %{
3455 3363 MacroAssembler _masm(&cbuf);
3456 3364
3457 3365 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), 0x00);
3458 3366 %}
3459 3367
3460 3368 enc_class pshufd(regD dst, regD src, int mode) %{
3461 3369 MacroAssembler _masm(&cbuf);
3462 3370
3463 3371 __ pshufd(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), $mode);
3464 3372 %}
3465 3373
3466 3374 enc_class pxor(regD dst, regD src) %{
3467 3375 MacroAssembler _masm(&cbuf);
3468 3376
3469 3377 __ pxor(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg));
3470 3378 %}
3471 3379
3472 3380 enc_class mov_i2x(regD dst, rRegI src) %{
3473 3381 MacroAssembler _masm(&cbuf);
3474 3382
3475 3383 __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg));
3476 3384 %}
3477 3385
3478 3386 // obj: object to lock
3479 3387 // box: box address (header location) -- killed
3480 3388 // tmp: rax -- killed
3481 3389 // scr: rbx -- killed
3482 3390 //
3483 3391 // What follows is a direct transliteration of fast_lock() and fast_unlock()
3484 3392 // from i486.ad. See that file for comments.
3485 3393 // TODO: where possible switch from movq (r, 0) to movl(r,0) and
3486 3394 // use the shorter encoding. (Movl clears the high-order 32-bits).
3487 3395
3488 3396
3489 3397 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr)
3490 3398 %{
3491 3399 Register objReg = as_Register((int)$obj$$reg);
3492 3400 Register boxReg = as_Register((int)$box$$reg);
3493 3401 Register tmpReg = as_Register($tmp$$reg);
3494 3402 Register scrReg = as_Register($scr$$reg);
3495 3403 MacroAssembler masm(&cbuf);
3496 3404
3497 3405 // Verify uniqueness of register assignments -- necessary but not sufficient
3498 3406 assert (objReg != boxReg && objReg != tmpReg &&
3499 3407 objReg != scrReg && tmpReg != scrReg, "invariant") ;
3500 3408
3501 3409 if (_counters != NULL) {
3502 3410 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr()));
3503 3411 }
3504 3412 if (EmitSync & 1) {
3505 3413 // Without cast to int32_t a movptr will destroy r10 which is typically obj
3506 3414 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
3507 3415 masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
3508 3416 } else
3509 3417 if (EmitSync & 2) {
3510 3418 Label DONE_LABEL;
3511 3419 if (UseBiasedLocking) {
3512 3420 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument.
3513 3421 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
3514 3422 }
3515 3423 // QQQ was movl...
3516 3424 masm.movptr(tmpReg, 0x1);
3517 3425 masm.orptr(tmpReg, Address(objReg, 0));
3518 3426 masm.movptr(Address(boxReg, 0), tmpReg);
3519 3427 if (os::is_MP()) {
3520 3428 masm.lock();
3521 3429 }
3522 3430 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
3523 3431 masm.jcc(Assembler::equal, DONE_LABEL);
3524 3432
3525 3433 // Recursive locking
3526 3434 masm.subptr(tmpReg, rsp);
3527 3435 masm.andptr(tmpReg, 7 - os::vm_page_size());
3528 3436 masm.movptr(Address(boxReg, 0), tmpReg);
3529 3437
3530 3438 masm.bind(DONE_LABEL);
3531 3439 masm.nop(); // avoid branch to branch
3532 3440 } else {
3533 3441 Label DONE_LABEL, IsInflated, Egress;
3534 3442
3535 3443 masm.movptr(tmpReg, Address(objReg, 0)) ;
3536 3444 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased
3537 3445 masm.jcc (Assembler::notZero, IsInflated) ;
3538 3446
3539 3447 // it's stack-locked, biased or neutral
3540 3448 // TODO: optimize markword triage order to reduce the number of
3541 3449 // conditional branches in the most common cases.
3542 3450 // Beware -- there's a subtle invariant that fetch of the markword
3543 3451 // at [FETCH], below, will never observe a biased encoding (*101b).
3544 3452 // If this invariant is not held we'll suffer exclusion (safety) failure.
3545 3453
3546 3454 if (UseBiasedLocking && !UseOptoBiasInlining) {
3547 3455 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
3548 3456 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH]
3549 3457 }
3550 3458
3551 3459 // was q will it destroy high?
3552 3460 masm.orl (tmpReg, 1) ;
3553 3461 masm.movptr(Address(boxReg, 0), tmpReg) ;
3554 3462 if (os::is_MP()) { masm.lock(); }
3555 3463 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
3556 3464 if (_counters != NULL) {
3557 3465 masm.cond_inc32(Assembler::equal,
3558 3466 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
3559 3467 }
3560 3468 masm.jcc (Assembler::equal, DONE_LABEL);
3561 3469
3562 3470 // Recursive locking
3563 3471 masm.subptr(tmpReg, rsp);
3564 3472 masm.andptr(tmpReg, 7 - os::vm_page_size());
3565 3473 masm.movptr(Address(boxReg, 0), tmpReg);
3566 3474 if (_counters != NULL) {
3567 3475 masm.cond_inc32(Assembler::equal,
3568 3476 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
3569 3477 }
3570 3478 masm.jmp (DONE_LABEL) ;
3571 3479
3572 3480 masm.bind (IsInflated) ;
3573 3481 // It's inflated
3574 3482
3575 3483 // TODO: someday avoid the ST-before-CAS penalty by
3576 3484 // relocating (deferring) the following ST.
3577 3485 // We should also think about trying a CAS without having
3578 3486 // fetched _owner. If the CAS is successful we may
3579 3487 // avoid an RTO->RTS upgrade on the $line.
3580 3488 // Without cast to int32_t a movptr will destroy r10 which is typically obj
3581 3489 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
3582 3490
3583 3491 masm.mov (boxReg, tmpReg) ;
3584 3492 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
3585 3493 masm.testptr(tmpReg, tmpReg) ;
3586 3494 masm.jcc (Assembler::notZero, DONE_LABEL) ;
3587 3495
3588 3496 // It's inflated and appears unlocked
3589 3497 if (os::is_MP()) { masm.lock(); }
3590 3498 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
3591 3499 // Intentional fall-through into DONE_LABEL ...
3592 3500
3593 3501 masm.bind (DONE_LABEL) ;
3594 3502 masm.nop () ; // avoid jmp to jmp
3595 3503 }
3596 3504 %}
3597 3505
3598 3506 // obj: object to unlock
3599 3507 // box: box address (displaced header location), killed
3600 3508 // RBX: killed tmp; cannot be obj nor box
3601 3509 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp)
3602 3510 %{
3603 3511
3604 3512 Register objReg = as_Register($obj$$reg);
3605 3513 Register boxReg = as_Register($box$$reg);
3606 3514 Register tmpReg = as_Register($tmp$$reg);
3607 3515 MacroAssembler masm(&cbuf);
3608 3516
3609 3517 if (EmitSync & 4) {
3610 3518 masm.cmpptr(rsp, 0) ;
3611 3519 } else
3612 3520 if (EmitSync & 8) {
3613 3521 Label DONE_LABEL;
3614 3522 if (UseBiasedLocking) {
3615 3523 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
3616 3524 }
3617 3525
3618 3526 // Check whether the displaced header is 0
3619 3527 //(=> recursive unlock)
3620 3528 masm.movptr(tmpReg, Address(boxReg, 0));
3621 3529 masm.testptr(tmpReg, tmpReg);
3622 3530 masm.jcc(Assembler::zero, DONE_LABEL);
3623 3531
3624 3532 // If not recursive lock, reset the header to displaced header
3625 3533 if (os::is_MP()) {
3626 3534 masm.lock();
3627 3535 }
3628 3536 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
3629 3537 masm.bind(DONE_LABEL);
3630 3538 masm.nop(); // avoid branch to branch
3631 3539 } else {
3632 3540 Label DONE_LABEL, Stacked, CheckSucc ;
3633 3541
3634 3542 if (UseBiasedLocking && !UseOptoBiasInlining) {
3635 3543 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
3636 3544 }
3637 3545
3638 3546 masm.movptr(tmpReg, Address(objReg, 0)) ;
3639 3547 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
3640 3548 masm.jcc (Assembler::zero, DONE_LABEL) ;
3641 3549 masm.testl (tmpReg, 0x02) ;
3642 3550 masm.jcc (Assembler::zero, Stacked) ;
3643 3551
3644 3552 // It's inflated
3645 3553 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
3646 3554 masm.xorptr(boxReg, r15_thread) ;
3647 3555 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
3648 3556 masm.jcc (Assembler::notZero, DONE_LABEL) ;
3649 3557 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
3650 3558 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
3651 3559 masm.jcc (Assembler::notZero, CheckSucc) ;
3652 3560 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3653 3561 masm.jmp (DONE_LABEL) ;
3654 3562
3655 3563 if ((EmitSync & 65536) == 0) {
3656 3564 Label LSuccess, LGoSlowPath ;
3657 3565 masm.bind (CheckSucc) ;
3658 3566 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3659 3567 masm.jcc (Assembler::zero, LGoSlowPath) ;
3660 3568
3661 3569 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the
3662 3570 // the explicit ST;MEMBAR combination, but masm doesn't currently support
3663 3571 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc
3664 3572 // are all faster when the write buffer is populated.
3665 3573 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3666 3574 if (os::is_MP()) {
3667 3575 masm.lock () ; masm.addl (Address(rsp, 0), 0) ;
3668 3576 }
3669 3577 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3670 3578 masm.jcc (Assembler::notZero, LSuccess) ;
3671 3579
3672 3580 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX
3673 3581 if (os::is_MP()) { masm.lock(); }
3674 3582 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2));
3675 3583 masm.jcc (Assembler::notEqual, LSuccess) ;
3676 3584 // Intentional fall-through into slow-path
3677 3585
3678 3586 masm.bind (LGoSlowPath) ;
3679 3587 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure
3680 3588 masm.jmp (DONE_LABEL) ;
3681 3589
3682 3590 masm.bind (LSuccess) ;
3683 3591 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success
3684 3592 masm.jmp (DONE_LABEL) ;
3685 3593 }
3686 3594
3687 3595 masm.bind (Stacked) ;
3688 3596 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch
3689 3597 if (os::is_MP()) { masm.lock(); }
3690 3598 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
3691 3599
3692 3600 if (EmitSync & 65536) {
3693 3601 masm.bind (CheckSucc) ;
3694 3602 }
3695 3603 masm.bind(DONE_LABEL);
3696 3604 if (EmitSync & 32768) {
3697 3605 masm.nop(); // avoid branch to branch
3698 3606 }
3699 3607 }
3700 3608 %}
3701 3609
3702 3610
3703 3611 enc_class enc_rethrow()
3704 3612 %{
3705 3613 cbuf.set_insts_mark();
3706 3614 emit_opcode(cbuf, 0xE9); // jmp entry
3707 3615 emit_d32_reloc(cbuf,
3708 3616 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
3709 3617 runtime_call_Relocation::spec(),
3710 3618 RELOC_DISP32);
3711 3619 %}
3712 3620
3713 3621 enc_class absF_encoding(regF dst)
3714 3622 %{
3715 3623 int dstenc = $dst$$reg;
3716 3624 address signmask_address = (address) StubRoutines::x86::float_sign_mask();
3717 3625
3718 3626 cbuf.set_insts_mark();
3719 3627 if (dstenc >= 8) {
3720 3628 emit_opcode(cbuf, Assembler::REX_R);
3721 3629 dstenc -= 8;
3722 3630 }
3723 3631 // XXX reg_mem doesn't support RIP-relative addressing yet
3724 3632 emit_opcode(cbuf, 0x0F);
3725 3633 emit_opcode(cbuf, 0x54);
3726 3634 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3727 3635 emit_d32_reloc(cbuf, signmask_address);
3728 3636 %}
3729 3637
3730 3638 enc_class absD_encoding(regD dst)
3731 3639 %{
3732 3640 int dstenc = $dst$$reg;
3733 3641 address signmask_address = (address) StubRoutines::x86::double_sign_mask();
3734 3642
3735 3643 cbuf.set_insts_mark();
3736 3644 emit_opcode(cbuf, 0x66);
3737 3645 if (dstenc >= 8) {
3738 3646 emit_opcode(cbuf, Assembler::REX_R);
3739 3647 dstenc -= 8;
3740 3648 }
3741 3649 // XXX reg_mem doesn't support RIP-relative addressing yet
3742 3650 emit_opcode(cbuf, 0x0F);
3743 3651 emit_opcode(cbuf, 0x54);
3744 3652 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3745 3653 emit_d32_reloc(cbuf, signmask_address);
3746 3654 %}
3747 3655
3748 3656 enc_class negF_encoding(regF dst)
3749 3657 %{
3750 3658 int dstenc = $dst$$reg;
3751 3659 address signflip_address = (address) StubRoutines::x86::float_sign_flip();
3752 3660
3753 3661 cbuf.set_insts_mark();
3754 3662 if (dstenc >= 8) {
3755 3663 emit_opcode(cbuf, Assembler::REX_R);
3756 3664 dstenc -= 8;
3757 3665 }
3758 3666 // XXX reg_mem doesn't support RIP-relative addressing yet
3759 3667 emit_opcode(cbuf, 0x0F);
3760 3668 emit_opcode(cbuf, 0x57);
3761 3669 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3762 3670 emit_d32_reloc(cbuf, signflip_address);
3763 3671 %}
3764 3672
3765 3673 enc_class negD_encoding(regD dst)
3766 3674 %{
3767 3675 int dstenc = $dst$$reg;
3768 3676 address signflip_address = (address) StubRoutines::x86::double_sign_flip();
3769 3677
3770 3678 cbuf.set_insts_mark();
3771 3679 emit_opcode(cbuf, 0x66);
3772 3680 if (dstenc >= 8) {
3773 3681 emit_opcode(cbuf, Assembler::REX_R);
3774 3682 dstenc -= 8;
3775 3683 }
3776 3684 // XXX reg_mem doesn't support RIP-relative addressing yet
3777 3685 emit_opcode(cbuf, 0x0F);
3778 3686 emit_opcode(cbuf, 0x57);
3779 3687 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3780 3688 emit_d32_reloc(cbuf, signflip_address);
3781 3689 %}
3782 3690
3783 3691 enc_class f2i_fixup(rRegI dst, regF src)
3784 3692 %{
3785 3693 int dstenc = $dst$$reg;
3786 3694 int srcenc = $src$$reg;
3787 3695
3788 3696 // cmpl $dst, #0x80000000
3789 3697 if (dstenc >= 8) {
3790 3698 emit_opcode(cbuf, Assembler::REX_B);
3791 3699 }
3792 3700 emit_opcode(cbuf, 0x81);
3793 3701 emit_rm(cbuf, 0x3, 0x7, dstenc & 7);
3794 3702 emit_d32(cbuf, 0x80000000);
3795 3703
3796 3704 // jne,s done
3797 3705 emit_opcode(cbuf, 0x75);
3798 3706 if (srcenc < 8 && dstenc < 8) {
3799 3707 emit_d8(cbuf, 0xF);
3800 3708 } else if (srcenc >= 8 && dstenc >= 8) {
3801 3709 emit_d8(cbuf, 0x11);
3802 3710 } else {
3803 3711 emit_d8(cbuf, 0x10);
3804 3712 }
3805 3713
3806 3714 // subq rsp, #8
3807 3715 emit_opcode(cbuf, Assembler::REX_W);
3808 3716 emit_opcode(cbuf, 0x83);
3809 3717 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3810 3718 emit_d8(cbuf, 8);
3811 3719
3812 3720 // movss [rsp], $src
3813 3721 emit_opcode(cbuf, 0xF3);
3814 3722 if (srcenc >= 8) {
3815 3723 emit_opcode(cbuf, Assembler::REX_R);
3816 3724 }
3817 3725 emit_opcode(cbuf, 0x0F);
3818 3726 emit_opcode(cbuf, 0x11);
3819 3727 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3820 3728
3821 3729 // call f2i_fixup
3822 3730 cbuf.set_insts_mark();
3823 3731 emit_opcode(cbuf, 0xE8);
3824 3732 emit_d32_reloc(cbuf,
3825 3733 (int)
3826 3734 (StubRoutines::x86::f2i_fixup() - cbuf.insts_end() - 4),
3827 3735 runtime_call_Relocation::spec(),
3828 3736 RELOC_DISP32);
3829 3737
3830 3738 // popq $dst
3831 3739 if (dstenc >= 8) {
3832 3740 emit_opcode(cbuf, Assembler::REX_B);
3833 3741 }
3834 3742 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3835 3743
3836 3744 // done:
3837 3745 %}
3838 3746
3839 3747 enc_class f2l_fixup(rRegL dst, regF src)
3840 3748 %{
3841 3749 int dstenc = $dst$$reg;
3842 3750 int srcenc = $src$$reg;
3843 3751 address const_address = (address) StubRoutines::x86::double_sign_flip();
3844 3752
3845 3753 // cmpq $dst, [0x8000000000000000]
3846 3754 cbuf.set_insts_mark();
3847 3755 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR);
3848 3756 emit_opcode(cbuf, 0x39);
3849 3757 // XXX reg_mem doesn't support RIP-relative addressing yet
3850 3758 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101
3851 3759 emit_d32_reloc(cbuf, const_address);
3852 3760
3853 3761
3854 3762 // jne,s done
3855 3763 emit_opcode(cbuf, 0x75);
3856 3764 if (srcenc < 8 && dstenc < 8) {
3857 3765 emit_d8(cbuf, 0xF);
3858 3766 } else if (srcenc >= 8 && dstenc >= 8) {
3859 3767 emit_d8(cbuf, 0x11);
3860 3768 } else {
3861 3769 emit_d8(cbuf, 0x10);
3862 3770 }
3863 3771
3864 3772 // subq rsp, #8
3865 3773 emit_opcode(cbuf, Assembler::REX_W);
3866 3774 emit_opcode(cbuf, 0x83);
3867 3775 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3868 3776 emit_d8(cbuf, 8);
3869 3777
3870 3778 // movss [rsp], $src
3871 3779 emit_opcode(cbuf, 0xF3);
3872 3780 if (srcenc >= 8) {
3873 3781 emit_opcode(cbuf, Assembler::REX_R);
3874 3782 }
3875 3783 emit_opcode(cbuf, 0x0F);
3876 3784 emit_opcode(cbuf, 0x11);
3877 3785 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3878 3786
3879 3787 // call f2l_fixup
3880 3788 cbuf.set_insts_mark();
3881 3789 emit_opcode(cbuf, 0xE8);
3882 3790 emit_d32_reloc(cbuf,
3883 3791 (int)
3884 3792 (StubRoutines::x86::f2l_fixup() - cbuf.insts_end() - 4),
3885 3793 runtime_call_Relocation::spec(),
3886 3794 RELOC_DISP32);
3887 3795
3888 3796 // popq $dst
3889 3797 if (dstenc >= 8) {
3890 3798 emit_opcode(cbuf, Assembler::REX_B);
3891 3799 }
3892 3800 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3893 3801
3894 3802 // done:
3895 3803 %}
3896 3804
3897 3805 enc_class d2i_fixup(rRegI dst, regD src)
3898 3806 %{
3899 3807 int dstenc = $dst$$reg;
3900 3808 int srcenc = $src$$reg;
3901 3809
3902 3810 // cmpl $dst, #0x80000000
3903 3811 if (dstenc >= 8) {
3904 3812 emit_opcode(cbuf, Assembler::REX_B);
3905 3813 }
3906 3814 emit_opcode(cbuf, 0x81);
3907 3815 emit_rm(cbuf, 0x3, 0x7, dstenc & 7);
3908 3816 emit_d32(cbuf, 0x80000000);
3909 3817
3910 3818 // jne,s done
3911 3819 emit_opcode(cbuf, 0x75);
3912 3820 if (srcenc < 8 && dstenc < 8) {
3913 3821 emit_d8(cbuf, 0xF);
3914 3822 } else if (srcenc >= 8 && dstenc >= 8) {
3915 3823 emit_d8(cbuf, 0x11);
3916 3824 } else {
3917 3825 emit_d8(cbuf, 0x10);
3918 3826 }
3919 3827
3920 3828 // subq rsp, #8
3921 3829 emit_opcode(cbuf, Assembler::REX_W);
3922 3830 emit_opcode(cbuf, 0x83);
3923 3831 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3924 3832 emit_d8(cbuf, 8);
3925 3833
3926 3834 // movsd [rsp], $src
3927 3835 emit_opcode(cbuf, 0xF2);
3928 3836 if (srcenc >= 8) {
3929 3837 emit_opcode(cbuf, Assembler::REX_R);
3930 3838 }
3931 3839 emit_opcode(cbuf, 0x0F);
3932 3840 emit_opcode(cbuf, 0x11);
3933 3841 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3934 3842
3935 3843 // call d2i_fixup
3936 3844 cbuf.set_insts_mark();
3937 3845 emit_opcode(cbuf, 0xE8);
3938 3846 emit_d32_reloc(cbuf,
3939 3847 (int)
3940 3848 (StubRoutines::x86::d2i_fixup() - cbuf.insts_end() - 4),
3941 3849 runtime_call_Relocation::spec(),
3942 3850 RELOC_DISP32);
3943 3851
3944 3852 // popq $dst
3945 3853 if (dstenc >= 8) {
3946 3854 emit_opcode(cbuf, Assembler::REX_B);
3947 3855 }
3948 3856 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3949 3857
3950 3858 // done:
3951 3859 %}
3952 3860
3953 3861 enc_class d2l_fixup(rRegL dst, regD src)
3954 3862 %{
3955 3863 int dstenc = $dst$$reg;
3956 3864 int srcenc = $src$$reg;
3957 3865 address const_address = (address) StubRoutines::x86::double_sign_flip();
3958 3866
3959 3867 // cmpq $dst, [0x8000000000000000]
3960 3868 cbuf.set_insts_mark();
3961 3869 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR);
3962 3870 emit_opcode(cbuf, 0x39);
3963 3871 // XXX reg_mem doesn't support RIP-relative addressing yet
3964 3872 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101
3965 3873 emit_d32_reloc(cbuf, const_address);
3966 3874
3967 3875
3968 3876 // jne,s done
3969 3877 emit_opcode(cbuf, 0x75);
3970 3878 if (srcenc < 8 && dstenc < 8) {
3971 3879 emit_d8(cbuf, 0xF);
3972 3880 } else if (srcenc >= 8 && dstenc >= 8) {
3973 3881 emit_d8(cbuf, 0x11);
3974 3882 } else {
3975 3883 emit_d8(cbuf, 0x10);
3976 3884 }
3977 3885
3978 3886 // subq rsp, #8
3979 3887 emit_opcode(cbuf, Assembler::REX_W);
3980 3888 emit_opcode(cbuf, 0x83);
3981 3889 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3982 3890 emit_d8(cbuf, 8);
3983 3891
3984 3892 // movsd [rsp], $src
3985 3893 emit_opcode(cbuf, 0xF2);
3986 3894 if (srcenc >= 8) {
3987 3895 emit_opcode(cbuf, Assembler::REX_R);
3988 3896 }
3989 3897 emit_opcode(cbuf, 0x0F);
3990 3898 emit_opcode(cbuf, 0x11);
3991 3899 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3992 3900
3993 3901 // call d2l_fixup
3994 3902 cbuf.set_insts_mark();
3995 3903 emit_opcode(cbuf, 0xE8);
3996 3904 emit_d32_reloc(cbuf,
3997 3905 (int)
3998 3906 (StubRoutines::x86::d2l_fixup() - cbuf.insts_end() - 4),
3999 3907 runtime_call_Relocation::spec(),
4000 3908 RELOC_DISP32);
4001 3909
4002 3910 // popq $dst
4003 3911 if (dstenc >= 8) {
4004 3912 emit_opcode(cbuf, Assembler::REX_B);
4005 3913 }
4006 3914 emit_opcode(cbuf, 0x58 | (dstenc & 7));
4007 3915
4008 3916 // done:
4009 3917 %}
4010 3918
4011 3919 // Safepoint Poll. This polls the safepoint page, and causes an
4012 3920 // exception if it is not readable. Unfortunately, it kills
4013 3921 // RFLAGS in the process.
4014 3922 enc_class enc_safepoint_poll
4015 3923 %{
4016 3924 // testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
4017 3925 // XXX reg_mem doesn't support RIP-relative addressing yet
4018 3926 cbuf.set_insts_mark();
4019 3927 cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0); // XXX
4020 3928 emit_opcode(cbuf, 0x85); // testl
4021 3929 emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
4022 3930 // cbuf.insts_mark() is beginning of instruction
4023 3931 emit_d32_reloc(cbuf, os::get_polling_page());
4024 3932 // relocInfo::poll_type,
4025 3933 %}
4026 3934 %}
4027 3935
4028 3936
4029 3937
4030 3938 //----------FRAME--------------------------------------------------------------
4031 3939 // Definition of frame structure and management information.
4032 3940 //
4033 3941 // S T A C K L A Y O U T Allocators stack-slot number
4034 3942 // | (to get allocators register number
4035 3943 // G Owned by | | v add OptoReg::stack0())
4036 3944 // r CALLER | |
4037 3945 // o | +--------+ pad to even-align allocators stack-slot
4038 3946 // w V | pad0 | numbers; owned by CALLER
4039 3947 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
4040 3948 // h ^ | in | 5
4041 3949 // | | args | 4 Holes in incoming args owned by SELF
4042 3950 // | | | | 3
4043 3951 // | | +--------+
4044 3952 // V | | old out| Empty on Intel, window on Sparc
4045 3953 // | old |preserve| Must be even aligned.
4046 3954 // | SP-+--------+----> Matcher::_old_SP, even aligned
4047 3955 // | | in | 3 area for Intel ret address
4048 3956 // Owned by |preserve| Empty on Sparc.
4049 3957 // SELF +--------+
4050 3958 // | | pad2 | 2 pad to align old SP
4051 3959 // | +--------+ 1
4052 3960 // | | locks | 0
4053 3961 // | +--------+----> OptoReg::stack0(), even aligned
4054 3962 // | | pad1 | 11 pad to align new SP
4055 3963 // | +--------+
4056 3964 // | | | 10
4057 3965 // | | spills | 9 spills
4058 3966 // V | | 8 (pad0 slot for callee)
4059 3967 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
4060 3968 // ^ | out | 7
4061 3969 // | | args | 6 Holes in outgoing args owned by CALLEE
4062 3970 // Owned by +--------+
4063 3971 // CALLEE | new out| 6 Empty on Intel, window on Sparc
4064 3972 // | new |preserve| Must be even-aligned.
4065 3973 // | SP-+--------+----> Matcher::_new_SP, even aligned
4066 3974 // | | |
4067 3975 //
4068 3976 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
4069 3977 // known from SELF's arguments and the Java calling convention.
4070 3978 // Region 6-7 is determined per call site.
4071 3979 // Note 2: If the calling convention leaves holes in the incoming argument
4072 3980 // area, those holes are owned by SELF. Holes in the outgoing area
4073 3981 // are owned by the CALLEE. Holes should not be nessecary in the
4074 3982 // incoming area, as the Java calling convention is completely under
4075 3983 // the control of the AD file. Doubles can be sorted and packed to
4076 3984 // avoid holes. Holes in the outgoing arguments may be nessecary for
4077 3985 // varargs C calling conventions.
4078 3986 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
4079 3987 // even aligned with pad0 as needed.
4080 3988 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
4081 3989 // region 6-11 is even aligned; it may be padded out more so that
4082 3990 // the region from SP to FP meets the minimum stack alignment.
4083 3991 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
4084 3992 // alignment. Region 11, pad1, may be dynamically extended so that
4085 3993 // SP meets the minimum alignment.
4086 3994
4087 3995 frame
4088 3996 %{
4089 3997 // What direction does stack grow in (assumed to be same for C & Java)
4090 3998 stack_direction(TOWARDS_LOW);
4091 3999
4092 4000 // These three registers define part of the calling convention
4093 4001 // between compiled code and the interpreter.
4094 4002 inline_cache_reg(RAX); // Inline Cache Register
4095 4003 interpreter_method_oop_reg(RBX); // Method Oop Register when
4096 4004 // calling interpreter
4097 4005
4098 4006 // Optional: name the operand used by cisc-spilling to access
4099 4007 // [stack_pointer + offset]
4100 4008 cisc_spilling_operand_name(indOffset32);
4101 4009
4102 4010 // Number of stack slots consumed by locking an object
4103 4011 sync_stack_slots(2);
4104 4012
4105 4013 // Compiled code's Frame Pointer
4106 4014 frame_pointer(RSP);
4107 4015
4108 4016 // Interpreter stores its frame pointer in a register which is
4109 4017 // stored to the stack by I2CAdaptors.
4110 4018 // I2CAdaptors convert from interpreted java to compiled java.
4111 4019 interpreter_frame_pointer(RBP);
4112 4020
4113 4021 // Stack alignment requirement
4114 4022 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
4115 4023
4116 4024 // Number of stack slots between incoming argument block and the start of
4117 4025 // a new frame. The PROLOG must add this many slots to the stack. The
4118 4026 // EPILOG must remove this many slots. amd64 needs two slots for
4119 4027 // return address.
4120 4028 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls);
4121 4029
4122 4030 // Number of outgoing stack slots killed above the out_preserve_stack_slots
4123 4031 // for calls to C. Supports the var-args backing area for register parms.
4124 4032 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
4125 4033
4126 4034 // The after-PROLOG location of the return address. Location of
4127 4035 // return address specifies a type (REG or STACK) and a number
4128 4036 // representing the register number (i.e. - use a register name) or
4129 4037 // stack slot.
4130 4038 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
4131 4039 // Otherwise, it is above the locks and verification slot and alignment word
4132 4040 return_addr(STACK - 2 +
4133 4041 round_to(2 + 2 * VerifyStackAtCalls +
4134 4042 Compile::current()->fixed_slots(),
4135 4043 WordsPerLong * 2));
4136 4044
4137 4045 // Body of function which returns an integer array locating
4138 4046 // arguments either in registers or in stack slots. Passed an array
4139 4047 // of ideal registers called "sig" and a "length" count. Stack-slot
4140 4048 // offsets are based on outgoing arguments, i.e. a CALLER setting up
4141 4049 // arguments for a CALLEE. Incoming stack arguments are
4142 4050 // automatically biased by the preserve_stack_slots field above.
4143 4051
4144 4052 calling_convention
4145 4053 %{
4146 4054 // No difference between ingoing/outgoing just pass false
4147 4055 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
4148 4056 %}
4149 4057
4150 4058 c_calling_convention
4151 4059 %{
4152 4060 // This is obviously always outgoing
4153 4061 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length);
4154 4062 %}
4155 4063
4156 4064 // Location of compiled Java return values. Same as C for now.
4157 4065 return_value
4158 4066 %{
4159 4067 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
4160 4068 "only return normal values");
4161 4069
4162 4070 static const int lo[Op_RegL + 1] = {
4163 4071 0,
4164 4072 0,
4165 4073 RAX_num, // Op_RegN
4166 4074 RAX_num, // Op_RegI
4167 4075 RAX_num, // Op_RegP
4168 4076 XMM0_num, // Op_RegF
4169 4077 XMM0_num, // Op_RegD
4170 4078 RAX_num // Op_RegL
4171 4079 };
4172 4080 static const int hi[Op_RegL + 1] = {
4173 4081 0,
4174 4082 0,
4175 4083 OptoReg::Bad, // Op_RegN
4176 4084 OptoReg::Bad, // Op_RegI
4177 4085 RAX_H_num, // Op_RegP
4178 4086 OptoReg::Bad, // Op_RegF
4179 4087 XMM0_H_num, // Op_RegD
4180 4088 RAX_H_num // Op_RegL
4181 4089 };
4182 4090 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type");
4183 4091 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
4184 4092 %}
4185 4093 %}
4186 4094
4187 4095 //----------ATTRIBUTES---------------------------------------------------------
4188 4096 //----------Operand Attributes-------------------------------------------------
4189 4097 op_attrib op_cost(0); // Required cost attribute
4190 4098
4191 4099 //----------Instruction Attributes---------------------------------------------
4192 4100 ins_attrib ins_cost(100); // Required cost attribute
4193 4101 ins_attrib ins_size(8); // Required size attribute (in bits)
4194 4102 ins_attrib ins_pc_relative(0); // Required PC Relative flag
4195 4103 ins_attrib ins_short_branch(0); // Required flag: is this instruction
4196 4104 // a non-matching short branch variant
4197 4105 // of some long branch?
4198 4106 ins_attrib ins_alignment(1); // Required alignment attribute (must
4199 4107 // be a power of 2) specifies the
4200 4108 // alignment that some part of the
4201 4109 // instruction (not necessarily the
4202 4110 // start) requires. If > 1, a
4203 4111 // compute_padding() function must be
4204 4112 // provided for the instruction
4205 4113
4206 4114 //----------OPERANDS-----------------------------------------------------------
4207 4115 // Operand definitions must precede instruction definitions for correct parsing
4208 4116 // in the ADLC because operands constitute user defined types which are used in
4209 4117 // instruction definitions.
4210 4118
4211 4119 //----------Simple Operands----------------------------------------------------
4212 4120 // Immediate Operands
4213 4121 // Integer Immediate
4214 4122 operand immI()
4215 4123 %{
4216 4124 match(ConI);
4217 4125
4218 4126 op_cost(10);
4219 4127 format %{ %}
4220 4128 interface(CONST_INTER);
4221 4129 %}
4222 4130
4223 4131 // Constant for test vs zero
4224 4132 operand immI0()
4225 4133 %{
4226 4134 predicate(n->get_int() == 0);
4227 4135 match(ConI);
4228 4136
4229 4137 op_cost(0);
4230 4138 format %{ %}
4231 4139 interface(CONST_INTER);
4232 4140 %}
4233 4141
4234 4142 // Constant for increment
4235 4143 operand immI1()
4236 4144 %{
4237 4145 predicate(n->get_int() == 1);
4238 4146 match(ConI);
4239 4147
4240 4148 op_cost(0);
4241 4149 format %{ %}
4242 4150 interface(CONST_INTER);
4243 4151 %}
4244 4152
4245 4153 // Constant for decrement
4246 4154 operand immI_M1()
4247 4155 %{
4248 4156 predicate(n->get_int() == -1);
4249 4157 match(ConI);
4250 4158
4251 4159 op_cost(0);
4252 4160 format %{ %}
4253 4161 interface(CONST_INTER);
4254 4162 %}
4255 4163
4256 4164 // Valid scale values for addressing modes
4257 4165 operand immI2()
4258 4166 %{
4259 4167 predicate(0 <= n->get_int() && (n->get_int() <= 3));
4260 4168 match(ConI);
4261 4169
4262 4170 format %{ %}
4263 4171 interface(CONST_INTER);
4264 4172 %}
4265 4173
4266 4174 operand immI8()
4267 4175 %{
4268 4176 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80));
4269 4177 match(ConI);
4270 4178
4271 4179 op_cost(5);
4272 4180 format %{ %}
4273 4181 interface(CONST_INTER);
4274 4182 %}
4275 4183
4276 4184 operand immI16()
4277 4185 %{
4278 4186 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
4279 4187 match(ConI);
4280 4188
4281 4189 op_cost(10);
4282 4190 format %{ %}
4283 4191 interface(CONST_INTER);
4284 4192 %}
4285 4193
4286 4194 // Constant for long shifts
4287 4195 operand immI_32()
4288 4196 %{
4289 4197 predicate( n->get_int() == 32 );
4290 4198 match(ConI);
4291 4199
4292 4200 op_cost(0);
4293 4201 format %{ %}
4294 4202 interface(CONST_INTER);
4295 4203 %}
4296 4204
4297 4205 // Constant for long shifts
4298 4206 operand immI_64()
4299 4207 %{
4300 4208 predicate( n->get_int() == 64 );
4301 4209 match(ConI);
4302 4210
4303 4211 op_cost(0);
4304 4212 format %{ %}
4305 4213 interface(CONST_INTER);
4306 4214 %}
4307 4215
4308 4216 // Pointer Immediate
4309 4217 operand immP()
4310 4218 %{
4311 4219 match(ConP);
4312 4220
4313 4221 op_cost(10);
4314 4222 format %{ %}
4315 4223 interface(CONST_INTER);
4316 4224 %}
4317 4225
4318 4226 // NULL Pointer Immediate
4319 4227 operand immP0()
4320 4228 %{
4321 4229 predicate(n->get_ptr() == 0);
4322 4230 match(ConP);
4323 4231
4324 4232 op_cost(5);
4325 4233 format %{ %}
4326 4234 interface(CONST_INTER);
4327 4235 %}
4328 4236
4329 4237 // Pointer Immediate
4330 4238 operand immN() %{
4331 4239 match(ConN);
4332 4240
4333 4241 op_cost(10);
4334 4242 format %{ %}
4335 4243 interface(CONST_INTER);
4336 4244 %}
4337 4245
4338 4246 // NULL Pointer Immediate
4339 4247 operand immN0() %{
4340 4248 predicate(n->get_narrowcon() == 0);
4341 4249 match(ConN);
4342 4250
4343 4251 op_cost(5);
4344 4252 format %{ %}
4345 4253 interface(CONST_INTER);
4346 4254 %}
4347 4255
4348 4256 operand immP31()
4349 4257 %{
4350 4258 predicate(!n->as_Type()->type()->isa_oopptr()
4351 4259 && (n->get_ptr() >> 31) == 0);
4352 4260 match(ConP);
4353 4261
4354 4262 op_cost(5);
4355 4263 format %{ %}
4356 4264 interface(CONST_INTER);
4357 4265 %}
4358 4266
4359 4267
4360 4268 // Long Immediate
4361 4269 operand immL()
4362 4270 %{
4363 4271 match(ConL);
4364 4272
4365 4273 op_cost(20);
4366 4274 format %{ %}
4367 4275 interface(CONST_INTER);
4368 4276 %}
4369 4277
4370 4278 // Long Immediate 8-bit
4371 4279 operand immL8()
4372 4280 %{
4373 4281 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
4374 4282 match(ConL);
4375 4283
4376 4284 op_cost(5);
4377 4285 format %{ %}
4378 4286 interface(CONST_INTER);
4379 4287 %}
4380 4288
4381 4289 // Long Immediate 32-bit unsigned
4382 4290 operand immUL32()
4383 4291 %{
4384 4292 predicate(n->get_long() == (unsigned int) (n->get_long()));
4385 4293 match(ConL);
4386 4294
4387 4295 op_cost(10);
4388 4296 format %{ %}
4389 4297 interface(CONST_INTER);
4390 4298 %}
4391 4299
4392 4300 // Long Immediate 32-bit signed
4393 4301 operand immL32()
4394 4302 %{
4395 4303 predicate(n->get_long() == (int) (n->get_long()));
4396 4304 match(ConL);
4397 4305
4398 4306 op_cost(15);
4399 4307 format %{ %}
4400 4308 interface(CONST_INTER);
4401 4309 %}
4402 4310
4403 4311 // Long Immediate zero
4404 4312 operand immL0()
4405 4313 %{
4406 4314 predicate(n->get_long() == 0L);
4407 4315 match(ConL);
4408 4316
4409 4317 op_cost(10);
4410 4318 format %{ %}
4411 4319 interface(CONST_INTER);
4412 4320 %}
4413 4321
4414 4322 // Constant for increment
4415 4323 operand immL1()
4416 4324 %{
4417 4325 predicate(n->get_long() == 1);
4418 4326 match(ConL);
4419 4327
4420 4328 format %{ %}
4421 4329 interface(CONST_INTER);
4422 4330 %}
4423 4331
4424 4332 // Constant for decrement
4425 4333 operand immL_M1()
4426 4334 %{
4427 4335 predicate(n->get_long() == -1);
4428 4336 match(ConL);
4429 4337
4430 4338 format %{ %}
4431 4339 interface(CONST_INTER);
4432 4340 %}
4433 4341
4434 4342 // Long Immediate: the value 10
4435 4343 operand immL10()
4436 4344 %{
4437 4345 predicate(n->get_long() == 10);
4438 4346 match(ConL);
4439 4347
4440 4348 format %{ %}
4441 4349 interface(CONST_INTER);
4442 4350 %}
4443 4351
4444 4352 // Long immediate from 0 to 127.
4445 4353 // Used for a shorter form of long mul by 10.
4446 4354 operand immL_127()
4447 4355 %{
4448 4356 predicate(0 <= n->get_long() && n->get_long() < 0x80);
4449 4357 match(ConL);
4450 4358
4451 4359 op_cost(10);
4452 4360 format %{ %}
4453 4361 interface(CONST_INTER);
4454 4362 %}
4455 4363
4456 4364 // Long Immediate: low 32-bit mask
4457 4365 operand immL_32bits()
4458 4366 %{
4459 4367 predicate(n->get_long() == 0xFFFFFFFFL);
4460 4368 match(ConL);
4461 4369 op_cost(20);
4462 4370
4463 4371 format %{ %}
4464 4372 interface(CONST_INTER);
4465 4373 %}
4466 4374
4467 4375 // Float Immediate zero
4468 4376 operand immF0()
4469 4377 %{
4470 4378 predicate(jint_cast(n->getf()) == 0);
4471 4379 match(ConF);
4472 4380
4473 4381 op_cost(5);
4474 4382 format %{ %}
4475 4383 interface(CONST_INTER);
4476 4384 %}
4477 4385
4478 4386 // Float Immediate
4479 4387 operand immF()
4480 4388 %{
4481 4389 match(ConF);
4482 4390
4483 4391 op_cost(15);
4484 4392 format %{ %}
4485 4393 interface(CONST_INTER);
4486 4394 %}
4487 4395
4488 4396 // Double Immediate zero
4489 4397 operand immD0()
4490 4398 %{
4491 4399 predicate(jlong_cast(n->getd()) == 0);
4492 4400 match(ConD);
4493 4401
4494 4402 op_cost(5);
4495 4403 format %{ %}
4496 4404 interface(CONST_INTER);
4497 4405 %}
4498 4406
4499 4407 // Double Immediate
4500 4408 operand immD()
4501 4409 %{
4502 4410 match(ConD);
4503 4411
4504 4412 op_cost(15);
4505 4413 format %{ %}
4506 4414 interface(CONST_INTER);
4507 4415 %}
4508 4416
4509 4417 // Immediates for special shifts (sign extend)
4510 4418
4511 4419 // Constants for increment
4512 4420 operand immI_16()
4513 4421 %{
4514 4422 predicate(n->get_int() == 16);
4515 4423 match(ConI);
4516 4424
4517 4425 format %{ %}
4518 4426 interface(CONST_INTER);
4519 4427 %}
4520 4428
4521 4429 operand immI_24()
4522 4430 %{
4523 4431 predicate(n->get_int() == 24);
4524 4432 match(ConI);
4525 4433
4526 4434 format %{ %}
4527 4435 interface(CONST_INTER);
4528 4436 %}
4529 4437
4530 4438 // Constant for byte-wide masking
4531 4439 operand immI_255()
4532 4440 %{
4533 4441 predicate(n->get_int() == 255);
4534 4442 match(ConI);
4535 4443
4536 4444 format %{ %}
4537 4445 interface(CONST_INTER);
4538 4446 %}
4539 4447
4540 4448 // Constant for short-wide masking
4541 4449 operand immI_65535()
4542 4450 %{
4543 4451 predicate(n->get_int() == 65535);
4544 4452 match(ConI);
4545 4453
4546 4454 format %{ %}
4547 4455 interface(CONST_INTER);
4548 4456 %}
4549 4457
4550 4458 // Constant for byte-wide masking
4551 4459 operand immL_255()
4552 4460 %{
4553 4461 predicate(n->get_long() == 255);
4554 4462 match(ConL);
4555 4463
4556 4464 format %{ %}
4557 4465 interface(CONST_INTER);
4558 4466 %}
4559 4467
4560 4468 // Constant for short-wide masking
4561 4469 operand immL_65535()
4562 4470 %{
4563 4471 predicate(n->get_long() == 65535);
4564 4472 match(ConL);
4565 4473
4566 4474 format %{ %}
4567 4475 interface(CONST_INTER);
4568 4476 %}
4569 4477
4570 4478 // Register Operands
4571 4479 // Integer Register
4572 4480 operand rRegI()
4573 4481 %{
4574 4482 constraint(ALLOC_IN_RC(int_reg));
4575 4483 match(RegI);
4576 4484
4577 4485 match(rax_RegI);
4578 4486 match(rbx_RegI);
4579 4487 match(rcx_RegI);
4580 4488 match(rdx_RegI);
4581 4489 match(rdi_RegI);
4582 4490
4583 4491 format %{ %}
4584 4492 interface(REG_INTER);
4585 4493 %}
4586 4494
4587 4495 // Special Registers
4588 4496 operand rax_RegI()
4589 4497 %{
4590 4498 constraint(ALLOC_IN_RC(int_rax_reg));
4591 4499 match(RegI);
4592 4500 match(rRegI);
4593 4501
4594 4502 format %{ "RAX" %}
4595 4503 interface(REG_INTER);
4596 4504 %}
4597 4505
4598 4506 // Special Registers
4599 4507 operand rbx_RegI()
4600 4508 %{
4601 4509 constraint(ALLOC_IN_RC(int_rbx_reg));
4602 4510 match(RegI);
4603 4511 match(rRegI);
4604 4512
4605 4513 format %{ "RBX" %}
4606 4514 interface(REG_INTER);
4607 4515 %}
4608 4516
4609 4517 operand rcx_RegI()
4610 4518 %{
4611 4519 constraint(ALLOC_IN_RC(int_rcx_reg));
4612 4520 match(RegI);
4613 4521 match(rRegI);
4614 4522
4615 4523 format %{ "RCX" %}
4616 4524 interface(REG_INTER);
4617 4525 %}
4618 4526
4619 4527 operand rdx_RegI()
4620 4528 %{
4621 4529 constraint(ALLOC_IN_RC(int_rdx_reg));
4622 4530 match(RegI);
4623 4531 match(rRegI);
4624 4532
4625 4533 format %{ "RDX" %}
4626 4534 interface(REG_INTER);
4627 4535 %}
4628 4536
4629 4537 operand rdi_RegI()
4630 4538 %{
4631 4539 constraint(ALLOC_IN_RC(int_rdi_reg));
4632 4540 match(RegI);
4633 4541 match(rRegI);
4634 4542
4635 4543 format %{ "RDI" %}
4636 4544 interface(REG_INTER);
4637 4545 %}
4638 4546
4639 4547 operand no_rcx_RegI()
4640 4548 %{
4641 4549 constraint(ALLOC_IN_RC(int_no_rcx_reg));
4642 4550 match(RegI);
4643 4551 match(rax_RegI);
4644 4552 match(rbx_RegI);
4645 4553 match(rdx_RegI);
4646 4554 match(rdi_RegI);
4647 4555
4648 4556 format %{ %}
4649 4557 interface(REG_INTER);
4650 4558 %}
4651 4559
4652 4560 operand no_rax_rdx_RegI()
4653 4561 %{
4654 4562 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg));
4655 4563 match(RegI);
4656 4564 match(rbx_RegI);
4657 4565 match(rcx_RegI);
4658 4566 match(rdi_RegI);
4659 4567
4660 4568 format %{ %}
4661 4569 interface(REG_INTER);
4662 4570 %}
4663 4571
4664 4572 // Pointer Register
4665 4573 operand any_RegP()
4666 4574 %{
4667 4575 constraint(ALLOC_IN_RC(any_reg));
4668 4576 match(RegP);
4669 4577 match(rax_RegP);
4670 4578 match(rbx_RegP);
4671 4579 match(rdi_RegP);
4672 4580 match(rsi_RegP);
4673 4581 match(rbp_RegP);
4674 4582 match(r15_RegP);
4675 4583 match(rRegP);
4676 4584
4677 4585 format %{ %}
4678 4586 interface(REG_INTER);
4679 4587 %}
4680 4588
4681 4589 operand rRegP()
4682 4590 %{
4683 4591 constraint(ALLOC_IN_RC(ptr_reg));
4684 4592 match(RegP);
4685 4593 match(rax_RegP);
4686 4594 match(rbx_RegP);
4687 4595 match(rdi_RegP);
4688 4596 match(rsi_RegP);
4689 4597 match(rbp_RegP);
4690 4598 match(r15_RegP); // See Q&A below about r15_RegP.
4691 4599
4692 4600 format %{ %}
4693 4601 interface(REG_INTER);
4694 4602 %}
4695 4603
4696 4604 operand rRegN() %{
4697 4605 constraint(ALLOC_IN_RC(int_reg));
4698 4606 match(RegN);
4699 4607
4700 4608 format %{ %}
4701 4609 interface(REG_INTER);
4702 4610 %}
4703 4611
4704 4612 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
4705 4613 // Answer: Operand match rules govern the DFA as it processes instruction inputs.
4706 4614 // It's fine for an instruction input which expects rRegP to match a r15_RegP.
4707 4615 // The output of an instruction is controlled by the allocator, which respects
4708 4616 // register class masks, not match rules. Unless an instruction mentions
4709 4617 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered
4710 4618 // by the allocator as an input.
4711 4619
4712 4620 operand no_rax_RegP()
4713 4621 %{
4714 4622 constraint(ALLOC_IN_RC(ptr_no_rax_reg));
4715 4623 match(RegP);
4716 4624 match(rbx_RegP);
4717 4625 match(rsi_RegP);
4718 4626 match(rdi_RegP);
4719 4627
4720 4628 format %{ %}
4721 4629 interface(REG_INTER);
4722 4630 %}
4723 4631
4724 4632 operand no_rbp_RegP()
4725 4633 %{
4726 4634 constraint(ALLOC_IN_RC(ptr_no_rbp_reg));
4727 4635 match(RegP);
4728 4636 match(rbx_RegP);
4729 4637 match(rsi_RegP);
4730 4638 match(rdi_RegP);
4731 4639
4732 4640 format %{ %}
4733 4641 interface(REG_INTER);
4734 4642 %}
4735 4643
4736 4644 operand no_rax_rbx_RegP()
4737 4645 %{
4738 4646 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg));
4739 4647 match(RegP);
4740 4648 match(rsi_RegP);
4741 4649 match(rdi_RegP);
4742 4650
4743 4651 format %{ %}
4744 4652 interface(REG_INTER);
4745 4653 %}
4746 4654
4747 4655 // Special Registers
4748 4656 // Return a pointer value
4749 4657 operand rax_RegP()
4750 4658 %{
4751 4659 constraint(ALLOC_IN_RC(ptr_rax_reg));
4752 4660 match(RegP);
4753 4661 match(rRegP);
4754 4662
4755 4663 format %{ %}
4756 4664 interface(REG_INTER);
4757 4665 %}
4758 4666
4759 4667 // Special Registers
4760 4668 // Return a compressed pointer value
4761 4669 operand rax_RegN()
4762 4670 %{
4763 4671 constraint(ALLOC_IN_RC(int_rax_reg));
4764 4672 match(RegN);
4765 4673 match(rRegN);
4766 4674
4767 4675 format %{ %}
4768 4676 interface(REG_INTER);
4769 4677 %}
4770 4678
4771 4679 // Used in AtomicAdd
4772 4680 operand rbx_RegP()
4773 4681 %{
4774 4682 constraint(ALLOC_IN_RC(ptr_rbx_reg));
4775 4683 match(RegP);
4776 4684 match(rRegP);
4777 4685
4778 4686 format %{ %}
4779 4687 interface(REG_INTER);
4780 4688 %}
4781 4689
4782 4690 operand rsi_RegP()
4783 4691 %{
4784 4692 constraint(ALLOC_IN_RC(ptr_rsi_reg));
4785 4693 match(RegP);
4786 4694 match(rRegP);
4787 4695
4788 4696 format %{ %}
4789 4697 interface(REG_INTER);
4790 4698 %}
4791 4699
4792 4700 // Used in rep stosq
4793 4701 operand rdi_RegP()
4794 4702 %{
4795 4703 constraint(ALLOC_IN_RC(ptr_rdi_reg));
4796 4704 match(RegP);
4797 4705 match(rRegP);
4798 4706
4799 4707 format %{ %}
4800 4708 interface(REG_INTER);
4801 4709 %}
4802 4710
4803 4711 operand rbp_RegP()
4804 4712 %{
4805 4713 constraint(ALLOC_IN_RC(ptr_rbp_reg));
4806 4714 match(RegP);
4807 4715 match(rRegP);
4808 4716
4809 4717 format %{ %}
4810 4718 interface(REG_INTER);
4811 4719 %}
4812 4720
4813 4721 operand r15_RegP()
4814 4722 %{
4815 4723 constraint(ALLOC_IN_RC(ptr_r15_reg));
4816 4724 match(RegP);
4817 4725 match(rRegP);
4818 4726
4819 4727 format %{ %}
4820 4728 interface(REG_INTER);
4821 4729 %}
4822 4730
4823 4731 operand rRegL()
4824 4732 %{
4825 4733 constraint(ALLOC_IN_RC(long_reg));
4826 4734 match(RegL);
4827 4735 match(rax_RegL);
4828 4736 match(rdx_RegL);
4829 4737
4830 4738 format %{ %}
4831 4739 interface(REG_INTER);
4832 4740 %}
4833 4741
4834 4742 // Special Registers
4835 4743 operand no_rax_rdx_RegL()
4836 4744 %{
4837 4745 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
4838 4746 match(RegL);
4839 4747 match(rRegL);
4840 4748
4841 4749 format %{ %}
4842 4750 interface(REG_INTER);
4843 4751 %}
4844 4752
4845 4753 operand no_rax_RegL()
4846 4754 %{
4847 4755 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
4848 4756 match(RegL);
4849 4757 match(rRegL);
4850 4758 match(rdx_RegL);
4851 4759
4852 4760 format %{ %}
4853 4761 interface(REG_INTER);
4854 4762 %}
4855 4763
4856 4764 operand no_rcx_RegL()
4857 4765 %{
4858 4766 constraint(ALLOC_IN_RC(long_no_rcx_reg));
4859 4767 match(RegL);
4860 4768 match(rRegL);
4861 4769
4862 4770 format %{ %}
4863 4771 interface(REG_INTER);
4864 4772 %}
4865 4773
4866 4774 operand rax_RegL()
4867 4775 %{
4868 4776 constraint(ALLOC_IN_RC(long_rax_reg));
4869 4777 match(RegL);
4870 4778 match(rRegL);
4871 4779
4872 4780 format %{ "RAX" %}
4873 4781 interface(REG_INTER);
4874 4782 %}
4875 4783
4876 4784 operand rcx_RegL()
4877 4785 %{
4878 4786 constraint(ALLOC_IN_RC(long_rcx_reg));
4879 4787 match(RegL);
4880 4788 match(rRegL);
4881 4789
4882 4790 format %{ %}
4883 4791 interface(REG_INTER);
4884 4792 %}
4885 4793
4886 4794 operand rdx_RegL()
4887 4795 %{
4888 4796 constraint(ALLOC_IN_RC(long_rdx_reg));
4889 4797 match(RegL);
4890 4798 match(rRegL);
4891 4799
4892 4800 format %{ %}
4893 4801 interface(REG_INTER);
4894 4802 %}
4895 4803
4896 4804 // Flags register, used as output of compare instructions
4897 4805 operand rFlagsReg()
4898 4806 %{
4899 4807 constraint(ALLOC_IN_RC(int_flags));
4900 4808 match(RegFlags);
4901 4809
4902 4810 format %{ "RFLAGS" %}
4903 4811 interface(REG_INTER);
4904 4812 %}
4905 4813
4906 4814 // Flags register, used as output of FLOATING POINT compare instructions
4907 4815 operand rFlagsRegU()
4908 4816 %{
4909 4817 constraint(ALLOC_IN_RC(int_flags));
4910 4818 match(RegFlags);
4911 4819
4912 4820 format %{ "RFLAGS_U" %}
4913 4821 interface(REG_INTER);
4914 4822 %}
4915 4823
4916 4824 operand rFlagsRegUCF() %{
4917 4825 constraint(ALLOC_IN_RC(int_flags));
4918 4826 match(RegFlags);
4919 4827 predicate(false);
4920 4828
4921 4829 format %{ "RFLAGS_U_CF" %}
4922 4830 interface(REG_INTER);
4923 4831 %}
4924 4832
4925 4833 // Float register operands
4926 4834 operand regF()
4927 4835 %{
4928 4836 constraint(ALLOC_IN_RC(float_reg));
4929 4837 match(RegF);
4930 4838
4931 4839 format %{ %}
4932 4840 interface(REG_INTER);
4933 4841 %}
4934 4842
4935 4843 // Double register operands
4936 4844 operand regD()
4937 4845 %{
4938 4846 constraint(ALLOC_IN_RC(double_reg));
4939 4847 match(RegD);
4940 4848
4941 4849 format %{ %}
4942 4850 interface(REG_INTER);
4943 4851 %}
4944 4852
4945 4853
4946 4854 //----------Memory Operands----------------------------------------------------
4947 4855 // Direct Memory Operand
4948 4856 // operand direct(immP addr)
4949 4857 // %{
4950 4858 // match(addr);
4951 4859
4952 4860 // format %{ "[$addr]" %}
4953 4861 // interface(MEMORY_INTER) %{
4954 4862 // base(0xFFFFFFFF);
4955 4863 // index(0x4);
4956 4864 // scale(0x0);
4957 4865 // disp($addr);
4958 4866 // %}
4959 4867 // %}
4960 4868
4961 4869 // Indirect Memory Operand
4962 4870 operand indirect(any_RegP reg)
4963 4871 %{
4964 4872 constraint(ALLOC_IN_RC(ptr_reg));
4965 4873 match(reg);
4966 4874
4967 4875 format %{ "[$reg]" %}
4968 4876 interface(MEMORY_INTER) %{
4969 4877 base($reg);
4970 4878 index(0x4);
4971 4879 scale(0x0);
4972 4880 disp(0x0);
4973 4881 %}
4974 4882 %}
4975 4883
4976 4884 // Indirect Memory Plus Short Offset Operand
4977 4885 operand indOffset8(any_RegP reg, immL8 off)
4978 4886 %{
4979 4887 constraint(ALLOC_IN_RC(ptr_reg));
4980 4888 match(AddP reg off);
4981 4889
4982 4890 format %{ "[$reg + $off (8-bit)]" %}
4983 4891 interface(MEMORY_INTER) %{
4984 4892 base($reg);
4985 4893 index(0x4);
4986 4894 scale(0x0);
4987 4895 disp($off);
4988 4896 %}
4989 4897 %}
4990 4898
4991 4899 // Indirect Memory Plus Long Offset Operand
4992 4900 operand indOffset32(any_RegP reg, immL32 off)
4993 4901 %{
4994 4902 constraint(ALLOC_IN_RC(ptr_reg));
4995 4903 match(AddP reg off);
4996 4904
4997 4905 format %{ "[$reg + $off (32-bit)]" %}
4998 4906 interface(MEMORY_INTER) %{
4999 4907 base($reg);
5000 4908 index(0x4);
5001 4909 scale(0x0);
5002 4910 disp($off);
5003 4911 %}
5004 4912 %}
5005 4913
5006 4914 // Indirect Memory Plus Index Register Plus Offset Operand
5007 4915 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off)
5008 4916 %{
5009 4917 constraint(ALLOC_IN_RC(ptr_reg));
5010 4918 match(AddP (AddP reg lreg) off);
5011 4919
5012 4920 op_cost(10);
5013 4921 format %{"[$reg + $off + $lreg]" %}
5014 4922 interface(MEMORY_INTER) %{
5015 4923 base($reg);
5016 4924 index($lreg);
5017 4925 scale(0x0);
5018 4926 disp($off);
5019 4927 %}
5020 4928 %}
5021 4929
5022 4930 // Indirect Memory Plus Index Register Plus Offset Operand
5023 4931 operand indIndex(any_RegP reg, rRegL lreg)
5024 4932 %{
5025 4933 constraint(ALLOC_IN_RC(ptr_reg));
5026 4934 match(AddP reg lreg);
5027 4935
5028 4936 op_cost(10);
5029 4937 format %{"[$reg + $lreg]" %}
5030 4938 interface(MEMORY_INTER) %{
5031 4939 base($reg);
5032 4940 index($lreg);
5033 4941 scale(0x0);
5034 4942 disp(0x0);
5035 4943 %}
5036 4944 %}
5037 4945
5038 4946 // Indirect Memory Times Scale Plus Index Register
5039 4947 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale)
5040 4948 %{
5041 4949 constraint(ALLOC_IN_RC(ptr_reg));
5042 4950 match(AddP reg (LShiftL lreg scale));
5043 4951
5044 4952 op_cost(10);
5045 4953 format %{"[$reg + $lreg << $scale]" %}
5046 4954 interface(MEMORY_INTER) %{
5047 4955 base($reg);
5048 4956 index($lreg);
5049 4957 scale($scale);
5050 4958 disp(0x0);
5051 4959 %}
5052 4960 %}
5053 4961
5054 4962 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5055 4963 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
5056 4964 %{
5057 4965 constraint(ALLOC_IN_RC(ptr_reg));
5058 4966 match(AddP (AddP reg (LShiftL lreg scale)) off);
5059 4967
5060 4968 op_cost(10);
5061 4969 format %{"[$reg + $off + $lreg << $scale]" %}
5062 4970 interface(MEMORY_INTER) %{
5063 4971 base($reg);
5064 4972 index($lreg);
5065 4973 scale($scale);
5066 4974 disp($off);
5067 4975 %}
5068 4976 %}
5069 4977
5070 4978 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
5071 4979 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale)
5072 4980 %{
5073 4981 constraint(ALLOC_IN_RC(ptr_reg));
5074 4982 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5075 4983 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off);
5076 4984
5077 4985 op_cost(10);
5078 4986 format %{"[$reg + $off + $idx << $scale]" %}
5079 4987 interface(MEMORY_INTER) %{
5080 4988 base($reg);
5081 4989 index($idx);
5082 4990 scale($scale);
5083 4991 disp($off);
5084 4992 %}
5085 4993 %}
5086 4994
5087 4995 // Indirect Narrow Oop Plus Offset Operand
5088 4996 // Note: x86 architecture doesn't support "scale * index + offset" without a base
5089 4997 // we can't free r12 even with Universe::narrow_oop_base() == NULL.
5090 4998 operand indCompressedOopOffset(rRegN reg, immL32 off) %{
5091 4999 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8));
5092 5000 constraint(ALLOC_IN_RC(ptr_reg));
5093 5001 match(AddP (DecodeN reg) off);
5094 5002
5095 5003 op_cost(10);
5096 5004 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
5097 5005 interface(MEMORY_INTER) %{
5098 5006 base(0xc); // R12
5099 5007 index($reg);
5100 5008 scale(0x3);
5101 5009 disp($off);
5102 5010 %}
5103 5011 %}
5104 5012
5105 5013 // Indirect Memory Operand
5106 5014 operand indirectNarrow(rRegN reg)
5107 5015 %{
5108 5016 predicate(Universe::narrow_oop_shift() == 0);
5109 5017 constraint(ALLOC_IN_RC(ptr_reg));
5110 5018 match(DecodeN reg);
5111 5019
5112 5020 format %{ "[$reg]" %}
5113 5021 interface(MEMORY_INTER) %{
5114 5022 base($reg);
5115 5023 index(0x4);
5116 5024 scale(0x0);
5117 5025 disp(0x0);
5118 5026 %}
5119 5027 %}
5120 5028
5121 5029 // Indirect Memory Plus Short Offset Operand
5122 5030 operand indOffset8Narrow(rRegN reg, immL8 off)
5123 5031 %{
5124 5032 predicate(Universe::narrow_oop_shift() == 0);
5125 5033 constraint(ALLOC_IN_RC(ptr_reg));
5126 5034 match(AddP (DecodeN reg) off);
5127 5035
5128 5036 format %{ "[$reg + $off (8-bit)]" %}
5129 5037 interface(MEMORY_INTER) %{
5130 5038 base($reg);
5131 5039 index(0x4);
5132 5040 scale(0x0);
5133 5041 disp($off);
5134 5042 %}
5135 5043 %}
5136 5044
5137 5045 // Indirect Memory Plus Long Offset Operand
5138 5046 operand indOffset32Narrow(rRegN reg, immL32 off)
5139 5047 %{
5140 5048 predicate(Universe::narrow_oop_shift() == 0);
5141 5049 constraint(ALLOC_IN_RC(ptr_reg));
5142 5050 match(AddP (DecodeN reg) off);
5143 5051
5144 5052 format %{ "[$reg + $off (32-bit)]" %}
5145 5053 interface(MEMORY_INTER) %{
5146 5054 base($reg);
5147 5055 index(0x4);
5148 5056 scale(0x0);
5149 5057 disp($off);
5150 5058 %}
5151 5059 %}
5152 5060
5153 5061 // Indirect Memory Plus Index Register Plus Offset Operand
5154 5062 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off)
5155 5063 %{
5156 5064 predicate(Universe::narrow_oop_shift() == 0);
5157 5065 constraint(ALLOC_IN_RC(ptr_reg));
5158 5066 match(AddP (AddP (DecodeN reg) lreg) off);
5159 5067
5160 5068 op_cost(10);
5161 5069 format %{"[$reg + $off + $lreg]" %}
5162 5070 interface(MEMORY_INTER) %{
5163 5071 base($reg);
5164 5072 index($lreg);
5165 5073 scale(0x0);
5166 5074 disp($off);
5167 5075 %}
5168 5076 %}
5169 5077
5170 5078 // Indirect Memory Plus Index Register Plus Offset Operand
5171 5079 operand indIndexNarrow(rRegN reg, rRegL lreg)
5172 5080 %{
5173 5081 predicate(Universe::narrow_oop_shift() == 0);
5174 5082 constraint(ALLOC_IN_RC(ptr_reg));
5175 5083 match(AddP (DecodeN reg) lreg);
5176 5084
5177 5085 op_cost(10);
5178 5086 format %{"[$reg + $lreg]" %}
5179 5087 interface(MEMORY_INTER) %{
5180 5088 base($reg);
5181 5089 index($lreg);
5182 5090 scale(0x0);
5183 5091 disp(0x0);
5184 5092 %}
5185 5093 %}
5186 5094
5187 5095 // Indirect Memory Times Scale Plus Index Register
5188 5096 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale)
5189 5097 %{
5190 5098 predicate(Universe::narrow_oop_shift() == 0);
5191 5099 constraint(ALLOC_IN_RC(ptr_reg));
5192 5100 match(AddP (DecodeN reg) (LShiftL lreg scale));
5193 5101
5194 5102 op_cost(10);
5195 5103 format %{"[$reg + $lreg << $scale]" %}
5196 5104 interface(MEMORY_INTER) %{
5197 5105 base($reg);
5198 5106 index($lreg);
5199 5107 scale($scale);
5200 5108 disp(0x0);
5201 5109 %}
5202 5110 %}
5203 5111
5204 5112 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5205 5113 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
5206 5114 %{
5207 5115 predicate(Universe::narrow_oop_shift() == 0);
5208 5116 constraint(ALLOC_IN_RC(ptr_reg));
5209 5117 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
5210 5118
5211 5119 op_cost(10);
5212 5120 format %{"[$reg + $off + $lreg << $scale]" %}
5213 5121 interface(MEMORY_INTER) %{
5214 5122 base($reg);
5215 5123 index($lreg);
5216 5124 scale($scale);
5217 5125 disp($off);
5218 5126 %}
5219 5127 %}
5220 5128
5221 5129 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
5222 5130 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
5223 5131 %{
5224 5132 constraint(ALLOC_IN_RC(ptr_reg));
5225 5133 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5226 5134 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
5227 5135
5228 5136 op_cost(10);
5229 5137 format %{"[$reg + $off + $idx << $scale]" %}
5230 5138 interface(MEMORY_INTER) %{
5231 5139 base($reg);
5232 5140 index($idx);
5233 5141 scale($scale);
5234 5142 disp($off);
5235 5143 %}
5236 5144 %}
5237 5145
5238 5146
5239 5147 //----------Special Memory Operands--------------------------------------------
5240 5148 // Stack Slot Operand - This operand is used for loading and storing temporary
5241 5149 // values on the stack where a match requires a value to
5242 5150 // flow through memory.
5243 5151 operand stackSlotP(sRegP reg)
5244 5152 %{
5245 5153 constraint(ALLOC_IN_RC(stack_slots));
5246 5154 // No match rule because this operand is only generated in matching
5247 5155
5248 5156 format %{ "[$reg]" %}
5249 5157 interface(MEMORY_INTER) %{
5250 5158 base(0x4); // RSP
5251 5159 index(0x4); // No Index
5252 5160 scale(0x0); // No Scale
5253 5161 disp($reg); // Stack Offset
5254 5162 %}
5255 5163 %}
5256 5164
5257 5165 operand stackSlotI(sRegI reg)
5258 5166 %{
5259 5167 constraint(ALLOC_IN_RC(stack_slots));
5260 5168 // No match rule because this operand is only generated in matching
5261 5169
5262 5170 format %{ "[$reg]" %}
5263 5171 interface(MEMORY_INTER) %{
5264 5172 base(0x4); // RSP
5265 5173 index(0x4); // No Index
5266 5174 scale(0x0); // No Scale
5267 5175 disp($reg); // Stack Offset
5268 5176 %}
5269 5177 %}
5270 5178
5271 5179 operand stackSlotF(sRegF reg)
5272 5180 %{
5273 5181 constraint(ALLOC_IN_RC(stack_slots));
5274 5182 // No match rule because this operand is only generated in matching
5275 5183
5276 5184 format %{ "[$reg]" %}
5277 5185 interface(MEMORY_INTER) %{
5278 5186 base(0x4); // RSP
5279 5187 index(0x4); // No Index
5280 5188 scale(0x0); // No Scale
5281 5189 disp($reg); // Stack Offset
5282 5190 %}
5283 5191 %}
5284 5192
5285 5193 operand stackSlotD(sRegD reg)
5286 5194 %{
5287 5195 constraint(ALLOC_IN_RC(stack_slots));
5288 5196 // No match rule because this operand is only generated in matching
5289 5197
5290 5198 format %{ "[$reg]" %}
5291 5199 interface(MEMORY_INTER) %{
5292 5200 base(0x4); // RSP
5293 5201 index(0x4); // No Index
5294 5202 scale(0x0); // No Scale
5295 5203 disp($reg); // Stack Offset
5296 5204 %}
5297 5205 %}
5298 5206 operand stackSlotL(sRegL reg)
5299 5207 %{
5300 5208 constraint(ALLOC_IN_RC(stack_slots));
5301 5209 // No match rule because this operand is only generated in matching
5302 5210
5303 5211 format %{ "[$reg]" %}
5304 5212 interface(MEMORY_INTER) %{
5305 5213 base(0x4); // RSP
5306 5214 index(0x4); // No Index
5307 5215 scale(0x0); // No Scale
5308 5216 disp($reg); // Stack Offset
5309 5217 %}
5310 5218 %}
5311 5219
5312 5220 //----------Conditional Branch Operands----------------------------------------
5313 5221 // Comparison Op - This is the operation of the comparison, and is limited to
5314 5222 // the following set of codes:
5315 5223 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5316 5224 //
5317 5225 // Other attributes of the comparison, such as unsignedness, are specified
5318 5226 // by the comparison instruction that sets a condition code flags register.
5319 5227 // That result is represented by a flags operand whose subtype is appropriate
5320 5228 // to the unsignedness (etc.) of the comparison.
5321 5229 //
5322 5230 // Later, the instruction which matches both the Comparison Op (a Bool) and
5323 5231 // the flags (produced by the Cmp) specifies the coding of the comparison op
5324 5232 // by matching a specific subtype of Bool operand below, such as cmpOpU.
5325 5233
5326 5234 // Comparision Code
5327 5235 operand cmpOp()
5328 5236 %{
5329 5237 match(Bool);
5330 5238
5331 5239 format %{ "" %}
5332 5240 interface(COND_INTER) %{
5333 5241 equal(0x4, "e");
5334 5242 not_equal(0x5, "ne");
5335 5243 less(0xC, "l");
5336 5244 greater_equal(0xD, "ge");
5337 5245 less_equal(0xE, "le");
5338 5246 greater(0xF, "g");
5339 5247 %}
5340 5248 %}
5341 5249
5342 5250 // Comparison Code, unsigned compare. Used by FP also, with
5343 5251 // C2 (unordered) turned into GT or LT already. The other bits
5344 5252 // C0 and C3 are turned into Carry & Zero flags.
5345 5253 operand cmpOpU()
5346 5254 %{
5347 5255 match(Bool);
5348 5256
5349 5257 format %{ "" %}
5350 5258 interface(COND_INTER) %{
5351 5259 equal(0x4, "e");
5352 5260 not_equal(0x5, "ne");
5353 5261 less(0x2, "b");
5354 5262 greater_equal(0x3, "nb");
5355 5263 less_equal(0x6, "be");
5356 5264 greater(0x7, "nbe");
5357 5265 %}
5358 5266 %}
5359 5267
5360 5268
5361 5269 // Floating comparisons that don't require any fixup for the unordered case
5362 5270 operand cmpOpUCF() %{
5363 5271 match(Bool);
5364 5272 predicate(n->as_Bool()->_test._test == BoolTest::lt ||
5365 5273 n->as_Bool()->_test._test == BoolTest::ge ||
5366 5274 n->as_Bool()->_test._test == BoolTest::le ||
5367 5275 n->as_Bool()->_test._test == BoolTest::gt);
5368 5276 format %{ "" %}
5369 5277 interface(COND_INTER) %{
5370 5278 equal(0x4, "e");
5371 5279 not_equal(0x5, "ne");
5372 5280 less(0x2, "b");
5373 5281 greater_equal(0x3, "nb");
5374 5282 less_equal(0x6, "be");
5375 5283 greater(0x7, "nbe");
5376 5284 %}
5377 5285 %}
5378 5286
5379 5287
5380 5288 // Floating comparisons that can be fixed up with extra conditional jumps
5381 5289 operand cmpOpUCF2() %{
5382 5290 match(Bool);
5383 5291 predicate(n->as_Bool()->_test._test == BoolTest::ne ||
5384 5292 n->as_Bool()->_test._test == BoolTest::eq);
5385 5293 format %{ "" %}
5386 5294 interface(COND_INTER) %{
5387 5295 equal(0x4, "e");
5388 5296 not_equal(0x5, "ne");
5389 5297 less(0x2, "b");
5390 5298 greater_equal(0x3, "nb");
5391 5299 less_equal(0x6, "be");
5392 5300 greater(0x7, "nbe");
5393 5301 %}
5394 5302 %}
5395 5303
5396 5304
5397 5305 //----------OPERAND CLASSES----------------------------------------------------
5398 5306 // Operand Classes are groups of operands that are used as to simplify
5399 5307 // instruction definitions by not requiring the AD writer to specify separate
5400 5308 // instructions for every form of operand when the instruction accepts
5401 5309 // multiple operand types with the same basic encoding and format. The classic
5402 5310 // case of this is memory operands.
5403 5311
5404 5312 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
5405 5313 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
5406 5314 indCompressedOopOffset,
5407 5315 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
5408 5316 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
5409 5317 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow);
5410 5318
5411 5319 //----------PIPELINE-----------------------------------------------------------
5412 5320 // Rules which define the behavior of the target architectures pipeline.
5413 5321 pipeline %{
5414 5322
5415 5323 //----------ATTRIBUTES---------------------------------------------------------
5416 5324 attributes %{
5417 5325 variable_size_instructions; // Fixed size instructions
5418 5326 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
5419 5327 instruction_unit_size = 1; // An instruction is 1 bytes long
5420 5328 instruction_fetch_unit_size = 16; // The processor fetches one line
5421 5329 instruction_fetch_units = 1; // of 16 bytes
5422 5330
5423 5331 // List of nop instructions
5424 5332 nops( MachNop );
5425 5333 %}
5426 5334
5427 5335 //----------RESOURCES----------------------------------------------------------
5428 5336 // Resources are the functional units available to the machine
5429 5337
5430 5338 // Generic P2/P3 pipeline
5431 5339 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of
5432 5340 // 3 instructions decoded per cycle.
5433 5341 // 2 load/store ops per cycle, 1 branch, 1 FPU,
5434 5342 // 3 ALU op, only ALU0 handles mul instructions.
5435 5343 resources( D0, D1, D2, DECODE = D0 | D1 | D2,
5436 5344 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2,
5437 5345 BR, FPU,
5438 5346 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2);
5439 5347
5440 5348 //----------PIPELINE DESCRIPTION-----------------------------------------------
5441 5349 // Pipeline Description specifies the stages in the machine's pipeline
5442 5350
5443 5351 // Generic P2/P3 pipeline
5444 5352 pipe_desc(S0, S1, S2, S3, S4, S5);
5445 5353
5446 5354 //----------PIPELINE CLASSES---------------------------------------------------
5447 5355 // Pipeline Classes describe the stages in which input and output are
5448 5356 // referenced by the hardware pipeline.
5449 5357
5450 5358 // Naming convention: ialu or fpu
5451 5359 // Then: _reg
5452 5360 // Then: _reg if there is a 2nd register
5453 5361 // Then: _long if it's a pair of instructions implementing a long
5454 5362 // Then: _fat if it requires the big decoder
5455 5363 // Or: _mem if it requires the big decoder and a memory unit.
5456 5364
5457 5365 // Integer ALU reg operation
5458 5366 pipe_class ialu_reg(rRegI dst)
5459 5367 %{
5460 5368 single_instruction;
5461 5369 dst : S4(write);
5462 5370 dst : S3(read);
5463 5371 DECODE : S0; // any decoder
5464 5372 ALU : S3; // any alu
5465 5373 %}
5466 5374
5467 5375 // Long ALU reg operation
5468 5376 pipe_class ialu_reg_long(rRegL dst)
5469 5377 %{
5470 5378 instruction_count(2);
5471 5379 dst : S4(write);
5472 5380 dst : S3(read);
5473 5381 DECODE : S0(2); // any 2 decoders
5474 5382 ALU : S3(2); // both alus
5475 5383 %}
5476 5384
5477 5385 // Integer ALU reg operation using big decoder
5478 5386 pipe_class ialu_reg_fat(rRegI dst)
5479 5387 %{
5480 5388 single_instruction;
5481 5389 dst : S4(write);
5482 5390 dst : S3(read);
5483 5391 D0 : S0; // big decoder only
5484 5392 ALU : S3; // any alu
5485 5393 %}
5486 5394
5487 5395 // Long ALU reg operation using big decoder
5488 5396 pipe_class ialu_reg_long_fat(rRegL dst)
5489 5397 %{
5490 5398 instruction_count(2);
5491 5399 dst : S4(write);
5492 5400 dst : S3(read);
5493 5401 D0 : S0(2); // big decoder only; twice
5494 5402 ALU : S3(2); // any 2 alus
5495 5403 %}
5496 5404
5497 5405 // Integer ALU reg-reg operation
5498 5406 pipe_class ialu_reg_reg(rRegI dst, rRegI src)
5499 5407 %{
5500 5408 single_instruction;
5501 5409 dst : S4(write);
5502 5410 src : S3(read);
5503 5411 DECODE : S0; // any decoder
5504 5412 ALU : S3; // any alu
5505 5413 %}
5506 5414
5507 5415 // Long ALU reg-reg operation
5508 5416 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src)
5509 5417 %{
5510 5418 instruction_count(2);
5511 5419 dst : S4(write);
5512 5420 src : S3(read);
5513 5421 DECODE : S0(2); // any 2 decoders
5514 5422 ALU : S3(2); // both alus
5515 5423 %}
5516 5424
5517 5425 // Integer ALU reg-reg operation
5518 5426 pipe_class ialu_reg_reg_fat(rRegI dst, memory src)
5519 5427 %{
5520 5428 single_instruction;
5521 5429 dst : S4(write);
5522 5430 src : S3(read);
5523 5431 D0 : S0; // big decoder only
5524 5432 ALU : S3; // any alu
5525 5433 %}
5526 5434
5527 5435 // Long ALU reg-reg operation
5528 5436 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src)
5529 5437 %{
5530 5438 instruction_count(2);
5531 5439 dst : S4(write);
5532 5440 src : S3(read);
5533 5441 D0 : S0(2); // big decoder only; twice
5534 5442 ALU : S3(2); // both alus
5535 5443 %}
5536 5444
5537 5445 // Integer ALU reg-mem operation
5538 5446 pipe_class ialu_reg_mem(rRegI dst, memory mem)
5539 5447 %{
5540 5448 single_instruction;
5541 5449 dst : S5(write);
5542 5450 mem : S3(read);
5543 5451 D0 : S0; // big decoder only
5544 5452 ALU : S4; // any alu
5545 5453 MEM : S3; // any mem
5546 5454 %}
5547 5455
5548 5456 // Integer mem operation (prefetch)
5549 5457 pipe_class ialu_mem(memory mem)
5550 5458 %{
5551 5459 single_instruction;
5552 5460 mem : S3(read);
5553 5461 D0 : S0; // big decoder only
5554 5462 MEM : S3; // any mem
5555 5463 %}
5556 5464
5557 5465 // Integer Store to Memory
5558 5466 pipe_class ialu_mem_reg(memory mem, rRegI src)
5559 5467 %{
5560 5468 single_instruction;
5561 5469 mem : S3(read);
5562 5470 src : S5(read);
5563 5471 D0 : S0; // big decoder only
5564 5472 ALU : S4; // any alu
5565 5473 MEM : S3;
5566 5474 %}
5567 5475
5568 5476 // // Long Store to Memory
5569 5477 // pipe_class ialu_mem_long_reg(memory mem, rRegL src)
5570 5478 // %{
5571 5479 // instruction_count(2);
5572 5480 // mem : S3(read);
5573 5481 // src : S5(read);
5574 5482 // D0 : S0(2); // big decoder only; twice
5575 5483 // ALU : S4(2); // any 2 alus
5576 5484 // MEM : S3(2); // Both mems
5577 5485 // %}
5578 5486
5579 5487 // Integer Store to Memory
5580 5488 pipe_class ialu_mem_imm(memory mem)
5581 5489 %{
5582 5490 single_instruction;
5583 5491 mem : S3(read);
5584 5492 D0 : S0; // big decoder only
5585 5493 ALU : S4; // any alu
5586 5494 MEM : S3;
5587 5495 %}
5588 5496
5589 5497 // Integer ALU0 reg-reg operation
5590 5498 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src)
5591 5499 %{
5592 5500 single_instruction;
5593 5501 dst : S4(write);
5594 5502 src : S3(read);
5595 5503 D0 : S0; // Big decoder only
5596 5504 ALU0 : S3; // only alu0
5597 5505 %}
5598 5506
5599 5507 // Integer ALU0 reg-mem operation
5600 5508 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem)
5601 5509 %{
5602 5510 single_instruction;
5603 5511 dst : S5(write);
5604 5512 mem : S3(read);
5605 5513 D0 : S0; // big decoder only
5606 5514 ALU0 : S4; // ALU0 only
5607 5515 MEM : S3; // any mem
5608 5516 %}
5609 5517
5610 5518 // Integer ALU reg-reg operation
5611 5519 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2)
5612 5520 %{
5613 5521 single_instruction;
5614 5522 cr : S4(write);
5615 5523 src1 : S3(read);
5616 5524 src2 : S3(read);
5617 5525 DECODE : S0; // any decoder
5618 5526 ALU : S3; // any alu
5619 5527 %}
5620 5528
5621 5529 // Integer ALU reg-imm operation
5622 5530 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1)
5623 5531 %{
5624 5532 single_instruction;
5625 5533 cr : S4(write);
5626 5534 src1 : S3(read);
5627 5535 DECODE : S0; // any decoder
5628 5536 ALU : S3; // any alu
5629 5537 %}
5630 5538
5631 5539 // Integer ALU reg-mem operation
5632 5540 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2)
5633 5541 %{
5634 5542 single_instruction;
5635 5543 cr : S4(write);
5636 5544 src1 : S3(read);
5637 5545 src2 : S3(read);
5638 5546 D0 : S0; // big decoder only
5639 5547 ALU : S4; // any alu
5640 5548 MEM : S3;
5641 5549 %}
5642 5550
5643 5551 // Conditional move reg-reg
5644 5552 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y)
5645 5553 %{
5646 5554 instruction_count(4);
5647 5555 y : S4(read);
5648 5556 q : S3(read);
5649 5557 p : S3(read);
5650 5558 DECODE : S0(4); // any decoder
5651 5559 %}
5652 5560
5653 5561 // Conditional move reg-reg
5654 5562 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr)
5655 5563 %{
5656 5564 single_instruction;
5657 5565 dst : S4(write);
5658 5566 src : S3(read);
5659 5567 cr : S3(read);
5660 5568 DECODE : S0; // any decoder
5661 5569 %}
5662 5570
5663 5571 // Conditional move reg-mem
5664 5572 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src)
5665 5573 %{
5666 5574 single_instruction;
5667 5575 dst : S4(write);
5668 5576 src : S3(read);
5669 5577 cr : S3(read);
5670 5578 DECODE : S0; // any decoder
5671 5579 MEM : S3;
5672 5580 %}
5673 5581
5674 5582 // Conditional move reg-reg long
5675 5583 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src)
5676 5584 %{
5677 5585 single_instruction;
5678 5586 dst : S4(write);
5679 5587 src : S3(read);
5680 5588 cr : S3(read);
5681 5589 DECODE : S0(2); // any 2 decoders
5682 5590 %}
5683 5591
5684 5592 // XXX
5685 5593 // // Conditional move double reg-reg
5686 5594 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src)
5687 5595 // %{
5688 5596 // single_instruction;
5689 5597 // dst : S4(write);
5690 5598 // src : S3(read);
5691 5599 // cr : S3(read);
5692 5600 // DECODE : S0; // any decoder
5693 5601 // %}
5694 5602
5695 5603 // Float reg-reg operation
5696 5604 pipe_class fpu_reg(regD dst)
5697 5605 %{
5698 5606 instruction_count(2);
5699 5607 dst : S3(read);
5700 5608 DECODE : S0(2); // any 2 decoders
5701 5609 FPU : S3;
5702 5610 %}
5703 5611
5704 5612 // Float reg-reg operation
5705 5613 pipe_class fpu_reg_reg(regD dst, regD src)
5706 5614 %{
5707 5615 instruction_count(2);
5708 5616 dst : S4(write);
5709 5617 src : S3(read);
5710 5618 DECODE : S0(2); // any 2 decoders
5711 5619 FPU : S3;
5712 5620 %}
5713 5621
5714 5622 // Float reg-reg operation
5715 5623 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2)
5716 5624 %{
5717 5625 instruction_count(3);
5718 5626 dst : S4(write);
5719 5627 src1 : S3(read);
5720 5628 src2 : S3(read);
5721 5629 DECODE : S0(3); // any 3 decoders
5722 5630 FPU : S3(2);
5723 5631 %}
5724 5632
5725 5633 // Float reg-reg operation
5726 5634 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3)
5727 5635 %{
5728 5636 instruction_count(4);
5729 5637 dst : S4(write);
5730 5638 src1 : S3(read);
5731 5639 src2 : S3(read);
5732 5640 src3 : S3(read);
5733 5641 DECODE : S0(4); // any 3 decoders
5734 5642 FPU : S3(2);
5735 5643 %}
5736 5644
5737 5645 // Float reg-reg operation
5738 5646 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3)
5739 5647 %{
5740 5648 instruction_count(4);
5741 5649 dst : S4(write);
5742 5650 src1 : S3(read);
5743 5651 src2 : S3(read);
5744 5652 src3 : S3(read);
5745 5653 DECODE : S1(3); // any 3 decoders
5746 5654 D0 : S0; // Big decoder only
5747 5655 FPU : S3(2);
5748 5656 MEM : S3;
5749 5657 %}
5750 5658
5751 5659 // Float reg-mem operation
5752 5660 pipe_class fpu_reg_mem(regD dst, memory mem)
5753 5661 %{
5754 5662 instruction_count(2);
5755 5663 dst : S5(write);
5756 5664 mem : S3(read);
5757 5665 D0 : S0; // big decoder only
5758 5666 DECODE : S1; // any decoder for FPU POP
5759 5667 FPU : S4;
5760 5668 MEM : S3; // any mem
5761 5669 %}
5762 5670
5763 5671 // Float reg-mem operation
5764 5672 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem)
5765 5673 %{
5766 5674 instruction_count(3);
5767 5675 dst : S5(write);
5768 5676 src1 : S3(read);
5769 5677 mem : S3(read);
5770 5678 D0 : S0; // big decoder only
5771 5679 DECODE : S1(2); // any decoder for FPU POP
5772 5680 FPU : S4;
5773 5681 MEM : S3; // any mem
5774 5682 %}
5775 5683
5776 5684 // Float mem-reg operation
5777 5685 pipe_class fpu_mem_reg(memory mem, regD src)
5778 5686 %{
5779 5687 instruction_count(2);
5780 5688 src : S5(read);
5781 5689 mem : S3(read);
5782 5690 DECODE : S0; // any decoder for FPU PUSH
5783 5691 D0 : S1; // big decoder only
5784 5692 FPU : S4;
5785 5693 MEM : S3; // any mem
5786 5694 %}
5787 5695
5788 5696 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2)
5789 5697 %{
5790 5698 instruction_count(3);
5791 5699 src1 : S3(read);
5792 5700 src2 : S3(read);
5793 5701 mem : S3(read);
5794 5702 DECODE : S0(2); // any decoder for FPU PUSH
5795 5703 D0 : S1; // big decoder only
5796 5704 FPU : S4;
5797 5705 MEM : S3; // any mem
5798 5706 %}
5799 5707
5800 5708 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2)
5801 5709 %{
5802 5710 instruction_count(3);
5803 5711 src1 : S3(read);
5804 5712 src2 : S3(read);
5805 5713 mem : S4(read);
5806 5714 DECODE : S0; // any decoder for FPU PUSH
5807 5715 D0 : S0(2); // big decoder only
5808 5716 FPU : S4;
5809 5717 MEM : S3(2); // any mem
5810 5718 %}
5811 5719
5812 5720 pipe_class fpu_mem_mem(memory dst, memory src1)
5813 5721 %{
5814 5722 instruction_count(2);
5815 5723 src1 : S3(read);
5816 5724 dst : S4(read);
5817 5725 D0 : S0(2); // big decoder only
5818 5726 MEM : S3(2); // any mem
5819 5727 %}
5820 5728
5821 5729 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2)
5822 5730 %{
5823 5731 instruction_count(3);
5824 5732 src1 : S3(read);
5825 5733 src2 : S3(read);
5826 5734 dst : S4(read);
5827 5735 D0 : S0(3); // big decoder only
5828 5736 FPU : S4;
5829 5737 MEM : S3(3); // any mem
5830 5738 %}
5831 5739
5832 5740 pipe_class fpu_mem_reg_con(memory mem, regD src1)
5833 5741 %{
5834 5742 instruction_count(3);
5835 5743 src1 : S4(read);
5836 5744 mem : S4(read);
5837 5745 DECODE : S0; // any decoder for FPU PUSH
5838 5746 D0 : S0(2); // big decoder only
5839 5747 FPU : S4;
5840 5748 MEM : S3(2); // any mem
5841 5749 %}
5842 5750
5843 5751 // Float load constant
5844 5752 pipe_class fpu_reg_con(regD dst)
5845 5753 %{
5846 5754 instruction_count(2);
5847 5755 dst : S5(write);
5848 5756 D0 : S0; // big decoder only for the load
5849 5757 DECODE : S1; // any decoder for FPU POP
5850 5758 FPU : S4;
5851 5759 MEM : S3; // any mem
5852 5760 %}
5853 5761
5854 5762 // Float load constant
5855 5763 pipe_class fpu_reg_reg_con(regD dst, regD src)
5856 5764 %{
5857 5765 instruction_count(3);
5858 5766 dst : S5(write);
5859 5767 src : S3(read);
5860 5768 D0 : S0; // big decoder only for the load
5861 5769 DECODE : S1(2); // any decoder for FPU POP
5862 5770 FPU : S4;
5863 5771 MEM : S3; // any mem
5864 5772 %}
5865 5773
5866 5774 // UnConditional branch
5867 5775 pipe_class pipe_jmp(label labl)
5868 5776 %{
5869 5777 single_instruction;
5870 5778 BR : S3;
5871 5779 %}
5872 5780
5873 5781 // Conditional branch
5874 5782 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl)
5875 5783 %{
5876 5784 single_instruction;
5877 5785 cr : S1(read);
5878 5786 BR : S3;
5879 5787 %}
5880 5788
5881 5789 // Allocation idiom
5882 5790 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr)
5883 5791 %{
5884 5792 instruction_count(1); force_serialization;
5885 5793 fixed_latency(6);
5886 5794 heap_ptr : S3(read);
5887 5795 DECODE : S0(3);
5888 5796 D0 : S2;
5889 5797 MEM : S3;
5890 5798 ALU : S3(2);
5891 5799 dst : S5(write);
5892 5800 BR : S5;
5893 5801 %}
5894 5802
5895 5803 // Generic big/slow expanded idiom
5896 5804 pipe_class pipe_slow()
5897 5805 %{
5898 5806 instruction_count(10); multiple_bundles; force_serialization;
5899 5807 fixed_latency(100);
5900 5808 D0 : S0(2);
5901 5809 MEM : S3(2);
5902 5810 %}
5903 5811
5904 5812 // The real do-nothing guy
5905 5813 pipe_class empty()
5906 5814 %{
5907 5815 instruction_count(0);
5908 5816 %}
5909 5817
5910 5818 // Define the class for the Nop node
5911 5819 define
5912 5820 %{
5913 5821 MachNop = empty;
5914 5822 %}
5915 5823
5916 5824 %}
5917 5825
5918 5826 //----------INSTRUCTIONS-------------------------------------------------------
5919 5827 //
5920 5828 // match -- States which machine-independent subtree may be replaced
5921 5829 // by this instruction.
5922 5830 // ins_cost -- The estimated cost of this instruction is used by instruction
5923 5831 // selection to identify a minimum cost tree of machine
5924 5832 // instructions that matches a tree of machine-independent
5925 5833 // instructions.
5926 5834 // format -- A string providing the disassembly for this instruction.
5927 5835 // The value of an instruction's operand may be inserted
5928 5836 // by referring to it with a '$' prefix.
5929 5837 // opcode -- Three instruction opcodes may be provided. These are referred
5930 5838 // to within an encode class as $primary, $secondary, and $tertiary
5931 5839 // rrspectively. The primary opcode is commonly used to
5932 5840 // indicate the type of machine instruction, while secondary
5933 5841 // and tertiary are often used for prefix options or addressing
5934 5842 // modes.
5935 5843 // ins_encode -- A list of encode classes with parameters. The encode class
5936 5844 // name must have been defined in an 'enc_class' specification
5937 5845 // in the encode section of the architecture description.
5938 5846
5939 5847
5940 5848 //----------Load/Store/Move Instructions---------------------------------------
5941 5849 //----------Load Instructions--------------------------------------------------
5942 5850
5943 5851 // Load Byte (8 bit signed)
5944 5852 instruct loadB(rRegI dst, memory mem)
5945 5853 %{
5946 5854 match(Set dst (LoadB mem));
5947 5855
5948 5856 ins_cost(125);
5949 5857 format %{ "movsbl $dst, $mem\t# byte" %}
5950 5858
5951 5859 ins_encode %{
5952 5860 __ movsbl($dst$$Register, $mem$$Address);
5953 5861 %}
5954 5862
5955 5863 ins_pipe(ialu_reg_mem);
5956 5864 %}
5957 5865
5958 5866 // Load Byte (8 bit signed) into Long Register
5959 5867 instruct loadB2L(rRegL dst, memory mem)
5960 5868 %{
5961 5869 match(Set dst (ConvI2L (LoadB mem)));
5962 5870
5963 5871 ins_cost(125);
5964 5872 format %{ "movsbq $dst, $mem\t# byte -> long" %}
5965 5873
5966 5874 ins_encode %{
5967 5875 __ movsbq($dst$$Register, $mem$$Address);
5968 5876 %}
5969 5877
5970 5878 ins_pipe(ialu_reg_mem);
5971 5879 %}
5972 5880
5973 5881 // Load Unsigned Byte (8 bit UNsigned)
5974 5882 instruct loadUB(rRegI dst, memory mem)
5975 5883 %{
5976 5884 match(Set dst (LoadUB mem));
5977 5885
5978 5886 ins_cost(125);
5979 5887 format %{ "movzbl $dst, $mem\t# ubyte" %}
5980 5888
5981 5889 ins_encode %{
5982 5890 __ movzbl($dst$$Register, $mem$$Address);
5983 5891 %}
5984 5892
5985 5893 ins_pipe(ialu_reg_mem);
5986 5894 %}
5987 5895
5988 5896 // Load Unsigned Byte (8 bit UNsigned) into Long Register
5989 5897 instruct loadUB2L(rRegL dst, memory mem)
5990 5898 %{
5991 5899 match(Set dst (ConvI2L (LoadUB mem)));
5992 5900
5993 5901 ins_cost(125);
5994 5902 format %{ "movzbq $dst, $mem\t# ubyte -> long" %}
5995 5903
5996 5904 ins_encode %{
5997 5905 __ movzbq($dst$$Register, $mem$$Address);
5998 5906 %}
5999 5907
6000 5908 ins_pipe(ialu_reg_mem);
6001 5909 %}
6002 5910
6003 5911 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register
6004 5912 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{
6005 5913 match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
6006 5914 effect(KILL cr);
6007 5915
6008 5916 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t"
6009 5917 "andl $dst, $mask" %}
6010 5918 ins_encode %{
6011 5919 Register Rdst = $dst$$Register;
6012 5920 __ movzbq(Rdst, $mem$$Address);
6013 5921 __ andl(Rdst, $mask$$constant);
6014 5922 %}
6015 5923 ins_pipe(ialu_reg_mem);
6016 5924 %}
6017 5925
6018 5926 // Load Short (16 bit signed)
6019 5927 instruct loadS(rRegI dst, memory mem)
6020 5928 %{
6021 5929 match(Set dst (LoadS mem));
6022 5930
6023 5931 ins_cost(125);
6024 5932 format %{ "movswl $dst, $mem\t# short" %}
6025 5933
6026 5934 ins_encode %{
6027 5935 __ movswl($dst$$Register, $mem$$Address);
6028 5936 %}
6029 5937
6030 5938 ins_pipe(ialu_reg_mem);
6031 5939 %}
6032 5940
6033 5941 // Load Short (16 bit signed) to Byte (8 bit signed)
6034 5942 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
6035 5943 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
6036 5944
6037 5945 ins_cost(125);
6038 5946 format %{ "movsbl $dst, $mem\t# short -> byte" %}
6039 5947 ins_encode %{
6040 5948 __ movsbl($dst$$Register, $mem$$Address);
6041 5949 %}
6042 5950 ins_pipe(ialu_reg_mem);
6043 5951 %}
6044 5952
6045 5953 // Load Short (16 bit signed) into Long Register
6046 5954 instruct loadS2L(rRegL dst, memory mem)
6047 5955 %{
6048 5956 match(Set dst (ConvI2L (LoadS mem)));
6049 5957
6050 5958 ins_cost(125);
6051 5959 format %{ "movswq $dst, $mem\t# short -> long" %}
6052 5960
6053 5961 ins_encode %{
6054 5962 __ movswq($dst$$Register, $mem$$Address);
6055 5963 %}
6056 5964
6057 5965 ins_pipe(ialu_reg_mem);
6058 5966 %}
6059 5967
6060 5968 // Load Unsigned Short/Char (16 bit UNsigned)
6061 5969 instruct loadUS(rRegI dst, memory mem)
6062 5970 %{
6063 5971 match(Set dst (LoadUS mem));
6064 5972
6065 5973 ins_cost(125);
6066 5974 format %{ "movzwl $dst, $mem\t# ushort/char" %}
6067 5975
6068 5976 ins_encode %{
6069 5977 __ movzwl($dst$$Register, $mem$$Address);
6070 5978 %}
6071 5979
6072 5980 ins_pipe(ialu_reg_mem);
6073 5981 %}
6074 5982
6075 5983 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
6076 5984 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
6077 5985 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
6078 5986
6079 5987 ins_cost(125);
6080 5988 format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
6081 5989 ins_encode %{
6082 5990 __ movsbl($dst$$Register, $mem$$Address);
6083 5991 %}
6084 5992 ins_pipe(ialu_reg_mem);
6085 5993 %}
6086 5994
6087 5995 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
6088 5996 instruct loadUS2L(rRegL dst, memory mem)
6089 5997 %{
6090 5998 match(Set dst (ConvI2L (LoadUS mem)));
6091 5999
6092 6000 ins_cost(125);
6093 6001 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %}
6094 6002
6095 6003 ins_encode %{
6096 6004 __ movzwq($dst$$Register, $mem$$Address);
6097 6005 %}
6098 6006
6099 6007 ins_pipe(ialu_reg_mem);
6100 6008 %}
6101 6009
6102 6010 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register
6103 6011 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
6104 6012 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
6105 6013
6106 6014 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %}
6107 6015 ins_encode %{
6108 6016 __ movzbq($dst$$Register, $mem$$Address);
6109 6017 %}
6110 6018 ins_pipe(ialu_reg_mem);
6111 6019 %}
6112 6020
6113 6021 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register
6114 6022 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{
6115 6023 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
6116 6024 effect(KILL cr);
6117 6025
6118 6026 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t"
6119 6027 "andl $dst, $mask" %}
6120 6028 ins_encode %{
6121 6029 Register Rdst = $dst$$Register;
6122 6030 __ movzwq(Rdst, $mem$$Address);
6123 6031 __ andl(Rdst, $mask$$constant);
6124 6032 %}
6125 6033 ins_pipe(ialu_reg_mem);
6126 6034 %}
6127 6035
6128 6036 // Load Integer
6129 6037 instruct loadI(rRegI dst, memory mem)
6130 6038 %{
6131 6039 match(Set dst (LoadI mem));
6132 6040
6133 6041 ins_cost(125);
6134 6042 format %{ "movl $dst, $mem\t# int" %}
6135 6043
6136 6044 ins_encode %{
6137 6045 __ movl($dst$$Register, $mem$$Address);
6138 6046 %}
6139 6047
6140 6048 ins_pipe(ialu_reg_mem);
6141 6049 %}
6142 6050
6143 6051 // Load Integer (32 bit signed) to Byte (8 bit signed)
6144 6052 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
6145 6053 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
6146 6054
6147 6055 ins_cost(125);
6148 6056 format %{ "movsbl $dst, $mem\t# int -> byte" %}
6149 6057 ins_encode %{
6150 6058 __ movsbl($dst$$Register, $mem$$Address);
6151 6059 %}
6152 6060 ins_pipe(ialu_reg_mem);
6153 6061 %}
6154 6062
6155 6063 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
6156 6064 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
6157 6065 match(Set dst (AndI (LoadI mem) mask));
6158 6066
6159 6067 ins_cost(125);
6160 6068 format %{ "movzbl $dst, $mem\t# int -> ubyte" %}
6161 6069 ins_encode %{
6162 6070 __ movzbl($dst$$Register, $mem$$Address);
6163 6071 %}
6164 6072 ins_pipe(ialu_reg_mem);
6165 6073 %}
6166 6074
6167 6075 // Load Integer (32 bit signed) to Short (16 bit signed)
6168 6076 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
6169 6077 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
6170 6078
6171 6079 ins_cost(125);
6172 6080 format %{ "movswl $dst, $mem\t# int -> short" %}
6173 6081 ins_encode %{
6174 6082 __ movswl($dst$$Register, $mem$$Address);
6175 6083 %}
6176 6084 ins_pipe(ialu_reg_mem);
6177 6085 %}
6178 6086
6179 6087 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
6180 6088 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
6181 6089 match(Set dst (AndI (LoadI mem) mask));
6182 6090
6183 6091 ins_cost(125);
6184 6092 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %}
6185 6093 ins_encode %{
6186 6094 __ movzwl($dst$$Register, $mem$$Address);
6187 6095 %}
6188 6096 ins_pipe(ialu_reg_mem);
6189 6097 %}
6190 6098
6191 6099 // Load Integer into Long Register
6192 6100 instruct loadI2L(rRegL dst, memory mem)
6193 6101 %{
6194 6102 match(Set dst (ConvI2L (LoadI mem)));
6195 6103
6196 6104 ins_cost(125);
6197 6105 format %{ "movslq $dst, $mem\t# int -> long" %}
6198 6106
6199 6107 ins_encode %{
6200 6108 __ movslq($dst$$Register, $mem$$Address);
6201 6109 %}
6202 6110
6203 6111 ins_pipe(ialu_reg_mem);
6204 6112 %}
6205 6113
6206 6114 // Load Integer with mask 0xFF into Long Register
6207 6115 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
6208 6116 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
6209 6117
6210 6118 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %}
6211 6119 ins_encode %{
6212 6120 __ movzbq($dst$$Register, $mem$$Address);
6213 6121 %}
6214 6122 ins_pipe(ialu_reg_mem);
6215 6123 %}
6216 6124
6217 6125 // Load Integer with mask 0xFFFF into Long Register
6218 6126 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{
6219 6127 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
6220 6128
6221 6129 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %}
6222 6130 ins_encode %{
6223 6131 __ movzwq($dst$$Register, $mem$$Address);
6224 6132 %}
6225 6133 ins_pipe(ialu_reg_mem);
6226 6134 %}
6227 6135
6228 6136 // Load Integer with a 32-bit mask into Long Register
6229 6137 instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
6230 6138 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
6231 6139 effect(KILL cr);
6232 6140
6233 6141 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t"
6234 6142 "andl $dst, $mask" %}
6235 6143 ins_encode %{
6236 6144 Register Rdst = $dst$$Register;
6237 6145 __ movl(Rdst, $mem$$Address);
6238 6146 __ andl(Rdst, $mask$$constant);
6239 6147 %}
6240 6148 ins_pipe(ialu_reg_mem);
6241 6149 %}
6242 6150
6243 6151 // Load Unsigned Integer into Long Register
6244 6152 instruct loadUI2L(rRegL dst, memory mem)
6245 6153 %{
6246 6154 match(Set dst (LoadUI2L mem));
6247 6155
6248 6156 ins_cost(125);
6249 6157 format %{ "movl $dst, $mem\t# uint -> long" %}
6250 6158
6251 6159 ins_encode %{
6252 6160 __ movl($dst$$Register, $mem$$Address);
6253 6161 %}
6254 6162
6255 6163 ins_pipe(ialu_reg_mem);
6256 6164 %}
6257 6165
6258 6166 // Load Long
6259 6167 instruct loadL(rRegL dst, memory mem)
6260 6168 %{
6261 6169 match(Set dst (LoadL mem));
6262 6170
6263 6171 ins_cost(125);
6264 6172 format %{ "movq $dst, $mem\t# long" %}
6265 6173
6266 6174 ins_encode %{
6267 6175 __ movq($dst$$Register, $mem$$Address);
6268 6176 %}
6269 6177
6270 6178 ins_pipe(ialu_reg_mem); // XXX
6271 6179 %}
6272 6180
6273 6181 // Load Range
6274 6182 instruct loadRange(rRegI dst, memory mem)
6275 6183 %{
6276 6184 match(Set dst (LoadRange mem));
6277 6185
6278 6186 ins_cost(125); // XXX
6279 6187 format %{ "movl $dst, $mem\t# range" %}
6280 6188 opcode(0x8B);
6281 6189 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem));
6282 6190 ins_pipe(ialu_reg_mem);
6283 6191 %}
6284 6192
6285 6193 // Load Pointer
6286 6194 instruct loadP(rRegP dst, memory mem)
6287 6195 %{
6288 6196 match(Set dst (LoadP mem));
6289 6197
6290 6198 ins_cost(125); // XXX
6291 6199 format %{ "movq $dst, $mem\t# ptr" %}
6292 6200 opcode(0x8B);
6293 6201 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6294 6202 ins_pipe(ialu_reg_mem); // XXX
6295 6203 %}
6296 6204
6297 6205 // Load Compressed Pointer
6298 6206 instruct loadN(rRegN dst, memory mem)
6299 6207 %{
6300 6208 match(Set dst (LoadN mem));
6301 6209
6302 6210 ins_cost(125); // XXX
6303 6211 format %{ "movl $dst, $mem\t# compressed ptr" %}
6304 6212 ins_encode %{
6305 6213 __ movl($dst$$Register, $mem$$Address);
6306 6214 %}
6307 6215 ins_pipe(ialu_reg_mem); // XXX
6308 6216 %}
6309 6217
6310 6218
6311 6219 // Load Klass Pointer
6312 6220 instruct loadKlass(rRegP dst, memory mem)
6313 6221 %{
6314 6222 match(Set dst (LoadKlass mem));
6315 6223
6316 6224 ins_cost(125); // XXX
6317 6225 format %{ "movq $dst, $mem\t# class" %}
6318 6226 opcode(0x8B);
6319 6227 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6320 6228 ins_pipe(ialu_reg_mem); // XXX
6321 6229 %}
6322 6230
6323 6231 // Load narrow Klass Pointer
6324 6232 instruct loadNKlass(rRegN dst, memory mem)
6325 6233 %{
6326 6234 match(Set dst (LoadNKlass mem));
6327 6235
6328 6236 ins_cost(125); // XXX
6329 6237 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
6330 6238 ins_encode %{
6331 6239 __ movl($dst$$Register, $mem$$Address);
6332 6240 %}
6333 6241 ins_pipe(ialu_reg_mem); // XXX
6334 6242 %}
6335 6243
6336 6244 // Load Float
6337 6245 instruct loadF(regF dst, memory mem)
6338 6246 %{
6339 6247 match(Set dst (LoadF mem));
6340 6248
6341 6249 ins_cost(145); // XXX
6342 6250 format %{ "movss $dst, $mem\t# float" %}
6343 6251 opcode(0xF3, 0x0F, 0x10);
6344 6252 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem));
6345 6253 ins_pipe(pipe_slow); // XXX
6346 6254 %}
6347 6255
6348 6256 // Load Double
6349 6257 instruct loadD_partial(regD dst, memory mem)
6350 6258 %{
6351 6259 predicate(!UseXmmLoadAndClearUpper);
6352 6260 match(Set dst (LoadD mem));
6353 6261
6354 6262 ins_cost(145); // XXX
6355 6263 format %{ "movlpd $dst, $mem\t# double" %}
6356 6264 opcode(0x66, 0x0F, 0x12);
6357 6265 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem));
6358 6266 ins_pipe(pipe_slow); // XXX
6359 6267 %}
6360 6268
6361 6269 instruct loadD(regD dst, memory mem)
6362 6270 %{
6363 6271 predicate(UseXmmLoadAndClearUpper);
6364 6272 match(Set dst (LoadD mem));
6365 6273
6366 6274 ins_cost(145); // XXX
6367 6275 format %{ "movsd $dst, $mem\t# double" %}
6368 6276 opcode(0xF2, 0x0F, 0x10);
6369 6277 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem));
6370 6278 ins_pipe(pipe_slow); // XXX
6371 6279 %}
6372 6280
6373 6281 // Load Aligned Packed Byte to XMM register
6374 6282 instruct loadA8B(regD dst, memory mem) %{
6375 6283 match(Set dst (Load8B mem));
6376 6284 ins_cost(125);
6377 6285 format %{ "MOVQ $dst,$mem\t! packed8B" %}
6378 6286 ins_encode( movq_ld(dst, mem));
6379 6287 ins_pipe( pipe_slow );
6380 6288 %}
6381 6289
6382 6290 // Load Aligned Packed Short to XMM register
6383 6291 instruct loadA4S(regD dst, memory mem) %{
6384 6292 match(Set dst (Load4S mem));
6385 6293 ins_cost(125);
6386 6294 format %{ "MOVQ $dst,$mem\t! packed4S" %}
6387 6295 ins_encode( movq_ld(dst, mem));
6388 6296 ins_pipe( pipe_slow );
6389 6297 %}
6390 6298
6391 6299 // Load Aligned Packed Char to XMM register
6392 6300 instruct loadA4C(regD dst, memory mem) %{
6393 6301 match(Set dst (Load4C mem));
6394 6302 ins_cost(125);
6395 6303 format %{ "MOVQ $dst,$mem\t! packed4C" %}
6396 6304 ins_encode( movq_ld(dst, mem));
6397 6305 ins_pipe( pipe_slow );
6398 6306 %}
6399 6307
6400 6308 // Load Aligned Packed Integer to XMM register
6401 6309 instruct load2IU(regD dst, memory mem) %{
6402 6310 match(Set dst (Load2I mem));
6403 6311 ins_cost(125);
6404 6312 format %{ "MOVQ $dst,$mem\t! packed2I" %}
6405 6313 ins_encode( movq_ld(dst, mem));
6406 6314 ins_pipe( pipe_slow );
6407 6315 %}
6408 6316
6409 6317 // Load Aligned Packed Single to XMM
6410 6318 instruct loadA2F(regD dst, memory mem) %{
6411 6319 match(Set dst (Load2F mem));
6412 6320 ins_cost(145);
6413 6321 format %{ "MOVQ $dst,$mem\t! packed2F" %}
6414 6322 ins_encode( movq_ld(dst, mem));
6415 6323 ins_pipe( pipe_slow );
6416 6324 %}
6417 6325
6418 6326 // Load Effective Address
6419 6327 instruct leaP8(rRegP dst, indOffset8 mem)
6420 6328 %{
6421 6329 match(Set dst mem);
6422 6330
6423 6331 ins_cost(110); // XXX
6424 6332 format %{ "leaq $dst, $mem\t# ptr 8" %}
6425 6333 opcode(0x8D);
6426 6334 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6427 6335 ins_pipe(ialu_reg_reg_fat);
6428 6336 %}
6429 6337
6430 6338 instruct leaP32(rRegP dst, indOffset32 mem)
6431 6339 %{
6432 6340 match(Set dst mem);
6433 6341
6434 6342 ins_cost(110);
6435 6343 format %{ "leaq $dst, $mem\t# ptr 32" %}
6436 6344 opcode(0x8D);
6437 6345 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6438 6346 ins_pipe(ialu_reg_reg_fat);
6439 6347 %}
6440 6348
6441 6349 // instruct leaPIdx(rRegP dst, indIndex mem)
6442 6350 // %{
6443 6351 // match(Set dst mem);
6444 6352
6445 6353 // ins_cost(110);
6446 6354 // format %{ "leaq $dst, $mem\t# ptr idx" %}
6447 6355 // opcode(0x8D);
6448 6356 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6449 6357 // ins_pipe(ialu_reg_reg_fat);
6450 6358 // %}
6451 6359
6452 6360 instruct leaPIdxOff(rRegP dst, indIndexOffset mem)
6453 6361 %{
6454 6362 match(Set dst mem);
6455 6363
6456 6364 ins_cost(110);
6457 6365 format %{ "leaq $dst, $mem\t# ptr idxoff" %}
6458 6366 opcode(0x8D);
6459 6367 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6460 6368 ins_pipe(ialu_reg_reg_fat);
6461 6369 %}
6462 6370
6463 6371 instruct leaPIdxScale(rRegP dst, indIndexScale mem)
6464 6372 %{
6465 6373 match(Set dst mem);
6466 6374
6467 6375 ins_cost(110);
6468 6376 format %{ "leaq $dst, $mem\t# ptr idxscale" %}
6469 6377 opcode(0x8D);
6470 6378 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6471 6379 ins_pipe(ialu_reg_reg_fat);
6472 6380 %}
6473 6381
6474 6382 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem)
6475 6383 %{
6476 6384 match(Set dst mem);
6477 6385
6478 6386 ins_cost(110);
6479 6387 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %}
6480 6388 opcode(0x8D);
6481 6389 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6482 6390 ins_pipe(ialu_reg_reg_fat);
6483 6391 %}
6484 6392
6485 6393 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem)
6486 6394 %{
6487 6395 match(Set dst mem);
6488 6396
6489 6397 ins_cost(110);
6490 6398 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %}
6491 6399 opcode(0x8D);
6492 6400 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6493 6401 ins_pipe(ialu_reg_reg_fat);
6494 6402 %}
6495 6403
6496 6404 // Load Effective Address which uses Narrow (32-bits) oop
6497 6405 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem)
6498 6406 %{
6499 6407 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0));
6500 6408 match(Set dst mem);
6501 6409
6502 6410 ins_cost(110);
6503 6411 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %}
6504 6412 opcode(0x8D);
6505 6413 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6506 6414 ins_pipe(ialu_reg_reg_fat);
6507 6415 %}
6508 6416
6509 6417 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem)
6510 6418 %{
6511 6419 predicate(Universe::narrow_oop_shift() == 0);
6512 6420 match(Set dst mem);
6513 6421
6514 6422 ins_cost(110); // XXX
6515 6423 format %{ "leaq $dst, $mem\t# ptr off8narrow" %}
6516 6424 opcode(0x8D);
6517 6425 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6518 6426 ins_pipe(ialu_reg_reg_fat);
6519 6427 %}
6520 6428
6521 6429 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem)
6522 6430 %{
6523 6431 predicate(Universe::narrow_oop_shift() == 0);
6524 6432 match(Set dst mem);
6525 6433
6526 6434 ins_cost(110);
6527 6435 format %{ "leaq $dst, $mem\t# ptr off32narrow" %}
6528 6436 opcode(0x8D);
6529 6437 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6530 6438 ins_pipe(ialu_reg_reg_fat);
6531 6439 %}
6532 6440
6533 6441 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem)
6534 6442 %{
6535 6443 predicate(Universe::narrow_oop_shift() == 0);
6536 6444 match(Set dst mem);
6537 6445
6538 6446 ins_cost(110);
6539 6447 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %}
6540 6448 opcode(0x8D);
6541 6449 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6542 6450 ins_pipe(ialu_reg_reg_fat);
6543 6451 %}
6544 6452
6545 6453 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem)
6546 6454 %{
6547 6455 predicate(Universe::narrow_oop_shift() == 0);
6548 6456 match(Set dst mem);
6549 6457
6550 6458 ins_cost(110);
6551 6459 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %}
6552 6460 opcode(0x8D);
6553 6461 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6554 6462 ins_pipe(ialu_reg_reg_fat);
6555 6463 %}
6556 6464
6557 6465 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem)
6558 6466 %{
6559 6467 predicate(Universe::narrow_oop_shift() == 0);
6560 6468 match(Set dst mem);
6561 6469
6562 6470 ins_cost(110);
6563 6471 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %}
6564 6472 opcode(0x8D);
6565 6473 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6566 6474 ins_pipe(ialu_reg_reg_fat);
6567 6475 %}
6568 6476
6569 6477 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem)
6570 6478 %{
6571 6479 predicate(Universe::narrow_oop_shift() == 0);
6572 6480 match(Set dst mem);
6573 6481
6574 6482 ins_cost(110);
6575 6483 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %}
6576 6484 opcode(0x8D);
6577 6485 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6578 6486 ins_pipe(ialu_reg_reg_fat);
6579 6487 %}
6580 6488
6581 6489 instruct loadConI(rRegI dst, immI src)
6582 6490 %{
6583 6491 match(Set dst src);
6584 6492
6585 6493 format %{ "movl $dst, $src\t# int" %}
6586 6494 ins_encode(load_immI(dst, src));
6587 6495 ins_pipe(ialu_reg_fat); // XXX
6588 6496 %}
6589 6497
6590 6498 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr)
6591 6499 %{
6592 6500 match(Set dst src);
6593 6501 effect(KILL cr);
6594 6502
6595 6503 ins_cost(50);
6596 6504 format %{ "xorl $dst, $dst\t# int" %}
6597 6505 opcode(0x33); /* + rd */
6598 6506 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
6599 6507 ins_pipe(ialu_reg);
6600 6508 %}
6601 6509
6602 6510 instruct loadConL(rRegL dst, immL src)
6603 6511 %{
6604 6512 match(Set dst src);
6605 6513
6606 6514 ins_cost(150);
6607 6515 format %{ "movq $dst, $src\t# long" %}
6608 6516 ins_encode(load_immL(dst, src));
6609 6517 ins_pipe(ialu_reg);
6610 6518 %}
6611 6519
6612 6520 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr)
6613 6521 %{
6614 6522 match(Set dst src);
6615 6523 effect(KILL cr);
6616 6524
6617 6525 ins_cost(50);
6618 6526 format %{ "xorl $dst, $dst\t# long" %}
6619 6527 opcode(0x33); /* + rd */
6620 6528 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
6621 6529 ins_pipe(ialu_reg); // XXX
6622 6530 %}
6623 6531
6624 6532 instruct loadConUL32(rRegL dst, immUL32 src)
6625 6533 %{
6626 6534 match(Set dst src);
6627 6535
6628 6536 ins_cost(60);
6629 6537 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %}
6630 6538 ins_encode(load_immUL32(dst, src));
6631 6539 ins_pipe(ialu_reg);
6632 6540 %}
6633 6541
↓ open down ↓ |
3638 lines elided |
↑ open up ↑ |
6634 6542 instruct loadConL32(rRegL dst, immL32 src)
6635 6543 %{
6636 6544 match(Set dst src);
6637 6545
6638 6546 ins_cost(70);
6639 6547 format %{ "movq $dst, $src\t# long (32-bit)" %}
6640 6548 ins_encode(load_immL32(dst, src));
6641 6549 ins_pipe(ialu_reg);
6642 6550 %}
6643 6551
6644 -instruct loadConP(rRegP dst, immP src)
6645 -%{
6646 - match(Set dst src);
6552 +instruct loadConP(rRegP dst, immP con) %{
6553 + match(Set dst con);
6647 6554
6648 - format %{ "movq $dst, $src\t# ptr" %}
6649 - ins_encode(load_immP(dst, src));
6555 + format %{ "movq $dst, $con\t# ptr" %}
6556 + ins_encode(load_immP(dst, con));
6650 6557 ins_pipe(ialu_reg_fat); // XXX
6651 6558 %}
6652 6559
6653 6560 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
6654 6561 %{
6655 6562 match(Set dst src);
6656 6563 effect(KILL cr);
6657 6564
6658 6565 ins_cost(50);
6659 6566 format %{ "xorl $dst, $dst\t# ptr" %}
6660 6567 opcode(0x33); /* + rd */
6661 6568 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
6662 6569 ins_pipe(ialu_reg);
6663 6570 %}
6664 6571
6665 6572 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
6666 6573 %{
6667 6574 match(Set dst src);
6668 6575 effect(KILL cr);
6669 6576
6670 6577 ins_cost(60);
6671 6578 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %}
6672 6579 ins_encode(load_immP31(dst, src));
6673 6580 ins_pipe(ialu_reg);
6674 6581 %}
6675 6582
6676 -instruct loadConF(regF dst, immF src)
6677 -%{
6678 - match(Set dst src);
6583 +instruct loadConF(regF dst, immF con) %{
6584 + match(Set dst con);
6679 6585 ins_cost(125);
6680 -
6681 - format %{ "movss $dst, [$src]" %}
6682 - ins_encode(load_conF(dst, src));
6586 + format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
6587 + ins_encode %{
6588 + __ movflt($dst$$XMMRegister, $constantaddress($con));
6589 + %}
6683 6590 ins_pipe(pipe_slow);
6684 6591 %}
6685 6592
6686 6593 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
6687 6594 match(Set dst src);
6688 6595 effect(KILL cr);
6689 6596 format %{ "xorq $dst, $src\t# compressed NULL ptr" %}
6690 6597 ins_encode %{
6691 6598 __ xorq($dst$$Register, $dst$$Register);
6692 6599 %}
6693 6600 ins_pipe(ialu_reg);
6694 6601 %}
6695 6602
6696 6603 instruct loadConN(rRegN dst, immN src) %{
6697 6604 match(Set dst src);
6698 6605
6699 6606 ins_cost(125);
6700 6607 format %{ "movl $dst, $src\t# compressed ptr" %}
6701 6608 ins_encode %{
6702 6609 address con = (address)$src$$constant;
6703 6610 if (con == NULL) {
6704 6611 ShouldNotReachHere();
6705 6612 } else {
6706 6613 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
6707 6614 }
6708 6615 %}
6709 6616 ins_pipe(ialu_reg_fat); // XXX
6710 6617 %}
6711 6618
6712 6619 instruct loadConF0(regF dst, immF0 src)
6713 6620 %{
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
6714 6621 match(Set dst src);
6715 6622 ins_cost(100);
6716 6623
6717 6624 format %{ "xorps $dst, $dst\t# float 0.0" %}
6718 6625 opcode(0x0F, 0x57);
6719 6626 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
6720 6627 ins_pipe(pipe_slow);
6721 6628 %}
6722 6629
6723 6630 // Use the same format since predicate() can not be used here.
6724 -instruct loadConD(regD dst, immD src)
6725 -%{
6726 - match(Set dst src);
6631 +instruct loadConD(regD dst, immD con) %{
6632 + match(Set dst con);
6727 6633 ins_cost(125);
6728 -
6729 - format %{ "movsd $dst, [$src]" %}
6730 - ins_encode(load_conD(dst, src));
6634 + format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
6635 + ins_encode %{
6636 + __ movdbl($dst$$XMMRegister, $constantaddress($con));
6637 + %}
6731 6638 ins_pipe(pipe_slow);
6732 6639 %}
6733 6640
6734 6641 instruct loadConD0(regD dst, immD0 src)
6735 6642 %{
6736 6643 match(Set dst src);
6737 6644 ins_cost(100);
6738 6645
6739 6646 format %{ "xorpd $dst, $dst\t# double 0.0" %}
6740 6647 opcode(0x66, 0x0F, 0x57);
6741 6648 ins_encode(OpcP, REX_reg_reg(dst, dst), OpcS, OpcT, reg_reg(dst, dst));
6742 6649 ins_pipe(pipe_slow);
6743 6650 %}
6744 6651
6745 6652 instruct loadSSI(rRegI dst, stackSlotI src)
6746 6653 %{
6747 6654 match(Set dst src);
6748 6655
6749 6656 ins_cost(125);
6750 6657 format %{ "movl $dst, $src\t# int stk" %}
6751 6658 opcode(0x8B);
6752 6659 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
6753 6660 ins_pipe(ialu_reg_mem);
6754 6661 %}
6755 6662
6756 6663 instruct loadSSL(rRegL dst, stackSlotL src)
6757 6664 %{
6758 6665 match(Set dst src);
6759 6666
6760 6667 ins_cost(125);
6761 6668 format %{ "movq $dst, $src\t# long stk" %}
6762 6669 opcode(0x8B);
6763 6670 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
6764 6671 ins_pipe(ialu_reg_mem);
6765 6672 %}
6766 6673
6767 6674 instruct loadSSP(rRegP dst, stackSlotP src)
6768 6675 %{
6769 6676 match(Set dst src);
6770 6677
6771 6678 ins_cost(125);
6772 6679 format %{ "movq $dst, $src\t# ptr stk" %}
6773 6680 opcode(0x8B);
6774 6681 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
6775 6682 ins_pipe(ialu_reg_mem);
6776 6683 %}
6777 6684
6778 6685 instruct loadSSF(regF dst, stackSlotF src)
6779 6686 %{
6780 6687 match(Set dst src);
6781 6688
6782 6689 ins_cost(125);
6783 6690 format %{ "movss $dst, $src\t# float stk" %}
6784 6691 opcode(0xF3, 0x0F, 0x10);
6785 6692 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
6786 6693 ins_pipe(pipe_slow); // XXX
6787 6694 %}
6788 6695
6789 6696 // Use the same format since predicate() can not be used here.
6790 6697 instruct loadSSD(regD dst, stackSlotD src)
6791 6698 %{
6792 6699 match(Set dst src);
6793 6700
6794 6701 ins_cost(125);
6795 6702 format %{ "movsd $dst, $src\t# double stk" %}
6796 6703 ins_encode %{
6797 6704 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
6798 6705 %}
6799 6706 ins_pipe(pipe_slow); // XXX
6800 6707 %}
6801 6708
6802 6709 // Prefetch instructions.
6803 6710 // Must be safe to execute with invalid address (cannot fault).
6804 6711
6805 6712 instruct prefetchr( memory mem ) %{
6806 6713 predicate(ReadPrefetchInstr==3);
6807 6714 match(PrefetchRead mem);
6808 6715 ins_cost(125);
6809 6716
6810 6717 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %}
6811 6718 opcode(0x0F, 0x0D); /* Opcode 0F 0D /0 */
6812 6719 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem));
6813 6720 ins_pipe(ialu_mem);
6814 6721 %}
6815 6722
6816 6723 instruct prefetchrNTA( memory mem ) %{
6817 6724 predicate(ReadPrefetchInstr==0);
6818 6725 match(PrefetchRead mem);
6819 6726 ins_cost(125);
6820 6727
6821 6728 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %}
6822 6729 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */
6823 6730 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem));
6824 6731 ins_pipe(ialu_mem);
6825 6732 %}
6826 6733
6827 6734 instruct prefetchrT0( memory mem ) %{
6828 6735 predicate(ReadPrefetchInstr==1);
6829 6736 match(PrefetchRead mem);
6830 6737 ins_cost(125);
6831 6738
6832 6739 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %}
6833 6740 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */
6834 6741 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem));
6835 6742 ins_pipe(ialu_mem);
6836 6743 %}
6837 6744
6838 6745 instruct prefetchrT2( memory mem ) %{
6839 6746 predicate(ReadPrefetchInstr==2);
6840 6747 match(PrefetchRead mem);
6841 6748 ins_cost(125);
6842 6749
6843 6750 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %}
6844 6751 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */
6845 6752 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x03, mem));
6846 6753 ins_pipe(ialu_mem);
6847 6754 %}
6848 6755
6849 6756 instruct prefetchw( memory mem ) %{
6850 6757 predicate(AllocatePrefetchInstr==3);
6851 6758 match(PrefetchWrite mem);
6852 6759 ins_cost(125);
6853 6760
6854 6761 format %{ "PREFETCHW $mem\t# Prefetch into level 1 cache and mark modified" %}
6855 6762 opcode(0x0F, 0x0D); /* Opcode 0F 0D /1 */
6856 6763 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem));
6857 6764 ins_pipe(ialu_mem);
6858 6765 %}
6859 6766
6860 6767 instruct prefetchwNTA( memory mem ) %{
6861 6768 predicate(AllocatePrefetchInstr==0);
6862 6769 match(PrefetchWrite mem);
6863 6770 ins_cost(125);
6864 6771
6865 6772 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %}
6866 6773 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */
6867 6774 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem));
6868 6775 ins_pipe(ialu_mem);
6869 6776 %}
6870 6777
6871 6778 instruct prefetchwT0( memory mem ) %{
6872 6779 predicate(AllocatePrefetchInstr==1);
6873 6780 match(PrefetchWrite mem);
6874 6781 ins_cost(125);
6875 6782
6876 6783 format %{ "PREFETCHT0 $mem\t# Prefetch to level 1 and 2 caches for write" %}
6877 6784 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */
6878 6785 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem));
6879 6786 ins_pipe(ialu_mem);
6880 6787 %}
6881 6788
6882 6789 instruct prefetchwT2( memory mem ) %{
6883 6790 predicate(AllocatePrefetchInstr==2);
6884 6791 match(PrefetchWrite mem);
6885 6792 ins_cost(125);
6886 6793
6887 6794 format %{ "PREFETCHT2 $mem\t# Prefetch to level 2 cache for write" %}
6888 6795 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */
6889 6796 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x03, mem));
6890 6797 ins_pipe(ialu_mem);
6891 6798 %}
6892 6799
6893 6800 //----------Store Instructions-------------------------------------------------
6894 6801
6895 6802 // Store Byte
6896 6803 instruct storeB(memory mem, rRegI src)
6897 6804 %{
6898 6805 match(Set mem (StoreB mem src));
6899 6806
6900 6807 ins_cost(125); // XXX
6901 6808 format %{ "movb $mem, $src\t# byte" %}
6902 6809 opcode(0x88);
6903 6810 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem));
6904 6811 ins_pipe(ialu_mem_reg);
6905 6812 %}
6906 6813
6907 6814 // Store Char/Short
6908 6815 instruct storeC(memory mem, rRegI src)
6909 6816 %{
6910 6817 match(Set mem (StoreC mem src));
6911 6818
6912 6819 ins_cost(125); // XXX
6913 6820 format %{ "movw $mem, $src\t# char/short" %}
6914 6821 opcode(0x89);
6915 6822 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
6916 6823 ins_pipe(ialu_mem_reg);
6917 6824 %}
6918 6825
6919 6826 // Store Integer
6920 6827 instruct storeI(memory mem, rRegI src)
6921 6828 %{
6922 6829 match(Set mem (StoreI mem src));
6923 6830
6924 6831 ins_cost(125); // XXX
6925 6832 format %{ "movl $mem, $src\t# int" %}
6926 6833 opcode(0x89);
6927 6834 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
6928 6835 ins_pipe(ialu_mem_reg);
6929 6836 %}
6930 6837
6931 6838 // Store Long
6932 6839 instruct storeL(memory mem, rRegL src)
6933 6840 %{
6934 6841 match(Set mem (StoreL mem src));
6935 6842
6936 6843 ins_cost(125); // XXX
6937 6844 format %{ "movq $mem, $src\t# long" %}
6938 6845 opcode(0x89);
6939 6846 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
6940 6847 ins_pipe(ialu_mem_reg); // XXX
6941 6848 %}
6942 6849
6943 6850 // Store Pointer
6944 6851 instruct storeP(memory mem, any_RegP src)
6945 6852 %{
6946 6853 match(Set mem (StoreP mem src));
6947 6854
6948 6855 ins_cost(125); // XXX
6949 6856 format %{ "movq $mem, $src\t# ptr" %}
6950 6857 opcode(0x89);
6951 6858 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
6952 6859 ins_pipe(ialu_mem_reg);
6953 6860 %}
6954 6861
6955 6862 instruct storeImmP0(memory mem, immP0 zero)
6956 6863 %{
6957 6864 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6958 6865 match(Set mem (StoreP mem zero));
6959 6866
6960 6867 ins_cost(125); // XXX
6961 6868 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
6962 6869 ins_encode %{
6963 6870 __ movq($mem$$Address, r12);
6964 6871 %}
6965 6872 ins_pipe(ialu_mem_reg);
6966 6873 %}
6967 6874
6968 6875 // Store NULL Pointer, mark word, or other simple pointer constant.
6969 6876 instruct storeImmP(memory mem, immP31 src)
6970 6877 %{
6971 6878 match(Set mem (StoreP mem src));
6972 6879
6973 6880 ins_cost(150); // XXX
6974 6881 format %{ "movq $mem, $src\t# ptr" %}
6975 6882 opcode(0xC7); /* C7 /0 */
6976 6883 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6977 6884 ins_pipe(ialu_mem_imm);
6978 6885 %}
6979 6886
6980 6887 // Store Compressed Pointer
6981 6888 instruct storeN(memory mem, rRegN src)
6982 6889 %{
6983 6890 match(Set mem (StoreN mem src));
6984 6891
6985 6892 ins_cost(125); // XXX
6986 6893 format %{ "movl $mem, $src\t# compressed ptr" %}
6987 6894 ins_encode %{
6988 6895 __ movl($mem$$Address, $src$$Register);
6989 6896 %}
6990 6897 ins_pipe(ialu_mem_reg);
6991 6898 %}
6992 6899
6993 6900 instruct storeImmN0(memory mem, immN0 zero)
6994 6901 %{
6995 6902 predicate(Universe::narrow_oop_base() == NULL);
6996 6903 match(Set mem (StoreN mem zero));
6997 6904
6998 6905 ins_cost(125); // XXX
6999 6906 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
7000 6907 ins_encode %{
7001 6908 __ movl($mem$$Address, r12);
7002 6909 %}
7003 6910 ins_pipe(ialu_mem_reg);
7004 6911 %}
7005 6912
7006 6913 instruct storeImmN(memory mem, immN src)
7007 6914 %{
7008 6915 match(Set mem (StoreN mem src));
7009 6916
7010 6917 ins_cost(150); // XXX
7011 6918 format %{ "movl $mem, $src\t# compressed ptr" %}
7012 6919 ins_encode %{
7013 6920 address con = (address)$src$$constant;
7014 6921 if (con == NULL) {
7015 6922 __ movl($mem$$Address, (int32_t)0);
7016 6923 } else {
7017 6924 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant);
7018 6925 }
7019 6926 %}
7020 6927 ins_pipe(ialu_mem_imm);
7021 6928 %}
7022 6929
7023 6930 // Store Integer Immediate
7024 6931 instruct storeImmI0(memory mem, immI0 zero)
7025 6932 %{
7026 6933 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7027 6934 match(Set mem (StoreI mem zero));
7028 6935
7029 6936 ins_cost(125); // XXX
7030 6937 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
7031 6938 ins_encode %{
7032 6939 __ movl($mem$$Address, r12);
7033 6940 %}
7034 6941 ins_pipe(ialu_mem_reg);
7035 6942 %}
7036 6943
7037 6944 instruct storeImmI(memory mem, immI src)
7038 6945 %{
7039 6946 match(Set mem (StoreI mem src));
7040 6947
7041 6948 ins_cost(150);
7042 6949 format %{ "movl $mem, $src\t# int" %}
7043 6950 opcode(0xC7); /* C7 /0 */
7044 6951 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
7045 6952 ins_pipe(ialu_mem_imm);
7046 6953 %}
7047 6954
7048 6955 // Store Long Immediate
7049 6956 instruct storeImmL0(memory mem, immL0 zero)
7050 6957 %{
7051 6958 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7052 6959 match(Set mem (StoreL mem zero));
7053 6960
7054 6961 ins_cost(125); // XXX
7055 6962 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
7056 6963 ins_encode %{
7057 6964 __ movq($mem$$Address, r12);
7058 6965 %}
7059 6966 ins_pipe(ialu_mem_reg);
7060 6967 %}
7061 6968
7062 6969 instruct storeImmL(memory mem, immL32 src)
7063 6970 %{
7064 6971 match(Set mem (StoreL mem src));
7065 6972
7066 6973 ins_cost(150);
7067 6974 format %{ "movq $mem, $src\t# long" %}
7068 6975 opcode(0xC7); /* C7 /0 */
7069 6976 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
7070 6977 ins_pipe(ialu_mem_imm);
7071 6978 %}
7072 6979
7073 6980 // Store Short/Char Immediate
7074 6981 instruct storeImmC0(memory mem, immI0 zero)
7075 6982 %{
7076 6983 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7077 6984 match(Set mem (StoreC mem zero));
7078 6985
7079 6986 ins_cost(125); // XXX
7080 6987 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
7081 6988 ins_encode %{
7082 6989 __ movw($mem$$Address, r12);
7083 6990 %}
7084 6991 ins_pipe(ialu_mem_reg);
7085 6992 %}
7086 6993
7087 6994 instruct storeImmI16(memory mem, immI16 src)
7088 6995 %{
7089 6996 predicate(UseStoreImmI16);
7090 6997 match(Set mem (StoreC mem src));
7091 6998
7092 6999 ins_cost(150);
7093 7000 format %{ "movw $mem, $src\t# short/char" %}
7094 7001 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */
7095 7002 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src));
7096 7003 ins_pipe(ialu_mem_imm);
7097 7004 %}
7098 7005
7099 7006 // Store Byte Immediate
7100 7007 instruct storeImmB0(memory mem, immI0 zero)
7101 7008 %{
7102 7009 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7103 7010 match(Set mem (StoreB mem zero));
7104 7011
7105 7012 ins_cost(125); // XXX
7106 7013 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
7107 7014 ins_encode %{
7108 7015 __ movb($mem$$Address, r12);
7109 7016 %}
7110 7017 ins_pipe(ialu_mem_reg);
7111 7018 %}
7112 7019
7113 7020 instruct storeImmB(memory mem, immI8 src)
7114 7021 %{
7115 7022 match(Set mem (StoreB mem src));
7116 7023
7117 7024 ins_cost(150); // XXX
7118 7025 format %{ "movb $mem, $src\t# byte" %}
7119 7026 opcode(0xC6); /* C6 /0 */
7120 7027 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
7121 7028 ins_pipe(ialu_mem_imm);
7122 7029 %}
7123 7030
7124 7031 // Store Aligned Packed Byte XMM register to memory
7125 7032 instruct storeA8B(memory mem, regD src) %{
7126 7033 match(Set mem (Store8B mem src));
7127 7034 ins_cost(145);
7128 7035 format %{ "MOVQ $mem,$src\t! packed8B" %}
7129 7036 ins_encode( movq_st(mem, src));
7130 7037 ins_pipe( pipe_slow );
7131 7038 %}
7132 7039
7133 7040 // Store Aligned Packed Char/Short XMM register to memory
7134 7041 instruct storeA4C(memory mem, regD src) %{
7135 7042 match(Set mem (Store4C mem src));
7136 7043 ins_cost(145);
7137 7044 format %{ "MOVQ $mem,$src\t! packed4C" %}
7138 7045 ins_encode( movq_st(mem, src));
7139 7046 ins_pipe( pipe_slow );
7140 7047 %}
7141 7048
7142 7049 // Store Aligned Packed Integer XMM register to memory
7143 7050 instruct storeA2I(memory mem, regD src) %{
7144 7051 match(Set mem (Store2I mem src));
7145 7052 ins_cost(145);
7146 7053 format %{ "MOVQ $mem,$src\t! packed2I" %}
7147 7054 ins_encode( movq_st(mem, src));
7148 7055 ins_pipe( pipe_slow );
7149 7056 %}
7150 7057
7151 7058 // Store CMS card-mark Immediate
7152 7059 instruct storeImmCM0_reg(memory mem, immI0 zero)
7153 7060 %{
7154 7061 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7155 7062 match(Set mem (StoreCM mem zero));
7156 7063
7157 7064 ins_cost(125); // XXX
7158 7065 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
7159 7066 ins_encode %{
7160 7067 __ movb($mem$$Address, r12);
7161 7068 %}
7162 7069 ins_pipe(ialu_mem_reg);
7163 7070 %}
7164 7071
7165 7072 instruct storeImmCM0(memory mem, immI0 src)
7166 7073 %{
7167 7074 match(Set mem (StoreCM mem src));
7168 7075
7169 7076 ins_cost(150); // XXX
7170 7077 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
7171 7078 opcode(0xC6); /* C6 /0 */
7172 7079 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
7173 7080 ins_pipe(ialu_mem_imm);
7174 7081 %}
7175 7082
7176 7083 // Store Aligned Packed Single Float XMM register to memory
7177 7084 instruct storeA2F(memory mem, regD src) %{
7178 7085 match(Set mem (Store2F mem src));
7179 7086 ins_cost(145);
7180 7087 format %{ "MOVQ $mem,$src\t! packed2F" %}
7181 7088 ins_encode( movq_st(mem, src));
7182 7089 ins_pipe( pipe_slow );
7183 7090 %}
7184 7091
7185 7092 // Store Float
7186 7093 instruct storeF(memory mem, regF src)
7187 7094 %{
7188 7095 match(Set mem (StoreF mem src));
7189 7096
7190 7097 ins_cost(95); // XXX
7191 7098 format %{ "movss $mem, $src\t# float" %}
7192 7099 opcode(0xF3, 0x0F, 0x11);
7193 7100 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem));
7194 7101 ins_pipe(pipe_slow); // XXX
7195 7102 %}
7196 7103
7197 7104 // Store immediate Float value (it is faster than store from XMM register)
7198 7105 instruct storeF0(memory mem, immF0 zero)
7199 7106 %{
7200 7107 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7201 7108 match(Set mem (StoreF mem zero));
7202 7109
7203 7110 ins_cost(25); // XXX
7204 7111 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
7205 7112 ins_encode %{
7206 7113 __ movl($mem$$Address, r12);
7207 7114 %}
7208 7115 ins_pipe(ialu_mem_reg);
7209 7116 %}
7210 7117
7211 7118 instruct storeF_imm(memory mem, immF src)
7212 7119 %{
7213 7120 match(Set mem (StoreF mem src));
7214 7121
7215 7122 ins_cost(50);
7216 7123 format %{ "movl $mem, $src\t# float" %}
7217 7124 opcode(0xC7); /* C7 /0 */
7218 7125 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
7219 7126 ins_pipe(ialu_mem_imm);
7220 7127 %}
7221 7128
7222 7129 // Store Double
7223 7130 instruct storeD(memory mem, regD src)
7224 7131 %{
7225 7132 match(Set mem (StoreD mem src));
7226 7133
7227 7134 ins_cost(95); // XXX
7228 7135 format %{ "movsd $mem, $src\t# double" %}
7229 7136 opcode(0xF2, 0x0F, 0x11);
7230 7137 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem));
7231 7138 ins_pipe(pipe_slow); // XXX
7232 7139 %}
7233 7140
7234 7141 // Store immediate double 0.0 (it is faster than store from XMM register)
7235 7142 instruct storeD0_imm(memory mem, immD0 src)
7236 7143 %{
7237 7144 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
7238 7145 match(Set mem (StoreD mem src));
7239 7146
7240 7147 ins_cost(50);
7241 7148 format %{ "movq $mem, $src\t# double 0." %}
7242 7149 opcode(0xC7); /* C7 /0 */
7243 7150 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
7244 7151 ins_pipe(ialu_mem_imm);
7245 7152 %}
7246 7153
7247 7154 instruct storeD0(memory mem, immD0 zero)
7248 7155 %{
7249 7156 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7250 7157 match(Set mem (StoreD mem zero));
7251 7158
7252 7159 ins_cost(25); // XXX
7253 7160 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
7254 7161 ins_encode %{
7255 7162 __ movq($mem$$Address, r12);
7256 7163 %}
7257 7164 ins_pipe(ialu_mem_reg);
7258 7165 %}
7259 7166
7260 7167 instruct storeSSI(stackSlotI dst, rRegI src)
7261 7168 %{
7262 7169 match(Set dst src);
7263 7170
7264 7171 ins_cost(100);
7265 7172 format %{ "movl $dst, $src\t# int stk" %}
7266 7173 opcode(0x89);
7267 7174 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
7268 7175 ins_pipe( ialu_mem_reg );
7269 7176 %}
7270 7177
7271 7178 instruct storeSSL(stackSlotL dst, rRegL src)
7272 7179 %{
7273 7180 match(Set dst src);
7274 7181
7275 7182 ins_cost(100);
7276 7183 format %{ "movq $dst, $src\t# long stk" %}
7277 7184 opcode(0x89);
7278 7185 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7279 7186 ins_pipe(ialu_mem_reg);
7280 7187 %}
7281 7188
7282 7189 instruct storeSSP(stackSlotP dst, rRegP src)
7283 7190 %{
7284 7191 match(Set dst src);
7285 7192
7286 7193 ins_cost(100);
7287 7194 format %{ "movq $dst, $src\t# ptr stk" %}
7288 7195 opcode(0x89);
7289 7196 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7290 7197 ins_pipe(ialu_mem_reg);
7291 7198 %}
7292 7199
7293 7200 instruct storeSSF(stackSlotF dst, regF src)
7294 7201 %{
7295 7202 match(Set dst src);
7296 7203
7297 7204 ins_cost(95); // XXX
7298 7205 format %{ "movss $dst, $src\t# float stk" %}
7299 7206 opcode(0xF3, 0x0F, 0x11);
7300 7207 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
7301 7208 ins_pipe(pipe_slow); // XXX
7302 7209 %}
7303 7210
7304 7211 instruct storeSSD(stackSlotD dst, regD src)
7305 7212 %{
7306 7213 match(Set dst src);
7307 7214
7308 7215 ins_cost(95); // XXX
7309 7216 format %{ "movsd $dst, $src\t# double stk" %}
7310 7217 opcode(0xF2, 0x0F, 0x11);
7311 7218 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
7312 7219 ins_pipe(pipe_slow); // XXX
7313 7220 %}
7314 7221
7315 7222 //----------BSWAP Instructions-------------------------------------------------
7316 7223 instruct bytes_reverse_int(rRegI dst) %{
7317 7224 match(Set dst (ReverseBytesI dst));
7318 7225
7319 7226 format %{ "bswapl $dst" %}
7320 7227 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */
7321 7228 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) );
7322 7229 ins_pipe( ialu_reg );
7323 7230 %}
7324 7231
7325 7232 instruct bytes_reverse_long(rRegL dst) %{
7326 7233 match(Set dst (ReverseBytesL dst));
7327 7234
7328 7235 format %{ "bswapq $dst" %}
7329 7236
7330 7237 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */
7331 7238 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) );
7332 7239 ins_pipe( ialu_reg);
7333 7240 %}
7334 7241
7335 7242 instruct bytes_reverse_unsigned_short(rRegI dst) %{
7336 7243 match(Set dst (ReverseBytesUS dst));
7337 7244
7338 7245 format %{ "bswapl $dst\n\t"
7339 7246 "shrl $dst,16\n\t" %}
7340 7247 ins_encode %{
7341 7248 __ bswapl($dst$$Register);
7342 7249 __ shrl($dst$$Register, 16);
7343 7250 %}
7344 7251 ins_pipe( ialu_reg );
7345 7252 %}
7346 7253
7347 7254 instruct bytes_reverse_short(rRegI dst) %{
7348 7255 match(Set dst (ReverseBytesS dst));
7349 7256
7350 7257 format %{ "bswapl $dst\n\t"
7351 7258 "sar $dst,16\n\t" %}
7352 7259 ins_encode %{
7353 7260 __ bswapl($dst$$Register);
7354 7261 __ sarl($dst$$Register, 16);
7355 7262 %}
7356 7263 ins_pipe( ialu_reg );
7357 7264 %}
7358 7265
7359 7266 //---------- Zeros Count Instructions ------------------------------------------
7360 7267
7361 7268 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
7362 7269 predicate(UseCountLeadingZerosInstruction);
7363 7270 match(Set dst (CountLeadingZerosI src));
7364 7271 effect(KILL cr);
7365 7272
7366 7273 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %}
7367 7274 ins_encode %{
7368 7275 __ lzcntl($dst$$Register, $src$$Register);
7369 7276 %}
7370 7277 ins_pipe(ialu_reg);
7371 7278 %}
7372 7279
7373 7280 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{
7374 7281 predicate(!UseCountLeadingZerosInstruction);
7375 7282 match(Set dst (CountLeadingZerosI src));
7376 7283 effect(KILL cr);
7377 7284
7378 7285 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t"
7379 7286 "jnz skip\n\t"
7380 7287 "movl $dst, -1\n"
7381 7288 "skip:\n\t"
7382 7289 "negl $dst\n\t"
7383 7290 "addl $dst, 31" %}
7384 7291 ins_encode %{
7385 7292 Register Rdst = $dst$$Register;
7386 7293 Register Rsrc = $src$$Register;
7387 7294 Label skip;
7388 7295 __ bsrl(Rdst, Rsrc);
7389 7296 __ jccb(Assembler::notZero, skip);
7390 7297 __ movl(Rdst, -1);
7391 7298 __ bind(skip);
7392 7299 __ negl(Rdst);
7393 7300 __ addl(Rdst, BitsPerInt - 1);
7394 7301 %}
7395 7302 ins_pipe(ialu_reg);
7396 7303 %}
7397 7304
7398 7305 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
7399 7306 predicate(UseCountLeadingZerosInstruction);
7400 7307 match(Set dst (CountLeadingZerosL src));
7401 7308 effect(KILL cr);
7402 7309
7403 7310 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %}
7404 7311 ins_encode %{
7405 7312 __ lzcntq($dst$$Register, $src$$Register);
7406 7313 %}
7407 7314 ins_pipe(ialu_reg);
7408 7315 %}
7409 7316
7410 7317 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{
7411 7318 predicate(!UseCountLeadingZerosInstruction);
7412 7319 match(Set dst (CountLeadingZerosL src));
7413 7320 effect(KILL cr);
7414 7321
7415 7322 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t"
7416 7323 "jnz skip\n\t"
7417 7324 "movl $dst, -1\n"
7418 7325 "skip:\n\t"
7419 7326 "negl $dst\n\t"
7420 7327 "addl $dst, 63" %}
7421 7328 ins_encode %{
7422 7329 Register Rdst = $dst$$Register;
7423 7330 Register Rsrc = $src$$Register;
7424 7331 Label skip;
7425 7332 __ bsrq(Rdst, Rsrc);
7426 7333 __ jccb(Assembler::notZero, skip);
7427 7334 __ movl(Rdst, -1);
7428 7335 __ bind(skip);
7429 7336 __ negl(Rdst);
7430 7337 __ addl(Rdst, BitsPerLong - 1);
7431 7338 %}
7432 7339 ins_pipe(ialu_reg);
7433 7340 %}
7434 7341
7435 7342 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
7436 7343 match(Set dst (CountTrailingZerosI src));
7437 7344 effect(KILL cr);
7438 7345
7439 7346 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t"
7440 7347 "jnz done\n\t"
7441 7348 "movl $dst, 32\n"
7442 7349 "done:" %}
7443 7350 ins_encode %{
7444 7351 Register Rdst = $dst$$Register;
7445 7352 Label done;
7446 7353 __ bsfl(Rdst, $src$$Register);
7447 7354 __ jccb(Assembler::notZero, done);
7448 7355 __ movl(Rdst, BitsPerInt);
7449 7356 __ bind(done);
7450 7357 %}
7451 7358 ins_pipe(ialu_reg);
7452 7359 %}
7453 7360
7454 7361 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
7455 7362 match(Set dst (CountTrailingZerosL src));
7456 7363 effect(KILL cr);
7457 7364
7458 7365 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t"
7459 7366 "jnz done\n\t"
7460 7367 "movl $dst, 64\n"
7461 7368 "done:" %}
7462 7369 ins_encode %{
7463 7370 Register Rdst = $dst$$Register;
7464 7371 Label done;
7465 7372 __ bsfq(Rdst, $src$$Register);
7466 7373 __ jccb(Assembler::notZero, done);
7467 7374 __ movl(Rdst, BitsPerLong);
7468 7375 __ bind(done);
7469 7376 %}
7470 7377 ins_pipe(ialu_reg);
7471 7378 %}
7472 7379
7473 7380
7474 7381 //---------- Population Count Instructions -------------------------------------
7475 7382
7476 7383 instruct popCountI(rRegI dst, rRegI src) %{
7477 7384 predicate(UsePopCountInstruction);
7478 7385 match(Set dst (PopCountI src));
7479 7386
7480 7387 format %{ "popcnt $dst, $src" %}
7481 7388 ins_encode %{
7482 7389 __ popcntl($dst$$Register, $src$$Register);
7483 7390 %}
7484 7391 ins_pipe(ialu_reg);
7485 7392 %}
7486 7393
7487 7394 instruct popCountI_mem(rRegI dst, memory mem) %{
7488 7395 predicate(UsePopCountInstruction);
7489 7396 match(Set dst (PopCountI (LoadI mem)));
7490 7397
7491 7398 format %{ "popcnt $dst, $mem" %}
7492 7399 ins_encode %{
7493 7400 __ popcntl($dst$$Register, $mem$$Address);
7494 7401 %}
7495 7402 ins_pipe(ialu_reg);
7496 7403 %}
7497 7404
7498 7405 // Note: Long.bitCount(long) returns an int.
7499 7406 instruct popCountL(rRegI dst, rRegL src) %{
7500 7407 predicate(UsePopCountInstruction);
7501 7408 match(Set dst (PopCountL src));
7502 7409
7503 7410 format %{ "popcnt $dst, $src" %}
7504 7411 ins_encode %{
7505 7412 __ popcntq($dst$$Register, $src$$Register);
7506 7413 %}
7507 7414 ins_pipe(ialu_reg);
7508 7415 %}
7509 7416
7510 7417 // Note: Long.bitCount(long) returns an int.
7511 7418 instruct popCountL_mem(rRegI dst, memory mem) %{
7512 7419 predicate(UsePopCountInstruction);
7513 7420 match(Set dst (PopCountL (LoadL mem)));
7514 7421
7515 7422 format %{ "popcnt $dst, $mem" %}
7516 7423 ins_encode %{
7517 7424 __ popcntq($dst$$Register, $mem$$Address);
7518 7425 %}
7519 7426 ins_pipe(ialu_reg);
7520 7427 %}
7521 7428
7522 7429
7523 7430 //----------MemBar Instructions-----------------------------------------------
7524 7431 // Memory barrier flavors
7525 7432
7526 7433 instruct membar_acquire()
7527 7434 %{
7528 7435 match(MemBarAcquire);
7529 7436 ins_cost(0);
7530 7437
7531 7438 size(0);
7532 7439 format %{ "MEMBAR-acquire ! (empty encoding)" %}
7533 7440 ins_encode();
7534 7441 ins_pipe(empty);
7535 7442 %}
7536 7443
7537 7444 instruct membar_acquire_lock()
7538 7445 %{
7539 7446 match(MemBarAcquire);
7540 7447 predicate(Matcher::prior_fast_lock(n));
7541 7448 ins_cost(0);
7542 7449
7543 7450 size(0);
7544 7451 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %}
7545 7452 ins_encode();
7546 7453 ins_pipe(empty);
7547 7454 %}
7548 7455
7549 7456 instruct membar_release()
7550 7457 %{
7551 7458 match(MemBarRelease);
7552 7459 ins_cost(0);
7553 7460
7554 7461 size(0);
7555 7462 format %{ "MEMBAR-release ! (empty encoding)" %}
7556 7463 ins_encode();
7557 7464 ins_pipe(empty);
7558 7465 %}
7559 7466
7560 7467 instruct membar_release_lock()
7561 7468 %{
7562 7469 match(MemBarRelease);
7563 7470 predicate(Matcher::post_fast_unlock(n));
7564 7471 ins_cost(0);
7565 7472
7566 7473 size(0);
7567 7474 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
7568 7475 ins_encode();
7569 7476 ins_pipe(empty);
7570 7477 %}
7571 7478
7572 7479 instruct membar_volatile(rFlagsReg cr) %{
7573 7480 match(MemBarVolatile);
7574 7481 effect(KILL cr);
7575 7482 ins_cost(400);
7576 7483
7577 7484 format %{
7578 7485 $$template
7579 7486 if (os::is_MP()) {
7580 7487 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
7581 7488 } else {
7582 7489 $$emit$$"MEMBAR-volatile ! (empty encoding)"
7583 7490 }
7584 7491 %}
7585 7492 ins_encode %{
7586 7493 __ membar(Assembler::StoreLoad);
7587 7494 %}
7588 7495 ins_pipe(pipe_slow);
7589 7496 %}
7590 7497
7591 7498 instruct unnecessary_membar_volatile()
7592 7499 %{
7593 7500 match(MemBarVolatile);
7594 7501 predicate(Matcher::post_store_load_barrier(n));
7595 7502 ins_cost(0);
7596 7503
7597 7504 size(0);
7598 7505 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
7599 7506 ins_encode();
7600 7507 ins_pipe(empty);
7601 7508 %}
7602 7509
7603 7510 //----------Move Instructions--------------------------------------------------
7604 7511
7605 7512 instruct castX2P(rRegP dst, rRegL src)
7606 7513 %{
7607 7514 match(Set dst (CastX2P src));
7608 7515
7609 7516 format %{ "movq $dst, $src\t# long->ptr" %}
7610 7517 ins_encode(enc_copy_wide(dst, src));
7611 7518 ins_pipe(ialu_reg_reg); // XXX
7612 7519 %}
7613 7520
7614 7521 instruct castP2X(rRegL dst, rRegP src)
7615 7522 %{
7616 7523 match(Set dst (CastP2X src));
7617 7524
7618 7525 format %{ "movq $dst, $src\t# ptr -> long" %}
7619 7526 ins_encode(enc_copy_wide(dst, src));
7620 7527 ins_pipe(ialu_reg_reg); // XXX
7621 7528 %}
7622 7529
7623 7530
7624 7531 // Convert oop pointer into compressed form
7625 7532 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
7626 7533 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
7627 7534 match(Set dst (EncodeP src));
7628 7535 effect(KILL cr);
7629 7536 format %{ "encode_heap_oop $dst,$src" %}
7630 7537 ins_encode %{
7631 7538 Register s = $src$$Register;
7632 7539 Register d = $dst$$Register;
7633 7540 if (s != d) {
7634 7541 __ movq(d, s);
7635 7542 }
7636 7543 __ encode_heap_oop(d);
7637 7544 %}
7638 7545 ins_pipe(ialu_reg_long);
7639 7546 %}
7640 7547
7641 7548 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
7642 7549 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
7643 7550 match(Set dst (EncodeP src));
7644 7551 effect(KILL cr);
7645 7552 format %{ "encode_heap_oop_not_null $dst,$src" %}
7646 7553 ins_encode %{
7647 7554 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
7648 7555 %}
7649 7556 ins_pipe(ialu_reg_long);
7650 7557 %}
7651 7558
7652 7559 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
7653 7560 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
7654 7561 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
7655 7562 match(Set dst (DecodeN src));
7656 7563 effect(KILL cr);
7657 7564 format %{ "decode_heap_oop $dst,$src" %}
7658 7565 ins_encode %{
7659 7566 Register s = $src$$Register;
7660 7567 Register d = $dst$$Register;
7661 7568 if (s != d) {
7662 7569 __ movq(d, s);
7663 7570 }
7664 7571 __ decode_heap_oop(d);
7665 7572 %}
7666 7573 ins_pipe(ialu_reg_long);
7667 7574 %}
7668 7575
7669 7576 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
7670 7577 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
7671 7578 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
7672 7579 match(Set dst (DecodeN src));
7673 7580 effect(KILL cr);
7674 7581 format %{ "decode_heap_oop_not_null $dst,$src" %}
7675 7582 ins_encode %{
7676 7583 Register s = $src$$Register;
7677 7584 Register d = $dst$$Register;
7678 7585 if (s != d) {
7679 7586 __ decode_heap_oop_not_null(d, s);
7680 7587 } else {
7681 7588 __ decode_heap_oop_not_null(d);
7682 7589 }
7683 7590 %}
7684 7591 ins_pipe(ialu_reg_long);
7685 7592 %}
7686 7593
↓ open down ↓ |
946 lines elided |
↑ open up ↑ |
7687 7594
7688 7595 //----------Conditional Move---------------------------------------------------
7689 7596 // Jump
7690 7597 // dummy instruction for generating temp registers
7691 7598 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
7692 7599 match(Jump (LShiftL switch_val shift));
7693 7600 ins_cost(350);
7694 7601 predicate(false);
7695 7602 effect(TEMP dest);
7696 7603
7697 - format %{ "leaq $dest, table_base\n\t"
7604 + format %{ "leaq $dest, [$constantaddress]\n\t"
7698 7605 "jmp [$dest + $switch_val << $shift]\n\t" %}
7699 - ins_encode(jump_enc_offset(switch_val, shift, dest));
7606 + ins_encode %{
7607 + // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
7608 + // to do that and the compiler is using that register as one it can allocate.
7609 + // So we build it all by hand.
7610 + // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
7611 + // ArrayAddress dispatch(table, index);
7612 + Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
7613 + __ lea($dest$$Register, $constantaddress);
7614 + __ jmp(dispatch);
7615 + %}
7700 7616 ins_pipe(pipe_jmp);
7701 7617 ins_pc_relative(1);
7702 7618 %}
7703 7619
7704 7620 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
7705 7621 match(Jump (AddL (LShiftL switch_val shift) offset));
7706 7622 ins_cost(350);
7707 7623 effect(TEMP dest);
7708 7624
7709 - format %{ "leaq $dest, table_base\n\t"
7625 + format %{ "leaq $dest, [$constantaddress]\n\t"
7710 7626 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %}
7711 - ins_encode(jump_enc_addr(switch_val, shift, offset, dest));
7627 + ins_encode %{
7628 + // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
7629 + // to do that and the compiler is using that register as one it can allocate.
7630 + // So we build it all by hand.
7631 + // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
7632 + // ArrayAddress dispatch(table, index);
7633 + Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
7634 + __ lea($dest$$Register, $constantaddress);
7635 + __ jmp(dispatch);
7636 + %}
7712 7637 ins_pipe(pipe_jmp);
7713 7638 ins_pc_relative(1);
7714 7639 %}
7715 7640
7716 7641 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
7717 7642 match(Jump switch_val);
7718 7643 ins_cost(350);
7719 7644 effect(TEMP dest);
7720 7645
7721 - format %{ "leaq $dest, table_base\n\t"
7646 + format %{ "leaq $dest, [$constantaddress]\n\t"
7722 7647 "jmp [$dest + $switch_val]\n\t" %}
7723 - ins_encode(jump_enc(switch_val, dest));
7648 + ins_encode %{
7649 + // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
7650 + // to do that and the compiler is using that register as one it can allocate.
7651 + // So we build it all by hand.
7652 + // Address index(noreg, switch_reg, Address::times_1);
7653 + // ArrayAddress dispatch(table, index);
7654 + Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1);
7655 + __ lea($dest$$Register, $constantaddress);
7656 + __ jmp(dispatch);
7657 + %}
7724 7658 ins_pipe(pipe_jmp);
7725 7659 ins_pc_relative(1);
7726 7660 %}
7727 7661
7728 7662 // Conditional move
7729 7663 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
7730 7664 %{
7731 7665 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7732 7666
7733 7667 ins_cost(200); // XXX
7734 7668 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
7735 7669 opcode(0x0F, 0x40);
7736 7670 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7737 7671 ins_pipe(pipe_cmov_reg);
7738 7672 %}
7739 7673
7740 7674 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
7741 7675 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7742 7676
7743 7677 ins_cost(200); // XXX
7744 7678 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
7745 7679 opcode(0x0F, 0x40);
7746 7680 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7747 7681 ins_pipe(pipe_cmov_reg);
7748 7682 %}
7749 7683
7750 7684 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
7751 7685 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7752 7686 ins_cost(200);
7753 7687 expand %{
7754 7688 cmovI_regU(cop, cr, dst, src);
7755 7689 %}
7756 7690 %}
7757 7691
7758 7692 // Conditional move
7759 7693 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
7760 7694 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7761 7695
7762 7696 ins_cost(250); // XXX
7763 7697 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
7764 7698 opcode(0x0F, 0x40);
7765 7699 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
7766 7700 ins_pipe(pipe_cmov_mem);
7767 7701 %}
7768 7702
7769 7703 // Conditional move
7770 7704 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
7771 7705 %{
7772 7706 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7773 7707
7774 7708 ins_cost(250); // XXX
7775 7709 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
7776 7710 opcode(0x0F, 0x40);
7777 7711 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
7778 7712 ins_pipe(pipe_cmov_mem);
7779 7713 %}
7780 7714
7781 7715 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
7782 7716 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7783 7717 ins_cost(250);
7784 7718 expand %{
7785 7719 cmovI_memU(cop, cr, dst, src);
7786 7720 %}
7787 7721 %}
7788 7722
7789 7723 // Conditional move
7790 7724 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
7791 7725 %{
7792 7726 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7793 7727
7794 7728 ins_cost(200); // XXX
7795 7729 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
7796 7730 opcode(0x0F, 0x40);
7797 7731 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7798 7732 ins_pipe(pipe_cmov_reg);
7799 7733 %}
7800 7734
7801 7735 // Conditional move
7802 7736 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
7803 7737 %{
7804 7738 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7805 7739
7806 7740 ins_cost(200); // XXX
7807 7741 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
7808 7742 opcode(0x0F, 0x40);
7809 7743 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7810 7744 ins_pipe(pipe_cmov_reg);
7811 7745 %}
7812 7746
7813 7747 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
7814 7748 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7815 7749 ins_cost(200);
7816 7750 expand %{
7817 7751 cmovN_regU(cop, cr, dst, src);
7818 7752 %}
7819 7753 %}
7820 7754
7821 7755 // Conditional move
7822 7756 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
7823 7757 %{
7824 7758 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7825 7759
7826 7760 ins_cost(200); // XXX
7827 7761 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %}
7828 7762 opcode(0x0F, 0x40);
7829 7763 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7830 7764 ins_pipe(pipe_cmov_reg); // XXX
7831 7765 %}
7832 7766
7833 7767 // Conditional move
7834 7768 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
7835 7769 %{
7836 7770 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7837 7771
7838 7772 ins_cost(200); // XXX
7839 7773 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %}
7840 7774 opcode(0x0F, 0x40);
7841 7775 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7842 7776 ins_pipe(pipe_cmov_reg); // XXX
7843 7777 %}
7844 7778
7845 7779 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
7846 7780 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7847 7781 ins_cost(200);
7848 7782 expand %{
7849 7783 cmovP_regU(cop, cr, dst, src);
7850 7784 %}
7851 7785 %}
7852 7786
7853 7787 // DISABLED: Requires the ADLC to emit a bottom_type call that
7854 7788 // correctly meets the two pointer arguments; one is an incoming
7855 7789 // register but the other is a memory operand. ALSO appears to
7856 7790 // be buggy with implicit null checks.
7857 7791 //
7858 7792 //// Conditional move
7859 7793 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src)
7860 7794 //%{
7861 7795 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
7862 7796 // ins_cost(250);
7863 7797 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
7864 7798 // opcode(0x0F,0x40);
7865 7799 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
7866 7800 // ins_pipe( pipe_cmov_mem );
7867 7801 //%}
7868 7802 //
7869 7803 //// Conditional move
7870 7804 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src)
7871 7805 //%{
7872 7806 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
7873 7807 // ins_cost(250);
7874 7808 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
7875 7809 // opcode(0x0F,0x40);
7876 7810 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
7877 7811 // ins_pipe( pipe_cmov_mem );
7878 7812 //%}
7879 7813
7880 7814 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src)
7881 7815 %{
7882 7816 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7883 7817
7884 7818 ins_cost(200); // XXX
7885 7819 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
7886 7820 opcode(0x0F, 0x40);
7887 7821 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7888 7822 ins_pipe(pipe_cmov_reg); // XXX
7889 7823 %}
7890 7824
7891 7825 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src)
7892 7826 %{
7893 7827 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7894 7828
7895 7829 ins_cost(200); // XXX
7896 7830 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
7897 7831 opcode(0x0F, 0x40);
7898 7832 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7899 7833 ins_pipe(pipe_cmov_mem); // XXX
7900 7834 %}
7901 7835
7902 7836 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src)
7903 7837 %{
7904 7838 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7905 7839
7906 7840 ins_cost(200); // XXX
7907 7841 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7908 7842 opcode(0x0F, 0x40);
7909 7843 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7910 7844 ins_pipe(pipe_cmov_reg); // XXX
7911 7845 %}
7912 7846
7913 7847 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
7914 7848 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7915 7849 ins_cost(200);
7916 7850 expand %{
7917 7851 cmovL_regU(cop, cr, dst, src);
7918 7852 %}
7919 7853 %}
7920 7854
7921 7855 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
7922 7856 %{
7923 7857 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7924 7858
7925 7859 ins_cost(200); // XXX
7926 7860 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7927 7861 opcode(0x0F, 0x40);
7928 7862 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7929 7863 ins_pipe(pipe_cmov_mem); // XXX
7930 7864 %}
7931 7865
7932 7866 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
7933 7867 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7934 7868 ins_cost(200);
7935 7869 expand %{
7936 7870 cmovL_memU(cop, cr, dst, src);
7937 7871 %}
7938 7872 %}
7939 7873
7940 7874 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
7941 7875 %{
7942 7876 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7943 7877
7944 7878 ins_cost(200); // XXX
7945 7879 format %{ "jn$cop skip\t# signed cmove float\n\t"
7946 7880 "movss $dst, $src\n"
7947 7881 "skip:" %}
7948 7882 ins_encode(enc_cmovf_branch(cop, dst, src));
7949 7883 ins_pipe(pipe_slow);
7950 7884 %}
7951 7885
7952 7886 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
7953 7887 // %{
7954 7888 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src))));
7955 7889
7956 7890 // ins_cost(200); // XXX
7957 7891 // format %{ "jn$cop skip\t# signed cmove float\n\t"
7958 7892 // "movss $dst, $src\n"
7959 7893 // "skip:" %}
7960 7894 // ins_encode(enc_cmovf_mem_branch(cop, dst, src));
7961 7895 // ins_pipe(pipe_slow);
7962 7896 // %}
7963 7897
7964 7898 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
7965 7899 %{
7966 7900 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7967 7901
7968 7902 ins_cost(200); // XXX
7969 7903 format %{ "jn$cop skip\t# unsigned cmove float\n\t"
7970 7904 "movss $dst, $src\n"
7971 7905 "skip:" %}
7972 7906 ins_encode(enc_cmovf_branch(cop, dst, src));
7973 7907 ins_pipe(pipe_slow);
7974 7908 %}
7975 7909
7976 7910 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
7977 7911 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7978 7912 ins_cost(200);
7979 7913 expand %{
7980 7914 cmovF_regU(cop, cr, dst, src);
7981 7915 %}
7982 7916 %}
7983 7917
7984 7918 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
7985 7919 %{
7986 7920 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7987 7921
7988 7922 ins_cost(200); // XXX
7989 7923 format %{ "jn$cop skip\t# signed cmove double\n\t"
7990 7924 "movsd $dst, $src\n"
7991 7925 "skip:" %}
7992 7926 ins_encode(enc_cmovd_branch(cop, dst, src));
7993 7927 ins_pipe(pipe_slow);
7994 7928 %}
7995 7929
7996 7930 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
7997 7931 %{
7998 7932 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7999 7933
8000 7934 ins_cost(200); // XXX
8001 7935 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
8002 7936 "movsd $dst, $src\n"
8003 7937 "skip:" %}
8004 7938 ins_encode(enc_cmovd_branch(cop, dst, src));
8005 7939 ins_pipe(pipe_slow);
8006 7940 %}
8007 7941
8008 7942 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
8009 7943 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
8010 7944 ins_cost(200);
8011 7945 expand %{
8012 7946 cmovD_regU(cop, cr, dst, src);
8013 7947 %}
8014 7948 %}
8015 7949
8016 7950 //----------Arithmetic Instructions--------------------------------------------
8017 7951 //----------Addition Instructions----------------------------------------------
8018 7952
8019 7953 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8020 7954 %{
8021 7955 match(Set dst (AddI dst src));
8022 7956 effect(KILL cr);
8023 7957
8024 7958 format %{ "addl $dst, $src\t# int" %}
8025 7959 opcode(0x03);
8026 7960 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8027 7961 ins_pipe(ialu_reg_reg);
8028 7962 %}
8029 7963
8030 7964 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8031 7965 %{
8032 7966 match(Set dst (AddI dst src));
8033 7967 effect(KILL cr);
8034 7968
8035 7969 format %{ "addl $dst, $src\t# int" %}
8036 7970 opcode(0x81, 0x00); /* /0 id */
8037 7971 ins_encode(OpcSErm(dst, src), Con8or32(src));
8038 7972 ins_pipe( ialu_reg );
8039 7973 %}
8040 7974
8041 7975 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8042 7976 %{
8043 7977 match(Set dst (AddI dst (LoadI src)));
8044 7978 effect(KILL cr);
8045 7979
8046 7980 ins_cost(125); // XXX
8047 7981 format %{ "addl $dst, $src\t# int" %}
8048 7982 opcode(0x03);
8049 7983 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
8050 7984 ins_pipe(ialu_reg_mem);
8051 7985 %}
8052 7986
8053 7987 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8054 7988 %{
8055 7989 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
8056 7990 effect(KILL cr);
8057 7991
8058 7992 ins_cost(150); // XXX
8059 7993 format %{ "addl $dst, $src\t# int" %}
8060 7994 opcode(0x01); /* Opcode 01 /r */
8061 7995 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
8062 7996 ins_pipe(ialu_mem_reg);
8063 7997 %}
8064 7998
8065 7999 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr)
8066 8000 %{
8067 8001 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
8068 8002 effect(KILL cr);
8069 8003
8070 8004 ins_cost(125); // XXX
8071 8005 format %{ "addl $dst, $src\t# int" %}
8072 8006 opcode(0x81); /* Opcode 81 /0 id */
8073 8007 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
8074 8008 ins_pipe(ialu_mem_imm);
8075 8009 %}
8076 8010
8077 8011 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
8078 8012 %{
8079 8013 predicate(UseIncDec);
8080 8014 match(Set dst (AddI dst src));
8081 8015 effect(KILL cr);
8082 8016
8083 8017 format %{ "incl $dst\t# int" %}
8084 8018 opcode(0xFF, 0x00); // FF /0
8085 8019 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8086 8020 ins_pipe(ialu_reg);
8087 8021 %}
8088 8022
8089 8023 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr)
8090 8024 %{
8091 8025 predicate(UseIncDec);
8092 8026 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
8093 8027 effect(KILL cr);
8094 8028
8095 8029 ins_cost(125); // XXX
8096 8030 format %{ "incl $dst\t# int" %}
8097 8031 opcode(0xFF); /* Opcode FF /0 */
8098 8032 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst));
8099 8033 ins_pipe(ialu_mem_imm);
8100 8034 %}
8101 8035
8102 8036 // XXX why does that use AddI
8103 8037 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr)
8104 8038 %{
8105 8039 predicate(UseIncDec);
8106 8040 match(Set dst (AddI dst src));
8107 8041 effect(KILL cr);
8108 8042
8109 8043 format %{ "decl $dst\t# int" %}
8110 8044 opcode(0xFF, 0x01); // FF /1
8111 8045 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8112 8046 ins_pipe(ialu_reg);
8113 8047 %}
8114 8048
8115 8049 // XXX why does that use AddI
8116 8050 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr)
8117 8051 %{
8118 8052 predicate(UseIncDec);
8119 8053 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
8120 8054 effect(KILL cr);
8121 8055
8122 8056 ins_cost(125); // XXX
8123 8057 format %{ "decl $dst\t# int" %}
8124 8058 opcode(0xFF); /* Opcode FF /1 */
8125 8059 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst));
8126 8060 ins_pipe(ialu_mem_imm);
8127 8061 %}
8128 8062
8129 8063 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1)
8130 8064 %{
8131 8065 match(Set dst (AddI src0 src1));
8132 8066
8133 8067 ins_cost(110);
8134 8068 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %}
8135 8069 opcode(0x8D); /* 0x8D /r */
8136 8070 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
8137 8071 ins_pipe(ialu_reg_reg);
8138 8072 %}
8139 8073
8140 8074 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8141 8075 %{
8142 8076 match(Set dst (AddL dst src));
8143 8077 effect(KILL cr);
8144 8078
8145 8079 format %{ "addq $dst, $src\t# long" %}
8146 8080 opcode(0x03);
8147 8081 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8148 8082 ins_pipe(ialu_reg_reg);
8149 8083 %}
8150 8084
8151 8085 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
8152 8086 %{
8153 8087 match(Set dst (AddL dst src));
8154 8088 effect(KILL cr);
8155 8089
8156 8090 format %{ "addq $dst, $src\t# long" %}
8157 8091 opcode(0x81, 0x00); /* /0 id */
8158 8092 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
8159 8093 ins_pipe( ialu_reg );
8160 8094 %}
8161 8095
8162 8096 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
8163 8097 %{
8164 8098 match(Set dst (AddL dst (LoadL src)));
8165 8099 effect(KILL cr);
8166 8100
8167 8101 ins_cost(125); // XXX
8168 8102 format %{ "addq $dst, $src\t# long" %}
8169 8103 opcode(0x03);
8170 8104 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
8171 8105 ins_pipe(ialu_reg_mem);
8172 8106 %}
8173 8107
8174 8108 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
8175 8109 %{
8176 8110 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
8177 8111 effect(KILL cr);
8178 8112
8179 8113 ins_cost(150); // XXX
8180 8114 format %{ "addq $dst, $src\t# long" %}
8181 8115 opcode(0x01); /* Opcode 01 /r */
8182 8116 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
8183 8117 ins_pipe(ialu_mem_reg);
8184 8118 %}
8185 8119
8186 8120 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
8187 8121 %{
8188 8122 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
8189 8123 effect(KILL cr);
8190 8124
8191 8125 ins_cost(125); // XXX
8192 8126 format %{ "addq $dst, $src\t# long" %}
8193 8127 opcode(0x81); /* Opcode 81 /0 id */
8194 8128 ins_encode(REX_mem_wide(dst),
8195 8129 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
8196 8130 ins_pipe(ialu_mem_imm);
8197 8131 %}
8198 8132
8199 8133 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr)
8200 8134 %{
8201 8135 predicate(UseIncDec);
8202 8136 match(Set dst (AddL dst src));
8203 8137 effect(KILL cr);
8204 8138
8205 8139 format %{ "incq $dst\t# long" %}
8206 8140 opcode(0xFF, 0x00); // FF /0
8207 8141 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8208 8142 ins_pipe(ialu_reg);
8209 8143 %}
8210 8144
8211 8145 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr)
8212 8146 %{
8213 8147 predicate(UseIncDec);
8214 8148 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
8215 8149 effect(KILL cr);
8216 8150
8217 8151 ins_cost(125); // XXX
8218 8152 format %{ "incq $dst\t# long" %}
8219 8153 opcode(0xFF); /* Opcode FF /0 */
8220 8154 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst));
8221 8155 ins_pipe(ialu_mem_imm);
8222 8156 %}
8223 8157
8224 8158 // XXX why does that use AddL
8225 8159 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr)
8226 8160 %{
8227 8161 predicate(UseIncDec);
8228 8162 match(Set dst (AddL dst src));
8229 8163 effect(KILL cr);
8230 8164
8231 8165 format %{ "decq $dst\t# long" %}
8232 8166 opcode(0xFF, 0x01); // FF /1
8233 8167 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8234 8168 ins_pipe(ialu_reg);
8235 8169 %}
8236 8170
8237 8171 // XXX why does that use AddL
8238 8172 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr)
8239 8173 %{
8240 8174 predicate(UseIncDec);
8241 8175 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
8242 8176 effect(KILL cr);
8243 8177
8244 8178 ins_cost(125); // XXX
8245 8179 format %{ "decq $dst\t# long" %}
8246 8180 opcode(0xFF); /* Opcode FF /1 */
8247 8181 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst));
8248 8182 ins_pipe(ialu_mem_imm);
8249 8183 %}
8250 8184
8251 8185 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1)
8252 8186 %{
8253 8187 match(Set dst (AddL src0 src1));
8254 8188
8255 8189 ins_cost(110);
8256 8190 format %{ "leaq $dst, [$src0 + $src1]\t# long" %}
8257 8191 opcode(0x8D); /* 0x8D /r */
8258 8192 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
8259 8193 ins_pipe(ialu_reg_reg);
8260 8194 %}
8261 8195
8262 8196 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr)
8263 8197 %{
8264 8198 match(Set dst (AddP dst src));
8265 8199 effect(KILL cr);
8266 8200
8267 8201 format %{ "addq $dst, $src\t# ptr" %}
8268 8202 opcode(0x03);
8269 8203 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8270 8204 ins_pipe(ialu_reg_reg);
8271 8205 %}
8272 8206
8273 8207 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr)
8274 8208 %{
8275 8209 match(Set dst (AddP dst src));
8276 8210 effect(KILL cr);
8277 8211
8278 8212 format %{ "addq $dst, $src\t# ptr" %}
8279 8213 opcode(0x81, 0x00); /* /0 id */
8280 8214 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
8281 8215 ins_pipe( ialu_reg );
8282 8216 %}
8283 8217
8284 8218 // XXX addP mem ops ????
8285 8219
8286 8220 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1)
8287 8221 %{
8288 8222 match(Set dst (AddP src0 src1));
8289 8223
8290 8224 ins_cost(110);
8291 8225 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %}
8292 8226 opcode(0x8D); /* 0x8D /r */
8293 8227 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX
8294 8228 ins_pipe(ialu_reg_reg);
8295 8229 %}
8296 8230
8297 8231 instruct checkCastPP(rRegP dst)
8298 8232 %{
8299 8233 match(Set dst (CheckCastPP dst));
8300 8234
8301 8235 size(0);
8302 8236 format %{ "# checkcastPP of $dst" %}
8303 8237 ins_encode(/* empty encoding */);
8304 8238 ins_pipe(empty);
8305 8239 %}
8306 8240
8307 8241 instruct castPP(rRegP dst)
8308 8242 %{
8309 8243 match(Set dst (CastPP dst));
8310 8244
8311 8245 size(0);
8312 8246 format %{ "# castPP of $dst" %}
8313 8247 ins_encode(/* empty encoding */);
8314 8248 ins_pipe(empty);
8315 8249 %}
8316 8250
8317 8251 instruct castII(rRegI dst)
8318 8252 %{
8319 8253 match(Set dst (CastII dst));
8320 8254
8321 8255 size(0);
8322 8256 format %{ "# castII of $dst" %}
8323 8257 ins_encode(/* empty encoding */);
8324 8258 ins_cost(0);
8325 8259 ins_pipe(empty);
8326 8260 %}
8327 8261
8328 8262 // LoadP-locked same as a regular LoadP when used with compare-swap
8329 8263 instruct loadPLocked(rRegP dst, memory mem)
8330 8264 %{
8331 8265 match(Set dst (LoadPLocked mem));
8332 8266
8333 8267 ins_cost(125); // XXX
8334 8268 format %{ "movq $dst, $mem\t# ptr locked" %}
8335 8269 opcode(0x8B);
8336 8270 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
8337 8271 ins_pipe(ialu_reg_mem); // XXX
8338 8272 %}
8339 8273
8340 8274 // LoadL-locked - same as a regular LoadL when used with compare-swap
8341 8275 instruct loadLLocked(rRegL dst, memory mem)
8342 8276 %{
8343 8277 match(Set dst (LoadLLocked mem));
8344 8278
8345 8279 ins_cost(125); // XXX
8346 8280 format %{ "movq $dst, $mem\t# long locked" %}
8347 8281 opcode(0x8B);
8348 8282 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
8349 8283 ins_pipe(ialu_reg_mem); // XXX
8350 8284 %}
8351 8285
8352 8286 // Conditional-store of the updated heap-top.
8353 8287 // Used during allocation of the shared heap.
8354 8288 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
8355 8289
8356 8290 instruct storePConditional(memory heap_top_ptr,
8357 8291 rax_RegP oldval, rRegP newval,
8358 8292 rFlagsReg cr)
8359 8293 %{
8360 8294 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
8361 8295
8362 8296 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
8363 8297 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
8364 8298 opcode(0x0F, 0xB1);
8365 8299 ins_encode(lock_prefix,
8366 8300 REX_reg_mem_wide(newval, heap_top_ptr),
8367 8301 OpcP, OpcS,
8368 8302 reg_mem(newval, heap_top_ptr));
8369 8303 ins_pipe(pipe_cmpxchg);
8370 8304 %}
8371 8305
8372 8306 // Conditional-store of an int value.
8373 8307 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
8374 8308 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
8375 8309 %{
8376 8310 match(Set cr (StoreIConditional mem (Binary oldval newval)));
8377 8311 effect(KILL oldval);
8378 8312
8379 8313 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
8380 8314 opcode(0x0F, 0xB1);
8381 8315 ins_encode(lock_prefix,
8382 8316 REX_reg_mem(newval, mem),
8383 8317 OpcP, OpcS,
8384 8318 reg_mem(newval, mem));
8385 8319 ins_pipe(pipe_cmpxchg);
8386 8320 %}
8387 8321
8388 8322 // Conditional-store of a long value.
8389 8323 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
8390 8324 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
8391 8325 %{
8392 8326 match(Set cr (StoreLConditional mem (Binary oldval newval)));
8393 8327 effect(KILL oldval);
8394 8328
8395 8329 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
8396 8330 opcode(0x0F, 0xB1);
8397 8331 ins_encode(lock_prefix,
8398 8332 REX_reg_mem_wide(newval, mem),
8399 8333 OpcP, OpcS,
8400 8334 reg_mem(newval, mem));
8401 8335 ins_pipe(pipe_cmpxchg);
8402 8336 %}
8403 8337
8404 8338
8405 8339 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
8406 8340 instruct compareAndSwapP(rRegI res,
8407 8341 memory mem_ptr,
8408 8342 rax_RegP oldval, rRegP newval,
8409 8343 rFlagsReg cr)
8410 8344 %{
8411 8345 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
8412 8346 effect(KILL cr, KILL oldval);
8413 8347
8414 8348 format %{ "cmpxchgq $mem_ptr,$newval\t# "
8415 8349 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
8416 8350 "sete $res\n\t"
8417 8351 "movzbl $res, $res" %}
8418 8352 opcode(0x0F, 0xB1);
8419 8353 ins_encode(lock_prefix,
8420 8354 REX_reg_mem_wide(newval, mem_ptr),
8421 8355 OpcP, OpcS,
8422 8356 reg_mem(newval, mem_ptr),
8423 8357 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
8424 8358 REX_reg_breg(res, res), // movzbl
8425 8359 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
8426 8360 ins_pipe( pipe_cmpxchg );
8427 8361 %}
8428 8362
8429 8363 instruct compareAndSwapL(rRegI res,
8430 8364 memory mem_ptr,
8431 8365 rax_RegL oldval, rRegL newval,
8432 8366 rFlagsReg cr)
8433 8367 %{
8434 8368 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
8435 8369 effect(KILL cr, KILL oldval);
8436 8370
8437 8371 format %{ "cmpxchgq $mem_ptr,$newval\t# "
8438 8372 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
8439 8373 "sete $res\n\t"
8440 8374 "movzbl $res, $res" %}
8441 8375 opcode(0x0F, 0xB1);
8442 8376 ins_encode(lock_prefix,
8443 8377 REX_reg_mem_wide(newval, mem_ptr),
8444 8378 OpcP, OpcS,
8445 8379 reg_mem(newval, mem_ptr),
8446 8380 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
8447 8381 REX_reg_breg(res, res), // movzbl
8448 8382 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
8449 8383 ins_pipe( pipe_cmpxchg );
8450 8384 %}
8451 8385
8452 8386 instruct compareAndSwapI(rRegI res,
8453 8387 memory mem_ptr,
8454 8388 rax_RegI oldval, rRegI newval,
8455 8389 rFlagsReg cr)
8456 8390 %{
8457 8391 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
8458 8392 effect(KILL cr, KILL oldval);
8459 8393
8460 8394 format %{ "cmpxchgl $mem_ptr,$newval\t# "
8461 8395 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
8462 8396 "sete $res\n\t"
8463 8397 "movzbl $res, $res" %}
8464 8398 opcode(0x0F, 0xB1);
8465 8399 ins_encode(lock_prefix,
8466 8400 REX_reg_mem(newval, mem_ptr),
8467 8401 OpcP, OpcS,
8468 8402 reg_mem(newval, mem_ptr),
8469 8403 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
8470 8404 REX_reg_breg(res, res), // movzbl
8471 8405 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
8472 8406 ins_pipe( pipe_cmpxchg );
8473 8407 %}
8474 8408
8475 8409
8476 8410 instruct compareAndSwapN(rRegI res,
8477 8411 memory mem_ptr,
8478 8412 rax_RegN oldval, rRegN newval,
8479 8413 rFlagsReg cr) %{
8480 8414 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
8481 8415 effect(KILL cr, KILL oldval);
8482 8416
8483 8417 format %{ "cmpxchgl $mem_ptr,$newval\t# "
8484 8418 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
8485 8419 "sete $res\n\t"
8486 8420 "movzbl $res, $res" %}
8487 8421 opcode(0x0F, 0xB1);
8488 8422 ins_encode(lock_prefix,
8489 8423 REX_reg_mem(newval, mem_ptr),
8490 8424 OpcP, OpcS,
8491 8425 reg_mem(newval, mem_ptr),
8492 8426 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
8493 8427 REX_reg_breg(res, res), // movzbl
8494 8428 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
8495 8429 ins_pipe( pipe_cmpxchg );
8496 8430 %}
8497 8431
8498 8432 //----------Subtraction Instructions-------------------------------------------
8499 8433
8500 8434 // Integer Subtraction Instructions
8501 8435 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8502 8436 %{
8503 8437 match(Set dst (SubI dst src));
8504 8438 effect(KILL cr);
8505 8439
8506 8440 format %{ "subl $dst, $src\t# int" %}
8507 8441 opcode(0x2B);
8508 8442 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8509 8443 ins_pipe(ialu_reg_reg);
8510 8444 %}
8511 8445
8512 8446 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8513 8447 %{
8514 8448 match(Set dst (SubI dst src));
8515 8449 effect(KILL cr);
8516 8450
8517 8451 format %{ "subl $dst, $src\t# int" %}
8518 8452 opcode(0x81, 0x05); /* Opcode 81 /5 */
8519 8453 ins_encode(OpcSErm(dst, src), Con8or32(src));
8520 8454 ins_pipe(ialu_reg);
8521 8455 %}
8522 8456
8523 8457 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8524 8458 %{
8525 8459 match(Set dst (SubI dst (LoadI src)));
8526 8460 effect(KILL cr);
8527 8461
8528 8462 ins_cost(125);
8529 8463 format %{ "subl $dst, $src\t# int" %}
8530 8464 opcode(0x2B);
8531 8465 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
8532 8466 ins_pipe(ialu_reg_mem);
8533 8467 %}
8534 8468
8535 8469 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8536 8470 %{
8537 8471 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
8538 8472 effect(KILL cr);
8539 8473
8540 8474 ins_cost(150);
8541 8475 format %{ "subl $dst, $src\t# int" %}
8542 8476 opcode(0x29); /* Opcode 29 /r */
8543 8477 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
8544 8478 ins_pipe(ialu_mem_reg);
8545 8479 %}
8546 8480
8547 8481 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr)
8548 8482 %{
8549 8483 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
8550 8484 effect(KILL cr);
8551 8485
8552 8486 ins_cost(125); // XXX
8553 8487 format %{ "subl $dst, $src\t# int" %}
8554 8488 opcode(0x81); /* Opcode 81 /5 id */
8555 8489 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
8556 8490 ins_pipe(ialu_mem_imm);
8557 8491 %}
8558 8492
8559 8493 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8560 8494 %{
8561 8495 match(Set dst (SubL dst src));
8562 8496 effect(KILL cr);
8563 8497
8564 8498 format %{ "subq $dst, $src\t# long" %}
8565 8499 opcode(0x2B);
8566 8500 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8567 8501 ins_pipe(ialu_reg_reg);
8568 8502 %}
8569 8503
8570 8504 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr)
8571 8505 %{
8572 8506 match(Set dst (SubL dst src));
8573 8507 effect(KILL cr);
8574 8508
8575 8509 format %{ "subq $dst, $src\t# long" %}
8576 8510 opcode(0x81, 0x05); /* Opcode 81 /5 */
8577 8511 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
8578 8512 ins_pipe(ialu_reg);
8579 8513 %}
8580 8514
8581 8515 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
8582 8516 %{
8583 8517 match(Set dst (SubL dst (LoadL src)));
8584 8518 effect(KILL cr);
8585 8519
8586 8520 ins_cost(125);
8587 8521 format %{ "subq $dst, $src\t# long" %}
8588 8522 opcode(0x2B);
8589 8523 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
8590 8524 ins_pipe(ialu_reg_mem);
8591 8525 %}
8592 8526
8593 8527 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
8594 8528 %{
8595 8529 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
8596 8530 effect(KILL cr);
8597 8531
8598 8532 ins_cost(150);
8599 8533 format %{ "subq $dst, $src\t# long" %}
8600 8534 opcode(0x29); /* Opcode 29 /r */
8601 8535 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
8602 8536 ins_pipe(ialu_mem_reg);
8603 8537 %}
8604 8538
8605 8539 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
8606 8540 %{
8607 8541 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
8608 8542 effect(KILL cr);
8609 8543
8610 8544 ins_cost(125); // XXX
8611 8545 format %{ "subq $dst, $src\t# long" %}
8612 8546 opcode(0x81); /* Opcode 81 /5 id */
8613 8547 ins_encode(REX_mem_wide(dst),
8614 8548 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
8615 8549 ins_pipe(ialu_mem_imm);
8616 8550 %}
8617 8551
8618 8552 // Subtract from a pointer
8619 8553 // XXX hmpf???
8620 8554 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr)
8621 8555 %{
8622 8556 match(Set dst (AddP dst (SubI zero src)));
8623 8557 effect(KILL cr);
8624 8558
8625 8559 format %{ "subq $dst, $src\t# ptr - int" %}
8626 8560 opcode(0x2B);
8627 8561 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8628 8562 ins_pipe(ialu_reg_reg);
8629 8563 %}
8630 8564
8631 8565 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr)
8632 8566 %{
8633 8567 match(Set dst (SubI zero dst));
8634 8568 effect(KILL cr);
8635 8569
8636 8570 format %{ "negl $dst\t# int" %}
8637 8571 opcode(0xF7, 0x03); // Opcode F7 /3
8638 8572 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8639 8573 ins_pipe(ialu_reg);
8640 8574 %}
8641 8575
8642 8576 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr)
8643 8577 %{
8644 8578 match(Set dst (StoreI dst (SubI zero (LoadI dst))));
8645 8579 effect(KILL cr);
8646 8580
8647 8581 format %{ "negl $dst\t# int" %}
8648 8582 opcode(0xF7, 0x03); // Opcode F7 /3
8649 8583 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8650 8584 ins_pipe(ialu_reg);
8651 8585 %}
8652 8586
8653 8587 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr)
8654 8588 %{
8655 8589 match(Set dst (SubL zero dst));
8656 8590 effect(KILL cr);
8657 8591
8658 8592 format %{ "negq $dst\t# long" %}
8659 8593 opcode(0xF7, 0x03); // Opcode F7 /3
8660 8594 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8661 8595 ins_pipe(ialu_reg);
8662 8596 %}
8663 8597
8664 8598 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr)
8665 8599 %{
8666 8600 match(Set dst (StoreL dst (SubL zero (LoadL dst))));
8667 8601 effect(KILL cr);
8668 8602
8669 8603 format %{ "negq $dst\t# long" %}
8670 8604 opcode(0xF7, 0x03); // Opcode F7 /3
8671 8605 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8672 8606 ins_pipe(ialu_reg);
8673 8607 %}
8674 8608
8675 8609
8676 8610 //----------Multiplication/Division Instructions-------------------------------
8677 8611 // Integer Multiplication Instructions
8678 8612 // Multiply Register
8679 8613
8680 8614 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8681 8615 %{
8682 8616 match(Set dst (MulI dst src));
8683 8617 effect(KILL cr);
8684 8618
8685 8619 ins_cost(300);
8686 8620 format %{ "imull $dst, $src\t# int" %}
8687 8621 opcode(0x0F, 0xAF);
8688 8622 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8689 8623 ins_pipe(ialu_reg_reg_alu0);
8690 8624 %}
8691 8625
8692 8626 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr)
8693 8627 %{
8694 8628 match(Set dst (MulI src imm));
8695 8629 effect(KILL cr);
8696 8630
8697 8631 ins_cost(300);
8698 8632 format %{ "imull $dst, $src, $imm\t# int" %}
8699 8633 opcode(0x69); /* 69 /r id */
8700 8634 ins_encode(REX_reg_reg(dst, src),
8701 8635 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
8702 8636 ins_pipe(ialu_reg_reg_alu0);
8703 8637 %}
8704 8638
8705 8639 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr)
8706 8640 %{
8707 8641 match(Set dst (MulI dst (LoadI src)));
8708 8642 effect(KILL cr);
8709 8643
8710 8644 ins_cost(350);
8711 8645 format %{ "imull $dst, $src\t# int" %}
8712 8646 opcode(0x0F, 0xAF);
8713 8647 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src));
8714 8648 ins_pipe(ialu_reg_mem_alu0);
8715 8649 %}
8716 8650
8717 8651 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr)
8718 8652 %{
8719 8653 match(Set dst (MulI (LoadI src) imm));
8720 8654 effect(KILL cr);
8721 8655
8722 8656 ins_cost(300);
8723 8657 format %{ "imull $dst, $src, $imm\t# int" %}
8724 8658 opcode(0x69); /* 69 /r id */
8725 8659 ins_encode(REX_reg_mem(dst, src),
8726 8660 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
8727 8661 ins_pipe(ialu_reg_mem_alu0);
8728 8662 %}
8729 8663
8730 8664 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8731 8665 %{
8732 8666 match(Set dst (MulL dst src));
8733 8667 effect(KILL cr);
8734 8668
8735 8669 ins_cost(300);
8736 8670 format %{ "imulq $dst, $src\t# long" %}
8737 8671 opcode(0x0F, 0xAF);
8738 8672 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src));
8739 8673 ins_pipe(ialu_reg_reg_alu0);
8740 8674 %}
8741 8675
8742 8676 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr)
8743 8677 %{
8744 8678 match(Set dst (MulL src imm));
8745 8679 effect(KILL cr);
8746 8680
8747 8681 ins_cost(300);
8748 8682 format %{ "imulq $dst, $src, $imm\t# long" %}
8749 8683 opcode(0x69); /* 69 /r id */
8750 8684 ins_encode(REX_reg_reg_wide(dst, src),
8751 8685 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
8752 8686 ins_pipe(ialu_reg_reg_alu0);
8753 8687 %}
8754 8688
8755 8689 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr)
8756 8690 %{
8757 8691 match(Set dst (MulL dst (LoadL src)));
8758 8692 effect(KILL cr);
8759 8693
8760 8694 ins_cost(350);
8761 8695 format %{ "imulq $dst, $src\t# long" %}
8762 8696 opcode(0x0F, 0xAF);
8763 8697 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src));
8764 8698 ins_pipe(ialu_reg_mem_alu0);
8765 8699 %}
8766 8700
8767 8701 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr)
8768 8702 %{
8769 8703 match(Set dst (MulL (LoadL src) imm));
8770 8704 effect(KILL cr);
8771 8705
8772 8706 ins_cost(300);
8773 8707 format %{ "imulq $dst, $src, $imm\t# long" %}
8774 8708 opcode(0x69); /* 69 /r id */
8775 8709 ins_encode(REX_reg_mem_wide(dst, src),
8776 8710 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
8777 8711 ins_pipe(ialu_reg_mem_alu0);
8778 8712 %}
8779 8713
8780 8714 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8781 8715 %{
8782 8716 match(Set dst (MulHiL src rax));
8783 8717 effect(USE_KILL rax, KILL cr);
8784 8718
8785 8719 ins_cost(300);
8786 8720 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %}
8787 8721 opcode(0xF7, 0x5); /* Opcode F7 /5 */
8788 8722 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
8789 8723 ins_pipe(ialu_reg_reg_alu0);
8790 8724 %}
8791 8725
8792 8726 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8793 8727 rFlagsReg cr)
8794 8728 %{
8795 8729 match(Set rax (DivI rax div));
8796 8730 effect(KILL rdx, KILL cr);
8797 8731
8798 8732 ins_cost(30*100+10*100); // XXX
8799 8733 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
8800 8734 "jne,s normal\n\t"
8801 8735 "xorl rdx, rdx\n\t"
8802 8736 "cmpl $div, -1\n\t"
8803 8737 "je,s done\n"
8804 8738 "normal: cdql\n\t"
8805 8739 "idivl $div\n"
8806 8740 "done:" %}
8807 8741 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8808 8742 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8809 8743 ins_pipe(ialu_reg_reg_alu0);
8810 8744 %}
8811 8745
8812 8746 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8813 8747 rFlagsReg cr)
8814 8748 %{
8815 8749 match(Set rax (DivL rax div));
8816 8750 effect(KILL rdx, KILL cr);
8817 8751
8818 8752 ins_cost(30*100+10*100); // XXX
8819 8753 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8820 8754 "cmpq rax, rdx\n\t"
8821 8755 "jne,s normal\n\t"
8822 8756 "xorl rdx, rdx\n\t"
8823 8757 "cmpq $div, -1\n\t"
8824 8758 "je,s done\n"
8825 8759 "normal: cdqq\n\t"
8826 8760 "idivq $div\n"
8827 8761 "done:" %}
8828 8762 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8829 8763 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8830 8764 ins_pipe(ialu_reg_reg_alu0);
8831 8765 %}
8832 8766
8833 8767 // Integer DIVMOD with Register, both quotient and mod results
8834 8768 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8835 8769 rFlagsReg cr)
8836 8770 %{
8837 8771 match(DivModI rax div);
8838 8772 effect(KILL cr);
8839 8773
8840 8774 ins_cost(30*100+10*100); // XXX
8841 8775 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
8842 8776 "jne,s normal\n\t"
8843 8777 "xorl rdx, rdx\n\t"
8844 8778 "cmpl $div, -1\n\t"
8845 8779 "je,s done\n"
8846 8780 "normal: cdql\n\t"
8847 8781 "idivl $div\n"
8848 8782 "done:" %}
8849 8783 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8850 8784 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8851 8785 ins_pipe(pipe_slow);
8852 8786 %}
8853 8787
8854 8788 // Long DIVMOD with Register, both quotient and mod results
8855 8789 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8856 8790 rFlagsReg cr)
8857 8791 %{
8858 8792 match(DivModL rax div);
8859 8793 effect(KILL cr);
8860 8794
8861 8795 ins_cost(30*100+10*100); // XXX
8862 8796 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8863 8797 "cmpq rax, rdx\n\t"
8864 8798 "jne,s normal\n\t"
8865 8799 "xorl rdx, rdx\n\t"
8866 8800 "cmpq $div, -1\n\t"
8867 8801 "je,s done\n"
8868 8802 "normal: cdqq\n\t"
8869 8803 "idivq $div\n"
8870 8804 "done:" %}
8871 8805 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8872 8806 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8873 8807 ins_pipe(pipe_slow);
8874 8808 %}
8875 8809
8876 8810 //----------- DivL-By-Constant-Expansions--------------------------------------
8877 8811 // DivI cases are handled by the compiler
8878 8812
8879 8813 // Magic constant, reciprocal of 10
8880 8814 instruct loadConL_0x6666666666666667(rRegL dst)
8881 8815 %{
8882 8816 effect(DEF dst);
8883 8817
8884 8818 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %}
8885 8819 ins_encode(load_immL(dst, 0x6666666666666667));
8886 8820 ins_pipe(ialu_reg);
8887 8821 %}
8888 8822
8889 8823 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8890 8824 %{
8891 8825 effect(DEF dst, USE src, USE_KILL rax, KILL cr);
8892 8826
8893 8827 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %}
8894 8828 opcode(0xF7, 0x5); /* Opcode F7 /5 */
8895 8829 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
8896 8830 ins_pipe(ialu_reg_reg_alu0);
8897 8831 %}
8898 8832
8899 8833 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr)
8900 8834 %{
8901 8835 effect(USE_DEF dst, KILL cr);
8902 8836
8903 8837 format %{ "sarq $dst, #63\t# Used in div-by-10" %}
8904 8838 opcode(0xC1, 0x7); /* C1 /7 ib */
8905 8839 ins_encode(reg_opc_imm_wide(dst, 0x3F));
8906 8840 ins_pipe(ialu_reg);
8907 8841 %}
8908 8842
8909 8843 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr)
8910 8844 %{
8911 8845 effect(USE_DEF dst, KILL cr);
8912 8846
8913 8847 format %{ "sarq $dst, #2\t# Used in div-by-10" %}
8914 8848 opcode(0xC1, 0x7); /* C1 /7 ib */
8915 8849 ins_encode(reg_opc_imm_wide(dst, 0x2));
8916 8850 ins_pipe(ialu_reg);
8917 8851 %}
8918 8852
8919 8853 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div)
8920 8854 %{
8921 8855 match(Set dst (DivL src div));
8922 8856
8923 8857 ins_cost((5+8)*100);
8924 8858 expand %{
8925 8859 rax_RegL rax; // Killed temp
8926 8860 rFlagsReg cr; // Killed
8927 8861 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667
8928 8862 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src
8929 8863 sarL_rReg_63(src, cr); // sarq src, 63
8930 8864 sarL_rReg_2(dst, cr); // sarq rdx, 2
8931 8865 subL_rReg(dst, src, cr); // subl rdx, src
8932 8866 %}
8933 8867 %}
8934 8868
8935 8869 //-----------------------------------------------------------------------------
8936 8870
8937 8871 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div,
8938 8872 rFlagsReg cr)
8939 8873 %{
8940 8874 match(Set rdx (ModI rax div));
8941 8875 effect(KILL rax, KILL cr);
8942 8876
8943 8877 ins_cost(300); // XXX
8944 8878 format %{ "cmpl rax, 0x80000000\t# irem\n\t"
8945 8879 "jne,s normal\n\t"
8946 8880 "xorl rdx, rdx\n\t"
8947 8881 "cmpl $div, -1\n\t"
8948 8882 "je,s done\n"
8949 8883 "normal: cdql\n\t"
8950 8884 "idivl $div\n"
8951 8885 "done:" %}
8952 8886 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8953 8887 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8954 8888 ins_pipe(ialu_reg_reg_alu0);
8955 8889 %}
8956 8890
8957 8891 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div,
8958 8892 rFlagsReg cr)
8959 8893 %{
8960 8894 match(Set rdx (ModL rax div));
8961 8895 effect(KILL rax, KILL cr);
8962 8896
8963 8897 ins_cost(300); // XXX
8964 8898 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t"
8965 8899 "cmpq rax, rdx\n\t"
8966 8900 "jne,s normal\n\t"
8967 8901 "xorl rdx, rdx\n\t"
8968 8902 "cmpq $div, -1\n\t"
8969 8903 "je,s done\n"
8970 8904 "normal: cdqq\n\t"
8971 8905 "idivq $div\n"
8972 8906 "done:" %}
8973 8907 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8974 8908 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8975 8909 ins_pipe(ialu_reg_reg_alu0);
8976 8910 %}
8977 8911
8978 8912 // Integer Shift Instructions
8979 8913 // Shift Left by one
8980 8914 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8981 8915 %{
8982 8916 match(Set dst (LShiftI dst shift));
8983 8917 effect(KILL cr);
8984 8918
8985 8919 format %{ "sall $dst, $shift" %}
8986 8920 opcode(0xD1, 0x4); /* D1 /4 */
8987 8921 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8988 8922 ins_pipe(ialu_reg);
8989 8923 %}
8990 8924
8991 8925 // Shift Left by one
8992 8926 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8993 8927 %{
8994 8928 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8995 8929 effect(KILL cr);
8996 8930
8997 8931 format %{ "sall $dst, $shift\t" %}
8998 8932 opcode(0xD1, 0x4); /* D1 /4 */
8999 8933 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9000 8934 ins_pipe(ialu_mem_imm);
9001 8935 %}
9002 8936
9003 8937 // Shift Left by 8-bit immediate
9004 8938 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
9005 8939 %{
9006 8940 match(Set dst (LShiftI dst shift));
9007 8941 effect(KILL cr);
9008 8942
9009 8943 format %{ "sall $dst, $shift" %}
9010 8944 opcode(0xC1, 0x4); /* C1 /4 ib */
9011 8945 ins_encode(reg_opc_imm(dst, shift));
9012 8946 ins_pipe(ialu_reg);
9013 8947 %}
9014 8948
9015 8949 // Shift Left by 8-bit immediate
9016 8950 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9017 8951 %{
9018 8952 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
9019 8953 effect(KILL cr);
9020 8954
9021 8955 format %{ "sall $dst, $shift" %}
9022 8956 opcode(0xC1, 0x4); /* C1 /4 ib */
9023 8957 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
9024 8958 ins_pipe(ialu_mem_imm);
9025 8959 %}
9026 8960
9027 8961 // Shift Left by variable
9028 8962 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
9029 8963 %{
9030 8964 match(Set dst (LShiftI dst shift));
9031 8965 effect(KILL cr);
9032 8966
9033 8967 format %{ "sall $dst, $shift" %}
9034 8968 opcode(0xD3, 0x4); /* D3 /4 */
9035 8969 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9036 8970 ins_pipe(ialu_reg_reg);
9037 8971 %}
9038 8972
9039 8973 // Shift Left by variable
9040 8974 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9041 8975 %{
9042 8976 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
9043 8977 effect(KILL cr);
9044 8978
9045 8979 format %{ "sall $dst, $shift" %}
9046 8980 opcode(0xD3, 0x4); /* D3 /4 */
9047 8981 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9048 8982 ins_pipe(ialu_mem_reg);
9049 8983 %}
9050 8984
9051 8985 // Arithmetic shift right by one
9052 8986 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
9053 8987 %{
9054 8988 match(Set dst (RShiftI dst shift));
9055 8989 effect(KILL cr);
9056 8990
9057 8991 format %{ "sarl $dst, $shift" %}
9058 8992 opcode(0xD1, 0x7); /* D1 /7 */
9059 8993 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9060 8994 ins_pipe(ialu_reg);
9061 8995 %}
9062 8996
9063 8997 // Arithmetic shift right by one
9064 8998 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9065 8999 %{
9066 9000 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
9067 9001 effect(KILL cr);
9068 9002
9069 9003 format %{ "sarl $dst, $shift" %}
9070 9004 opcode(0xD1, 0x7); /* D1 /7 */
9071 9005 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9072 9006 ins_pipe(ialu_mem_imm);
9073 9007 %}
9074 9008
9075 9009 // Arithmetic Shift Right by 8-bit immediate
9076 9010 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
9077 9011 %{
9078 9012 match(Set dst (RShiftI dst shift));
9079 9013 effect(KILL cr);
9080 9014
9081 9015 format %{ "sarl $dst, $shift" %}
9082 9016 opcode(0xC1, 0x7); /* C1 /7 ib */
9083 9017 ins_encode(reg_opc_imm(dst, shift));
9084 9018 ins_pipe(ialu_mem_imm);
9085 9019 %}
9086 9020
9087 9021 // Arithmetic Shift Right by 8-bit immediate
9088 9022 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9089 9023 %{
9090 9024 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
9091 9025 effect(KILL cr);
9092 9026
9093 9027 format %{ "sarl $dst, $shift" %}
9094 9028 opcode(0xC1, 0x7); /* C1 /7 ib */
9095 9029 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
9096 9030 ins_pipe(ialu_mem_imm);
9097 9031 %}
9098 9032
9099 9033 // Arithmetic Shift Right by variable
9100 9034 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
9101 9035 %{
9102 9036 match(Set dst (RShiftI dst shift));
9103 9037 effect(KILL cr);
9104 9038
9105 9039 format %{ "sarl $dst, $shift" %}
9106 9040 opcode(0xD3, 0x7); /* D3 /7 */
9107 9041 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9108 9042 ins_pipe(ialu_reg_reg);
9109 9043 %}
9110 9044
9111 9045 // Arithmetic Shift Right by variable
9112 9046 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9113 9047 %{
9114 9048 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
9115 9049 effect(KILL cr);
9116 9050
9117 9051 format %{ "sarl $dst, $shift" %}
9118 9052 opcode(0xD3, 0x7); /* D3 /7 */
9119 9053 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9120 9054 ins_pipe(ialu_mem_reg);
9121 9055 %}
9122 9056
9123 9057 // Logical shift right by one
9124 9058 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
9125 9059 %{
9126 9060 match(Set dst (URShiftI dst shift));
9127 9061 effect(KILL cr);
9128 9062
9129 9063 format %{ "shrl $dst, $shift" %}
9130 9064 opcode(0xD1, 0x5); /* D1 /5 */
9131 9065 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9132 9066 ins_pipe(ialu_reg);
9133 9067 %}
9134 9068
9135 9069 // Logical shift right by one
9136 9070 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9137 9071 %{
9138 9072 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
9139 9073 effect(KILL cr);
9140 9074
9141 9075 format %{ "shrl $dst, $shift" %}
9142 9076 opcode(0xD1, 0x5); /* D1 /5 */
9143 9077 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9144 9078 ins_pipe(ialu_mem_imm);
9145 9079 %}
9146 9080
9147 9081 // Logical Shift Right by 8-bit immediate
9148 9082 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
9149 9083 %{
9150 9084 match(Set dst (URShiftI dst shift));
9151 9085 effect(KILL cr);
9152 9086
9153 9087 format %{ "shrl $dst, $shift" %}
9154 9088 opcode(0xC1, 0x5); /* C1 /5 ib */
9155 9089 ins_encode(reg_opc_imm(dst, shift));
9156 9090 ins_pipe(ialu_reg);
9157 9091 %}
9158 9092
9159 9093 // Logical Shift Right by 8-bit immediate
9160 9094 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9161 9095 %{
9162 9096 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
9163 9097 effect(KILL cr);
9164 9098
9165 9099 format %{ "shrl $dst, $shift" %}
9166 9100 opcode(0xC1, 0x5); /* C1 /5 ib */
9167 9101 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
9168 9102 ins_pipe(ialu_mem_imm);
9169 9103 %}
9170 9104
9171 9105 // Logical Shift Right by variable
9172 9106 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
9173 9107 %{
9174 9108 match(Set dst (URShiftI dst shift));
9175 9109 effect(KILL cr);
9176 9110
9177 9111 format %{ "shrl $dst, $shift" %}
9178 9112 opcode(0xD3, 0x5); /* D3 /5 */
9179 9113 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9180 9114 ins_pipe(ialu_reg_reg);
9181 9115 %}
9182 9116
9183 9117 // Logical Shift Right by variable
9184 9118 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9185 9119 %{
9186 9120 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
9187 9121 effect(KILL cr);
9188 9122
9189 9123 format %{ "shrl $dst, $shift" %}
9190 9124 opcode(0xD3, 0x5); /* D3 /5 */
9191 9125 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9192 9126 ins_pipe(ialu_mem_reg);
9193 9127 %}
9194 9128
9195 9129 // Long Shift Instructions
9196 9130 // Shift Left by one
9197 9131 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
9198 9132 %{
9199 9133 match(Set dst (LShiftL dst shift));
9200 9134 effect(KILL cr);
9201 9135
9202 9136 format %{ "salq $dst, $shift" %}
9203 9137 opcode(0xD1, 0x4); /* D1 /4 */
9204 9138 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9205 9139 ins_pipe(ialu_reg);
9206 9140 %}
9207 9141
9208 9142 // Shift Left by one
9209 9143 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9210 9144 %{
9211 9145 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
9212 9146 effect(KILL cr);
9213 9147
9214 9148 format %{ "salq $dst, $shift" %}
9215 9149 opcode(0xD1, 0x4); /* D1 /4 */
9216 9150 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9217 9151 ins_pipe(ialu_mem_imm);
9218 9152 %}
9219 9153
9220 9154 // Shift Left by 8-bit immediate
9221 9155 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
9222 9156 %{
9223 9157 match(Set dst (LShiftL dst shift));
9224 9158 effect(KILL cr);
9225 9159
9226 9160 format %{ "salq $dst, $shift" %}
9227 9161 opcode(0xC1, 0x4); /* C1 /4 ib */
9228 9162 ins_encode(reg_opc_imm_wide(dst, shift));
9229 9163 ins_pipe(ialu_reg);
9230 9164 %}
9231 9165
9232 9166 // Shift Left by 8-bit immediate
9233 9167 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9234 9168 %{
9235 9169 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
9236 9170 effect(KILL cr);
9237 9171
9238 9172 format %{ "salq $dst, $shift" %}
9239 9173 opcode(0xC1, 0x4); /* C1 /4 ib */
9240 9174 ins_encode(REX_mem_wide(dst), OpcP,
9241 9175 RM_opc_mem(secondary, dst), Con8or32(shift));
9242 9176 ins_pipe(ialu_mem_imm);
9243 9177 %}
9244 9178
9245 9179 // Shift Left by variable
9246 9180 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
9247 9181 %{
9248 9182 match(Set dst (LShiftL dst shift));
9249 9183 effect(KILL cr);
9250 9184
9251 9185 format %{ "salq $dst, $shift" %}
9252 9186 opcode(0xD3, 0x4); /* D3 /4 */
9253 9187 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9254 9188 ins_pipe(ialu_reg_reg);
9255 9189 %}
9256 9190
9257 9191 // Shift Left by variable
9258 9192 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9259 9193 %{
9260 9194 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
9261 9195 effect(KILL cr);
9262 9196
9263 9197 format %{ "salq $dst, $shift" %}
9264 9198 opcode(0xD3, 0x4); /* D3 /4 */
9265 9199 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9266 9200 ins_pipe(ialu_mem_reg);
9267 9201 %}
9268 9202
9269 9203 // Arithmetic shift right by one
9270 9204 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
9271 9205 %{
9272 9206 match(Set dst (RShiftL dst shift));
9273 9207 effect(KILL cr);
9274 9208
9275 9209 format %{ "sarq $dst, $shift" %}
9276 9210 opcode(0xD1, 0x7); /* D1 /7 */
9277 9211 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9278 9212 ins_pipe(ialu_reg);
9279 9213 %}
9280 9214
9281 9215 // Arithmetic shift right by one
9282 9216 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9283 9217 %{
9284 9218 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
9285 9219 effect(KILL cr);
9286 9220
9287 9221 format %{ "sarq $dst, $shift" %}
9288 9222 opcode(0xD1, 0x7); /* D1 /7 */
9289 9223 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9290 9224 ins_pipe(ialu_mem_imm);
9291 9225 %}
9292 9226
9293 9227 // Arithmetic Shift Right by 8-bit immediate
9294 9228 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
9295 9229 %{
9296 9230 match(Set dst (RShiftL dst shift));
9297 9231 effect(KILL cr);
9298 9232
9299 9233 format %{ "sarq $dst, $shift" %}
9300 9234 opcode(0xC1, 0x7); /* C1 /7 ib */
9301 9235 ins_encode(reg_opc_imm_wide(dst, shift));
9302 9236 ins_pipe(ialu_mem_imm);
9303 9237 %}
9304 9238
9305 9239 // Arithmetic Shift Right by 8-bit immediate
9306 9240 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9307 9241 %{
9308 9242 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
9309 9243 effect(KILL cr);
9310 9244
9311 9245 format %{ "sarq $dst, $shift" %}
9312 9246 opcode(0xC1, 0x7); /* C1 /7 ib */
9313 9247 ins_encode(REX_mem_wide(dst), OpcP,
9314 9248 RM_opc_mem(secondary, dst), Con8or32(shift));
9315 9249 ins_pipe(ialu_mem_imm);
9316 9250 %}
9317 9251
9318 9252 // Arithmetic Shift Right by variable
9319 9253 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
9320 9254 %{
9321 9255 match(Set dst (RShiftL dst shift));
9322 9256 effect(KILL cr);
9323 9257
9324 9258 format %{ "sarq $dst, $shift" %}
9325 9259 opcode(0xD3, 0x7); /* D3 /7 */
9326 9260 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9327 9261 ins_pipe(ialu_reg_reg);
9328 9262 %}
9329 9263
9330 9264 // Arithmetic Shift Right by variable
9331 9265 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9332 9266 %{
9333 9267 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
9334 9268 effect(KILL cr);
9335 9269
9336 9270 format %{ "sarq $dst, $shift" %}
9337 9271 opcode(0xD3, 0x7); /* D3 /7 */
9338 9272 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9339 9273 ins_pipe(ialu_mem_reg);
9340 9274 %}
9341 9275
9342 9276 // Logical shift right by one
9343 9277 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
9344 9278 %{
9345 9279 match(Set dst (URShiftL dst shift));
9346 9280 effect(KILL cr);
9347 9281
9348 9282 format %{ "shrq $dst, $shift" %}
9349 9283 opcode(0xD1, 0x5); /* D1 /5 */
9350 9284 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst ));
9351 9285 ins_pipe(ialu_reg);
9352 9286 %}
9353 9287
9354 9288 // Logical shift right by one
9355 9289 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9356 9290 %{
9357 9291 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
9358 9292 effect(KILL cr);
9359 9293
9360 9294 format %{ "shrq $dst, $shift" %}
9361 9295 opcode(0xD1, 0x5); /* D1 /5 */
9362 9296 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9363 9297 ins_pipe(ialu_mem_imm);
9364 9298 %}
9365 9299
9366 9300 // Logical Shift Right by 8-bit immediate
9367 9301 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
9368 9302 %{
9369 9303 match(Set dst (URShiftL dst shift));
9370 9304 effect(KILL cr);
9371 9305
9372 9306 format %{ "shrq $dst, $shift" %}
9373 9307 opcode(0xC1, 0x5); /* C1 /5 ib */
9374 9308 ins_encode(reg_opc_imm_wide(dst, shift));
9375 9309 ins_pipe(ialu_reg);
9376 9310 %}
9377 9311
9378 9312
9379 9313 // Logical Shift Right by 8-bit immediate
9380 9314 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9381 9315 %{
9382 9316 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
9383 9317 effect(KILL cr);
9384 9318
9385 9319 format %{ "shrq $dst, $shift" %}
9386 9320 opcode(0xC1, 0x5); /* C1 /5 ib */
9387 9321 ins_encode(REX_mem_wide(dst), OpcP,
9388 9322 RM_opc_mem(secondary, dst), Con8or32(shift));
9389 9323 ins_pipe(ialu_mem_imm);
9390 9324 %}
9391 9325
9392 9326 // Logical Shift Right by variable
9393 9327 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
9394 9328 %{
9395 9329 match(Set dst (URShiftL dst shift));
9396 9330 effect(KILL cr);
9397 9331
9398 9332 format %{ "shrq $dst, $shift" %}
9399 9333 opcode(0xD3, 0x5); /* D3 /5 */
9400 9334 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9401 9335 ins_pipe(ialu_reg_reg);
9402 9336 %}
9403 9337
9404 9338 // Logical Shift Right by variable
9405 9339 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9406 9340 %{
9407 9341 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
9408 9342 effect(KILL cr);
9409 9343
9410 9344 format %{ "shrq $dst, $shift" %}
9411 9345 opcode(0xD3, 0x5); /* D3 /5 */
9412 9346 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9413 9347 ins_pipe(ialu_mem_reg);
9414 9348 %}
9415 9349
9416 9350 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
9417 9351 // This idiom is used by the compiler for the i2b bytecode.
9418 9352 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour)
9419 9353 %{
9420 9354 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
9421 9355
9422 9356 format %{ "movsbl $dst, $src\t# i2b" %}
9423 9357 opcode(0x0F, 0xBE);
9424 9358 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9425 9359 ins_pipe(ialu_reg_reg);
9426 9360 %}
9427 9361
9428 9362 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
9429 9363 // This idiom is used by the compiler the i2s bytecode.
9430 9364 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen)
9431 9365 %{
9432 9366 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
9433 9367
9434 9368 format %{ "movswl $dst, $src\t# i2s" %}
9435 9369 opcode(0x0F, 0xBF);
9436 9370 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9437 9371 ins_pipe(ialu_reg_reg);
9438 9372 %}
9439 9373
9440 9374 // ROL/ROR instructions
9441 9375
9442 9376 // ROL expand
9443 9377 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{
9444 9378 effect(KILL cr, USE_DEF dst);
9445 9379
9446 9380 format %{ "roll $dst" %}
9447 9381 opcode(0xD1, 0x0); /* Opcode D1 /0 */
9448 9382 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9449 9383 ins_pipe(ialu_reg);
9450 9384 %}
9451 9385
9452 9386 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{
9453 9387 effect(USE_DEF dst, USE shift, KILL cr);
9454 9388
9455 9389 format %{ "roll $dst, $shift" %}
9456 9390 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
9457 9391 ins_encode( reg_opc_imm(dst, shift) );
9458 9392 ins_pipe(ialu_reg);
9459 9393 %}
9460 9394
9461 9395 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
9462 9396 %{
9463 9397 effect(USE_DEF dst, USE shift, KILL cr);
9464 9398
9465 9399 format %{ "roll $dst, $shift" %}
9466 9400 opcode(0xD3, 0x0); /* Opcode D3 /0 */
9467 9401 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9468 9402 ins_pipe(ialu_reg_reg);
9469 9403 %}
9470 9404 // end of ROL expand
9471 9405
9472 9406 // Rotate Left by one
9473 9407 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
9474 9408 %{
9475 9409 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
9476 9410
9477 9411 expand %{
9478 9412 rolI_rReg_imm1(dst, cr);
9479 9413 %}
9480 9414 %}
9481 9415
9482 9416 // Rotate Left by 8-bit immediate
9483 9417 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
9484 9418 %{
9485 9419 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9486 9420 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
9487 9421
9488 9422 expand %{
9489 9423 rolI_rReg_imm8(dst, lshift, cr);
9490 9424 %}
9491 9425 %}
9492 9426
9493 9427 // Rotate Left by variable
9494 9428 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9495 9429 %{
9496 9430 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift))));
9497 9431
9498 9432 expand %{
9499 9433 rolI_rReg_CL(dst, shift, cr);
9500 9434 %}
9501 9435 %}
9502 9436
9503 9437 // Rotate Left by variable
9504 9438 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
9505 9439 %{
9506 9440 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift))));
9507 9441
9508 9442 expand %{
9509 9443 rolI_rReg_CL(dst, shift, cr);
9510 9444 %}
9511 9445 %}
9512 9446
9513 9447 // ROR expand
9514 9448 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr)
9515 9449 %{
9516 9450 effect(USE_DEF dst, KILL cr);
9517 9451
9518 9452 format %{ "rorl $dst" %}
9519 9453 opcode(0xD1, 0x1); /* D1 /1 */
9520 9454 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9521 9455 ins_pipe(ialu_reg);
9522 9456 %}
9523 9457
9524 9458 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr)
9525 9459 %{
9526 9460 effect(USE_DEF dst, USE shift, KILL cr);
9527 9461
9528 9462 format %{ "rorl $dst, $shift" %}
9529 9463 opcode(0xC1, 0x1); /* C1 /1 ib */
9530 9464 ins_encode(reg_opc_imm(dst, shift));
9531 9465 ins_pipe(ialu_reg);
9532 9466 %}
9533 9467
9534 9468 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
9535 9469 %{
9536 9470 effect(USE_DEF dst, USE shift, KILL cr);
9537 9471
9538 9472 format %{ "rorl $dst, $shift" %}
9539 9473 opcode(0xD3, 0x1); /* D3 /1 */
9540 9474 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9541 9475 ins_pipe(ialu_reg_reg);
9542 9476 %}
9543 9477 // end of ROR expand
9544 9478
9545 9479 // Rotate Right by one
9546 9480 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
9547 9481 %{
9548 9482 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
9549 9483
9550 9484 expand %{
9551 9485 rorI_rReg_imm1(dst, cr);
9552 9486 %}
9553 9487 %}
9554 9488
9555 9489 // Rotate Right by 8-bit immediate
9556 9490 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
9557 9491 %{
9558 9492 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9559 9493 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
9560 9494
9561 9495 expand %{
9562 9496 rorI_rReg_imm8(dst, rshift, cr);
9563 9497 %}
9564 9498 %}
9565 9499
9566 9500 // Rotate Right by variable
9567 9501 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9568 9502 %{
9569 9503 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift))));
9570 9504
9571 9505 expand %{
9572 9506 rorI_rReg_CL(dst, shift, cr);
9573 9507 %}
9574 9508 %}
9575 9509
9576 9510 // Rotate Right by variable
9577 9511 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
9578 9512 %{
9579 9513 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift))));
9580 9514
9581 9515 expand %{
9582 9516 rorI_rReg_CL(dst, shift, cr);
9583 9517 %}
9584 9518 %}
9585 9519
9586 9520 // for long rotate
9587 9521 // ROL expand
9588 9522 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{
9589 9523 effect(USE_DEF dst, KILL cr);
9590 9524
9591 9525 format %{ "rolq $dst" %}
9592 9526 opcode(0xD1, 0x0); /* Opcode D1 /0 */
9593 9527 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9594 9528 ins_pipe(ialu_reg);
9595 9529 %}
9596 9530
9597 9531 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{
9598 9532 effect(USE_DEF dst, USE shift, KILL cr);
9599 9533
9600 9534 format %{ "rolq $dst, $shift" %}
9601 9535 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
9602 9536 ins_encode( reg_opc_imm_wide(dst, shift) );
9603 9537 ins_pipe(ialu_reg);
9604 9538 %}
9605 9539
9606 9540 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
9607 9541 %{
9608 9542 effect(USE_DEF dst, USE shift, KILL cr);
9609 9543
9610 9544 format %{ "rolq $dst, $shift" %}
9611 9545 opcode(0xD3, 0x0); /* Opcode D3 /0 */
9612 9546 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9613 9547 ins_pipe(ialu_reg_reg);
9614 9548 %}
9615 9549 // end of ROL expand
9616 9550
9617 9551 // Rotate Left by one
9618 9552 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
9619 9553 %{
9620 9554 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
9621 9555
9622 9556 expand %{
9623 9557 rolL_rReg_imm1(dst, cr);
9624 9558 %}
9625 9559 %}
9626 9560
9627 9561 // Rotate Left by 8-bit immediate
9628 9562 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
9629 9563 %{
9630 9564 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9631 9565 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
9632 9566
9633 9567 expand %{
9634 9568 rolL_rReg_imm8(dst, lshift, cr);
9635 9569 %}
9636 9570 %}
9637 9571
9638 9572 // Rotate Left by variable
9639 9573 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9640 9574 %{
9641 9575 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift))));
9642 9576
9643 9577 expand %{
9644 9578 rolL_rReg_CL(dst, shift, cr);
9645 9579 %}
9646 9580 %}
9647 9581
9648 9582 // Rotate Left by variable
9649 9583 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
9650 9584 %{
9651 9585 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift))));
9652 9586
9653 9587 expand %{
9654 9588 rolL_rReg_CL(dst, shift, cr);
9655 9589 %}
9656 9590 %}
9657 9591
9658 9592 // ROR expand
9659 9593 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr)
9660 9594 %{
9661 9595 effect(USE_DEF dst, KILL cr);
9662 9596
9663 9597 format %{ "rorq $dst" %}
9664 9598 opcode(0xD1, 0x1); /* D1 /1 */
9665 9599 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9666 9600 ins_pipe(ialu_reg);
9667 9601 %}
9668 9602
9669 9603 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr)
9670 9604 %{
9671 9605 effect(USE_DEF dst, USE shift, KILL cr);
9672 9606
9673 9607 format %{ "rorq $dst, $shift" %}
9674 9608 opcode(0xC1, 0x1); /* C1 /1 ib */
9675 9609 ins_encode(reg_opc_imm_wide(dst, shift));
9676 9610 ins_pipe(ialu_reg);
9677 9611 %}
9678 9612
9679 9613 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
9680 9614 %{
9681 9615 effect(USE_DEF dst, USE shift, KILL cr);
9682 9616
9683 9617 format %{ "rorq $dst, $shift" %}
9684 9618 opcode(0xD3, 0x1); /* D3 /1 */
9685 9619 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9686 9620 ins_pipe(ialu_reg_reg);
9687 9621 %}
9688 9622 // end of ROR expand
9689 9623
9690 9624 // Rotate Right by one
9691 9625 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
9692 9626 %{
9693 9627 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
9694 9628
9695 9629 expand %{
9696 9630 rorL_rReg_imm1(dst, cr);
9697 9631 %}
9698 9632 %}
9699 9633
9700 9634 // Rotate Right by 8-bit immediate
9701 9635 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
9702 9636 %{
9703 9637 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9704 9638 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
9705 9639
9706 9640 expand %{
9707 9641 rorL_rReg_imm8(dst, rshift, cr);
9708 9642 %}
9709 9643 %}
9710 9644
9711 9645 // Rotate Right by variable
9712 9646 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9713 9647 %{
9714 9648 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift))));
9715 9649
9716 9650 expand %{
9717 9651 rorL_rReg_CL(dst, shift, cr);
9718 9652 %}
9719 9653 %}
9720 9654
9721 9655 // Rotate Right by variable
9722 9656 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
9723 9657 %{
9724 9658 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift))));
9725 9659
9726 9660 expand %{
9727 9661 rorL_rReg_CL(dst, shift, cr);
9728 9662 %}
9729 9663 %}
9730 9664
9731 9665 // Logical Instructions
9732 9666
9733 9667 // Integer Logical Instructions
9734 9668
9735 9669 // And Instructions
9736 9670 // And Register with Register
9737 9671 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9738 9672 %{
9739 9673 match(Set dst (AndI dst src));
9740 9674 effect(KILL cr);
9741 9675
9742 9676 format %{ "andl $dst, $src\t# int" %}
9743 9677 opcode(0x23);
9744 9678 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9745 9679 ins_pipe(ialu_reg_reg);
9746 9680 %}
9747 9681
9748 9682 // And Register with Immediate 255
9749 9683 instruct andI_rReg_imm255(rRegI dst, immI_255 src)
9750 9684 %{
9751 9685 match(Set dst (AndI dst src));
9752 9686
9753 9687 format %{ "movzbl $dst, $dst\t# int & 0xFF" %}
9754 9688 opcode(0x0F, 0xB6);
9755 9689 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9756 9690 ins_pipe(ialu_reg);
9757 9691 %}
9758 9692
9759 9693 // And Register with Immediate 255 and promote to long
9760 9694 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask)
9761 9695 %{
9762 9696 match(Set dst (ConvI2L (AndI src mask)));
9763 9697
9764 9698 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %}
9765 9699 opcode(0x0F, 0xB6);
9766 9700 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9767 9701 ins_pipe(ialu_reg);
9768 9702 %}
9769 9703
9770 9704 // And Register with Immediate 65535
9771 9705 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src)
9772 9706 %{
9773 9707 match(Set dst (AndI dst src));
9774 9708
9775 9709 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %}
9776 9710 opcode(0x0F, 0xB7);
9777 9711 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9778 9712 ins_pipe(ialu_reg);
9779 9713 %}
9780 9714
9781 9715 // And Register with Immediate 65535 and promote to long
9782 9716 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask)
9783 9717 %{
9784 9718 match(Set dst (ConvI2L (AndI src mask)));
9785 9719
9786 9720 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %}
9787 9721 opcode(0x0F, 0xB7);
9788 9722 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9789 9723 ins_pipe(ialu_reg);
9790 9724 %}
9791 9725
9792 9726 // And Register with Immediate
9793 9727 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9794 9728 %{
9795 9729 match(Set dst (AndI dst src));
9796 9730 effect(KILL cr);
9797 9731
9798 9732 format %{ "andl $dst, $src\t# int" %}
9799 9733 opcode(0x81, 0x04); /* Opcode 81 /4 */
9800 9734 ins_encode(OpcSErm(dst, src), Con8or32(src));
9801 9735 ins_pipe(ialu_reg);
9802 9736 %}
9803 9737
9804 9738 // And Register with Memory
9805 9739 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9806 9740 %{
9807 9741 match(Set dst (AndI dst (LoadI src)));
9808 9742 effect(KILL cr);
9809 9743
9810 9744 ins_cost(125);
9811 9745 format %{ "andl $dst, $src\t# int" %}
9812 9746 opcode(0x23);
9813 9747 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9814 9748 ins_pipe(ialu_reg_mem);
9815 9749 %}
9816 9750
9817 9751 // And Memory with Register
9818 9752 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9819 9753 %{
9820 9754 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9821 9755 effect(KILL cr);
9822 9756
9823 9757 ins_cost(150);
9824 9758 format %{ "andl $dst, $src\t# int" %}
9825 9759 opcode(0x21); /* Opcode 21 /r */
9826 9760 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9827 9761 ins_pipe(ialu_mem_reg);
9828 9762 %}
9829 9763
9830 9764 // And Memory with Immediate
9831 9765 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr)
9832 9766 %{
9833 9767 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9834 9768 effect(KILL cr);
9835 9769
9836 9770 ins_cost(125);
9837 9771 format %{ "andl $dst, $src\t# int" %}
9838 9772 opcode(0x81, 0x4); /* Opcode 81 /4 id */
9839 9773 ins_encode(REX_mem(dst), OpcSE(src),
9840 9774 RM_opc_mem(secondary, dst), Con8or32(src));
9841 9775 ins_pipe(ialu_mem_imm);
9842 9776 %}
9843 9777
9844 9778 // Or Instructions
9845 9779 // Or Register with Register
9846 9780 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9847 9781 %{
9848 9782 match(Set dst (OrI dst src));
9849 9783 effect(KILL cr);
9850 9784
9851 9785 format %{ "orl $dst, $src\t# int" %}
9852 9786 opcode(0x0B);
9853 9787 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9854 9788 ins_pipe(ialu_reg_reg);
9855 9789 %}
9856 9790
9857 9791 // Or Register with Immediate
9858 9792 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9859 9793 %{
9860 9794 match(Set dst (OrI dst src));
9861 9795 effect(KILL cr);
9862 9796
9863 9797 format %{ "orl $dst, $src\t# int" %}
9864 9798 opcode(0x81, 0x01); /* Opcode 81 /1 id */
9865 9799 ins_encode(OpcSErm(dst, src), Con8or32(src));
9866 9800 ins_pipe(ialu_reg);
9867 9801 %}
9868 9802
9869 9803 // Or Register with Memory
9870 9804 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9871 9805 %{
9872 9806 match(Set dst (OrI dst (LoadI src)));
9873 9807 effect(KILL cr);
9874 9808
9875 9809 ins_cost(125);
9876 9810 format %{ "orl $dst, $src\t# int" %}
9877 9811 opcode(0x0B);
9878 9812 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9879 9813 ins_pipe(ialu_reg_mem);
9880 9814 %}
9881 9815
9882 9816 // Or Memory with Register
9883 9817 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9884 9818 %{
9885 9819 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9886 9820 effect(KILL cr);
9887 9821
9888 9822 ins_cost(150);
9889 9823 format %{ "orl $dst, $src\t# int" %}
9890 9824 opcode(0x09); /* Opcode 09 /r */
9891 9825 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9892 9826 ins_pipe(ialu_mem_reg);
9893 9827 %}
9894 9828
9895 9829 // Or Memory with Immediate
9896 9830 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr)
9897 9831 %{
9898 9832 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9899 9833 effect(KILL cr);
9900 9834
9901 9835 ins_cost(125);
9902 9836 format %{ "orl $dst, $src\t# int" %}
9903 9837 opcode(0x81, 0x1); /* Opcode 81 /1 id */
9904 9838 ins_encode(REX_mem(dst), OpcSE(src),
9905 9839 RM_opc_mem(secondary, dst), Con8or32(src));
9906 9840 ins_pipe(ialu_mem_imm);
9907 9841 %}
9908 9842
9909 9843 // Xor Instructions
9910 9844 // Xor Register with Register
9911 9845 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9912 9846 %{
9913 9847 match(Set dst (XorI dst src));
9914 9848 effect(KILL cr);
9915 9849
9916 9850 format %{ "xorl $dst, $src\t# int" %}
9917 9851 opcode(0x33);
9918 9852 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9919 9853 ins_pipe(ialu_reg_reg);
9920 9854 %}
9921 9855
9922 9856 // Xor Register with Immediate -1
9923 9857 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
9924 9858 match(Set dst (XorI dst imm));
9925 9859
9926 9860 format %{ "not $dst" %}
9927 9861 ins_encode %{
9928 9862 __ notl($dst$$Register);
9929 9863 %}
9930 9864 ins_pipe(ialu_reg);
9931 9865 %}
9932 9866
9933 9867 // Xor Register with Immediate
9934 9868 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9935 9869 %{
9936 9870 match(Set dst (XorI dst src));
9937 9871 effect(KILL cr);
9938 9872
9939 9873 format %{ "xorl $dst, $src\t# int" %}
9940 9874 opcode(0x81, 0x06); /* Opcode 81 /6 id */
9941 9875 ins_encode(OpcSErm(dst, src), Con8or32(src));
9942 9876 ins_pipe(ialu_reg);
9943 9877 %}
9944 9878
9945 9879 // Xor Register with Memory
9946 9880 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9947 9881 %{
9948 9882 match(Set dst (XorI dst (LoadI src)));
9949 9883 effect(KILL cr);
9950 9884
9951 9885 ins_cost(125);
9952 9886 format %{ "xorl $dst, $src\t# int" %}
9953 9887 opcode(0x33);
9954 9888 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9955 9889 ins_pipe(ialu_reg_mem);
9956 9890 %}
9957 9891
9958 9892 // Xor Memory with Register
9959 9893 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9960 9894 %{
9961 9895 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9962 9896 effect(KILL cr);
9963 9897
9964 9898 ins_cost(150);
9965 9899 format %{ "xorl $dst, $src\t# int" %}
9966 9900 opcode(0x31); /* Opcode 31 /r */
9967 9901 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9968 9902 ins_pipe(ialu_mem_reg);
9969 9903 %}
9970 9904
9971 9905 // Xor Memory with Immediate
9972 9906 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr)
9973 9907 %{
9974 9908 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9975 9909 effect(KILL cr);
9976 9910
9977 9911 ins_cost(125);
9978 9912 format %{ "xorl $dst, $src\t# int" %}
9979 9913 opcode(0x81, 0x6); /* Opcode 81 /6 id */
9980 9914 ins_encode(REX_mem(dst), OpcSE(src),
9981 9915 RM_opc_mem(secondary, dst), Con8or32(src));
9982 9916 ins_pipe(ialu_mem_imm);
9983 9917 %}
9984 9918
9985 9919
9986 9920 // Long Logical Instructions
9987 9921
9988 9922 // And Instructions
9989 9923 // And Register with Register
9990 9924 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9991 9925 %{
9992 9926 match(Set dst (AndL dst src));
9993 9927 effect(KILL cr);
9994 9928
9995 9929 format %{ "andq $dst, $src\t# long" %}
9996 9930 opcode(0x23);
9997 9931 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9998 9932 ins_pipe(ialu_reg_reg);
9999 9933 %}
10000 9934
10001 9935 // And Register with Immediate 255
10002 9936 instruct andL_rReg_imm255(rRegL dst, immL_255 src)
10003 9937 %{
10004 9938 match(Set dst (AndL dst src));
10005 9939
10006 9940 format %{ "movzbq $dst, $dst\t# long & 0xFF" %}
10007 9941 opcode(0x0F, 0xB6);
10008 9942 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
10009 9943 ins_pipe(ialu_reg);
10010 9944 %}
10011 9945
10012 9946 // And Register with Immediate 65535
10013 9947 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
10014 9948 %{
10015 9949 match(Set dst (AndL dst src));
10016 9950
10017 9951 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %}
10018 9952 opcode(0x0F, 0xB7);
10019 9953 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
10020 9954 ins_pipe(ialu_reg);
10021 9955 %}
10022 9956
10023 9957 // And Register with Immediate
10024 9958 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
10025 9959 %{
10026 9960 match(Set dst (AndL dst src));
10027 9961 effect(KILL cr);
10028 9962
10029 9963 format %{ "andq $dst, $src\t# long" %}
10030 9964 opcode(0x81, 0x04); /* Opcode 81 /4 */
10031 9965 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
10032 9966 ins_pipe(ialu_reg);
10033 9967 %}
10034 9968
10035 9969 // And Register with Memory
10036 9970 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
10037 9971 %{
10038 9972 match(Set dst (AndL dst (LoadL src)));
10039 9973 effect(KILL cr);
10040 9974
10041 9975 ins_cost(125);
10042 9976 format %{ "andq $dst, $src\t# long" %}
10043 9977 opcode(0x23);
10044 9978 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
10045 9979 ins_pipe(ialu_reg_mem);
10046 9980 %}
10047 9981
10048 9982 // And Memory with Register
10049 9983 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
10050 9984 %{
10051 9985 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
10052 9986 effect(KILL cr);
10053 9987
10054 9988 ins_cost(150);
10055 9989 format %{ "andq $dst, $src\t# long" %}
10056 9990 opcode(0x21); /* Opcode 21 /r */
10057 9991 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
10058 9992 ins_pipe(ialu_mem_reg);
10059 9993 %}
10060 9994
10061 9995 // And Memory with Immediate
10062 9996 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
10063 9997 %{
10064 9998 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
10065 9999 effect(KILL cr);
10066 10000
10067 10001 ins_cost(125);
10068 10002 format %{ "andq $dst, $src\t# long" %}
10069 10003 opcode(0x81, 0x4); /* Opcode 81 /4 id */
10070 10004 ins_encode(REX_mem_wide(dst), OpcSE(src),
10071 10005 RM_opc_mem(secondary, dst), Con8or32(src));
10072 10006 ins_pipe(ialu_mem_imm);
10073 10007 %}
10074 10008
10075 10009 // Or Instructions
10076 10010 // Or Register with Register
10077 10011 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
10078 10012 %{
10079 10013 match(Set dst (OrL dst src));
10080 10014 effect(KILL cr);
10081 10015
10082 10016 format %{ "orq $dst, $src\t# long" %}
10083 10017 opcode(0x0B);
10084 10018 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
10085 10019 ins_pipe(ialu_reg_reg);
10086 10020 %}
10087 10021
10088 10022 // Use any_RegP to match R15 (TLS register) without spilling.
10089 10023 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
10090 10024 match(Set dst (OrL dst (CastP2X src)));
10091 10025 effect(KILL cr);
10092 10026
10093 10027 format %{ "orq $dst, $src\t# long" %}
10094 10028 opcode(0x0B);
10095 10029 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
10096 10030 ins_pipe(ialu_reg_reg);
10097 10031 %}
10098 10032
10099 10033
10100 10034 // Or Register with Immediate
10101 10035 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
10102 10036 %{
10103 10037 match(Set dst (OrL dst src));
10104 10038 effect(KILL cr);
10105 10039
10106 10040 format %{ "orq $dst, $src\t# long" %}
10107 10041 opcode(0x81, 0x01); /* Opcode 81 /1 id */
10108 10042 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
10109 10043 ins_pipe(ialu_reg);
10110 10044 %}
10111 10045
10112 10046 // Or Register with Memory
10113 10047 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
10114 10048 %{
10115 10049 match(Set dst (OrL dst (LoadL src)));
10116 10050 effect(KILL cr);
10117 10051
10118 10052 ins_cost(125);
10119 10053 format %{ "orq $dst, $src\t# long" %}
10120 10054 opcode(0x0B);
10121 10055 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
10122 10056 ins_pipe(ialu_reg_mem);
10123 10057 %}
10124 10058
10125 10059 // Or Memory with Register
10126 10060 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
10127 10061 %{
10128 10062 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
10129 10063 effect(KILL cr);
10130 10064
10131 10065 ins_cost(150);
10132 10066 format %{ "orq $dst, $src\t# long" %}
10133 10067 opcode(0x09); /* Opcode 09 /r */
10134 10068 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
10135 10069 ins_pipe(ialu_mem_reg);
10136 10070 %}
10137 10071
10138 10072 // Or Memory with Immediate
10139 10073 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
10140 10074 %{
10141 10075 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
10142 10076 effect(KILL cr);
10143 10077
10144 10078 ins_cost(125);
10145 10079 format %{ "orq $dst, $src\t# long" %}
10146 10080 opcode(0x81, 0x1); /* Opcode 81 /1 id */
10147 10081 ins_encode(REX_mem_wide(dst), OpcSE(src),
10148 10082 RM_opc_mem(secondary, dst), Con8or32(src));
10149 10083 ins_pipe(ialu_mem_imm);
10150 10084 %}
10151 10085
10152 10086 // Xor Instructions
10153 10087 // Xor Register with Register
10154 10088 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
10155 10089 %{
10156 10090 match(Set dst (XorL dst src));
10157 10091 effect(KILL cr);
10158 10092
10159 10093 format %{ "xorq $dst, $src\t# long" %}
10160 10094 opcode(0x33);
10161 10095 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
10162 10096 ins_pipe(ialu_reg_reg);
10163 10097 %}
10164 10098
10165 10099 // Xor Register with Immediate -1
10166 10100 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
10167 10101 match(Set dst (XorL dst imm));
10168 10102
10169 10103 format %{ "notq $dst" %}
10170 10104 ins_encode %{
10171 10105 __ notq($dst$$Register);
10172 10106 %}
10173 10107 ins_pipe(ialu_reg);
10174 10108 %}
10175 10109
10176 10110 // Xor Register with Immediate
10177 10111 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
10178 10112 %{
10179 10113 match(Set dst (XorL dst src));
10180 10114 effect(KILL cr);
10181 10115
10182 10116 format %{ "xorq $dst, $src\t# long" %}
10183 10117 opcode(0x81, 0x06); /* Opcode 81 /6 id */
10184 10118 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
10185 10119 ins_pipe(ialu_reg);
10186 10120 %}
10187 10121
10188 10122 // Xor Register with Memory
10189 10123 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
10190 10124 %{
10191 10125 match(Set dst (XorL dst (LoadL src)));
10192 10126 effect(KILL cr);
10193 10127
10194 10128 ins_cost(125);
10195 10129 format %{ "xorq $dst, $src\t# long" %}
10196 10130 opcode(0x33);
10197 10131 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
10198 10132 ins_pipe(ialu_reg_mem);
10199 10133 %}
10200 10134
10201 10135 // Xor Memory with Register
10202 10136 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
10203 10137 %{
10204 10138 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
10205 10139 effect(KILL cr);
10206 10140
10207 10141 ins_cost(150);
10208 10142 format %{ "xorq $dst, $src\t# long" %}
10209 10143 opcode(0x31); /* Opcode 31 /r */
10210 10144 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
10211 10145 ins_pipe(ialu_mem_reg);
10212 10146 %}
10213 10147
10214 10148 // Xor Memory with Immediate
10215 10149 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
10216 10150 %{
10217 10151 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
10218 10152 effect(KILL cr);
10219 10153
10220 10154 ins_cost(125);
10221 10155 format %{ "xorq $dst, $src\t# long" %}
10222 10156 opcode(0x81, 0x6); /* Opcode 81 /6 id */
10223 10157 ins_encode(REX_mem_wide(dst), OpcSE(src),
10224 10158 RM_opc_mem(secondary, dst), Con8or32(src));
10225 10159 ins_pipe(ialu_mem_imm);
10226 10160 %}
10227 10161
10228 10162 // Convert Int to Boolean
10229 10163 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr)
10230 10164 %{
10231 10165 match(Set dst (Conv2B src));
10232 10166 effect(KILL cr);
10233 10167
10234 10168 format %{ "testl $src, $src\t# ci2b\n\t"
10235 10169 "setnz $dst\n\t"
10236 10170 "movzbl $dst, $dst" %}
10237 10171 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl
10238 10172 setNZ_reg(dst),
10239 10173 REX_reg_breg(dst, dst), // movzbl
10240 10174 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
10241 10175 ins_pipe(pipe_slow); // XXX
10242 10176 %}
10243 10177
10244 10178 // Convert Pointer to Boolean
10245 10179 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr)
10246 10180 %{
10247 10181 match(Set dst (Conv2B src));
10248 10182 effect(KILL cr);
10249 10183
10250 10184 format %{ "testq $src, $src\t# cp2b\n\t"
10251 10185 "setnz $dst\n\t"
10252 10186 "movzbl $dst, $dst" %}
10253 10187 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq
10254 10188 setNZ_reg(dst),
10255 10189 REX_reg_breg(dst, dst), // movzbl
10256 10190 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
10257 10191 ins_pipe(pipe_slow); // XXX
10258 10192 %}
10259 10193
10260 10194 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr)
10261 10195 %{
10262 10196 match(Set dst (CmpLTMask p q));
10263 10197 effect(KILL cr);
10264 10198
10265 10199 ins_cost(400); // XXX
10266 10200 format %{ "cmpl $p, $q\t# cmpLTMask\n\t"
10267 10201 "setlt $dst\n\t"
10268 10202 "movzbl $dst, $dst\n\t"
10269 10203 "negl $dst" %}
10270 10204 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl
10271 10205 setLT_reg(dst),
10272 10206 REX_reg_breg(dst, dst), // movzbl
10273 10207 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst),
10274 10208 neg_reg(dst));
10275 10209 ins_pipe(pipe_slow);
10276 10210 %}
10277 10211
10278 10212 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr)
10279 10213 %{
10280 10214 match(Set dst (CmpLTMask dst zero));
10281 10215 effect(KILL cr);
10282 10216
10283 10217 ins_cost(100); // XXX
10284 10218 format %{ "sarl $dst, #31\t# cmpLTMask0" %}
10285 10219 opcode(0xC1, 0x7); /* C1 /7 ib */
10286 10220 ins_encode(reg_opc_imm(dst, 0x1F));
10287 10221 ins_pipe(ialu_reg);
10288 10222 %}
10289 10223
10290 10224
10291 10225 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y,
10292 10226 rRegI tmp,
10293 10227 rFlagsReg cr)
10294 10228 %{
10295 10229 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
10296 10230 effect(TEMP tmp, KILL cr);
10297 10231
10298 10232 ins_cost(400); // XXX
10299 10233 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t"
10300 10234 "sbbl $tmp, $tmp\n\t"
10301 10235 "andl $tmp, $y\n\t"
10302 10236 "addl $p, $tmp" %}
10303 10237 ins_encode(enc_cmpLTP(p, q, y, tmp));
10304 10238 ins_pipe(pipe_cmplt);
10305 10239 %}
10306 10240
10307 10241 /* If I enable this, I encourage spilling in the inner loop of compress.
10308 10242 instruct cadd_cmpLTMask_mem( rRegI p, rRegI q, memory y, rRegI tmp, rFlagsReg cr )
10309 10243 %{
10310 10244 match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q)));
10311 10245 effect( TEMP tmp, KILL cr );
10312 10246 ins_cost(400);
10313 10247
10314 10248 format %{ "SUB $p,$q\n\t"
10315 10249 "SBB RCX,RCX\n\t"
10316 10250 "AND RCX,$y\n\t"
10317 10251 "ADD $p,RCX" %}
10318 10252 ins_encode( enc_cmpLTP_mem(p,q,y,tmp) );
10319 10253 %}
10320 10254 */
10321 10255
10322 10256 //---------- FP Instructions------------------------------------------------
10323 10257
10324 10258 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
10325 10259 %{
10326 10260 match(Set cr (CmpF src1 src2));
10327 10261
10328 10262 ins_cost(145);
10329 10263 format %{ "ucomiss $src1, $src2\n\t"
10330 10264 "jnp,s exit\n\t"
10331 10265 "pushfq\t# saw NaN, set CF\n\t"
10332 10266 "andq [rsp], #0xffffff2b\n\t"
10333 10267 "popfq\n"
10334 10268 "exit: nop\t# avoid branch to branch" %}
10335 10269 opcode(0x0F, 0x2E);
10336 10270 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2),
10337 10271 cmpfp_fixup);
10338 10272 ins_pipe(pipe_slow);
10339 10273 %}
10340 10274
10341 10275 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
10342 10276 match(Set cr (CmpF src1 src2));
10343 10277
10344 10278 ins_cost(145);
10345 10279 format %{ "ucomiss $src1, $src2" %}
10346 10280 ins_encode %{
10347 10281 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10348 10282 %}
10349 10283 ins_pipe(pipe_slow);
10350 10284 %}
10351 10285
10352 10286 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
10353 10287 %{
10354 10288 match(Set cr (CmpF src1 (LoadF src2)));
10355 10289
10356 10290 ins_cost(145);
10357 10291 format %{ "ucomiss $src1, $src2\n\t"
10358 10292 "jnp,s exit\n\t"
10359 10293 "pushfq\t# saw NaN, set CF\n\t"
10360 10294 "andq [rsp], #0xffffff2b\n\t"
10361 10295 "popfq\n"
10362 10296 "exit: nop\t# avoid branch to branch" %}
10363 10297 opcode(0x0F, 0x2E);
10364 10298 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
10365 10299 cmpfp_fixup);
10366 10300 ins_pipe(pipe_slow);
10367 10301 %}
10368 10302
↓ open down ↓ |
2635 lines elided |
↑ open up ↑ |
10369 10303 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
10370 10304 match(Set cr (CmpF src1 (LoadF src2)));
10371 10305
10372 10306 ins_cost(100);
10373 10307 format %{ "ucomiss $src1, $src2" %}
10374 10308 opcode(0x0F, 0x2E);
10375 10309 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
10376 10310 ins_pipe(pipe_slow);
10377 10311 %}
10378 10312
10379 -instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
10380 -%{
10381 - match(Set cr (CmpF src1 src2));
10313 +instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
10314 + match(Set cr (CmpF src con));
10382 10315
10383 10316 ins_cost(145);
10384 - format %{ "ucomiss $src1, $src2\n\t"
10317 + format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10385 10318 "jnp,s exit\n\t"
10386 10319 "pushfq\t# saw NaN, set CF\n\t"
10387 10320 "andq [rsp], #0xffffff2b\n\t"
10388 10321 "popfq\n"
10389 10322 "exit: nop\t# avoid branch to branch" %}
10390 - opcode(0x0F, 0x2E);
10391 - ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2),
10392 - cmpfp_fixup);
10323 + ins_encode %{
10324 + Label L_exit;
10325 + __ ucomiss($src$$XMMRegister, $constantaddress($con));
10326 + __ jcc(Assembler::noParity, L_exit);
10327 + __ pushf();
10328 + __ andq(rsp, 0xffffff2b);
10329 + __ popf();
10330 + __ bind(L_exit);
10331 + __ nop();
10332 + %}
10393 10333 ins_pipe(pipe_slow);
10394 10334 %}
10395 10335
10396 -instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
10397 - match(Set cr (CmpF src1 src2));
10398 -
10336 +instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
10337 + match(Set cr (CmpF src con));
10399 10338 ins_cost(100);
10400 - format %{ "ucomiss $src1, $src2" %}
10401 - opcode(0x0F, 0x2E);
10402 - ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
10339 + format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
10340 + ins_encode %{
10341 + __ ucomiss($src$$XMMRegister, $constantaddress($con));
10342 + %}
10403 10343 ins_pipe(pipe_slow);
10404 10344 %}
10405 10345
10406 10346 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
10407 10347 %{
10408 10348 match(Set cr (CmpD src1 src2));
10409 10349
10410 10350 ins_cost(145);
10411 10351 format %{ "ucomisd $src1, $src2\n\t"
10412 10352 "jnp,s exit\n\t"
10413 10353 "pushfq\t# saw NaN, set CF\n\t"
10414 10354 "andq [rsp], #0xffffff2b\n\t"
10415 10355 "popfq\n"
10416 10356 "exit: nop\t# avoid branch to branch" %}
10417 10357 opcode(0x66, 0x0F, 0x2E);
10418 10358 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
10419 10359 cmpfp_fixup);
10420 10360 ins_pipe(pipe_slow);
10421 10361 %}
10422 10362
10423 10363 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
10424 10364 match(Set cr (CmpD src1 src2));
10425 10365
10426 10366 ins_cost(100);
10427 10367 format %{ "ucomisd $src1, $src2 test" %}
10428 10368 ins_encode %{
10429 10369 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10430 10370 %}
10431 10371 ins_pipe(pipe_slow);
10432 10372 %}
10433 10373
10434 10374 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
10435 10375 %{
10436 10376 match(Set cr (CmpD src1 (LoadD src2)));
10437 10377
10438 10378 ins_cost(145);
10439 10379 format %{ "ucomisd $src1, $src2\n\t"
10440 10380 "jnp,s exit\n\t"
10441 10381 "pushfq\t# saw NaN, set CF\n\t"
10442 10382 "andq [rsp], #0xffffff2b\n\t"
10443 10383 "popfq\n"
10444 10384 "exit: nop\t# avoid branch to branch" %}
10445 10385 opcode(0x66, 0x0F, 0x2E);
10446 10386 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
10447 10387 cmpfp_fixup);
10448 10388 ins_pipe(pipe_slow);
10449 10389 %}
10450 10390
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
10451 10391 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
10452 10392 match(Set cr (CmpD src1 (LoadD src2)));
10453 10393
10454 10394 ins_cost(100);
10455 10395 format %{ "ucomisd $src1, $src2" %}
10456 10396 opcode(0x66, 0x0F, 0x2E);
10457 10397 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
10458 10398 ins_pipe(pipe_slow);
10459 10399 %}
10460 10400
10461 -instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
10462 -%{
10463 - match(Set cr (CmpD src1 src2));
10401 +instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
10402 + match(Set cr (CmpD src con));
10464 10403
10465 10404 ins_cost(145);
10466 - format %{ "ucomisd $src1, [$src2]\n\t"
10405 + format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10467 10406 "jnp,s exit\n\t"
10468 10407 "pushfq\t# saw NaN, set CF\n\t"
10469 10408 "andq [rsp], #0xffffff2b\n\t"
10470 10409 "popfq\n"
10471 10410 "exit: nop\t# avoid branch to branch" %}
10472 - opcode(0x66, 0x0F, 0x2E);
10473 - ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2),
10474 - cmpfp_fixup);
10411 + ins_encode %{
10412 + Label L_exit;
10413 + __ ucomisd($src$$XMMRegister, $constantaddress($con));
10414 + __ jcc(Assembler::noParity, L_exit);
10415 + __ pushf();
10416 + __ andq(rsp, 0xffffff2b);
10417 + __ popf();
10418 + __ bind(L_exit);
10419 + __ nop();
10420 + %}
10475 10421 ins_pipe(pipe_slow);
10476 10422 %}
10477 10423
10478 -instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
10479 - match(Set cr (CmpD src1 src2));
10480 -
10424 +instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
10425 + match(Set cr (CmpD src con));
10481 10426 ins_cost(100);
10482 - format %{ "ucomisd $src1, [$src2]" %}
10483 - opcode(0x66, 0x0F, 0x2E);
10484 - ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2));
10427 + format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
10428 + ins_encode %{
10429 + __ ucomisd($src$$XMMRegister, $constantaddress($con));
10430 + %}
10485 10431 ins_pipe(pipe_slow);
10486 10432 %}
10487 10433
10488 10434 // Compare into -1,0,1
10489 10435 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
10490 10436 %{
10491 10437 match(Set dst (CmpF3 src1 src2));
10492 10438 effect(KILL cr);
10493 10439
10494 10440 ins_cost(275);
10495 10441 format %{ "ucomiss $src1, $src2\n\t"
10496 10442 "movl $dst, #-1\n\t"
10497 10443 "jp,s done\n\t"
10498 10444 "jb,s done\n\t"
10499 10445 "setne $dst\n\t"
10500 10446 "movzbl $dst, $dst\n"
10501 10447 "done:" %}
10502 10448
10503 10449 opcode(0x0F, 0x2E);
10504 10450 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2),
10505 10451 cmpfp3(dst));
10506 10452 ins_pipe(pipe_slow);
10507 10453 %}
10508 10454
10509 10455 // Compare into -1,0,1
10510 10456 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
10511 10457 %{
10512 10458 match(Set dst (CmpF3 src1 (LoadF src2)));
10513 10459 effect(KILL cr);
10514 10460
10515 10461 ins_cost(275);
10516 10462 format %{ "ucomiss $src1, $src2\n\t"
10517 10463 "movl $dst, #-1\n\t"
10518 10464 "jp,s done\n\t"
10519 10465 "jb,s done\n\t"
10520 10466 "setne $dst\n\t"
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
10521 10467 "movzbl $dst, $dst\n"
10522 10468 "done:" %}
10523 10469
10524 10470 opcode(0x0F, 0x2E);
10525 10471 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
10526 10472 cmpfp3(dst));
10527 10473 ins_pipe(pipe_slow);
10528 10474 %}
10529 10475
10530 10476 // Compare into -1,0,1
10531 -instruct cmpF_imm(rRegI dst, regF src1, immF src2, rFlagsReg cr)
10532 -%{
10533 - match(Set dst (CmpF3 src1 src2));
10477 +instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
10478 + match(Set dst (CmpF3 src con));
10534 10479 effect(KILL cr);
10535 10480
10536 10481 ins_cost(275);
10537 - format %{ "ucomiss $src1, [$src2]\n\t"
10482 + format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10538 10483 "movl $dst, #-1\n\t"
10539 10484 "jp,s done\n\t"
10540 10485 "jb,s done\n\t"
10541 10486 "setne $dst\n\t"
10542 10487 "movzbl $dst, $dst\n"
10543 10488 "done:" %}
10544 -
10545 - opcode(0x0F, 0x2E);
10546 - ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2),
10547 - cmpfp3(dst));
10489 + ins_encode %{
10490 + Label L_done;
10491 + Register Rdst = $dst$$Register;
10492 + __ ucomiss($src$$XMMRegister, $constantaddress($con));
10493 + __ movl(Rdst, -1);
10494 + __ jcc(Assembler::parity, L_done);
10495 + __ jcc(Assembler::below, L_done);
10496 + __ setb(Assembler::notEqual, Rdst);
10497 + __ movzbl(Rdst, Rdst);
10498 + __ bind(L_done);
10499 + %}
10548 10500 ins_pipe(pipe_slow);
10549 10501 %}
10550 10502
10551 10503 // Compare into -1,0,1
10552 10504 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
10553 10505 %{
10554 10506 match(Set dst (CmpD3 src1 src2));
10555 10507 effect(KILL cr);
10556 10508
10557 10509 ins_cost(275);
10558 10510 format %{ "ucomisd $src1, $src2\n\t"
10559 10511 "movl $dst, #-1\n\t"
10560 10512 "jp,s done\n\t"
10561 10513 "jb,s done\n\t"
10562 10514 "setne $dst\n\t"
10563 10515 "movzbl $dst, $dst\n"
10564 10516 "done:" %}
10565 10517
10566 10518 opcode(0x66, 0x0F, 0x2E);
10567 10519 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
10568 10520 cmpfp3(dst));
10569 10521 ins_pipe(pipe_slow);
10570 10522 %}
10571 10523
10572 10524 // Compare into -1,0,1
10573 10525 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
10574 10526 %{
10575 10527 match(Set dst (CmpD3 src1 (LoadD src2)));
10576 10528 effect(KILL cr);
10577 10529
10578 10530 ins_cost(275);
10579 10531 format %{ "ucomisd $src1, $src2\n\t"
10580 10532 "movl $dst, #-1\n\t"
10581 10533 "jp,s done\n\t"
10582 10534 "jb,s done\n\t"
10583 10535 "setne $dst\n\t"
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
10584 10536 "movzbl $dst, $dst\n"
10585 10537 "done:" %}
10586 10538
10587 10539 opcode(0x66, 0x0F, 0x2E);
10588 10540 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
10589 10541 cmpfp3(dst));
10590 10542 ins_pipe(pipe_slow);
10591 10543 %}
10592 10544
10593 10545 // Compare into -1,0,1
10594 -instruct cmpD_imm(rRegI dst, regD src1, immD src2, rFlagsReg cr)
10595 -%{
10596 - match(Set dst (CmpD3 src1 src2));
10546 +instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
10547 + match(Set dst (CmpD3 src con));
10597 10548 effect(KILL cr);
10598 10549
10599 10550 ins_cost(275);
10600 - format %{ "ucomisd $src1, [$src2]\n\t"
10551 + format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10601 10552 "movl $dst, #-1\n\t"
10602 10553 "jp,s done\n\t"
10603 10554 "jb,s done\n\t"
10604 10555 "setne $dst\n\t"
10605 10556 "movzbl $dst, $dst\n"
10606 10557 "done:" %}
10607 -
10608 - opcode(0x66, 0x0F, 0x2E);
10609 - ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2),
10610 - cmpfp3(dst));
10558 + ins_encode %{
10559 + Register Rdst = $dst$$Register;
10560 + Label L_done;
10561 + __ ucomisd($src$$XMMRegister, $constantaddress($con));
10562 + __ movl(Rdst, -1);
10563 + __ jcc(Assembler::parity, L_done);
10564 + __ jcc(Assembler::below, L_done);
10565 + __ setb(Assembler::notEqual, Rdst);
10566 + __ movzbl(Rdst, Rdst);
10567 + __ bind(L_done);
10568 + %}
10611 10569 ins_pipe(pipe_slow);
10612 10570 %}
10613 10571
10614 10572 instruct addF_reg(regF dst, regF src)
10615 10573 %{
10616 10574 match(Set dst (AddF dst src));
10617 10575
10618 10576 format %{ "addss $dst, $src" %}
10619 10577 ins_cost(150); // XXX
10620 10578 opcode(0xF3, 0x0F, 0x58);
10621 10579 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10622 10580 ins_pipe(pipe_slow);
10623 10581 %}
10624 10582
10625 10583 instruct addF_mem(regF dst, memory src)
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
10626 10584 %{
10627 10585 match(Set dst (AddF dst (LoadF src)));
10628 10586
10629 10587 format %{ "addss $dst, $src" %}
10630 10588 ins_cost(150); // XXX
10631 10589 opcode(0xF3, 0x0F, 0x58);
10632 10590 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10633 10591 ins_pipe(pipe_slow);
10634 10592 %}
10635 10593
10636 -instruct addF_imm(regF dst, immF src)
10637 -%{
10638 - match(Set dst (AddF dst src));
10639 -
10640 - format %{ "addss $dst, [$src]" %}
10594 +instruct addF_imm(regF dst, immF con) %{
10595 + match(Set dst (AddF dst con));
10596 + format %{ "addss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10641 10597 ins_cost(150); // XXX
10642 - opcode(0xF3, 0x0F, 0x58);
10643 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10598 + ins_encode %{
10599 + __ addss($dst$$XMMRegister, $constantaddress($con));
10600 + %}
10644 10601 ins_pipe(pipe_slow);
10645 10602 %}
10646 10603
10647 10604 instruct addD_reg(regD dst, regD src)
10648 10605 %{
10649 10606 match(Set dst (AddD dst src));
10650 10607
10651 10608 format %{ "addsd $dst, $src" %}
10652 10609 ins_cost(150); // XXX
10653 10610 opcode(0xF2, 0x0F, 0x58);
10654 10611 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10655 10612 ins_pipe(pipe_slow);
10656 10613 %}
10657 10614
10658 10615 instruct addD_mem(regD dst, memory src)
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
10659 10616 %{
10660 10617 match(Set dst (AddD dst (LoadD src)));
10661 10618
10662 10619 format %{ "addsd $dst, $src" %}
10663 10620 ins_cost(150); // XXX
10664 10621 opcode(0xF2, 0x0F, 0x58);
10665 10622 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10666 10623 ins_pipe(pipe_slow);
10667 10624 %}
10668 10625
10669 -instruct addD_imm(regD dst, immD src)
10670 -%{
10671 - match(Set dst (AddD dst src));
10672 -
10673 - format %{ "addsd $dst, [$src]" %}
10626 +instruct addD_imm(regD dst, immD con) %{
10627 + match(Set dst (AddD dst con));
10628 + format %{ "addsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10674 10629 ins_cost(150); // XXX
10675 - opcode(0xF2, 0x0F, 0x58);
10676 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10630 + ins_encode %{
10631 + __ addsd($dst$$XMMRegister, $constantaddress($con));
10632 + %}
10677 10633 ins_pipe(pipe_slow);
10678 10634 %}
10679 10635
10680 10636 instruct subF_reg(regF dst, regF src)
10681 10637 %{
10682 10638 match(Set dst (SubF dst src));
10683 10639
10684 10640 format %{ "subss $dst, $src" %}
10685 10641 ins_cost(150); // XXX
10686 10642 opcode(0xF3, 0x0F, 0x5C);
10687 10643 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10688 10644 ins_pipe(pipe_slow);
10689 10645 %}
10690 10646
10691 10647 instruct subF_mem(regF dst, memory src)
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
10692 10648 %{
10693 10649 match(Set dst (SubF dst (LoadF src)));
10694 10650
10695 10651 format %{ "subss $dst, $src" %}
10696 10652 ins_cost(150); // XXX
10697 10653 opcode(0xF3, 0x0F, 0x5C);
10698 10654 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10699 10655 ins_pipe(pipe_slow);
10700 10656 %}
10701 10657
10702 -instruct subF_imm(regF dst, immF src)
10703 -%{
10704 - match(Set dst (SubF dst src));
10705 -
10706 - format %{ "subss $dst, [$src]" %}
10658 +instruct subF_imm(regF dst, immF con) %{
10659 + match(Set dst (SubF dst con));
10660 + format %{ "subss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10707 10661 ins_cost(150); // XXX
10708 - opcode(0xF3, 0x0F, 0x5C);
10709 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10662 + ins_encode %{
10663 + __ subss($dst$$XMMRegister, $constantaddress($con));
10664 + %}
10710 10665 ins_pipe(pipe_slow);
10711 10666 %}
10712 10667
10713 10668 instruct subD_reg(regD dst, regD src)
10714 10669 %{
10715 10670 match(Set dst (SubD dst src));
10716 10671
10717 10672 format %{ "subsd $dst, $src" %}
10718 10673 ins_cost(150); // XXX
10719 10674 opcode(0xF2, 0x0F, 0x5C);
10720 10675 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10721 10676 ins_pipe(pipe_slow);
10722 10677 %}
10723 10678
10724 10679 instruct subD_mem(regD dst, memory src)
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
10725 10680 %{
10726 10681 match(Set dst (SubD dst (LoadD src)));
10727 10682
10728 10683 format %{ "subsd $dst, $src" %}
10729 10684 ins_cost(150); // XXX
10730 10685 opcode(0xF2, 0x0F, 0x5C);
10731 10686 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10732 10687 ins_pipe(pipe_slow);
10733 10688 %}
10734 10689
10735 -instruct subD_imm(regD dst, immD src)
10736 -%{
10737 - match(Set dst (SubD dst src));
10738 -
10739 - format %{ "subsd $dst, [$src]" %}
10690 +instruct subD_imm(regD dst, immD con) %{
10691 + match(Set dst (SubD dst con));
10692 + format %{ "subsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10740 10693 ins_cost(150); // XXX
10741 - opcode(0xF2, 0x0F, 0x5C);
10742 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10694 + ins_encode %{
10695 + __ subsd($dst$$XMMRegister, $constantaddress($con));
10696 + %}
10743 10697 ins_pipe(pipe_slow);
10744 10698 %}
10745 10699
10746 10700 instruct mulF_reg(regF dst, regF src)
10747 10701 %{
10748 10702 match(Set dst (MulF dst src));
10749 10703
10750 10704 format %{ "mulss $dst, $src" %}
10751 10705 ins_cost(150); // XXX
10752 10706 opcode(0xF3, 0x0F, 0x59);
10753 10707 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10754 10708 ins_pipe(pipe_slow);
10755 10709 %}
10756 10710
10757 10711 instruct mulF_mem(regF dst, memory src)
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
10758 10712 %{
10759 10713 match(Set dst (MulF dst (LoadF src)));
10760 10714
10761 10715 format %{ "mulss $dst, $src" %}
10762 10716 ins_cost(150); // XXX
10763 10717 opcode(0xF3, 0x0F, 0x59);
10764 10718 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10765 10719 ins_pipe(pipe_slow);
10766 10720 %}
10767 10721
10768 -instruct mulF_imm(regF dst, immF src)
10769 -%{
10770 - match(Set dst (MulF dst src));
10771 -
10772 - format %{ "mulss $dst, [$src]" %}
10722 +instruct mulF_imm(regF dst, immF con) %{
10723 + match(Set dst (MulF dst con));
10724 + format %{ "mulss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10773 10725 ins_cost(150); // XXX
10774 - opcode(0xF3, 0x0F, 0x59);
10775 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10726 + ins_encode %{
10727 + __ mulss($dst$$XMMRegister, $constantaddress($con));
10728 + %}
10776 10729 ins_pipe(pipe_slow);
10777 10730 %}
10778 10731
10779 10732 instruct mulD_reg(regD dst, regD src)
10780 10733 %{
10781 10734 match(Set dst (MulD dst src));
10782 10735
10783 10736 format %{ "mulsd $dst, $src" %}
10784 10737 ins_cost(150); // XXX
10785 10738 opcode(0xF2, 0x0F, 0x59);
10786 10739 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10787 10740 ins_pipe(pipe_slow);
10788 10741 %}
10789 10742
10790 10743 instruct mulD_mem(regD dst, memory src)
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
10791 10744 %{
10792 10745 match(Set dst (MulD dst (LoadD src)));
10793 10746
10794 10747 format %{ "mulsd $dst, $src" %}
10795 10748 ins_cost(150); // XXX
10796 10749 opcode(0xF2, 0x0F, 0x59);
10797 10750 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10798 10751 ins_pipe(pipe_slow);
10799 10752 %}
10800 10753
10801 -instruct mulD_imm(regD dst, immD src)
10802 -%{
10803 - match(Set dst (MulD dst src));
10804 -
10805 - format %{ "mulsd $dst, [$src]" %}
10754 +instruct mulD_imm(regD dst, immD con) %{
10755 + match(Set dst (MulD dst con));
10756 + format %{ "mulsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10806 10757 ins_cost(150); // XXX
10807 - opcode(0xF2, 0x0F, 0x59);
10808 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10758 + ins_encode %{
10759 + __ mulsd($dst$$XMMRegister, $constantaddress($con));
10760 + %}
10809 10761 ins_pipe(pipe_slow);
10810 10762 %}
10811 10763
10812 10764 instruct divF_reg(regF dst, regF src)
10813 10765 %{
10814 10766 match(Set dst (DivF dst src));
10815 10767
10816 10768 format %{ "divss $dst, $src" %}
10817 10769 ins_cost(150); // XXX
10818 10770 opcode(0xF3, 0x0F, 0x5E);
10819 10771 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10820 10772 ins_pipe(pipe_slow);
10821 10773 %}
10822 10774
10823 10775 instruct divF_mem(regF dst, memory src)
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
10824 10776 %{
10825 10777 match(Set dst (DivF dst (LoadF src)));
10826 10778
10827 10779 format %{ "divss $dst, $src" %}
10828 10780 ins_cost(150); // XXX
10829 10781 opcode(0xF3, 0x0F, 0x5E);
10830 10782 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10831 10783 ins_pipe(pipe_slow);
10832 10784 %}
10833 10785
10834 -instruct divF_imm(regF dst, immF src)
10835 -%{
10836 - match(Set dst (DivF dst src));
10837 -
10838 - format %{ "divss $dst, [$src]" %}
10786 +instruct divF_imm(regF dst, immF con) %{
10787 + match(Set dst (DivF dst con));
10788 + format %{ "divss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10839 10789 ins_cost(150); // XXX
10840 - opcode(0xF3, 0x0F, 0x5E);
10841 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10790 + ins_encode %{
10791 + __ divss($dst$$XMMRegister, $constantaddress($con));
10792 + %}
10842 10793 ins_pipe(pipe_slow);
10843 10794 %}
10844 10795
10845 10796 instruct divD_reg(regD dst, regD src)
10846 10797 %{
10847 10798 match(Set dst (DivD dst src));
10848 10799
10849 10800 format %{ "divsd $dst, $src" %}
10850 10801 ins_cost(150); // XXX
10851 10802 opcode(0xF2, 0x0F, 0x5E);
10852 10803 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10853 10804 ins_pipe(pipe_slow);
10854 10805 %}
10855 10806
10856 10807 instruct divD_mem(regD dst, memory src)
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
10857 10808 %{
10858 10809 match(Set dst (DivD dst (LoadD src)));
10859 10810
10860 10811 format %{ "divsd $dst, $src" %}
10861 10812 ins_cost(150); // XXX
10862 10813 opcode(0xF2, 0x0F, 0x5E);
10863 10814 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10864 10815 ins_pipe(pipe_slow);
10865 10816 %}
10866 10817
10867 -instruct divD_imm(regD dst, immD src)
10868 -%{
10869 - match(Set dst (DivD dst src));
10870 -
10871 - format %{ "divsd $dst, [$src]" %}
10818 +instruct divD_imm(regD dst, immD con) %{
10819 + match(Set dst (DivD dst con));
10820 + format %{ "divsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10872 10821 ins_cost(150); // XXX
10873 - opcode(0xF2, 0x0F, 0x5E);
10874 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10822 + ins_encode %{
10823 + __ divsd($dst$$XMMRegister, $constantaddress($con));
10824 + %}
10875 10825 ins_pipe(pipe_slow);
10876 10826 %}
10877 10827
10878 10828 instruct sqrtF_reg(regF dst, regF src)
10879 10829 %{
10880 10830 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10881 10831
10882 10832 format %{ "sqrtss $dst, $src" %}
10883 10833 ins_cost(150); // XXX
10884 10834 opcode(0xF3, 0x0F, 0x51);
10885 10835 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10886 10836 ins_pipe(pipe_slow);
10887 10837 %}
10888 10838
10889 10839 instruct sqrtF_mem(regF dst, memory src)
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
10890 10840 %{
10891 10841 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
10892 10842
10893 10843 format %{ "sqrtss $dst, $src" %}
10894 10844 ins_cost(150); // XXX
10895 10845 opcode(0xF3, 0x0F, 0x51);
10896 10846 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10897 10847 ins_pipe(pipe_slow);
10898 10848 %}
10899 10849
10900 -instruct sqrtF_imm(regF dst, immF src)
10901 -%{
10902 - match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10903 -
10904 - format %{ "sqrtss $dst, [$src]" %}
10850 +instruct sqrtF_imm(regF dst, immF con) %{
10851 + match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
10852 + format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
10905 10853 ins_cost(150); // XXX
10906 - opcode(0xF3, 0x0F, 0x51);
10907 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10854 + ins_encode %{
10855 + __ sqrtss($dst$$XMMRegister, $constantaddress($con));
10856 + %}
10908 10857 ins_pipe(pipe_slow);
10909 10858 %}
10910 10859
10911 10860 instruct sqrtD_reg(regD dst, regD src)
10912 10861 %{
10913 10862 match(Set dst (SqrtD src));
10914 10863
10915 10864 format %{ "sqrtsd $dst, $src" %}
10916 10865 ins_cost(150); // XXX
10917 10866 opcode(0xF2, 0x0F, 0x51);
10918 10867 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10919 10868 ins_pipe(pipe_slow);
10920 10869 %}
10921 10870
10922 10871 instruct sqrtD_mem(regD dst, memory src)
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
10923 10872 %{
10924 10873 match(Set dst (SqrtD (LoadD src)));
10925 10874
10926 10875 format %{ "sqrtsd $dst, $src" %}
10927 10876 ins_cost(150); // XXX
10928 10877 opcode(0xF2, 0x0F, 0x51);
10929 10878 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10930 10879 ins_pipe(pipe_slow);
10931 10880 %}
10932 10881
10933 -instruct sqrtD_imm(regD dst, immD src)
10934 -%{
10935 - match(Set dst (SqrtD src));
10936 -
10937 - format %{ "sqrtsd $dst, [$src]" %}
10882 +instruct sqrtD_imm(regD dst, immD con) %{
10883 + match(Set dst (SqrtD con));
10884 + format %{ "sqrtsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
10938 10885 ins_cost(150); // XXX
10939 - opcode(0xF2, 0x0F, 0x51);
10940 - ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10886 + ins_encode %{
10887 + __ sqrtsd($dst$$XMMRegister, $constantaddress($con));
10888 + %}
10941 10889 ins_pipe(pipe_slow);
10942 10890 %}
10943 10891
10944 10892 instruct absF_reg(regF dst)
10945 10893 %{
10946 10894 match(Set dst (AbsF dst));
10947 10895
10948 10896 format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %}
10949 10897 ins_encode(absF_encoding(dst));
10950 10898 ins_pipe(pipe_slow);
10951 10899 %}
10952 10900
10953 10901 instruct absD_reg(regD dst)
10954 10902 %{
10955 10903 match(Set dst (AbsD dst));
10956 10904
10957 10905 format %{ "andpd $dst, [0x7fffffffffffffff]\t"
10958 10906 "# abs double by sign masking" %}
10959 10907 ins_encode(absD_encoding(dst));
10960 10908 ins_pipe(pipe_slow);
10961 10909 %}
10962 10910
10963 10911 instruct negF_reg(regF dst)
10964 10912 %{
10965 10913 match(Set dst (NegF dst));
10966 10914
10967 10915 format %{ "xorps $dst, [0x80000000]\t# neg float by sign flipping" %}
10968 10916 ins_encode(negF_encoding(dst));
10969 10917 ins_pipe(pipe_slow);
10970 10918 %}
10971 10919
10972 10920 instruct negD_reg(regD dst)
10973 10921 %{
10974 10922 match(Set dst (NegD dst));
10975 10923
10976 10924 format %{ "xorpd $dst, [0x8000000000000000]\t"
10977 10925 "# neg double by sign flipping" %}
10978 10926 ins_encode(negD_encoding(dst));
10979 10927 ins_pipe(pipe_slow);
10980 10928 %}
10981 10929
10982 10930 // -----------Trig and Trancendental Instructions------------------------------
10983 10931 instruct cosD_reg(regD dst) %{
10984 10932 match(Set dst (CosD dst));
10985 10933
10986 10934 format %{ "dcos $dst\n\t" %}
10987 10935 opcode(0xD9, 0xFF);
10988 10936 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
10989 10937 ins_pipe( pipe_slow );
10990 10938 %}
10991 10939
10992 10940 instruct sinD_reg(regD dst) %{
10993 10941 match(Set dst (SinD dst));
10994 10942
10995 10943 format %{ "dsin $dst\n\t" %}
10996 10944 opcode(0xD9, 0xFE);
10997 10945 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
10998 10946 ins_pipe( pipe_slow );
10999 10947 %}
11000 10948
11001 10949 instruct tanD_reg(regD dst) %{
11002 10950 match(Set dst (TanD dst));
11003 10951
11004 10952 format %{ "dtan $dst\n\t" %}
11005 10953 ins_encode( Push_SrcXD(dst),
11006 10954 Opcode(0xD9), Opcode(0xF2), //fptan
11007 10955 Opcode(0xDD), Opcode(0xD8), //fstp st
11008 10956 Push_ResultXD(dst) );
11009 10957 ins_pipe( pipe_slow );
11010 10958 %}
11011 10959
11012 10960 instruct log10D_reg(regD dst) %{
11013 10961 // The source and result Double operands in XMM registers
11014 10962 match(Set dst (Log10D dst));
11015 10963 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number
11016 10964 // fyl2x ; compute log_10(2) * log_2(x)
11017 10965 format %{ "fldlg2\t\t\t#Log10\n\t"
11018 10966 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t"
11019 10967 %}
11020 10968 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2
11021 10969 Push_SrcXD(dst),
11022 10970 Opcode(0xD9), Opcode(0xF1), // fyl2x
11023 10971 Push_ResultXD(dst));
11024 10972
11025 10973 ins_pipe( pipe_slow );
11026 10974 %}
11027 10975
11028 10976 instruct logD_reg(regD dst) %{
11029 10977 // The source and result Double operands in XMM registers
11030 10978 match(Set dst (LogD dst));
11031 10979 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number
11032 10980 // fyl2x ; compute log_e(2) * log_2(x)
11033 10981 format %{ "fldln2\t\t\t#Log_e\n\t"
11034 10982 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t"
11035 10983 %}
11036 10984 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2
11037 10985 Push_SrcXD(dst),
11038 10986 Opcode(0xD9), Opcode(0xF1), // fyl2x
11039 10987 Push_ResultXD(dst));
11040 10988 ins_pipe( pipe_slow );
11041 10989 %}
11042 10990
11043 10991
11044 10992
11045 10993 //----------Arithmetic Conversion Instructions---------------------------------
11046 10994
11047 10995 instruct roundFloat_nop(regF dst)
11048 10996 %{
11049 10997 match(Set dst (RoundFloat dst));
11050 10998
11051 10999 ins_cost(0);
11052 11000 ins_encode();
11053 11001 ins_pipe(empty);
11054 11002 %}
11055 11003
11056 11004 instruct roundDouble_nop(regD dst)
11057 11005 %{
11058 11006 match(Set dst (RoundDouble dst));
11059 11007
11060 11008 ins_cost(0);
11061 11009 ins_encode();
11062 11010 ins_pipe(empty);
11063 11011 %}
11064 11012
11065 11013 instruct convF2D_reg_reg(regD dst, regF src)
11066 11014 %{
11067 11015 match(Set dst (ConvF2D src));
11068 11016
11069 11017 format %{ "cvtss2sd $dst, $src" %}
11070 11018 opcode(0xF3, 0x0F, 0x5A);
11071 11019 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
11072 11020 ins_pipe(pipe_slow); // XXX
11073 11021 %}
11074 11022
11075 11023 instruct convF2D_reg_mem(regD dst, memory src)
11076 11024 %{
11077 11025 match(Set dst (ConvF2D (LoadF src)));
11078 11026
11079 11027 format %{ "cvtss2sd $dst, $src" %}
11080 11028 opcode(0xF3, 0x0F, 0x5A);
11081 11029 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11082 11030 ins_pipe(pipe_slow); // XXX
11083 11031 %}
11084 11032
11085 11033 instruct convD2F_reg_reg(regF dst, regD src)
11086 11034 %{
11087 11035 match(Set dst (ConvD2F src));
11088 11036
11089 11037 format %{ "cvtsd2ss $dst, $src" %}
11090 11038 opcode(0xF2, 0x0F, 0x5A);
11091 11039 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
11092 11040 ins_pipe(pipe_slow); // XXX
11093 11041 %}
11094 11042
11095 11043 instruct convD2F_reg_mem(regF dst, memory src)
11096 11044 %{
11097 11045 match(Set dst (ConvD2F (LoadD src)));
11098 11046
11099 11047 format %{ "cvtsd2ss $dst, $src" %}
11100 11048 opcode(0xF2, 0x0F, 0x5A);
11101 11049 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11102 11050 ins_pipe(pipe_slow); // XXX
11103 11051 %}
11104 11052
11105 11053 // XXX do mem variants
11106 11054 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
11107 11055 %{
11108 11056 match(Set dst (ConvF2I src));
11109 11057 effect(KILL cr);
11110 11058
11111 11059 format %{ "cvttss2sil $dst, $src\t# f2i\n\t"
11112 11060 "cmpl $dst, #0x80000000\n\t"
11113 11061 "jne,s done\n\t"
11114 11062 "subq rsp, #8\n\t"
11115 11063 "movss [rsp], $src\n\t"
11116 11064 "call f2i_fixup\n\t"
11117 11065 "popq $dst\n"
11118 11066 "done: "%}
11119 11067 opcode(0xF3, 0x0F, 0x2C);
11120 11068 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src),
11121 11069 f2i_fixup(dst, src));
11122 11070 ins_pipe(pipe_slow);
11123 11071 %}
11124 11072
11125 11073 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
11126 11074 %{
11127 11075 match(Set dst (ConvF2L src));
11128 11076 effect(KILL cr);
11129 11077
11130 11078 format %{ "cvttss2siq $dst, $src\t# f2l\n\t"
11131 11079 "cmpq $dst, [0x8000000000000000]\n\t"
11132 11080 "jne,s done\n\t"
11133 11081 "subq rsp, #8\n\t"
11134 11082 "movss [rsp], $src\n\t"
11135 11083 "call f2l_fixup\n\t"
11136 11084 "popq $dst\n"
11137 11085 "done: "%}
11138 11086 opcode(0xF3, 0x0F, 0x2C);
11139 11087 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src),
11140 11088 f2l_fixup(dst, src));
11141 11089 ins_pipe(pipe_slow);
11142 11090 %}
11143 11091
11144 11092 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
11145 11093 %{
11146 11094 match(Set dst (ConvD2I src));
11147 11095 effect(KILL cr);
11148 11096
11149 11097 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t"
11150 11098 "cmpl $dst, #0x80000000\n\t"
11151 11099 "jne,s done\n\t"
11152 11100 "subq rsp, #8\n\t"
11153 11101 "movsd [rsp], $src\n\t"
11154 11102 "call d2i_fixup\n\t"
11155 11103 "popq $dst\n"
11156 11104 "done: "%}
11157 11105 opcode(0xF2, 0x0F, 0x2C);
11158 11106 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src),
11159 11107 d2i_fixup(dst, src));
11160 11108 ins_pipe(pipe_slow);
11161 11109 %}
11162 11110
11163 11111 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
11164 11112 %{
11165 11113 match(Set dst (ConvD2L src));
11166 11114 effect(KILL cr);
11167 11115
11168 11116 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t"
11169 11117 "cmpq $dst, [0x8000000000000000]\n\t"
11170 11118 "jne,s done\n\t"
11171 11119 "subq rsp, #8\n\t"
11172 11120 "movsd [rsp], $src\n\t"
11173 11121 "call d2l_fixup\n\t"
11174 11122 "popq $dst\n"
11175 11123 "done: "%}
11176 11124 opcode(0xF2, 0x0F, 0x2C);
11177 11125 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src),
11178 11126 d2l_fixup(dst, src));
11179 11127 ins_pipe(pipe_slow);
11180 11128 %}
11181 11129
11182 11130 instruct convI2F_reg_reg(regF dst, rRegI src)
11183 11131 %{
11184 11132 predicate(!UseXmmI2F);
11185 11133 match(Set dst (ConvI2F src));
11186 11134
11187 11135 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
11188 11136 opcode(0xF3, 0x0F, 0x2A);
11189 11137 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
11190 11138 ins_pipe(pipe_slow); // XXX
11191 11139 %}
11192 11140
11193 11141 instruct convI2F_reg_mem(regF dst, memory src)
11194 11142 %{
11195 11143 match(Set dst (ConvI2F (LoadI src)));
11196 11144
11197 11145 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
11198 11146 opcode(0xF3, 0x0F, 0x2A);
11199 11147 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11200 11148 ins_pipe(pipe_slow); // XXX
11201 11149 %}
11202 11150
11203 11151 instruct convI2D_reg_reg(regD dst, rRegI src)
11204 11152 %{
11205 11153 predicate(!UseXmmI2D);
11206 11154 match(Set dst (ConvI2D src));
11207 11155
11208 11156 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
11209 11157 opcode(0xF2, 0x0F, 0x2A);
11210 11158 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
11211 11159 ins_pipe(pipe_slow); // XXX
11212 11160 %}
11213 11161
11214 11162 instruct convI2D_reg_mem(regD dst, memory src)
11215 11163 %{
11216 11164 match(Set dst (ConvI2D (LoadI src)));
11217 11165
11218 11166 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
11219 11167 opcode(0xF2, 0x0F, 0x2A);
11220 11168 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11221 11169 ins_pipe(pipe_slow); // XXX
11222 11170 %}
11223 11171
11224 11172 instruct convXI2F_reg(regF dst, rRegI src)
11225 11173 %{
11226 11174 predicate(UseXmmI2F);
11227 11175 match(Set dst (ConvI2F src));
11228 11176
11229 11177 format %{ "movdl $dst, $src\n\t"
11230 11178 "cvtdq2psl $dst, $dst\t# i2f" %}
11231 11179 ins_encode %{
11232 11180 __ movdl($dst$$XMMRegister, $src$$Register);
11233 11181 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
11234 11182 %}
11235 11183 ins_pipe(pipe_slow); // XXX
11236 11184 %}
11237 11185
11238 11186 instruct convXI2D_reg(regD dst, rRegI src)
11239 11187 %{
11240 11188 predicate(UseXmmI2D);
11241 11189 match(Set dst (ConvI2D src));
11242 11190
11243 11191 format %{ "movdl $dst, $src\n\t"
11244 11192 "cvtdq2pdl $dst, $dst\t# i2d" %}
11245 11193 ins_encode %{
11246 11194 __ movdl($dst$$XMMRegister, $src$$Register);
11247 11195 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
11248 11196 %}
11249 11197 ins_pipe(pipe_slow); // XXX
11250 11198 %}
11251 11199
11252 11200 instruct convL2F_reg_reg(regF dst, rRegL src)
11253 11201 %{
11254 11202 match(Set dst (ConvL2F src));
11255 11203
11256 11204 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
11257 11205 opcode(0xF3, 0x0F, 0x2A);
11258 11206 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src));
11259 11207 ins_pipe(pipe_slow); // XXX
11260 11208 %}
11261 11209
11262 11210 instruct convL2F_reg_mem(regF dst, memory src)
11263 11211 %{
11264 11212 match(Set dst (ConvL2F (LoadL src)));
11265 11213
11266 11214 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
11267 11215 opcode(0xF3, 0x0F, 0x2A);
11268 11216 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src));
11269 11217 ins_pipe(pipe_slow); // XXX
11270 11218 %}
11271 11219
11272 11220 instruct convL2D_reg_reg(regD dst, rRegL src)
11273 11221 %{
11274 11222 match(Set dst (ConvL2D src));
11275 11223
11276 11224 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
11277 11225 opcode(0xF2, 0x0F, 0x2A);
11278 11226 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src));
11279 11227 ins_pipe(pipe_slow); // XXX
11280 11228 %}
11281 11229
11282 11230 instruct convL2D_reg_mem(regD dst, memory src)
11283 11231 %{
11284 11232 match(Set dst (ConvL2D (LoadL src)));
11285 11233
11286 11234 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
11287 11235 opcode(0xF2, 0x0F, 0x2A);
11288 11236 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src));
11289 11237 ins_pipe(pipe_slow); // XXX
11290 11238 %}
11291 11239
11292 11240 instruct convI2L_reg_reg(rRegL dst, rRegI src)
11293 11241 %{
11294 11242 match(Set dst (ConvI2L src));
11295 11243
11296 11244 ins_cost(125);
11297 11245 format %{ "movslq $dst, $src\t# i2l" %}
11298 11246 ins_encode %{
11299 11247 __ movslq($dst$$Register, $src$$Register);
11300 11248 %}
11301 11249 ins_pipe(ialu_reg_reg);
11302 11250 %}
11303 11251
11304 11252 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src)
11305 11253 // %{
11306 11254 // match(Set dst (ConvI2L src));
11307 11255 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 &&
11308 11256 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0);
11309 11257 // predicate(((const TypeNode*) n)->type()->is_long()->_hi ==
11310 11258 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi &&
11311 11259 // ((const TypeNode*) n)->type()->is_long()->_lo ==
11312 11260 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo);
11313 11261
11314 11262 // format %{ "movl $dst, $src\t# unsigned i2l" %}
11315 11263 // ins_encode(enc_copy(dst, src));
11316 11264 // // opcode(0x63); // needs REX.W
11317 11265 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
11318 11266 // ins_pipe(ialu_reg_reg);
11319 11267 // %}
11320 11268
11321 11269 // Zero-extend convert int to long
11322 11270 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
11323 11271 %{
11324 11272 match(Set dst (AndL (ConvI2L src) mask));
11325 11273
11326 11274 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
11327 11275 ins_encode(enc_copy(dst, src));
11328 11276 ins_pipe(ialu_reg_reg);
11329 11277 %}
11330 11278
11331 11279 // Zero-extend convert int to long
11332 11280 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
11333 11281 %{
11334 11282 match(Set dst (AndL (ConvI2L (LoadI src)) mask));
11335 11283
11336 11284 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
11337 11285 opcode(0x8B);
11338 11286 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
11339 11287 ins_pipe(ialu_reg_mem);
11340 11288 %}
11341 11289
11342 11290 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
11343 11291 %{
11344 11292 match(Set dst (AndL src mask));
11345 11293
11346 11294 format %{ "movl $dst, $src\t# zero-extend long" %}
11347 11295 ins_encode(enc_copy_always(dst, src));
11348 11296 ins_pipe(ialu_reg_reg);
11349 11297 %}
11350 11298
11351 11299 instruct convL2I_reg_reg(rRegI dst, rRegL src)
11352 11300 %{
11353 11301 match(Set dst (ConvL2I src));
11354 11302
11355 11303 format %{ "movl $dst, $src\t# l2i" %}
11356 11304 ins_encode(enc_copy_always(dst, src));
11357 11305 ins_pipe(ialu_reg_reg);
11358 11306 %}
11359 11307
11360 11308
11361 11309 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
11362 11310 match(Set dst (MoveF2I src));
11363 11311 effect(DEF dst, USE src);
11364 11312
11365 11313 ins_cost(125);
11366 11314 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %}
11367 11315 opcode(0x8B);
11368 11316 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
11369 11317 ins_pipe(ialu_reg_mem);
11370 11318 %}
11371 11319
11372 11320 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
11373 11321 match(Set dst (MoveI2F src));
11374 11322 effect(DEF dst, USE src);
11375 11323
11376 11324 ins_cost(125);
11377 11325 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %}
11378 11326 opcode(0xF3, 0x0F, 0x10);
11379 11327 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11380 11328 ins_pipe(pipe_slow);
11381 11329 %}
11382 11330
11383 11331 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
11384 11332 match(Set dst (MoveD2L src));
11385 11333 effect(DEF dst, USE src);
11386 11334
11387 11335 ins_cost(125);
11388 11336 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %}
11389 11337 opcode(0x8B);
11390 11338 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
11391 11339 ins_pipe(ialu_reg_mem);
11392 11340 %}
11393 11341
11394 11342 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
11395 11343 predicate(!UseXmmLoadAndClearUpper);
11396 11344 match(Set dst (MoveL2D src));
11397 11345 effect(DEF dst, USE src);
11398 11346
11399 11347 ins_cost(125);
11400 11348 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %}
11401 11349 opcode(0x66, 0x0F, 0x12);
11402 11350 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11403 11351 ins_pipe(pipe_slow);
11404 11352 %}
11405 11353
11406 11354 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
11407 11355 predicate(UseXmmLoadAndClearUpper);
11408 11356 match(Set dst (MoveL2D src));
11409 11357 effect(DEF dst, USE src);
11410 11358
11411 11359 ins_cost(125);
11412 11360 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %}
11413 11361 opcode(0xF2, 0x0F, 0x10);
11414 11362 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11415 11363 ins_pipe(pipe_slow);
11416 11364 %}
11417 11365
11418 11366
11419 11367 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
11420 11368 match(Set dst (MoveF2I src));
11421 11369 effect(DEF dst, USE src);
11422 11370
11423 11371 ins_cost(95); // XXX
11424 11372 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %}
11425 11373 opcode(0xF3, 0x0F, 0x11);
11426 11374 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
11427 11375 ins_pipe(pipe_slow);
11428 11376 %}
11429 11377
11430 11378 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
11431 11379 match(Set dst (MoveI2F src));
11432 11380 effect(DEF dst, USE src);
11433 11381
11434 11382 ins_cost(100);
11435 11383 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %}
11436 11384 opcode(0x89);
11437 11385 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
11438 11386 ins_pipe( ialu_mem_reg );
11439 11387 %}
11440 11388
11441 11389 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
11442 11390 match(Set dst (MoveD2L src));
11443 11391 effect(DEF dst, USE src);
11444 11392
11445 11393 ins_cost(95); // XXX
11446 11394 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %}
11447 11395 opcode(0xF2, 0x0F, 0x11);
11448 11396 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
11449 11397 ins_pipe(pipe_slow);
11450 11398 %}
11451 11399
11452 11400 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
11453 11401 match(Set dst (MoveL2D src));
11454 11402 effect(DEF dst, USE src);
11455 11403
11456 11404 ins_cost(100);
11457 11405 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %}
11458 11406 opcode(0x89);
11459 11407 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
11460 11408 ins_pipe(ialu_mem_reg);
11461 11409 %}
11462 11410
11463 11411 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
11464 11412 match(Set dst (MoveF2I src));
11465 11413 effect(DEF dst, USE src);
11466 11414 ins_cost(85);
11467 11415 format %{ "movd $dst,$src\t# MoveF2I" %}
11468 11416 ins_encode %{ __ movdl($dst$$Register, $src$$XMMRegister); %}
11469 11417 ins_pipe( pipe_slow );
11470 11418 %}
11471 11419
11472 11420 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
11473 11421 match(Set dst (MoveD2L src));
11474 11422 effect(DEF dst, USE src);
11475 11423 ins_cost(85);
11476 11424 format %{ "movd $dst,$src\t# MoveD2L" %}
11477 11425 ins_encode %{ __ movdq($dst$$Register, $src$$XMMRegister); %}
11478 11426 ins_pipe( pipe_slow );
11479 11427 %}
11480 11428
11481 11429 // The next instructions have long latency and use Int unit. Set high cost.
11482 11430 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
11483 11431 match(Set dst (MoveI2F src));
11484 11432 effect(DEF dst, USE src);
11485 11433 ins_cost(300);
11486 11434 format %{ "movd $dst,$src\t# MoveI2F" %}
11487 11435 ins_encode %{ __ movdl($dst$$XMMRegister, $src$$Register); %}
11488 11436 ins_pipe( pipe_slow );
11489 11437 %}
11490 11438
11491 11439 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
11492 11440 match(Set dst (MoveL2D src));
11493 11441 effect(DEF dst, USE src);
11494 11442 ins_cost(300);
11495 11443 format %{ "movd $dst,$src\t# MoveL2D" %}
11496 11444 ins_encode %{ __ movdq($dst$$XMMRegister, $src$$Register); %}
11497 11445 ins_pipe( pipe_slow );
11498 11446 %}
11499 11447
11500 11448 // Replicate scalar to packed byte (1 byte) values in xmm
11501 11449 instruct Repl8B_reg(regD dst, regD src) %{
11502 11450 match(Set dst (Replicate8B src));
11503 11451 format %{ "MOVDQA $dst,$src\n\t"
11504 11452 "PUNPCKLBW $dst,$dst\n\t"
11505 11453 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
11506 11454 ins_encode( pshufd_8x8(dst, src));
11507 11455 ins_pipe( pipe_slow );
11508 11456 %}
11509 11457
11510 11458 // Replicate scalar to packed byte (1 byte) values in xmm
11511 11459 instruct Repl8B_rRegI(regD dst, rRegI src) %{
11512 11460 match(Set dst (Replicate8B src));
11513 11461 format %{ "MOVD $dst,$src\n\t"
11514 11462 "PUNPCKLBW $dst,$dst\n\t"
11515 11463 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
11516 11464 ins_encode( mov_i2x(dst, src), pshufd_8x8(dst, dst));
11517 11465 ins_pipe( pipe_slow );
11518 11466 %}
11519 11467
11520 11468 // Replicate scalar zero to packed byte (1 byte) values in xmm
11521 11469 instruct Repl8B_immI0(regD dst, immI0 zero) %{
11522 11470 match(Set dst (Replicate8B zero));
11523 11471 format %{ "PXOR $dst,$dst\t! replicate8B" %}
11524 11472 ins_encode( pxor(dst, dst));
11525 11473 ins_pipe( fpu_reg_reg );
11526 11474 %}
11527 11475
11528 11476 // Replicate scalar to packed shore (2 byte) values in xmm
11529 11477 instruct Repl4S_reg(regD dst, regD src) %{
11530 11478 match(Set dst (Replicate4S src));
11531 11479 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
11532 11480 ins_encode( pshufd_4x16(dst, src));
11533 11481 ins_pipe( fpu_reg_reg );
11534 11482 %}
11535 11483
11536 11484 // Replicate scalar to packed shore (2 byte) values in xmm
11537 11485 instruct Repl4S_rRegI(regD dst, rRegI src) %{
11538 11486 match(Set dst (Replicate4S src));
11539 11487 format %{ "MOVD $dst,$src\n\t"
11540 11488 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
11541 11489 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst));
11542 11490 ins_pipe( fpu_reg_reg );
11543 11491 %}
11544 11492
11545 11493 // Replicate scalar zero to packed short (2 byte) values in xmm
11546 11494 instruct Repl4S_immI0(regD dst, immI0 zero) %{
11547 11495 match(Set dst (Replicate4S zero));
11548 11496 format %{ "PXOR $dst,$dst\t! replicate4S" %}
11549 11497 ins_encode( pxor(dst, dst));
11550 11498 ins_pipe( fpu_reg_reg );
11551 11499 %}
11552 11500
11553 11501 // Replicate scalar to packed char (2 byte) values in xmm
11554 11502 instruct Repl4C_reg(regD dst, regD src) %{
11555 11503 match(Set dst (Replicate4C src));
11556 11504 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
11557 11505 ins_encode( pshufd_4x16(dst, src));
11558 11506 ins_pipe( fpu_reg_reg );
11559 11507 %}
11560 11508
11561 11509 // Replicate scalar to packed char (2 byte) values in xmm
11562 11510 instruct Repl4C_rRegI(regD dst, rRegI src) %{
11563 11511 match(Set dst (Replicate4C src));
11564 11512 format %{ "MOVD $dst,$src\n\t"
11565 11513 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
11566 11514 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst));
11567 11515 ins_pipe( fpu_reg_reg );
11568 11516 %}
11569 11517
11570 11518 // Replicate scalar zero to packed char (2 byte) values in xmm
11571 11519 instruct Repl4C_immI0(regD dst, immI0 zero) %{
11572 11520 match(Set dst (Replicate4C zero));
11573 11521 format %{ "PXOR $dst,$dst\t! replicate4C" %}
11574 11522 ins_encode( pxor(dst, dst));
11575 11523 ins_pipe( fpu_reg_reg );
11576 11524 %}
11577 11525
11578 11526 // Replicate scalar to packed integer (4 byte) values in xmm
11579 11527 instruct Repl2I_reg(regD dst, regD src) %{
11580 11528 match(Set dst (Replicate2I src));
11581 11529 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
11582 11530 ins_encode( pshufd(dst, src, 0x00));
11583 11531 ins_pipe( fpu_reg_reg );
11584 11532 %}
11585 11533
11586 11534 // Replicate scalar to packed integer (4 byte) values in xmm
11587 11535 instruct Repl2I_rRegI(regD dst, rRegI src) %{
11588 11536 match(Set dst (Replicate2I src));
11589 11537 format %{ "MOVD $dst,$src\n\t"
11590 11538 "PSHUFD $dst,$dst,0x00\t! replicate2I" %}
11591 11539 ins_encode( mov_i2x(dst, src), pshufd(dst, dst, 0x00));
11592 11540 ins_pipe( fpu_reg_reg );
11593 11541 %}
11594 11542
11595 11543 // Replicate scalar zero to packed integer (2 byte) values in xmm
11596 11544 instruct Repl2I_immI0(regD dst, immI0 zero) %{
11597 11545 match(Set dst (Replicate2I zero));
11598 11546 format %{ "PXOR $dst,$dst\t! replicate2I" %}
11599 11547 ins_encode( pxor(dst, dst));
11600 11548 ins_pipe( fpu_reg_reg );
11601 11549 %}
11602 11550
11603 11551 // Replicate scalar to packed single precision floating point values in xmm
11604 11552 instruct Repl2F_reg(regD dst, regD src) %{
11605 11553 match(Set dst (Replicate2F src));
11606 11554 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11607 11555 ins_encode( pshufd(dst, src, 0xe0));
11608 11556 ins_pipe( fpu_reg_reg );
11609 11557 %}
11610 11558
11611 11559 // Replicate scalar to packed single precision floating point values in xmm
11612 11560 instruct Repl2F_regF(regD dst, regF src) %{
11613 11561 match(Set dst (Replicate2F src));
11614 11562 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11615 11563 ins_encode( pshufd(dst, src, 0xe0));
11616 11564 ins_pipe( fpu_reg_reg );
11617 11565 %}
11618 11566
11619 11567 // Replicate scalar to packed single precision floating point values in xmm
11620 11568 instruct Repl2F_immF0(regD dst, immF0 zero) %{
11621 11569 match(Set dst (Replicate2F zero));
11622 11570 format %{ "PXOR $dst,$dst\t! replicate2F" %}
11623 11571 ins_encode( pxor(dst, dst));
11624 11572 ins_pipe( fpu_reg_reg );
11625 11573 %}
11626 11574
11627 11575
11628 11576 // =======================================================================
11629 11577 // fast clearing of an array
11630 11578 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
11631 11579 rFlagsReg cr)
11632 11580 %{
11633 11581 match(Set dummy (ClearArray cnt base));
11634 11582 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
11635 11583
11636 11584 format %{ "xorl rax, rax\t# ClearArray:\n\t"
11637 11585 "rep stosq\t# Store rax to *rdi++ while rcx--" %}
11638 11586 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax
11639 11587 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos
11640 11588 ins_pipe(pipe_slow);
11641 11589 %}
11642 11590
11643 11591 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rbx_RegI cnt2,
11644 11592 rax_RegI result, regD tmp1, regD tmp2, rFlagsReg cr)
11645 11593 %{
11646 11594 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11647 11595 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11648 11596
11649 11597 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %}
11650 11598 ins_encode %{
11651 11599 __ string_compare($str1$$Register, $str2$$Register,
11652 11600 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11653 11601 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11654 11602 %}
11655 11603 ins_pipe( pipe_slow );
11656 11604 %}
11657 11605
11658 11606 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
11659 11607 rbx_RegI result, regD tmp1, rcx_RegI tmp2, rFlagsReg cr)
11660 11608 %{
11661 11609 predicate(UseSSE42Intrinsics);
11662 11610 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11663 11611 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
11664 11612
11665 11613 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %}
11666 11614 ins_encode %{
11667 11615 __ string_indexof($str1$$Register, $str2$$Register,
11668 11616 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11669 11617 $tmp1$$XMMRegister, $tmp2$$Register);
11670 11618 %}
11671 11619 ins_pipe( pipe_slow );
11672 11620 %}
11673 11621
11674 11622 // fast string equals
11675 11623 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
11676 11624 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
11677 11625 %{
11678 11626 match(Set result (StrEquals (Binary str1 str2) cnt));
11679 11627 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
11680 11628
11681 11629 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
11682 11630 ins_encode %{
11683 11631 __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
11684 11632 $cnt$$Register, $result$$Register, $tmp3$$Register,
11685 11633 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11686 11634 %}
11687 11635 ins_pipe( pipe_slow );
11688 11636 %}
11689 11637
11690 11638 // fast array equals
11691 11639 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
11692 11640 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
11693 11641 %{
11694 11642 match(Set result (AryEq ary1 ary2));
11695 11643 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
11696 11644 //ins_cost(300);
11697 11645
11698 11646 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
11699 11647 ins_encode %{
11700 11648 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
11701 11649 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11702 11650 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11703 11651 %}
11704 11652 ins_pipe( pipe_slow );
11705 11653 %}
11706 11654
11707 11655 //----------Control Flow Instructions------------------------------------------
11708 11656 // Signed compare Instructions
11709 11657
11710 11658 // XXX more variants!!
11711 11659 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
11712 11660 %{
11713 11661 match(Set cr (CmpI op1 op2));
11714 11662 effect(DEF cr, USE op1, USE op2);
11715 11663
11716 11664 format %{ "cmpl $op1, $op2" %}
11717 11665 opcode(0x3B); /* Opcode 3B /r */
11718 11666 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
11719 11667 ins_pipe(ialu_cr_reg_reg);
11720 11668 %}
11721 11669
11722 11670 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
11723 11671 %{
11724 11672 match(Set cr (CmpI op1 op2));
11725 11673
11726 11674 format %{ "cmpl $op1, $op2" %}
11727 11675 opcode(0x81, 0x07); /* Opcode 81 /7 */
11728 11676 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
11729 11677 ins_pipe(ialu_cr_reg_imm);
11730 11678 %}
11731 11679
11732 11680 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2)
11733 11681 %{
11734 11682 match(Set cr (CmpI op1 (LoadI op2)));
11735 11683
11736 11684 ins_cost(500); // XXX
11737 11685 format %{ "cmpl $op1, $op2" %}
11738 11686 opcode(0x3B); /* Opcode 3B /r */
11739 11687 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
11740 11688 ins_pipe(ialu_cr_reg_mem);
11741 11689 %}
11742 11690
11743 11691 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero)
11744 11692 %{
11745 11693 match(Set cr (CmpI src zero));
11746 11694
11747 11695 format %{ "testl $src, $src" %}
11748 11696 opcode(0x85);
11749 11697 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
11750 11698 ins_pipe(ialu_cr_reg_imm);
11751 11699 %}
11752 11700
11753 11701 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero)
11754 11702 %{
11755 11703 match(Set cr (CmpI (AndI src con) zero));
11756 11704
11757 11705 format %{ "testl $src, $con" %}
11758 11706 opcode(0xF7, 0x00);
11759 11707 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con));
11760 11708 ins_pipe(ialu_cr_reg_imm);
11761 11709 %}
11762 11710
11763 11711 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero)
11764 11712 %{
11765 11713 match(Set cr (CmpI (AndI src (LoadI mem)) zero));
11766 11714
11767 11715 format %{ "testl $src, $mem" %}
11768 11716 opcode(0x85);
11769 11717 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
11770 11718 ins_pipe(ialu_cr_reg_mem);
11771 11719 %}
11772 11720
11773 11721 // Unsigned compare Instructions; really, same as signed except they
11774 11722 // produce an rFlagsRegU instead of rFlagsReg.
11775 11723 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2)
11776 11724 %{
11777 11725 match(Set cr (CmpU op1 op2));
11778 11726
11779 11727 format %{ "cmpl $op1, $op2\t# unsigned" %}
11780 11728 opcode(0x3B); /* Opcode 3B /r */
11781 11729 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
11782 11730 ins_pipe(ialu_cr_reg_reg);
11783 11731 %}
11784 11732
11785 11733 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2)
11786 11734 %{
11787 11735 match(Set cr (CmpU op1 op2));
11788 11736
11789 11737 format %{ "cmpl $op1, $op2\t# unsigned" %}
11790 11738 opcode(0x81,0x07); /* Opcode 81 /7 */
11791 11739 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
11792 11740 ins_pipe(ialu_cr_reg_imm);
11793 11741 %}
11794 11742
11795 11743 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2)
11796 11744 %{
11797 11745 match(Set cr (CmpU op1 (LoadI op2)));
11798 11746
11799 11747 ins_cost(500); // XXX
11800 11748 format %{ "cmpl $op1, $op2\t# unsigned" %}
11801 11749 opcode(0x3B); /* Opcode 3B /r */
11802 11750 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
11803 11751 ins_pipe(ialu_cr_reg_mem);
11804 11752 %}
11805 11753
11806 11754 // // // Cisc-spilled version of cmpU_rReg
11807 11755 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2)
11808 11756 // //%{
11809 11757 // // match(Set cr (CmpU (LoadI op1) op2));
11810 11758 // //
11811 11759 // // format %{ "CMPu $op1,$op2" %}
11812 11760 // // ins_cost(500);
11813 11761 // // opcode(0x39); /* Opcode 39 /r */
11814 11762 // // ins_encode( OpcP, reg_mem( op1, op2) );
11815 11763 // //%}
11816 11764
11817 11765 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero)
11818 11766 %{
11819 11767 match(Set cr (CmpU src zero));
11820 11768
11821 11769 format %{ "testl $src, $src\t# unsigned" %}
11822 11770 opcode(0x85);
11823 11771 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
11824 11772 ins_pipe(ialu_cr_reg_imm);
11825 11773 %}
11826 11774
11827 11775 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2)
11828 11776 %{
11829 11777 match(Set cr (CmpP op1 op2));
11830 11778
11831 11779 format %{ "cmpq $op1, $op2\t# ptr" %}
11832 11780 opcode(0x3B); /* Opcode 3B /r */
11833 11781 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
11834 11782 ins_pipe(ialu_cr_reg_reg);
11835 11783 %}
11836 11784
11837 11785 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
11838 11786 %{
11839 11787 match(Set cr (CmpP op1 (LoadP op2)));
11840 11788
11841 11789 ins_cost(500); // XXX
11842 11790 format %{ "cmpq $op1, $op2\t# ptr" %}
11843 11791 opcode(0x3B); /* Opcode 3B /r */
11844 11792 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
11845 11793 ins_pipe(ialu_cr_reg_mem);
11846 11794 %}
11847 11795
11848 11796 // // // Cisc-spilled version of cmpP_rReg
11849 11797 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2)
11850 11798 // //%{
11851 11799 // // match(Set cr (CmpP (LoadP op1) op2));
11852 11800 // //
11853 11801 // // format %{ "CMPu $op1,$op2" %}
11854 11802 // // ins_cost(500);
11855 11803 // // opcode(0x39); /* Opcode 39 /r */
11856 11804 // // ins_encode( OpcP, reg_mem( op1, op2) );
11857 11805 // //%}
11858 11806
11859 11807 // XXX this is generalized by compP_rReg_mem???
11860 11808 // Compare raw pointer (used in out-of-heap check).
11861 11809 // Only works because non-oop pointers must be raw pointers
11862 11810 // and raw pointers have no anti-dependencies.
11863 11811 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
11864 11812 %{
11865 11813 predicate(!n->in(2)->in(2)->bottom_type()->isa_oop_ptr());
11866 11814 match(Set cr (CmpP op1 (LoadP op2)));
11867 11815
11868 11816 format %{ "cmpq $op1, $op2\t# raw ptr" %}
11869 11817 opcode(0x3B); /* Opcode 3B /r */
11870 11818 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
11871 11819 ins_pipe(ialu_cr_reg_mem);
11872 11820 %}
11873 11821
11874 11822 // This will generate a signed flags result. This should be OK since
11875 11823 // any compare to a zero should be eq/neq.
11876 11824 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero)
11877 11825 %{
11878 11826 match(Set cr (CmpP src zero));
11879 11827
11880 11828 format %{ "testq $src, $src\t# ptr" %}
11881 11829 opcode(0x85);
11882 11830 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
11883 11831 ins_pipe(ialu_cr_reg_imm);
11884 11832 %}
11885 11833
11886 11834 // This will generate a signed flags result. This should be OK since
11887 11835 // any compare to a zero should be eq/neq.
11888 11836 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
11889 11837 %{
11890 11838 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
11891 11839 match(Set cr (CmpP (LoadP op) zero));
11892 11840
11893 11841 ins_cost(500); // XXX
11894 11842 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %}
11895 11843 opcode(0xF7); /* Opcode F7 /0 */
11896 11844 ins_encode(REX_mem_wide(op),
11897 11845 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
11898 11846 ins_pipe(ialu_cr_reg_imm);
11899 11847 %}
11900 11848
11901 11849 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
11902 11850 %{
11903 11851 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
11904 11852 match(Set cr (CmpP (LoadP mem) zero));
11905 11853
11906 11854 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
11907 11855 ins_encode %{
11908 11856 __ cmpq(r12, $mem$$Address);
11909 11857 %}
11910 11858 ins_pipe(ialu_cr_reg_mem);
11911 11859 %}
11912 11860
11913 11861 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
11914 11862 %{
11915 11863 match(Set cr (CmpN op1 op2));
11916 11864
11917 11865 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
11918 11866 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %}
11919 11867 ins_pipe(ialu_cr_reg_reg);
11920 11868 %}
11921 11869
11922 11870 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
11923 11871 %{
11924 11872 match(Set cr (CmpN src (LoadN mem)));
11925 11873
11926 11874 format %{ "cmpl $src, $mem\t# compressed ptr" %}
11927 11875 ins_encode %{
11928 11876 __ cmpl($src$$Register, $mem$$Address);
11929 11877 %}
11930 11878 ins_pipe(ialu_cr_reg_mem);
11931 11879 %}
11932 11880
11933 11881 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{
11934 11882 match(Set cr (CmpN op1 op2));
11935 11883
11936 11884 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
11937 11885 ins_encode %{
11938 11886 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant);
11939 11887 %}
11940 11888 ins_pipe(ialu_cr_reg_imm);
11941 11889 %}
11942 11890
11943 11891 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src)
11944 11892 %{
11945 11893 match(Set cr (CmpN src (LoadN mem)));
11946 11894
11947 11895 format %{ "cmpl $mem, $src\t# compressed ptr" %}
11948 11896 ins_encode %{
11949 11897 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
11950 11898 %}
11951 11899 ins_pipe(ialu_cr_reg_mem);
11952 11900 %}
11953 11901
11954 11902 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
11955 11903 match(Set cr (CmpN src zero));
11956 11904
11957 11905 format %{ "testl $src, $src\t# compressed ptr" %}
11958 11906 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
11959 11907 ins_pipe(ialu_cr_reg_imm);
11960 11908 %}
11961 11909
11962 11910 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
11963 11911 %{
11964 11912 predicate(Universe::narrow_oop_base() != NULL);
11965 11913 match(Set cr (CmpN (LoadN mem) zero));
11966 11914
11967 11915 ins_cost(500); // XXX
11968 11916 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
11969 11917 ins_encode %{
11970 11918 __ cmpl($mem$$Address, (int)0xFFFFFFFF);
11971 11919 %}
11972 11920 ins_pipe(ialu_cr_reg_mem);
11973 11921 %}
11974 11922
11975 11923 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
11976 11924 %{
11977 11925 predicate(Universe::narrow_oop_base() == NULL);
11978 11926 match(Set cr (CmpN (LoadN mem) zero));
11979 11927
11980 11928 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
11981 11929 ins_encode %{
11982 11930 __ cmpl(r12, $mem$$Address);
11983 11931 %}
11984 11932 ins_pipe(ialu_cr_reg_mem);
11985 11933 %}
11986 11934
11987 11935 // Yanked all unsigned pointer compare operations.
11988 11936 // Pointer compares are done with CmpP which is already unsigned.
11989 11937
11990 11938 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
11991 11939 %{
11992 11940 match(Set cr (CmpL op1 op2));
11993 11941
11994 11942 format %{ "cmpq $op1, $op2" %}
11995 11943 opcode(0x3B); /* Opcode 3B /r */
11996 11944 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
11997 11945 ins_pipe(ialu_cr_reg_reg);
11998 11946 %}
11999 11947
12000 11948 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
12001 11949 %{
12002 11950 match(Set cr (CmpL op1 op2));
12003 11951
12004 11952 format %{ "cmpq $op1, $op2" %}
12005 11953 opcode(0x81, 0x07); /* Opcode 81 /7 */
12006 11954 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2));
12007 11955 ins_pipe(ialu_cr_reg_imm);
12008 11956 %}
12009 11957
12010 11958 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2)
12011 11959 %{
12012 11960 match(Set cr (CmpL op1 (LoadL op2)));
12013 11961
12014 11962 format %{ "cmpq $op1, $op2" %}
12015 11963 opcode(0x3B); /* Opcode 3B /r */
12016 11964 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
12017 11965 ins_pipe(ialu_cr_reg_mem);
12018 11966 %}
12019 11967
12020 11968 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero)
12021 11969 %{
12022 11970 match(Set cr (CmpL src zero));
12023 11971
12024 11972 format %{ "testq $src, $src" %}
12025 11973 opcode(0x85);
12026 11974 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
12027 11975 ins_pipe(ialu_cr_reg_imm);
12028 11976 %}
12029 11977
12030 11978 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero)
12031 11979 %{
12032 11980 match(Set cr (CmpL (AndL src con) zero));
12033 11981
12034 11982 format %{ "testq $src, $con\t# long" %}
12035 11983 opcode(0xF7, 0x00);
12036 11984 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con));
12037 11985 ins_pipe(ialu_cr_reg_imm);
12038 11986 %}
12039 11987
12040 11988 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero)
12041 11989 %{
12042 11990 match(Set cr (CmpL (AndL src (LoadL mem)) zero));
12043 11991
12044 11992 format %{ "testq $src, $mem" %}
12045 11993 opcode(0x85);
12046 11994 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
12047 11995 ins_pipe(ialu_cr_reg_mem);
12048 11996 %}
12049 11997
12050 11998 // Manifest a CmpL result in an integer register. Very painful.
12051 11999 // This is the test to avoid.
12052 12000 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
12053 12001 %{
12054 12002 match(Set dst (CmpL3 src1 src2));
12055 12003 effect(KILL flags);
12056 12004
12057 12005 ins_cost(275); // XXX
12058 12006 format %{ "cmpq $src1, $src2\t# CmpL3\n\t"
12059 12007 "movl $dst, -1\n\t"
12060 12008 "jl,s done\n\t"
12061 12009 "setne $dst\n\t"
12062 12010 "movzbl $dst, $dst\n\t"
12063 12011 "done:" %}
12064 12012 ins_encode(cmpl3_flag(src1, src2, dst));
12065 12013 ins_pipe(pipe_slow);
12066 12014 %}
12067 12015
12068 12016 //----------Max and Min--------------------------------------------------------
12069 12017 // Min Instructions
12070 12018
12071 12019 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr)
12072 12020 %{
12073 12021 effect(USE_DEF dst, USE src, USE cr);
12074 12022
12075 12023 format %{ "cmovlgt $dst, $src\t# min" %}
12076 12024 opcode(0x0F, 0x4F);
12077 12025 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
12078 12026 ins_pipe(pipe_cmov_reg);
12079 12027 %}
12080 12028
12081 12029
12082 12030 instruct minI_rReg(rRegI dst, rRegI src)
12083 12031 %{
12084 12032 match(Set dst (MinI dst src));
12085 12033
12086 12034 ins_cost(200);
12087 12035 expand %{
12088 12036 rFlagsReg cr;
12089 12037 compI_rReg(cr, dst, src);
12090 12038 cmovI_reg_g(dst, src, cr);
12091 12039 %}
12092 12040 %}
12093 12041
12094 12042 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr)
12095 12043 %{
12096 12044 effect(USE_DEF dst, USE src, USE cr);
12097 12045
12098 12046 format %{ "cmovllt $dst, $src\t# max" %}
12099 12047 opcode(0x0F, 0x4C);
12100 12048 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
12101 12049 ins_pipe(pipe_cmov_reg);
12102 12050 %}
12103 12051
12104 12052
12105 12053 instruct maxI_rReg(rRegI dst, rRegI src)
12106 12054 %{
12107 12055 match(Set dst (MaxI dst src));
12108 12056
12109 12057 ins_cost(200);
12110 12058 expand %{
12111 12059 rFlagsReg cr;
12112 12060 compI_rReg(cr, dst, src);
12113 12061 cmovI_reg_l(dst, src, cr);
12114 12062 %}
12115 12063 %}
12116 12064
12117 12065 // ============================================================================
12118 12066 // Branch Instructions
12119 12067
12120 12068 // Jump Direct - Label defines a relative address from JMP+1
12121 12069 instruct jmpDir(label labl)
12122 12070 %{
12123 12071 match(Goto);
12124 12072 effect(USE labl);
12125 12073
12126 12074 ins_cost(300);
12127 12075 format %{ "jmp $labl" %}
12128 12076 size(5);
12129 12077 opcode(0xE9);
12130 12078 ins_encode(OpcP, Lbl(labl));
12131 12079 ins_pipe(pipe_jmp);
12132 12080 ins_pc_relative(1);
12133 12081 %}
12134 12082
12135 12083 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12136 12084 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl)
12137 12085 %{
12138 12086 match(If cop cr);
12139 12087 effect(USE labl);
12140 12088
12141 12089 ins_cost(300);
12142 12090 format %{ "j$cop $labl" %}
12143 12091 size(6);
12144 12092 opcode(0x0F, 0x80);
12145 12093 ins_encode(Jcc(cop, labl));
12146 12094 ins_pipe(pipe_jcc);
12147 12095 ins_pc_relative(1);
12148 12096 %}
12149 12097
12150 12098 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12151 12099 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
12152 12100 %{
12153 12101 match(CountedLoopEnd cop cr);
12154 12102 effect(USE labl);
12155 12103
12156 12104 ins_cost(300);
12157 12105 format %{ "j$cop $labl\t# loop end" %}
12158 12106 size(6);
12159 12107 opcode(0x0F, 0x80);
12160 12108 ins_encode(Jcc(cop, labl));
12161 12109 ins_pipe(pipe_jcc);
12162 12110 ins_pc_relative(1);
12163 12111 %}
12164 12112
12165 12113 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12166 12114 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12167 12115 match(CountedLoopEnd cop cmp);
12168 12116 effect(USE labl);
12169 12117
12170 12118 ins_cost(300);
12171 12119 format %{ "j$cop,u $labl\t# loop end" %}
12172 12120 size(6);
12173 12121 opcode(0x0F, 0x80);
12174 12122 ins_encode(Jcc(cop, labl));
12175 12123 ins_pipe(pipe_jcc);
12176 12124 ins_pc_relative(1);
12177 12125 %}
12178 12126
12179 12127 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12180 12128 match(CountedLoopEnd cop cmp);
12181 12129 effect(USE labl);
12182 12130
12183 12131 ins_cost(200);
12184 12132 format %{ "j$cop,u $labl\t# loop end" %}
12185 12133 size(6);
12186 12134 opcode(0x0F, 0x80);
12187 12135 ins_encode(Jcc(cop, labl));
12188 12136 ins_pipe(pipe_jcc);
12189 12137 ins_pc_relative(1);
12190 12138 %}
12191 12139
12192 12140 // Jump Direct Conditional - using unsigned comparison
12193 12141 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12194 12142 match(If cop cmp);
12195 12143 effect(USE labl);
12196 12144
12197 12145 ins_cost(300);
12198 12146 format %{ "j$cop,u $labl" %}
12199 12147 size(6);
12200 12148 opcode(0x0F, 0x80);
12201 12149 ins_encode(Jcc(cop, labl));
12202 12150 ins_pipe(pipe_jcc);
12203 12151 ins_pc_relative(1);
12204 12152 %}
12205 12153
12206 12154 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12207 12155 match(If cop cmp);
12208 12156 effect(USE labl);
12209 12157
12210 12158 ins_cost(200);
12211 12159 format %{ "j$cop,u $labl" %}
12212 12160 size(6);
12213 12161 opcode(0x0F, 0x80);
12214 12162 ins_encode(Jcc(cop, labl));
12215 12163 ins_pipe(pipe_jcc);
12216 12164 ins_pc_relative(1);
12217 12165 %}
12218 12166
12219 12167 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
12220 12168 match(If cop cmp);
12221 12169 effect(USE labl);
12222 12170
12223 12171 ins_cost(200);
12224 12172 format %{ $$template
12225 12173 if ($cop$$cmpcode == Assembler::notEqual) {
12226 12174 $$emit$$"jp,u $labl\n\t"
12227 12175 $$emit$$"j$cop,u $labl"
12228 12176 } else {
12229 12177 $$emit$$"jp,u done\n\t"
12230 12178 $$emit$$"j$cop,u $labl\n\t"
12231 12179 $$emit$$"done:"
12232 12180 }
12233 12181 %}
12234 12182 size(12);
12235 12183 opcode(0x0F, 0x80);
12236 12184 ins_encode %{
12237 12185 Label* l = $labl$$label;
12238 12186 $$$emit8$primary;
12239 12187 emit_cc(cbuf, $secondary, Assembler::parity);
12240 12188 int parity_disp = -1;
12241 12189 if ($cop$$cmpcode == Assembler::notEqual) {
12242 12190 // the two jumps 6 bytes apart so the jump distances are too
12243 12191 parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
12244 12192 } else if ($cop$$cmpcode == Assembler::equal) {
12245 12193 parity_disp = 6;
12246 12194 } else {
12247 12195 ShouldNotReachHere();
12248 12196 }
12249 12197 emit_d32(cbuf, parity_disp);
12250 12198 $$$emit8$primary;
12251 12199 emit_cc(cbuf, $secondary, $cop$$cmpcode);
12252 12200 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
12253 12201 emit_d32(cbuf, disp);
12254 12202 %}
12255 12203 ins_pipe(pipe_jcc);
12256 12204 ins_pc_relative(1);
12257 12205 %}
12258 12206
12259 12207 // ============================================================================
12260 12208 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
12261 12209 // superklass array for an instance of the superklass. Set a hidden
12262 12210 // internal cache on a hit (cache is checked with exposed code in
12263 12211 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The
12264 12212 // encoding ALSO sets flags.
12265 12213
12266 12214 instruct partialSubtypeCheck(rdi_RegP result,
12267 12215 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
12268 12216 rFlagsReg cr)
12269 12217 %{
12270 12218 match(Set result (PartialSubtypeCheck sub super));
12271 12219 effect(KILL rcx, KILL cr);
12272 12220
12273 12221 ins_cost(1100); // slightly larger than the next version
12274 12222 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t"
12275 12223 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t"
12276 12224 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t"
12277 12225 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t"
12278 12226 "jne,s miss\t\t# Missed: rdi not-zero\n\t"
12279 12227 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t"
12280 12228 "xorq $result, $result\t\t Hit: rdi zero\n\t"
12281 12229 "miss:\t" %}
12282 12230
12283 12231 opcode(0x1); // Force a XOR of RDI
12284 12232 ins_encode(enc_PartialSubtypeCheck());
12285 12233 ins_pipe(pipe_slow);
12286 12234 %}
12287 12235
12288 12236 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr,
12289 12237 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
12290 12238 immP0 zero,
12291 12239 rdi_RegP result)
12292 12240 %{
12293 12241 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
12294 12242 effect(KILL rcx, KILL result);
12295 12243
12296 12244 ins_cost(1000);
12297 12245 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t"
12298 12246 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t"
12299 12247 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t"
12300 12248 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t"
12301 12249 "jne,s miss\t\t# Missed: flags nz\n\t"
12302 12250 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t"
12303 12251 "miss:\t" %}
12304 12252
12305 12253 opcode(0x0); // No need to XOR RDI
12306 12254 ins_encode(enc_PartialSubtypeCheck());
12307 12255 ins_pipe(pipe_slow);
12308 12256 %}
12309 12257
12310 12258 // ============================================================================
12311 12259 // Branch Instructions -- short offset versions
12312 12260 //
12313 12261 // These instructions are used to replace jumps of a long offset (the default
12314 12262 // match) with jumps of a shorter offset. These instructions are all tagged
12315 12263 // with the ins_short_branch attribute, which causes the ADLC to suppress the
12316 12264 // match rules in general matching. Instead, the ADLC generates a conversion
12317 12265 // method in the MachNode which can be used to do in-place replacement of the
12318 12266 // long variant with the shorter variant. The compiler will determine if a
12319 12267 // branch can be taken by the is_short_branch_offset() predicate in the machine
12320 12268 // specific code section of the file.
12321 12269
12322 12270 // Jump Direct - Label defines a relative address from JMP+1
12323 12271 instruct jmpDir_short(label labl) %{
12324 12272 match(Goto);
12325 12273 effect(USE labl);
12326 12274
12327 12275 ins_cost(300);
12328 12276 format %{ "jmp,s $labl" %}
12329 12277 size(2);
12330 12278 opcode(0xEB);
12331 12279 ins_encode(OpcP, LblShort(labl));
12332 12280 ins_pipe(pipe_jmp);
12333 12281 ins_pc_relative(1);
12334 12282 ins_short_branch(1);
12335 12283 %}
12336 12284
12337 12285 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12338 12286 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
12339 12287 match(If cop cr);
12340 12288 effect(USE labl);
12341 12289
12342 12290 ins_cost(300);
12343 12291 format %{ "j$cop,s $labl" %}
12344 12292 size(2);
12345 12293 opcode(0x70);
12346 12294 ins_encode(JccShort(cop, labl));
12347 12295 ins_pipe(pipe_jcc);
12348 12296 ins_pc_relative(1);
12349 12297 ins_short_branch(1);
12350 12298 %}
12351 12299
12352 12300 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12353 12301 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
12354 12302 match(CountedLoopEnd cop cr);
12355 12303 effect(USE labl);
12356 12304
12357 12305 ins_cost(300);
12358 12306 format %{ "j$cop,s $labl\t# loop end" %}
12359 12307 size(2);
12360 12308 opcode(0x70);
12361 12309 ins_encode(JccShort(cop, labl));
12362 12310 ins_pipe(pipe_jcc);
12363 12311 ins_pc_relative(1);
12364 12312 ins_short_branch(1);
12365 12313 %}
12366 12314
12367 12315 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12368 12316 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12369 12317 match(CountedLoopEnd cop cmp);
12370 12318 effect(USE labl);
12371 12319
12372 12320 ins_cost(300);
12373 12321 format %{ "j$cop,us $labl\t# loop end" %}
12374 12322 size(2);
12375 12323 opcode(0x70);
12376 12324 ins_encode(JccShort(cop, labl));
12377 12325 ins_pipe(pipe_jcc);
12378 12326 ins_pc_relative(1);
12379 12327 ins_short_branch(1);
12380 12328 %}
12381 12329
12382 12330 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12383 12331 match(CountedLoopEnd cop cmp);
12384 12332 effect(USE labl);
12385 12333
12386 12334 ins_cost(300);
12387 12335 format %{ "j$cop,us $labl\t# loop end" %}
12388 12336 size(2);
12389 12337 opcode(0x70);
12390 12338 ins_encode(JccShort(cop, labl));
12391 12339 ins_pipe(pipe_jcc);
12392 12340 ins_pc_relative(1);
12393 12341 ins_short_branch(1);
12394 12342 %}
12395 12343
12396 12344 // Jump Direct Conditional - using unsigned comparison
12397 12345 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12398 12346 match(If cop cmp);
12399 12347 effect(USE labl);
12400 12348
12401 12349 ins_cost(300);
12402 12350 format %{ "j$cop,us $labl" %}
12403 12351 size(2);
12404 12352 opcode(0x70);
12405 12353 ins_encode(JccShort(cop, labl));
12406 12354 ins_pipe(pipe_jcc);
12407 12355 ins_pc_relative(1);
12408 12356 ins_short_branch(1);
12409 12357 %}
12410 12358
12411 12359 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12412 12360 match(If cop cmp);
12413 12361 effect(USE labl);
12414 12362
12415 12363 ins_cost(300);
12416 12364 format %{ "j$cop,us $labl" %}
12417 12365 size(2);
12418 12366 opcode(0x70);
12419 12367 ins_encode(JccShort(cop, labl));
12420 12368 ins_pipe(pipe_jcc);
12421 12369 ins_pc_relative(1);
12422 12370 ins_short_branch(1);
12423 12371 %}
12424 12372
12425 12373 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
12426 12374 match(If cop cmp);
12427 12375 effect(USE labl);
12428 12376
12429 12377 ins_cost(300);
12430 12378 format %{ $$template
12431 12379 if ($cop$$cmpcode == Assembler::notEqual) {
12432 12380 $$emit$$"jp,u,s $labl\n\t"
12433 12381 $$emit$$"j$cop,u,s $labl"
12434 12382 } else {
12435 12383 $$emit$$"jp,u,s done\n\t"
12436 12384 $$emit$$"j$cop,u,s $labl\n\t"
12437 12385 $$emit$$"done:"
12438 12386 }
12439 12387 %}
12440 12388 size(4);
12441 12389 opcode(0x70);
12442 12390 ins_encode %{
12443 12391 Label* l = $labl$$label;
12444 12392 emit_cc(cbuf, $primary, Assembler::parity);
12445 12393 int parity_disp = -1;
12446 12394 if ($cop$$cmpcode == Assembler::notEqual) {
12447 12395 parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
12448 12396 } else if ($cop$$cmpcode == Assembler::equal) {
12449 12397 parity_disp = 2;
12450 12398 } else {
12451 12399 ShouldNotReachHere();
12452 12400 }
12453 12401 emit_d8(cbuf, parity_disp);
12454 12402 emit_cc(cbuf, $primary, $cop$$cmpcode);
12455 12403 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
12456 12404 emit_d8(cbuf, disp);
12457 12405 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
12458 12406 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
12459 12407 %}
12460 12408 ins_pipe(pipe_jcc);
12461 12409 ins_pc_relative(1);
12462 12410 ins_short_branch(1);
12463 12411 %}
12464 12412
12465 12413 // ============================================================================
12466 12414 // inlined locking and unlocking
12467 12415
12468 12416 instruct cmpFastLock(rFlagsReg cr,
12469 12417 rRegP object, rRegP box, rax_RegI tmp, rRegP scr)
12470 12418 %{
12471 12419 match(Set cr (FastLock object box));
12472 12420 effect(TEMP tmp, TEMP scr);
12473 12421
12474 12422 ins_cost(300);
12475 12423 format %{ "fastlock $object,$box,$tmp,$scr" %}
12476 12424 ins_encode(Fast_Lock(object, box, tmp, scr));
12477 12425 ins_pipe(pipe_slow);
12478 12426 ins_pc_relative(1);
12479 12427 %}
12480 12428
12481 12429 instruct cmpFastUnlock(rFlagsReg cr,
12482 12430 rRegP object, rax_RegP box, rRegP tmp)
12483 12431 %{
12484 12432 match(Set cr (FastUnlock object box));
12485 12433 effect(TEMP tmp);
12486 12434
12487 12435 ins_cost(300);
12488 12436 format %{ "fastunlock $object, $box, $tmp" %}
12489 12437 ins_encode(Fast_Unlock(object, box, tmp));
12490 12438 ins_pipe(pipe_slow);
12491 12439 ins_pc_relative(1);
12492 12440 %}
12493 12441
12494 12442
12495 12443 // ============================================================================
12496 12444 // Safepoint Instructions
12497 12445 instruct safePoint_poll(rFlagsReg cr)
12498 12446 %{
12499 12447 match(SafePoint);
12500 12448 effect(KILL cr);
12501 12449
12502 12450 format %{ "testl rax, [rip + #offset_to_poll_page]\t"
12503 12451 "# Safepoint: poll for GC" %}
12504 12452 size(6); // Opcode + ModRM + Disp32 == 6 bytes
12505 12453 ins_cost(125);
12506 12454 ins_encode(enc_safepoint_poll);
12507 12455 ins_pipe(ialu_reg_mem);
12508 12456 %}
12509 12457
12510 12458 // ============================================================================
12511 12459 // Procedure Call/Return Instructions
12512 12460 // Call Java Static Instruction
12513 12461 // Note: If this code changes, the corresponding ret_addr_offset() and
12514 12462 // compute_padding() functions will have to be adjusted.
12515 12463 instruct CallStaticJavaDirect(method meth) %{
12516 12464 match(CallStaticJava);
12517 12465 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke());
12518 12466 effect(USE meth);
12519 12467
12520 12468 ins_cost(300);
12521 12469 format %{ "call,static " %}
12522 12470 opcode(0xE8); /* E8 cd */
12523 12471 ins_encode(Java_Static_Call(meth), call_epilog);
12524 12472 ins_pipe(pipe_slow);
12525 12473 ins_pc_relative(1);
12526 12474 ins_alignment(4);
12527 12475 %}
12528 12476
12529 12477 // Call Java Static Instruction (method handle version)
12530 12478 // Note: If this code changes, the corresponding ret_addr_offset() and
12531 12479 // compute_padding() functions will have to be adjusted.
12532 12480 instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{
12533 12481 match(CallStaticJava);
12534 12482 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke());
12535 12483 effect(USE meth);
12536 12484 // RBP is saved by all callees (for interpreter stack correction).
12537 12485 // We use it here for a similar purpose, in {preserve,restore}_SP.
12538 12486
12539 12487 ins_cost(300);
12540 12488 format %{ "call,static/MethodHandle " %}
12541 12489 opcode(0xE8); /* E8 cd */
12542 12490 ins_encode(preserve_SP,
12543 12491 Java_Static_Call(meth),
12544 12492 restore_SP,
12545 12493 call_epilog);
12546 12494 ins_pipe(pipe_slow);
12547 12495 ins_pc_relative(1);
12548 12496 ins_alignment(4);
12549 12497 %}
12550 12498
12551 12499 // Call Java Dynamic Instruction
12552 12500 // Note: If this code changes, the corresponding ret_addr_offset() and
12553 12501 // compute_padding() functions will have to be adjusted.
12554 12502 instruct CallDynamicJavaDirect(method meth)
12555 12503 %{
12556 12504 match(CallDynamicJava);
12557 12505 effect(USE meth);
12558 12506
12559 12507 ins_cost(300);
12560 12508 format %{ "movq rax, #Universe::non_oop_word()\n\t"
12561 12509 "call,dynamic " %}
12562 12510 opcode(0xE8); /* E8 cd */
12563 12511 ins_encode(Java_Dynamic_Call(meth), call_epilog);
12564 12512 ins_pipe(pipe_slow);
12565 12513 ins_pc_relative(1);
12566 12514 ins_alignment(4);
12567 12515 %}
12568 12516
12569 12517 // Call Runtime Instruction
12570 12518 instruct CallRuntimeDirect(method meth)
12571 12519 %{
12572 12520 match(CallRuntime);
12573 12521 effect(USE meth);
12574 12522
12575 12523 ins_cost(300);
12576 12524 format %{ "call,runtime " %}
12577 12525 opcode(0xE8); /* E8 cd */
12578 12526 ins_encode(Java_To_Runtime(meth));
12579 12527 ins_pipe(pipe_slow);
12580 12528 ins_pc_relative(1);
12581 12529 %}
12582 12530
12583 12531 // Call runtime without safepoint
12584 12532 instruct CallLeafDirect(method meth)
12585 12533 %{
12586 12534 match(CallLeaf);
12587 12535 effect(USE meth);
12588 12536
12589 12537 ins_cost(300);
12590 12538 format %{ "call_leaf,runtime " %}
12591 12539 opcode(0xE8); /* E8 cd */
12592 12540 ins_encode(Java_To_Runtime(meth));
12593 12541 ins_pipe(pipe_slow);
12594 12542 ins_pc_relative(1);
12595 12543 %}
12596 12544
12597 12545 // Call runtime without safepoint
12598 12546 instruct CallLeafNoFPDirect(method meth)
12599 12547 %{
12600 12548 match(CallLeafNoFP);
12601 12549 effect(USE meth);
12602 12550
12603 12551 ins_cost(300);
12604 12552 format %{ "call_leaf_nofp,runtime " %}
12605 12553 opcode(0xE8); /* E8 cd */
12606 12554 ins_encode(Java_To_Runtime(meth));
12607 12555 ins_pipe(pipe_slow);
12608 12556 ins_pc_relative(1);
12609 12557 %}
12610 12558
12611 12559 // Return Instruction
12612 12560 // Remove the return address & jump to it.
12613 12561 // Notice: We always emit a nop after a ret to make sure there is room
12614 12562 // for safepoint patching
12615 12563 instruct Ret()
12616 12564 %{
12617 12565 match(Return);
12618 12566
12619 12567 format %{ "ret" %}
12620 12568 opcode(0xC3);
12621 12569 ins_encode(OpcP);
12622 12570 ins_pipe(pipe_jmp);
12623 12571 %}
12624 12572
12625 12573 // Tail Call; Jump from runtime stub to Java code.
12626 12574 // Also known as an 'interprocedural jump'.
12627 12575 // Target of jump will eventually return to caller.
12628 12576 // TailJump below removes the return address.
12629 12577 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop)
12630 12578 %{
12631 12579 match(TailCall jump_target method_oop);
12632 12580
12633 12581 ins_cost(300);
12634 12582 format %{ "jmp $jump_target\t# rbx holds method oop" %}
12635 12583 opcode(0xFF, 0x4); /* Opcode FF /4 */
12636 12584 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target));
12637 12585 ins_pipe(pipe_jmp);
12638 12586 %}
12639 12587
12640 12588 // Tail Jump; remove the return address; jump to target.
12641 12589 // TailCall above leaves the return address around.
12642 12590 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop)
12643 12591 %{
12644 12592 match(TailJump jump_target ex_oop);
12645 12593
12646 12594 ins_cost(300);
12647 12595 format %{ "popq rdx\t# pop return address\n\t"
12648 12596 "jmp $jump_target" %}
12649 12597 opcode(0xFF, 0x4); /* Opcode FF /4 */
12650 12598 ins_encode(Opcode(0x5a), // popq rdx
12651 12599 REX_reg(jump_target), OpcP, reg_opc(jump_target));
12652 12600 ins_pipe(pipe_jmp);
12653 12601 %}
12654 12602
12655 12603 // Create exception oop: created by stack-crawling runtime code.
12656 12604 // Created exception is now available to this handler, and is setup
12657 12605 // just prior to jumping to this handler. No code emitted.
12658 12606 instruct CreateException(rax_RegP ex_oop)
12659 12607 %{
12660 12608 match(Set ex_oop (CreateEx));
12661 12609
12662 12610 size(0);
12663 12611 // use the following format syntax
12664 12612 format %{ "# exception oop is in rax; no code emitted" %}
12665 12613 ins_encode();
12666 12614 ins_pipe(empty);
12667 12615 %}
12668 12616
12669 12617 // Rethrow exception:
12670 12618 // The exception oop will come in the first argument position.
12671 12619 // Then JUMP (not call) to the rethrow stub code.
12672 12620 instruct RethrowException()
12673 12621 %{
12674 12622 match(Rethrow);
12675 12623
12676 12624 // use the following format syntax
12677 12625 format %{ "jmp rethrow_stub" %}
12678 12626 ins_encode(enc_rethrow);
12679 12627 ins_pipe(pipe_jmp);
12680 12628 %}
12681 12629
12682 12630
12683 12631 //----------PEEPHOLE RULES-----------------------------------------------------
12684 12632 // These must follow all instruction definitions as they use the names
12685 12633 // defined in the instructions definitions.
12686 12634 //
12687 12635 // peepmatch ( root_instr_name [preceding_instruction]* );
12688 12636 //
12689 12637 // peepconstraint %{
12690 12638 // (instruction_number.operand_name relational_op instruction_number.operand_name
12691 12639 // [, ...] );
12692 12640 // // instruction numbers are zero-based using left to right order in peepmatch
12693 12641 //
12694 12642 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
12695 12643 // // provide an instruction_number.operand_name for each operand that appears
12696 12644 // // in the replacement instruction's match rule
12697 12645 //
12698 12646 // ---------VM FLAGS---------------------------------------------------------
12699 12647 //
12700 12648 // All peephole optimizations can be turned off using -XX:-OptoPeephole
12701 12649 //
12702 12650 // Each peephole rule is given an identifying number starting with zero and
12703 12651 // increasing by one in the order seen by the parser. An individual peephole
12704 12652 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
12705 12653 // on the command-line.
12706 12654 //
12707 12655 // ---------CURRENT LIMITATIONS----------------------------------------------
12708 12656 //
12709 12657 // Only match adjacent instructions in same basic block
12710 12658 // Only equality constraints
12711 12659 // Only constraints between operands, not (0.dest_reg == RAX_enc)
12712 12660 // Only one replacement instruction
12713 12661 //
12714 12662 // ---------EXAMPLE----------------------------------------------------------
12715 12663 //
12716 12664 // // pertinent parts of existing instructions in architecture description
12717 12665 // instruct movI(rRegI dst, rRegI src)
12718 12666 // %{
12719 12667 // match(Set dst (CopyI src));
12720 12668 // %}
12721 12669 //
12722 12670 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
12723 12671 // %{
12724 12672 // match(Set dst (AddI dst src));
12725 12673 // effect(KILL cr);
12726 12674 // %}
12727 12675 //
12728 12676 // // Change (inc mov) to lea
12729 12677 // peephole %{
12730 12678 // // increment preceeded by register-register move
12731 12679 // peepmatch ( incI_rReg movI );
12732 12680 // // require that the destination register of the increment
12733 12681 // // match the destination register of the move
12734 12682 // peepconstraint ( 0.dst == 1.dst );
12735 12683 // // construct a replacement instruction that sets
12736 12684 // // the destination to ( move's source register + one )
12737 12685 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) );
12738 12686 // %}
12739 12687 //
12740 12688
12741 12689 // Implementation no longer uses movX instructions since
12742 12690 // machine-independent system no longer uses CopyX nodes.
12743 12691 //
12744 12692 // peephole
12745 12693 // %{
12746 12694 // peepmatch (incI_rReg movI);
12747 12695 // peepconstraint (0.dst == 1.dst);
12748 12696 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
12749 12697 // %}
12750 12698
12751 12699 // peephole
12752 12700 // %{
12753 12701 // peepmatch (decI_rReg movI);
12754 12702 // peepconstraint (0.dst == 1.dst);
12755 12703 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
12756 12704 // %}
12757 12705
12758 12706 // peephole
12759 12707 // %{
12760 12708 // peepmatch (addI_rReg_imm movI);
12761 12709 // peepconstraint (0.dst == 1.dst);
12762 12710 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
12763 12711 // %}
12764 12712
12765 12713 // peephole
12766 12714 // %{
12767 12715 // peepmatch (incL_rReg movL);
12768 12716 // peepconstraint (0.dst == 1.dst);
12769 12717 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
12770 12718 // %}
12771 12719
12772 12720 // peephole
12773 12721 // %{
12774 12722 // peepmatch (decL_rReg movL);
12775 12723 // peepconstraint (0.dst == 1.dst);
12776 12724 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
12777 12725 // %}
12778 12726
12779 12727 // peephole
12780 12728 // %{
12781 12729 // peepmatch (addL_rReg_imm movL);
12782 12730 // peepconstraint (0.dst == 1.dst);
12783 12731 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
12784 12732 // %}
12785 12733
12786 12734 // peephole
12787 12735 // %{
12788 12736 // peepmatch (addP_rReg_imm movP);
12789 12737 // peepconstraint (0.dst == 1.dst);
12790 12738 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src));
12791 12739 // %}
12792 12740
12793 12741 // // Change load of spilled value to only a spill
12794 12742 // instruct storeI(memory mem, rRegI src)
12795 12743 // %{
12796 12744 // match(Set mem (StoreI mem src));
12797 12745 // %}
12798 12746 //
12799 12747 // instruct loadI(rRegI dst, memory mem)
12800 12748 // %{
12801 12749 // match(Set dst (LoadI mem));
12802 12750 // %}
12803 12751 //
12804 12752
12805 12753 peephole
12806 12754 %{
12807 12755 peepmatch (loadI storeI);
12808 12756 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
12809 12757 peepreplace (storeI(1.mem 1.mem 1.src));
12810 12758 %}
12811 12759
12812 12760 peephole
12813 12761 %{
12814 12762 peepmatch (loadL storeL);
12815 12763 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
12816 12764 peepreplace (storeL(1.mem 1.mem 1.src));
12817 12765 %}
12818 12766
12819 12767 //----------SMARTSPILL RULES---------------------------------------------------
12820 12768 // These must follow all instruction definitions as they use the names
12821 12769 // defined in the instructions definitions.
↓ open down ↓ |
1871 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX