Thu, 15 Oct 2015 17:38:41 +0200
8080650: Enable stubs to use frame pointers correctly
Summary: Change MacroAssembler::verified_entry() to set up RBP correctly when generating stub code.
Reviewed-by: kvn
1 //
2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 //
5 // This code is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License version 2 only, as
7 // published by the Free Software Foundation.
8 //
9 // This code is distributed in the hope that it will be useful, but WITHOUT
10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 // version 2 for more details (a copy is included in the LICENSE file that
13 // accompanied this code).
14 //
15 // You should have received a copy of the GNU General Public License version
16 // 2 along with this work; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 //
19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 // or visit www.oracle.com if you need additional information or have any
21 // questions.
22 //
23 //
25 // AMD64 Architecture Description File
27 //----------REGISTER DEFINITION BLOCK------------------------------------------
28 // This information is used by the matcher and the register allocator to
29 // describe individual registers and classes of registers within the target
30 // archtecture.
32 register %{
33 //----------Architecture Description Register Definitions----------------------
34 // General Registers
35 // "reg_def" name ( register save type, C convention save type,
36 // ideal register type, encoding );
37 // Register Save Types:
38 //
39 // NS = No-Save: The register allocator assumes that these registers
40 // can be used without saving upon entry to the method, &
41 // that they do not need to be saved at call sites.
42 //
43 // SOC = Save-On-Call: The register allocator assumes that these registers
44 // can be used without saving upon entry to the method,
45 // but that they must be saved at call sites.
46 //
47 // SOE = Save-On-Entry: The register allocator assumes that these registers
48 // must be saved before using them upon entry to the
49 // method, but they do not need to be saved at call
50 // sites.
51 //
52 // AS = Always-Save: The register allocator assumes that these registers
53 // must be saved before using them upon entry to the
54 // method, & that they must be saved at call sites.
55 //
56 // Ideal Register Type is used to determine how to save & restore a
57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
59 //
60 // The encoding number is the actual bit-pattern placed into the opcodes.
62 // General Registers
63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when
64 // used as byte registers)
66 // Previously set RBX, RSI, and RDI as save-on-entry for java code
67 // Turn off SOE in java-code due to frequent use of uncommon-traps.
68 // Now that allocator is better, turn on RSI and RDI as SOE registers.
70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg());
71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next());
73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg());
74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next());
76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg());
77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next());
79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg());
80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next());
82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg());
83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next());
85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code
86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg());
87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next());
89 #ifdef _WIN64
91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg());
92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next());
94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg());
95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next());
97 #else
99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg());
100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next());
102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg());
103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next());
105 #endif
107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg());
108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next());
110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg());
111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next());
113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg());
114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg());
117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg());
120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next());
122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg());
123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next());
125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg());
126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next());
128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg());
129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next());
132 // Floating Point Registers
134 // Specify priority of register selection within phases of register
135 // allocation. Highest priority is first. A useful heuristic is to
136 // give registers a low priority when they are required by machine
137 // instructions, like EAX and EDX on I486, and choose no-save registers
138 // before save-on-call, & save-on-call before save-on-entry. Registers
139 // which participate in fixed calling sequences should come last.
140 // Registers which are used as pairs must fall on an even boundary.
142 alloc_class chunk0(R10, R10_H,
143 R11, R11_H,
144 R8, R8_H,
145 R9, R9_H,
146 R12, R12_H,
147 RCX, RCX_H,
148 RBX, RBX_H,
149 RDI, RDI_H,
150 RDX, RDX_H,
151 RSI, RSI_H,
152 RAX, RAX_H,
153 RBP, RBP_H,
154 R13, R13_H,
155 R14, R14_H,
156 R15, R15_H,
157 RSP, RSP_H);
160 //----------Architecture Description Register Classes--------------------------
161 // Several register classes are automatically defined based upon information in
162 // this architecture description.
163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ )
164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ )
165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
167 //
169 // Empty register class.
170 reg_class no_reg();
172 // Class for all pointer registers (including RSP and RBP)
173 reg_class any_reg_with_rbp(RAX, RAX_H,
174 RDX, RDX_H,
175 RBP, RBP_H,
176 RDI, RDI_H,
177 RSI, RSI_H,
178 RCX, RCX_H,
179 RBX, RBX_H,
180 RSP, RSP_H,
181 R8, R8_H,
182 R9, R9_H,
183 R10, R10_H,
184 R11, R11_H,
185 R12, R12_H,
186 R13, R13_H,
187 R14, R14_H,
188 R15, R15_H);
190 // Class for all pointer registers (including RSP, but excluding RBP)
191 reg_class any_reg_no_rbp(RAX, RAX_H,
192 RDX, RDX_H,
193 RDI, RDI_H,
194 RSI, RSI_H,
195 RCX, RCX_H,
196 RBX, RBX_H,
197 RSP, RSP_H,
198 R8, R8_H,
199 R9, R9_H,
200 R10, R10_H,
201 R11, R11_H,
202 R12, R12_H,
203 R13, R13_H,
204 R14, R14_H,
205 R15, R15_H);
207 // Dynamic register class that selects at runtime between register classes
208 // any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer).
209 // Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp;
210 reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %});
212 // Class for all pointer registers (excluding RSP)
213 reg_class ptr_reg_with_rbp(RAX, RAX_H,
214 RDX, RDX_H,
215 RBP, RBP_H,
216 RDI, RDI_H,
217 RSI, RSI_H,
218 RCX, RCX_H,
219 RBX, RBX_H,
220 R8, R8_H,
221 R9, R9_H,
222 R10, R10_H,
223 R11, R11_H,
224 R13, R13_H,
225 R14, R14_H);
227 // Class for all pointer registers (excluding RSP and RBP)
228 reg_class ptr_reg_no_rbp(RAX, RAX_H,
229 RDX, RDX_H,
230 RDI, RDI_H,
231 RSI, RSI_H,
232 RCX, RCX_H,
233 RBX, RBX_H,
234 R8, R8_H,
235 R9, R9_H,
236 R10, R10_H,
237 R11, R11_H,
238 R13, R13_H,
239 R14, R14_H);
241 // Dynamic register class that selects between ptr_reg_no_rbp and ptr_reg_with_rbp.
242 reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %});
244 // Class for all pointer registers (excluding RAX and RSP)
245 reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H,
246 RBP, RBP_H,
247 RDI, RDI_H,
248 RSI, RSI_H,
249 RCX, RCX_H,
250 RBX, RBX_H,
251 R8, R8_H,
252 R9, R9_H,
253 R10, R10_H,
254 R11, R11_H,
255 R13, R13_H,
256 R14, R14_H);
258 // Class for all pointer registers (excluding RAX, RSP, and RBP)
259 reg_class ptr_no_rax_reg_no_rbp(RDX, RDX_H,
260 RDI, RDI_H,
261 RSI, RSI_H,
262 RCX, RCX_H,
263 RBX, RBX_H,
264 R8, R8_H,
265 R9, R9_H,
266 R10, R10_H,
267 R11, R11_H,
268 R13, R13_H,
269 R14, R14_H);
271 // Dynamic register class that selects between ptr_no_rax_reg_no_rbp and ptr_no_rax_reg_with_rbp.
272 reg_class_dynamic ptr_no_rax_reg(ptr_no_rax_reg_no_rbp, ptr_no_rax_reg_with_rbp, %{ PreserveFramePointer %});
274 // Class for all pointer registers (excluding RAX, RBX, and RSP)
275 reg_class ptr_no_rax_rbx_reg_with_rbp(RDX, RDX_H,
276 RBP, RBP_H,
277 RDI, RDI_H,
278 RSI, RSI_H,
279 RCX, RCX_H,
280 R8, R8_H,
281 R9, R9_H,
282 R10, R10_H,
283 R11, R11_H,
284 R13, R13_H,
285 R14, R14_H);
287 // Class for all pointer registers (excluding RAX, RBX, RSP, and RBP)
288 reg_class ptr_no_rax_rbx_reg_no_rbp(RDX, RDX_H,
289 RDI, RDI_H,
290 RSI, RSI_H,
291 RCX, RCX_H,
292 R8, R8_H,
293 R9, R9_H,
294 R10, R10_H,
295 R11, R11_H,
296 R13, R13_H,
297 R14, R14_H);
299 // Dynamic register class that selects between ptr_no_rax_rbx_reg_no_rbp and ptr_no_rax_rbx_reg_with_rbp.
300 reg_class_dynamic ptr_no_rax_rbx_reg(ptr_no_rax_rbx_reg_no_rbp, ptr_no_rax_rbx_reg_with_rbp, %{ PreserveFramePointer %});
302 // Singleton class for RAX pointer register
303 reg_class ptr_rax_reg(RAX, RAX_H);
305 // Singleton class for RBX pointer register
306 reg_class ptr_rbx_reg(RBX, RBX_H);
308 // Singleton class for RSI pointer register
309 reg_class ptr_rsi_reg(RSI, RSI_H);
311 // Singleton class for RDI pointer register
312 reg_class ptr_rdi_reg(RDI, RDI_H);
314 // Singleton class for stack pointer
315 reg_class ptr_rsp_reg(RSP, RSP_H);
317 // Singleton class for TLS pointer
318 reg_class ptr_r15_reg(R15, R15_H);
320 // Class for all long registers (excluding RSP)
321 reg_class long_reg_with_rbp(RAX, RAX_H,
322 RDX, RDX_H,
323 RBP, RBP_H,
324 RDI, RDI_H,
325 RSI, RSI_H,
326 RCX, RCX_H,
327 RBX, RBX_H,
328 R8, R8_H,
329 R9, R9_H,
330 R10, R10_H,
331 R11, R11_H,
332 R13, R13_H,
333 R14, R14_H);
335 // Class for all long registers (excluding RSP and RBP)
336 reg_class long_reg_no_rbp(RAX, RAX_H,
337 RDX, RDX_H,
338 RDI, RDI_H,
339 RSI, RSI_H,
340 RCX, RCX_H,
341 RBX, RBX_H,
342 R8, R8_H,
343 R9, R9_H,
344 R10, R10_H,
345 R11, R11_H,
346 R13, R13_H,
347 R14, R14_H);
349 // Dynamic register class that selects between long_reg_no_rbp and long_reg_with_rbp.
350 reg_class_dynamic long_reg(long_reg_no_rbp, long_reg_with_rbp, %{ PreserveFramePointer %});
352 // Class for all long registers (excluding RAX, RDX and RSP)
353 reg_class long_no_rax_rdx_reg_with_rbp(RBP, RBP_H,
354 RDI, RDI_H,
355 RSI, RSI_H,
356 RCX, RCX_H,
357 RBX, RBX_H,
358 R8, R8_H,
359 R9, R9_H,
360 R10, R10_H,
361 R11, R11_H,
362 R13, R13_H,
363 R14, R14_H);
365 // Class for all long registers (excluding RAX, RDX, RSP, and RBP)
366 reg_class long_no_rax_rdx_reg_no_rbp(RDI, RDI_H,
367 RSI, RSI_H,
368 RCX, RCX_H,
369 RBX, RBX_H,
370 R8, R8_H,
371 R9, R9_H,
372 R10, R10_H,
373 R11, R11_H,
374 R13, R13_H,
375 R14, R14_H);
377 // Dynamic register class that selects between long_no_rax_rdx_reg_no_rbp and long_no_rax_rdx_reg_with_rbp.
378 reg_class_dynamic long_no_rax_rdx_reg(long_no_rax_rdx_reg_no_rbp, long_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %});
380 // Class for all long registers (excluding RCX and RSP)
381 reg_class long_no_rcx_reg_with_rbp(RBP, RBP_H,
382 RDI, RDI_H,
383 RSI, RSI_H,
384 RAX, RAX_H,
385 RDX, RDX_H,
386 RBX, RBX_H,
387 R8, R8_H,
388 R9, R9_H,
389 R10, R10_H,
390 R11, R11_H,
391 R13, R13_H,
392 R14, R14_H);
394 // Class for all long registers (excluding RCX, RSP, and RBP)
395 reg_class long_no_rcx_reg_no_rbp(RDI, RDI_H,
396 RSI, RSI_H,
397 RAX, RAX_H,
398 RDX, RDX_H,
399 RBX, RBX_H,
400 R8, R8_H,
401 R9, R9_H,
402 R10, R10_H,
403 R11, R11_H,
404 R13, R13_H,
405 R14, R14_H);
407 // Dynamic register class that selects between long_no_rcx_reg_no_rbp and long_no_rcx_reg_with_rbp.
408 reg_class_dynamic long_no_rcx_reg(long_no_rcx_reg_no_rbp, long_no_rcx_reg_with_rbp, %{ PreserveFramePointer %});
410 // Singleton class for RAX long register
411 reg_class long_rax_reg(RAX, RAX_H);
413 // Singleton class for RCX long register
414 reg_class long_rcx_reg(RCX, RCX_H);
416 // Singleton class for RDX long register
417 reg_class long_rdx_reg(RDX, RDX_H);
419 // Class for all int registers (excluding RSP)
420 reg_class int_reg_with_rbp(RAX,
421 RDX,
422 RBP,
423 RDI,
424 RSI,
425 RCX,
426 RBX,
427 R8,
428 R9,
429 R10,
430 R11,
431 R13,
432 R14);
434 // Class for all int registers (excluding RSP and RBP)
435 reg_class int_reg_no_rbp(RAX,
436 RDX,
437 RDI,
438 RSI,
439 RCX,
440 RBX,
441 R8,
442 R9,
443 R10,
444 R11,
445 R13,
446 R14);
448 // Dynamic register class that selects between int_reg_no_rbp and int_reg_with_rbp.
449 reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %});
451 // Class for all int registers (excluding RCX and RSP)
452 reg_class int_no_rcx_reg_with_rbp(RAX,
453 RDX,
454 RBP,
455 RDI,
456 RSI,
457 RBX,
458 R8,
459 R9,
460 R10,
461 R11,
462 R13,
463 R14);
465 // Class for all int registers (excluding RCX, RSP, and RBP)
466 reg_class int_no_rcx_reg_no_rbp(RAX,
467 RDX,
468 RDI,
469 RSI,
470 RBX,
471 R8,
472 R9,
473 R10,
474 R11,
475 R13,
476 R14);
478 // Dynamic register class that selects between int_no_rcx_reg_no_rbp and int_no_rcx_reg_with_rbp.
479 reg_class_dynamic int_no_rcx_reg(int_no_rcx_reg_no_rbp, int_no_rcx_reg_with_rbp, %{ PreserveFramePointer %});
481 // Class for all int registers (excluding RAX, RDX, and RSP)
482 reg_class int_no_rax_rdx_reg_with_rbp(RBP,
483 RDI,
484 RSI,
485 RCX,
486 RBX,
487 R8,
488 R9,
489 R10,
490 R11,
491 R13,
492 R14);
494 // Class for all int registers (excluding RAX, RDX, RSP, and RBP)
495 reg_class int_no_rax_rdx_reg_no_rbp(RDI,
496 RSI,
497 RCX,
498 RBX,
499 R8,
500 R9,
501 R10,
502 R11,
503 R13,
504 R14);
506 // Dynamic register class that selects between int_no_rax_rdx_reg_no_rbp and int_no_rax_rdx_reg_with_rbp.
507 reg_class_dynamic int_no_rax_rdx_reg(int_no_rax_rdx_reg_no_rbp, int_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %});
509 // Singleton class for RAX int register
510 reg_class int_rax_reg(RAX);
512 // Singleton class for RBX int register
513 reg_class int_rbx_reg(RBX);
515 // Singleton class for RCX int register
516 reg_class int_rcx_reg(RCX);
518 // Singleton class for RCX int register
519 reg_class int_rdx_reg(RDX);
521 // Singleton class for RCX int register
522 reg_class int_rdi_reg(RDI);
524 // Singleton class for instruction pointer
525 // reg_class ip_reg(RIP);
527 %}
529 //----------SOURCE BLOCK-------------------------------------------------------
530 // This is a block of C++ code which provides values, functions, and
531 // definitions necessary in the rest of the architecture description
532 source %{
533 #define RELOC_IMM64 Assembler::imm_operand
534 #define RELOC_DISP32 Assembler::disp32_operand
536 #define __ _masm.
538 static int clear_avx_size() {
539 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper
540 }
542 // !!!!! Special hack to get all types of calls to specify the byte offset
543 // from the start of the call to the point where the return address
544 // will point.
545 int MachCallStaticJavaNode::ret_addr_offset()
546 {
547 int offset = 5; // 5 bytes from start of call to where return address points
548 offset += clear_avx_size();
549 return offset;
550 }
552 int MachCallDynamicJavaNode::ret_addr_offset()
553 {
554 int offset = 15; // 15 bytes from start of call to where return address points
555 offset += clear_avx_size();
556 return offset;
557 }
559 int MachCallRuntimeNode::ret_addr_offset() {
560 int offset = 13; // movq r10,#addr; callq (r10)
561 offset += clear_avx_size();
562 return offset;
563 }
565 // Indicate if the safepoint node needs the polling page as an input,
566 // it does if the polling page is more than disp32 away.
567 bool SafePointNode::needs_polling_address_input()
568 {
569 return Assembler::is_polling_page_far();
570 }
572 //
573 // Compute padding required for nodes which need alignment
574 //
576 // The address of the call instruction needs to be 4-byte aligned to
577 // ensure that it does not span a cache line so that it can be patched.
578 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
579 {
580 current_offset += clear_avx_size(); // skip vzeroupper
581 current_offset += 1; // skip call opcode byte
582 return round_to(current_offset, alignment_required()) - current_offset;
583 }
585 // The address of the call instruction needs to be 4-byte aligned to
586 // ensure that it does not span a cache line so that it can be patched.
587 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
588 {
589 current_offset += clear_avx_size(); // skip vzeroupper
590 current_offset += 11; // skip movq instruction + call opcode byte
591 return round_to(current_offset, alignment_required()) - current_offset;
592 }
594 // EMIT_RM()
595 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
596 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
597 cbuf.insts()->emit_int8(c);
598 }
600 // EMIT_CC()
601 void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
602 unsigned char c = (unsigned char) (f1 | f2);
603 cbuf.insts()->emit_int8(c);
604 }
606 // EMIT_OPCODE()
607 void emit_opcode(CodeBuffer &cbuf, int code) {
608 cbuf.insts()->emit_int8((unsigned char) code);
609 }
611 // EMIT_OPCODE() w/ relocation information
612 void emit_opcode(CodeBuffer &cbuf,
613 int code, relocInfo::relocType reloc, int offset, int format)
614 {
615 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format);
616 emit_opcode(cbuf, code);
617 }
619 // EMIT_D8()
620 void emit_d8(CodeBuffer &cbuf, int d8) {
621 cbuf.insts()->emit_int8((unsigned char) d8);
622 }
624 // EMIT_D16()
625 void emit_d16(CodeBuffer &cbuf, int d16) {
626 cbuf.insts()->emit_int16(d16);
627 }
629 // EMIT_D32()
630 void emit_d32(CodeBuffer &cbuf, int d32) {
631 cbuf.insts()->emit_int32(d32);
632 }
634 // EMIT_D64()
635 void emit_d64(CodeBuffer &cbuf, int64_t d64) {
636 cbuf.insts()->emit_int64(d64);
637 }
639 // emit 32 bit value and construct relocation entry from relocInfo::relocType
640 void emit_d32_reloc(CodeBuffer& cbuf,
641 int d32,
642 relocInfo::relocType reloc,
643 int format)
644 {
645 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
646 cbuf.relocate(cbuf.insts_mark(), reloc, format);
647 cbuf.insts()->emit_int32(d32);
648 }
650 // emit 32 bit value and construct relocation entry from RelocationHolder
651 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) {
652 #ifdef ASSERT
653 if (rspec.reloc()->type() == relocInfo::oop_type &&
654 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
655 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop");
656 assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
657 }
658 #endif
659 cbuf.relocate(cbuf.insts_mark(), rspec, format);
660 cbuf.insts()->emit_int32(d32);
661 }
663 void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
664 address next_ip = cbuf.insts_end() + 4;
665 emit_d32_reloc(cbuf, (int) (addr - next_ip),
666 external_word_Relocation::spec(addr),
667 RELOC_DISP32);
668 }
671 // emit 64 bit value and construct relocation entry from relocInfo::relocType
672 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) {
673 cbuf.relocate(cbuf.insts_mark(), reloc, format);
674 cbuf.insts()->emit_int64(d64);
675 }
677 // emit 64 bit value and construct relocation entry from RelocationHolder
678 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) {
679 #ifdef ASSERT
680 if (rspec.reloc()->type() == relocInfo::oop_type &&
681 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
682 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop");
683 assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()),
684 "cannot embed scavengable oops in code");
685 }
686 #endif
687 cbuf.relocate(cbuf.insts_mark(), rspec, format);
688 cbuf.insts()->emit_int64(d64);
689 }
691 // Access stack slot for load or store
692 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp)
693 {
694 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src])
695 if (-0x80 <= disp && disp < 0x80) {
696 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte
697 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
698 emit_d8(cbuf, disp); // Displacement // R/M byte
699 } else {
700 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte
701 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
702 emit_d32(cbuf, disp); // Displacement // R/M byte
703 }
704 }
706 // rRegI ereg, memory mem) %{ // emit_reg_mem
707 void encode_RegMem(CodeBuffer &cbuf,
708 int reg,
709 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc)
710 {
711 assert(disp_reloc == relocInfo::none, "cannot have disp");
712 int regenc = reg & 7;
713 int baseenc = base & 7;
714 int indexenc = index & 7;
716 // There is no index & no scale, use form without SIB byte
717 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) {
718 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
719 if (disp == 0 && base != RBP_enc && base != R13_enc) {
720 emit_rm(cbuf, 0x0, regenc, baseenc); // *
721 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
722 // If 8-bit displacement, mode 0x1
723 emit_rm(cbuf, 0x1, regenc, baseenc); // *
724 emit_d8(cbuf, disp);
725 } else {
726 // If 32-bit displacement
727 if (base == -1) { // Special flag for absolute address
728 emit_rm(cbuf, 0x0, regenc, 0x5); // *
729 if (disp_reloc != relocInfo::none) {
730 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
731 } else {
732 emit_d32(cbuf, disp);
733 }
734 } else {
735 // Normal base + offset
736 emit_rm(cbuf, 0x2, regenc, baseenc); // *
737 if (disp_reloc != relocInfo::none) {
738 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
739 } else {
740 emit_d32(cbuf, disp);
741 }
742 }
743 }
744 } else {
745 // Else, encode with the SIB byte
746 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
747 if (disp == 0 && base != RBP_enc && base != R13_enc) {
748 // If no displacement
749 emit_rm(cbuf, 0x0, regenc, 0x4); // *
750 emit_rm(cbuf, scale, indexenc, baseenc);
751 } else {
752 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
753 // If 8-bit displacement, mode 0x1
754 emit_rm(cbuf, 0x1, regenc, 0x4); // *
755 emit_rm(cbuf, scale, indexenc, baseenc);
756 emit_d8(cbuf, disp);
757 } else {
758 // If 32-bit displacement
759 if (base == 0x04 ) {
760 emit_rm(cbuf, 0x2, regenc, 0x4);
761 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
762 } else {
763 emit_rm(cbuf, 0x2, regenc, 0x4);
764 emit_rm(cbuf, scale, indexenc, baseenc); // *
765 }
766 if (disp_reloc != relocInfo::none) {
767 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
768 } else {
769 emit_d32(cbuf, disp);
770 }
771 }
772 }
773 }
774 }
776 // This could be in MacroAssembler but it's fairly C2 specific
777 void emit_cmpfp_fixup(MacroAssembler& _masm) {
778 Label exit;
779 __ jccb(Assembler::noParity, exit);
780 __ pushf();
781 //
782 // comiss/ucomiss instructions set ZF,PF,CF flags and
783 // zero OF,AF,SF for NaN values.
784 // Fixup flags by zeroing ZF,PF so that compare of NaN
785 // values returns 'less than' result (CF is set).
786 // Leave the rest of flags unchanged.
787 //
788 // 7 6 5 4 3 2 1 0
789 // |S|Z|r|A|r|P|r|C| (r - reserved bit)
790 // 0 0 1 0 1 0 1 1 (0x2B)
791 //
792 __ andq(Address(rsp, 0), 0xffffff2b);
793 __ popf();
794 __ bind(exit);
795 }
797 void emit_cmpfp3(MacroAssembler& _masm, Register dst) {
798 Label done;
799 __ movl(dst, -1);
800 __ jcc(Assembler::parity, done);
801 __ jcc(Assembler::below, done);
802 __ setb(Assembler::notEqual, dst);
803 __ movzbl(dst, dst);
804 __ bind(done);
805 }
808 //=============================================================================
809 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
811 int Compile::ConstantTable::calculate_table_base_offset() const {
812 return 0; // absolute addressing, no offset
813 }
815 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
816 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
817 ShouldNotReachHere();
818 }
820 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
821 // Empty encoding
822 }
824 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
825 return 0;
826 }
828 #ifndef PRODUCT
829 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
830 st->print("# MachConstantBaseNode (empty encoding)");
831 }
832 #endif
835 //=============================================================================
836 #ifndef PRODUCT
837 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
838 Compile* C = ra_->C;
840 int framesize = C->frame_size_in_bytes();
841 int bangsize = C->bang_size_in_bytes();
842 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
843 // Remove wordSize for return addr which is already pushed.
844 framesize -= wordSize;
846 if (C->need_stack_bang(bangsize)) {
847 framesize -= wordSize;
848 st->print("# stack bang (%d bytes)", bangsize);
849 st->print("\n\t");
850 st->print("pushq rbp\t# Save rbp");
851 if (PreserveFramePointer) {
852 st->print("\n\t");
853 st->print("movq rbp, rsp\t# Save the caller's SP into rbp");
854 }
855 if (framesize) {
856 st->print("\n\t");
857 st->print("subq rsp, #%d\t# Create frame",framesize);
858 }
859 } else {
860 st->print("subq rsp, #%d\t# Create frame",framesize);
861 st->print("\n\t");
862 framesize -= wordSize;
863 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
864 if (PreserveFramePointer) {
865 st->print("\n\t");
866 st->print("movq rbp, rsp\t# Save the caller's SP into rbp");
867 if (framesize > 0) {
868 st->print("\n\t");
869 st->print("addq rbp, #%d", framesize);
870 }
871 }
872 }
874 if (VerifyStackAtCalls) {
875 st->print("\n\t");
876 framesize -= wordSize;
877 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize);
878 #ifdef ASSERT
879 st->print("\n\t");
880 st->print("# stack alignment check");
881 #endif
882 }
883 st->cr();
884 }
885 #endif
887 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
888 Compile* C = ra_->C;
889 MacroAssembler _masm(&cbuf);
891 int framesize = C->frame_size_in_bytes();
892 int bangsize = C->bang_size_in_bytes();
894 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false);
896 C->set_frame_complete(cbuf.insts_size());
898 if (C->has_mach_constant_base_node()) {
899 // NOTE: We set the table base offset here because users might be
900 // emitted before MachConstantBaseNode.
901 Compile::ConstantTable& constant_table = C->constant_table();
902 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
903 }
904 }
906 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
907 {
908 return MachNode::size(ra_); // too many variables; just compute it
909 // the hard way
910 }
912 int MachPrologNode::reloc() const
913 {
914 return 0; // a large enough number
915 }
917 //=============================================================================
918 #ifndef PRODUCT
919 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
920 {
921 Compile* C = ra_->C;
922 if (C->max_vector_size() > 16) {
923 st->print("vzeroupper");
924 st->cr(); st->print("\t");
925 }
927 int framesize = C->frame_size_in_bytes();
928 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
929 // Remove word for return adr already pushed
930 // and RBP
931 framesize -= 2*wordSize;
933 if (framesize) {
934 st->print_cr("addq rsp, %d\t# Destroy frame", framesize);
935 st->print("\t");
936 }
938 st->print_cr("popq rbp");
939 if (do_polling() && C->is_method_compilation()) {
940 st->print("\t");
941 if (Assembler::is_polling_page_far()) {
942 st->print_cr("movq rscratch1, #polling_page_address\n\t"
943 "testl rax, [rscratch1]\t"
944 "# Safepoint: poll for GC");
945 } else {
946 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t"
947 "# Safepoint: poll for GC");
948 }
949 }
950 }
951 #endif
953 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
954 {
955 Compile* C = ra_->C;
956 if (C->max_vector_size() > 16) {
957 // Clear upper bits of YMM registers when current compiled code uses
958 // wide vectors to avoid AVX <-> SSE transition penalty during call.
959 MacroAssembler _masm(&cbuf);
960 __ vzeroupper();
961 }
963 int framesize = C->frame_size_in_bytes();
964 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
965 // Remove word for return adr already pushed
966 // and RBP
967 framesize -= 2*wordSize;
969 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here
971 if (framesize) {
972 emit_opcode(cbuf, Assembler::REX_W);
973 if (framesize < 0x80) {
974 emit_opcode(cbuf, 0x83); // addq rsp, #framesize
975 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
976 emit_d8(cbuf, framesize);
977 } else {
978 emit_opcode(cbuf, 0x81); // addq rsp, #framesize
979 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
980 emit_d32(cbuf, framesize);
981 }
982 }
984 // popq rbp
985 emit_opcode(cbuf, 0x58 | RBP_enc);
987 if (do_polling() && C->is_method_compilation()) {
988 MacroAssembler _masm(&cbuf);
989 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
990 if (Assembler::is_polling_page_far()) {
991 __ lea(rscratch1, polling_page);
992 __ relocate(relocInfo::poll_return_type);
993 __ testl(rax, Address(rscratch1, 0));
994 } else {
995 __ testl(rax, polling_page);
996 }
997 }
998 }
1000 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
1001 {
1002 return MachNode::size(ra_); // too many variables; just compute it
1003 // the hard way
1004 }
1006 int MachEpilogNode::reloc() const
1007 {
1008 return 2; // a large enough number
1009 }
1011 const Pipeline* MachEpilogNode::pipeline() const
1012 {
1013 return MachNode::pipeline_class();
1014 }
1016 int MachEpilogNode::safepoint_offset() const
1017 {
1018 return 0;
1019 }
1021 //=============================================================================
1023 enum RC {
1024 rc_bad,
1025 rc_int,
1026 rc_float,
1027 rc_stack
1028 };
1030 static enum RC rc_class(OptoReg::Name reg)
1031 {
1032 if( !OptoReg::is_valid(reg) ) return rc_bad;
1034 if (OptoReg::is_stack(reg)) return rc_stack;
1036 VMReg r = OptoReg::as_VMReg(reg);
1038 if (r->is_Register()) return rc_int;
1040 assert(r->is_XMMRegister(), "must be");
1041 return rc_float;
1042 }
1044 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad.
1045 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
1046 int src_hi, int dst_hi, uint ireg, outputStream* st);
1048 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
1049 int stack_offset, int reg, uint ireg, outputStream* st);
1051 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
1052 int dst_offset, uint ireg, outputStream* st) {
1053 if (cbuf) {
1054 MacroAssembler _masm(cbuf);
1055 switch (ireg) {
1056 case Op_VecS:
1057 __ movq(Address(rsp, -8), rax);
1058 __ movl(rax, Address(rsp, src_offset));
1059 __ movl(Address(rsp, dst_offset), rax);
1060 __ movq(rax, Address(rsp, -8));
1061 break;
1062 case Op_VecD:
1063 __ pushq(Address(rsp, src_offset));
1064 __ popq (Address(rsp, dst_offset));
1065 break;
1066 case Op_VecX:
1067 __ pushq(Address(rsp, src_offset));
1068 __ popq (Address(rsp, dst_offset));
1069 __ pushq(Address(rsp, src_offset+8));
1070 __ popq (Address(rsp, dst_offset+8));
1071 break;
1072 case Op_VecY:
1073 __ vmovdqu(Address(rsp, -32), xmm0);
1074 __ vmovdqu(xmm0, Address(rsp, src_offset));
1075 __ vmovdqu(Address(rsp, dst_offset), xmm0);
1076 __ vmovdqu(xmm0, Address(rsp, -32));
1077 break;
1078 default:
1079 ShouldNotReachHere();
1080 }
1081 #ifndef PRODUCT
1082 } else {
1083 switch (ireg) {
1084 case Op_VecS:
1085 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1086 "movl rax, [rsp + #%d]\n\t"
1087 "movl [rsp + #%d], rax\n\t"
1088 "movq rax, [rsp - #8]",
1089 src_offset, dst_offset);
1090 break;
1091 case Op_VecD:
1092 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1093 "popq [rsp + #%d]",
1094 src_offset, dst_offset);
1095 break;
1096 case Op_VecX:
1097 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t"
1098 "popq [rsp + #%d]\n\t"
1099 "pushq [rsp + #%d]\n\t"
1100 "popq [rsp + #%d]",
1101 src_offset, dst_offset, src_offset+8, dst_offset+8);
1102 break;
1103 case Op_VecY:
1104 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
1105 "vmovdqu xmm0, [rsp + #%d]\n\t"
1106 "vmovdqu [rsp + #%d], xmm0\n\t"
1107 "vmovdqu xmm0, [rsp - #32]",
1108 src_offset, dst_offset);
1109 break;
1110 default:
1111 ShouldNotReachHere();
1112 }
1113 #endif
1114 }
1115 }
1117 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
1118 PhaseRegAlloc* ra_,
1119 bool do_size,
1120 outputStream* st) const {
1121 assert(cbuf != NULL || st != NULL, "sanity");
1122 // Get registers to move
1123 OptoReg::Name src_second = ra_->get_reg_second(in(1));
1124 OptoReg::Name src_first = ra_->get_reg_first(in(1));
1125 OptoReg::Name dst_second = ra_->get_reg_second(this);
1126 OptoReg::Name dst_first = ra_->get_reg_first(this);
1128 enum RC src_second_rc = rc_class(src_second);
1129 enum RC src_first_rc = rc_class(src_first);
1130 enum RC dst_second_rc = rc_class(dst_second);
1131 enum RC dst_first_rc = rc_class(dst_first);
1133 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
1134 "must move at least 1 register" );
1136 if (src_first == dst_first && src_second == dst_second) {
1137 // Self copy, no move
1138 return 0;
1139 }
1140 if (bottom_type()->isa_vect() != NULL) {
1141 uint ireg = ideal_reg();
1142 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
1143 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
1144 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
1145 // mem -> mem
1146 int src_offset = ra_->reg2offset(src_first);
1147 int dst_offset = ra_->reg2offset(dst_first);
1148 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st);
1149 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) {
1150 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st);
1151 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) {
1152 int stack_offset = ra_->reg2offset(dst_first);
1153 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st);
1154 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) {
1155 int stack_offset = ra_->reg2offset(src_first);
1156 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st);
1157 } else {
1158 ShouldNotReachHere();
1159 }
1160 return 0;
1161 }
1162 if (src_first_rc == rc_stack) {
1163 // mem ->
1164 if (dst_first_rc == rc_stack) {
1165 // mem -> mem
1166 assert(src_second != dst_first, "overlap");
1167 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1168 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1169 // 64-bit
1170 int src_offset = ra_->reg2offset(src_first);
1171 int dst_offset = ra_->reg2offset(dst_first);
1172 if (cbuf) {
1173 MacroAssembler _masm(cbuf);
1174 __ pushq(Address(rsp, src_offset));
1175 __ popq (Address(rsp, dst_offset));
1176 #ifndef PRODUCT
1177 } else {
1178 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1179 "popq [rsp + #%d]",
1180 src_offset, dst_offset);
1181 #endif
1182 }
1183 } else {
1184 // 32-bit
1185 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1186 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1187 // No pushl/popl, so:
1188 int src_offset = ra_->reg2offset(src_first);
1189 int dst_offset = ra_->reg2offset(dst_first);
1190 if (cbuf) {
1191 MacroAssembler _masm(cbuf);
1192 __ movq(Address(rsp, -8), rax);
1193 __ movl(rax, Address(rsp, src_offset));
1194 __ movl(Address(rsp, dst_offset), rax);
1195 __ movq(rax, Address(rsp, -8));
1196 #ifndef PRODUCT
1197 } else {
1198 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1199 "movl rax, [rsp + #%d]\n\t"
1200 "movl [rsp + #%d], rax\n\t"
1201 "movq rax, [rsp - #8]",
1202 src_offset, dst_offset);
1203 #endif
1204 }
1205 }
1206 return 0;
1207 } else if (dst_first_rc == rc_int) {
1208 // mem -> gpr
1209 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1210 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1211 // 64-bit
1212 int offset = ra_->reg2offset(src_first);
1213 if (cbuf) {
1214 MacroAssembler _masm(cbuf);
1215 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1216 #ifndef PRODUCT
1217 } else {
1218 st->print("movq %s, [rsp + #%d]\t# spill",
1219 Matcher::regName[dst_first],
1220 offset);
1221 #endif
1222 }
1223 } else {
1224 // 32-bit
1225 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1226 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1227 int offset = ra_->reg2offset(src_first);
1228 if (cbuf) {
1229 MacroAssembler _masm(cbuf);
1230 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1231 #ifndef PRODUCT
1232 } else {
1233 st->print("movl %s, [rsp + #%d]\t# spill",
1234 Matcher::regName[dst_first],
1235 offset);
1236 #endif
1237 }
1238 }
1239 return 0;
1240 } else if (dst_first_rc == rc_float) {
1241 // mem-> xmm
1242 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1243 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1244 // 64-bit
1245 int offset = ra_->reg2offset(src_first);
1246 if (cbuf) {
1247 MacroAssembler _masm(cbuf);
1248 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1249 #ifndef PRODUCT
1250 } else {
1251 st->print("%s %s, [rsp + #%d]\t# spill",
1252 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1253 Matcher::regName[dst_first],
1254 offset);
1255 #endif
1256 }
1257 } else {
1258 // 32-bit
1259 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1260 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1261 int offset = ra_->reg2offset(src_first);
1262 if (cbuf) {
1263 MacroAssembler _masm(cbuf);
1264 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1265 #ifndef PRODUCT
1266 } else {
1267 st->print("movss %s, [rsp + #%d]\t# spill",
1268 Matcher::regName[dst_first],
1269 offset);
1270 #endif
1271 }
1272 }
1273 return 0;
1274 }
1275 } else if (src_first_rc == rc_int) {
1276 // gpr ->
1277 if (dst_first_rc == rc_stack) {
1278 // gpr -> mem
1279 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1280 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1281 // 64-bit
1282 int offset = ra_->reg2offset(dst_first);
1283 if (cbuf) {
1284 MacroAssembler _masm(cbuf);
1285 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
1286 #ifndef PRODUCT
1287 } else {
1288 st->print("movq [rsp + #%d], %s\t# spill",
1289 offset,
1290 Matcher::regName[src_first]);
1291 #endif
1292 }
1293 } else {
1294 // 32-bit
1295 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1296 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1297 int offset = ra_->reg2offset(dst_first);
1298 if (cbuf) {
1299 MacroAssembler _masm(cbuf);
1300 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
1301 #ifndef PRODUCT
1302 } else {
1303 st->print("movl [rsp + #%d], %s\t# spill",
1304 offset,
1305 Matcher::regName[src_first]);
1306 #endif
1307 }
1308 }
1309 return 0;
1310 } else if (dst_first_rc == rc_int) {
1311 // gpr -> gpr
1312 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1313 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1314 // 64-bit
1315 if (cbuf) {
1316 MacroAssembler _masm(cbuf);
1317 __ movq(as_Register(Matcher::_regEncode[dst_first]),
1318 as_Register(Matcher::_regEncode[src_first]));
1319 #ifndef PRODUCT
1320 } else {
1321 st->print("movq %s, %s\t# spill",
1322 Matcher::regName[dst_first],
1323 Matcher::regName[src_first]);
1324 #endif
1325 }
1326 return 0;
1327 } else {
1328 // 32-bit
1329 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1330 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1331 if (cbuf) {
1332 MacroAssembler _masm(cbuf);
1333 __ movl(as_Register(Matcher::_regEncode[dst_first]),
1334 as_Register(Matcher::_regEncode[src_first]));
1335 #ifndef PRODUCT
1336 } else {
1337 st->print("movl %s, %s\t# spill",
1338 Matcher::regName[dst_first],
1339 Matcher::regName[src_first]);
1340 #endif
1341 }
1342 return 0;
1343 }
1344 } else if (dst_first_rc == rc_float) {
1345 // gpr -> xmm
1346 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1347 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1348 // 64-bit
1349 if (cbuf) {
1350 MacroAssembler _masm(cbuf);
1351 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1352 #ifndef PRODUCT
1353 } else {
1354 st->print("movdq %s, %s\t# spill",
1355 Matcher::regName[dst_first],
1356 Matcher::regName[src_first]);
1357 #endif
1358 }
1359 } else {
1360 // 32-bit
1361 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1362 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1363 if (cbuf) {
1364 MacroAssembler _masm(cbuf);
1365 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1366 #ifndef PRODUCT
1367 } else {
1368 st->print("movdl %s, %s\t# spill",
1369 Matcher::regName[dst_first],
1370 Matcher::regName[src_first]);
1371 #endif
1372 }
1373 }
1374 return 0;
1375 }
1376 } else if (src_first_rc == rc_float) {
1377 // xmm ->
1378 if (dst_first_rc == rc_stack) {
1379 // xmm -> mem
1380 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1381 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1382 // 64-bit
1383 int offset = ra_->reg2offset(dst_first);
1384 if (cbuf) {
1385 MacroAssembler _masm(cbuf);
1386 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1387 #ifndef PRODUCT
1388 } else {
1389 st->print("movsd [rsp + #%d], %s\t# spill",
1390 offset,
1391 Matcher::regName[src_first]);
1392 #endif
1393 }
1394 } else {
1395 // 32-bit
1396 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1397 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1398 int offset = ra_->reg2offset(dst_first);
1399 if (cbuf) {
1400 MacroAssembler _masm(cbuf);
1401 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1402 #ifndef PRODUCT
1403 } else {
1404 st->print("movss [rsp + #%d], %s\t# spill",
1405 offset,
1406 Matcher::regName[src_first]);
1407 #endif
1408 }
1409 }
1410 return 0;
1411 } else if (dst_first_rc == rc_int) {
1412 // xmm -> gpr
1413 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1414 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1415 // 64-bit
1416 if (cbuf) {
1417 MacroAssembler _masm(cbuf);
1418 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1419 #ifndef PRODUCT
1420 } else {
1421 st->print("movdq %s, %s\t# spill",
1422 Matcher::regName[dst_first],
1423 Matcher::regName[src_first]);
1424 #endif
1425 }
1426 } else {
1427 // 32-bit
1428 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1429 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1430 if (cbuf) {
1431 MacroAssembler _masm(cbuf);
1432 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1433 #ifndef PRODUCT
1434 } else {
1435 st->print("movdl %s, %s\t# spill",
1436 Matcher::regName[dst_first],
1437 Matcher::regName[src_first]);
1438 #endif
1439 }
1440 }
1441 return 0;
1442 } else if (dst_first_rc == rc_float) {
1443 // xmm -> xmm
1444 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1445 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1446 // 64-bit
1447 if (cbuf) {
1448 MacroAssembler _masm(cbuf);
1449 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1450 #ifndef PRODUCT
1451 } else {
1452 st->print("%s %s, %s\t# spill",
1453 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
1454 Matcher::regName[dst_first],
1455 Matcher::regName[src_first]);
1456 #endif
1457 }
1458 } else {
1459 // 32-bit
1460 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1461 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1462 if (cbuf) {
1463 MacroAssembler _masm(cbuf);
1464 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1465 #ifndef PRODUCT
1466 } else {
1467 st->print("%s %s, %s\t# spill",
1468 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1469 Matcher::regName[dst_first],
1470 Matcher::regName[src_first]);
1471 #endif
1472 }
1473 }
1474 return 0;
1475 }
1476 }
1478 assert(0," foo ");
1479 Unimplemented();
1480 return 0;
1481 }
1483 #ifndef PRODUCT
1484 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const {
1485 implementation(NULL, ra_, false, st);
1486 }
1487 #endif
1489 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1490 implementation(&cbuf, ra_, false, NULL);
1491 }
1493 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1494 return MachNode::size(ra_);
1495 }
1497 //=============================================================================
1498 #ifndef PRODUCT
1499 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1500 {
1501 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1502 int reg = ra_->get_reg_first(this);
1503 st->print("leaq %s, [rsp + #%d]\t# box lock",
1504 Matcher::regName[reg], offset);
1505 }
1506 #endif
1508 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1509 {
1510 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1511 int reg = ra_->get_encode(this);
1512 if (offset >= 0x80) {
1513 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1514 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1515 emit_rm(cbuf, 0x2, reg & 7, 0x04);
1516 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1517 emit_d32(cbuf, offset);
1518 } else {
1519 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1520 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1521 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1522 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1523 emit_d8(cbuf, offset);
1524 }
1525 }
1527 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1528 {
1529 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1530 return (offset < 0x80) ? 5 : 8; // REX
1531 }
1533 //=============================================================================
1534 #ifndef PRODUCT
1535 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1536 {
1537 if (UseCompressedClassPointers) {
1538 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1539 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1540 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1541 } else {
1542 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1543 "# Inline cache check");
1544 }
1545 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1546 st->print_cr("\tnop\t# nops to align entry point");
1547 }
1548 #endif
1550 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1551 {
1552 MacroAssembler masm(&cbuf);
1553 uint insts_size = cbuf.insts_size();
1554 if (UseCompressedClassPointers) {
1555 masm.load_klass(rscratch1, j_rarg0);
1556 masm.cmpptr(rax, rscratch1);
1557 } else {
1558 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1559 }
1561 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1563 /* WARNING these NOPs are critical so that verified entry point is properly
1564 4 bytes aligned for patching by NativeJump::patch_verified_entry() */
1565 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
1566 if (OptoBreakpoint) {
1567 // Leave space for int3
1568 nops_cnt -= 1;
1569 }
1570 nops_cnt &= 0x3; // Do not add nops if code is aligned.
1571 if (nops_cnt > 0)
1572 masm.nop(nops_cnt);
1573 }
1575 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1576 {
1577 return MachNode::size(ra_); // too many variables; just compute it
1578 // the hard way
1579 }
1582 //=============================================================================
1584 int Matcher::regnum_to_fpu_offset(int regnum)
1585 {
1586 return regnum - 32; // The FP registers are in the second chunk
1587 }
1589 // This is UltraSparc specific, true just means we have fast l2f conversion
1590 const bool Matcher::convL2FSupported(void) {
1591 return true;
1592 }
1594 // Is this branch offset short enough that a short branch can be used?
1595 //
1596 // NOTE: If the platform does not provide any short branch variants, then
1597 // this method should return false for offset 0.
1598 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1599 // The passed offset is relative to address of the branch.
1600 // On 86 a branch displacement is calculated relative to address
1601 // of a next instruction.
1602 offset -= br_size;
1604 // the short version of jmpConUCF2 contains multiple branches,
1605 // making the reach slightly less
1606 if (rule == jmpConUCF2_rule)
1607 return (-126 <= offset && offset <= 125);
1608 return (-128 <= offset && offset <= 127);
1609 }
1611 const bool Matcher::isSimpleConstant64(jlong value) {
1612 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1613 //return value == (int) value; // Cf. storeImmL and immL32.
1615 // Probably always true, even if a temp register is required.
1616 return true;
1617 }
1619 // The ecx parameter to rep stosq for the ClearArray node is in words.
1620 const bool Matcher::init_array_count_is_in_bytes = false;
1622 // Threshold size for cleararray.
1623 const int Matcher::init_array_short_size = 8 * BytesPerLong;
1625 // No additional cost for CMOVL.
1626 const int Matcher::long_cmove_cost() { return 0; }
1628 // No CMOVF/CMOVD with SSE2
1629 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1631 // Does the CPU require late expand (see block.cpp for description of late expand)?
1632 const bool Matcher::require_postalloc_expand = false;
1634 // Should the Matcher clone shifts on addressing modes, expecting them
1635 // to be subsumed into complex addressing expressions or compute them
1636 // into registers? True for Intel but false for most RISCs
1637 const bool Matcher::clone_shift_expressions = true;
1639 // Do we need to mask the count passed to shift instructions or does
1640 // the cpu only look at the lower 5/6 bits anyway?
1641 const bool Matcher::need_masked_shift_count = false;
1643 bool Matcher::narrow_oop_use_complex_address() {
1644 assert(UseCompressedOops, "only for compressed oops code");
1645 return (LogMinObjAlignmentInBytes <= 3);
1646 }
1648 bool Matcher::narrow_klass_use_complex_address() {
1649 assert(UseCompressedClassPointers, "only for compressed klass code");
1650 return (LogKlassAlignmentInBytes <= 3);
1651 }
1653 // Is it better to copy float constants, or load them directly from
1654 // memory? Intel can load a float constant from a direct address,
1655 // requiring no extra registers. Most RISCs will have to materialize
1656 // an address into a register first, so they would do better to copy
1657 // the constant from stack.
1658 const bool Matcher::rematerialize_float_constants = true; // XXX
1660 // If CPU can load and store mis-aligned doubles directly then no
1661 // fixup is needed. Else we split the double into 2 integer pieces
1662 // and move it piece-by-piece. Only happens when passing doubles into
1663 // C code as the Java calling convention forces doubles to be aligned.
1664 const bool Matcher::misaligned_doubles_ok = true;
1666 // No-op on amd64
1667 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {}
1669 // Advertise here if the CPU requires explicit rounding operations to
1670 // implement the UseStrictFP mode.
1671 const bool Matcher::strict_fp_requires_explicit_rounding = true;
1673 // Are floats conerted to double when stored to stack during deoptimization?
1674 // On x64 it is stored without convertion so we can use normal access.
1675 bool Matcher::float_in_double() { return false; }
1677 // Do ints take an entire long register or just half?
1678 const bool Matcher::int_in_long = true;
1680 // Return whether or not this register is ever used as an argument.
1681 // This function is used on startup to build the trampoline stubs in
1682 // generateOptoStub. Registers not mentioned will be killed by the VM
1683 // call in the trampoline, and arguments in those registers not be
1684 // available to the callee.
1685 bool Matcher::can_be_java_arg(int reg)
1686 {
1687 return
1688 reg == RDI_num || reg == RDI_H_num ||
1689 reg == RSI_num || reg == RSI_H_num ||
1690 reg == RDX_num || reg == RDX_H_num ||
1691 reg == RCX_num || reg == RCX_H_num ||
1692 reg == R8_num || reg == R8_H_num ||
1693 reg == R9_num || reg == R9_H_num ||
1694 reg == R12_num || reg == R12_H_num ||
1695 reg == XMM0_num || reg == XMM0b_num ||
1696 reg == XMM1_num || reg == XMM1b_num ||
1697 reg == XMM2_num || reg == XMM2b_num ||
1698 reg == XMM3_num || reg == XMM3b_num ||
1699 reg == XMM4_num || reg == XMM4b_num ||
1700 reg == XMM5_num || reg == XMM5b_num ||
1701 reg == XMM6_num || reg == XMM6b_num ||
1702 reg == XMM7_num || reg == XMM7b_num;
1703 }
1705 bool Matcher::is_spillable_arg(int reg)
1706 {
1707 return can_be_java_arg(reg);
1708 }
1710 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1711 // In 64 bit mode a code which use multiply when
1712 // devisor is constant is faster than hardware
1713 // DIV instruction (it uses MulHiL).
1714 return false;
1715 }
1717 // Register for DIVI projection of divmodI
1718 RegMask Matcher::divI_proj_mask() {
1719 return INT_RAX_REG_mask();
1720 }
1722 // Register for MODI projection of divmodI
1723 RegMask Matcher::modI_proj_mask() {
1724 return INT_RDX_REG_mask();
1725 }
1727 // Register for DIVL projection of divmodL
1728 RegMask Matcher::divL_proj_mask() {
1729 return LONG_RAX_REG_mask();
1730 }
1732 // Register for MODL projection of divmodL
1733 RegMask Matcher::modL_proj_mask() {
1734 return LONG_RDX_REG_mask();
1735 }
1737 // Register for saving SP into on method handle invokes. Not used on x86_64.
1738 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1739 return NO_REG_mask();
1740 }
1742 %}
1744 //----------ENCODING BLOCK-----------------------------------------------------
1745 // This block specifies the encoding classes used by the compiler to
1746 // output byte streams. Encoding classes are parameterized macros
1747 // used by Machine Instruction Nodes in order to generate the bit
1748 // encoding of the instruction. Operands specify their base encoding
1749 // interface with the interface keyword. There are currently
1750 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
1751 // COND_INTER. REG_INTER causes an operand to generate a function
1752 // which returns its register number when queried. CONST_INTER causes
1753 // an operand to generate a function which returns the value of the
1754 // constant when queried. MEMORY_INTER causes an operand to generate
1755 // four functions which return the Base Register, the Index Register,
1756 // the Scale Value, and the Offset Value of the operand when queried.
1757 // COND_INTER causes an operand to generate six functions which return
1758 // the encoding code (ie - encoding bits for the instruction)
1759 // associated with each basic boolean condition for a conditional
1760 // instruction.
1761 //
1762 // Instructions specify two basic values for encoding. Again, a
1763 // function is available to check if the constant displacement is an
1764 // oop. They use the ins_encode keyword to specify their encoding
1765 // classes (which must be a sequence of enc_class names, and their
1766 // parameters, specified in the encoding block), and they use the
1767 // opcode keyword to specify, in order, their primary, secondary, and
1768 // tertiary opcode. Only the opcode sections which a particular
1769 // instruction needs for encoding need to be specified.
1770 encode %{
1771 // Build emit functions for each basic byte or larger field in the
1772 // intel encoding scheme (opcode, rm, sib, immediate), and call them
1773 // from C++ code in the enc_class source block. Emit functions will
1774 // live in the main source block for now. In future, we can
1775 // generalize this by adding a syntax that specifies the sizes of
1776 // fields in an order, so that the adlc can build the emit functions
1777 // automagically
1779 // Emit primary opcode
1780 enc_class OpcP
1781 %{
1782 emit_opcode(cbuf, $primary);
1783 %}
1785 // Emit secondary opcode
1786 enc_class OpcS
1787 %{
1788 emit_opcode(cbuf, $secondary);
1789 %}
1791 // Emit tertiary opcode
1792 enc_class OpcT
1793 %{
1794 emit_opcode(cbuf, $tertiary);
1795 %}
1797 // Emit opcode directly
1798 enc_class Opcode(immI d8)
1799 %{
1800 emit_opcode(cbuf, $d8$$constant);
1801 %}
1803 // Emit size prefix
1804 enc_class SizePrefix
1805 %{
1806 emit_opcode(cbuf, 0x66);
1807 %}
1809 enc_class reg(rRegI reg)
1810 %{
1811 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
1812 %}
1814 enc_class reg_reg(rRegI dst, rRegI src)
1815 %{
1816 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1817 %}
1819 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
1820 %{
1821 emit_opcode(cbuf, $opcode$$constant);
1822 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1823 %}
1825 enc_class cdql_enc(no_rax_rdx_RegI div)
1826 %{
1827 // Full implementation of Java idiv and irem; checks for
1828 // special case as described in JVM spec., p.243 & p.271.
1829 //
1830 // normal case special case
1831 //
1832 // input : rax: dividend min_int
1833 // reg: divisor -1
1834 //
1835 // output: rax: quotient (= rax idiv reg) min_int
1836 // rdx: remainder (= rax irem reg) 0
1837 //
1838 // Code sequnce:
1839 //
1840 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax
1841 // 5: 75 07/08 jne e <normal>
1842 // 7: 33 d2 xor %edx,%edx
1843 // [div >= 8 -> offset + 1]
1844 // [REX_B]
1845 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div
1846 // c: 74 03/04 je 11 <done>
1847 // 000000000000000e <normal>:
1848 // e: 99 cltd
1849 // [div >= 8 -> offset + 1]
1850 // [REX_B]
1851 // f: f7 f9 idiv $div
1852 // 0000000000000011 <done>:
1854 // cmp $0x80000000,%eax
1855 emit_opcode(cbuf, 0x3d);
1856 emit_d8(cbuf, 0x00);
1857 emit_d8(cbuf, 0x00);
1858 emit_d8(cbuf, 0x00);
1859 emit_d8(cbuf, 0x80);
1861 // jne e <normal>
1862 emit_opcode(cbuf, 0x75);
1863 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08);
1865 // xor %edx,%edx
1866 emit_opcode(cbuf, 0x33);
1867 emit_d8(cbuf, 0xD2);
1869 // cmp $0xffffffffffffffff,%ecx
1870 if ($div$$reg >= 8) {
1871 emit_opcode(cbuf, Assembler::REX_B);
1872 }
1873 emit_opcode(cbuf, 0x83);
1874 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
1875 emit_d8(cbuf, 0xFF);
1877 // je 11 <done>
1878 emit_opcode(cbuf, 0x74);
1879 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04);
1881 // <normal>
1882 // cltd
1883 emit_opcode(cbuf, 0x99);
1885 // idivl (note: must be emitted by the user of this rule)
1886 // <done>
1887 %}
1889 enc_class cdqq_enc(no_rax_rdx_RegL div)
1890 %{
1891 // Full implementation of Java ldiv and lrem; checks for
1892 // special case as described in JVM spec., p.243 & p.271.
1893 //
1894 // normal case special case
1895 //
1896 // input : rax: dividend min_long
1897 // reg: divisor -1
1898 //
1899 // output: rax: quotient (= rax idiv reg) min_long
1900 // rdx: remainder (= rax irem reg) 0
1901 //
1902 // Code sequnce:
1903 //
1904 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx
1905 // 7: 00 00 80
1906 // a: 48 39 d0 cmp %rdx,%rax
1907 // d: 75 08 jne 17 <normal>
1908 // f: 33 d2 xor %edx,%edx
1909 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div
1910 // 15: 74 05 je 1c <done>
1911 // 0000000000000017 <normal>:
1912 // 17: 48 99 cqto
1913 // 19: 48 f7 f9 idiv $div
1914 // 000000000000001c <done>:
1916 // mov $0x8000000000000000,%rdx
1917 emit_opcode(cbuf, Assembler::REX_W);
1918 emit_opcode(cbuf, 0xBA);
1919 emit_d8(cbuf, 0x00);
1920 emit_d8(cbuf, 0x00);
1921 emit_d8(cbuf, 0x00);
1922 emit_d8(cbuf, 0x00);
1923 emit_d8(cbuf, 0x00);
1924 emit_d8(cbuf, 0x00);
1925 emit_d8(cbuf, 0x00);
1926 emit_d8(cbuf, 0x80);
1928 // cmp %rdx,%rax
1929 emit_opcode(cbuf, Assembler::REX_W);
1930 emit_opcode(cbuf, 0x39);
1931 emit_d8(cbuf, 0xD0);
1933 // jne 17 <normal>
1934 emit_opcode(cbuf, 0x75);
1935 emit_d8(cbuf, 0x08);
1937 // xor %edx,%edx
1938 emit_opcode(cbuf, 0x33);
1939 emit_d8(cbuf, 0xD2);
1941 // cmp $0xffffffffffffffff,$div
1942 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB);
1943 emit_opcode(cbuf, 0x83);
1944 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
1945 emit_d8(cbuf, 0xFF);
1947 // je 1e <done>
1948 emit_opcode(cbuf, 0x74);
1949 emit_d8(cbuf, 0x05);
1951 // <normal>
1952 // cqto
1953 emit_opcode(cbuf, Assembler::REX_W);
1954 emit_opcode(cbuf, 0x99);
1956 // idivq (note: must be emitted by the user of this rule)
1957 // <done>
1958 %}
1960 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
1961 enc_class OpcSE(immI imm)
1962 %{
1963 // Emit primary opcode and set sign-extend bit
1964 // Check for 8-bit immediate, and set sign extend bit in opcode
1965 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1966 emit_opcode(cbuf, $primary | 0x02);
1967 } else {
1968 // 32-bit immediate
1969 emit_opcode(cbuf, $primary);
1970 }
1971 %}
1973 enc_class OpcSErm(rRegI dst, immI imm)
1974 %{
1975 // OpcSEr/m
1976 int dstenc = $dst$$reg;
1977 if (dstenc >= 8) {
1978 emit_opcode(cbuf, Assembler::REX_B);
1979 dstenc -= 8;
1980 }
1981 // Emit primary opcode and set sign-extend bit
1982 // Check for 8-bit immediate, and set sign extend bit in opcode
1983 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1984 emit_opcode(cbuf, $primary | 0x02);
1985 } else {
1986 // 32-bit immediate
1987 emit_opcode(cbuf, $primary);
1988 }
1989 // Emit r/m byte with secondary opcode, after primary opcode.
1990 emit_rm(cbuf, 0x3, $secondary, dstenc);
1991 %}
1993 enc_class OpcSErm_wide(rRegL dst, immI imm)
1994 %{
1995 // OpcSEr/m
1996 int dstenc = $dst$$reg;
1997 if (dstenc < 8) {
1998 emit_opcode(cbuf, Assembler::REX_W);
1999 } else {
2000 emit_opcode(cbuf, Assembler::REX_WB);
2001 dstenc -= 8;
2002 }
2003 // Emit primary opcode and set sign-extend bit
2004 // Check for 8-bit immediate, and set sign extend bit in opcode
2005 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2006 emit_opcode(cbuf, $primary | 0x02);
2007 } else {
2008 // 32-bit immediate
2009 emit_opcode(cbuf, $primary);
2010 }
2011 // Emit r/m byte with secondary opcode, after primary opcode.
2012 emit_rm(cbuf, 0x3, $secondary, dstenc);
2013 %}
2015 enc_class Con8or32(immI imm)
2016 %{
2017 // Check for 8-bit immediate, and set sign extend bit in opcode
2018 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2019 $$$emit8$imm$$constant;
2020 } else {
2021 // 32-bit immediate
2022 $$$emit32$imm$$constant;
2023 }
2024 %}
2026 enc_class opc2_reg(rRegI dst)
2027 %{
2028 // BSWAP
2029 emit_cc(cbuf, $secondary, $dst$$reg);
2030 %}
2032 enc_class opc3_reg(rRegI dst)
2033 %{
2034 // BSWAP
2035 emit_cc(cbuf, $tertiary, $dst$$reg);
2036 %}
2038 enc_class reg_opc(rRegI div)
2039 %{
2040 // INC, DEC, IDIV, IMOD, JMP indirect, ...
2041 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
2042 %}
2044 enc_class enc_cmov(cmpOp cop)
2045 %{
2046 // CMOV
2047 $$$emit8$primary;
2048 emit_cc(cbuf, $secondary, $cop$$cmpcode);
2049 %}
2051 enc_class enc_PartialSubtypeCheck()
2052 %{
2053 Register Rrdi = as_Register(RDI_enc); // result register
2054 Register Rrax = as_Register(RAX_enc); // super class
2055 Register Rrcx = as_Register(RCX_enc); // killed
2056 Register Rrsi = as_Register(RSI_enc); // sub class
2057 Label miss;
2058 const bool set_cond_codes = true;
2060 MacroAssembler _masm(&cbuf);
2061 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
2062 NULL, &miss,
2063 /*set_cond_codes:*/ true);
2064 if ($primary) {
2065 __ xorptr(Rrdi, Rrdi);
2066 }
2067 __ bind(miss);
2068 %}
2070 enc_class clear_avx %{
2071 debug_only(int off0 = cbuf.insts_size());
2072 if (ra_->C->max_vector_size() > 16) {
2073 // Clear upper bits of YMM registers when current compiled code uses
2074 // wide vectors to avoid AVX <-> SSE transition penalty during call.
2075 MacroAssembler _masm(&cbuf);
2076 __ vzeroupper();
2077 }
2078 debug_only(int off1 = cbuf.insts_size());
2079 assert(off1 - off0 == clear_avx_size(), "correct size prediction");
2080 %}
2082 enc_class Java_To_Runtime(method meth) %{
2083 // No relocation needed
2084 MacroAssembler _masm(&cbuf);
2085 __ mov64(r10, (int64_t) $meth$$method);
2086 __ call(r10);
2087 %}
2089 enc_class Java_To_Interpreter(method meth)
2090 %{
2091 // CALL Java_To_Interpreter
2092 // This is the instruction starting address for relocation info.
2093 cbuf.set_insts_mark();
2094 $$$emit8$primary;
2095 // CALL directly to the runtime
2096 emit_d32_reloc(cbuf,
2097 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2098 runtime_call_Relocation::spec(),
2099 RELOC_DISP32);
2100 %}
2102 enc_class Java_Static_Call(method meth)
2103 %{
2104 // JAVA STATIC CALL
2105 // CALL to fixup routine. Fixup routine uses ScopeDesc info to
2106 // determine who we intended to call.
2107 cbuf.set_insts_mark();
2108 $$$emit8$primary;
2110 if (!_method) {
2111 emit_d32_reloc(cbuf,
2112 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2113 runtime_call_Relocation::spec(),
2114 RELOC_DISP32);
2115 } else if (_optimized_virtual) {
2116 emit_d32_reloc(cbuf,
2117 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2118 opt_virtual_call_Relocation::spec(),
2119 RELOC_DISP32);
2120 } else {
2121 emit_d32_reloc(cbuf,
2122 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2123 static_call_Relocation::spec(),
2124 RELOC_DISP32);
2125 }
2126 if (_method) {
2127 // Emit stub for static call.
2128 CompiledStaticCall::emit_to_interp_stub(cbuf);
2129 }
2130 %}
2132 enc_class Java_Dynamic_Call(method meth) %{
2133 MacroAssembler _masm(&cbuf);
2134 __ ic_call((address)$meth$$method);
2135 %}
2137 enc_class Java_Compiled_Call(method meth)
2138 %{
2139 // JAVA COMPILED CALL
2140 int disp = in_bytes(Method:: from_compiled_offset());
2142 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
2143 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
2145 // callq *disp(%rax)
2146 cbuf.set_insts_mark();
2147 $$$emit8$primary;
2148 if (disp < 0x80) {
2149 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
2150 emit_d8(cbuf, disp); // Displacement
2151 } else {
2152 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte
2153 emit_d32(cbuf, disp); // Displacement
2154 }
2155 %}
2157 enc_class reg_opc_imm(rRegI dst, immI8 shift)
2158 %{
2159 // SAL, SAR, SHR
2160 int dstenc = $dst$$reg;
2161 if (dstenc >= 8) {
2162 emit_opcode(cbuf, Assembler::REX_B);
2163 dstenc -= 8;
2164 }
2165 $$$emit8$primary;
2166 emit_rm(cbuf, 0x3, $secondary, dstenc);
2167 $$$emit8$shift$$constant;
2168 %}
2170 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift)
2171 %{
2172 // SAL, SAR, SHR
2173 int dstenc = $dst$$reg;
2174 if (dstenc < 8) {
2175 emit_opcode(cbuf, Assembler::REX_W);
2176 } else {
2177 emit_opcode(cbuf, Assembler::REX_WB);
2178 dstenc -= 8;
2179 }
2180 $$$emit8$primary;
2181 emit_rm(cbuf, 0x3, $secondary, dstenc);
2182 $$$emit8$shift$$constant;
2183 %}
2185 enc_class load_immI(rRegI dst, immI src)
2186 %{
2187 int dstenc = $dst$$reg;
2188 if (dstenc >= 8) {
2189 emit_opcode(cbuf, Assembler::REX_B);
2190 dstenc -= 8;
2191 }
2192 emit_opcode(cbuf, 0xB8 | dstenc);
2193 $$$emit32$src$$constant;
2194 %}
2196 enc_class load_immL(rRegL dst, immL src)
2197 %{
2198 int dstenc = $dst$$reg;
2199 if (dstenc < 8) {
2200 emit_opcode(cbuf, Assembler::REX_W);
2201 } else {
2202 emit_opcode(cbuf, Assembler::REX_WB);
2203 dstenc -= 8;
2204 }
2205 emit_opcode(cbuf, 0xB8 | dstenc);
2206 emit_d64(cbuf, $src$$constant);
2207 %}
2209 enc_class load_immUL32(rRegL dst, immUL32 src)
2210 %{
2211 // same as load_immI, but this time we care about zeroes in the high word
2212 int dstenc = $dst$$reg;
2213 if (dstenc >= 8) {
2214 emit_opcode(cbuf, Assembler::REX_B);
2215 dstenc -= 8;
2216 }
2217 emit_opcode(cbuf, 0xB8 | dstenc);
2218 $$$emit32$src$$constant;
2219 %}
2221 enc_class load_immL32(rRegL dst, immL32 src)
2222 %{
2223 int dstenc = $dst$$reg;
2224 if (dstenc < 8) {
2225 emit_opcode(cbuf, Assembler::REX_W);
2226 } else {
2227 emit_opcode(cbuf, Assembler::REX_WB);
2228 dstenc -= 8;
2229 }
2230 emit_opcode(cbuf, 0xC7);
2231 emit_rm(cbuf, 0x03, 0x00, dstenc);
2232 $$$emit32$src$$constant;
2233 %}
2235 enc_class load_immP31(rRegP dst, immP32 src)
2236 %{
2237 // same as load_immI, but this time we care about zeroes in the high word
2238 int dstenc = $dst$$reg;
2239 if (dstenc >= 8) {
2240 emit_opcode(cbuf, Assembler::REX_B);
2241 dstenc -= 8;
2242 }
2243 emit_opcode(cbuf, 0xB8 | dstenc);
2244 $$$emit32$src$$constant;
2245 %}
2247 enc_class load_immP(rRegP dst, immP src)
2248 %{
2249 int dstenc = $dst$$reg;
2250 if (dstenc < 8) {
2251 emit_opcode(cbuf, Assembler::REX_W);
2252 } else {
2253 emit_opcode(cbuf, Assembler::REX_WB);
2254 dstenc -= 8;
2255 }
2256 emit_opcode(cbuf, 0xB8 | dstenc);
2257 // This next line should be generated from ADLC
2258 if ($src->constant_reloc() != relocInfo::none) {
2259 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64);
2260 } else {
2261 emit_d64(cbuf, $src$$constant);
2262 }
2263 %}
2265 enc_class Con32(immI src)
2266 %{
2267 // Output immediate
2268 $$$emit32$src$$constant;
2269 %}
2271 enc_class Con32F_as_bits(immF src)
2272 %{
2273 // Output Float immediate bits
2274 jfloat jf = $src$$constant;
2275 jint jf_as_bits = jint_cast(jf);
2276 emit_d32(cbuf, jf_as_bits);
2277 %}
2279 enc_class Con16(immI src)
2280 %{
2281 // Output immediate
2282 $$$emit16$src$$constant;
2283 %}
2285 // How is this different from Con32??? XXX
2286 enc_class Con_d32(immI src)
2287 %{
2288 emit_d32(cbuf,$src$$constant);
2289 %}
2291 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
2292 // Output immediate memory reference
2293 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2294 emit_d32(cbuf, 0x00);
2295 %}
2297 enc_class lock_prefix()
2298 %{
2299 if (os::is_MP()) {
2300 emit_opcode(cbuf, 0xF0); // lock
2301 }
2302 %}
2304 enc_class REX_mem(memory mem)
2305 %{
2306 if ($mem$$base >= 8) {
2307 if ($mem$$index < 8) {
2308 emit_opcode(cbuf, Assembler::REX_B);
2309 } else {
2310 emit_opcode(cbuf, Assembler::REX_XB);
2311 }
2312 } else {
2313 if ($mem$$index >= 8) {
2314 emit_opcode(cbuf, Assembler::REX_X);
2315 }
2316 }
2317 %}
2319 enc_class REX_mem_wide(memory mem)
2320 %{
2321 if ($mem$$base >= 8) {
2322 if ($mem$$index < 8) {
2323 emit_opcode(cbuf, Assembler::REX_WB);
2324 } else {
2325 emit_opcode(cbuf, Assembler::REX_WXB);
2326 }
2327 } else {
2328 if ($mem$$index < 8) {
2329 emit_opcode(cbuf, Assembler::REX_W);
2330 } else {
2331 emit_opcode(cbuf, Assembler::REX_WX);
2332 }
2333 }
2334 %}
2336 // for byte regs
2337 enc_class REX_breg(rRegI reg)
2338 %{
2339 if ($reg$$reg >= 4) {
2340 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2341 }
2342 %}
2344 // for byte regs
2345 enc_class REX_reg_breg(rRegI dst, rRegI src)
2346 %{
2347 if ($dst$$reg < 8) {
2348 if ($src$$reg >= 4) {
2349 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2350 }
2351 } else {
2352 if ($src$$reg < 8) {
2353 emit_opcode(cbuf, Assembler::REX_R);
2354 } else {
2355 emit_opcode(cbuf, Assembler::REX_RB);
2356 }
2357 }
2358 %}
2360 // for byte regs
2361 enc_class REX_breg_mem(rRegI reg, memory mem)
2362 %{
2363 if ($reg$$reg < 8) {
2364 if ($mem$$base < 8) {
2365 if ($mem$$index >= 8) {
2366 emit_opcode(cbuf, Assembler::REX_X);
2367 } else if ($reg$$reg >= 4) {
2368 emit_opcode(cbuf, Assembler::REX);
2369 }
2370 } else {
2371 if ($mem$$index < 8) {
2372 emit_opcode(cbuf, Assembler::REX_B);
2373 } else {
2374 emit_opcode(cbuf, Assembler::REX_XB);
2375 }
2376 }
2377 } else {
2378 if ($mem$$base < 8) {
2379 if ($mem$$index < 8) {
2380 emit_opcode(cbuf, Assembler::REX_R);
2381 } else {
2382 emit_opcode(cbuf, Assembler::REX_RX);
2383 }
2384 } else {
2385 if ($mem$$index < 8) {
2386 emit_opcode(cbuf, Assembler::REX_RB);
2387 } else {
2388 emit_opcode(cbuf, Assembler::REX_RXB);
2389 }
2390 }
2391 }
2392 %}
2394 enc_class REX_reg(rRegI reg)
2395 %{
2396 if ($reg$$reg >= 8) {
2397 emit_opcode(cbuf, Assembler::REX_B);
2398 }
2399 %}
2401 enc_class REX_reg_wide(rRegI reg)
2402 %{
2403 if ($reg$$reg < 8) {
2404 emit_opcode(cbuf, Assembler::REX_W);
2405 } else {
2406 emit_opcode(cbuf, Assembler::REX_WB);
2407 }
2408 %}
2410 enc_class REX_reg_reg(rRegI dst, rRegI src)
2411 %{
2412 if ($dst$$reg < 8) {
2413 if ($src$$reg >= 8) {
2414 emit_opcode(cbuf, Assembler::REX_B);
2415 }
2416 } else {
2417 if ($src$$reg < 8) {
2418 emit_opcode(cbuf, Assembler::REX_R);
2419 } else {
2420 emit_opcode(cbuf, Assembler::REX_RB);
2421 }
2422 }
2423 %}
2425 enc_class REX_reg_reg_wide(rRegI dst, rRegI src)
2426 %{
2427 if ($dst$$reg < 8) {
2428 if ($src$$reg < 8) {
2429 emit_opcode(cbuf, Assembler::REX_W);
2430 } else {
2431 emit_opcode(cbuf, Assembler::REX_WB);
2432 }
2433 } else {
2434 if ($src$$reg < 8) {
2435 emit_opcode(cbuf, Assembler::REX_WR);
2436 } else {
2437 emit_opcode(cbuf, Assembler::REX_WRB);
2438 }
2439 }
2440 %}
2442 enc_class REX_reg_mem(rRegI reg, memory mem)
2443 %{
2444 if ($reg$$reg < 8) {
2445 if ($mem$$base < 8) {
2446 if ($mem$$index >= 8) {
2447 emit_opcode(cbuf, Assembler::REX_X);
2448 }
2449 } else {
2450 if ($mem$$index < 8) {
2451 emit_opcode(cbuf, Assembler::REX_B);
2452 } else {
2453 emit_opcode(cbuf, Assembler::REX_XB);
2454 }
2455 }
2456 } else {
2457 if ($mem$$base < 8) {
2458 if ($mem$$index < 8) {
2459 emit_opcode(cbuf, Assembler::REX_R);
2460 } else {
2461 emit_opcode(cbuf, Assembler::REX_RX);
2462 }
2463 } else {
2464 if ($mem$$index < 8) {
2465 emit_opcode(cbuf, Assembler::REX_RB);
2466 } else {
2467 emit_opcode(cbuf, Assembler::REX_RXB);
2468 }
2469 }
2470 }
2471 %}
2473 enc_class REX_reg_mem_wide(rRegL reg, memory mem)
2474 %{
2475 if ($reg$$reg < 8) {
2476 if ($mem$$base < 8) {
2477 if ($mem$$index < 8) {
2478 emit_opcode(cbuf, Assembler::REX_W);
2479 } else {
2480 emit_opcode(cbuf, Assembler::REX_WX);
2481 }
2482 } else {
2483 if ($mem$$index < 8) {
2484 emit_opcode(cbuf, Assembler::REX_WB);
2485 } else {
2486 emit_opcode(cbuf, Assembler::REX_WXB);
2487 }
2488 }
2489 } else {
2490 if ($mem$$base < 8) {
2491 if ($mem$$index < 8) {
2492 emit_opcode(cbuf, Assembler::REX_WR);
2493 } else {
2494 emit_opcode(cbuf, Assembler::REX_WRX);
2495 }
2496 } else {
2497 if ($mem$$index < 8) {
2498 emit_opcode(cbuf, Assembler::REX_WRB);
2499 } else {
2500 emit_opcode(cbuf, Assembler::REX_WRXB);
2501 }
2502 }
2503 }
2504 %}
2506 enc_class reg_mem(rRegI ereg, memory mem)
2507 %{
2508 // High registers handle in encode_RegMem
2509 int reg = $ereg$$reg;
2510 int base = $mem$$base;
2511 int index = $mem$$index;
2512 int scale = $mem$$scale;
2513 int disp = $mem$$disp;
2514 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2516 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc);
2517 %}
2519 enc_class RM_opc_mem(immI rm_opcode, memory mem)
2520 %{
2521 int rm_byte_opcode = $rm_opcode$$constant;
2523 // High registers handle in encode_RegMem
2524 int base = $mem$$base;
2525 int index = $mem$$index;
2526 int scale = $mem$$scale;
2527 int displace = $mem$$disp;
2529 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when
2530 // working with static
2531 // globals
2532 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace,
2533 disp_reloc);
2534 %}
2536 enc_class reg_lea(rRegI dst, rRegI src0, immI src1)
2537 %{
2538 int reg_encoding = $dst$$reg;
2539 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
2540 int index = 0x04; // 0x04 indicates no index
2541 int scale = 0x00; // 0x00 indicates no scale
2542 int displace = $src1$$constant; // 0x00 indicates no displacement
2543 relocInfo::relocType disp_reloc = relocInfo::none;
2544 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace,
2545 disp_reloc);
2546 %}
2548 enc_class neg_reg(rRegI dst)
2549 %{
2550 int dstenc = $dst$$reg;
2551 if (dstenc >= 8) {
2552 emit_opcode(cbuf, Assembler::REX_B);
2553 dstenc -= 8;
2554 }
2555 // NEG $dst
2556 emit_opcode(cbuf, 0xF7);
2557 emit_rm(cbuf, 0x3, 0x03, dstenc);
2558 %}
2560 enc_class neg_reg_wide(rRegI dst)
2561 %{
2562 int dstenc = $dst$$reg;
2563 if (dstenc < 8) {
2564 emit_opcode(cbuf, Assembler::REX_W);
2565 } else {
2566 emit_opcode(cbuf, Assembler::REX_WB);
2567 dstenc -= 8;
2568 }
2569 // NEG $dst
2570 emit_opcode(cbuf, 0xF7);
2571 emit_rm(cbuf, 0x3, 0x03, dstenc);
2572 %}
2574 enc_class setLT_reg(rRegI dst)
2575 %{
2576 int dstenc = $dst$$reg;
2577 if (dstenc >= 8) {
2578 emit_opcode(cbuf, Assembler::REX_B);
2579 dstenc -= 8;
2580 } else if (dstenc >= 4) {
2581 emit_opcode(cbuf, Assembler::REX);
2582 }
2583 // SETLT $dst
2584 emit_opcode(cbuf, 0x0F);
2585 emit_opcode(cbuf, 0x9C);
2586 emit_rm(cbuf, 0x3, 0x0, dstenc);
2587 %}
2589 enc_class setNZ_reg(rRegI dst)
2590 %{
2591 int dstenc = $dst$$reg;
2592 if (dstenc >= 8) {
2593 emit_opcode(cbuf, Assembler::REX_B);
2594 dstenc -= 8;
2595 } else if (dstenc >= 4) {
2596 emit_opcode(cbuf, Assembler::REX);
2597 }
2598 // SETNZ $dst
2599 emit_opcode(cbuf, 0x0F);
2600 emit_opcode(cbuf, 0x95);
2601 emit_rm(cbuf, 0x3, 0x0, dstenc);
2602 %}
2605 // Compare the lonogs and set -1, 0, or 1 into dst
2606 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst)
2607 %{
2608 int src1enc = $src1$$reg;
2609 int src2enc = $src2$$reg;
2610 int dstenc = $dst$$reg;
2612 // cmpq $src1, $src2
2613 if (src1enc < 8) {
2614 if (src2enc < 8) {
2615 emit_opcode(cbuf, Assembler::REX_W);
2616 } else {
2617 emit_opcode(cbuf, Assembler::REX_WB);
2618 }
2619 } else {
2620 if (src2enc < 8) {
2621 emit_opcode(cbuf, Assembler::REX_WR);
2622 } else {
2623 emit_opcode(cbuf, Assembler::REX_WRB);
2624 }
2625 }
2626 emit_opcode(cbuf, 0x3B);
2627 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7);
2629 // movl $dst, -1
2630 if (dstenc >= 8) {
2631 emit_opcode(cbuf, Assembler::REX_B);
2632 }
2633 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
2634 emit_d32(cbuf, -1);
2636 // jl,s done
2637 emit_opcode(cbuf, 0x7C);
2638 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
2640 // setne $dst
2641 if (dstenc >= 4) {
2642 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
2643 }
2644 emit_opcode(cbuf, 0x0F);
2645 emit_opcode(cbuf, 0x95);
2646 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
2648 // movzbl $dst, $dst
2649 if (dstenc >= 4) {
2650 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
2651 }
2652 emit_opcode(cbuf, 0x0F);
2653 emit_opcode(cbuf, 0xB6);
2654 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
2655 %}
2657 enc_class Push_ResultXD(regD dst) %{
2658 MacroAssembler _masm(&cbuf);
2659 __ fstp_d(Address(rsp, 0));
2660 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
2661 __ addptr(rsp, 8);
2662 %}
2664 enc_class Push_SrcXD(regD src) %{
2665 MacroAssembler _masm(&cbuf);
2666 __ subptr(rsp, 8);
2667 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
2668 __ fld_d(Address(rsp, 0));
2669 %}
2672 enc_class enc_rethrow()
2673 %{
2674 cbuf.set_insts_mark();
2675 emit_opcode(cbuf, 0xE9); // jmp entry
2676 emit_d32_reloc(cbuf,
2677 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
2678 runtime_call_Relocation::spec(),
2679 RELOC_DISP32);
2680 %}
2682 %}
2686 //----------FRAME--------------------------------------------------------------
2687 // Definition of frame structure and management information.
2688 //
2689 // S T A C K L A Y O U T Allocators stack-slot number
2690 // | (to get allocators register number
2691 // G Owned by | | v add OptoReg::stack0())
2692 // r CALLER | |
2693 // o | +--------+ pad to even-align allocators stack-slot
2694 // w V | pad0 | numbers; owned by CALLER
2695 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
2696 // h ^ | in | 5
2697 // | | args | 4 Holes in incoming args owned by SELF
2698 // | | | | 3
2699 // | | +--------+
2700 // V | | old out| Empty on Intel, window on Sparc
2701 // | old |preserve| Must be even aligned.
2702 // | SP-+--------+----> Matcher::_old_SP, even aligned
2703 // | | in | 3 area for Intel ret address
2704 // Owned by |preserve| Empty on Sparc.
2705 // SELF +--------+
2706 // | | pad2 | 2 pad to align old SP
2707 // | +--------+ 1
2708 // | | locks | 0
2709 // | +--------+----> OptoReg::stack0(), even aligned
2710 // | | pad1 | 11 pad to align new SP
2711 // | +--------+
2712 // | | | 10
2713 // | | spills | 9 spills
2714 // V | | 8 (pad0 slot for callee)
2715 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
2716 // ^ | out | 7
2717 // | | args | 6 Holes in outgoing args owned by CALLEE
2718 // Owned by +--------+
2719 // CALLEE | new out| 6 Empty on Intel, window on Sparc
2720 // | new |preserve| Must be even-aligned.
2721 // | SP-+--------+----> Matcher::_new_SP, even aligned
2722 // | | |
2723 //
2724 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
2725 // known from SELF's arguments and the Java calling convention.
2726 // Region 6-7 is determined per call site.
2727 // Note 2: If the calling convention leaves holes in the incoming argument
2728 // area, those holes are owned by SELF. Holes in the outgoing area
2729 // are owned by the CALLEE. Holes should not be nessecary in the
2730 // incoming area, as the Java calling convention is completely under
2731 // the control of the AD file. Doubles can be sorted and packed to
2732 // avoid holes. Holes in the outgoing arguments may be nessecary for
2733 // varargs C calling conventions.
2734 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
2735 // even aligned with pad0 as needed.
2736 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
2737 // region 6-11 is even aligned; it may be padded out more so that
2738 // the region from SP to FP meets the minimum stack alignment.
2739 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
2740 // alignment. Region 11, pad1, may be dynamically extended so that
2741 // SP meets the minimum alignment.
2743 frame
2744 %{
2745 // What direction does stack grow in (assumed to be same for C & Java)
2746 stack_direction(TOWARDS_LOW);
2748 // These three registers define part of the calling convention
2749 // between compiled code and the interpreter.
2750 inline_cache_reg(RAX); // Inline Cache Register
2751 interpreter_method_oop_reg(RBX); // Method Oop Register when
2752 // calling interpreter
2754 // Optional: name the operand used by cisc-spilling to access
2755 // [stack_pointer + offset]
2756 cisc_spilling_operand_name(indOffset32);
2758 // Number of stack slots consumed by locking an object
2759 sync_stack_slots(2);
2761 // Compiled code's Frame Pointer
2762 frame_pointer(RSP);
2764 // Interpreter stores its frame pointer in a register which is
2765 // stored to the stack by I2CAdaptors.
2766 // I2CAdaptors convert from interpreted java to compiled java.
2767 interpreter_frame_pointer(RBP);
2769 // Stack alignment requirement
2770 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
2772 // Number of stack slots between incoming argument block and the start of
2773 // a new frame. The PROLOG must add this many slots to the stack. The
2774 // EPILOG must remove this many slots. amd64 needs two slots for
2775 // return address.
2776 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls);
2778 // Number of outgoing stack slots killed above the out_preserve_stack_slots
2779 // for calls to C. Supports the var-args backing area for register parms.
2780 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
2782 // The after-PROLOG location of the return address. Location of
2783 // return address specifies a type (REG or STACK) and a number
2784 // representing the register number (i.e. - use a register name) or
2785 // stack slot.
2786 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
2787 // Otherwise, it is above the locks and verification slot and alignment word
2788 return_addr(STACK - 2 +
2789 round_to((Compile::current()->in_preserve_stack_slots() +
2790 Compile::current()->fixed_slots()),
2791 stack_alignment_in_slots()));
2793 // Body of function which returns an integer array locating
2794 // arguments either in registers or in stack slots. Passed an array
2795 // of ideal registers called "sig" and a "length" count. Stack-slot
2796 // offsets are based on outgoing arguments, i.e. a CALLER setting up
2797 // arguments for a CALLEE. Incoming stack arguments are
2798 // automatically biased by the preserve_stack_slots field above.
2800 calling_convention
2801 %{
2802 // No difference between ingoing/outgoing just pass false
2803 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
2804 %}
2806 c_calling_convention
2807 %{
2808 // This is obviously always outgoing
2809 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
2810 %}
2812 // Location of compiled Java return values. Same as C for now.
2813 return_value
2814 %{
2815 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
2816 "only return normal values");
2818 static const int lo[Op_RegL + 1] = {
2819 0,
2820 0,
2821 RAX_num, // Op_RegN
2822 RAX_num, // Op_RegI
2823 RAX_num, // Op_RegP
2824 XMM0_num, // Op_RegF
2825 XMM0_num, // Op_RegD
2826 RAX_num // Op_RegL
2827 };
2828 static const int hi[Op_RegL + 1] = {
2829 0,
2830 0,
2831 OptoReg::Bad, // Op_RegN
2832 OptoReg::Bad, // Op_RegI
2833 RAX_H_num, // Op_RegP
2834 OptoReg::Bad, // Op_RegF
2835 XMM0b_num, // Op_RegD
2836 RAX_H_num // Op_RegL
2837 };
2838 // Excluded flags and vector registers.
2839 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type");
2840 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
2841 %}
2842 %}
2844 //----------ATTRIBUTES---------------------------------------------------------
2845 //----------Operand Attributes-------------------------------------------------
2846 op_attrib op_cost(0); // Required cost attribute
2848 //----------Instruction Attributes---------------------------------------------
2849 ins_attrib ins_cost(100); // Required cost attribute
2850 ins_attrib ins_size(8); // Required size attribute (in bits)
2851 ins_attrib ins_short_branch(0); // Required flag: is this instruction
2852 // a non-matching short branch variant
2853 // of some long branch?
2854 ins_attrib ins_alignment(1); // Required alignment attribute (must
2855 // be a power of 2) specifies the
2856 // alignment that some part of the
2857 // instruction (not necessarily the
2858 // start) requires. If > 1, a
2859 // compute_padding() function must be
2860 // provided for the instruction
2862 //----------OPERANDS-----------------------------------------------------------
2863 // Operand definitions must precede instruction definitions for correct parsing
2864 // in the ADLC because operands constitute user defined types which are used in
2865 // instruction definitions.
2867 //----------Simple Operands----------------------------------------------------
2868 // Immediate Operands
2869 // Integer Immediate
2870 operand immI()
2871 %{
2872 match(ConI);
2874 op_cost(10);
2875 format %{ %}
2876 interface(CONST_INTER);
2877 %}
2879 // Constant for test vs zero
2880 operand immI0()
2881 %{
2882 predicate(n->get_int() == 0);
2883 match(ConI);
2885 op_cost(0);
2886 format %{ %}
2887 interface(CONST_INTER);
2888 %}
2890 // Constant for increment
2891 operand immI1()
2892 %{
2893 predicate(n->get_int() == 1);
2894 match(ConI);
2896 op_cost(0);
2897 format %{ %}
2898 interface(CONST_INTER);
2899 %}
2901 // Constant for decrement
2902 operand immI_M1()
2903 %{
2904 predicate(n->get_int() == -1);
2905 match(ConI);
2907 op_cost(0);
2908 format %{ %}
2909 interface(CONST_INTER);
2910 %}
2912 // Valid scale values for addressing modes
2913 operand immI2()
2914 %{
2915 predicate(0 <= n->get_int() && (n->get_int() <= 3));
2916 match(ConI);
2918 format %{ %}
2919 interface(CONST_INTER);
2920 %}
2922 operand immI8()
2923 %{
2924 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80));
2925 match(ConI);
2927 op_cost(5);
2928 format %{ %}
2929 interface(CONST_INTER);
2930 %}
2932 operand immI16()
2933 %{
2934 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
2935 match(ConI);
2937 op_cost(10);
2938 format %{ %}
2939 interface(CONST_INTER);
2940 %}
2942 // Int Immediate non-negative
2943 operand immU31()
2944 %{
2945 predicate(n->get_int() >= 0);
2946 match(ConI);
2948 op_cost(0);
2949 format %{ %}
2950 interface(CONST_INTER);
2951 %}
2953 // Constant for long shifts
2954 operand immI_32()
2955 %{
2956 predicate( n->get_int() == 32 );
2957 match(ConI);
2959 op_cost(0);
2960 format %{ %}
2961 interface(CONST_INTER);
2962 %}
2964 // Constant for long shifts
2965 operand immI_64()
2966 %{
2967 predicate( n->get_int() == 64 );
2968 match(ConI);
2970 op_cost(0);
2971 format %{ %}
2972 interface(CONST_INTER);
2973 %}
2975 // Pointer Immediate
2976 operand immP()
2977 %{
2978 match(ConP);
2980 op_cost(10);
2981 format %{ %}
2982 interface(CONST_INTER);
2983 %}
2985 // NULL Pointer Immediate
2986 operand immP0()
2987 %{
2988 predicate(n->get_ptr() == 0);
2989 match(ConP);
2991 op_cost(5);
2992 format %{ %}
2993 interface(CONST_INTER);
2994 %}
2996 // Pointer Immediate
2997 operand immN() %{
2998 match(ConN);
3000 op_cost(10);
3001 format %{ %}
3002 interface(CONST_INTER);
3003 %}
3005 operand immNKlass() %{
3006 match(ConNKlass);
3008 op_cost(10);
3009 format %{ %}
3010 interface(CONST_INTER);
3011 %}
3013 // NULL Pointer Immediate
3014 operand immN0() %{
3015 predicate(n->get_narrowcon() == 0);
3016 match(ConN);
3018 op_cost(5);
3019 format %{ %}
3020 interface(CONST_INTER);
3021 %}
3023 operand immP31()
3024 %{
3025 predicate(n->as_Type()->type()->reloc() == relocInfo::none
3026 && (n->get_ptr() >> 31) == 0);
3027 match(ConP);
3029 op_cost(5);
3030 format %{ %}
3031 interface(CONST_INTER);
3032 %}
3035 // Long Immediate
3036 operand immL()
3037 %{
3038 match(ConL);
3040 op_cost(20);
3041 format %{ %}
3042 interface(CONST_INTER);
3043 %}
3045 // Long Immediate 8-bit
3046 operand immL8()
3047 %{
3048 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3049 match(ConL);
3051 op_cost(5);
3052 format %{ %}
3053 interface(CONST_INTER);
3054 %}
3056 // Long Immediate 32-bit unsigned
3057 operand immUL32()
3058 %{
3059 predicate(n->get_long() == (unsigned int) (n->get_long()));
3060 match(ConL);
3062 op_cost(10);
3063 format %{ %}
3064 interface(CONST_INTER);
3065 %}
3067 // Long Immediate 32-bit signed
3068 operand immL32()
3069 %{
3070 predicate(n->get_long() == (int) (n->get_long()));
3071 match(ConL);
3073 op_cost(15);
3074 format %{ %}
3075 interface(CONST_INTER);
3076 %}
3078 // Long Immediate zero
3079 operand immL0()
3080 %{
3081 predicate(n->get_long() == 0L);
3082 match(ConL);
3084 op_cost(10);
3085 format %{ %}
3086 interface(CONST_INTER);
3087 %}
3089 // Constant for increment
3090 operand immL1()
3091 %{
3092 predicate(n->get_long() == 1);
3093 match(ConL);
3095 format %{ %}
3096 interface(CONST_INTER);
3097 %}
3099 // Constant for decrement
3100 operand immL_M1()
3101 %{
3102 predicate(n->get_long() == -1);
3103 match(ConL);
3105 format %{ %}
3106 interface(CONST_INTER);
3107 %}
3109 // Long Immediate: the value 10
3110 operand immL10()
3111 %{
3112 predicate(n->get_long() == 10);
3113 match(ConL);
3115 format %{ %}
3116 interface(CONST_INTER);
3117 %}
3119 // Long immediate from 0 to 127.
3120 // Used for a shorter form of long mul by 10.
3121 operand immL_127()
3122 %{
3123 predicate(0 <= n->get_long() && n->get_long() < 0x80);
3124 match(ConL);
3126 op_cost(10);
3127 format %{ %}
3128 interface(CONST_INTER);
3129 %}
3131 // Long Immediate: low 32-bit mask
3132 operand immL_32bits()
3133 %{
3134 predicate(n->get_long() == 0xFFFFFFFFL);
3135 match(ConL);
3136 op_cost(20);
3138 format %{ %}
3139 interface(CONST_INTER);
3140 %}
3142 // Float Immediate zero
3143 operand immF0()
3144 %{
3145 predicate(jint_cast(n->getf()) == 0);
3146 match(ConF);
3148 op_cost(5);
3149 format %{ %}
3150 interface(CONST_INTER);
3151 %}
3153 // Float Immediate
3154 operand immF()
3155 %{
3156 match(ConF);
3158 op_cost(15);
3159 format %{ %}
3160 interface(CONST_INTER);
3161 %}
3163 // Double Immediate zero
3164 operand immD0()
3165 %{
3166 predicate(jlong_cast(n->getd()) == 0);
3167 match(ConD);
3169 op_cost(5);
3170 format %{ %}
3171 interface(CONST_INTER);
3172 %}
3174 // Double Immediate
3175 operand immD()
3176 %{
3177 match(ConD);
3179 op_cost(15);
3180 format %{ %}
3181 interface(CONST_INTER);
3182 %}
3184 // Immediates for special shifts (sign extend)
3186 // Constants for increment
3187 operand immI_16()
3188 %{
3189 predicate(n->get_int() == 16);
3190 match(ConI);
3192 format %{ %}
3193 interface(CONST_INTER);
3194 %}
3196 operand immI_24()
3197 %{
3198 predicate(n->get_int() == 24);
3199 match(ConI);
3201 format %{ %}
3202 interface(CONST_INTER);
3203 %}
3205 // Constant for byte-wide masking
3206 operand immI_255()
3207 %{
3208 predicate(n->get_int() == 255);
3209 match(ConI);
3211 format %{ %}
3212 interface(CONST_INTER);
3213 %}
3215 // Constant for short-wide masking
3216 operand immI_65535()
3217 %{
3218 predicate(n->get_int() == 65535);
3219 match(ConI);
3221 format %{ %}
3222 interface(CONST_INTER);
3223 %}
3225 // Constant for byte-wide masking
3226 operand immL_255()
3227 %{
3228 predicate(n->get_long() == 255);
3229 match(ConL);
3231 format %{ %}
3232 interface(CONST_INTER);
3233 %}
3235 // Constant for short-wide masking
3236 operand immL_65535()
3237 %{
3238 predicate(n->get_long() == 65535);
3239 match(ConL);
3241 format %{ %}
3242 interface(CONST_INTER);
3243 %}
3245 // Register Operands
3246 // Integer Register
3247 operand rRegI()
3248 %{
3249 constraint(ALLOC_IN_RC(int_reg));
3250 match(RegI);
3252 match(rax_RegI);
3253 match(rbx_RegI);
3254 match(rcx_RegI);
3255 match(rdx_RegI);
3256 match(rdi_RegI);
3258 format %{ %}
3259 interface(REG_INTER);
3260 %}
3262 // Special Registers
3263 operand rax_RegI()
3264 %{
3265 constraint(ALLOC_IN_RC(int_rax_reg));
3266 match(RegI);
3267 match(rRegI);
3269 format %{ "RAX" %}
3270 interface(REG_INTER);
3271 %}
3273 // Special Registers
3274 operand rbx_RegI()
3275 %{
3276 constraint(ALLOC_IN_RC(int_rbx_reg));
3277 match(RegI);
3278 match(rRegI);
3280 format %{ "RBX" %}
3281 interface(REG_INTER);
3282 %}
3284 operand rcx_RegI()
3285 %{
3286 constraint(ALLOC_IN_RC(int_rcx_reg));
3287 match(RegI);
3288 match(rRegI);
3290 format %{ "RCX" %}
3291 interface(REG_INTER);
3292 %}
3294 operand rdx_RegI()
3295 %{
3296 constraint(ALLOC_IN_RC(int_rdx_reg));
3297 match(RegI);
3298 match(rRegI);
3300 format %{ "RDX" %}
3301 interface(REG_INTER);
3302 %}
3304 operand rdi_RegI()
3305 %{
3306 constraint(ALLOC_IN_RC(int_rdi_reg));
3307 match(RegI);
3308 match(rRegI);
3310 format %{ "RDI" %}
3311 interface(REG_INTER);
3312 %}
3314 operand no_rcx_RegI()
3315 %{
3316 constraint(ALLOC_IN_RC(int_no_rcx_reg));
3317 match(RegI);
3318 match(rax_RegI);
3319 match(rbx_RegI);
3320 match(rdx_RegI);
3321 match(rdi_RegI);
3323 format %{ %}
3324 interface(REG_INTER);
3325 %}
3327 operand no_rax_rdx_RegI()
3328 %{
3329 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg));
3330 match(RegI);
3331 match(rbx_RegI);
3332 match(rcx_RegI);
3333 match(rdi_RegI);
3335 format %{ %}
3336 interface(REG_INTER);
3337 %}
3339 // Pointer Register
3340 operand any_RegP()
3341 %{
3342 constraint(ALLOC_IN_RC(any_reg));
3343 match(RegP);
3344 match(rax_RegP);
3345 match(rbx_RegP);
3346 match(rdi_RegP);
3347 match(rsi_RegP);
3348 match(rbp_RegP);
3349 match(r15_RegP);
3350 match(rRegP);
3352 format %{ %}
3353 interface(REG_INTER);
3354 %}
3356 operand rRegP()
3357 %{
3358 constraint(ALLOC_IN_RC(ptr_reg));
3359 match(RegP);
3360 match(rax_RegP);
3361 match(rbx_RegP);
3362 match(rdi_RegP);
3363 match(rsi_RegP);
3364 match(rbp_RegP); // See Q&A below about
3365 match(r15_RegP); // r15_RegP and rbp_RegP.
3367 format %{ %}
3368 interface(REG_INTER);
3369 %}
3371 operand rRegN() %{
3372 constraint(ALLOC_IN_RC(int_reg));
3373 match(RegN);
3375 format %{ %}
3376 interface(REG_INTER);
3377 %}
3379 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
3380 // Answer: Operand match rules govern the DFA as it processes instruction inputs.
3381 // It's fine for an instruction input that expects rRegP to match a r15_RegP.
3382 // The output of an instruction is controlled by the allocator, which respects
3383 // register class masks, not match rules. Unless an instruction mentions
3384 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered
3385 // by the allocator as an input.
3386 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true,
3387 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a
3388 // result, RBP is not included in the output of the instruction either.
3390 operand no_rax_RegP()
3391 %{
3392 constraint(ALLOC_IN_RC(ptr_no_rax_reg));
3393 match(RegP);
3394 match(rbx_RegP);
3395 match(rsi_RegP);
3396 match(rdi_RegP);
3398 format %{ %}
3399 interface(REG_INTER);
3400 %}
3402 // This operand is not allowed to use RBP even if
3403 // RBP is not used to hold the frame pointer.
3404 operand no_rbp_RegP()
3405 %{
3406 constraint(ALLOC_IN_RC(ptr_reg_no_rbp));
3407 match(RegP);
3408 match(rbx_RegP);
3409 match(rsi_RegP);
3410 match(rdi_RegP);
3412 format %{ %}
3413 interface(REG_INTER);
3414 %}
3416 operand no_rax_rbx_RegP()
3417 %{
3418 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg));
3419 match(RegP);
3420 match(rsi_RegP);
3421 match(rdi_RegP);
3423 format %{ %}
3424 interface(REG_INTER);
3425 %}
3427 // Special Registers
3428 // Return a pointer value
3429 operand rax_RegP()
3430 %{
3431 constraint(ALLOC_IN_RC(ptr_rax_reg));
3432 match(RegP);
3433 match(rRegP);
3435 format %{ %}
3436 interface(REG_INTER);
3437 %}
3439 // Special Registers
3440 // Return a compressed pointer value
3441 operand rax_RegN()
3442 %{
3443 constraint(ALLOC_IN_RC(int_rax_reg));
3444 match(RegN);
3445 match(rRegN);
3447 format %{ %}
3448 interface(REG_INTER);
3449 %}
3451 // Used in AtomicAdd
3452 operand rbx_RegP()
3453 %{
3454 constraint(ALLOC_IN_RC(ptr_rbx_reg));
3455 match(RegP);
3456 match(rRegP);
3458 format %{ %}
3459 interface(REG_INTER);
3460 %}
3462 operand rsi_RegP()
3463 %{
3464 constraint(ALLOC_IN_RC(ptr_rsi_reg));
3465 match(RegP);
3466 match(rRegP);
3468 format %{ %}
3469 interface(REG_INTER);
3470 %}
3472 // Used in rep stosq
3473 operand rdi_RegP()
3474 %{
3475 constraint(ALLOC_IN_RC(ptr_rdi_reg));
3476 match(RegP);
3477 match(rRegP);
3479 format %{ %}
3480 interface(REG_INTER);
3481 %}
3483 operand r15_RegP()
3484 %{
3485 constraint(ALLOC_IN_RC(ptr_r15_reg));
3486 match(RegP);
3487 match(rRegP);
3489 format %{ %}
3490 interface(REG_INTER);
3491 %}
3493 operand rRegL()
3494 %{
3495 constraint(ALLOC_IN_RC(long_reg));
3496 match(RegL);
3497 match(rax_RegL);
3498 match(rdx_RegL);
3500 format %{ %}
3501 interface(REG_INTER);
3502 %}
3504 // Special Registers
3505 operand no_rax_rdx_RegL()
3506 %{
3507 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3508 match(RegL);
3509 match(rRegL);
3511 format %{ %}
3512 interface(REG_INTER);
3513 %}
3515 operand no_rax_RegL()
3516 %{
3517 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3518 match(RegL);
3519 match(rRegL);
3520 match(rdx_RegL);
3522 format %{ %}
3523 interface(REG_INTER);
3524 %}
3526 operand no_rcx_RegL()
3527 %{
3528 constraint(ALLOC_IN_RC(long_no_rcx_reg));
3529 match(RegL);
3530 match(rRegL);
3532 format %{ %}
3533 interface(REG_INTER);
3534 %}
3536 operand rax_RegL()
3537 %{
3538 constraint(ALLOC_IN_RC(long_rax_reg));
3539 match(RegL);
3540 match(rRegL);
3542 format %{ "RAX" %}
3543 interface(REG_INTER);
3544 %}
3546 operand rcx_RegL()
3547 %{
3548 constraint(ALLOC_IN_RC(long_rcx_reg));
3549 match(RegL);
3550 match(rRegL);
3552 format %{ %}
3553 interface(REG_INTER);
3554 %}
3556 operand rdx_RegL()
3557 %{
3558 constraint(ALLOC_IN_RC(long_rdx_reg));
3559 match(RegL);
3560 match(rRegL);
3562 format %{ %}
3563 interface(REG_INTER);
3564 %}
3566 // Flags register, used as output of compare instructions
3567 operand rFlagsReg()
3568 %{
3569 constraint(ALLOC_IN_RC(int_flags));
3570 match(RegFlags);
3572 format %{ "RFLAGS" %}
3573 interface(REG_INTER);
3574 %}
3576 // Flags register, used as output of FLOATING POINT compare instructions
3577 operand rFlagsRegU()
3578 %{
3579 constraint(ALLOC_IN_RC(int_flags));
3580 match(RegFlags);
3582 format %{ "RFLAGS_U" %}
3583 interface(REG_INTER);
3584 %}
3586 operand rFlagsRegUCF() %{
3587 constraint(ALLOC_IN_RC(int_flags));
3588 match(RegFlags);
3589 predicate(false);
3591 format %{ "RFLAGS_U_CF" %}
3592 interface(REG_INTER);
3593 %}
3595 // Float register operands
3596 operand regF()
3597 %{
3598 constraint(ALLOC_IN_RC(float_reg));
3599 match(RegF);
3601 format %{ %}
3602 interface(REG_INTER);
3603 %}
3605 // Double register operands
3606 operand regD()
3607 %{
3608 constraint(ALLOC_IN_RC(double_reg));
3609 match(RegD);
3611 format %{ %}
3612 interface(REG_INTER);
3613 %}
3615 //----------Memory Operands----------------------------------------------------
3616 // Direct Memory Operand
3617 // operand direct(immP addr)
3618 // %{
3619 // match(addr);
3621 // format %{ "[$addr]" %}
3622 // interface(MEMORY_INTER) %{
3623 // base(0xFFFFFFFF);
3624 // index(0x4);
3625 // scale(0x0);
3626 // disp($addr);
3627 // %}
3628 // %}
3630 // Indirect Memory Operand
3631 operand indirect(any_RegP reg)
3632 %{
3633 constraint(ALLOC_IN_RC(ptr_reg));
3634 match(reg);
3636 format %{ "[$reg]" %}
3637 interface(MEMORY_INTER) %{
3638 base($reg);
3639 index(0x4);
3640 scale(0x0);
3641 disp(0x0);
3642 %}
3643 %}
3645 // Indirect Memory Plus Short Offset Operand
3646 operand indOffset8(any_RegP reg, immL8 off)
3647 %{
3648 constraint(ALLOC_IN_RC(ptr_reg));
3649 match(AddP reg off);
3651 format %{ "[$reg + $off (8-bit)]" %}
3652 interface(MEMORY_INTER) %{
3653 base($reg);
3654 index(0x4);
3655 scale(0x0);
3656 disp($off);
3657 %}
3658 %}
3660 // Indirect Memory Plus Long Offset Operand
3661 operand indOffset32(any_RegP reg, immL32 off)
3662 %{
3663 constraint(ALLOC_IN_RC(ptr_reg));
3664 match(AddP reg off);
3666 format %{ "[$reg + $off (32-bit)]" %}
3667 interface(MEMORY_INTER) %{
3668 base($reg);
3669 index(0x4);
3670 scale(0x0);
3671 disp($off);
3672 %}
3673 %}
3675 // Indirect Memory Plus Index Register Plus Offset Operand
3676 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off)
3677 %{
3678 constraint(ALLOC_IN_RC(ptr_reg));
3679 match(AddP (AddP reg lreg) off);
3681 op_cost(10);
3682 format %{"[$reg + $off + $lreg]" %}
3683 interface(MEMORY_INTER) %{
3684 base($reg);
3685 index($lreg);
3686 scale(0x0);
3687 disp($off);
3688 %}
3689 %}
3691 // Indirect Memory Plus Index Register Plus Offset Operand
3692 operand indIndex(any_RegP reg, rRegL lreg)
3693 %{
3694 constraint(ALLOC_IN_RC(ptr_reg));
3695 match(AddP reg lreg);
3697 op_cost(10);
3698 format %{"[$reg + $lreg]" %}
3699 interface(MEMORY_INTER) %{
3700 base($reg);
3701 index($lreg);
3702 scale(0x0);
3703 disp(0x0);
3704 %}
3705 %}
3707 // Indirect Memory Times Scale Plus Index Register
3708 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale)
3709 %{
3710 constraint(ALLOC_IN_RC(ptr_reg));
3711 match(AddP reg (LShiftL lreg scale));
3713 op_cost(10);
3714 format %{"[$reg + $lreg << $scale]" %}
3715 interface(MEMORY_INTER) %{
3716 base($reg);
3717 index($lreg);
3718 scale($scale);
3719 disp(0x0);
3720 %}
3721 %}
3723 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
3724 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
3725 %{
3726 constraint(ALLOC_IN_RC(ptr_reg));
3727 match(AddP (AddP reg (LShiftL lreg scale)) off);
3729 op_cost(10);
3730 format %{"[$reg + $off + $lreg << $scale]" %}
3731 interface(MEMORY_INTER) %{
3732 base($reg);
3733 index($lreg);
3734 scale($scale);
3735 disp($off);
3736 %}
3737 %}
3739 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
3740 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale)
3741 %{
3742 constraint(ALLOC_IN_RC(ptr_reg));
3743 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
3744 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off);
3746 op_cost(10);
3747 format %{"[$reg + $off + $idx << $scale]" %}
3748 interface(MEMORY_INTER) %{
3749 base($reg);
3750 index($idx);
3751 scale($scale);
3752 disp($off);
3753 %}
3754 %}
3756 // Indirect Narrow Oop Plus Offset Operand
3757 // Note: x86 architecture doesn't support "scale * index + offset" without a base
3758 // we can't free r12 even with Universe::narrow_oop_base() == NULL.
3759 operand indCompressedOopOffset(rRegN reg, immL32 off) %{
3760 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8));
3761 constraint(ALLOC_IN_RC(ptr_reg));
3762 match(AddP (DecodeN reg) off);
3764 op_cost(10);
3765 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
3766 interface(MEMORY_INTER) %{
3767 base(0xc); // R12
3768 index($reg);
3769 scale(0x3);
3770 disp($off);
3771 %}
3772 %}
3774 // Indirect Memory Operand
3775 operand indirectNarrow(rRegN reg)
3776 %{
3777 predicate(Universe::narrow_oop_shift() == 0);
3778 constraint(ALLOC_IN_RC(ptr_reg));
3779 match(DecodeN reg);
3781 format %{ "[$reg]" %}
3782 interface(MEMORY_INTER) %{
3783 base($reg);
3784 index(0x4);
3785 scale(0x0);
3786 disp(0x0);
3787 %}
3788 %}
3790 // Indirect Memory Plus Short Offset Operand
3791 operand indOffset8Narrow(rRegN reg, immL8 off)
3792 %{
3793 predicate(Universe::narrow_oop_shift() == 0);
3794 constraint(ALLOC_IN_RC(ptr_reg));
3795 match(AddP (DecodeN reg) off);
3797 format %{ "[$reg + $off (8-bit)]" %}
3798 interface(MEMORY_INTER) %{
3799 base($reg);
3800 index(0x4);
3801 scale(0x0);
3802 disp($off);
3803 %}
3804 %}
3806 // Indirect Memory Plus Long Offset Operand
3807 operand indOffset32Narrow(rRegN reg, immL32 off)
3808 %{
3809 predicate(Universe::narrow_oop_shift() == 0);
3810 constraint(ALLOC_IN_RC(ptr_reg));
3811 match(AddP (DecodeN reg) off);
3813 format %{ "[$reg + $off (32-bit)]" %}
3814 interface(MEMORY_INTER) %{
3815 base($reg);
3816 index(0x4);
3817 scale(0x0);
3818 disp($off);
3819 %}
3820 %}
3822 // Indirect Memory Plus Index Register Plus Offset Operand
3823 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off)
3824 %{
3825 predicate(Universe::narrow_oop_shift() == 0);
3826 constraint(ALLOC_IN_RC(ptr_reg));
3827 match(AddP (AddP (DecodeN reg) lreg) off);
3829 op_cost(10);
3830 format %{"[$reg + $off + $lreg]" %}
3831 interface(MEMORY_INTER) %{
3832 base($reg);
3833 index($lreg);
3834 scale(0x0);
3835 disp($off);
3836 %}
3837 %}
3839 // Indirect Memory Plus Index Register Plus Offset Operand
3840 operand indIndexNarrow(rRegN reg, rRegL lreg)
3841 %{
3842 predicate(Universe::narrow_oop_shift() == 0);
3843 constraint(ALLOC_IN_RC(ptr_reg));
3844 match(AddP (DecodeN reg) lreg);
3846 op_cost(10);
3847 format %{"[$reg + $lreg]" %}
3848 interface(MEMORY_INTER) %{
3849 base($reg);
3850 index($lreg);
3851 scale(0x0);
3852 disp(0x0);
3853 %}
3854 %}
3856 // Indirect Memory Times Scale Plus Index Register
3857 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale)
3858 %{
3859 predicate(Universe::narrow_oop_shift() == 0);
3860 constraint(ALLOC_IN_RC(ptr_reg));
3861 match(AddP (DecodeN reg) (LShiftL lreg scale));
3863 op_cost(10);
3864 format %{"[$reg + $lreg << $scale]" %}
3865 interface(MEMORY_INTER) %{
3866 base($reg);
3867 index($lreg);
3868 scale($scale);
3869 disp(0x0);
3870 %}
3871 %}
3873 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
3874 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
3875 %{
3876 predicate(Universe::narrow_oop_shift() == 0);
3877 constraint(ALLOC_IN_RC(ptr_reg));
3878 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
3880 op_cost(10);
3881 format %{"[$reg + $off + $lreg << $scale]" %}
3882 interface(MEMORY_INTER) %{
3883 base($reg);
3884 index($lreg);
3885 scale($scale);
3886 disp($off);
3887 %}
3888 %}
3890 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
3891 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
3892 %{
3893 constraint(ALLOC_IN_RC(ptr_reg));
3894 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
3895 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
3897 op_cost(10);
3898 format %{"[$reg + $off + $idx << $scale]" %}
3899 interface(MEMORY_INTER) %{
3900 base($reg);
3901 index($idx);
3902 scale($scale);
3903 disp($off);
3904 %}
3905 %}
3907 //----------Special Memory Operands--------------------------------------------
3908 // Stack Slot Operand - This operand is used for loading and storing temporary
3909 // values on the stack where a match requires a value to
3910 // flow through memory.
3911 operand stackSlotP(sRegP reg)
3912 %{
3913 constraint(ALLOC_IN_RC(stack_slots));
3914 // No match rule because this operand is only generated in matching
3916 format %{ "[$reg]" %}
3917 interface(MEMORY_INTER) %{
3918 base(0x4); // RSP
3919 index(0x4); // No Index
3920 scale(0x0); // No Scale
3921 disp($reg); // Stack Offset
3922 %}
3923 %}
3925 operand stackSlotI(sRegI reg)
3926 %{
3927 constraint(ALLOC_IN_RC(stack_slots));
3928 // No match rule because this operand is only generated in matching
3930 format %{ "[$reg]" %}
3931 interface(MEMORY_INTER) %{
3932 base(0x4); // RSP
3933 index(0x4); // No Index
3934 scale(0x0); // No Scale
3935 disp($reg); // Stack Offset
3936 %}
3937 %}
3939 operand stackSlotF(sRegF reg)
3940 %{
3941 constraint(ALLOC_IN_RC(stack_slots));
3942 // No match rule because this operand is only generated in matching
3944 format %{ "[$reg]" %}
3945 interface(MEMORY_INTER) %{
3946 base(0x4); // RSP
3947 index(0x4); // No Index
3948 scale(0x0); // No Scale
3949 disp($reg); // Stack Offset
3950 %}
3951 %}
3953 operand stackSlotD(sRegD reg)
3954 %{
3955 constraint(ALLOC_IN_RC(stack_slots));
3956 // No match rule because this operand is only generated in matching
3958 format %{ "[$reg]" %}
3959 interface(MEMORY_INTER) %{
3960 base(0x4); // RSP
3961 index(0x4); // No Index
3962 scale(0x0); // No Scale
3963 disp($reg); // Stack Offset
3964 %}
3965 %}
3966 operand stackSlotL(sRegL reg)
3967 %{
3968 constraint(ALLOC_IN_RC(stack_slots));
3969 // No match rule because this operand is only generated in matching
3971 format %{ "[$reg]" %}
3972 interface(MEMORY_INTER) %{
3973 base(0x4); // RSP
3974 index(0x4); // No Index
3975 scale(0x0); // No Scale
3976 disp($reg); // Stack Offset
3977 %}
3978 %}
3980 //----------Conditional Branch Operands----------------------------------------
3981 // Comparison Op - This is the operation of the comparison, and is limited to
3982 // the following set of codes:
3983 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
3984 //
3985 // Other attributes of the comparison, such as unsignedness, are specified
3986 // by the comparison instruction that sets a condition code flags register.
3987 // That result is represented by a flags operand whose subtype is appropriate
3988 // to the unsignedness (etc.) of the comparison.
3989 //
3990 // Later, the instruction which matches both the Comparison Op (a Bool) and
3991 // the flags (produced by the Cmp) specifies the coding of the comparison op
3992 // by matching a specific subtype of Bool operand below, such as cmpOpU.
3994 // Comparision Code
3995 operand cmpOp()
3996 %{
3997 match(Bool);
3999 format %{ "" %}
4000 interface(COND_INTER) %{
4001 equal(0x4, "e");
4002 not_equal(0x5, "ne");
4003 less(0xC, "l");
4004 greater_equal(0xD, "ge");
4005 less_equal(0xE, "le");
4006 greater(0xF, "g");
4007 overflow(0x0, "o");
4008 no_overflow(0x1, "no");
4009 %}
4010 %}
4012 // Comparison Code, unsigned compare. Used by FP also, with
4013 // C2 (unordered) turned into GT or LT already. The other bits
4014 // C0 and C3 are turned into Carry & Zero flags.
4015 operand cmpOpU()
4016 %{
4017 match(Bool);
4019 format %{ "" %}
4020 interface(COND_INTER) %{
4021 equal(0x4, "e");
4022 not_equal(0x5, "ne");
4023 less(0x2, "b");
4024 greater_equal(0x3, "nb");
4025 less_equal(0x6, "be");
4026 greater(0x7, "nbe");
4027 overflow(0x0, "o");
4028 no_overflow(0x1, "no");
4029 %}
4030 %}
4033 // Floating comparisons that don't require any fixup for the unordered case
4034 operand cmpOpUCF() %{
4035 match(Bool);
4036 predicate(n->as_Bool()->_test._test == BoolTest::lt ||
4037 n->as_Bool()->_test._test == BoolTest::ge ||
4038 n->as_Bool()->_test._test == BoolTest::le ||
4039 n->as_Bool()->_test._test == BoolTest::gt);
4040 format %{ "" %}
4041 interface(COND_INTER) %{
4042 equal(0x4, "e");
4043 not_equal(0x5, "ne");
4044 less(0x2, "b");
4045 greater_equal(0x3, "nb");
4046 less_equal(0x6, "be");
4047 greater(0x7, "nbe");
4048 overflow(0x0, "o");
4049 no_overflow(0x1, "no");
4050 %}
4051 %}
4054 // Floating comparisons that can be fixed up with extra conditional jumps
4055 operand cmpOpUCF2() %{
4056 match(Bool);
4057 predicate(n->as_Bool()->_test._test == BoolTest::ne ||
4058 n->as_Bool()->_test._test == BoolTest::eq);
4059 format %{ "" %}
4060 interface(COND_INTER) %{
4061 equal(0x4, "e");
4062 not_equal(0x5, "ne");
4063 less(0x2, "b");
4064 greater_equal(0x3, "nb");
4065 less_equal(0x6, "be");
4066 greater(0x7, "nbe");
4067 overflow(0x0, "o");
4068 no_overflow(0x1, "no");
4069 %}
4070 %}
4073 //----------OPERAND CLASSES----------------------------------------------------
4074 // Operand Classes are groups of operands that are used as to simplify
4075 // instruction definitions by not requiring the AD writer to specify separate
4076 // instructions for every form of operand when the instruction accepts
4077 // multiple operand types with the same basic encoding and format. The classic
4078 // case of this is memory operands.
4080 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
4081 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
4082 indCompressedOopOffset,
4083 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
4084 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
4085 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow);
4087 //----------PIPELINE-----------------------------------------------------------
4088 // Rules which define the behavior of the target architectures pipeline.
4089 pipeline %{
4091 //----------ATTRIBUTES---------------------------------------------------------
4092 attributes %{
4093 variable_size_instructions; // Fixed size instructions
4094 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
4095 instruction_unit_size = 1; // An instruction is 1 bytes long
4096 instruction_fetch_unit_size = 16; // The processor fetches one line
4097 instruction_fetch_units = 1; // of 16 bytes
4099 // List of nop instructions
4100 nops( MachNop );
4101 %}
4103 //----------RESOURCES----------------------------------------------------------
4104 // Resources are the functional units available to the machine
4106 // Generic P2/P3 pipeline
4107 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of
4108 // 3 instructions decoded per cycle.
4109 // 2 load/store ops per cycle, 1 branch, 1 FPU,
4110 // 3 ALU op, only ALU0 handles mul instructions.
4111 resources( D0, D1, D2, DECODE = D0 | D1 | D2,
4112 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2,
4113 BR, FPU,
4114 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2);
4116 //----------PIPELINE DESCRIPTION-----------------------------------------------
4117 // Pipeline Description specifies the stages in the machine's pipeline
4119 // Generic P2/P3 pipeline
4120 pipe_desc(S0, S1, S2, S3, S4, S5);
4122 //----------PIPELINE CLASSES---------------------------------------------------
4123 // Pipeline Classes describe the stages in which input and output are
4124 // referenced by the hardware pipeline.
4126 // Naming convention: ialu or fpu
4127 // Then: _reg
4128 // Then: _reg if there is a 2nd register
4129 // Then: _long if it's a pair of instructions implementing a long
4130 // Then: _fat if it requires the big decoder
4131 // Or: _mem if it requires the big decoder and a memory unit.
4133 // Integer ALU reg operation
4134 pipe_class ialu_reg(rRegI dst)
4135 %{
4136 single_instruction;
4137 dst : S4(write);
4138 dst : S3(read);
4139 DECODE : S0; // any decoder
4140 ALU : S3; // any alu
4141 %}
4143 // Long ALU reg operation
4144 pipe_class ialu_reg_long(rRegL dst)
4145 %{
4146 instruction_count(2);
4147 dst : S4(write);
4148 dst : S3(read);
4149 DECODE : S0(2); // any 2 decoders
4150 ALU : S3(2); // both alus
4151 %}
4153 // Integer ALU reg operation using big decoder
4154 pipe_class ialu_reg_fat(rRegI dst)
4155 %{
4156 single_instruction;
4157 dst : S4(write);
4158 dst : S3(read);
4159 D0 : S0; // big decoder only
4160 ALU : S3; // any alu
4161 %}
4163 // Long ALU reg operation using big decoder
4164 pipe_class ialu_reg_long_fat(rRegL dst)
4165 %{
4166 instruction_count(2);
4167 dst : S4(write);
4168 dst : S3(read);
4169 D0 : S0(2); // big decoder only; twice
4170 ALU : S3(2); // any 2 alus
4171 %}
4173 // Integer ALU reg-reg operation
4174 pipe_class ialu_reg_reg(rRegI dst, rRegI src)
4175 %{
4176 single_instruction;
4177 dst : S4(write);
4178 src : S3(read);
4179 DECODE : S0; // any decoder
4180 ALU : S3; // any alu
4181 %}
4183 // Long ALU reg-reg operation
4184 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src)
4185 %{
4186 instruction_count(2);
4187 dst : S4(write);
4188 src : S3(read);
4189 DECODE : S0(2); // any 2 decoders
4190 ALU : S3(2); // both alus
4191 %}
4193 // Integer ALU reg-reg operation
4194 pipe_class ialu_reg_reg_fat(rRegI dst, memory src)
4195 %{
4196 single_instruction;
4197 dst : S4(write);
4198 src : S3(read);
4199 D0 : S0; // big decoder only
4200 ALU : S3; // any alu
4201 %}
4203 // Long ALU reg-reg operation
4204 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src)
4205 %{
4206 instruction_count(2);
4207 dst : S4(write);
4208 src : S3(read);
4209 D0 : S0(2); // big decoder only; twice
4210 ALU : S3(2); // both alus
4211 %}
4213 // Integer ALU reg-mem operation
4214 pipe_class ialu_reg_mem(rRegI dst, memory mem)
4215 %{
4216 single_instruction;
4217 dst : S5(write);
4218 mem : S3(read);
4219 D0 : S0; // big decoder only
4220 ALU : S4; // any alu
4221 MEM : S3; // any mem
4222 %}
4224 // Integer mem operation (prefetch)
4225 pipe_class ialu_mem(memory mem)
4226 %{
4227 single_instruction;
4228 mem : S3(read);
4229 D0 : S0; // big decoder only
4230 MEM : S3; // any mem
4231 %}
4233 // Integer Store to Memory
4234 pipe_class ialu_mem_reg(memory mem, rRegI src)
4235 %{
4236 single_instruction;
4237 mem : S3(read);
4238 src : S5(read);
4239 D0 : S0; // big decoder only
4240 ALU : S4; // any alu
4241 MEM : S3;
4242 %}
4244 // // Long Store to Memory
4245 // pipe_class ialu_mem_long_reg(memory mem, rRegL src)
4246 // %{
4247 // instruction_count(2);
4248 // mem : S3(read);
4249 // src : S5(read);
4250 // D0 : S0(2); // big decoder only; twice
4251 // ALU : S4(2); // any 2 alus
4252 // MEM : S3(2); // Both mems
4253 // %}
4255 // Integer Store to Memory
4256 pipe_class ialu_mem_imm(memory mem)
4257 %{
4258 single_instruction;
4259 mem : S3(read);
4260 D0 : S0; // big decoder only
4261 ALU : S4; // any alu
4262 MEM : S3;
4263 %}
4265 // Integer ALU0 reg-reg operation
4266 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src)
4267 %{
4268 single_instruction;
4269 dst : S4(write);
4270 src : S3(read);
4271 D0 : S0; // Big decoder only
4272 ALU0 : S3; // only alu0
4273 %}
4275 // Integer ALU0 reg-mem operation
4276 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem)
4277 %{
4278 single_instruction;
4279 dst : S5(write);
4280 mem : S3(read);
4281 D0 : S0; // big decoder only
4282 ALU0 : S4; // ALU0 only
4283 MEM : S3; // any mem
4284 %}
4286 // Integer ALU reg-reg operation
4287 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2)
4288 %{
4289 single_instruction;
4290 cr : S4(write);
4291 src1 : S3(read);
4292 src2 : S3(read);
4293 DECODE : S0; // any decoder
4294 ALU : S3; // any alu
4295 %}
4297 // Integer ALU reg-imm operation
4298 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1)
4299 %{
4300 single_instruction;
4301 cr : S4(write);
4302 src1 : S3(read);
4303 DECODE : S0; // any decoder
4304 ALU : S3; // any alu
4305 %}
4307 // Integer ALU reg-mem operation
4308 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2)
4309 %{
4310 single_instruction;
4311 cr : S4(write);
4312 src1 : S3(read);
4313 src2 : S3(read);
4314 D0 : S0; // big decoder only
4315 ALU : S4; // any alu
4316 MEM : S3;
4317 %}
4319 // Conditional move reg-reg
4320 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y)
4321 %{
4322 instruction_count(4);
4323 y : S4(read);
4324 q : S3(read);
4325 p : S3(read);
4326 DECODE : S0(4); // any decoder
4327 %}
4329 // Conditional move reg-reg
4330 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr)
4331 %{
4332 single_instruction;
4333 dst : S4(write);
4334 src : S3(read);
4335 cr : S3(read);
4336 DECODE : S0; // any decoder
4337 %}
4339 // Conditional move reg-mem
4340 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src)
4341 %{
4342 single_instruction;
4343 dst : S4(write);
4344 src : S3(read);
4345 cr : S3(read);
4346 DECODE : S0; // any decoder
4347 MEM : S3;
4348 %}
4350 // Conditional move reg-reg long
4351 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src)
4352 %{
4353 single_instruction;
4354 dst : S4(write);
4355 src : S3(read);
4356 cr : S3(read);
4357 DECODE : S0(2); // any 2 decoders
4358 %}
4360 // XXX
4361 // // Conditional move double reg-reg
4362 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src)
4363 // %{
4364 // single_instruction;
4365 // dst : S4(write);
4366 // src : S3(read);
4367 // cr : S3(read);
4368 // DECODE : S0; // any decoder
4369 // %}
4371 // Float reg-reg operation
4372 pipe_class fpu_reg(regD dst)
4373 %{
4374 instruction_count(2);
4375 dst : S3(read);
4376 DECODE : S0(2); // any 2 decoders
4377 FPU : S3;
4378 %}
4380 // Float reg-reg operation
4381 pipe_class fpu_reg_reg(regD dst, regD src)
4382 %{
4383 instruction_count(2);
4384 dst : S4(write);
4385 src : S3(read);
4386 DECODE : S0(2); // any 2 decoders
4387 FPU : S3;
4388 %}
4390 // Float reg-reg operation
4391 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2)
4392 %{
4393 instruction_count(3);
4394 dst : S4(write);
4395 src1 : S3(read);
4396 src2 : S3(read);
4397 DECODE : S0(3); // any 3 decoders
4398 FPU : S3(2);
4399 %}
4401 // Float reg-reg operation
4402 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3)
4403 %{
4404 instruction_count(4);
4405 dst : S4(write);
4406 src1 : S3(read);
4407 src2 : S3(read);
4408 src3 : S3(read);
4409 DECODE : S0(4); // any 3 decoders
4410 FPU : S3(2);
4411 %}
4413 // Float reg-reg operation
4414 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3)
4415 %{
4416 instruction_count(4);
4417 dst : S4(write);
4418 src1 : S3(read);
4419 src2 : S3(read);
4420 src3 : S3(read);
4421 DECODE : S1(3); // any 3 decoders
4422 D0 : S0; // Big decoder only
4423 FPU : S3(2);
4424 MEM : S3;
4425 %}
4427 // Float reg-mem operation
4428 pipe_class fpu_reg_mem(regD dst, memory mem)
4429 %{
4430 instruction_count(2);
4431 dst : S5(write);
4432 mem : S3(read);
4433 D0 : S0; // big decoder only
4434 DECODE : S1; // any decoder for FPU POP
4435 FPU : S4;
4436 MEM : S3; // any mem
4437 %}
4439 // Float reg-mem operation
4440 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem)
4441 %{
4442 instruction_count(3);
4443 dst : S5(write);
4444 src1 : S3(read);
4445 mem : S3(read);
4446 D0 : S0; // big decoder only
4447 DECODE : S1(2); // any decoder for FPU POP
4448 FPU : S4;
4449 MEM : S3; // any mem
4450 %}
4452 // Float mem-reg operation
4453 pipe_class fpu_mem_reg(memory mem, regD src)
4454 %{
4455 instruction_count(2);
4456 src : S5(read);
4457 mem : S3(read);
4458 DECODE : S0; // any decoder for FPU PUSH
4459 D0 : S1; // big decoder only
4460 FPU : S4;
4461 MEM : S3; // any mem
4462 %}
4464 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2)
4465 %{
4466 instruction_count(3);
4467 src1 : S3(read);
4468 src2 : S3(read);
4469 mem : S3(read);
4470 DECODE : S0(2); // any decoder for FPU PUSH
4471 D0 : S1; // big decoder only
4472 FPU : S4;
4473 MEM : S3; // any mem
4474 %}
4476 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2)
4477 %{
4478 instruction_count(3);
4479 src1 : S3(read);
4480 src2 : S3(read);
4481 mem : S4(read);
4482 DECODE : S0; // any decoder for FPU PUSH
4483 D0 : S0(2); // big decoder only
4484 FPU : S4;
4485 MEM : S3(2); // any mem
4486 %}
4488 pipe_class fpu_mem_mem(memory dst, memory src1)
4489 %{
4490 instruction_count(2);
4491 src1 : S3(read);
4492 dst : S4(read);
4493 D0 : S0(2); // big decoder only
4494 MEM : S3(2); // any mem
4495 %}
4497 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2)
4498 %{
4499 instruction_count(3);
4500 src1 : S3(read);
4501 src2 : S3(read);
4502 dst : S4(read);
4503 D0 : S0(3); // big decoder only
4504 FPU : S4;
4505 MEM : S3(3); // any mem
4506 %}
4508 pipe_class fpu_mem_reg_con(memory mem, regD src1)
4509 %{
4510 instruction_count(3);
4511 src1 : S4(read);
4512 mem : S4(read);
4513 DECODE : S0; // any decoder for FPU PUSH
4514 D0 : S0(2); // big decoder only
4515 FPU : S4;
4516 MEM : S3(2); // any mem
4517 %}
4519 // Float load constant
4520 pipe_class fpu_reg_con(regD dst)
4521 %{
4522 instruction_count(2);
4523 dst : S5(write);
4524 D0 : S0; // big decoder only for the load
4525 DECODE : S1; // any decoder for FPU POP
4526 FPU : S4;
4527 MEM : S3; // any mem
4528 %}
4530 // Float load constant
4531 pipe_class fpu_reg_reg_con(regD dst, regD src)
4532 %{
4533 instruction_count(3);
4534 dst : S5(write);
4535 src : S3(read);
4536 D0 : S0; // big decoder only for the load
4537 DECODE : S1(2); // any decoder for FPU POP
4538 FPU : S4;
4539 MEM : S3; // any mem
4540 %}
4542 // UnConditional branch
4543 pipe_class pipe_jmp(label labl)
4544 %{
4545 single_instruction;
4546 BR : S3;
4547 %}
4549 // Conditional branch
4550 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl)
4551 %{
4552 single_instruction;
4553 cr : S1(read);
4554 BR : S3;
4555 %}
4557 // Allocation idiom
4558 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr)
4559 %{
4560 instruction_count(1); force_serialization;
4561 fixed_latency(6);
4562 heap_ptr : S3(read);
4563 DECODE : S0(3);
4564 D0 : S2;
4565 MEM : S3;
4566 ALU : S3(2);
4567 dst : S5(write);
4568 BR : S5;
4569 %}
4571 // Generic big/slow expanded idiom
4572 pipe_class pipe_slow()
4573 %{
4574 instruction_count(10); multiple_bundles; force_serialization;
4575 fixed_latency(100);
4576 D0 : S0(2);
4577 MEM : S3(2);
4578 %}
4580 // The real do-nothing guy
4581 pipe_class empty()
4582 %{
4583 instruction_count(0);
4584 %}
4586 // Define the class for the Nop node
4587 define
4588 %{
4589 MachNop = empty;
4590 %}
4592 %}
4594 //----------INSTRUCTIONS-------------------------------------------------------
4595 //
4596 // match -- States which machine-independent subtree may be replaced
4597 // by this instruction.
4598 // ins_cost -- The estimated cost of this instruction is used by instruction
4599 // selection to identify a minimum cost tree of machine
4600 // instructions that matches a tree of machine-independent
4601 // instructions.
4602 // format -- A string providing the disassembly for this instruction.
4603 // The value of an instruction's operand may be inserted
4604 // by referring to it with a '$' prefix.
4605 // opcode -- Three instruction opcodes may be provided. These are referred
4606 // to within an encode class as $primary, $secondary, and $tertiary
4607 // rrspectively. The primary opcode is commonly used to
4608 // indicate the type of machine instruction, while secondary
4609 // and tertiary are often used for prefix options or addressing
4610 // modes.
4611 // ins_encode -- A list of encode classes with parameters. The encode class
4612 // name must have been defined in an 'enc_class' specification
4613 // in the encode section of the architecture description.
4616 //----------Load/Store/Move Instructions---------------------------------------
4617 //----------Load Instructions--------------------------------------------------
4619 // Load Byte (8 bit signed)
4620 instruct loadB(rRegI dst, memory mem)
4621 %{
4622 match(Set dst (LoadB mem));
4624 ins_cost(125);
4625 format %{ "movsbl $dst, $mem\t# byte" %}
4627 ins_encode %{
4628 __ movsbl($dst$$Register, $mem$$Address);
4629 %}
4631 ins_pipe(ialu_reg_mem);
4632 %}
4634 // Load Byte (8 bit signed) into Long Register
4635 instruct loadB2L(rRegL dst, memory mem)
4636 %{
4637 match(Set dst (ConvI2L (LoadB mem)));
4639 ins_cost(125);
4640 format %{ "movsbq $dst, $mem\t# byte -> long" %}
4642 ins_encode %{
4643 __ movsbq($dst$$Register, $mem$$Address);
4644 %}
4646 ins_pipe(ialu_reg_mem);
4647 %}
4649 // Load Unsigned Byte (8 bit UNsigned)
4650 instruct loadUB(rRegI dst, memory mem)
4651 %{
4652 match(Set dst (LoadUB mem));
4654 ins_cost(125);
4655 format %{ "movzbl $dst, $mem\t# ubyte" %}
4657 ins_encode %{
4658 __ movzbl($dst$$Register, $mem$$Address);
4659 %}
4661 ins_pipe(ialu_reg_mem);
4662 %}
4664 // Load Unsigned Byte (8 bit UNsigned) into Long Register
4665 instruct loadUB2L(rRegL dst, memory mem)
4666 %{
4667 match(Set dst (ConvI2L (LoadUB mem)));
4669 ins_cost(125);
4670 format %{ "movzbq $dst, $mem\t# ubyte -> long" %}
4672 ins_encode %{
4673 __ movzbq($dst$$Register, $mem$$Address);
4674 %}
4676 ins_pipe(ialu_reg_mem);
4677 %}
4679 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register
4680 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{
4681 match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
4682 effect(KILL cr);
4684 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t"
4685 "andl $dst, $mask" %}
4686 ins_encode %{
4687 Register Rdst = $dst$$Register;
4688 __ movzbq(Rdst, $mem$$Address);
4689 __ andl(Rdst, $mask$$constant);
4690 %}
4691 ins_pipe(ialu_reg_mem);
4692 %}
4694 // Load Short (16 bit signed)
4695 instruct loadS(rRegI dst, memory mem)
4696 %{
4697 match(Set dst (LoadS mem));
4699 ins_cost(125);
4700 format %{ "movswl $dst, $mem\t# short" %}
4702 ins_encode %{
4703 __ movswl($dst$$Register, $mem$$Address);
4704 %}
4706 ins_pipe(ialu_reg_mem);
4707 %}
4709 // Load Short (16 bit signed) to Byte (8 bit signed)
4710 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4711 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
4713 ins_cost(125);
4714 format %{ "movsbl $dst, $mem\t# short -> byte" %}
4715 ins_encode %{
4716 __ movsbl($dst$$Register, $mem$$Address);
4717 %}
4718 ins_pipe(ialu_reg_mem);
4719 %}
4721 // Load Short (16 bit signed) into Long Register
4722 instruct loadS2L(rRegL dst, memory mem)
4723 %{
4724 match(Set dst (ConvI2L (LoadS mem)));
4726 ins_cost(125);
4727 format %{ "movswq $dst, $mem\t# short -> long" %}
4729 ins_encode %{
4730 __ movswq($dst$$Register, $mem$$Address);
4731 %}
4733 ins_pipe(ialu_reg_mem);
4734 %}
4736 // Load Unsigned Short/Char (16 bit UNsigned)
4737 instruct loadUS(rRegI dst, memory mem)
4738 %{
4739 match(Set dst (LoadUS mem));
4741 ins_cost(125);
4742 format %{ "movzwl $dst, $mem\t# ushort/char" %}
4744 ins_encode %{
4745 __ movzwl($dst$$Register, $mem$$Address);
4746 %}
4748 ins_pipe(ialu_reg_mem);
4749 %}
4751 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
4752 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4753 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
4755 ins_cost(125);
4756 format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
4757 ins_encode %{
4758 __ movsbl($dst$$Register, $mem$$Address);
4759 %}
4760 ins_pipe(ialu_reg_mem);
4761 %}
4763 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
4764 instruct loadUS2L(rRegL dst, memory mem)
4765 %{
4766 match(Set dst (ConvI2L (LoadUS mem)));
4768 ins_cost(125);
4769 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %}
4771 ins_encode %{
4772 __ movzwq($dst$$Register, $mem$$Address);
4773 %}
4775 ins_pipe(ialu_reg_mem);
4776 %}
4778 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register
4779 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
4780 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4782 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %}
4783 ins_encode %{
4784 __ movzbq($dst$$Register, $mem$$Address);
4785 %}
4786 ins_pipe(ialu_reg_mem);
4787 %}
4789 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register
4790 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{
4791 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4792 effect(KILL cr);
4794 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t"
4795 "andl $dst, $mask" %}
4796 ins_encode %{
4797 Register Rdst = $dst$$Register;
4798 __ movzwq(Rdst, $mem$$Address);
4799 __ andl(Rdst, $mask$$constant);
4800 %}
4801 ins_pipe(ialu_reg_mem);
4802 %}
4804 // Load Integer
4805 instruct loadI(rRegI dst, memory mem)
4806 %{
4807 match(Set dst (LoadI mem));
4809 ins_cost(125);
4810 format %{ "movl $dst, $mem\t# int" %}
4812 ins_encode %{
4813 __ movl($dst$$Register, $mem$$Address);
4814 %}
4816 ins_pipe(ialu_reg_mem);
4817 %}
4819 // Load Integer (32 bit signed) to Byte (8 bit signed)
4820 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4821 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
4823 ins_cost(125);
4824 format %{ "movsbl $dst, $mem\t# int -> byte" %}
4825 ins_encode %{
4826 __ movsbl($dst$$Register, $mem$$Address);
4827 %}
4828 ins_pipe(ialu_reg_mem);
4829 %}
4831 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
4832 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
4833 match(Set dst (AndI (LoadI mem) mask));
4835 ins_cost(125);
4836 format %{ "movzbl $dst, $mem\t# int -> ubyte" %}
4837 ins_encode %{
4838 __ movzbl($dst$$Register, $mem$$Address);
4839 %}
4840 ins_pipe(ialu_reg_mem);
4841 %}
4843 // Load Integer (32 bit signed) to Short (16 bit signed)
4844 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
4845 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
4847 ins_cost(125);
4848 format %{ "movswl $dst, $mem\t# int -> short" %}
4849 ins_encode %{
4850 __ movswl($dst$$Register, $mem$$Address);
4851 %}
4852 ins_pipe(ialu_reg_mem);
4853 %}
4855 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
4856 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
4857 match(Set dst (AndI (LoadI mem) mask));
4859 ins_cost(125);
4860 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %}
4861 ins_encode %{
4862 __ movzwl($dst$$Register, $mem$$Address);
4863 %}
4864 ins_pipe(ialu_reg_mem);
4865 %}
4867 // Load Integer into Long Register
4868 instruct loadI2L(rRegL dst, memory mem)
4869 %{
4870 match(Set dst (ConvI2L (LoadI mem)));
4872 ins_cost(125);
4873 format %{ "movslq $dst, $mem\t# int -> long" %}
4875 ins_encode %{
4876 __ movslq($dst$$Register, $mem$$Address);
4877 %}
4879 ins_pipe(ialu_reg_mem);
4880 %}
4882 // Load Integer with mask 0xFF into Long Register
4883 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
4884 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4886 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %}
4887 ins_encode %{
4888 __ movzbq($dst$$Register, $mem$$Address);
4889 %}
4890 ins_pipe(ialu_reg_mem);
4891 %}
4893 // Load Integer with mask 0xFFFF into Long Register
4894 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{
4895 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4897 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %}
4898 ins_encode %{
4899 __ movzwq($dst$$Register, $mem$$Address);
4900 %}
4901 ins_pipe(ialu_reg_mem);
4902 %}
4904 // Load Integer with a 31-bit mask into Long Register
4905 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{
4906 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4907 effect(KILL cr);
4909 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t"
4910 "andl $dst, $mask" %}
4911 ins_encode %{
4912 Register Rdst = $dst$$Register;
4913 __ movl(Rdst, $mem$$Address);
4914 __ andl(Rdst, $mask$$constant);
4915 %}
4916 ins_pipe(ialu_reg_mem);
4917 %}
4919 // Load Unsigned Integer into Long Register
4920 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask)
4921 %{
4922 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
4924 ins_cost(125);
4925 format %{ "movl $dst, $mem\t# uint -> long" %}
4927 ins_encode %{
4928 __ movl($dst$$Register, $mem$$Address);
4929 %}
4931 ins_pipe(ialu_reg_mem);
4932 %}
4934 // Load Long
4935 instruct loadL(rRegL dst, memory mem)
4936 %{
4937 match(Set dst (LoadL mem));
4939 ins_cost(125);
4940 format %{ "movq $dst, $mem\t# long" %}
4942 ins_encode %{
4943 __ movq($dst$$Register, $mem$$Address);
4944 %}
4946 ins_pipe(ialu_reg_mem); // XXX
4947 %}
4949 // Load Range
4950 instruct loadRange(rRegI dst, memory mem)
4951 %{
4952 match(Set dst (LoadRange mem));
4954 ins_cost(125); // XXX
4955 format %{ "movl $dst, $mem\t# range" %}
4956 opcode(0x8B);
4957 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem));
4958 ins_pipe(ialu_reg_mem);
4959 %}
4961 // Load Pointer
4962 instruct loadP(rRegP dst, memory mem)
4963 %{
4964 match(Set dst (LoadP mem));
4966 ins_cost(125); // XXX
4967 format %{ "movq $dst, $mem\t# ptr" %}
4968 opcode(0x8B);
4969 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
4970 ins_pipe(ialu_reg_mem); // XXX
4971 %}
4973 // Load Compressed Pointer
4974 instruct loadN(rRegN dst, memory mem)
4975 %{
4976 match(Set dst (LoadN mem));
4978 ins_cost(125); // XXX
4979 format %{ "movl $dst, $mem\t# compressed ptr" %}
4980 ins_encode %{
4981 __ movl($dst$$Register, $mem$$Address);
4982 %}
4983 ins_pipe(ialu_reg_mem); // XXX
4984 %}
4987 // Load Klass Pointer
4988 instruct loadKlass(rRegP dst, memory mem)
4989 %{
4990 match(Set dst (LoadKlass mem));
4992 ins_cost(125); // XXX
4993 format %{ "movq $dst, $mem\t# class" %}
4994 opcode(0x8B);
4995 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
4996 ins_pipe(ialu_reg_mem); // XXX
4997 %}
4999 // Load narrow Klass Pointer
5000 instruct loadNKlass(rRegN dst, memory mem)
5001 %{
5002 match(Set dst (LoadNKlass mem));
5004 ins_cost(125); // XXX
5005 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
5006 ins_encode %{
5007 __ movl($dst$$Register, $mem$$Address);
5008 %}
5009 ins_pipe(ialu_reg_mem); // XXX
5010 %}
5012 // Load Float
5013 instruct loadF(regF dst, memory mem)
5014 %{
5015 match(Set dst (LoadF mem));
5017 ins_cost(145); // XXX
5018 format %{ "movss $dst, $mem\t# float" %}
5019 ins_encode %{
5020 __ movflt($dst$$XMMRegister, $mem$$Address);
5021 %}
5022 ins_pipe(pipe_slow); // XXX
5023 %}
5025 // Load Double
5026 instruct loadD_partial(regD dst, memory mem)
5027 %{
5028 predicate(!UseXmmLoadAndClearUpper);
5029 match(Set dst (LoadD mem));
5031 ins_cost(145); // XXX
5032 format %{ "movlpd $dst, $mem\t# double" %}
5033 ins_encode %{
5034 __ movdbl($dst$$XMMRegister, $mem$$Address);
5035 %}
5036 ins_pipe(pipe_slow); // XXX
5037 %}
5039 instruct loadD(regD dst, memory mem)
5040 %{
5041 predicate(UseXmmLoadAndClearUpper);
5042 match(Set dst (LoadD mem));
5044 ins_cost(145); // XXX
5045 format %{ "movsd $dst, $mem\t# double" %}
5046 ins_encode %{
5047 __ movdbl($dst$$XMMRegister, $mem$$Address);
5048 %}
5049 ins_pipe(pipe_slow); // XXX
5050 %}
5052 // Load Effective Address
5053 instruct leaP8(rRegP dst, indOffset8 mem)
5054 %{
5055 match(Set dst mem);
5057 ins_cost(110); // XXX
5058 format %{ "leaq $dst, $mem\t# ptr 8" %}
5059 opcode(0x8D);
5060 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5061 ins_pipe(ialu_reg_reg_fat);
5062 %}
5064 instruct leaP32(rRegP dst, indOffset32 mem)
5065 %{
5066 match(Set dst mem);
5068 ins_cost(110);
5069 format %{ "leaq $dst, $mem\t# ptr 32" %}
5070 opcode(0x8D);
5071 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5072 ins_pipe(ialu_reg_reg_fat);
5073 %}
5075 // instruct leaPIdx(rRegP dst, indIndex mem)
5076 // %{
5077 // match(Set dst mem);
5079 // ins_cost(110);
5080 // format %{ "leaq $dst, $mem\t# ptr idx" %}
5081 // opcode(0x8D);
5082 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5083 // ins_pipe(ialu_reg_reg_fat);
5084 // %}
5086 instruct leaPIdxOff(rRegP dst, indIndexOffset mem)
5087 %{
5088 match(Set dst mem);
5090 ins_cost(110);
5091 format %{ "leaq $dst, $mem\t# ptr idxoff" %}
5092 opcode(0x8D);
5093 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5094 ins_pipe(ialu_reg_reg_fat);
5095 %}
5097 instruct leaPIdxScale(rRegP dst, indIndexScale mem)
5098 %{
5099 match(Set dst mem);
5101 ins_cost(110);
5102 format %{ "leaq $dst, $mem\t# ptr idxscale" %}
5103 opcode(0x8D);
5104 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5105 ins_pipe(ialu_reg_reg_fat);
5106 %}
5108 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem)
5109 %{
5110 match(Set dst mem);
5112 ins_cost(110);
5113 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %}
5114 opcode(0x8D);
5115 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5116 ins_pipe(ialu_reg_reg_fat);
5117 %}
5119 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem)
5120 %{
5121 match(Set dst mem);
5123 ins_cost(110);
5124 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %}
5125 opcode(0x8D);
5126 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5127 ins_pipe(ialu_reg_reg_fat);
5128 %}
5130 // Load Effective Address which uses Narrow (32-bits) oop
5131 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem)
5132 %{
5133 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0));
5134 match(Set dst mem);
5136 ins_cost(110);
5137 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %}
5138 opcode(0x8D);
5139 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5140 ins_pipe(ialu_reg_reg_fat);
5141 %}
5143 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem)
5144 %{
5145 predicate(Universe::narrow_oop_shift() == 0);
5146 match(Set dst mem);
5148 ins_cost(110); // XXX
5149 format %{ "leaq $dst, $mem\t# ptr off8narrow" %}
5150 opcode(0x8D);
5151 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5152 ins_pipe(ialu_reg_reg_fat);
5153 %}
5155 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem)
5156 %{
5157 predicate(Universe::narrow_oop_shift() == 0);
5158 match(Set dst mem);
5160 ins_cost(110);
5161 format %{ "leaq $dst, $mem\t# ptr off32narrow" %}
5162 opcode(0x8D);
5163 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5164 ins_pipe(ialu_reg_reg_fat);
5165 %}
5167 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem)
5168 %{
5169 predicate(Universe::narrow_oop_shift() == 0);
5170 match(Set dst mem);
5172 ins_cost(110);
5173 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %}
5174 opcode(0x8D);
5175 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5176 ins_pipe(ialu_reg_reg_fat);
5177 %}
5179 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem)
5180 %{
5181 predicate(Universe::narrow_oop_shift() == 0);
5182 match(Set dst mem);
5184 ins_cost(110);
5185 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %}
5186 opcode(0x8D);
5187 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5188 ins_pipe(ialu_reg_reg_fat);
5189 %}
5191 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem)
5192 %{
5193 predicate(Universe::narrow_oop_shift() == 0);
5194 match(Set dst mem);
5196 ins_cost(110);
5197 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %}
5198 opcode(0x8D);
5199 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5200 ins_pipe(ialu_reg_reg_fat);
5201 %}
5203 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem)
5204 %{
5205 predicate(Universe::narrow_oop_shift() == 0);
5206 match(Set dst mem);
5208 ins_cost(110);
5209 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %}
5210 opcode(0x8D);
5211 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5212 ins_pipe(ialu_reg_reg_fat);
5213 %}
5215 instruct loadConI(rRegI dst, immI src)
5216 %{
5217 match(Set dst src);
5219 format %{ "movl $dst, $src\t# int" %}
5220 ins_encode(load_immI(dst, src));
5221 ins_pipe(ialu_reg_fat); // XXX
5222 %}
5224 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr)
5225 %{
5226 match(Set dst src);
5227 effect(KILL cr);
5229 ins_cost(50);
5230 format %{ "xorl $dst, $dst\t# int" %}
5231 opcode(0x33); /* + rd */
5232 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5233 ins_pipe(ialu_reg);
5234 %}
5236 instruct loadConL(rRegL dst, immL src)
5237 %{
5238 match(Set dst src);
5240 ins_cost(150);
5241 format %{ "movq $dst, $src\t# long" %}
5242 ins_encode(load_immL(dst, src));
5243 ins_pipe(ialu_reg);
5244 %}
5246 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr)
5247 %{
5248 match(Set dst src);
5249 effect(KILL cr);
5251 ins_cost(50);
5252 format %{ "xorl $dst, $dst\t# long" %}
5253 opcode(0x33); /* + rd */
5254 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5255 ins_pipe(ialu_reg); // XXX
5256 %}
5258 instruct loadConUL32(rRegL dst, immUL32 src)
5259 %{
5260 match(Set dst src);
5262 ins_cost(60);
5263 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %}
5264 ins_encode(load_immUL32(dst, src));
5265 ins_pipe(ialu_reg);
5266 %}
5268 instruct loadConL32(rRegL dst, immL32 src)
5269 %{
5270 match(Set dst src);
5272 ins_cost(70);
5273 format %{ "movq $dst, $src\t# long (32-bit)" %}
5274 ins_encode(load_immL32(dst, src));
5275 ins_pipe(ialu_reg);
5276 %}
5278 instruct loadConP(rRegP dst, immP con) %{
5279 match(Set dst con);
5281 format %{ "movq $dst, $con\t# ptr" %}
5282 ins_encode(load_immP(dst, con));
5283 ins_pipe(ialu_reg_fat); // XXX
5284 %}
5286 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
5287 %{
5288 match(Set dst src);
5289 effect(KILL cr);
5291 ins_cost(50);
5292 format %{ "xorl $dst, $dst\t# ptr" %}
5293 opcode(0x33); /* + rd */
5294 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5295 ins_pipe(ialu_reg);
5296 %}
5298 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
5299 %{
5300 match(Set dst src);
5301 effect(KILL cr);
5303 ins_cost(60);
5304 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %}
5305 ins_encode(load_immP31(dst, src));
5306 ins_pipe(ialu_reg);
5307 %}
5309 instruct loadConF(regF dst, immF con) %{
5310 match(Set dst con);
5311 ins_cost(125);
5312 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
5313 ins_encode %{
5314 __ movflt($dst$$XMMRegister, $constantaddress($con));
5315 %}
5316 ins_pipe(pipe_slow);
5317 %}
5319 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
5320 match(Set dst src);
5321 effect(KILL cr);
5322 format %{ "xorq $dst, $src\t# compressed NULL ptr" %}
5323 ins_encode %{
5324 __ xorq($dst$$Register, $dst$$Register);
5325 %}
5326 ins_pipe(ialu_reg);
5327 %}
5329 instruct loadConN(rRegN dst, immN src) %{
5330 match(Set dst src);
5332 ins_cost(125);
5333 format %{ "movl $dst, $src\t# compressed ptr" %}
5334 ins_encode %{
5335 address con = (address)$src$$constant;
5336 if (con == NULL) {
5337 ShouldNotReachHere();
5338 } else {
5339 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
5340 }
5341 %}
5342 ins_pipe(ialu_reg_fat); // XXX
5343 %}
5345 instruct loadConNKlass(rRegN dst, immNKlass src) %{
5346 match(Set dst src);
5348 ins_cost(125);
5349 format %{ "movl $dst, $src\t# compressed klass ptr" %}
5350 ins_encode %{
5351 address con = (address)$src$$constant;
5352 if (con == NULL) {
5353 ShouldNotReachHere();
5354 } else {
5355 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant);
5356 }
5357 %}
5358 ins_pipe(ialu_reg_fat); // XXX
5359 %}
5361 instruct loadConF0(regF dst, immF0 src)
5362 %{
5363 match(Set dst src);
5364 ins_cost(100);
5366 format %{ "xorps $dst, $dst\t# float 0.0" %}
5367 ins_encode %{
5368 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
5369 %}
5370 ins_pipe(pipe_slow);
5371 %}
5373 // Use the same format since predicate() can not be used here.
5374 instruct loadConD(regD dst, immD con) %{
5375 match(Set dst con);
5376 ins_cost(125);
5377 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
5378 ins_encode %{
5379 __ movdbl($dst$$XMMRegister, $constantaddress($con));
5380 %}
5381 ins_pipe(pipe_slow);
5382 %}
5384 instruct loadConD0(regD dst, immD0 src)
5385 %{
5386 match(Set dst src);
5387 ins_cost(100);
5389 format %{ "xorpd $dst, $dst\t# double 0.0" %}
5390 ins_encode %{
5391 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
5392 %}
5393 ins_pipe(pipe_slow);
5394 %}
5396 instruct loadSSI(rRegI dst, stackSlotI src)
5397 %{
5398 match(Set dst src);
5400 ins_cost(125);
5401 format %{ "movl $dst, $src\t# int stk" %}
5402 opcode(0x8B);
5403 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
5404 ins_pipe(ialu_reg_mem);
5405 %}
5407 instruct loadSSL(rRegL dst, stackSlotL src)
5408 %{
5409 match(Set dst src);
5411 ins_cost(125);
5412 format %{ "movq $dst, $src\t# long stk" %}
5413 opcode(0x8B);
5414 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5415 ins_pipe(ialu_reg_mem);
5416 %}
5418 instruct loadSSP(rRegP dst, stackSlotP src)
5419 %{
5420 match(Set dst src);
5422 ins_cost(125);
5423 format %{ "movq $dst, $src\t# ptr stk" %}
5424 opcode(0x8B);
5425 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5426 ins_pipe(ialu_reg_mem);
5427 %}
5429 instruct loadSSF(regF dst, stackSlotF src)
5430 %{
5431 match(Set dst src);
5433 ins_cost(125);
5434 format %{ "movss $dst, $src\t# float stk" %}
5435 ins_encode %{
5436 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
5437 %}
5438 ins_pipe(pipe_slow); // XXX
5439 %}
5441 // Use the same format since predicate() can not be used here.
5442 instruct loadSSD(regD dst, stackSlotD src)
5443 %{
5444 match(Set dst src);
5446 ins_cost(125);
5447 format %{ "movsd $dst, $src\t# double stk" %}
5448 ins_encode %{
5449 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
5450 %}
5451 ins_pipe(pipe_slow); // XXX
5452 %}
5454 // Prefetch instructions.
5455 // Must be safe to execute with invalid address (cannot fault).
5457 instruct prefetchr( memory mem ) %{
5458 predicate(ReadPrefetchInstr==3);
5459 match(PrefetchRead mem);
5460 ins_cost(125);
5462 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %}
5463 ins_encode %{
5464 __ prefetchr($mem$$Address);
5465 %}
5466 ins_pipe(ialu_mem);
5467 %}
5469 instruct prefetchrNTA( memory mem ) %{
5470 predicate(ReadPrefetchInstr==0);
5471 match(PrefetchRead mem);
5472 ins_cost(125);
5474 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %}
5475 ins_encode %{
5476 __ prefetchnta($mem$$Address);
5477 %}
5478 ins_pipe(ialu_mem);
5479 %}
5481 instruct prefetchrT0( memory mem ) %{
5482 predicate(ReadPrefetchInstr==1);
5483 match(PrefetchRead mem);
5484 ins_cost(125);
5486 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %}
5487 ins_encode %{
5488 __ prefetcht0($mem$$Address);
5489 %}
5490 ins_pipe(ialu_mem);
5491 %}
5493 instruct prefetchrT2( memory mem ) %{
5494 predicate(ReadPrefetchInstr==2);
5495 match(PrefetchRead mem);
5496 ins_cost(125);
5498 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %}
5499 ins_encode %{
5500 __ prefetcht2($mem$$Address);
5501 %}
5502 ins_pipe(ialu_mem);
5503 %}
5505 instruct prefetchwNTA( memory mem ) %{
5506 match(PrefetchWrite mem);
5507 ins_cost(125);
5509 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %}
5510 ins_encode %{
5511 __ prefetchnta($mem$$Address);
5512 %}
5513 ins_pipe(ialu_mem);
5514 %}
5516 // Prefetch instructions for allocation.
5518 instruct prefetchAlloc( memory mem ) %{
5519 predicate(AllocatePrefetchInstr==3);
5520 match(PrefetchAllocation mem);
5521 ins_cost(125);
5523 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %}
5524 ins_encode %{
5525 __ prefetchw($mem$$Address);
5526 %}
5527 ins_pipe(ialu_mem);
5528 %}
5530 instruct prefetchAllocNTA( memory mem ) %{
5531 predicate(AllocatePrefetchInstr==0);
5532 match(PrefetchAllocation mem);
5533 ins_cost(125);
5535 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %}
5536 ins_encode %{
5537 __ prefetchnta($mem$$Address);
5538 %}
5539 ins_pipe(ialu_mem);
5540 %}
5542 instruct prefetchAllocT0( memory mem ) %{
5543 predicate(AllocatePrefetchInstr==1);
5544 match(PrefetchAllocation mem);
5545 ins_cost(125);
5547 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %}
5548 ins_encode %{
5549 __ prefetcht0($mem$$Address);
5550 %}
5551 ins_pipe(ialu_mem);
5552 %}
5554 instruct prefetchAllocT2( memory mem ) %{
5555 predicate(AllocatePrefetchInstr==2);
5556 match(PrefetchAllocation mem);
5557 ins_cost(125);
5559 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %}
5560 ins_encode %{
5561 __ prefetcht2($mem$$Address);
5562 %}
5563 ins_pipe(ialu_mem);
5564 %}
5566 //----------Store Instructions-------------------------------------------------
5568 // Store Byte
5569 instruct storeB(memory mem, rRegI src)
5570 %{
5571 match(Set mem (StoreB mem src));
5573 ins_cost(125); // XXX
5574 format %{ "movb $mem, $src\t# byte" %}
5575 opcode(0x88);
5576 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem));
5577 ins_pipe(ialu_mem_reg);
5578 %}
5580 // Store Char/Short
5581 instruct storeC(memory mem, rRegI src)
5582 %{
5583 match(Set mem (StoreC mem src));
5585 ins_cost(125); // XXX
5586 format %{ "movw $mem, $src\t# char/short" %}
5587 opcode(0x89);
5588 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
5589 ins_pipe(ialu_mem_reg);
5590 %}
5592 // Store Integer
5593 instruct storeI(memory mem, rRegI src)
5594 %{
5595 match(Set mem (StoreI mem src));
5597 ins_cost(125); // XXX
5598 format %{ "movl $mem, $src\t# int" %}
5599 opcode(0x89);
5600 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
5601 ins_pipe(ialu_mem_reg);
5602 %}
5604 // Store Long
5605 instruct storeL(memory mem, rRegL src)
5606 %{
5607 match(Set mem (StoreL mem src));
5609 ins_cost(125); // XXX
5610 format %{ "movq $mem, $src\t# long" %}
5611 opcode(0x89);
5612 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5613 ins_pipe(ialu_mem_reg); // XXX
5614 %}
5616 // Store Pointer
5617 instruct storeP(memory mem, any_RegP src)
5618 %{
5619 match(Set mem (StoreP mem src));
5621 ins_cost(125); // XXX
5622 format %{ "movq $mem, $src\t# ptr" %}
5623 opcode(0x89);
5624 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5625 ins_pipe(ialu_mem_reg);
5626 %}
5628 instruct storeImmP0(memory mem, immP0 zero)
5629 %{
5630 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5631 match(Set mem (StoreP mem zero));
5633 ins_cost(125); // XXX
5634 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
5635 ins_encode %{
5636 __ movq($mem$$Address, r12);
5637 %}
5638 ins_pipe(ialu_mem_reg);
5639 %}
5641 // Store NULL Pointer, mark word, or other simple pointer constant.
5642 instruct storeImmP(memory mem, immP31 src)
5643 %{
5644 match(Set mem (StoreP mem src));
5646 ins_cost(150); // XXX
5647 format %{ "movq $mem, $src\t# ptr" %}
5648 opcode(0xC7); /* C7 /0 */
5649 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5650 ins_pipe(ialu_mem_imm);
5651 %}
5653 // Store Compressed Pointer
5654 instruct storeN(memory mem, rRegN src)
5655 %{
5656 match(Set mem (StoreN mem src));
5658 ins_cost(125); // XXX
5659 format %{ "movl $mem, $src\t# compressed ptr" %}
5660 ins_encode %{
5661 __ movl($mem$$Address, $src$$Register);
5662 %}
5663 ins_pipe(ialu_mem_reg);
5664 %}
5666 instruct storeNKlass(memory mem, rRegN src)
5667 %{
5668 match(Set mem (StoreNKlass mem src));
5670 ins_cost(125); // XXX
5671 format %{ "movl $mem, $src\t# compressed klass ptr" %}
5672 ins_encode %{
5673 __ movl($mem$$Address, $src$$Register);
5674 %}
5675 ins_pipe(ialu_mem_reg);
5676 %}
5678 instruct storeImmN0(memory mem, immN0 zero)
5679 %{
5680 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL);
5681 match(Set mem (StoreN mem zero));
5683 ins_cost(125); // XXX
5684 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
5685 ins_encode %{
5686 __ movl($mem$$Address, r12);
5687 %}
5688 ins_pipe(ialu_mem_reg);
5689 %}
5691 instruct storeImmN(memory mem, immN src)
5692 %{
5693 match(Set mem (StoreN mem src));
5695 ins_cost(150); // XXX
5696 format %{ "movl $mem, $src\t# compressed ptr" %}
5697 ins_encode %{
5698 address con = (address)$src$$constant;
5699 if (con == NULL) {
5700 __ movl($mem$$Address, (int32_t)0);
5701 } else {
5702 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant);
5703 }
5704 %}
5705 ins_pipe(ialu_mem_imm);
5706 %}
5708 instruct storeImmNKlass(memory mem, immNKlass src)
5709 %{
5710 match(Set mem (StoreNKlass mem src));
5712 ins_cost(150); // XXX
5713 format %{ "movl $mem, $src\t# compressed klass ptr" %}
5714 ins_encode %{
5715 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant);
5716 %}
5717 ins_pipe(ialu_mem_imm);
5718 %}
5720 // Store Integer Immediate
5721 instruct storeImmI0(memory mem, immI0 zero)
5722 %{
5723 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5724 match(Set mem (StoreI mem zero));
5726 ins_cost(125); // XXX
5727 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
5728 ins_encode %{
5729 __ movl($mem$$Address, r12);
5730 %}
5731 ins_pipe(ialu_mem_reg);
5732 %}
5734 instruct storeImmI(memory mem, immI src)
5735 %{
5736 match(Set mem (StoreI mem src));
5738 ins_cost(150);
5739 format %{ "movl $mem, $src\t# int" %}
5740 opcode(0xC7); /* C7 /0 */
5741 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5742 ins_pipe(ialu_mem_imm);
5743 %}
5745 // Store Long Immediate
5746 instruct storeImmL0(memory mem, immL0 zero)
5747 %{
5748 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5749 match(Set mem (StoreL mem zero));
5751 ins_cost(125); // XXX
5752 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
5753 ins_encode %{
5754 __ movq($mem$$Address, r12);
5755 %}
5756 ins_pipe(ialu_mem_reg);
5757 %}
5759 instruct storeImmL(memory mem, immL32 src)
5760 %{
5761 match(Set mem (StoreL mem src));
5763 ins_cost(150);
5764 format %{ "movq $mem, $src\t# long" %}
5765 opcode(0xC7); /* C7 /0 */
5766 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5767 ins_pipe(ialu_mem_imm);
5768 %}
5770 // Store Short/Char Immediate
5771 instruct storeImmC0(memory mem, immI0 zero)
5772 %{
5773 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5774 match(Set mem (StoreC mem zero));
5776 ins_cost(125); // XXX
5777 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
5778 ins_encode %{
5779 __ movw($mem$$Address, r12);
5780 %}
5781 ins_pipe(ialu_mem_reg);
5782 %}
5784 instruct storeImmI16(memory mem, immI16 src)
5785 %{
5786 predicate(UseStoreImmI16);
5787 match(Set mem (StoreC mem src));
5789 ins_cost(150);
5790 format %{ "movw $mem, $src\t# short/char" %}
5791 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */
5792 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src));
5793 ins_pipe(ialu_mem_imm);
5794 %}
5796 // Store Byte Immediate
5797 instruct storeImmB0(memory mem, immI0 zero)
5798 %{
5799 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5800 match(Set mem (StoreB mem zero));
5802 ins_cost(125); // XXX
5803 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
5804 ins_encode %{
5805 __ movb($mem$$Address, r12);
5806 %}
5807 ins_pipe(ialu_mem_reg);
5808 %}
5810 instruct storeImmB(memory mem, immI8 src)
5811 %{
5812 match(Set mem (StoreB mem src));
5814 ins_cost(150); // XXX
5815 format %{ "movb $mem, $src\t# byte" %}
5816 opcode(0xC6); /* C6 /0 */
5817 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
5818 ins_pipe(ialu_mem_imm);
5819 %}
5821 // Store CMS card-mark Immediate
5822 instruct storeImmCM0_reg(memory mem, immI0 zero)
5823 %{
5824 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5825 match(Set mem (StoreCM mem zero));
5827 ins_cost(125); // XXX
5828 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
5829 ins_encode %{
5830 __ movb($mem$$Address, r12);
5831 %}
5832 ins_pipe(ialu_mem_reg);
5833 %}
5835 instruct storeImmCM0(memory mem, immI0 src)
5836 %{
5837 match(Set mem (StoreCM mem src));
5839 ins_cost(150); // XXX
5840 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
5841 opcode(0xC6); /* C6 /0 */
5842 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
5843 ins_pipe(ialu_mem_imm);
5844 %}
5846 // Store Float
5847 instruct storeF(memory mem, regF src)
5848 %{
5849 match(Set mem (StoreF mem src));
5851 ins_cost(95); // XXX
5852 format %{ "movss $mem, $src\t# float" %}
5853 ins_encode %{
5854 __ movflt($mem$$Address, $src$$XMMRegister);
5855 %}
5856 ins_pipe(pipe_slow); // XXX
5857 %}
5859 // Store immediate Float value (it is faster than store from XMM register)
5860 instruct storeF0(memory mem, immF0 zero)
5861 %{
5862 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5863 match(Set mem (StoreF mem zero));
5865 ins_cost(25); // XXX
5866 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
5867 ins_encode %{
5868 __ movl($mem$$Address, r12);
5869 %}
5870 ins_pipe(ialu_mem_reg);
5871 %}
5873 instruct storeF_imm(memory mem, immF src)
5874 %{
5875 match(Set mem (StoreF mem src));
5877 ins_cost(50);
5878 format %{ "movl $mem, $src\t# float" %}
5879 opcode(0xC7); /* C7 /0 */
5880 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
5881 ins_pipe(ialu_mem_imm);
5882 %}
5884 // Store Double
5885 instruct storeD(memory mem, regD src)
5886 %{
5887 match(Set mem (StoreD mem src));
5889 ins_cost(95); // XXX
5890 format %{ "movsd $mem, $src\t# double" %}
5891 ins_encode %{
5892 __ movdbl($mem$$Address, $src$$XMMRegister);
5893 %}
5894 ins_pipe(pipe_slow); // XXX
5895 %}
5897 // Store immediate double 0.0 (it is faster than store from XMM register)
5898 instruct storeD0_imm(memory mem, immD0 src)
5899 %{
5900 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
5901 match(Set mem (StoreD mem src));
5903 ins_cost(50);
5904 format %{ "movq $mem, $src\t# double 0." %}
5905 opcode(0xC7); /* C7 /0 */
5906 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
5907 ins_pipe(ialu_mem_imm);
5908 %}
5910 instruct storeD0(memory mem, immD0 zero)
5911 %{
5912 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5913 match(Set mem (StoreD mem zero));
5915 ins_cost(25); // XXX
5916 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
5917 ins_encode %{
5918 __ movq($mem$$Address, r12);
5919 %}
5920 ins_pipe(ialu_mem_reg);
5921 %}
5923 instruct storeSSI(stackSlotI dst, rRegI src)
5924 %{
5925 match(Set dst src);
5927 ins_cost(100);
5928 format %{ "movl $dst, $src\t# int stk" %}
5929 opcode(0x89);
5930 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
5931 ins_pipe( ialu_mem_reg );
5932 %}
5934 instruct storeSSL(stackSlotL dst, rRegL src)
5935 %{
5936 match(Set dst src);
5938 ins_cost(100);
5939 format %{ "movq $dst, $src\t# long stk" %}
5940 opcode(0x89);
5941 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
5942 ins_pipe(ialu_mem_reg);
5943 %}
5945 instruct storeSSP(stackSlotP dst, rRegP src)
5946 %{
5947 match(Set dst src);
5949 ins_cost(100);
5950 format %{ "movq $dst, $src\t# ptr stk" %}
5951 opcode(0x89);
5952 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
5953 ins_pipe(ialu_mem_reg);
5954 %}
5956 instruct storeSSF(stackSlotF dst, regF src)
5957 %{
5958 match(Set dst src);
5960 ins_cost(95); // XXX
5961 format %{ "movss $dst, $src\t# float stk" %}
5962 ins_encode %{
5963 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
5964 %}
5965 ins_pipe(pipe_slow); // XXX
5966 %}
5968 instruct storeSSD(stackSlotD dst, regD src)
5969 %{
5970 match(Set dst src);
5972 ins_cost(95); // XXX
5973 format %{ "movsd $dst, $src\t# double stk" %}
5974 ins_encode %{
5975 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
5976 %}
5977 ins_pipe(pipe_slow); // XXX
5978 %}
5980 //----------BSWAP Instructions-------------------------------------------------
5981 instruct bytes_reverse_int(rRegI dst) %{
5982 match(Set dst (ReverseBytesI dst));
5984 format %{ "bswapl $dst" %}
5985 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */
5986 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) );
5987 ins_pipe( ialu_reg );
5988 %}
5990 instruct bytes_reverse_long(rRegL dst) %{
5991 match(Set dst (ReverseBytesL dst));
5993 format %{ "bswapq $dst" %}
5994 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */
5995 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) );
5996 ins_pipe( ialu_reg);
5997 %}
5999 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{
6000 match(Set dst (ReverseBytesUS dst));
6001 effect(KILL cr);
6003 format %{ "bswapl $dst\n\t"
6004 "shrl $dst,16\n\t" %}
6005 ins_encode %{
6006 __ bswapl($dst$$Register);
6007 __ shrl($dst$$Register, 16);
6008 %}
6009 ins_pipe( ialu_reg );
6010 %}
6012 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{
6013 match(Set dst (ReverseBytesS dst));
6014 effect(KILL cr);
6016 format %{ "bswapl $dst\n\t"
6017 "sar $dst,16\n\t" %}
6018 ins_encode %{
6019 __ bswapl($dst$$Register);
6020 __ sarl($dst$$Register, 16);
6021 %}
6022 ins_pipe( ialu_reg );
6023 %}
6025 //---------- Zeros Count Instructions ------------------------------------------
6027 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6028 predicate(UseCountLeadingZerosInstruction);
6029 match(Set dst (CountLeadingZerosI src));
6030 effect(KILL cr);
6032 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %}
6033 ins_encode %{
6034 __ lzcntl($dst$$Register, $src$$Register);
6035 %}
6036 ins_pipe(ialu_reg);
6037 %}
6039 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{
6040 predicate(!UseCountLeadingZerosInstruction);
6041 match(Set dst (CountLeadingZerosI src));
6042 effect(KILL cr);
6044 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t"
6045 "jnz skip\n\t"
6046 "movl $dst, -1\n"
6047 "skip:\n\t"
6048 "negl $dst\n\t"
6049 "addl $dst, 31" %}
6050 ins_encode %{
6051 Register Rdst = $dst$$Register;
6052 Register Rsrc = $src$$Register;
6053 Label skip;
6054 __ bsrl(Rdst, Rsrc);
6055 __ jccb(Assembler::notZero, skip);
6056 __ movl(Rdst, -1);
6057 __ bind(skip);
6058 __ negl(Rdst);
6059 __ addl(Rdst, BitsPerInt - 1);
6060 %}
6061 ins_pipe(ialu_reg);
6062 %}
6064 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6065 predicate(UseCountLeadingZerosInstruction);
6066 match(Set dst (CountLeadingZerosL src));
6067 effect(KILL cr);
6069 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %}
6070 ins_encode %{
6071 __ lzcntq($dst$$Register, $src$$Register);
6072 %}
6073 ins_pipe(ialu_reg);
6074 %}
6076 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{
6077 predicate(!UseCountLeadingZerosInstruction);
6078 match(Set dst (CountLeadingZerosL src));
6079 effect(KILL cr);
6081 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t"
6082 "jnz skip\n\t"
6083 "movl $dst, -1\n"
6084 "skip:\n\t"
6085 "negl $dst\n\t"
6086 "addl $dst, 63" %}
6087 ins_encode %{
6088 Register Rdst = $dst$$Register;
6089 Register Rsrc = $src$$Register;
6090 Label skip;
6091 __ bsrq(Rdst, Rsrc);
6092 __ jccb(Assembler::notZero, skip);
6093 __ movl(Rdst, -1);
6094 __ bind(skip);
6095 __ negl(Rdst);
6096 __ addl(Rdst, BitsPerLong - 1);
6097 %}
6098 ins_pipe(ialu_reg);
6099 %}
6101 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6102 predicate(UseCountTrailingZerosInstruction);
6103 match(Set dst (CountTrailingZerosI src));
6104 effect(KILL cr);
6106 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %}
6107 ins_encode %{
6108 __ tzcntl($dst$$Register, $src$$Register);
6109 %}
6110 ins_pipe(ialu_reg);
6111 %}
6113 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{
6114 predicate(!UseCountTrailingZerosInstruction);
6115 match(Set dst (CountTrailingZerosI src));
6116 effect(KILL cr);
6118 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t"
6119 "jnz done\n\t"
6120 "movl $dst, 32\n"
6121 "done:" %}
6122 ins_encode %{
6123 Register Rdst = $dst$$Register;
6124 Label done;
6125 __ bsfl(Rdst, $src$$Register);
6126 __ jccb(Assembler::notZero, done);
6127 __ movl(Rdst, BitsPerInt);
6128 __ bind(done);
6129 %}
6130 ins_pipe(ialu_reg);
6131 %}
6133 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6134 predicate(UseCountTrailingZerosInstruction);
6135 match(Set dst (CountTrailingZerosL src));
6136 effect(KILL cr);
6138 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %}
6139 ins_encode %{
6140 __ tzcntq($dst$$Register, $src$$Register);
6141 %}
6142 ins_pipe(ialu_reg);
6143 %}
6145 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{
6146 predicate(!UseCountTrailingZerosInstruction);
6147 match(Set dst (CountTrailingZerosL src));
6148 effect(KILL cr);
6150 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t"
6151 "jnz done\n\t"
6152 "movl $dst, 64\n"
6153 "done:" %}
6154 ins_encode %{
6155 Register Rdst = $dst$$Register;
6156 Label done;
6157 __ bsfq(Rdst, $src$$Register);
6158 __ jccb(Assembler::notZero, done);
6159 __ movl(Rdst, BitsPerLong);
6160 __ bind(done);
6161 %}
6162 ins_pipe(ialu_reg);
6163 %}
6166 //---------- Population Count Instructions -------------------------------------
6168 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{
6169 predicate(UsePopCountInstruction);
6170 match(Set dst (PopCountI src));
6171 effect(KILL cr);
6173 format %{ "popcnt $dst, $src" %}
6174 ins_encode %{
6175 __ popcntl($dst$$Register, $src$$Register);
6176 %}
6177 ins_pipe(ialu_reg);
6178 %}
6180 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{
6181 predicate(UsePopCountInstruction);
6182 match(Set dst (PopCountI (LoadI mem)));
6183 effect(KILL cr);
6185 format %{ "popcnt $dst, $mem" %}
6186 ins_encode %{
6187 __ popcntl($dst$$Register, $mem$$Address);
6188 %}
6189 ins_pipe(ialu_reg);
6190 %}
6192 // Note: Long.bitCount(long) returns an int.
6193 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{
6194 predicate(UsePopCountInstruction);
6195 match(Set dst (PopCountL src));
6196 effect(KILL cr);
6198 format %{ "popcnt $dst, $src" %}
6199 ins_encode %{
6200 __ popcntq($dst$$Register, $src$$Register);
6201 %}
6202 ins_pipe(ialu_reg);
6203 %}
6205 // Note: Long.bitCount(long) returns an int.
6206 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{
6207 predicate(UsePopCountInstruction);
6208 match(Set dst (PopCountL (LoadL mem)));
6209 effect(KILL cr);
6211 format %{ "popcnt $dst, $mem" %}
6212 ins_encode %{
6213 __ popcntq($dst$$Register, $mem$$Address);
6214 %}
6215 ins_pipe(ialu_reg);
6216 %}
6219 //----------MemBar Instructions-----------------------------------------------
6220 // Memory barrier flavors
6222 instruct membar_acquire()
6223 %{
6224 match(MemBarAcquire);
6225 match(LoadFence);
6226 ins_cost(0);
6228 size(0);
6229 format %{ "MEMBAR-acquire ! (empty encoding)" %}
6230 ins_encode();
6231 ins_pipe(empty);
6232 %}
6234 instruct membar_acquire_lock()
6235 %{
6236 match(MemBarAcquireLock);
6237 ins_cost(0);
6239 size(0);
6240 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %}
6241 ins_encode();
6242 ins_pipe(empty);
6243 %}
6245 instruct membar_release()
6246 %{
6247 match(MemBarRelease);
6248 match(StoreFence);
6249 ins_cost(0);
6251 size(0);
6252 format %{ "MEMBAR-release ! (empty encoding)" %}
6253 ins_encode();
6254 ins_pipe(empty);
6255 %}
6257 instruct membar_release_lock()
6258 %{
6259 match(MemBarReleaseLock);
6260 ins_cost(0);
6262 size(0);
6263 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
6264 ins_encode();
6265 ins_pipe(empty);
6266 %}
6268 instruct membar_volatile(rFlagsReg cr) %{
6269 match(MemBarVolatile);
6270 effect(KILL cr);
6271 ins_cost(400);
6273 format %{
6274 $$template
6275 if (os::is_MP()) {
6276 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
6277 } else {
6278 $$emit$$"MEMBAR-volatile ! (empty encoding)"
6279 }
6280 %}
6281 ins_encode %{
6282 __ membar(Assembler::StoreLoad);
6283 %}
6284 ins_pipe(pipe_slow);
6285 %}
6287 instruct unnecessary_membar_volatile()
6288 %{
6289 match(MemBarVolatile);
6290 predicate(Matcher::post_store_load_barrier(n));
6291 ins_cost(0);
6293 size(0);
6294 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
6295 ins_encode();
6296 ins_pipe(empty);
6297 %}
6299 instruct membar_storestore() %{
6300 match(MemBarStoreStore);
6301 ins_cost(0);
6303 size(0);
6304 format %{ "MEMBAR-storestore (empty encoding)" %}
6305 ins_encode( );
6306 ins_pipe(empty);
6307 %}
6309 //----------Move Instructions--------------------------------------------------
6311 instruct castX2P(rRegP dst, rRegL src)
6312 %{
6313 match(Set dst (CastX2P src));
6315 format %{ "movq $dst, $src\t# long->ptr" %}
6316 ins_encode %{
6317 if ($dst$$reg != $src$$reg) {
6318 __ movptr($dst$$Register, $src$$Register);
6319 }
6320 %}
6321 ins_pipe(ialu_reg_reg); // XXX
6322 %}
6324 instruct castP2X(rRegL dst, rRegP src)
6325 %{
6326 match(Set dst (CastP2X src));
6328 format %{ "movq $dst, $src\t# ptr -> long" %}
6329 ins_encode %{
6330 if ($dst$$reg != $src$$reg) {
6331 __ movptr($dst$$Register, $src$$Register);
6332 }
6333 %}
6334 ins_pipe(ialu_reg_reg); // XXX
6335 %}
6337 // Convert oop into int for vectors alignment masking
6338 instruct convP2I(rRegI dst, rRegP src)
6339 %{
6340 match(Set dst (ConvL2I (CastP2X src)));
6342 format %{ "movl $dst, $src\t# ptr -> int" %}
6343 ins_encode %{
6344 __ movl($dst$$Register, $src$$Register);
6345 %}
6346 ins_pipe(ialu_reg_reg); // XXX
6347 %}
6349 // Convert compressed oop into int for vectors alignment masking
6350 // in case of 32bit oops (heap < 4Gb).
6351 instruct convN2I(rRegI dst, rRegN src)
6352 %{
6353 predicate(Universe::narrow_oop_shift() == 0);
6354 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6356 format %{ "movl $dst, $src\t# compressed ptr -> int" %}
6357 ins_encode %{
6358 __ movl($dst$$Register, $src$$Register);
6359 %}
6360 ins_pipe(ialu_reg_reg); // XXX
6361 %}
6363 // Convert oop pointer into compressed form
6364 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
6365 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
6366 match(Set dst (EncodeP src));
6367 effect(KILL cr);
6368 format %{ "encode_heap_oop $dst,$src" %}
6369 ins_encode %{
6370 Register s = $src$$Register;
6371 Register d = $dst$$Register;
6372 if (s != d) {
6373 __ movq(d, s);
6374 }
6375 __ encode_heap_oop(d);
6376 %}
6377 ins_pipe(ialu_reg_long);
6378 %}
6380 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6381 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
6382 match(Set dst (EncodeP src));
6383 effect(KILL cr);
6384 format %{ "encode_heap_oop_not_null $dst,$src" %}
6385 ins_encode %{
6386 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
6387 %}
6388 ins_pipe(ialu_reg_long);
6389 %}
6391 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
6392 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
6393 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
6394 match(Set dst (DecodeN src));
6395 effect(KILL cr);
6396 format %{ "decode_heap_oop $dst,$src" %}
6397 ins_encode %{
6398 Register s = $src$$Register;
6399 Register d = $dst$$Register;
6400 if (s != d) {
6401 __ movq(d, s);
6402 }
6403 __ decode_heap_oop(d);
6404 %}
6405 ins_pipe(ialu_reg_long);
6406 %}
6408 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6409 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
6410 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
6411 match(Set dst (DecodeN src));
6412 effect(KILL cr);
6413 format %{ "decode_heap_oop_not_null $dst,$src" %}
6414 ins_encode %{
6415 Register s = $src$$Register;
6416 Register d = $dst$$Register;
6417 if (s != d) {
6418 __ decode_heap_oop_not_null(d, s);
6419 } else {
6420 __ decode_heap_oop_not_null(d);
6421 }
6422 %}
6423 ins_pipe(ialu_reg_long);
6424 %}
6426 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6427 match(Set dst (EncodePKlass src));
6428 effect(KILL cr);
6429 format %{ "encode_klass_not_null $dst,$src" %}
6430 ins_encode %{
6431 __ encode_klass_not_null($dst$$Register, $src$$Register);
6432 %}
6433 ins_pipe(ialu_reg_long);
6434 %}
6436 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6437 match(Set dst (DecodeNKlass src));
6438 effect(KILL cr);
6439 format %{ "decode_klass_not_null $dst,$src" %}
6440 ins_encode %{
6441 Register s = $src$$Register;
6442 Register d = $dst$$Register;
6443 if (s != d) {
6444 __ decode_klass_not_null(d, s);
6445 } else {
6446 __ decode_klass_not_null(d);
6447 }
6448 %}
6449 ins_pipe(ialu_reg_long);
6450 %}
6453 //----------Conditional Move---------------------------------------------------
6454 // Jump
6455 // dummy instruction for generating temp registers
6456 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
6457 match(Jump (LShiftL switch_val shift));
6458 ins_cost(350);
6459 predicate(false);
6460 effect(TEMP dest);
6462 format %{ "leaq $dest, [$constantaddress]\n\t"
6463 "jmp [$dest + $switch_val << $shift]\n\t" %}
6464 ins_encode %{
6465 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6466 // to do that and the compiler is using that register as one it can allocate.
6467 // So we build it all by hand.
6468 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
6469 // ArrayAddress dispatch(table, index);
6470 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
6471 __ lea($dest$$Register, $constantaddress);
6472 __ jmp(dispatch);
6473 %}
6474 ins_pipe(pipe_jmp);
6475 %}
6477 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
6478 match(Jump (AddL (LShiftL switch_val shift) offset));
6479 ins_cost(350);
6480 effect(TEMP dest);
6482 format %{ "leaq $dest, [$constantaddress]\n\t"
6483 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %}
6484 ins_encode %{
6485 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6486 // to do that and the compiler is using that register as one it can allocate.
6487 // So we build it all by hand.
6488 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6489 // ArrayAddress dispatch(table, index);
6490 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6491 __ lea($dest$$Register, $constantaddress);
6492 __ jmp(dispatch);
6493 %}
6494 ins_pipe(pipe_jmp);
6495 %}
6497 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
6498 match(Jump switch_val);
6499 ins_cost(350);
6500 effect(TEMP dest);
6502 format %{ "leaq $dest, [$constantaddress]\n\t"
6503 "jmp [$dest + $switch_val]\n\t" %}
6504 ins_encode %{
6505 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6506 // to do that and the compiler is using that register as one it can allocate.
6507 // So we build it all by hand.
6508 // Address index(noreg, switch_reg, Address::times_1);
6509 // ArrayAddress dispatch(table, index);
6510 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1);
6511 __ lea($dest$$Register, $constantaddress);
6512 __ jmp(dispatch);
6513 %}
6514 ins_pipe(pipe_jmp);
6515 %}
6517 // Conditional move
6518 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
6519 %{
6520 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6522 ins_cost(200); // XXX
6523 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
6524 opcode(0x0F, 0x40);
6525 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6526 ins_pipe(pipe_cmov_reg);
6527 %}
6529 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
6530 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6532 ins_cost(200); // XXX
6533 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
6534 opcode(0x0F, 0x40);
6535 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6536 ins_pipe(pipe_cmov_reg);
6537 %}
6539 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
6540 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6541 ins_cost(200);
6542 expand %{
6543 cmovI_regU(cop, cr, dst, src);
6544 %}
6545 %}
6547 // Conditional move
6548 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
6549 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6551 ins_cost(250); // XXX
6552 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
6553 opcode(0x0F, 0x40);
6554 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
6555 ins_pipe(pipe_cmov_mem);
6556 %}
6558 // Conditional move
6559 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
6560 %{
6561 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6563 ins_cost(250); // XXX
6564 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
6565 opcode(0x0F, 0x40);
6566 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
6567 ins_pipe(pipe_cmov_mem);
6568 %}
6570 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
6571 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6572 ins_cost(250);
6573 expand %{
6574 cmovI_memU(cop, cr, dst, src);
6575 %}
6576 %}
6578 // Conditional move
6579 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
6580 %{
6581 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6583 ins_cost(200); // XXX
6584 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
6585 opcode(0x0F, 0x40);
6586 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6587 ins_pipe(pipe_cmov_reg);
6588 %}
6590 // Conditional move
6591 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
6592 %{
6593 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6595 ins_cost(200); // XXX
6596 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
6597 opcode(0x0F, 0x40);
6598 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6599 ins_pipe(pipe_cmov_reg);
6600 %}
6602 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
6603 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6604 ins_cost(200);
6605 expand %{
6606 cmovN_regU(cop, cr, dst, src);
6607 %}
6608 %}
6610 // Conditional move
6611 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
6612 %{
6613 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6615 ins_cost(200); // XXX
6616 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %}
6617 opcode(0x0F, 0x40);
6618 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6619 ins_pipe(pipe_cmov_reg); // XXX
6620 %}
6622 // Conditional move
6623 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
6624 %{
6625 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6627 ins_cost(200); // XXX
6628 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %}
6629 opcode(0x0F, 0x40);
6630 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6631 ins_pipe(pipe_cmov_reg); // XXX
6632 %}
6634 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
6635 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6636 ins_cost(200);
6637 expand %{
6638 cmovP_regU(cop, cr, dst, src);
6639 %}
6640 %}
6642 // DISABLED: Requires the ADLC to emit a bottom_type call that
6643 // correctly meets the two pointer arguments; one is an incoming
6644 // register but the other is a memory operand. ALSO appears to
6645 // be buggy with implicit null checks.
6646 //
6647 //// Conditional move
6648 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src)
6649 //%{
6650 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
6651 // ins_cost(250);
6652 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
6653 // opcode(0x0F,0x40);
6654 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
6655 // ins_pipe( pipe_cmov_mem );
6656 //%}
6657 //
6658 //// Conditional move
6659 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src)
6660 //%{
6661 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
6662 // ins_cost(250);
6663 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
6664 // opcode(0x0F,0x40);
6665 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
6666 // ins_pipe( pipe_cmov_mem );
6667 //%}
6669 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src)
6670 %{
6671 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
6673 ins_cost(200); // XXX
6674 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
6675 opcode(0x0F, 0x40);
6676 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6677 ins_pipe(pipe_cmov_reg); // XXX
6678 %}
6680 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src)
6681 %{
6682 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
6684 ins_cost(200); // XXX
6685 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
6686 opcode(0x0F, 0x40);
6687 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
6688 ins_pipe(pipe_cmov_mem); // XXX
6689 %}
6691 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src)
6692 %{
6693 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
6695 ins_cost(200); // XXX
6696 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
6697 opcode(0x0F, 0x40);
6698 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6699 ins_pipe(pipe_cmov_reg); // XXX
6700 %}
6702 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
6703 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
6704 ins_cost(200);
6705 expand %{
6706 cmovL_regU(cop, cr, dst, src);
6707 %}
6708 %}
6710 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
6711 %{
6712 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
6714 ins_cost(200); // XXX
6715 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
6716 opcode(0x0F, 0x40);
6717 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
6718 ins_pipe(pipe_cmov_mem); // XXX
6719 %}
6721 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
6722 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
6723 ins_cost(200);
6724 expand %{
6725 cmovL_memU(cop, cr, dst, src);
6726 %}
6727 %}
6729 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
6730 %{
6731 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
6733 ins_cost(200); // XXX
6734 format %{ "jn$cop skip\t# signed cmove float\n\t"
6735 "movss $dst, $src\n"
6736 "skip:" %}
6737 ins_encode %{
6738 Label Lskip;
6739 // Invert sense of branch from sense of CMOV
6740 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
6741 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
6742 __ bind(Lskip);
6743 %}
6744 ins_pipe(pipe_slow);
6745 %}
6747 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
6748 // %{
6749 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src))));
6751 // ins_cost(200); // XXX
6752 // format %{ "jn$cop skip\t# signed cmove float\n\t"
6753 // "movss $dst, $src\n"
6754 // "skip:" %}
6755 // ins_encode(enc_cmovf_mem_branch(cop, dst, src));
6756 // ins_pipe(pipe_slow);
6757 // %}
6759 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
6760 %{
6761 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
6763 ins_cost(200); // XXX
6764 format %{ "jn$cop skip\t# unsigned cmove float\n\t"
6765 "movss $dst, $src\n"
6766 "skip:" %}
6767 ins_encode %{
6768 Label Lskip;
6769 // Invert sense of branch from sense of CMOV
6770 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
6771 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
6772 __ bind(Lskip);
6773 %}
6774 ins_pipe(pipe_slow);
6775 %}
6777 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
6778 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
6779 ins_cost(200);
6780 expand %{
6781 cmovF_regU(cop, cr, dst, src);
6782 %}
6783 %}
6785 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
6786 %{
6787 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
6789 ins_cost(200); // XXX
6790 format %{ "jn$cop skip\t# signed cmove double\n\t"
6791 "movsd $dst, $src\n"
6792 "skip:" %}
6793 ins_encode %{
6794 Label Lskip;
6795 // Invert sense of branch from sense of CMOV
6796 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
6797 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
6798 __ bind(Lskip);
6799 %}
6800 ins_pipe(pipe_slow);
6801 %}
6803 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
6804 %{
6805 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
6807 ins_cost(200); // XXX
6808 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
6809 "movsd $dst, $src\n"
6810 "skip:" %}
6811 ins_encode %{
6812 Label Lskip;
6813 // Invert sense of branch from sense of CMOV
6814 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
6815 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
6816 __ bind(Lskip);
6817 %}
6818 ins_pipe(pipe_slow);
6819 %}
6821 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
6822 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
6823 ins_cost(200);
6824 expand %{
6825 cmovD_regU(cop, cr, dst, src);
6826 %}
6827 %}
6829 //----------Arithmetic Instructions--------------------------------------------
6830 //----------Addition Instructions----------------------------------------------
6832 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
6833 %{
6834 match(Set dst (AddI dst src));
6835 effect(KILL cr);
6837 format %{ "addl $dst, $src\t# int" %}
6838 opcode(0x03);
6839 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
6840 ins_pipe(ialu_reg_reg);
6841 %}
6843 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
6844 %{
6845 match(Set dst (AddI dst src));
6846 effect(KILL cr);
6848 format %{ "addl $dst, $src\t# int" %}
6849 opcode(0x81, 0x00); /* /0 id */
6850 ins_encode(OpcSErm(dst, src), Con8or32(src));
6851 ins_pipe( ialu_reg );
6852 %}
6854 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
6855 %{
6856 match(Set dst (AddI dst (LoadI src)));
6857 effect(KILL cr);
6859 ins_cost(125); // XXX
6860 format %{ "addl $dst, $src\t# int" %}
6861 opcode(0x03);
6862 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
6863 ins_pipe(ialu_reg_mem);
6864 %}
6866 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
6867 %{
6868 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
6869 effect(KILL cr);
6871 ins_cost(150); // XXX
6872 format %{ "addl $dst, $src\t# int" %}
6873 opcode(0x01); /* Opcode 01 /r */
6874 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
6875 ins_pipe(ialu_mem_reg);
6876 %}
6878 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr)
6879 %{
6880 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
6881 effect(KILL cr);
6883 ins_cost(125); // XXX
6884 format %{ "addl $dst, $src\t# int" %}
6885 opcode(0x81); /* Opcode 81 /0 id */
6886 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
6887 ins_pipe(ialu_mem_imm);
6888 %}
6890 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
6891 %{
6892 predicate(UseIncDec);
6893 match(Set dst (AddI dst src));
6894 effect(KILL cr);
6896 format %{ "incl $dst\t# int" %}
6897 opcode(0xFF, 0x00); // FF /0
6898 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
6899 ins_pipe(ialu_reg);
6900 %}
6902 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr)
6903 %{
6904 predicate(UseIncDec);
6905 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
6906 effect(KILL cr);
6908 ins_cost(125); // XXX
6909 format %{ "incl $dst\t# int" %}
6910 opcode(0xFF); /* Opcode FF /0 */
6911 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst));
6912 ins_pipe(ialu_mem_imm);
6913 %}
6915 // XXX why does that use AddI
6916 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr)
6917 %{
6918 predicate(UseIncDec);
6919 match(Set dst (AddI dst src));
6920 effect(KILL cr);
6922 format %{ "decl $dst\t# int" %}
6923 opcode(0xFF, 0x01); // FF /1
6924 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
6925 ins_pipe(ialu_reg);
6926 %}
6928 // XXX why does that use AddI
6929 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr)
6930 %{
6931 predicate(UseIncDec);
6932 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
6933 effect(KILL cr);
6935 ins_cost(125); // XXX
6936 format %{ "decl $dst\t# int" %}
6937 opcode(0xFF); /* Opcode FF /1 */
6938 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst));
6939 ins_pipe(ialu_mem_imm);
6940 %}
6942 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1)
6943 %{
6944 match(Set dst (AddI src0 src1));
6946 ins_cost(110);
6947 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %}
6948 opcode(0x8D); /* 0x8D /r */
6949 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
6950 ins_pipe(ialu_reg_reg);
6951 %}
6953 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
6954 %{
6955 match(Set dst (AddL dst src));
6956 effect(KILL cr);
6958 format %{ "addq $dst, $src\t# long" %}
6959 opcode(0x03);
6960 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
6961 ins_pipe(ialu_reg_reg);
6962 %}
6964 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
6965 %{
6966 match(Set dst (AddL dst src));
6967 effect(KILL cr);
6969 format %{ "addq $dst, $src\t# long" %}
6970 opcode(0x81, 0x00); /* /0 id */
6971 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
6972 ins_pipe( ialu_reg );
6973 %}
6975 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
6976 %{
6977 match(Set dst (AddL dst (LoadL src)));
6978 effect(KILL cr);
6980 ins_cost(125); // XXX
6981 format %{ "addq $dst, $src\t# long" %}
6982 opcode(0x03);
6983 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
6984 ins_pipe(ialu_reg_mem);
6985 %}
6987 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
6988 %{
6989 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
6990 effect(KILL cr);
6992 ins_cost(150); // XXX
6993 format %{ "addq $dst, $src\t# long" %}
6994 opcode(0x01); /* Opcode 01 /r */
6995 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6996 ins_pipe(ialu_mem_reg);
6997 %}
6999 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
7000 %{
7001 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7002 effect(KILL cr);
7004 ins_cost(125); // XXX
7005 format %{ "addq $dst, $src\t# long" %}
7006 opcode(0x81); /* Opcode 81 /0 id */
7007 ins_encode(REX_mem_wide(dst),
7008 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
7009 ins_pipe(ialu_mem_imm);
7010 %}
7012 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr)
7013 %{
7014 predicate(UseIncDec);
7015 match(Set dst (AddL dst src));
7016 effect(KILL cr);
7018 format %{ "incq $dst\t# long" %}
7019 opcode(0xFF, 0x00); // FF /0
7020 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7021 ins_pipe(ialu_reg);
7022 %}
7024 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr)
7025 %{
7026 predicate(UseIncDec);
7027 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7028 effect(KILL cr);
7030 ins_cost(125); // XXX
7031 format %{ "incq $dst\t# long" %}
7032 opcode(0xFF); /* Opcode FF /0 */
7033 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst));
7034 ins_pipe(ialu_mem_imm);
7035 %}
7037 // XXX why does that use AddL
7038 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr)
7039 %{
7040 predicate(UseIncDec);
7041 match(Set dst (AddL dst src));
7042 effect(KILL cr);
7044 format %{ "decq $dst\t# long" %}
7045 opcode(0xFF, 0x01); // FF /1
7046 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7047 ins_pipe(ialu_reg);
7048 %}
7050 // XXX why does that use AddL
7051 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr)
7052 %{
7053 predicate(UseIncDec);
7054 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7055 effect(KILL cr);
7057 ins_cost(125); // XXX
7058 format %{ "decq $dst\t# long" %}
7059 opcode(0xFF); /* Opcode FF /1 */
7060 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst));
7061 ins_pipe(ialu_mem_imm);
7062 %}
7064 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1)
7065 %{
7066 match(Set dst (AddL src0 src1));
7068 ins_cost(110);
7069 format %{ "leaq $dst, [$src0 + $src1]\t# long" %}
7070 opcode(0x8D); /* 0x8D /r */
7071 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
7072 ins_pipe(ialu_reg_reg);
7073 %}
7075 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr)
7076 %{
7077 match(Set dst (AddP dst src));
7078 effect(KILL cr);
7080 format %{ "addq $dst, $src\t# ptr" %}
7081 opcode(0x03);
7082 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7083 ins_pipe(ialu_reg_reg);
7084 %}
7086 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr)
7087 %{
7088 match(Set dst (AddP dst src));
7089 effect(KILL cr);
7091 format %{ "addq $dst, $src\t# ptr" %}
7092 opcode(0x81, 0x00); /* /0 id */
7093 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7094 ins_pipe( ialu_reg );
7095 %}
7097 // XXX addP mem ops ????
7099 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1)
7100 %{
7101 match(Set dst (AddP src0 src1));
7103 ins_cost(110);
7104 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %}
7105 opcode(0x8D); /* 0x8D /r */
7106 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX
7107 ins_pipe(ialu_reg_reg);
7108 %}
7110 instruct checkCastPP(rRegP dst)
7111 %{
7112 match(Set dst (CheckCastPP dst));
7114 size(0);
7115 format %{ "# checkcastPP of $dst" %}
7116 ins_encode(/* empty encoding */);
7117 ins_pipe(empty);
7118 %}
7120 instruct castPP(rRegP dst)
7121 %{
7122 match(Set dst (CastPP dst));
7124 size(0);
7125 format %{ "# castPP of $dst" %}
7126 ins_encode(/* empty encoding */);
7127 ins_pipe(empty);
7128 %}
7130 instruct castII(rRegI dst)
7131 %{
7132 match(Set dst (CastII dst));
7134 size(0);
7135 format %{ "# castII of $dst" %}
7136 ins_encode(/* empty encoding */);
7137 ins_cost(0);
7138 ins_pipe(empty);
7139 %}
7141 // LoadP-locked same as a regular LoadP when used with compare-swap
7142 instruct loadPLocked(rRegP dst, memory mem)
7143 %{
7144 match(Set dst (LoadPLocked mem));
7146 ins_cost(125); // XXX
7147 format %{ "movq $dst, $mem\t# ptr locked" %}
7148 opcode(0x8B);
7149 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
7150 ins_pipe(ialu_reg_mem); // XXX
7151 %}
7153 // Conditional-store of the updated heap-top.
7154 // Used during allocation of the shared heap.
7155 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
7157 instruct storePConditional(memory heap_top_ptr,
7158 rax_RegP oldval, rRegP newval,
7159 rFlagsReg cr)
7160 %{
7161 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
7163 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
7164 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
7165 opcode(0x0F, 0xB1);
7166 ins_encode(lock_prefix,
7167 REX_reg_mem_wide(newval, heap_top_ptr),
7168 OpcP, OpcS,
7169 reg_mem(newval, heap_top_ptr));
7170 ins_pipe(pipe_cmpxchg);
7171 %}
7173 // Conditional-store of an int value.
7174 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
7175 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
7176 %{
7177 match(Set cr (StoreIConditional mem (Binary oldval newval)));
7178 effect(KILL oldval);
7180 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7181 opcode(0x0F, 0xB1);
7182 ins_encode(lock_prefix,
7183 REX_reg_mem(newval, mem),
7184 OpcP, OpcS,
7185 reg_mem(newval, mem));
7186 ins_pipe(pipe_cmpxchg);
7187 %}
7189 // Conditional-store of a long value.
7190 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
7191 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
7192 %{
7193 match(Set cr (StoreLConditional mem (Binary oldval newval)));
7194 effect(KILL oldval);
7196 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7197 opcode(0x0F, 0xB1);
7198 ins_encode(lock_prefix,
7199 REX_reg_mem_wide(newval, mem),
7200 OpcP, OpcS,
7201 reg_mem(newval, mem));
7202 ins_pipe(pipe_cmpxchg);
7203 %}
7206 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7207 instruct compareAndSwapP(rRegI res,
7208 memory mem_ptr,
7209 rax_RegP oldval, rRegP newval,
7210 rFlagsReg cr)
7211 %{
7212 predicate(VM_Version::supports_cx8());
7213 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7214 effect(KILL cr, KILL oldval);
7216 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7217 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7218 "sete $res\n\t"
7219 "movzbl $res, $res" %}
7220 opcode(0x0F, 0xB1);
7221 ins_encode(lock_prefix,
7222 REX_reg_mem_wide(newval, mem_ptr),
7223 OpcP, OpcS,
7224 reg_mem(newval, mem_ptr),
7225 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7226 REX_reg_breg(res, res), // movzbl
7227 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7228 ins_pipe( pipe_cmpxchg );
7229 %}
7231 instruct compareAndSwapL(rRegI res,
7232 memory mem_ptr,
7233 rax_RegL oldval, rRegL newval,
7234 rFlagsReg cr)
7235 %{
7236 predicate(VM_Version::supports_cx8());
7237 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7238 effect(KILL cr, KILL oldval);
7240 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7241 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7242 "sete $res\n\t"
7243 "movzbl $res, $res" %}
7244 opcode(0x0F, 0xB1);
7245 ins_encode(lock_prefix,
7246 REX_reg_mem_wide(newval, mem_ptr),
7247 OpcP, OpcS,
7248 reg_mem(newval, mem_ptr),
7249 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7250 REX_reg_breg(res, res), // movzbl
7251 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7252 ins_pipe( pipe_cmpxchg );
7253 %}
7255 instruct compareAndSwapI(rRegI res,
7256 memory mem_ptr,
7257 rax_RegI oldval, rRegI newval,
7258 rFlagsReg cr)
7259 %{
7260 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
7261 effect(KILL cr, KILL oldval);
7263 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7264 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7265 "sete $res\n\t"
7266 "movzbl $res, $res" %}
7267 opcode(0x0F, 0xB1);
7268 ins_encode(lock_prefix,
7269 REX_reg_mem(newval, mem_ptr),
7270 OpcP, OpcS,
7271 reg_mem(newval, mem_ptr),
7272 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7273 REX_reg_breg(res, res), // movzbl
7274 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7275 ins_pipe( pipe_cmpxchg );
7276 %}
7279 instruct compareAndSwapN(rRegI res,
7280 memory mem_ptr,
7281 rax_RegN oldval, rRegN newval,
7282 rFlagsReg cr) %{
7283 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7284 effect(KILL cr, KILL oldval);
7286 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7287 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7288 "sete $res\n\t"
7289 "movzbl $res, $res" %}
7290 opcode(0x0F, 0xB1);
7291 ins_encode(lock_prefix,
7292 REX_reg_mem(newval, mem_ptr),
7293 OpcP, OpcS,
7294 reg_mem(newval, mem_ptr),
7295 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7296 REX_reg_breg(res, res), // movzbl
7297 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7298 ins_pipe( pipe_cmpxchg );
7299 %}
7301 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
7302 predicate(n->as_LoadStore()->result_not_used());
7303 match(Set dummy (GetAndAddI mem add));
7304 effect(KILL cr);
7305 format %{ "ADDL [$mem],$add" %}
7306 ins_encode %{
7307 if (os::is_MP()) { __ lock(); }
7308 __ addl($mem$$Address, $add$$constant);
7309 %}
7310 ins_pipe( pipe_cmpxchg );
7311 %}
7313 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{
7314 match(Set newval (GetAndAddI mem newval));
7315 effect(KILL cr);
7316 format %{ "XADDL [$mem],$newval" %}
7317 ins_encode %{
7318 if (os::is_MP()) { __ lock(); }
7319 __ xaddl($mem$$Address, $newval$$Register);
7320 %}
7321 ins_pipe( pipe_cmpxchg );
7322 %}
7324 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{
7325 predicate(n->as_LoadStore()->result_not_used());
7326 match(Set dummy (GetAndAddL mem add));
7327 effect(KILL cr);
7328 format %{ "ADDQ [$mem],$add" %}
7329 ins_encode %{
7330 if (os::is_MP()) { __ lock(); }
7331 __ addq($mem$$Address, $add$$constant);
7332 %}
7333 ins_pipe( pipe_cmpxchg );
7334 %}
7336 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{
7337 match(Set newval (GetAndAddL mem newval));
7338 effect(KILL cr);
7339 format %{ "XADDQ [$mem],$newval" %}
7340 ins_encode %{
7341 if (os::is_MP()) { __ lock(); }
7342 __ xaddq($mem$$Address, $newval$$Register);
7343 %}
7344 ins_pipe( pipe_cmpxchg );
7345 %}
7347 instruct xchgI( memory mem, rRegI newval) %{
7348 match(Set newval (GetAndSetI mem newval));
7349 format %{ "XCHGL $newval,[$mem]" %}
7350 ins_encode %{
7351 __ xchgl($newval$$Register, $mem$$Address);
7352 %}
7353 ins_pipe( pipe_cmpxchg );
7354 %}
7356 instruct xchgL( memory mem, rRegL newval) %{
7357 match(Set newval (GetAndSetL mem newval));
7358 format %{ "XCHGL $newval,[$mem]" %}
7359 ins_encode %{
7360 __ xchgq($newval$$Register, $mem$$Address);
7361 %}
7362 ins_pipe( pipe_cmpxchg );
7363 %}
7365 instruct xchgP( memory mem, rRegP newval) %{
7366 match(Set newval (GetAndSetP mem newval));
7367 format %{ "XCHGQ $newval,[$mem]" %}
7368 ins_encode %{
7369 __ xchgq($newval$$Register, $mem$$Address);
7370 %}
7371 ins_pipe( pipe_cmpxchg );
7372 %}
7374 instruct xchgN( memory mem, rRegN newval) %{
7375 match(Set newval (GetAndSetN mem newval));
7376 format %{ "XCHGL $newval,$mem]" %}
7377 ins_encode %{
7378 __ xchgl($newval$$Register, $mem$$Address);
7379 %}
7380 ins_pipe( pipe_cmpxchg );
7381 %}
7383 //----------Subtraction Instructions-------------------------------------------
7385 // Integer Subtraction Instructions
7386 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7387 %{
7388 match(Set dst (SubI dst src));
7389 effect(KILL cr);
7391 format %{ "subl $dst, $src\t# int" %}
7392 opcode(0x2B);
7393 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
7394 ins_pipe(ialu_reg_reg);
7395 %}
7397 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7398 %{
7399 match(Set dst (SubI dst src));
7400 effect(KILL cr);
7402 format %{ "subl $dst, $src\t# int" %}
7403 opcode(0x81, 0x05); /* Opcode 81 /5 */
7404 ins_encode(OpcSErm(dst, src), Con8or32(src));
7405 ins_pipe(ialu_reg);
7406 %}
7408 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
7409 %{
7410 match(Set dst (SubI dst (LoadI src)));
7411 effect(KILL cr);
7413 ins_cost(125);
7414 format %{ "subl $dst, $src\t# int" %}
7415 opcode(0x2B);
7416 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
7417 ins_pipe(ialu_reg_mem);
7418 %}
7420 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
7421 %{
7422 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
7423 effect(KILL cr);
7425 ins_cost(150);
7426 format %{ "subl $dst, $src\t# int" %}
7427 opcode(0x29); /* Opcode 29 /r */
7428 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
7429 ins_pipe(ialu_mem_reg);
7430 %}
7432 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr)
7433 %{
7434 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
7435 effect(KILL cr);
7437 ins_cost(125); // XXX
7438 format %{ "subl $dst, $src\t# int" %}
7439 opcode(0x81); /* Opcode 81 /5 id */
7440 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
7441 ins_pipe(ialu_mem_imm);
7442 %}
7444 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7445 %{
7446 match(Set dst (SubL dst src));
7447 effect(KILL cr);
7449 format %{ "subq $dst, $src\t# long" %}
7450 opcode(0x2B);
7451 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7452 ins_pipe(ialu_reg_reg);
7453 %}
7455 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr)
7456 %{
7457 match(Set dst (SubL dst src));
7458 effect(KILL cr);
7460 format %{ "subq $dst, $src\t# long" %}
7461 opcode(0x81, 0x05); /* Opcode 81 /5 */
7462 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7463 ins_pipe(ialu_reg);
7464 %}
7466 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
7467 %{
7468 match(Set dst (SubL dst (LoadL src)));
7469 effect(KILL cr);
7471 ins_cost(125);
7472 format %{ "subq $dst, $src\t# long" %}
7473 opcode(0x2B);
7474 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
7475 ins_pipe(ialu_reg_mem);
7476 %}
7478 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
7479 %{
7480 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
7481 effect(KILL cr);
7483 ins_cost(150);
7484 format %{ "subq $dst, $src\t# long" %}
7485 opcode(0x29); /* Opcode 29 /r */
7486 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7487 ins_pipe(ialu_mem_reg);
7488 %}
7490 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
7491 %{
7492 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
7493 effect(KILL cr);
7495 ins_cost(125); // XXX
7496 format %{ "subq $dst, $src\t# long" %}
7497 opcode(0x81); /* Opcode 81 /5 id */
7498 ins_encode(REX_mem_wide(dst),
7499 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
7500 ins_pipe(ialu_mem_imm);
7501 %}
7503 // Subtract from a pointer
7504 // XXX hmpf???
7505 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr)
7506 %{
7507 match(Set dst (AddP dst (SubI zero src)));
7508 effect(KILL cr);
7510 format %{ "subq $dst, $src\t# ptr - int" %}
7511 opcode(0x2B);
7512 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7513 ins_pipe(ialu_reg_reg);
7514 %}
7516 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr)
7517 %{
7518 match(Set dst (SubI zero dst));
7519 effect(KILL cr);
7521 format %{ "negl $dst\t# int" %}
7522 opcode(0xF7, 0x03); // Opcode F7 /3
7523 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7524 ins_pipe(ialu_reg);
7525 %}
7527 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr)
7528 %{
7529 match(Set dst (StoreI dst (SubI zero (LoadI dst))));
7530 effect(KILL cr);
7532 format %{ "negl $dst\t# int" %}
7533 opcode(0xF7, 0x03); // Opcode F7 /3
7534 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
7535 ins_pipe(ialu_reg);
7536 %}
7538 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr)
7539 %{
7540 match(Set dst (SubL zero dst));
7541 effect(KILL cr);
7543 format %{ "negq $dst\t# long" %}
7544 opcode(0xF7, 0x03); // Opcode F7 /3
7545 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7546 ins_pipe(ialu_reg);
7547 %}
7549 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr)
7550 %{
7551 match(Set dst (StoreL dst (SubL zero (LoadL dst))));
7552 effect(KILL cr);
7554 format %{ "negq $dst\t# long" %}
7555 opcode(0xF7, 0x03); // Opcode F7 /3
7556 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
7557 ins_pipe(ialu_reg);
7558 %}
7560 //----------Multiplication/Division Instructions-------------------------------
7561 // Integer Multiplication Instructions
7562 // Multiply Register
7564 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7565 %{
7566 match(Set dst (MulI dst src));
7567 effect(KILL cr);
7569 ins_cost(300);
7570 format %{ "imull $dst, $src\t# int" %}
7571 opcode(0x0F, 0xAF);
7572 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
7573 ins_pipe(ialu_reg_reg_alu0);
7574 %}
7576 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr)
7577 %{
7578 match(Set dst (MulI src imm));
7579 effect(KILL cr);
7581 ins_cost(300);
7582 format %{ "imull $dst, $src, $imm\t# int" %}
7583 opcode(0x69); /* 69 /r id */
7584 ins_encode(REX_reg_reg(dst, src),
7585 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
7586 ins_pipe(ialu_reg_reg_alu0);
7587 %}
7589 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr)
7590 %{
7591 match(Set dst (MulI dst (LoadI src)));
7592 effect(KILL cr);
7594 ins_cost(350);
7595 format %{ "imull $dst, $src\t# int" %}
7596 opcode(0x0F, 0xAF);
7597 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src));
7598 ins_pipe(ialu_reg_mem_alu0);
7599 %}
7601 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr)
7602 %{
7603 match(Set dst (MulI (LoadI src) imm));
7604 effect(KILL cr);
7606 ins_cost(300);
7607 format %{ "imull $dst, $src, $imm\t# int" %}
7608 opcode(0x69); /* 69 /r id */
7609 ins_encode(REX_reg_mem(dst, src),
7610 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
7611 ins_pipe(ialu_reg_mem_alu0);
7612 %}
7614 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7615 %{
7616 match(Set dst (MulL dst src));
7617 effect(KILL cr);
7619 ins_cost(300);
7620 format %{ "imulq $dst, $src\t# long" %}
7621 opcode(0x0F, 0xAF);
7622 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src));
7623 ins_pipe(ialu_reg_reg_alu0);
7624 %}
7626 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr)
7627 %{
7628 match(Set dst (MulL src imm));
7629 effect(KILL cr);
7631 ins_cost(300);
7632 format %{ "imulq $dst, $src, $imm\t# long" %}
7633 opcode(0x69); /* 69 /r id */
7634 ins_encode(REX_reg_reg_wide(dst, src),
7635 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
7636 ins_pipe(ialu_reg_reg_alu0);
7637 %}
7639 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr)
7640 %{
7641 match(Set dst (MulL dst (LoadL src)));
7642 effect(KILL cr);
7644 ins_cost(350);
7645 format %{ "imulq $dst, $src\t# long" %}
7646 opcode(0x0F, 0xAF);
7647 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src));
7648 ins_pipe(ialu_reg_mem_alu0);
7649 %}
7651 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr)
7652 %{
7653 match(Set dst (MulL (LoadL src) imm));
7654 effect(KILL cr);
7656 ins_cost(300);
7657 format %{ "imulq $dst, $src, $imm\t# long" %}
7658 opcode(0x69); /* 69 /r id */
7659 ins_encode(REX_reg_mem_wide(dst, src),
7660 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
7661 ins_pipe(ialu_reg_mem_alu0);
7662 %}
7664 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
7665 %{
7666 match(Set dst (MulHiL src rax));
7667 effect(USE_KILL rax, KILL cr);
7669 ins_cost(300);
7670 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %}
7671 opcode(0xF7, 0x5); /* Opcode F7 /5 */
7672 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
7673 ins_pipe(ialu_reg_reg_alu0);
7674 %}
7676 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
7677 rFlagsReg cr)
7678 %{
7679 match(Set rax (DivI rax div));
7680 effect(KILL rdx, KILL cr);
7682 ins_cost(30*100+10*100); // XXX
7683 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
7684 "jne,s normal\n\t"
7685 "xorl rdx, rdx\n\t"
7686 "cmpl $div, -1\n\t"
7687 "je,s done\n"
7688 "normal: cdql\n\t"
7689 "idivl $div\n"
7690 "done:" %}
7691 opcode(0xF7, 0x7); /* Opcode F7 /7 */
7692 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
7693 ins_pipe(ialu_reg_reg_alu0);
7694 %}
7696 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
7697 rFlagsReg cr)
7698 %{
7699 match(Set rax (DivL rax div));
7700 effect(KILL rdx, KILL cr);
7702 ins_cost(30*100+10*100); // XXX
7703 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
7704 "cmpq rax, rdx\n\t"
7705 "jne,s normal\n\t"
7706 "xorl rdx, rdx\n\t"
7707 "cmpq $div, -1\n\t"
7708 "je,s done\n"
7709 "normal: cdqq\n\t"
7710 "idivq $div\n"
7711 "done:" %}
7712 opcode(0xF7, 0x7); /* Opcode F7 /7 */
7713 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
7714 ins_pipe(ialu_reg_reg_alu0);
7715 %}
7717 // Integer DIVMOD with Register, both quotient and mod results
7718 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
7719 rFlagsReg cr)
7720 %{
7721 match(DivModI rax div);
7722 effect(KILL cr);
7724 ins_cost(30*100+10*100); // XXX
7725 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
7726 "jne,s normal\n\t"
7727 "xorl rdx, rdx\n\t"
7728 "cmpl $div, -1\n\t"
7729 "je,s done\n"
7730 "normal: cdql\n\t"
7731 "idivl $div\n"
7732 "done:" %}
7733 opcode(0xF7, 0x7); /* Opcode F7 /7 */
7734 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
7735 ins_pipe(pipe_slow);
7736 %}
7738 // Long DIVMOD with Register, both quotient and mod results
7739 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
7740 rFlagsReg cr)
7741 %{
7742 match(DivModL rax div);
7743 effect(KILL cr);
7745 ins_cost(30*100+10*100); // XXX
7746 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
7747 "cmpq rax, rdx\n\t"
7748 "jne,s normal\n\t"
7749 "xorl rdx, rdx\n\t"
7750 "cmpq $div, -1\n\t"
7751 "je,s done\n"
7752 "normal: cdqq\n\t"
7753 "idivq $div\n"
7754 "done:" %}
7755 opcode(0xF7, 0x7); /* Opcode F7 /7 */
7756 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
7757 ins_pipe(pipe_slow);
7758 %}
7760 //----------- DivL-By-Constant-Expansions--------------------------------------
7761 // DivI cases are handled by the compiler
7763 // Magic constant, reciprocal of 10
7764 instruct loadConL_0x6666666666666667(rRegL dst)
7765 %{
7766 effect(DEF dst);
7768 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %}
7769 ins_encode(load_immL(dst, 0x6666666666666667));
7770 ins_pipe(ialu_reg);
7771 %}
7773 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
7774 %{
7775 effect(DEF dst, USE src, USE_KILL rax, KILL cr);
7777 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %}
7778 opcode(0xF7, 0x5); /* Opcode F7 /5 */
7779 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
7780 ins_pipe(ialu_reg_reg_alu0);
7781 %}
7783 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr)
7784 %{
7785 effect(USE_DEF dst, KILL cr);
7787 format %{ "sarq $dst, #63\t# Used in div-by-10" %}
7788 opcode(0xC1, 0x7); /* C1 /7 ib */
7789 ins_encode(reg_opc_imm_wide(dst, 0x3F));
7790 ins_pipe(ialu_reg);
7791 %}
7793 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr)
7794 %{
7795 effect(USE_DEF dst, KILL cr);
7797 format %{ "sarq $dst, #2\t# Used in div-by-10" %}
7798 opcode(0xC1, 0x7); /* C1 /7 ib */
7799 ins_encode(reg_opc_imm_wide(dst, 0x2));
7800 ins_pipe(ialu_reg);
7801 %}
7803 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div)
7804 %{
7805 match(Set dst (DivL src div));
7807 ins_cost((5+8)*100);
7808 expand %{
7809 rax_RegL rax; // Killed temp
7810 rFlagsReg cr; // Killed
7811 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667
7812 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src
7813 sarL_rReg_63(src, cr); // sarq src, 63
7814 sarL_rReg_2(dst, cr); // sarq rdx, 2
7815 subL_rReg(dst, src, cr); // subl rdx, src
7816 %}
7817 %}
7819 //-----------------------------------------------------------------------------
7821 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div,
7822 rFlagsReg cr)
7823 %{
7824 match(Set rdx (ModI rax div));
7825 effect(KILL rax, KILL cr);
7827 ins_cost(300); // XXX
7828 format %{ "cmpl rax, 0x80000000\t# irem\n\t"
7829 "jne,s normal\n\t"
7830 "xorl rdx, rdx\n\t"
7831 "cmpl $div, -1\n\t"
7832 "je,s done\n"
7833 "normal: cdql\n\t"
7834 "idivl $div\n"
7835 "done:" %}
7836 opcode(0xF7, 0x7); /* Opcode F7 /7 */
7837 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
7838 ins_pipe(ialu_reg_reg_alu0);
7839 %}
7841 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div,
7842 rFlagsReg cr)
7843 %{
7844 match(Set rdx (ModL rax div));
7845 effect(KILL rax, KILL cr);
7847 ins_cost(300); // XXX
7848 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t"
7849 "cmpq rax, rdx\n\t"
7850 "jne,s normal\n\t"
7851 "xorl rdx, rdx\n\t"
7852 "cmpq $div, -1\n\t"
7853 "je,s done\n"
7854 "normal: cdqq\n\t"
7855 "idivq $div\n"
7856 "done:" %}
7857 opcode(0xF7, 0x7); /* Opcode F7 /7 */
7858 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
7859 ins_pipe(ialu_reg_reg_alu0);
7860 %}
7862 // Integer Shift Instructions
7863 // Shift Left by one
7864 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
7865 %{
7866 match(Set dst (LShiftI dst shift));
7867 effect(KILL cr);
7869 format %{ "sall $dst, $shift" %}
7870 opcode(0xD1, 0x4); /* D1 /4 */
7871 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7872 ins_pipe(ialu_reg);
7873 %}
7875 // Shift Left by one
7876 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
7877 %{
7878 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
7879 effect(KILL cr);
7881 format %{ "sall $dst, $shift\t" %}
7882 opcode(0xD1, 0x4); /* D1 /4 */
7883 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
7884 ins_pipe(ialu_mem_imm);
7885 %}
7887 // Shift Left by 8-bit immediate
7888 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
7889 %{
7890 match(Set dst (LShiftI dst shift));
7891 effect(KILL cr);
7893 format %{ "sall $dst, $shift" %}
7894 opcode(0xC1, 0x4); /* C1 /4 ib */
7895 ins_encode(reg_opc_imm(dst, shift));
7896 ins_pipe(ialu_reg);
7897 %}
7899 // Shift Left by 8-bit immediate
7900 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
7901 %{
7902 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
7903 effect(KILL cr);
7905 format %{ "sall $dst, $shift" %}
7906 opcode(0xC1, 0x4); /* C1 /4 ib */
7907 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
7908 ins_pipe(ialu_mem_imm);
7909 %}
7911 // Shift Left by variable
7912 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
7913 %{
7914 match(Set dst (LShiftI dst shift));
7915 effect(KILL cr);
7917 format %{ "sall $dst, $shift" %}
7918 opcode(0xD3, 0x4); /* D3 /4 */
7919 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7920 ins_pipe(ialu_reg_reg);
7921 %}
7923 // Shift Left by variable
7924 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
7925 %{
7926 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
7927 effect(KILL cr);
7929 format %{ "sall $dst, $shift" %}
7930 opcode(0xD3, 0x4); /* D3 /4 */
7931 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
7932 ins_pipe(ialu_mem_reg);
7933 %}
7935 // Arithmetic shift right by one
7936 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
7937 %{
7938 match(Set dst (RShiftI dst shift));
7939 effect(KILL cr);
7941 format %{ "sarl $dst, $shift" %}
7942 opcode(0xD1, 0x7); /* D1 /7 */
7943 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7944 ins_pipe(ialu_reg);
7945 %}
7947 // Arithmetic shift right by one
7948 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
7949 %{
7950 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
7951 effect(KILL cr);
7953 format %{ "sarl $dst, $shift" %}
7954 opcode(0xD1, 0x7); /* D1 /7 */
7955 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
7956 ins_pipe(ialu_mem_imm);
7957 %}
7959 // Arithmetic Shift Right by 8-bit immediate
7960 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
7961 %{
7962 match(Set dst (RShiftI dst shift));
7963 effect(KILL cr);
7965 format %{ "sarl $dst, $shift" %}
7966 opcode(0xC1, 0x7); /* C1 /7 ib */
7967 ins_encode(reg_opc_imm(dst, shift));
7968 ins_pipe(ialu_mem_imm);
7969 %}
7971 // Arithmetic Shift Right by 8-bit immediate
7972 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
7973 %{
7974 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
7975 effect(KILL cr);
7977 format %{ "sarl $dst, $shift" %}
7978 opcode(0xC1, 0x7); /* C1 /7 ib */
7979 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
7980 ins_pipe(ialu_mem_imm);
7981 %}
7983 // Arithmetic Shift Right by variable
7984 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
7985 %{
7986 match(Set dst (RShiftI dst shift));
7987 effect(KILL cr);
7989 format %{ "sarl $dst, $shift" %}
7990 opcode(0xD3, 0x7); /* D3 /7 */
7991 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7992 ins_pipe(ialu_reg_reg);
7993 %}
7995 // Arithmetic Shift Right by variable
7996 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
7997 %{
7998 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
7999 effect(KILL cr);
8001 format %{ "sarl $dst, $shift" %}
8002 opcode(0xD3, 0x7); /* D3 /7 */
8003 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8004 ins_pipe(ialu_mem_reg);
8005 %}
8007 // Logical shift right by one
8008 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8009 %{
8010 match(Set dst (URShiftI dst shift));
8011 effect(KILL cr);
8013 format %{ "shrl $dst, $shift" %}
8014 opcode(0xD1, 0x5); /* D1 /5 */
8015 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8016 ins_pipe(ialu_reg);
8017 %}
8019 // Logical shift right by one
8020 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8021 %{
8022 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8023 effect(KILL cr);
8025 format %{ "shrl $dst, $shift" %}
8026 opcode(0xD1, 0x5); /* D1 /5 */
8027 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8028 ins_pipe(ialu_mem_imm);
8029 %}
8031 // Logical Shift Right by 8-bit immediate
8032 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8033 %{
8034 match(Set dst (URShiftI dst shift));
8035 effect(KILL cr);
8037 format %{ "shrl $dst, $shift" %}
8038 opcode(0xC1, 0x5); /* C1 /5 ib */
8039 ins_encode(reg_opc_imm(dst, shift));
8040 ins_pipe(ialu_reg);
8041 %}
8043 // Logical Shift Right by 8-bit immediate
8044 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8045 %{
8046 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8047 effect(KILL cr);
8049 format %{ "shrl $dst, $shift" %}
8050 opcode(0xC1, 0x5); /* C1 /5 ib */
8051 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8052 ins_pipe(ialu_mem_imm);
8053 %}
8055 // Logical Shift Right by variable
8056 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8057 %{
8058 match(Set dst (URShiftI dst shift));
8059 effect(KILL cr);
8061 format %{ "shrl $dst, $shift" %}
8062 opcode(0xD3, 0x5); /* D3 /5 */
8063 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8064 ins_pipe(ialu_reg_reg);
8065 %}
8067 // Logical Shift Right by variable
8068 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8069 %{
8070 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8071 effect(KILL cr);
8073 format %{ "shrl $dst, $shift" %}
8074 opcode(0xD3, 0x5); /* D3 /5 */
8075 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8076 ins_pipe(ialu_mem_reg);
8077 %}
8079 // Long Shift Instructions
8080 // Shift Left by one
8081 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8082 %{
8083 match(Set dst (LShiftL dst shift));
8084 effect(KILL cr);
8086 format %{ "salq $dst, $shift" %}
8087 opcode(0xD1, 0x4); /* D1 /4 */
8088 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8089 ins_pipe(ialu_reg);
8090 %}
8092 // Shift Left by one
8093 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8094 %{
8095 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8096 effect(KILL cr);
8098 format %{ "salq $dst, $shift" %}
8099 opcode(0xD1, 0x4); /* D1 /4 */
8100 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8101 ins_pipe(ialu_mem_imm);
8102 %}
8104 // Shift Left by 8-bit immediate
8105 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8106 %{
8107 match(Set dst (LShiftL dst shift));
8108 effect(KILL cr);
8110 format %{ "salq $dst, $shift" %}
8111 opcode(0xC1, 0x4); /* C1 /4 ib */
8112 ins_encode(reg_opc_imm_wide(dst, shift));
8113 ins_pipe(ialu_reg);
8114 %}
8116 // Shift Left by 8-bit immediate
8117 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8118 %{
8119 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8120 effect(KILL cr);
8122 format %{ "salq $dst, $shift" %}
8123 opcode(0xC1, 0x4); /* C1 /4 ib */
8124 ins_encode(REX_mem_wide(dst), OpcP,
8125 RM_opc_mem(secondary, dst), Con8or32(shift));
8126 ins_pipe(ialu_mem_imm);
8127 %}
8129 // Shift Left by variable
8130 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8131 %{
8132 match(Set dst (LShiftL dst shift));
8133 effect(KILL cr);
8135 format %{ "salq $dst, $shift" %}
8136 opcode(0xD3, 0x4); /* D3 /4 */
8137 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8138 ins_pipe(ialu_reg_reg);
8139 %}
8141 // Shift Left by variable
8142 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8143 %{
8144 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8145 effect(KILL cr);
8147 format %{ "salq $dst, $shift" %}
8148 opcode(0xD3, 0x4); /* D3 /4 */
8149 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8150 ins_pipe(ialu_mem_reg);
8151 %}
8153 // Arithmetic shift right by one
8154 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8155 %{
8156 match(Set dst (RShiftL dst shift));
8157 effect(KILL cr);
8159 format %{ "sarq $dst, $shift" %}
8160 opcode(0xD1, 0x7); /* D1 /7 */
8161 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8162 ins_pipe(ialu_reg);
8163 %}
8165 // Arithmetic shift right by one
8166 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8167 %{
8168 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8169 effect(KILL cr);
8171 format %{ "sarq $dst, $shift" %}
8172 opcode(0xD1, 0x7); /* D1 /7 */
8173 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8174 ins_pipe(ialu_mem_imm);
8175 %}
8177 // Arithmetic Shift Right by 8-bit immediate
8178 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8179 %{
8180 match(Set dst (RShiftL dst shift));
8181 effect(KILL cr);
8183 format %{ "sarq $dst, $shift" %}
8184 opcode(0xC1, 0x7); /* C1 /7 ib */
8185 ins_encode(reg_opc_imm_wide(dst, shift));
8186 ins_pipe(ialu_mem_imm);
8187 %}
8189 // Arithmetic Shift Right by 8-bit immediate
8190 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8191 %{
8192 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8193 effect(KILL cr);
8195 format %{ "sarq $dst, $shift" %}
8196 opcode(0xC1, 0x7); /* C1 /7 ib */
8197 ins_encode(REX_mem_wide(dst), OpcP,
8198 RM_opc_mem(secondary, dst), Con8or32(shift));
8199 ins_pipe(ialu_mem_imm);
8200 %}
8202 // Arithmetic Shift Right by variable
8203 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8204 %{
8205 match(Set dst (RShiftL dst shift));
8206 effect(KILL cr);
8208 format %{ "sarq $dst, $shift" %}
8209 opcode(0xD3, 0x7); /* D3 /7 */
8210 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8211 ins_pipe(ialu_reg_reg);
8212 %}
8214 // Arithmetic Shift Right by variable
8215 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8216 %{
8217 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8218 effect(KILL cr);
8220 format %{ "sarq $dst, $shift" %}
8221 opcode(0xD3, 0x7); /* D3 /7 */
8222 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8223 ins_pipe(ialu_mem_reg);
8224 %}
8226 // Logical shift right by one
8227 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8228 %{
8229 match(Set dst (URShiftL dst shift));
8230 effect(KILL cr);
8232 format %{ "shrq $dst, $shift" %}
8233 opcode(0xD1, 0x5); /* D1 /5 */
8234 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst ));
8235 ins_pipe(ialu_reg);
8236 %}
8238 // Logical shift right by one
8239 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8240 %{
8241 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8242 effect(KILL cr);
8244 format %{ "shrq $dst, $shift" %}
8245 opcode(0xD1, 0x5); /* D1 /5 */
8246 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8247 ins_pipe(ialu_mem_imm);
8248 %}
8250 // Logical Shift Right by 8-bit immediate
8251 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8252 %{
8253 match(Set dst (URShiftL dst shift));
8254 effect(KILL cr);
8256 format %{ "shrq $dst, $shift" %}
8257 opcode(0xC1, 0x5); /* C1 /5 ib */
8258 ins_encode(reg_opc_imm_wide(dst, shift));
8259 ins_pipe(ialu_reg);
8260 %}
8263 // Logical Shift Right by 8-bit immediate
8264 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8265 %{
8266 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8267 effect(KILL cr);
8269 format %{ "shrq $dst, $shift" %}
8270 opcode(0xC1, 0x5); /* C1 /5 ib */
8271 ins_encode(REX_mem_wide(dst), OpcP,
8272 RM_opc_mem(secondary, dst), Con8or32(shift));
8273 ins_pipe(ialu_mem_imm);
8274 %}
8276 // Logical Shift Right by variable
8277 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8278 %{
8279 match(Set dst (URShiftL dst shift));
8280 effect(KILL cr);
8282 format %{ "shrq $dst, $shift" %}
8283 opcode(0xD3, 0x5); /* D3 /5 */
8284 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8285 ins_pipe(ialu_reg_reg);
8286 %}
8288 // Logical Shift Right by variable
8289 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8290 %{
8291 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8292 effect(KILL cr);
8294 format %{ "shrq $dst, $shift" %}
8295 opcode(0xD3, 0x5); /* D3 /5 */
8296 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8297 ins_pipe(ialu_mem_reg);
8298 %}
8300 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
8301 // This idiom is used by the compiler for the i2b bytecode.
8302 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour)
8303 %{
8304 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
8306 format %{ "movsbl $dst, $src\t# i2b" %}
8307 opcode(0x0F, 0xBE);
8308 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8309 ins_pipe(ialu_reg_reg);
8310 %}
8312 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
8313 // This idiom is used by the compiler the i2s bytecode.
8314 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen)
8315 %{
8316 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
8318 format %{ "movswl $dst, $src\t# i2s" %}
8319 opcode(0x0F, 0xBF);
8320 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8321 ins_pipe(ialu_reg_reg);
8322 %}
8324 // ROL/ROR instructions
8326 // ROL expand
8327 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{
8328 effect(KILL cr, USE_DEF dst);
8330 format %{ "roll $dst" %}
8331 opcode(0xD1, 0x0); /* Opcode D1 /0 */
8332 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8333 ins_pipe(ialu_reg);
8334 %}
8336 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{
8337 effect(USE_DEF dst, USE shift, KILL cr);
8339 format %{ "roll $dst, $shift" %}
8340 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
8341 ins_encode( reg_opc_imm(dst, shift) );
8342 ins_pipe(ialu_reg);
8343 %}
8345 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
8346 %{
8347 effect(USE_DEF dst, USE shift, KILL cr);
8349 format %{ "roll $dst, $shift" %}
8350 opcode(0xD3, 0x0); /* Opcode D3 /0 */
8351 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8352 ins_pipe(ialu_reg_reg);
8353 %}
8354 // end of ROL expand
8356 // Rotate Left by one
8357 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
8358 %{
8359 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8361 expand %{
8362 rolI_rReg_imm1(dst, cr);
8363 %}
8364 %}
8366 // Rotate Left by 8-bit immediate
8367 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
8368 %{
8369 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8370 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8372 expand %{
8373 rolI_rReg_imm8(dst, lshift, cr);
8374 %}
8375 %}
8377 // Rotate Left by variable
8378 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8379 %{
8380 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift))));
8382 expand %{
8383 rolI_rReg_CL(dst, shift, cr);
8384 %}
8385 %}
8387 // Rotate Left by variable
8388 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
8389 %{
8390 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift))));
8392 expand %{
8393 rolI_rReg_CL(dst, shift, cr);
8394 %}
8395 %}
8397 // ROR expand
8398 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr)
8399 %{
8400 effect(USE_DEF dst, KILL cr);
8402 format %{ "rorl $dst" %}
8403 opcode(0xD1, 0x1); /* D1 /1 */
8404 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8405 ins_pipe(ialu_reg);
8406 %}
8408 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr)
8409 %{
8410 effect(USE_DEF dst, USE shift, KILL cr);
8412 format %{ "rorl $dst, $shift" %}
8413 opcode(0xC1, 0x1); /* C1 /1 ib */
8414 ins_encode(reg_opc_imm(dst, shift));
8415 ins_pipe(ialu_reg);
8416 %}
8418 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
8419 %{
8420 effect(USE_DEF dst, USE shift, KILL cr);
8422 format %{ "rorl $dst, $shift" %}
8423 opcode(0xD3, 0x1); /* D3 /1 */
8424 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8425 ins_pipe(ialu_reg_reg);
8426 %}
8427 // end of ROR expand
8429 // Rotate Right by one
8430 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
8431 %{
8432 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8434 expand %{
8435 rorI_rReg_imm1(dst, cr);
8436 %}
8437 %}
8439 // Rotate Right by 8-bit immediate
8440 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
8441 %{
8442 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8443 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8445 expand %{
8446 rorI_rReg_imm8(dst, rshift, cr);
8447 %}
8448 %}
8450 // Rotate Right by variable
8451 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8452 %{
8453 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift))));
8455 expand %{
8456 rorI_rReg_CL(dst, shift, cr);
8457 %}
8458 %}
8460 // Rotate Right by variable
8461 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
8462 %{
8463 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift))));
8465 expand %{
8466 rorI_rReg_CL(dst, shift, cr);
8467 %}
8468 %}
8470 // for long rotate
8471 // ROL expand
8472 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{
8473 effect(USE_DEF dst, KILL cr);
8475 format %{ "rolq $dst" %}
8476 opcode(0xD1, 0x0); /* Opcode D1 /0 */
8477 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8478 ins_pipe(ialu_reg);
8479 %}
8481 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{
8482 effect(USE_DEF dst, USE shift, KILL cr);
8484 format %{ "rolq $dst, $shift" %}
8485 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
8486 ins_encode( reg_opc_imm_wide(dst, shift) );
8487 ins_pipe(ialu_reg);
8488 %}
8490 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
8491 %{
8492 effect(USE_DEF dst, USE shift, KILL cr);
8494 format %{ "rolq $dst, $shift" %}
8495 opcode(0xD3, 0x0); /* Opcode D3 /0 */
8496 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8497 ins_pipe(ialu_reg_reg);
8498 %}
8499 // end of ROL expand
8501 // Rotate Left by one
8502 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
8503 %{
8504 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
8506 expand %{
8507 rolL_rReg_imm1(dst, cr);
8508 %}
8509 %}
8511 // Rotate Left by 8-bit immediate
8512 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
8513 %{
8514 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
8515 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
8517 expand %{
8518 rolL_rReg_imm8(dst, lshift, cr);
8519 %}
8520 %}
8522 // Rotate Left by variable
8523 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8524 %{
8525 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift))));
8527 expand %{
8528 rolL_rReg_CL(dst, shift, cr);
8529 %}
8530 %}
8532 // Rotate Left by variable
8533 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
8534 %{
8535 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift))));
8537 expand %{
8538 rolL_rReg_CL(dst, shift, cr);
8539 %}
8540 %}
8542 // ROR expand
8543 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr)
8544 %{
8545 effect(USE_DEF dst, KILL cr);
8547 format %{ "rorq $dst" %}
8548 opcode(0xD1, 0x1); /* D1 /1 */
8549 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8550 ins_pipe(ialu_reg);
8551 %}
8553 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr)
8554 %{
8555 effect(USE_DEF dst, USE shift, KILL cr);
8557 format %{ "rorq $dst, $shift" %}
8558 opcode(0xC1, 0x1); /* C1 /1 ib */
8559 ins_encode(reg_opc_imm_wide(dst, shift));
8560 ins_pipe(ialu_reg);
8561 %}
8563 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
8564 %{
8565 effect(USE_DEF dst, USE shift, KILL cr);
8567 format %{ "rorq $dst, $shift" %}
8568 opcode(0xD3, 0x1); /* D3 /1 */
8569 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8570 ins_pipe(ialu_reg_reg);
8571 %}
8572 // end of ROR expand
8574 // Rotate Right by one
8575 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
8576 %{
8577 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
8579 expand %{
8580 rorL_rReg_imm1(dst, cr);
8581 %}
8582 %}
8584 // Rotate Right by 8-bit immediate
8585 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
8586 %{
8587 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
8588 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
8590 expand %{
8591 rorL_rReg_imm8(dst, rshift, cr);
8592 %}
8593 %}
8595 // Rotate Right by variable
8596 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8597 %{
8598 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift))));
8600 expand %{
8601 rorL_rReg_CL(dst, shift, cr);
8602 %}
8603 %}
8605 // Rotate Right by variable
8606 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
8607 %{
8608 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift))));
8610 expand %{
8611 rorL_rReg_CL(dst, shift, cr);
8612 %}
8613 %}
8615 // Logical Instructions
8617 // Integer Logical Instructions
8619 // And Instructions
8620 // And Register with Register
8621 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8622 %{
8623 match(Set dst (AndI dst src));
8624 effect(KILL cr);
8626 format %{ "andl $dst, $src\t# int" %}
8627 opcode(0x23);
8628 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8629 ins_pipe(ialu_reg_reg);
8630 %}
8632 // And Register with Immediate 255
8633 instruct andI_rReg_imm255(rRegI dst, immI_255 src)
8634 %{
8635 match(Set dst (AndI dst src));
8637 format %{ "movzbl $dst, $dst\t# int & 0xFF" %}
8638 opcode(0x0F, 0xB6);
8639 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
8640 ins_pipe(ialu_reg);
8641 %}
8643 // And Register with Immediate 255 and promote to long
8644 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask)
8645 %{
8646 match(Set dst (ConvI2L (AndI src mask)));
8648 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %}
8649 opcode(0x0F, 0xB6);
8650 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8651 ins_pipe(ialu_reg);
8652 %}
8654 // And Register with Immediate 65535
8655 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src)
8656 %{
8657 match(Set dst (AndI dst src));
8659 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %}
8660 opcode(0x0F, 0xB7);
8661 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
8662 ins_pipe(ialu_reg);
8663 %}
8665 // And Register with Immediate 65535 and promote to long
8666 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask)
8667 %{
8668 match(Set dst (ConvI2L (AndI src mask)));
8670 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %}
8671 opcode(0x0F, 0xB7);
8672 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8673 ins_pipe(ialu_reg);
8674 %}
8676 // And Register with Immediate
8677 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8678 %{
8679 match(Set dst (AndI dst src));
8680 effect(KILL cr);
8682 format %{ "andl $dst, $src\t# int" %}
8683 opcode(0x81, 0x04); /* Opcode 81 /4 */
8684 ins_encode(OpcSErm(dst, src), Con8or32(src));
8685 ins_pipe(ialu_reg);
8686 %}
8688 // And Register with Memory
8689 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8690 %{
8691 match(Set dst (AndI dst (LoadI src)));
8692 effect(KILL cr);
8694 ins_cost(125);
8695 format %{ "andl $dst, $src\t# int" %}
8696 opcode(0x23);
8697 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
8698 ins_pipe(ialu_reg_mem);
8699 %}
8701 // And Memory with Register
8702 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8703 %{
8704 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
8705 effect(KILL cr);
8707 ins_cost(150);
8708 format %{ "andl $dst, $src\t# int" %}
8709 opcode(0x21); /* Opcode 21 /r */
8710 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
8711 ins_pipe(ialu_mem_reg);
8712 %}
8714 // And Memory with Immediate
8715 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr)
8716 %{
8717 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
8718 effect(KILL cr);
8720 ins_cost(125);
8721 format %{ "andl $dst, $src\t# int" %}
8722 opcode(0x81, 0x4); /* Opcode 81 /4 id */
8723 ins_encode(REX_mem(dst), OpcSE(src),
8724 RM_opc_mem(secondary, dst), Con8or32(src));
8725 ins_pipe(ialu_mem_imm);
8726 %}
8728 // BMI1 instructions
8729 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{
8730 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2)));
8731 predicate(UseBMI1Instructions);
8732 effect(KILL cr);
8734 ins_cost(125);
8735 format %{ "andnl $dst, $src1, $src2" %}
8737 ins_encode %{
8738 __ andnl($dst$$Register, $src1$$Register, $src2$$Address);
8739 %}
8740 ins_pipe(ialu_reg_mem);
8741 %}
8743 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{
8744 match(Set dst (AndI (XorI src1 minus_1) src2));
8745 predicate(UseBMI1Instructions);
8746 effect(KILL cr);
8748 format %{ "andnl $dst, $src1, $src2" %}
8750 ins_encode %{
8751 __ andnl($dst$$Register, $src1$$Register, $src2$$Register);
8752 %}
8753 ins_pipe(ialu_reg);
8754 %}
8756 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{
8757 match(Set dst (AndI (SubI imm_zero src) src));
8758 predicate(UseBMI1Instructions);
8759 effect(KILL cr);
8761 format %{ "blsil $dst, $src" %}
8763 ins_encode %{
8764 __ blsil($dst$$Register, $src$$Register);
8765 %}
8766 ins_pipe(ialu_reg);
8767 %}
8769 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{
8770 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) ));
8771 predicate(UseBMI1Instructions);
8772 effect(KILL cr);
8774 ins_cost(125);
8775 format %{ "blsil $dst, $src" %}
8777 ins_encode %{
8778 __ blsil($dst$$Register, $src$$Address);
8779 %}
8780 ins_pipe(ialu_reg_mem);
8781 %}
8783 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr)
8784 %{
8785 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) );
8786 predicate(UseBMI1Instructions);
8787 effect(KILL cr);
8789 ins_cost(125);
8790 format %{ "blsmskl $dst, $src" %}
8792 ins_encode %{
8793 __ blsmskl($dst$$Register, $src$$Address);
8794 %}
8795 ins_pipe(ialu_reg_mem);
8796 %}
8798 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr)
8799 %{
8800 match(Set dst (XorI (AddI src minus_1) src));
8801 predicate(UseBMI1Instructions);
8802 effect(KILL cr);
8804 format %{ "blsmskl $dst, $src" %}
8806 ins_encode %{
8807 __ blsmskl($dst$$Register, $src$$Register);
8808 %}
8810 ins_pipe(ialu_reg);
8811 %}
8813 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr)
8814 %{
8815 match(Set dst (AndI (AddI src minus_1) src) );
8816 predicate(UseBMI1Instructions);
8817 effect(KILL cr);
8819 format %{ "blsrl $dst, $src" %}
8821 ins_encode %{
8822 __ blsrl($dst$$Register, $src$$Register);
8823 %}
8825 ins_pipe(ialu_reg_mem);
8826 %}
8828 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr)
8829 %{
8830 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) );
8831 predicate(UseBMI1Instructions);
8832 effect(KILL cr);
8834 ins_cost(125);
8835 format %{ "blsrl $dst, $src" %}
8837 ins_encode %{
8838 __ blsrl($dst$$Register, $src$$Address);
8839 %}
8841 ins_pipe(ialu_reg);
8842 %}
8844 // Or Instructions
8845 // Or Register with Register
8846 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8847 %{
8848 match(Set dst (OrI dst src));
8849 effect(KILL cr);
8851 format %{ "orl $dst, $src\t# int" %}
8852 opcode(0x0B);
8853 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8854 ins_pipe(ialu_reg_reg);
8855 %}
8857 // Or Register with Immediate
8858 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8859 %{
8860 match(Set dst (OrI dst src));
8861 effect(KILL cr);
8863 format %{ "orl $dst, $src\t# int" %}
8864 opcode(0x81, 0x01); /* Opcode 81 /1 id */
8865 ins_encode(OpcSErm(dst, src), Con8or32(src));
8866 ins_pipe(ialu_reg);
8867 %}
8869 // Or Register with Memory
8870 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8871 %{
8872 match(Set dst (OrI dst (LoadI src)));
8873 effect(KILL cr);
8875 ins_cost(125);
8876 format %{ "orl $dst, $src\t# int" %}
8877 opcode(0x0B);
8878 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
8879 ins_pipe(ialu_reg_mem);
8880 %}
8882 // Or Memory with Register
8883 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8884 %{
8885 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
8886 effect(KILL cr);
8888 ins_cost(150);
8889 format %{ "orl $dst, $src\t# int" %}
8890 opcode(0x09); /* Opcode 09 /r */
8891 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
8892 ins_pipe(ialu_mem_reg);
8893 %}
8895 // Or Memory with Immediate
8896 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr)
8897 %{
8898 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
8899 effect(KILL cr);
8901 ins_cost(125);
8902 format %{ "orl $dst, $src\t# int" %}
8903 opcode(0x81, 0x1); /* Opcode 81 /1 id */
8904 ins_encode(REX_mem(dst), OpcSE(src),
8905 RM_opc_mem(secondary, dst), Con8or32(src));
8906 ins_pipe(ialu_mem_imm);
8907 %}
8909 // Xor Instructions
8910 // Xor Register with Register
8911 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8912 %{
8913 match(Set dst (XorI dst src));
8914 effect(KILL cr);
8916 format %{ "xorl $dst, $src\t# int" %}
8917 opcode(0x33);
8918 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8919 ins_pipe(ialu_reg_reg);
8920 %}
8922 // Xor Register with Immediate -1
8923 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
8924 match(Set dst (XorI dst imm));
8926 format %{ "not $dst" %}
8927 ins_encode %{
8928 __ notl($dst$$Register);
8929 %}
8930 ins_pipe(ialu_reg);
8931 %}
8933 // Xor Register with Immediate
8934 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8935 %{
8936 match(Set dst (XorI dst src));
8937 effect(KILL cr);
8939 format %{ "xorl $dst, $src\t# int" %}
8940 opcode(0x81, 0x06); /* Opcode 81 /6 id */
8941 ins_encode(OpcSErm(dst, src), Con8or32(src));
8942 ins_pipe(ialu_reg);
8943 %}
8945 // Xor Register with Memory
8946 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8947 %{
8948 match(Set dst (XorI dst (LoadI src)));
8949 effect(KILL cr);
8951 ins_cost(125);
8952 format %{ "xorl $dst, $src\t# int" %}
8953 opcode(0x33);
8954 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
8955 ins_pipe(ialu_reg_mem);
8956 %}
8958 // Xor Memory with Register
8959 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8960 %{
8961 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
8962 effect(KILL cr);
8964 ins_cost(150);
8965 format %{ "xorl $dst, $src\t# int" %}
8966 opcode(0x31); /* Opcode 31 /r */
8967 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
8968 ins_pipe(ialu_mem_reg);
8969 %}
8971 // Xor Memory with Immediate
8972 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr)
8973 %{
8974 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
8975 effect(KILL cr);
8977 ins_cost(125);
8978 format %{ "xorl $dst, $src\t# int" %}
8979 opcode(0x81, 0x6); /* Opcode 81 /6 id */
8980 ins_encode(REX_mem(dst), OpcSE(src),
8981 RM_opc_mem(secondary, dst), Con8or32(src));
8982 ins_pipe(ialu_mem_imm);
8983 %}
8986 // Long Logical Instructions
8988 // And Instructions
8989 // And Register with Register
8990 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8991 %{
8992 match(Set dst (AndL dst src));
8993 effect(KILL cr);
8995 format %{ "andq $dst, $src\t# long" %}
8996 opcode(0x23);
8997 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8998 ins_pipe(ialu_reg_reg);
8999 %}
9001 // And Register with Immediate 255
9002 instruct andL_rReg_imm255(rRegL dst, immL_255 src)
9003 %{
9004 match(Set dst (AndL dst src));
9006 format %{ "movzbq $dst, $dst\t# long & 0xFF" %}
9007 opcode(0x0F, 0xB6);
9008 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9009 ins_pipe(ialu_reg);
9010 %}
9012 // And Register with Immediate 65535
9013 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
9014 %{
9015 match(Set dst (AndL dst src));
9017 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %}
9018 opcode(0x0F, 0xB7);
9019 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9020 ins_pipe(ialu_reg);
9021 %}
9023 // And Register with Immediate
9024 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9025 %{
9026 match(Set dst (AndL dst src));
9027 effect(KILL cr);
9029 format %{ "andq $dst, $src\t# long" %}
9030 opcode(0x81, 0x04); /* Opcode 81 /4 */
9031 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9032 ins_pipe(ialu_reg);
9033 %}
9035 // And Register with Memory
9036 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9037 %{
9038 match(Set dst (AndL dst (LoadL src)));
9039 effect(KILL cr);
9041 ins_cost(125);
9042 format %{ "andq $dst, $src\t# long" %}
9043 opcode(0x23);
9044 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9045 ins_pipe(ialu_reg_mem);
9046 %}
9048 // And Memory with Register
9049 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9050 %{
9051 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9052 effect(KILL cr);
9054 ins_cost(150);
9055 format %{ "andq $dst, $src\t# long" %}
9056 opcode(0x21); /* Opcode 21 /r */
9057 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9058 ins_pipe(ialu_mem_reg);
9059 %}
9061 // And Memory with Immediate
9062 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9063 %{
9064 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9065 effect(KILL cr);
9067 ins_cost(125);
9068 format %{ "andq $dst, $src\t# long" %}
9069 opcode(0x81, 0x4); /* Opcode 81 /4 id */
9070 ins_encode(REX_mem_wide(dst), OpcSE(src),
9071 RM_opc_mem(secondary, dst), Con8or32(src));
9072 ins_pipe(ialu_mem_imm);
9073 %}
9075 // BMI1 instructions
9076 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{
9077 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2)));
9078 predicate(UseBMI1Instructions);
9079 effect(KILL cr);
9081 ins_cost(125);
9082 format %{ "andnq $dst, $src1, $src2" %}
9084 ins_encode %{
9085 __ andnq($dst$$Register, $src1$$Register, $src2$$Address);
9086 %}
9087 ins_pipe(ialu_reg_mem);
9088 %}
9090 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{
9091 match(Set dst (AndL (XorL src1 minus_1) src2));
9092 predicate(UseBMI1Instructions);
9093 effect(KILL cr);
9095 format %{ "andnq $dst, $src1, $src2" %}
9097 ins_encode %{
9098 __ andnq($dst$$Register, $src1$$Register, $src2$$Register);
9099 %}
9100 ins_pipe(ialu_reg_mem);
9101 %}
9103 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{
9104 match(Set dst (AndL (SubL imm_zero src) src));
9105 predicate(UseBMI1Instructions);
9106 effect(KILL cr);
9108 format %{ "blsiq $dst, $src" %}
9110 ins_encode %{
9111 __ blsiq($dst$$Register, $src$$Register);
9112 %}
9113 ins_pipe(ialu_reg);
9114 %}
9116 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{
9117 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) ));
9118 predicate(UseBMI1Instructions);
9119 effect(KILL cr);
9121 ins_cost(125);
9122 format %{ "blsiq $dst, $src" %}
9124 ins_encode %{
9125 __ blsiq($dst$$Register, $src$$Address);
9126 %}
9127 ins_pipe(ialu_reg_mem);
9128 %}
9130 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr)
9131 %{
9132 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) );
9133 predicate(UseBMI1Instructions);
9134 effect(KILL cr);
9136 ins_cost(125);
9137 format %{ "blsmskq $dst, $src" %}
9139 ins_encode %{
9140 __ blsmskq($dst$$Register, $src$$Address);
9141 %}
9142 ins_pipe(ialu_reg_mem);
9143 %}
9145 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr)
9146 %{
9147 match(Set dst (XorL (AddL src minus_1) src));
9148 predicate(UseBMI1Instructions);
9149 effect(KILL cr);
9151 format %{ "blsmskq $dst, $src" %}
9153 ins_encode %{
9154 __ blsmskq($dst$$Register, $src$$Register);
9155 %}
9157 ins_pipe(ialu_reg);
9158 %}
9160 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr)
9161 %{
9162 match(Set dst (AndL (AddL src minus_1) src) );
9163 predicate(UseBMI1Instructions);
9164 effect(KILL cr);
9166 format %{ "blsrq $dst, $src" %}
9168 ins_encode %{
9169 __ blsrq($dst$$Register, $src$$Register);
9170 %}
9172 ins_pipe(ialu_reg);
9173 %}
9175 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr)
9176 %{
9177 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) );
9178 predicate(UseBMI1Instructions);
9179 effect(KILL cr);
9181 ins_cost(125);
9182 format %{ "blsrq $dst, $src" %}
9184 ins_encode %{
9185 __ blsrq($dst$$Register, $src$$Address);
9186 %}
9188 ins_pipe(ialu_reg);
9189 %}
9191 // Or Instructions
9192 // Or Register with Register
9193 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9194 %{
9195 match(Set dst (OrL dst src));
9196 effect(KILL cr);
9198 format %{ "orq $dst, $src\t# long" %}
9199 opcode(0x0B);
9200 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9201 ins_pipe(ialu_reg_reg);
9202 %}
9204 // Use any_RegP to match R15 (TLS register) without spilling.
9205 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
9206 match(Set dst (OrL dst (CastP2X src)));
9207 effect(KILL cr);
9209 format %{ "orq $dst, $src\t# long" %}
9210 opcode(0x0B);
9211 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9212 ins_pipe(ialu_reg_reg);
9213 %}
9216 // Or Register with Immediate
9217 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9218 %{
9219 match(Set dst (OrL dst src));
9220 effect(KILL cr);
9222 format %{ "orq $dst, $src\t# long" %}
9223 opcode(0x81, 0x01); /* Opcode 81 /1 id */
9224 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9225 ins_pipe(ialu_reg);
9226 %}
9228 // Or Register with Memory
9229 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9230 %{
9231 match(Set dst (OrL dst (LoadL src)));
9232 effect(KILL cr);
9234 ins_cost(125);
9235 format %{ "orq $dst, $src\t# long" %}
9236 opcode(0x0B);
9237 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9238 ins_pipe(ialu_reg_mem);
9239 %}
9241 // Or Memory with Register
9242 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9243 %{
9244 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
9245 effect(KILL cr);
9247 ins_cost(150);
9248 format %{ "orq $dst, $src\t# long" %}
9249 opcode(0x09); /* Opcode 09 /r */
9250 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9251 ins_pipe(ialu_mem_reg);
9252 %}
9254 // Or Memory with Immediate
9255 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9256 %{
9257 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
9258 effect(KILL cr);
9260 ins_cost(125);
9261 format %{ "orq $dst, $src\t# long" %}
9262 opcode(0x81, 0x1); /* Opcode 81 /1 id */
9263 ins_encode(REX_mem_wide(dst), OpcSE(src),
9264 RM_opc_mem(secondary, dst), Con8or32(src));
9265 ins_pipe(ialu_mem_imm);
9266 %}
9268 // Xor Instructions
9269 // Xor Register with Register
9270 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9271 %{
9272 match(Set dst (XorL dst src));
9273 effect(KILL cr);
9275 format %{ "xorq $dst, $src\t# long" %}
9276 opcode(0x33);
9277 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9278 ins_pipe(ialu_reg_reg);
9279 %}
9281 // Xor Register with Immediate -1
9282 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
9283 match(Set dst (XorL dst imm));
9285 format %{ "notq $dst" %}
9286 ins_encode %{
9287 __ notq($dst$$Register);
9288 %}
9289 ins_pipe(ialu_reg);
9290 %}
9292 // Xor Register with Immediate
9293 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9294 %{
9295 match(Set dst (XorL dst src));
9296 effect(KILL cr);
9298 format %{ "xorq $dst, $src\t# long" %}
9299 opcode(0x81, 0x06); /* Opcode 81 /6 id */
9300 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9301 ins_pipe(ialu_reg);
9302 %}
9304 // Xor Register with Memory
9305 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9306 %{
9307 match(Set dst (XorL dst (LoadL src)));
9308 effect(KILL cr);
9310 ins_cost(125);
9311 format %{ "xorq $dst, $src\t# long" %}
9312 opcode(0x33);
9313 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9314 ins_pipe(ialu_reg_mem);
9315 %}
9317 // Xor Memory with Register
9318 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9319 %{
9320 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
9321 effect(KILL cr);
9323 ins_cost(150);
9324 format %{ "xorq $dst, $src\t# long" %}
9325 opcode(0x31); /* Opcode 31 /r */
9326 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9327 ins_pipe(ialu_mem_reg);
9328 %}
9330 // Xor Memory with Immediate
9331 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9332 %{
9333 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
9334 effect(KILL cr);
9336 ins_cost(125);
9337 format %{ "xorq $dst, $src\t# long" %}
9338 opcode(0x81, 0x6); /* Opcode 81 /6 id */
9339 ins_encode(REX_mem_wide(dst), OpcSE(src),
9340 RM_opc_mem(secondary, dst), Con8or32(src));
9341 ins_pipe(ialu_mem_imm);
9342 %}
9344 // Convert Int to Boolean
9345 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr)
9346 %{
9347 match(Set dst (Conv2B src));
9348 effect(KILL cr);
9350 format %{ "testl $src, $src\t# ci2b\n\t"
9351 "setnz $dst\n\t"
9352 "movzbl $dst, $dst" %}
9353 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl
9354 setNZ_reg(dst),
9355 REX_reg_breg(dst, dst), // movzbl
9356 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
9357 ins_pipe(pipe_slow); // XXX
9358 %}
9360 // Convert Pointer to Boolean
9361 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr)
9362 %{
9363 match(Set dst (Conv2B src));
9364 effect(KILL cr);
9366 format %{ "testq $src, $src\t# cp2b\n\t"
9367 "setnz $dst\n\t"
9368 "movzbl $dst, $dst" %}
9369 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq
9370 setNZ_reg(dst),
9371 REX_reg_breg(dst, dst), // movzbl
9372 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
9373 ins_pipe(pipe_slow); // XXX
9374 %}
9376 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr)
9377 %{
9378 match(Set dst (CmpLTMask p q));
9379 effect(KILL cr);
9381 ins_cost(400);
9382 format %{ "cmpl $p, $q\t# cmpLTMask\n\t"
9383 "setlt $dst\n\t"
9384 "movzbl $dst, $dst\n\t"
9385 "negl $dst" %}
9386 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl
9387 setLT_reg(dst),
9388 REX_reg_breg(dst, dst), // movzbl
9389 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst),
9390 neg_reg(dst));
9391 ins_pipe(pipe_slow);
9392 %}
9394 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr)
9395 %{
9396 match(Set dst (CmpLTMask dst zero));
9397 effect(KILL cr);
9399 ins_cost(100);
9400 format %{ "sarl $dst, #31\t# cmpLTMask0" %}
9401 ins_encode %{
9402 __ sarl($dst$$Register, 31);
9403 %}
9404 ins_pipe(ialu_reg);
9405 %}
9407 /* Better to save a register than avoid a branch */
9408 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr)
9409 %{
9410 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
9411 effect(KILL cr);
9412 ins_cost(300);
9413 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t"
9414 "jge done\n\t"
9415 "addl $p,$y\n"
9416 "done: " %}
9417 ins_encode %{
9418 Register Rp = $p$$Register;
9419 Register Rq = $q$$Register;
9420 Register Ry = $y$$Register;
9421 Label done;
9422 __ subl(Rp, Rq);
9423 __ jccb(Assembler::greaterEqual, done);
9424 __ addl(Rp, Ry);
9425 __ bind(done);
9426 %}
9427 ins_pipe(pipe_cmplt);
9428 %}
9430 /* Better to save a register than avoid a branch */
9431 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr)
9432 %{
9433 match(Set y (AndI (CmpLTMask p q) y));
9434 effect(KILL cr);
9436 ins_cost(300);
9438 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t"
9439 "jlt done\n\t"
9440 "xorl $y, $y\n"
9441 "done: " %}
9442 ins_encode %{
9443 Register Rp = $p$$Register;
9444 Register Rq = $q$$Register;
9445 Register Ry = $y$$Register;
9446 Label done;
9447 __ cmpl(Rp, Rq);
9448 __ jccb(Assembler::less, done);
9449 __ xorl(Ry, Ry);
9450 __ bind(done);
9451 %}
9452 ins_pipe(pipe_cmplt);
9453 %}
9456 //---------- FP Instructions------------------------------------------------
9458 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
9459 %{
9460 match(Set cr (CmpF src1 src2));
9462 ins_cost(145);
9463 format %{ "ucomiss $src1, $src2\n\t"
9464 "jnp,s exit\n\t"
9465 "pushfq\t# saw NaN, set CF\n\t"
9466 "andq [rsp], #0xffffff2b\n\t"
9467 "popfq\n"
9468 "exit:" %}
9469 ins_encode %{
9470 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9471 emit_cmpfp_fixup(_masm);
9472 %}
9473 ins_pipe(pipe_slow);
9474 %}
9476 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
9477 match(Set cr (CmpF src1 src2));
9479 ins_cost(100);
9480 format %{ "ucomiss $src1, $src2" %}
9481 ins_encode %{
9482 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9483 %}
9484 ins_pipe(pipe_slow);
9485 %}
9487 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
9488 %{
9489 match(Set cr (CmpF src1 (LoadF src2)));
9491 ins_cost(145);
9492 format %{ "ucomiss $src1, $src2\n\t"
9493 "jnp,s exit\n\t"
9494 "pushfq\t# saw NaN, set CF\n\t"
9495 "andq [rsp], #0xffffff2b\n\t"
9496 "popfq\n"
9497 "exit:" %}
9498 ins_encode %{
9499 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9500 emit_cmpfp_fixup(_masm);
9501 %}
9502 ins_pipe(pipe_slow);
9503 %}
9505 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
9506 match(Set cr (CmpF src1 (LoadF src2)));
9508 ins_cost(100);
9509 format %{ "ucomiss $src1, $src2" %}
9510 ins_encode %{
9511 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9512 %}
9513 ins_pipe(pipe_slow);
9514 %}
9516 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
9517 match(Set cr (CmpF src con));
9519 ins_cost(145);
9520 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
9521 "jnp,s exit\n\t"
9522 "pushfq\t# saw NaN, set CF\n\t"
9523 "andq [rsp], #0xffffff2b\n\t"
9524 "popfq\n"
9525 "exit:" %}
9526 ins_encode %{
9527 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9528 emit_cmpfp_fixup(_masm);
9529 %}
9530 ins_pipe(pipe_slow);
9531 %}
9533 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
9534 match(Set cr (CmpF src con));
9535 ins_cost(100);
9536 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
9537 ins_encode %{
9538 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9539 %}
9540 ins_pipe(pipe_slow);
9541 %}
9543 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
9544 %{
9545 match(Set cr (CmpD src1 src2));
9547 ins_cost(145);
9548 format %{ "ucomisd $src1, $src2\n\t"
9549 "jnp,s exit\n\t"
9550 "pushfq\t# saw NaN, set CF\n\t"
9551 "andq [rsp], #0xffffff2b\n\t"
9552 "popfq\n"
9553 "exit:" %}
9554 ins_encode %{
9555 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9556 emit_cmpfp_fixup(_masm);
9557 %}
9558 ins_pipe(pipe_slow);
9559 %}
9561 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
9562 match(Set cr (CmpD src1 src2));
9564 ins_cost(100);
9565 format %{ "ucomisd $src1, $src2 test" %}
9566 ins_encode %{
9567 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9568 %}
9569 ins_pipe(pipe_slow);
9570 %}
9572 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
9573 %{
9574 match(Set cr (CmpD src1 (LoadD src2)));
9576 ins_cost(145);
9577 format %{ "ucomisd $src1, $src2\n\t"
9578 "jnp,s exit\n\t"
9579 "pushfq\t# saw NaN, set CF\n\t"
9580 "andq [rsp], #0xffffff2b\n\t"
9581 "popfq\n"
9582 "exit:" %}
9583 ins_encode %{
9584 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9585 emit_cmpfp_fixup(_masm);
9586 %}
9587 ins_pipe(pipe_slow);
9588 %}
9590 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
9591 match(Set cr (CmpD src1 (LoadD src2)));
9593 ins_cost(100);
9594 format %{ "ucomisd $src1, $src2" %}
9595 ins_encode %{
9596 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9597 %}
9598 ins_pipe(pipe_slow);
9599 %}
9601 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
9602 match(Set cr (CmpD src con));
9604 ins_cost(145);
9605 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
9606 "jnp,s exit\n\t"
9607 "pushfq\t# saw NaN, set CF\n\t"
9608 "andq [rsp], #0xffffff2b\n\t"
9609 "popfq\n"
9610 "exit:" %}
9611 ins_encode %{
9612 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9613 emit_cmpfp_fixup(_masm);
9614 %}
9615 ins_pipe(pipe_slow);
9616 %}
9618 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
9619 match(Set cr (CmpD src con));
9620 ins_cost(100);
9621 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
9622 ins_encode %{
9623 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9624 %}
9625 ins_pipe(pipe_slow);
9626 %}
9628 // Compare into -1,0,1
9629 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
9630 %{
9631 match(Set dst (CmpF3 src1 src2));
9632 effect(KILL cr);
9634 ins_cost(275);
9635 format %{ "ucomiss $src1, $src2\n\t"
9636 "movl $dst, #-1\n\t"
9637 "jp,s done\n\t"
9638 "jb,s done\n\t"
9639 "setne $dst\n\t"
9640 "movzbl $dst, $dst\n"
9641 "done:" %}
9642 ins_encode %{
9643 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9644 emit_cmpfp3(_masm, $dst$$Register);
9645 %}
9646 ins_pipe(pipe_slow);
9647 %}
9649 // Compare into -1,0,1
9650 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
9651 %{
9652 match(Set dst (CmpF3 src1 (LoadF src2)));
9653 effect(KILL cr);
9655 ins_cost(275);
9656 format %{ "ucomiss $src1, $src2\n\t"
9657 "movl $dst, #-1\n\t"
9658 "jp,s done\n\t"
9659 "jb,s done\n\t"
9660 "setne $dst\n\t"
9661 "movzbl $dst, $dst\n"
9662 "done:" %}
9663 ins_encode %{
9664 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9665 emit_cmpfp3(_masm, $dst$$Register);
9666 %}
9667 ins_pipe(pipe_slow);
9668 %}
9670 // Compare into -1,0,1
9671 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
9672 match(Set dst (CmpF3 src con));
9673 effect(KILL cr);
9675 ins_cost(275);
9676 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
9677 "movl $dst, #-1\n\t"
9678 "jp,s done\n\t"
9679 "jb,s done\n\t"
9680 "setne $dst\n\t"
9681 "movzbl $dst, $dst\n"
9682 "done:" %}
9683 ins_encode %{
9684 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9685 emit_cmpfp3(_masm, $dst$$Register);
9686 %}
9687 ins_pipe(pipe_slow);
9688 %}
9690 // Compare into -1,0,1
9691 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
9692 %{
9693 match(Set dst (CmpD3 src1 src2));
9694 effect(KILL cr);
9696 ins_cost(275);
9697 format %{ "ucomisd $src1, $src2\n\t"
9698 "movl $dst, #-1\n\t"
9699 "jp,s done\n\t"
9700 "jb,s done\n\t"
9701 "setne $dst\n\t"
9702 "movzbl $dst, $dst\n"
9703 "done:" %}
9704 ins_encode %{
9705 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9706 emit_cmpfp3(_masm, $dst$$Register);
9707 %}
9708 ins_pipe(pipe_slow);
9709 %}
9711 // Compare into -1,0,1
9712 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
9713 %{
9714 match(Set dst (CmpD3 src1 (LoadD src2)));
9715 effect(KILL cr);
9717 ins_cost(275);
9718 format %{ "ucomisd $src1, $src2\n\t"
9719 "movl $dst, #-1\n\t"
9720 "jp,s done\n\t"
9721 "jb,s done\n\t"
9722 "setne $dst\n\t"
9723 "movzbl $dst, $dst\n"
9724 "done:" %}
9725 ins_encode %{
9726 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9727 emit_cmpfp3(_masm, $dst$$Register);
9728 %}
9729 ins_pipe(pipe_slow);
9730 %}
9732 // Compare into -1,0,1
9733 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
9734 match(Set dst (CmpD3 src con));
9735 effect(KILL cr);
9737 ins_cost(275);
9738 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
9739 "movl $dst, #-1\n\t"
9740 "jp,s done\n\t"
9741 "jb,s done\n\t"
9742 "setne $dst\n\t"
9743 "movzbl $dst, $dst\n"
9744 "done:" %}
9745 ins_encode %{
9746 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9747 emit_cmpfp3(_masm, $dst$$Register);
9748 %}
9749 ins_pipe(pipe_slow);
9750 %}
9752 // -----------Trig and Trancendental Instructions------------------------------
9753 instruct cosD_reg(regD dst) %{
9754 match(Set dst (CosD dst));
9756 format %{ "dcos $dst\n\t" %}
9757 opcode(0xD9, 0xFF);
9758 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
9759 ins_pipe( pipe_slow );
9760 %}
9762 instruct sinD_reg(regD dst) %{
9763 match(Set dst (SinD dst));
9765 format %{ "dsin $dst\n\t" %}
9766 opcode(0xD9, 0xFE);
9767 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
9768 ins_pipe( pipe_slow );
9769 %}
9771 instruct tanD_reg(regD dst) %{
9772 match(Set dst (TanD dst));
9774 format %{ "dtan $dst\n\t" %}
9775 ins_encode( Push_SrcXD(dst),
9776 Opcode(0xD9), Opcode(0xF2), //fptan
9777 Opcode(0xDD), Opcode(0xD8), //fstp st
9778 Push_ResultXD(dst) );
9779 ins_pipe( pipe_slow );
9780 %}
9782 instruct log10D_reg(regD dst) %{
9783 // The source and result Double operands in XMM registers
9784 match(Set dst (Log10D dst));
9785 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number
9786 // fyl2x ; compute log_10(2) * log_2(x)
9787 format %{ "fldlg2\t\t\t#Log10\n\t"
9788 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t"
9789 %}
9790 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2
9791 Push_SrcXD(dst),
9792 Opcode(0xD9), Opcode(0xF1), // fyl2x
9793 Push_ResultXD(dst));
9795 ins_pipe( pipe_slow );
9796 %}
9798 instruct logD_reg(regD dst) %{
9799 // The source and result Double operands in XMM registers
9800 match(Set dst (LogD dst));
9801 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number
9802 // fyl2x ; compute log_e(2) * log_2(x)
9803 format %{ "fldln2\t\t\t#Log_e\n\t"
9804 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t"
9805 %}
9806 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2
9807 Push_SrcXD(dst),
9808 Opcode(0xD9), Opcode(0xF1), // fyl2x
9809 Push_ResultXD(dst));
9810 ins_pipe( pipe_slow );
9811 %}
9813 instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{
9814 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power
9815 effect(KILL rax, KILL rdx, KILL rcx, KILL cr);
9816 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %}
9817 ins_encode %{
9818 __ subptr(rsp, 8);
9819 __ movdbl(Address(rsp, 0), $src1$$XMMRegister);
9820 __ fld_d(Address(rsp, 0));
9821 __ movdbl(Address(rsp, 0), $src0$$XMMRegister);
9822 __ fld_d(Address(rsp, 0));
9823 __ fast_pow();
9824 __ fstp_d(Address(rsp, 0));
9825 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
9826 __ addptr(rsp, 8);
9827 %}
9828 ins_pipe( pipe_slow );
9829 %}
9831 instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{
9832 match(Set dst (ExpD src));
9833 effect(KILL rax, KILL rcx, KILL rdx, KILL cr);
9834 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %}
9835 ins_encode %{
9836 __ subptr(rsp, 8);
9837 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
9838 __ fld_d(Address(rsp, 0));
9839 __ fast_exp();
9840 __ fstp_d(Address(rsp, 0));
9841 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
9842 __ addptr(rsp, 8);
9843 %}
9844 ins_pipe( pipe_slow );
9845 %}
9847 //----------Arithmetic Conversion Instructions---------------------------------
9849 instruct roundFloat_nop(regF dst)
9850 %{
9851 match(Set dst (RoundFloat dst));
9853 ins_cost(0);
9854 ins_encode();
9855 ins_pipe(empty);
9856 %}
9858 instruct roundDouble_nop(regD dst)
9859 %{
9860 match(Set dst (RoundDouble dst));
9862 ins_cost(0);
9863 ins_encode();
9864 ins_pipe(empty);
9865 %}
9867 instruct convF2D_reg_reg(regD dst, regF src)
9868 %{
9869 match(Set dst (ConvF2D src));
9871 format %{ "cvtss2sd $dst, $src" %}
9872 ins_encode %{
9873 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister);
9874 %}
9875 ins_pipe(pipe_slow); // XXX
9876 %}
9878 instruct convF2D_reg_mem(regD dst, memory src)
9879 %{
9880 match(Set dst (ConvF2D (LoadF src)));
9882 format %{ "cvtss2sd $dst, $src" %}
9883 ins_encode %{
9884 __ cvtss2sd ($dst$$XMMRegister, $src$$Address);
9885 %}
9886 ins_pipe(pipe_slow); // XXX
9887 %}
9889 instruct convD2F_reg_reg(regF dst, regD src)
9890 %{
9891 match(Set dst (ConvD2F src));
9893 format %{ "cvtsd2ss $dst, $src" %}
9894 ins_encode %{
9895 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister);
9896 %}
9897 ins_pipe(pipe_slow); // XXX
9898 %}
9900 instruct convD2F_reg_mem(regF dst, memory src)
9901 %{
9902 match(Set dst (ConvD2F (LoadD src)));
9904 format %{ "cvtsd2ss $dst, $src" %}
9905 ins_encode %{
9906 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address);
9907 %}
9908 ins_pipe(pipe_slow); // XXX
9909 %}
9911 // XXX do mem variants
9912 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
9913 %{
9914 match(Set dst (ConvF2I src));
9915 effect(KILL cr);
9917 format %{ "cvttss2sil $dst, $src\t# f2i\n\t"
9918 "cmpl $dst, #0x80000000\n\t"
9919 "jne,s done\n\t"
9920 "subq rsp, #8\n\t"
9921 "movss [rsp], $src\n\t"
9922 "call f2i_fixup\n\t"
9923 "popq $dst\n"
9924 "done: "%}
9925 ins_encode %{
9926 Label done;
9927 __ cvttss2sil($dst$$Register, $src$$XMMRegister);
9928 __ cmpl($dst$$Register, 0x80000000);
9929 __ jccb(Assembler::notEqual, done);
9930 __ subptr(rsp, 8);
9931 __ movflt(Address(rsp, 0), $src$$XMMRegister);
9932 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup())));
9933 __ pop($dst$$Register);
9934 __ bind(done);
9935 %}
9936 ins_pipe(pipe_slow);
9937 %}
9939 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
9940 %{
9941 match(Set dst (ConvF2L src));
9942 effect(KILL cr);
9944 format %{ "cvttss2siq $dst, $src\t# f2l\n\t"
9945 "cmpq $dst, [0x8000000000000000]\n\t"
9946 "jne,s done\n\t"
9947 "subq rsp, #8\n\t"
9948 "movss [rsp], $src\n\t"
9949 "call f2l_fixup\n\t"
9950 "popq $dst\n"
9951 "done: "%}
9952 ins_encode %{
9953 Label done;
9954 __ cvttss2siq($dst$$Register, $src$$XMMRegister);
9955 __ cmp64($dst$$Register,
9956 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
9957 __ jccb(Assembler::notEqual, done);
9958 __ subptr(rsp, 8);
9959 __ movflt(Address(rsp, 0), $src$$XMMRegister);
9960 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup())));
9961 __ pop($dst$$Register);
9962 __ bind(done);
9963 %}
9964 ins_pipe(pipe_slow);
9965 %}
9967 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
9968 %{
9969 match(Set dst (ConvD2I src));
9970 effect(KILL cr);
9972 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t"
9973 "cmpl $dst, #0x80000000\n\t"
9974 "jne,s done\n\t"
9975 "subq rsp, #8\n\t"
9976 "movsd [rsp], $src\n\t"
9977 "call d2i_fixup\n\t"
9978 "popq $dst\n"
9979 "done: "%}
9980 ins_encode %{
9981 Label done;
9982 __ cvttsd2sil($dst$$Register, $src$$XMMRegister);
9983 __ cmpl($dst$$Register, 0x80000000);
9984 __ jccb(Assembler::notEqual, done);
9985 __ subptr(rsp, 8);
9986 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
9987 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup())));
9988 __ pop($dst$$Register);
9989 __ bind(done);
9990 %}
9991 ins_pipe(pipe_slow);
9992 %}
9994 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
9995 %{
9996 match(Set dst (ConvD2L src));
9997 effect(KILL cr);
9999 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t"
10000 "cmpq $dst, [0x8000000000000000]\n\t"
10001 "jne,s done\n\t"
10002 "subq rsp, #8\n\t"
10003 "movsd [rsp], $src\n\t"
10004 "call d2l_fixup\n\t"
10005 "popq $dst\n"
10006 "done: "%}
10007 ins_encode %{
10008 Label done;
10009 __ cvttsd2siq($dst$$Register, $src$$XMMRegister);
10010 __ cmp64($dst$$Register,
10011 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
10012 __ jccb(Assembler::notEqual, done);
10013 __ subptr(rsp, 8);
10014 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
10015 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup())));
10016 __ pop($dst$$Register);
10017 __ bind(done);
10018 %}
10019 ins_pipe(pipe_slow);
10020 %}
10022 instruct convI2F_reg_reg(regF dst, rRegI src)
10023 %{
10024 predicate(!UseXmmI2F);
10025 match(Set dst (ConvI2F src));
10027 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10028 ins_encode %{
10029 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
10030 %}
10031 ins_pipe(pipe_slow); // XXX
10032 %}
10034 instruct convI2F_reg_mem(regF dst, memory src)
10035 %{
10036 match(Set dst (ConvI2F (LoadI src)));
10038 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10039 ins_encode %{
10040 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address);
10041 %}
10042 ins_pipe(pipe_slow); // XXX
10043 %}
10045 instruct convI2D_reg_reg(regD dst, rRegI src)
10046 %{
10047 predicate(!UseXmmI2D);
10048 match(Set dst (ConvI2D src));
10050 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10051 ins_encode %{
10052 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
10053 %}
10054 ins_pipe(pipe_slow); // XXX
10055 %}
10057 instruct convI2D_reg_mem(regD dst, memory src)
10058 %{
10059 match(Set dst (ConvI2D (LoadI src)));
10061 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10062 ins_encode %{
10063 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address);
10064 %}
10065 ins_pipe(pipe_slow); // XXX
10066 %}
10068 instruct convXI2F_reg(regF dst, rRegI src)
10069 %{
10070 predicate(UseXmmI2F);
10071 match(Set dst (ConvI2F src));
10073 format %{ "movdl $dst, $src\n\t"
10074 "cvtdq2psl $dst, $dst\t# i2f" %}
10075 ins_encode %{
10076 __ movdl($dst$$XMMRegister, $src$$Register);
10077 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
10078 %}
10079 ins_pipe(pipe_slow); // XXX
10080 %}
10082 instruct convXI2D_reg(regD dst, rRegI src)
10083 %{
10084 predicate(UseXmmI2D);
10085 match(Set dst (ConvI2D src));
10087 format %{ "movdl $dst, $src\n\t"
10088 "cvtdq2pdl $dst, $dst\t# i2d" %}
10089 ins_encode %{
10090 __ movdl($dst$$XMMRegister, $src$$Register);
10091 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
10092 %}
10093 ins_pipe(pipe_slow); // XXX
10094 %}
10096 instruct convL2F_reg_reg(regF dst, rRegL src)
10097 %{
10098 match(Set dst (ConvL2F src));
10100 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10101 ins_encode %{
10102 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register);
10103 %}
10104 ins_pipe(pipe_slow); // XXX
10105 %}
10107 instruct convL2F_reg_mem(regF dst, memory src)
10108 %{
10109 match(Set dst (ConvL2F (LoadL src)));
10111 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10112 ins_encode %{
10113 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address);
10114 %}
10115 ins_pipe(pipe_slow); // XXX
10116 %}
10118 instruct convL2D_reg_reg(regD dst, rRegL src)
10119 %{
10120 match(Set dst (ConvL2D src));
10122 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10123 ins_encode %{
10124 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register);
10125 %}
10126 ins_pipe(pipe_slow); // XXX
10127 %}
10129 instruct convL2D_reg_mem(regD dst, memory src)
10130 %{
10131 match(Set dst (ConvL2D (LoadL src)));
10133 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10134 ins_encode %{
10135 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address);
10136 %}
10137 ins_pipe(pipe_slow); // XXX
10138 %}
10140 instruct convI2L_reg_reg(rRegL dst, rRegI src)
10141 %{
10142 match(Set dst (ConvI2L src));
10144 ins_cost(125);
10145 format %{ "movslq $dst, $src\t# i2l" %}
10146 ins_encode %{
10147 __ movslq($dst$$Register, $src$$Register);
10148 %}
10149 ins_pipe(ialu_reg_reg);
10150 %}
10152 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src)
10153 // %{
10154 // match(Set dst (ConvI2L src));
10155 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 &&
10156 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0);
10157 // predicate(((const TypeNode*) n)->type()->is_long()->_hi ==
10158 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi &&
10159 // ((const TypeNode*) n)->type()->is_long()->_lo ==
10160 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo);
10162 // format %{ "movl $dst, $src\t# unsigned i2l" %}
10163 // ins_encode(enc_copy(dst, src));
10164 // // opcode(0x63); // needs REX.W
10165 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
10166 // ins_pipe(ialu_reg_reg);
10167 // %}
10169 // Zero-extend convert int to long
10170 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
10171 %{
10172 match(Set dst (AndL (ConvI2L src) mask));
10174 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10175 ins_encode %{
10176 if ($dst$$reg != $src$$reg) {
10177 __ movl($dst$$Register, $src$$Register);
10178 }
10179 %}
10180 ins_pipe(ialu_reg_reg);
10181 %}
10183 // Zero-extend convert int to long
10184 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
10185 %{
10186 match(Set dst (AndL (ConvI2L (LoadI src)) mask));
10188 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10189 ins_encode %{
10190 __ movl($dst$$Register, $src$$Address);
10191 %}
10192 ins_pipe(ialu_reg_mem);
10193 %}
10195 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
10196 %{
10197 match(Set dst (AndL src mask));
10199 format %{ "movl $dst, $src\t# zero-extend long" %}
10200 ins_encode %{
10201 __ movl($dst$$Register, $src$$Register);
10202 %}
10203 ins_pipe(ialu_reg_reg);
10204 %}
10206 instruct convL2I_reg_reg(rRegI dst, rRegL src)
10207 %{
10208 match(Set dst (ConvL2I src));
10210 format %{ "movl $dst, $src\t# l2i" %}
10211 ins_encode %{
10212 __ movl($dst$$Register, $src$$Register);
10213 %}
10214 ins_pipe(ialu_reg_reg);
10215 %}
10218 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
10219 match(Set dst (MoveF2I src));
10220 effect(DEF dst, USE src);
10222 ins_cost(125);
10223 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %}
10224 ins_encode %{
10225 __ movl($dst$$Register, Address(rsp, $src$$disp));
10226 %}
10227 ins_pipe(ialu_reg_mem);
10228 %}
10230 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
10231 match(Set dst (MoveI2F src));
10232 effect(DEF dst, USE src);
10234 ins_cost(125);
10235 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %}
10236 ins_encode %{
10237 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
10238 %}
10239 ins_pipe(pipe_slow);
10240 %}
10242 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
10243 match(Set dst (MoveD2L src));
10244 effect(DEF dst, USE src);
10246 ins_cost(125);
10247 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %}
10248 ins_encode %{
10249 __ movq($dst$$Register, Address(rsp, $src$$disp));
10250 %}
10251 ins_pipe(ialu_reg_mem);
10252 %}
10254 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
10255 predicate(!UseXmmLoadAndClearUpper);
10256 match(Set dst (MoveL2D src));
10257 effect(DEF dst, USE src);
10259 ins_cost(125);
10260 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %}
10261 ins_encode %{
10262 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10263 %}
10264 ins_pipe(pipe_slow);
10265 %}
10267 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
10268 predicate(UseXmmLoadAndClearUpper);
10269 match(Set dst (MoveL2D src));
10270 effect(DEF dst, USE src);
10272 ins_cost(125);
10273 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %}
10274 ins_encode %{
10275 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10276 %}
10277 ins_pipe(pipe_slow);
10278 %}
10281 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
10282 match(Set dst (MoveF2I src));
10283 effect(DEF dst, USE src);
10285 ins_cost(95); // XXX
10286 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %}
10287 ins_encode %{
10288 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
10289 %}
10290 ins_pipe(pipe_slow);
10291 %}
10293 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
10294 match(Set dst (MoveI2F src));
10295 effect(DEF dst, USE src);
10297 ins_cost(100);
10298 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %}
10299 ins_encode %{
10300 __ movl(Address(rsp, $dst$$disp), $src$$Register);
10301 %}
10302 ins_pipe( ialu_mem_reg );
10303 %}
10305 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
10306 match(Set dst (MoveD2L src));
10307 effect(DEF dst, USE src);
10309 ins_cost(95); // XXX
10310 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %}
10311 ins_encode %{
10312 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
10313 %}
10314 ins_pipe(pipe_slow);
10315 %}
10317 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
10318 match(Set dst (MoveL2D src));
10319 effect(DEF dst, USE src);
10321 ins_cost(100);
10322 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %}
10323 ins_encode %{
10324 __ movq(Address(rsp, $dst$$disp), $src$$Register);
10325 %}
10326 ins_pipe(ialu_mem_reg);
10327 %}
10329 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
10330 match(Set dst (MoveF2I src));
10331 effect(DEF dst, USE src);
10332 ins_cost(85);
10333 format %{ "movd $dst,$src\t# MoveF2I" %}
10334 ins_encode %{
10335 __ movdl($dst$$Register, $src$$XMMRegister);
10336 %}
10337 ins_pipe( pipe_slow );
10338 %}
10340 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
10341 match(Set dst (MoveD2L src));
10342 effect(DEF dst, USE src);
10343 ins_cost(85);
10344 format %{ "movd $dst,$src\t# MoveD2L" %}
10345 ins_encode %{
10346 __ movdq($dst$$Register, $src$$XMMRegister);
10347 %}
10348 ins_pipe( pipe_slow );
10349 %}
10351 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
10352 match(Set dst (MoveI2F src));
10353 effect(DEF dst, USE src);
10354 ins_cost(100);
10355 format %{ "movd $dst,$src\t# MoveI2F" %}
10356 ins_encode %{
10357 __ movdl($dst$$XMMRegister, $src$$Register);
10358 %}
10359 ins_pipe( pipe_slow );
10360 %}
10362 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
10363 match(Set dst (MoveL2D src));
10364 effect(DEF dst, USE src);
10365 ins_cost(100);
10366 format %{ "movd $dst,$src\t# MoveL2D" %}
10367 ins_encode %{
10368 __ movdq($dst$$XMMRegister, $src$$Register);
10369 %}
10370 ins_pipe( pipe_slow );
10371 %}
10374 // =======================================================================
10375 // fast clearing of an array
10376 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10377 rFlagsReg cr)
10378 %{
10379 predicate(!UseFastStosb);
10380 match(Set dummy (ClearArray cnt base));
10381 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10383 format %{ "xorq rax, rax\t# ClearArray:\n\t"
10384 "rep stosq\t# Store rax to *rdi++ while rcx--" %}
10385 ins_encode %{
10386 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
10387 %}
10388 ins_pipe(pipe_slow);
10389 %}
10391 instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10392 rFlagsReg cr)
10393 %{
10394 predicate(UseFastStosb);
10395 match(Set dummy (ClearArray cnt base));
10396 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10397 format %{ "xorq rax, rax\t# ClearArray:\n\t"
10398 "shlq rcx,3\t# Convert doublewords to bytes\n\t"
10399 "rep stosb\t# Store rax to *rdi++ while rcx--" %}
10400 ins_encode %{
10401 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
10402 %}
10403 ins_pipe( pipe_slow );
10404 %}
10406 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
10407 rax_RegI result, regD tmp1, rFlagsReg cr)
10408 %{
10409 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
10410 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
10412 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
10413 ins_encode %{
10414 __ string_compare($str1$$Register, $str2$$Register,
10415 $cnt1$$Register, $cnt2$$Register, $result$$Register,
10416 $tmp1$$XMMRegister);
10417 %}
10418 ins_pipe( pipe_slow );
10419 %}
10421 // fast search of substring with known size.
10422 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
10423 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
10424 %{
10425 predicate(UseSSE42Intrinsics);
10426 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
10427 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
10429 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
10430 ins_encode %{
10431 int icnt2 = (int)$int_cnt2$$constant;
10432 if (icnt2 >= 8) {
10433 // IndexOf for constant substrings with size >= 8 elements
10434 // which don't need to be loaded through stack.
10435 __ string_indexofC8($str1$$Register, $str2$$Register,
10436 $cnt1$$Register, $cnt2$$Register,
10437 icnt2, $result$$Register,
10438 $vec$$XMMRegister, $tmp$$Register);
10439 } else {
10440 // Small strings are loaded through stack if they cross page boundary.
10441 __ string_indexof($str1$$Register, $str2$$Register,
10442 $cnt1$$Register, $cnt2$$Register,
10443 icnt2, $result$$Register,
10444 $vec$$XMMRegister, $tmp$$Register);
10445 }
10446 %}
10447 ins_pipe( pipe_slow );
10448 %}
10450 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
10451 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
10452 %{
10453 predicate(UseSSE42Intrinsics);
10454 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
10455 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
10457 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
10458 ins_encode %{
10459 __ string_indexof($str1$$Register, $str2$$Register,
10460 $cnt1$$Register, $cnt2$$Register,
10461 (-1), $result$$Register,
10462 $vec$$XMMRegister, $tmp$$Register);
10463 %}
10464 ins_pipe( pipe_slow );
10465 %}
10467 // fast string equals
10468 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
10469 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
10470 %{
10471 match(Set result (StrEquals (Binary str1 str2) cnt));
10472 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
10474 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
10475 ins_encode %{
10476 __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
10477 $cnt$$Register, $result$$Register, $tmp3$$Register,
10478 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
10479 %}
10480 ins_pipe( pipe_slow );
10481 %}
10483 // fast array equals
10484 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
10485 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
10486 %{
10487 match(Set result (AryEq ary1 ary2));
10488 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
10489 //ins_cost(300);
10491 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
10492 ins_encode %{
10493 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
10494 $tmp3$$Register, $result$$Register, $tmp4$$Register,
10495 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
10496 %}
10497 ins_pipe( pipe_slow );
10498 %}
10500 // encode char[] to byte[] in ISO_8859_1
10501 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len,
10502 regD tmp1, regD tmp2, regD tmp3, regD tmp4,
10503 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
10504 match(Set result (EncodeISOArray src (Binary dst len)));
10505 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
10507 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %}
10508 ins_encode %{
10509 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
10510 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
10511 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
10512 %}
10513 ins_pipe( pipe_slow );
10514 %}
10516 //----------Overflow Math Instructions-----------------------------------------
10518 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2)
10519 %{
10520 match(Set cr (OverflowAddI op1 op2));
10521 effect(DEF cr, USE_KILL op1, USE op2);
10523 format %{ "addl $op1, $op2\t# overflow check int" %}
10525 ins_encode %{
10526 __ addl($op1$$Register, $op2$$Register);
10527 %}
10528 ins_pipe(ialu_reg_reg);
10529 %}
10531 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2)
10532 %{
10533 match(Set cr (OverflowAddI op1 op2));
10534 effect(DEF cr, USE_KILL op1, USE op2);
10536 format %{ "addl $op1, $op2\t# overflow check int" %}
10538 ins_encode %{
10539 __ addl($op1$$Register, $op2$$constant);
10540 %}
10541 ins_pipe(ialu_reg_reg);
10542 %}
10544 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2)
10545 %{
10546 match(Set cr (OverflowAddL op1 op2));
10547 effect(DEF cr, USE_KILL op1, USE op2);
10549 format %{ "addq $op1, $op2\t# overflow check long" %}
10550 ins_encode %{
10551 __ addq($op1$$Register, $op2$$Register);
10552 %}
10553 ins_pipe(ialu_reg_reg);
10554 %}
10556 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2)
10557 %{
10558 match(Set cr (OverflowAddL op1 op2));
10559 effect(DEF cr, USE_KILL op1, USE op2);
10561 format %{ "addq $op1, $op2\t# overflow check long" %}
10562 ins_encode %{
10563 __ addq($op1$$Register, $op2$$constant);
10564 %}
10565 ins_pipe(ialu_reg_reg);
10566 %}
10568 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
10569 %{
10570 match(Set cr (OverflowSubI op1 op2));
10572 format %{ "cmpl $op1, $op2\t# overflow check int" %}
10573 ins_encode %{
10574 __ cmpl($op1$$Register, $op2$$Register);
10575 %}
10576 ins_pipe(ialu_reg_reg);
10577 %}
10579 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
10580 %{
10581 match(Set cr (OverflowSubI op1 op2));
10583 format %{ "cmpl $op1, $op2\t# overflow check int" %}
10584 ins_encode %{
10585 __ cmpl($op1$$Register, $op2$$constant);
10586 %}
10587 ins_pipe(ialu_reg_reg);
10588 %}
10590 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
10591 %{
10592 match(Set cr (OverflowSubL op1 op2));
10594 format %{ "cmpq $op1, $op2\t# overflow check long" %}
10595 ins_encode %{
10596 __ cmpq($op1$$Register, $op2$$Register);
10597 %}
10598 ins_pipe(ialu_reg_reg);
10599 %}
10601 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
10602 %{
10603 match(Set cr (OverflowSubL op1 op2));
10605 format %{ "cmpq $op1, $op2\t# overflow check long" %}
10606 ins_encode %{
10607 __ cmpq($op1$$Register, $op2$$constant);
10608 %}
10609 ins_pipe(ialu_reg_reg);
10610 %}
10612 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2)
10613 %{
10614 match(Set cr (OverflowSubI zero op2));
10615 effect(DEF cr, USE_KILL op2);
10617 format %{ "negl $op2\t# overflow check int" %}
10618 ins_encode %{
10619 __ negl($op2$$Register);
10620 %}
10621 ins_pipe(ialu_reg_reg);
10622 %}
10624 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2)
10625 %{
10626 match(Set cr (OverflowSubL zero op2));
10627 effect(DEF cr, USE_KILL op2);
10629 format %{ "negq $op2\t# overflow check long" %}
10630 ins_encode %{
10631 __ negq($op2$$Register);
10632 %}
10633 ins_pipe(ialu_reg_reg);
10634 %}
10636 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2)
10637 %{
10638 match(Set cr (OverflowMulI op1 op2));
10639 effect(DEF cr, USE_KILL op1, USE op2);
10641 format %{ "imull $op1, $op2\t# overflow check int" %}
10642 ins_encode %{
10643 __ imull($op1$$Register, $op2$$Register);
10644 %}
10645 ins_pipe(ialu_reg_reg_alu0);
10646 %}
10648 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp)
10649 %{
10650 match(Set cr (OverflowMulI op1 op2));
10651 effect(DEF cr, TEMP tmp, USE op1, USE op2);
10653 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %}
10654 ins_encode %{
10655 __ imull($tmp$$Register, $op1$$Register, $op2$$constant);
10656 %}
10657 ins_pipe(ialu_reg_reg_alu0);
10658 %}
10660 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2)
10661 %{
10662 match(Set cr (OverflowMulL op1 op2));
10663 effect(DEF cr, USE_KILL op1, USE op2);
10665 format %{ "imulq $op1, $op2\t# overflow check long" %}
10666 ins_encode %{
10667 __ imulq($op1$$Register, $op2$$Register);
10668 %}
10669 ins_pipe(ialu_reg_reg_alu0);
10670 %}
10672 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp)
10673 %{
10674 match(Set cr (OverflowMulL op1 op2));
10675 effect(DEF cr, TEMP tmp, USE op1, USE op2);
10677 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %}
10678 ins_encode %{
10679 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant);
10680 %}
10681 ins_pipe(ialu_reg_reg_alu0);
10682 %}
10685 //----------Control Flow Instructions------------------------------------------
10686 // Signed compare Instructions
10688 // XXX more variants!!
10689 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
10690 %{
10691 match(Set cr (CmpI op1 op2));
10692 effect(DEF cr, USE op1, USE op2);
10694 format %{ "cmpl $op1, $op2" %}
10695 opcode(0x3B); /* Opcode 3B /r */
10696 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
10697 ins_pipe(ialu_cr_reg_reg);
10698 %}
10700 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
10701 %{
10702 match(Set cr (CmpI op1 op2));
10704 format %{ "cmpl $op1, $op2" %}
10705 opcode(0x81, 0x07); /* Opcode 81 /7 */
10706 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
10707 ins_pipe(ialu_cr_reg_imm);
10708 %}
10710 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2)
10711 %{
10712 match(Set cr (CmpI op1 (LoadI op2)));
10714 ins_cost(500); // XXX
10715 format %{ "cmpl $op1, $op2" %}
10716 opcode(0x3B); /* Opcode 3B /r */
10717 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
10718 ins_pipe(ialu_cr_reg_mem);
10719 %}
10721 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero)
10722 %{
10723 match(Set cr (CmpI src zero));
10725 format %{ "testl $src, $src" %}
10726 opcode(0x85);
10727 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
10728 ins_pipe(ialu_cr_reg_imm);
10729 %}
10731 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero)
10732 %{
10733 match(Set cr (CmpI (AndI src con) zero));
10735 format %{ "testl $src, $con" %}
10736 opcode(0xF7, 0x00);
10737 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con));
10738 ins_pipe(ialu_cr_reg_imm);
10739 %}
10741 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero)
10742 %{
10743 match(Set cr (CmpI (AndI src (LoadI mem)) zero));
10745 format %{ "testl $src, $mem" %}
10746 opcode(0x85);
10747 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
10748 ins_pipe(ialu_cr_reg_mem);
10749 %}
10751 // Unsigned compare Instructions; really, same as signed except they
10752 // produce an rFlagsRegU instead of rFlagsReg.
10753 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2)
10754 %{
10755 match(Set cr (CmpU op1 op2));
10757 format %{ "cmpl $op1, $op2\t# unsigned" %}
10758 opcode(0x3B); /* Opcode 3B /r */
10759 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
10760 ins_pipe(ialu_cr_reg_reg);
10761 %}
10763 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2)
10764 %{
10765 match(Set cr (CmpU op1 op2));
10767 format %{ "cmpl $op1, $op2\t# unsigned" %}
10768 opcode(0x81,0x07); /* Opcode 81 /7 */
10769 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
10770 ins_pipe(ialu_cr_reg_imm);
10771 %}
10773 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2)
10774 %{
10775 match(Set cr (CmpU op1 (LoadI op2)));
10777 ins_cost(500); // XXX
10778 format %{ "cmpl $op1, $op2\t# unsigned" %}
10779 opcode(0x3B); /* Opcode 3B /r */
10780 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
10781 ins_pipe(ialu_cr_reg_mem);
10782 %}
10784 // // // Cisc-spilled version of cmpU_rReg
10785 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2)
10786 // //%{
10787 // // match(Set cr (CmpU (LoadI op1) op2));
10788 // //
10789 // // format %{ "CMPu $op1,$op2" %}
10790 // // ins_cost(500);
10791 // // opcode(0x39); /* Opcode 39 /r */
10792 // // ins_encode( OpcP, reg_mem( op1, op2) );
10793 // //%}
10795 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero)
10796 %{
10797 match(Set cr (CmpU src zero));
10799 format %{ "testl $src, $src\t# unsigned" %}
10800 opcode(0x85);
10801 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
10802 ins_pipe(ialu_cr_reg_imm);
10803 %}
10805 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2)
10806 %{
10807 match(Set cr (CmpP op1 op2));
10809 format %{ "cmpq $op1, $op2\t# ptr" %}
10810 opcode(0x3B); /* Opcode 3B /r */
10811 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
10812 ins_pipe(ialu_cr_reg_reg);
10813 %}
10815 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
10816 %{
10817 match(Set cr (CmpP op1 (LoadP op2)));
10819 ins_cost(500); // XXX
10820 format %{ "cmpq $op1, $op2\t# ptr" %}
10821 opcode(0x3B); /* Opcode 3B /r */
10822 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10823 ins_pipe(ialu_cr_reg_mem);
10824 %}
10826 // // // Cisc-spilled version of cmpP_rReg
10827 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2)
10828 // //%{
10829 // // match(Set cr (CmpP (LoadP op1) op2));
10830 // //
10831 // // format %{ "CMPu $op1,$op2" %}
10832 // // ins_cost(500);
10833 // // opcode(0x39); /* Opcode 39 /r */
10834 // // ins_encode( OpcP, reg_mem( op1, op2) );
10835 // //%}
10837 // XXX this is generalized by compP_rReg_mem???
10838 // Compare raw pointer (used in out-of-heap check).
10839 // Only works because non-oop pointers must be raw pointers
10840 // and raw pointers have no anti-dependencies.
10841 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
10842 %{
10843 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none);
10844 match(Set cr (CmpP op1 (LoadP op2)));
10846 format %{ "cmpq $op1, $op2\t# raw ptr" %}
10847 opcode(0x3B); /* Opcode 3B /r */
10848 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10849 ins_pipe(ialu_cr_reg_mem);
10850 %}
10852 // This will generate a signed flags result. This should be OK since
10853 // any compare to a zero should be eq/neq.
10854 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero)
10855 %{
10856 match(Set cr (CmpP src zero));
10858 format %{ "testq $src, $src\t# ptr" %}
10859 opcode(0x85);
10860 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
10861 ins_pipe(ialu_cr_reg_imm);
10862 %}
10864 // This will generate a signed flags result. This should be OK since
10865 // any compare to a zero should be eq/neq.
10866 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
10867 %{
10868 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
10869 match(Set cr (CmpP (LoadP op) zero));
10871 ins_cost(500); // XXX
10872 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %}
10873 opcode(0xF7); /* Opcode F7 /0 */
10874 ins_encode(REX_mem_wide(op),
10875 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
10876 ins_pipe(ialu_cr_reg_imm);
10877 %}
10879 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
10880 %{
10881 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
10882 match(Set cr (CmpP (LoadP mem) zero));
10884 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
10885 ins_encode %{
10886 __ cmpq(r12, $mem$$Address);
10887 %}
10888 ins_pipe(ialu_cr_reg_mem);
10889 %}
10891 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
10892 %{
10893 match(Set cr (CmpN op1 op2));
10895 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
10896 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %}
10897 ins_pipe(ialu_cr_reg_reg);
10898 %}
10900 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
10901 %{
10902 match(Set cr (CmpN src (LoadN mem)));
10904 format %{ "cmpl $src, $mem\t# compressed ptr" %}
10905 ins_encode %{
10906 __ cmpl($src$$Register, $mem$$Address);
10907 %}
10908 ins_pipe(ialu_cr_reg_mem);
10909 %}
10911 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{
10912 match(Set cr (CmpN op1 op2));
10914 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
10915 ins_encode %{
10916 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant);
10917 %}
10918 ins_pipe(ialu_cr_reg_imm);
10919 %}
10921 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src)
10922 %{
10923 match(Set cr (CmpN src (LoadN mem)));
10925 format %{ "cmpl $mem, $src\t# compressed ptr" %}
10926 ins_encode %{
10927 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
10928 %}
10929 ins_pipe(ialu_cr_reg_mem);
10930 %}
10932 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{
10933 match(Set cr (CmpN op1 op2));
10935 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %}
10936 ins_encode %{
10937 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant);
10938 %}
10939 ins_pipe(ialu_cr_reg_imm);
10940 %}
10942 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src)
10943 %{
10944 match(Set cr (CmpN src (LoadNKlass mem)));
10946 format %{ "cmpl $mem, $src\t# compressed klass ptr" %}
10947 ins_encode %{
10948 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant);
10949 %}
10950 ins_pipe(ialu_cr_reg_mem);
10951 %}
10953 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
10954 match(Set cr (CmpN src zero));
10956 format %{ "testl $src, $src\t# compressed ptr" %}
10957 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
10958 ins_pipe(ialu_cr_reg_imm);
10959 %}
10961 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
10962 %{
10963 predicate(Universe::narrow_oop_base() != NULL);
10964 match(Set cr (CmpN (LoadN mem) zero));
10966 ins_cost(500); // XXX
10967 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
10968 ins_encode %{
10969 __ cmpl($mem$$Address, (int)0xFFFFFFFF);
10970 %}
10971 ins_pipe(ialu_cr_reg_mem);
10972 %}
10974 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
10975 %{
10976 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL));
10977 match(Set cr (CmpN (LoadN mem) zero));
10979 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
10980 ins_encode %{
10981 __ cmpl(r12, $mem$$Address);
10982 %}
10983 ins_pipe(ialu_cr_reg_mem);
10984 %}
10986 // Yanked all unsigned pointer compare operations.
10987 // Pointer compares are done with CmpP which is already unsigned.
10989 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
10990 %{
10991 match(Set cr (CmpL op1 op2));
10993 format %{ "cmpq $op1, $op2" %}
10994 opcode(0x3B); /* Opcode 3B /r */
10995 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
10996 ins_pipe(ialu_cr_reg_reg);
10997 %}
10999 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
11000 %{
11001 match(Set cr (CmpL op1 op2));
11003 format %{ "cmpq $op1, $op2" %}
11004 opcode(0x81, 0x07); /* Opcode 81 /7 */
11005 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2));
11006 ins_pipe(ialu_cr_reg_imm);
11007 %}
11009 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2)
11010 %{
11011 match(Set cr (CmpL op1 (LoadL op2)));
11013 format %{ "cmpq $op1, $op2" %}
11014 opcode(0x3B); /* Opcode 3B /r */
11015 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
11016 ins_pipe(ialu_cr_reg_mem);
11017 %}
11019 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero)
11020 %{
11021 match(Set cr (CmpL src zero));
11023 format %{ "testq $src, $src" %}
11024 opcode(0x85);
11025 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
11026 ins_pipe(ialu_cr_reg_imm);
11027 %}
11029 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero)
11030 %{
11031 match(Set cr (CmpL (AndL src con) zero));
11033 format %{ "testq $src, $con\t# long" %}
11034 opcode(0xF7, 0x00);
11035 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con));
11036 ins_pipe(ialu_cr_reg_imm);
11037 %}
11039 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero)
11040 %{
11041 match(Set cr (CmpL (AndL src (LoadL mem)) zero));
11043 format %{ "testq $src, $mem" %}
11044 opcode(0x85);
11045 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
11046 ins_pipe(ialu_cr_reg_mem);
11047 %}
11049 // Manifest a CmpL result in an integer register. Very painful.
11050 // This is the test to avoid.
11051 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
11052 %{
11053 match(Set dst (CmpL3 src1 src2));
11054 effect(KILL flags);
11056 ins_cost(275); // XXX
11057 format %{ "cmpq $src1, $src2\t# CmpL3\n\t"
11058 "movl $dst, -1\n\t"
11059 "jl,s done\n\t"
11060 "setne $dst\n\t"
11061 "movzbl $dst, $dst\n\t"
11062 "done:" %}
11063 ins_encode(cmpl3_flag(src1, src2, dst));
11064 ins_pipe(pipe_slow);
11065 %}
11067 //----------Max and Min--------------------------------------------------------
11068 // Min Instructions
11070 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr)
11071 %{
11072 effect(USE_DEF dst, USE src, USE cr);
11074 format %{ "cmovlgt $dst, $src\t# min" %}
11075 opcode(0x0F, 0x4F);
11076 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
11077 ins_pipe(pipe_cmov_reg);
11078 %}
11081 instruct minI_rReg(rRegI dst, rRegI src)
11082 %{
11083 match(Set dst (MinI dst src));
11085 ins_cost(200);
11086 expand %{
11087 rFlagsReg cr;
11088 compI_rReg(cr, dst, src);
11089 cmovI_reg_g(dst, src, cr);
11090 %}
11091 %}
11093 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr)
11094 %{
11095 effect(USE_DEF dst, USE src, USE cr);
11097 format %{ "cmovllt $dst, $src\t# max" %}
11098 opcode(0x0F, 0x4C);
11099 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
11100 ins_pipe(pipe_cmov_reg);
11101 %}
11104 instruct maxI_rReg(rRegI dst, rRegI src)
11105 %{
11106 match(Set dst (MaxI dst src));
11108 ins_cost(200);
11109 expand %{
11110 rFlagsReg cr;
11111 compI_rReg(cr, dst, src);
11112 cmovI_reg_l(dst, src, cr);
11113 %}
11114 %}
11116 // ============================================================================
11117 // Branch Instructions
11119 // Jump Direct - Label defines a relative address from JMP+1
11120 instruct jmpDir(label labl)
11121 %{
11122 match(Goto);
11123 effect(USE labl);
11125 ins_cost(300);
11126 format %{ "jmp $labl" %}
11127 size(5);
11128 ins_encode %{
11129 Label* L = $labl$$label;
11130 __ jmp(*L, false); // Always long jump
11131 %}
11132 ins_pipe(pipe_jmp);
11133 %}
11135 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11136 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl)
11137 %{
11138 match(If cop cr);
11139 effect(USE labl);
11141 ins_cost(300);
11142 format %{ "j$cop $labl" %}
11143 size(6);
11144 ins_encode %{
11145 Label* L = $labl$$label;
11146 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11147 %}
11148 ins_pipe(pipe_jcc);
11149 %}
11151 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11152 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
11153 %{
11154 match(CountedLoopEnd cop cr);
11155 effect(USE labl);
11157 ins_cost(300);
11158 format %{ "j$cop $labl\t# loop end" %}
11159 size(6);
11160 ins_encode %{
11161 Label* L = $labl$$label;
11162 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11163 %}
11164 ins_pipe(pipe_jcc);
11165 %}
11167 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11168 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11169 match(CountedLoopEnd cop cmp);
11170 effect(USE labl);
11172 ins_cost(300);
11173 format %{ "j$cop,u $labl\t# loop end" %}
11174 size(6);
11175 ins_encode %{
11176 Label* L = $labl$$label;
11177 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11178 %}
11179 ins_pipe(pipe_jcc);
11180 %}
11182 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11183 match(CountedLoopEnd cop cmp);
11184 effect(USE labl);
11186 ins_cost(200);
11187 format %{ "j$cop,u $labl\t# loop end" %}
11188 size(6);
11189 ins_encode %{
11190 Label* L = $labl$$label;
11191 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11192 %}
11193 ins_pipe(pipe_jcc);
11194 %}
11196 // Jump Direct Conditional - using unsigned comparison
11197 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11198 match(If cop cmp);
11199 effect(USE labl);
11201 ins_cost(300);
11202 format %{ "j$cop,u $labl" %}
11203 size(6);
11204 ins_encode %{
11205 Label* L = $labl$$label;
11206 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11207 %}
11208 ins_pipe(pipe_jcc);
11209 %}
11211 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11212 match(If cop cmp);
11213 effect(USE labl);
11215 ins_cost(200);
11216 format %{ "j$cop,u $labl" %}
11217 size(6);
11218 ins_encode %{
11219 Label* L = $labl$$label;
11220 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11221 %}
11222 ins_pipe(pipe_jcc);
11223 %}
11225 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
11226 match(If cop cmp);
11227 effect(USE labl);
11229 ins_cost(200);
11230 format %{ $$template
11231 if ($cop$$cmpcode == Assembler::notEqual) {
11232 $$emit$$"jp,u $labl\n\t"
11233 $$emit$$"j$cop,u $labl"
11234 } else {
11235 $$emit$$"jp,u done\n\t"
11236 $$emit$$"j$cop,u $labl\n\t"
11237 $$emit$$"done:"
11238 }
11239 %}
11240 ins_encode %{
11241 Label* l = $labl$$label;
11242 if ($cop$$cmpcode == Assembler::notEqual) {
11243 __ jcc(Assembler::parity, *l, false);
11244 __ jcc(Assembler::notEqual, *l, false);
11245 } else if ($cop$$cmpcode == Assembler::equal) {
11246 Label done;
11247 __ jccb(Assembler::parity, done);
11248 __ jcc(Assembler::equal, *l, false);
11249 __ bind(done);
11250 } else {
11251 ShouldNotReachHere();
11252 }
11253 %}
11254 ins_pipe(pipe_jcc);
11255 %}
11257 // ============================================================================
11258 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
11259 // superklass array for an instance of the superklass. Set a hidden
11260 // internal cache on a hit (cache is checked with exposed code in
11261 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The
11262 // encoding ALSO sets flags.
11264 instruct partialSubtypeCheck(rdi_RegP result,
11265 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
11266 rFlagsReg cr)
11267 %{
11268 match(Set result (PartialSubtypeCheck sub super));
11269 effect(KILL rcx, KILL cr);
11271 ins_cost(1100); // slightly larger than the next version
11272 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
11273 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t"
11274 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t"
11275 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t"
11276 "jne,s miss\t\t# Missed: rdi not-zero\n\t"
11277 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
11278 "xorq $result, $result\t\t Hit: rdi zero\n\t"
11279 "miss:\t" %}
11281 opcode(0x1); // Force a XOR of RDI
11282 ins_encode(enc_PartialSubtypeCheck());
11283 ins_pipe(pipe_slow);
11284 %}
11286 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr,
11287 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
11288 immP0 zero,
11289 rdi_RegP result)
11290 %{
11291 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
11292 effect(KILL rcx, KILL result);
11294 ins_cost(1000);
11295 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
11296 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t"
11297 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t"
11298 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t"
11299 "jne,s miss\t\t# Missed: flags nz\n\t"
11300 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
11301 "miss:\t" %}
11303 opcode(0x0); // No need to XOR RDI
11304 ins_encode(enc_PartialSubtypeCheck());
11305 ins_pipe(pipe_slow);
11306 %}
11308 // ============================================================================
11309 // Branch Instructions -- short offset versions
11310 //
11311 // These instructions are used to replace jumps of a long offset (the default
11312 // match) with jumps of a shorter offset. These instructions are all tagged
11313 // with the ins_short_branch attribute, which causes the ADLC to suppress the
11314 // match rules in general matching. Instead, the ADLC generates a conversion
11315 // method in the MachNode which can be used to do in-place replacement of the
11316 // long variant with the shorter variant. The compiler will determine if a
11317 // branch can be taken by the is_short_branch_offset() predicate in the machine
11318 // specific code section of the file.
11320 // Jump Direct - Label defines a relative address from JMP+1
11321 instruct jmpDir_short(label labl) %{
11322 match(Goto);
11323 effect(USE labl);
11325 ins_cost(300);
11326 format %{ "jmp,s $labl" %}
11327 size(2);
11328 ins_encode %{
11329 Label* L = $labl$$label;
11330 __ jmpb(*L);
11331 %}
11332 ins_pipe(pipe_jmp);
11333 ins_short_branch(1);
11334 %}
11336 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11337 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
11338 match(If cop cr);
11339 effect(USE labl);
11341 ins_cost(300);
11342 format %{ "j$cop,s $labl" %}
11343 size(2);
11344 ins_encode %{
11345 Label* L = $labl$$label;
11346 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11347 %}
11348 ins_pipe(pipe_jcc);
11349 ins_short_branch(1);
11350 %}
11352 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11353 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
11354 match(CountedLoopEnd cop cr);
11355 effect(USE labl);
11357 ins_cost(300);
11358 format %{ "j$cop,s $labl\t# loop end" %}
11359 size(2);
11360 ins_encode %{
11361 Label* L = $labl$$label;
11362 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11363 %}
11364 ins_pipe(pipe_jcc);
11365 ins_short_branch(1);
11366 %}
11368 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11369 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11370 match(CountedLoopEnd cop cmp);
11371 effect(USE labl);
11373 ins_cost(300);
11374 format %{ "j$cop,us $labl\t# loop end" %}
11375 size(2);
11376 ins_encode %{
11377 Label* L = $labl$$label;
11378 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11379 %}
11380 ins_pipe(pipe_jcc);
11381 ins_short_branch(1);
11382 %}
11384 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11385 match(CountedLoopEnd cop cmp);
11386 effect(USE labl);
11388 ins_cost(300);
11389 format %{ "j$cop,us $labl\t# loop end" %}
11390 size(2);
11391 ins_encode %{
11392 Label* L = $labl$$label;
11393 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11394 %}
11395 ins_pipe(pipe_jcc);
11396 ins_short_branch(1);
11397 %}
11399 // Jump Direct Conditional - using unsigned comparison
11400 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11401 match(If cop cmp);
11402 effect(USE labl);
11404 ins_cost(300);
11405 format %{ "j$cop,us $labl" %}
11406 size(2);
11407 ins_encode %{
11408 Label* L = $labl$$label;
11409 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11410 %}
11411 ins_pipe(pipe_jcc);
11412 ins_short_branch(1);
11413 %}
11415 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11416 match(If cop cmp);
11417 effect(USE labl);
11419 ins_cost(300);
11420 format %{ "j$cop,us $labl" %}
11421 size(2);
11422 ins_encode %{
11423 Label* L = $labl$$label;
11424 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11425 %}
11426 ins_pipe(pipe_jcc);
11427 ins_short_branch(1);
11428 %}
11430 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
11431 match(If cop cmp);
11432 effect(USE labl);
11434 ins_cost(300);
11435 format %{ $$template
11436 if ($cop$$cmpcode == Assembler::notEqual) {
11437 $$emit$$"jp,u,s $labl\n\t"
11438 $$emit$$"j$cop,u,s $labl"
11439 } else {
11440 $$emit$$"jp,u,s done\n\t"
11441 $$emit$$"j$cop,u,s $labl\n\t"
11442 $$emit$$"done:"
11443 }
11444 %}
11445 size(4);
11446 ins_encode %{
11447 Label* l = $labl$$label;
11448 if ($cop$$cmpcode == Assembler::notEqual) {
11449 __ jccb(Assembler::parity, *l);
11450 __ jccb(Assembler::notEqual, *l);
11451 } else if ($cop$$cmpcode == Assembler::equal) {
11452 Label done;
11453 __ jccb(Assembler::parity, done);
11454 __ jccb(Assembler::equal, *l);
11455 __ bind(done);
11456 } else {
11457 ShouldNotReachHere();
11458 }
11459 %}
11460 ins_pipe(pipe_jcc);
11461 ins_short_branch(1);
11462 %}
11464 // ============================================================================
11465 // inlined locking and unlocking
11467 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{
11468 predicate(Compile::current()->use_rtm());
11469 match(Set cr (FastLock object box));
11470 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box);
11471 ins_cost(300);
11472 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %}
11473 ins_encode %{
11474 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
11475 $scr$$Register, $cx1$$Register, $cx2$$Register,
11476 _counters, _rtm_counters, _stack_rtm_counters,
11477 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(),
11478 true, ra_->C->profile_rtm());
11479 %}
11480 ins_pipe(pipe_slow);
11481 %}
11483 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{
11484 predicate(!Compile::current()->use_rtm());
11485 match(Set cr (FastLock object box));
11486 effect(TEMP tmp, TEMP scr, USE_KILL box);
11487 ins_cost(300);
11488 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
11489 ins_encode %{
11490 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
11491 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false);
11492 %}
11493 ins_pipe(pipe_slow);
11494 %}
11496 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{
11497 match(Set cr (FastUnlock object box));
11498 effect(TEMP tmp, USE_KILL box);
11499 ins_cost(300);
11500 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
11501 ins_encode %{
11502 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm());
11503 %}
11504 ins_pipe(pipe_slow);
11505 %}
11508 // ============================================================================
11509 // Safepoint Instructions
11510 instruct safePoint_poll(rFlagsReg cr)
11511 %{
11512 predicate(!Assembler::is_polling_page_far());
11513 match(SafePoint);
11514 effect(KILL cr);
11516 format %{ "testl rax, [rip + #offset_to_poll_page]\t"
11517 "# Safepoint: poll for GC" %}
11518 ins_cost(125);
11519 ins_encode %{
11520 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type);
11521 __ testl(rax, addr);
11522 %}
11523 ins_pipe(ialu_reg_mem);
11524 %}
11526 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
11527 %{
11528 predicate(Assembler::is_polling_page_far());
11529 match(SafePoint poll);
11530 effect(KILL cr, USE poll);
11532 format %{ "testl rax, [$poll]\t"
11533 "# Safepoint: poll for GC" %}
11534 ins_cost(125);
11535 ins_encode %{
11536 __ relocate(relocInfo::poll_type);
11537 __ testl(rax, Address($poll$$Register, 0));
11538 %}
11539 ins_pipe(ialu_reg_mem);
11540 %}
11542 // ============================================================================
11543 // Procedure Call/Return Instructions
11544 // Call Java Static Instruction
11545 // Note: If this code changes, the corresponding ret_addr_offset() and
11546 // compute_padding() functions will have to be adjusted.
11547 instruct CallStaticJavaDirect(method meth) %{
11548 match(CallStaticJava);
11549 effect(USE meth);
11551 ins_cost(300);
11552 format %{ "call,static " %}
11553 opcode(0xE8); /* E8 cd */
11554 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog);
11555 ins_pipe(pipe_slow);
11556 ins_alignment(4);
11557 %}
11559 // Call Java Dynamic Instruction
11560 // Note: If this code changes, the corresponding ret_addr_offset() and
11561 // compute_padding() functions will have to be adjusted.
11562 instruct CallDynamicJavaDirect(method meth)
11563 %{
11564 match(CallDynamicJava);
11565 effect(USE meth);
11567 ins_cost(300);
11568 format %{ "movq rax, #Universe::non_oop_word()\n\t"
11569 "call,dynamic " %}
11570 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog);
11571 ins_pipe(pipe_slow);
11572 ins_alignment(4);
11573 %}
11575 // Call Runtime Instruction
11576 instruct CallRuntimeDirect(method meth)
11577 %{
11578 match(CallRuntime);
11579 effect(USE meth);
11581 ins_cost(300);
11582 format %{ "call,runtime " %}
11583 ins_encode(clear_avx, Java_To_Runtime(meth));
11584 ins_pipe(pipe_slow);
11585 %}
11587 // Call runtime without safepoint
11588 instruct CallLeafDirect(method meth)
11589 %{
11590 match(CallLeaf);
11591 effect(USE meth);
11593 ins_cost(300);
11594 format %{ "call_leaf,runtime " %}
11595 ins_encode(clear_avx, Java_To_Runtime(meth));
11596 ins_pipe(pipe_slow);
11597 %}
11599 // Call runtime without safepoint
11600 instruct CallLeafNoFPDirect(method meth)
11601 %{
11602 match(CallLeafNoFP);
11603 effect(USE meth);
11605 ins_cost(300);
11606 format %{ "call_leaf_nofp,runtime " %}
11607 ins_encode(Java_To_Runtime(meth));
11608 ins_pipe(pipe_slow);
11609 %}
11611 // Return Instruction
11612 // Remove the return address & jump to it.
11613 // Notice: We always emit a nop after a ret to make sure there is room
11614 // for safepoint patching
11615 instruct Ret()
11616 %{
11617 match(Return);
11619 format %{ "ret" %}
11620 opcode(0xC3);
11621 ins_encode(OpcP);
11622 ins_pipe(pipe_jmp);
11623 %}
11625 // Tail Call; Jump from runtime stub to Java code.
11626 // Also known as an 'interprocedural jump'.
11627 // Target of jump will eventually return to caller.
11628 // TailJump below removes the return address.
11629 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop)
11630 %{
11631 match(TailCall jump_target method_oop);
11633 ins_cost(300);
11634 format %{ "jmp $jump_target\t# rbx holds method oop" %}
11635 opcode(0xFF, 0x4); /* Opcode FF /4 */
11636 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target));
11637 ins_pipe(pipe_jmp);
11638 %}
11640 // Tail Jump; remove the return address; jump to target.
11641 // TailCall above leaves the return address around.
11642 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop)
11643 %{
11644 match(TailJump jump_target ex_oop);
11646 ins_cost(300);
11647 format %{ "popq rdx\t# pop return address\n\t"
11648 "jmp $jump_target" %}
11649 opcode(0xFF, 0x4); /* Opcode FF /4 */
11650 ins_encode(Opcode(0x5a), // popq rdx
11651 REX_reg(jump_target), OpcP, reg_opc(jump_target));
11652 ins_pipe(pipe_jmp);
11653 %}
11655 // Create exception oop: created by stack-crawling runtime code.
11656 // Created exception is now available to this handler, and is setup
11657 // just prior to jumping to this handler. No code emitted.
11658 instruct CreateException(rax_RegP ex_oop)
11659 %{
11660 match(Set ex_oop (CreateEx));
11662 size(0);
11663 // use the following format syntax
11664 format %{ "# exception oop is in rax; no code emitted" %}
11665 ins_encode();
11666 ins_pipe(empty);
11667 %}
11669 // Rethrow exception:
11670 // The exception oop will come in the first argument position.
11671 // Then JUMP (not call) to the rethrow stub code.
11672 instruct RethrowException()
11673 %{
11674 match(Rethrow);
11676 // use the following format syntax
11677 format %{ "jmp rethrow_stub" %}
11678 ins_encode(enc_rethrow);
11679 ins_pipe(pipe_jmp);
11680 %}
11683 // ============================================================================
11684 // This name is KNOWN by the ADLC and cannot be changed.
11685 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
11686 // for this guy.
11687 instruct tlsLoadP(r15_RegP dst) %{
11688 match(Set dst (ThreadLocal));
11689 effect(DEF dst);
11691 size(0);
11692 format %{ "# TLS is in R15" %}
11693 ins_encode( /*empty encoding*/ );
11694 ins_pipe(ialu_reg_reg);
11695 %}
11698 //----------PEEPHOLE RULES-----------------------------------------------------
11699 // These must follow all instruction definitions as they use the names
11700 // defined in the instructions definitions.
11701 //
11702 // peepmatch ( root_instr_name [preceding_instruction]* );
11703 //
11704 // peepconstraint %{
11705 // (instruction_number.operand_name relational_op instruction_number.operand_name
11706 // [, ...] );
11707 // // instruction numbers are zero-based using left to right order in peepmatch
11708 //
11709 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
11710 // // provide an instruction_number.operand_name for each operand that appears
11711 // // in the replacement instruction's match rule
11712 //
11713 // ---------VM FLAGS---------------------------------------------------------
11714 //
11715 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11716 //
11717 // Each peephole rule is given an identifying number starting with zero and
11718 // increasing by one in the order seen by the parser. An individual peephole
11719 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11720 // on the command-line.
11721 //
11722 // ---------CURRENT LIMITATIONS----------------------------------------------
11723 //
11724 // Only match adjacent instructions in same basic block
11725 // Only equality constraints
11726 // Only constraints between operands, not (0.dest_reg == RAX_enc)
11727 // Only one replacement instruction
11728 //
11729 // ---------EXAMPLE----------------------------------------------------------
11730 //
11731 // // pertinent parts of existing instructions in architecture description
11732 // instruct movI(rRegI dst, rRegI src)
11733 // %{
11734 // match(Set dst (CopyI src));
11735 // %}
11736 //
11737 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
11738 // %{
11739 // match(Set dst (AddI dst src));
11740 // effect(KILL cr);
11741 // %}
11742 //
11743 // // Change (inc mov) to lea
11744 // peephole %{
11745 // // increment preceeded by register-register move
11746 // peepmatch ( incI_rReg movI );
11747 // // require that the destination register of the increment
11748 // // match the destination register of the move
11749 // peepconstraint ( 0.dst == 1.dst );
11750 // // construct a replacement instruction that sets
11751 // // the destination to ( move's source register + one )
11752 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) );
11753 // %}
11754 //
11756 // Implementation no longer uses movX instructions since
11757 // machine-independent system no longer uses CopyX nodes.
11758 //
11759 // peephole
11760 // %{
11761 // peepmatch (incI_rReg movI);
11762 // peepconstraint (0.dst == 1.dst);
11763 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11764 // %}
11766 // peephole
11767 // %{
11768 // peepmatch (decI_rReg movI);
11769 // peepconstraint (0.dst == 1.dst);
11770 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11771 // %}
11773 // peephole
11774 // %{
11775 // peepmatch (addI_rReg_imm movI);
11776 // peepconstraint (0.dst == 1.dst);
11777 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11778 // %}
11780 // peephole
11781 // %{
11782 // peepmatch (incL_rReg movL);
11783 // peepconstraint (0.dst == 1.dst);
11784 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11785 // %}
11787 // peephole
11788 // %{
11789 // peepmatch (decL_rReg movL);
11790 // peepconstraint (0.dst == 1.dst);
11791 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11792 // %}
11794 // peephole
11795 // %{
11796 // peepmatch (addL_rReg_imm movL);
11797 // peepconstraint (0.dst == 1.dst);
11798 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11799 // %}
11801 // peephole
11802 // %{
11803 // peepmatch (addP_rReg_imm movP);
11804 // peepconstraint (0.dst == 1.dst);
11805 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src));
11806 // %}
11808 // // Change load of spilled value to only a spill
11809 // instruct storeI(memory mem, rRegI src)
11810 // %{
11811 // match(Set mem (StoreI mem src));
11812 // %}
11813 //
11814 // instruct loadI(rRegI dst, memory mem)
11815 // %{
11816 // match(Set dst (LoadI mem));
11817 // %}
11818 //
11820 peephole
11821 %{
11822 peepmatch (loadI storeI);
11823 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
11824 peepreplace (storeI(1.mem 1.mem 1.src));
11825 %}
11827 peephole
11828 %{
11829 peepmatch (loadL storeL);
11830 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
11831 peepreplace (storeL(1.mem 1.mem 1.src));
11832 %}
11834 //----------SMARTSPILL RULES---------------------------------------------------
11835 // These must follow all instruction definitions as they use the names
11836 // defined in the instructions definitions.