1 //
2 // Copyright (c) 2003, 2020, 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 //
24
25 // AMD64 Architecture Description File
26
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.
31
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.
61
62 // General Registers
63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when
64 // used as byte registers)
65
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.
69
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());
72
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());
75
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());
78
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());
81
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());
84
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());
88
89 #ifdef _WIN64
90
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());
93
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());
96
97 #else
98
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());
101
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());
104
105 #endif
106
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());
109
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());
112
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());
115
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());
118
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());
121
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());
124
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());
127
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());
130
131
132 // Floating Point Registers
133
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.
141
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);
158
159
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 //
168
169 // Empty register class.
170 reg_class no_reg();
171
172 // Class for all pointer/long registers
173 reg_class all_reg(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);
189
190 // Class for all int registers
191 reg_class all_int_reg(RAX
192 RDX,
193 RBP,
194 RDI,
195 RSI,
196 RCX,
197 RBX,
198 R8,
199 R9,
200 R10,
201 R11,
202 R12,
203 R13,
204 R14);
205
206 // Class for all pointer registers
207 reg_class any_reg %{
208 return _ANY_REG_mask;
209 %}
210
211 // Class for all pointer registers (excluding RSP)
212 reg_class ptr_reg %{
213 return _PTR_REG_mask;
214 %}
215
216 // Class for all pointer registers (excluding RSP and RBP)
217 reg_class ptr_reg_no_rbp %{
218 return _PTR_REG_NO_RBP_mask;
219 %}
220
221 // Class for all pointer registers (excluding RAX and RSP)
222 reg_class ptr_no_rax_reg %{
223 return _PTR_NO_RAX_REG_mask;
224 %}
225
226 // Class for all pointer registers (excluding RAX, RBX, and RSP)
227 reg_class ptr_no_rax_rbx_reg %{
228 return _PTR_NO_RAX_RBX_REG_mask;
229 %}
230
231 // Class for all long registers (excluding RSP)
232 reg_class long_reg %{
233 return _LONG_REG_mask;
234 %}
235
236 // Class for all long registers (excluding RAX, RDX and RSP)
237 reg_class long_no_rax_rdx_reg %{
238 return _LONG_NO_RAX_RDX_REG_mask;
239 %}
240
241 // Class for all long registers (excluding RCX and RSP)
242 reg_class long_no_rcx_reg %{
243 return _LONG_NO_RCX_REG_mask;
244 %}
245
246 // Class for all int registers (excluding RSP)
247 reg_class int_reg %{
248 return _INT_REG_mask;
249 %}
250
251 // Class for all int registers (excluding RAX, RDX, and RSP)
252 reg_class int_no_rax_rdx_reg %{
253 return _INT_NO_RAX_RDX_REG_mask;
254 %}
255
256 // Class for all int registers (excluding RCX and RSP)
257 reg_class int_no_rcx_reg %{
258 return _INT_NO_RCX_REG_mask;
259 %}
260
261 // Singleton class for RAX pointer register
262 reg_class ptr_rax_reg(RAX, RAX_H);
263
264 // Singleton class for RBX pointer register
265 reg_class ptr_rbx_reg(RBX, RBX_H);
266
267 // Singleton class for RSI pointer register
268 reg_class ptr_rsi_reg(RSI, RSI_H);
269
270 // Singleton class for RBP pointer register
271 reg_class ptr_rbp_reg(RBP, RBP_H);
272
273 // Singleton class for RDI pointer register
274 reg_class ptr_rdi_reg(RDI, RDI_H);
275
276 // Singleton class for stack pointer
277 reg_class ptr_rsp_reg(RSP, RSP_H);
278
279 // Singleton class for TLS pointer
280 reg_class ptr_r15_reg(R15, R15_H);
281
282 // Singleton class for RAX long register
283 reg_class long_rax_reg(RAX, RAX_H);
284
285 // Singleton class for RCX long register
286 reg_class long_rcx_reg(RCX, RCX_H);
287
288 // Singleton class for RDX long register
289 reg_class long_rdx_reg(RDX, RDX_H);
290
291 // Singleton class for RAX int register
292 reg_class int_rax_reg(RAX);
293
294 // Singleton class for RBX int register
295 reg_class int_rbx_reg(RBX);
296
297 // Singleton class for RCX int register
298 reg_class int_rcx_reg(RCX);
299
300 // Singleton class for RCX int register
301 reg_class int_rdx_reg(RDX);
302
303 // Singleton class for RCX int register
304 reg_class int_rdi_reg(RDI);
305
306 // Singleton class for instruction pointer
307 // reg_class ip_reg(RIP);
308
309 %}
310
311 //----------SOURCE BLOCK-------------------------------------------------------
312 // This is a block of C++ code which provides values, functions, and
313 // definitions necessary in the rest of the architecture description
314 source_hpp %{
315
316 extern RegMask _ANY_REG_mask;
317 extern RegMask _PTR_REG_mask;
318 extern RegMask _PTR_REG_NO_RBP_mask;
319 extern RegMask _PTR_NO_RAX_REG_mask;
320 extern RegMask _PTR_NO_RAX_RBX_REG_mask;
321 extern RegMask _LONG_REG_mask;
322 extern RegMask _LONG_NO_RAX_RDX_REG_mask;
323 extern RegMask _LONG_NO_RCX_REG_mask;
324 extern RegMask _INT_REG_mask;
325 extern RegMask _INT_NO_RAX_RDX_REG_mask;
326 extern RegMask _INT_NO_RCX_REG_mask;
327
328 extern RegMask _STACK_OR_PTR_REG_mask;
329 extern RegMask _STACK_OR_LONG_REG_mask;
330 extern RegMask _STACK_OR_INT_REG_mask;
331
332 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; }
333 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; }
334 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; }
335
336 %}
337
338 source %{
339 #define RELOC_IMM64 Assembler::imm_operand
340 #define RELOC_DISP32 Assembler::disp32_operand
341
342 #define __ _masm.
343
344 RegMask _ANY_REG_mask;
345 RegMask _PTR_REG_mask;
346 RegMask _PTR_REG_NO_RBP_mask;
347 RegMask _PTR_NO_RAX_REG_mask;
348 RegMask _PTR_NO_RAX_RBX_REG_mask;
349 RegMask _LONG_REG_mask;
350 RegMask _LONG_NO_RAX_RDX_REG_mask;
351 RegMask _LONG_NO_RCX_REG_mask;
352 RegMask _INT_REG_mask;
353 RegMask _INT_NO_RAX_RDX_REG_mask;
354 RegMask _INT_NO_RCX_REG_mask;
355 RegMask _STACK_OR_PTR_REG_mask;
356 RegMask _STACK_OR_LONG_REG_mask;
357 RegMask _STACK_OR_INT_REG_mask;
358
359 static bool need_r12_heapbase() {
360 return UseCompressedOops;
361 }
362
363 void reg_mask_init() {
364 // _ALL_REG_mask is generated by adlc from the all_reg register class below.
365 // We derive a number of subsets from it.
366 _ANY_REG_mask = _ALL_REG_mask;
367
368 if (PreserveFramePointer) {
369 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()));
370 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next()));
371 }
372 if (need_r12_heapbase()) {
373 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()));
374 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next()));
375 }
376
377 _PTR_REG_mask = _ANY_REG_mask;
378 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()));
379 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next()));
380 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()));
381 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next()));
382
383 _STACK_OR_PTR_REG_mask = _PTR_REG_mask;
384 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask());
385
386 _PTR_REG_NO_RBP_mask = _PTR_REG_mask;
387 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()));
388 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next()));
389
390 _PTR_NO_RAX_REG_mask = _PTR_REG_mask;
391 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()));
392 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next()));
393
394 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask;
395 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()));
396 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next()));
397
398 _LONG_REG_mask = _PTR_REG_mask;
399 _STACK_OR_LONG_REG_mask = _LONG_REG_mask;
400 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask());
401
402 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask;
403 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()));
404 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next()));
405 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()));
406 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next()));
407
408 _LONG_NO_RCX_REG_mask = _LONG_REG_mask;
409 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()));
410 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next()));
411
412 _INT_REG_mask = _ALL_INT_REG_mask;
413 if (PreserveFramePointer) {
414 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()));
415 }
416 if (need_r12_heapbase()) {
417 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()));
418 }
419
420 _STACK_OR_INT_REG_mask = _INT_REG_mask;
421 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask());
422
423 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask;
424 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()));
425 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()));
426
427 _INT_NO_RCX_REG_mask = _INT_REG_mask;
428 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()));
429 }
430
431 static bool generate_vzeroupper(Compile* C) {
432 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper
433 }
434
435 static int clear_avx_size() {
436 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper
437 }
438
439 // !!!!! Special hack to get all types of calls to specify the byte offset
440 // from the start of the call to the point where the return address
441 // will point.
442 int MachCallStaticJavaNode::ret_addr_offset()
443 {
444 int offset = 5; // 5 bytes from start of call to where return address points
445 offset += clear_avx_size();
446 return offset;
447 }
448
449 int MachCallDynamicJavaNode::ret_addr_offset()
450 {
451 int offset = 15; // 15 bytes from start of call to where return address points
452 offset += clear_avx_size();
453 return offset;
454 }
455
456 int MachCallRuntimeNode::ret_addr_offset() {
457 int offset = 13; // movq r10,#addr; callq (r10)
458 offset += clear_avx_size();
459 return offset;
460 }
461
462 //
463 // Compute padding required for nodes which need alignment
464 //
465
466 // The address of the call instruction needs to be 4-byte aligned to
467 // ensure that it does not span a cache line so that it can be patched.
468 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
469 {
470 current_offset += clear_avx_size(); // skip vzeroupper
471 current_offset += 1; // skip call opcode byte
472 return align_up(current_offset, alignment_required()) - current_offset;
473 }
474
475 // The address of the call instruction needs to be 4-byte aligned to
476 // ensure that it does not span a cache line so that it can be patched.
477 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
478 {
479 current_offset += clear_avx_size(); // skip vzeroupper
480 current_offset += 11; // skip movq instruction + call opcode byte
481 return align_up(current_offset, alignment_required()) - current_offset;
482 }
483
484 // EMIT_RM()
485 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
486 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
487 cbuf.insts()->emit_int8(c);
488 }
489
490 // EMIT_CC()
491 void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
492 unsigned char c = (unsigned char) (f1 | f2);
493 cbuf.insts()->emit_int8(c);
494 }
495
496 // EMIT_OPCODE()
497 void emit_opcode(CodeBuffer &cbuf, int code) {
498 cbuf.insts()->emit_int8((unsigned char) code);
499 }
500
501 // EMIT_OPCODE() w/ relocation information
502 void emit_opcode(CodeBuffer &cbuf,
503 int code, relocInfo::relocType reloc, int offset, int format)
504 {
505 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format);
506 emit_opcode(cbuf, code);
507 }
508
509 // EMIT_D8()
510 void emit_d8(CodeBuffer &cbuf, int d8) {
511 cbuf.insts()->emit_int8((unsigned char) d8);
512 }
513
514 // EMIT_D16()
515 void emit_d16(CodeBuffer &cbuf, int d16) {
516 cbuf.insts()->emit_int16(d16);
517 }
518
519 // EMIT_D32()
520 void emit_d32(CodeBuffer &cbuf, int d32) {
521 cbuf.insts()->emit_int32(d32);
522 }
523
524 // EMIT_D64()
525 void emit_d64(CodeBuffer &cbuf, int64_t d64) {
526 cbuf.insts()->emit_int64(d64);
527 }
528
529 // emit 32 bit value and construct relocation entry from relocInfo::relocType
530 void emit_d32_reloc(CodeBuffer& cbuf,
531 int d32,
532 relocInfo::relocType reloc,
533 int format)
534 {
535 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
536 cbuf.relocate(cbuf.insts_mark(), reloc, format);
537 cbuf.insts()->emit_int32(d32);
538 }
539
540 // emit 32 bit value and construct relocation entry from RelocationHolder
541 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) {
542 #ifdef ASSERT
543 if (rspec.reloc()->type() == relocInfo::oop_type &&
544 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
545 assert(Universe::heap()->is_in((address)(intptr_t)d32), "should be real oop");
546 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)), "cannot embed broken oops in code");
547 }
548 #endif
549 cbuf.relocate(cbuf.insts_mark(), rspec, format);
550 cbuf.insts()->emit_int32(d32);
551 }
552
553 void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
554 address next_ip = cbuf.insts_end() + 4;
555 emit_d32_reloc(cbuf, (int) (addr - next_ip),
556 external_word_Relocation::spec(addr),
557 RELOC_DISP32);
558 }
559
560
561 // emit 64 bit value and construct relocation entry from relocInfo::relocType
562 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) {
563 cbuf.relocate(cbuf.insts_mark(), reloc, format);
564 cbuf.insts()->emit_int64(d64);
565 }
566
567 // emit 64 bit value and construct relocation entry from RelocationHolder
568 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) {
569 #ifdef ASSERT
570 if (rspec.reloc()->type() == relocInfo::oop_type &&
571 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
572 assert(Universe::heap()->is_in((address)d64), "should be real oop");
573 assert(oopDesc::is_oop(cast_to_oop(d64)), "cannot embed broken oops in code");
574 }
575 #endif
576 cbuf.relocate(cbuf.insts_mark(), rspec, format);
577 cbuf.insts()->emit_int64(d64);
578 }
579
580 // Access stack slot for load or store
581 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp)
582 {
583 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src])
584 if (-0x80 <= disp && disp < 0x80) {
585 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte
586 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
587 emit_d8(cbuf, disp); // Displacement // R/M byte
588 } else {
589 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte
590 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
591 emit_d32(cbuf, disp); // Displacement // R/M byte
592 }
593 }
594
595 // rRegI ereg, memory mem) %{ // emit_reg_mem
596 void encode_RegMem(CodeBuffer &cbuf,
597 int reg,
598 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc)
599 {
600 assert(disp_reloc == relocInfo::none, "cannot have disp");
601 int regenc = reg & 7;
602 int baseenc = base & 7;
603 int indexenc = index & 7;
604
605 // There is no index & no scale, use form without SIB byte
606 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) {
607 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
608 if (disp == 0 && base != RBP_enc && base != R13_enc) {
609 emit_rm(cbuf, 0x0, regenc, baseenc); // *
610 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
611 // If 8-bit displacement, mode 0x1
612 emit_rm(cbuf, 0x1, regenc, baseenc); // *
613 emit_d8(cbuf, disp);
614 } else {
615 // If 32-bit displacement
616 if (base == -1) { // Special flag for absolute address
617 emit_rm(cbuf, 0x0, regenc, 0x5); // *
618 if (disp_reloc != relocInfo::none) {
619 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
620 } else {
621 emit_d32(cbuf, disp);
622 }
623 } else {
624 // Normal base + offset
625 emit_rm(cbuf, 0x2, regenc, baseenc); // *
626 if (disp_reloc != relocInfo::none) {
627 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
628 } else {
629 emit_d32(cbuf, disp);
630 }
631 }
632 }
633 } else {
634 // Else, encode with the SIB byte
635 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
636 if (disp == 0 && base != RBP_enc && base != R13_enc) {
637 // If no displacement
638 emit_rm(cbuf, 0x0, regenc, 0x4); // *
639 emit_rm(cbuf, scale, indexenc, baseenc);
640 } else {
641 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
642 // If 8-bit displacement, mode 0x1
643 emit_rm(cbuf, 0x1, regenc, 0x4); // *
644 emit_rm(cbuf, scale, indexenc, baseenc);
645 emit_d8(cbuf, disp);
646 } else {
647 // If 32-bit displacement
648 if (base == 0x04 ) {
649 emit_rm(cbuf, 0x2, regenc, 0x4);
650 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
651 } else {
652 emit_rm(cbuf, 0x2, regenc, 0x4);
653 emit_rm(cbuf, scale, indexenc, baseenc); // *
654 }
655 if (disp_reloc != relocInfo::none) {
656 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
657 } else {
658 emit_d32(cbuf, disp);
659 }
660 }
661 }
662 }
663 }
664
665 // This could be in MacroAssembler but it's fairly C2 specific
666 void emit_cmpfp_fixup(MacroAssembler& _masm) {
667 Label exit;
668 __ jccb(Assembler::noParity, exit);
669 __ pushf();
670 //
671 // comiss/ucomiss instructions set ZF,PF,CF flags and
672 // zero OF,AF,SF for NaN values.
673 // Fixup flags by zeroing ZF,PF so that compare of NaN
674 // values returns 'less than' result (CF is set).
675 // Leave the rest of flags unchanged.
676 //
677 // 7 6 5 4 3 2 1 0
678 // |S|Z|r|A|r|P|r|C| (r - reserved bit)
679 // 0 0 1 0 1 0 1 1 (0x2B)
680 //
681 __ andq(Address(rsp, 0), 0xffffff2b);
682 __ popf();
683 __ bind(exit);
684 }
685
686 void emit_cmpfp3(MacroAssembler& _masm, Register dst) {
687 Label done;
688 __ movl(dst, -1);
689 __ jcc(Assembler::parity, done);
690 __ jcc(Assembler::below, done);
691 __ setb(Assembler::notEqual, dst);
692 __ movzbl(dst, dst);
693 __ bind(done);
694 }
695
696 // Math.min() # Math.max()
697 // --------------------------
698 // ucomis[s/d] #
699 // ja -> b # a
700 // jp -> NaN # NaN
701 // jb -> a # b
702 // je #
703 // |-jz -> a | b # a & b
704 // | -> a #
705 void emit_fp_min_max(MacroAssembler& _masm, XMMRegister dst,
706 XMMRegister a, XMMRegister b,
707 XMMRegister xmmt, Register rt,
708 bool min, bool single) {
709
710 Label nan, zero, below, above, done;
711
712 if (single)
713 __ ucomiss(a, b);
714 else
715 __ ucomisd(a, b);
716
717 if (dst->encoding() != (min ? b : a)->encoding())
718 __ jccb(Assembler::above, above); // CF=0 & ZF=0
719 else
720 __ jccb(Assembler::above, done);
721
722 __ jccb(Assembler::parity, nan); // PF=1
723 __ jccb(Assembler::below, below); // CF=1
724
725 // equal
726 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit);
727 if (single) {
728 __ ucomiss(a, xmmt);
729 __ jccb(Assembler::equal, zero);
730
731 __ movflt(dst, a);
732 __ jmp(done);
733 }
734 else {
735 __ ucomisd(a, xmmt);
736 __ jccb(Assembler::equal, zero);
737
738 __ movdbl(dst, a);
739 __ jmp(done);
740 }
741
742 __ bind(zero);
743 if (min)
744 __ vpor(dst, a, b, Assembler::AVX_128bit);
745 else
746 __ vpand(dst, a, b, Assembler::AVX_128bit);
747
748 __ jmp(done);
749
750 __ bind(above);
751 if (single)
752 __ movflt(dst, min ? b : a);
753 else
754 __ movdbl(dst, min ? b : a);
755
756 __ jmp(done);
757
758 __ bind(nan);
759 if (single) {
760 __ movl(rt, 0x7fc00000); // Float.NaN
761 __ movdl(dst, rt);
762 }
763 else {
764 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN
765 __ movdq(dst, rt);
766 }
767 __ jmp(done);
768
769 __ bind(below);
770 if (single)
771 __ movflt(dst, min ? a : b);
772 else
773 __ movdbl(dst, min ? a : b);
774
775 __ bind(done);
776 }
777
778 //=============================================================================
779 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
780
781 int ConstantTable::calculate_table_base_offset() const {
782 return 0; // absolute addressing, no offset
783 }
784
785 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
786 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
787 ShouldNotReachHere();
788 }
789
790 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
791 // Empty encoding
792 }
793
794 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
795 return 0;
796 }
797
798 #ifndef PRODUCT
799 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
800 st->print("# MachConstantBaseNode (empty encoding)");
801 }
802 #endif
803
804
805 //=============================================================================
806 #ifndef PRODUCT
807 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
808 Compile* C = ra_->C;
809
810 int framesize = C->output()->frame_size_in_bytes();
811 int bangsize = C->output()->bang_size_in_bytes();
812 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
813 // Remove wordSize for return addr which is already pushed.
814 framesize -= wordSize;
815
816 if (C->output()->need_stack_bang(bangsize)) {
817 framesize -= wordSize;
818 st->print("# stack bang (%d bytes)", bangsize);
819 st->print("\n\t");
820 st->print("pushq rbp\t# Save rbp");
821 if (PreserveFramePointer) {
822 st->print("\n\t");
823 st->print("movq rbp, rsp\t# Save the caller's SP into rbp");
824 }
825 if (framesize) {
826 st->print("\n\t");
827 st->print("subq rsp, #%d\t# Create frame",framesize);
828 }
829 } else {
830 st->print("subq rsp, #%d\t# Create frame",framesize);
831 st->print("\n\t");
832 framesize -= wordSize;
833 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
834 if (PreserveFramePointer) {
835 st->print("\n\t");
836 st->print("movq rbp, rsp\t# Save the caller's SP into rbp");
837 if (framesize > 0) {
838 st->print("\n\t");
839 st->print("addq rbp, #%d", framesize);
840 }
841 }
842 }
843
844 if (VerifyStackAtCalls) {
845 st->print("\n\t");
846 framesize -= wordSize;
847 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize);
848 #ifdef ASSERT
849 st->print("\n\t");
850 st->print("# stack alignment check");
851 #endif
852 }
853 if (C->stub_function() != NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) {
854 st->print("\n\t");
855 st->print("cmpl [r15_thread + #disarmed_offset], #disarmed_value\t");
856 st->print("\n\t");
857 st->print("je fast_entry\t");
858 st->print("\n\t");
859 st->print("call #nmethod_entry_barrier_stub\t");
860 st->print("\n\tfast_entry:");
861 }
862 st->cr();
863 }
864 #endif
865
866 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
867 Compile* C = ra_->C;
868 MacroAssembler _masm(&cbuf);
869
870 if (C->clinit_barrier_on_entry()) {
871 assert(VM_Version::supports_fast_class_init_checks(), "sanity");
872 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
873
874 Label L_skip_barrier;
875 Register klass = rscratch1;
876
877 __ mov_metadata(klass, C->method()->holder()->constant_encoding());
878 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/);
879
880 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path
881
882 __ bind(L_skip_barrier);
883 }
884
885 __ verified_entry(C);
886 __ bind(*_verified_entry);
887
888 if (C->stub_function() == NULL) {
889 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
890 bs->nmethod_entry_barrier(&_masm);
891 }
892
893 C->output()->set_frame_complete(cbuf.insts_size());
894
895 if (C->has_mach_constant_base_node()) {
896 // NOTE: We set the table base offset here because users might be
897 // emitted before MachConstantBaseNode.
898 ConstantTable& constant_table = C->output()->constant_table();
899 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
900 }
901 }
902
903 int MachPrologNode::reloc() const
904 {
905 return 0; // a large enough number
906 }
907
908 //=============================================================================
909 #ifndef PRODUCT
910 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
911 {
912 Compile* C = ra_->C;
913 if (generate_vzeroupper(C)) {
914 st->print("vzeroupper");
915 st->cr(); st->print("\t");
916 }
917
918 int framesize = C->output()->frame_size_in_bytes();
919 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
920 // Remove word for return adr already pushed
921 // and RBP
922 framesize -= 2*wordSize;
923
924 if (framesize) {
925 st->print_cr("addq rsp, %d\t# Destroy frame", framesize);
926 st->print("\t");
927 }
928
929 st->print_cr("popq rbp");
930 if (do_polling() && C->is_method_compilation()) {
931 st->print("\t");
932 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t"
933 "testl rax, [rscratch1]\t"
934 "# Safepoint: poll for GC");
935 }
936 }
937 #endif
938
939 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
940 {
941 Compile* C = ra_->C;
942 MacroAssembler _masm(&cbuf);
943
944 if (generate_vzeroupper(C)) {
945 // Clear upper bits of YMM registers when current compiled code uses
946 // wide vectors to avoid AVX <-> SSE transition penalty during call.
947 __ vzeroupper();
948 }
949
950 // Subtract two words to account for return address and rbp
951 int initial_framesize = C->output()->frame_size_in_bytes() - 2*wordSize;
952 __ remove_frame(initial_framesize, C->needs_stack_repair(), C->output()->sp_inc_offset());
953
954 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
955 __ reserved_stack_check();
956 }
957
958 if (do_polling() && C->is_method_compilation()) {
959 MacroAssembler _masm(&cbuf);
960 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset()));
961 __ relocate(relocInfo::poll_return_type);
962 __ testl(rax, Address(rscratch1, 0));
963 }
964 }
965
966 int MachEpilogNode::reloc() const
967 {
968 return 2; // a large enough number
969 }
970
971 const Pipeline* MachEpilogNode::pipeline() const
972 {
973 return MachNode::pipeline_class();
974 }
975
976 //=============================================================================
977
978 enum RC {
979 rc_bad,
980 rc_int,
981 rc_float,
982 rc_stack
983 };
984
985 static enum RC rc_class(OptoReg::Name reg)
986 {
987 if( !OptoReg::is_valid(reg) ) return rc_bad;
988
989 if (OptoReg::is_stack(reg)) return rc_stack;
990
991 VMReg r = OptoReg::as_VMReg(reg);
992
993 if (r->is_Register()) return rc_int;
994
995 assert(r->is_XMMRegister(), "must be");
996 return rc_float;
997 }
998
999 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad.
1000 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
1001 int src_hi, int dst_hi, uint ireg, outputStream* st);
1002
1003 int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
1004 int stack_offset, int reg, uint ireg, outputStream* st);
1005
1006 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
1007 int dst_offset, uint ireg, outputStream* st) {
1008 if (cbuf) {
1009 MacroAssembler _masm(cbuf);
1010 switch (ireg) {
1011 case Op_VecS:
1012 __ movq(Address(rsp, -8), rax);
1013 __ movl(rax, Address(rsp, src_offset));
1014 __ movl(Address(rsp, dst_offset), rax);
1015 __ movq(rax, Address(rsp, -8));
1016 break;
1017 case Op_VecD:
1018 __ pushq(Address(rsp, src_offset));
1019 __ popq (Address(rsp, dst_offset));
1020 break;
1021 case Op_VecX:
1022 __ pushq(Address(rsp, src_offset));
1023 __ popq (Address(rsp, dst_offset));
1024 __ pushq(Address(rsp, src_offset+8));
1025 __ popq (Address(rsp, dst_offset+8));
1026 break;
1027 case Op_VecY:
1028 __ vmovdqu(Address(rsp, -32), xmm0);
1029 __ vmovdqu(xmm0, Address(rsp, src_offset));
1030 __ vmovdqu(Address(rsp, dst_offset), xmm0);
1031 __ vmovdqu(xmm0, Address(rsp, -32));
1032 break;
1033 case Op_VecZ:
1034 __ evmovdquq(Address(rsp, -64), xmm0, 2);
1035 __ evmovdquq(xmm0, Address(rsp, src_offset), 2);
1036 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2);
1037 __ evmovdquq(xmm0, Address(rsp, -64), 2);
1038 break;
1039 default:
1040 ShouldNotReachHere();
1041 }
1042 #ifndef PRODUCT
1043 } else {
1044 switch (ireg) {
1045 case Op_VecS:
1046 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1047 "movl rax, [rsp + #%d]\n\t"
1048 "movl [rsp + #%d], rax\n\t"
1049 "movq rax, [rsp - #8]",
1050 src_offset, dst_offset);
1051 break;
1052 case Op_VecD:
1053 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1054 "popq [rsp + #%d]",
1055 src_offset, dst_offset);
1056 break;
1057 case Op_VecX:
1058 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t"
1059 "popq [rsp + #%d]\n\t"
1060 "pushq [rsp + #%d]\n\t"
1061 "popq [rsp + #%d]",
1062 src_offset, dst_offset, src_offset+8, dst_offset+8);
1063 break;
1064 case Op_VecY:
1065 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
1066 "vmovdqu xmm0, [rsp + #%d]\n\t"
1067 "vmovdqu [rsp + #%d], xmm0\n\t"
1068 "vmovdqu xmm0, [rsp - #32]",
1069 src_offset, dst_offset);
1070 break;
1071 case Op_VecZ:
1072 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t"
1073 "vmovdqu xmm0, [rsp + #%d]\n\t"
1074 "vmovdqu [rsp + #%d], xmm0\n\t"
1075 "vmovdqu xmm0, [rsp - #64]",
1076 src_offset, dst_offset);
1077 break;
1078 default:
1079 ShouldNotReachHere();
1080 }
1081 #endif
1082 }
1083 }
1084
1085 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
1086 PhaseRegAlloc* ra_,
1087 bool do_size,
1088 outputStream* st) const {
1089 assert(cbuf != NULL || st != NULL, "sanity");
1090 // Get registers to move
1091 OptoReg::Name src_second = ra_->get_reg_second(in(1));
1092 OptoReg::Name src_first = ra_->get_reg_first(in(1));
1093 OptoReg::Name dst_second = ra_->get_reg_second(this);
1094 OptoReg::Name dst_first = ra_->get_reg_first(this);
1095
1096 enum RC src_second_rc = rc_class(src_second);
1097 enum RC src_first_rc = rc_class(src_first);
1098 enum RC dst_second_rc = rc_class(dst_second);
1099 enum RC dst_first_rc = rc_class(dst_first);
1100
1101 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
1102 "must move at least 1 register" );
1103
1104 if (src_first == dst_first && src_second == dst_second) {
1105 // Self copy, no move
1106 return 0;
1107 }
1108 if (bottom_type()->isa_vect() != NULL) {
1109 uint ireg = ideal_reg();
1110 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
1111 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity");
1112 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
1113 // mem -> mem
1114 int src_offset = ra_->reg2offset(src_first);
1115 int dst_offset = ra_->reg2offset(dst_first);
1116 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st);
1117 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) {
1118 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st);
1119 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) {
1120 int stack_offset = ra_->reg2offset(dst_first);
1121 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st);
1122 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) {
1123 int stack_offset = ra_->reg2offset(src_first);
1124 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st);
1125 } else {
1126 ShouldNotReachHere();
1127 }
1128 return 0;
1129 }
1130 if (src_first_rc == rc_stack) {
1131 // mem ->
1132 if (dst_first_rc == rc_stack) {
1133 // mem -> mem
1134 assert(src_second != dst_first, "overlap");
1135 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1136 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1137 // 64-bit
1138 int src_offset = ra_->reg2offset(src_first);
1139 int dst_offset = ra_->reg2offset(dst_first);
1140 if (cbuf) {
1141 MacroAssembler _masm(cbuf);
1142 __ pushq(Address(rsp, src_offset));
1143 __ popq (Address(rsp, dst_offset));
1144 #ifndef PRODUCT
1145 } else {
1146 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1147 "popq [rsp + #%d]",
1148 src_offset, dst_offset);
1149 #endif
1150 }
1151 } else {
1152 // 32-bit
1153 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1154 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1155 // No pushl/popl, so:
1156 int src_offset = ra_->reg2offset(src_first);
1157 int dst_offset = ra_->reg2offset(dst_first);
1158 if (cbuf) {
1159 MacroAssembler _masm(cbuf);
1160 __ movq(Address(rsp, -8), rax);
1161 __ movl(rax, Address(rsp, src_offset));
1162 __ movl(Address(rsp, dst_offset), rax);
1163 __ movq(rax, Address(rsp, -8));
1164 #ifndef PRODUCT
1165 } else {
1166 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1167 "movl rax, [rsp + #%d]\n\t"
1168 "movl [rsp + #%d], rax\n\t"
1169 "movq rax, [rsp - #8]",
1170 src_offset, dst_offset);
1171 #endif
1172 }
1173 }
1174 return 0;
1175 } else if (dst_first_rc == rc_int) {
1176 // mem -> gpr
1177 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1178 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1179 // 64-bit
1180 int offset = ra_->reg2offset(src_first);
1181 if (cbuf) {
1182 MacroAssembler _masm(cbuf);
1183 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1184 #ifndef PRODUCT
1185 } else {
1186 st->print("movq %s, [rsp + #%d]\t# spill",
1187 Matcher::regName[dst_first],
1188 offset);
1189 #endif
1190 }
1191 } else {
1192 // 32-bit
1193 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1194 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1195 int offset = ra_->reg2offset(src_first);
1196 if (cbuf) {
1197 MacroAssembler _masm(cbuf);
1198 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1199 #ifndef PRODUCT
1200 } else {
1201 st->print("movl %s, [rsp + #%d]\t# spill",
1202 Matcher::regName[dst_first],
1203 offset);
1204 #endif
1205 }
1206 }
1207 return 0;
1208 } else if (dst_first_rc == rc_float) {
1209 // mem-> xmm
1210 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1211 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1212 // 64-bit
1213 int offset = ra_->reg2offset(src_first);
1214 if (cbuf) {
1215 MacroAssembler _masm(cbuf);
1216 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1217 #ifndef PRODUCT
1218 } else {
1219 st->print("%s %s, [rsp + #%d]\t# spill",
1220 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1221 Matcher::regName[dst_first],
1222 offset);
1223 #endif
1224 }
1225 } else {
1226 // 32-bit
1227 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1228 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1229 int offset = ra_->reg2offset(src_first);
1230 if (cbuf) {
1231 MacroAssembler _masm(cbuf);
1232 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1233 #ifndef PRODUCT
1234 } else {
1235 st->print("movss %s, [rsp + #%d]\t# spill",
1236 Matcher::regName[dst_first],
1237 offset);
1238 #endif
1239 }
1240 }
1241 return 0;
1242 }
1243 } else if (src_first_rc == rc_int) {
1244 // gpr ->
1245 if (dst_first_rc == rc_stack) {
1246 // gpr -> mem
1247 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1248 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1249 // 64-bit
1250 int offset = ra_->reg2offset(dst_first);
1251 if (cbuf) {
1252 MacroAssembler _masm(cbuf);
1253 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
1254 #ifndef PRODUCT
1255 } else {
1256 st->print("movq [rsp + #%d], %s\t# spill",
1257 offset,
1258 Matcher::regName[src_first]);
1259 #endif
1260 }
1261 } else {
1262 // 32-bit
1263 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1264 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1265 int offset = ra_->reg2offset(dst_first);
1266 if (cbuf) {
1267 MacroAssembler _masm(cbuf);
1268 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
1269 #ifndef PRODUCT
1270 } else {
1271 st->print("movl [rsp + #%d], %s\t# spill",
1272 offset,
1273 Matcher::regName[src_first]);
1274 #endif
1275 }
1276 }
1277 return 0;
1278 } else if (dst_first_rc == rc_int) {
1279 // gpr -> gpr
1280 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1281 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1282 // 64-bit
1283 if (cbuf) {
1284 MacroAssembler _masm(cbuf);
1285 __ movq(as_Register(Matcher::_regEncode[dst_first]),
1286 as_Register(Matcher::_regEncode[src_first]));
1287 #ifndef PRODUCT
1288 } else {
1289 st->print("movq %s, %s\t# spill",
1290 Matcher::regName[dst_first],
1291 Matcher::regName[src_first]);
1292 #endif
1293 }
1294 return 0;
1295 } else {
1296 // 32-bit
1297 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1298 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1299 if (cbuf) {
1300 MacroAssembler _masm(cbuf);
1301 __ movl(as_Register(Matcher::_regEncode[dst_first]),
1302 as_Register(Matcher::_regEncode[src_first]));
1303 #ifndef PRODUCT
1304 } else {
1305 st->print("movl %s, %s\t# spill",
1306 Matcher::regName[dst_first],
1307 Matcher::regName[src_first]);
1308 #endif
1309 }
1310 return 0;
1311 }
1312 } else if (dst_first_rc == rc_float) {
1313 // gpr -> xmm
1314 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1315 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1316 // 64-bit
1317 if (cbuf) {
1318 MacroAssembler _masm(cbuf);
1319 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1320 #ifndef PRODUCT
1321 } else {
1322 st->print("movdq %s, %s\t# spill",
1323 Matcher::regName[dst_first],
1324 Matcher::regName[src_first]);
1325 #endif
1326 }
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 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1334 #ifndef PRODUCT
1335 } else {
1336 st->print("movdl %s, %s\t# spill",
1337 Matcher::regName[dst_first],
1338 Matcher::regName[src_first]);
1339 #endif
1340 }
1341 }
1342 return 0;
1343 }
1344 } else if (src_first_rc == rc_float) {
1345 // xmm ->
1346 if (dst_first_rc == rc_stack) {
1347 // xmm -> mem
1348 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1349 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1350 // 64-bit
1351 int offset = ra_->reg2offset(dst_first);
1352 if (cbuf) {
1353 MacroAssembler _masm(cbuf);
1354 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1355 #ifndef PRODUCT
1356 } else {
1357 st->print("movsd [rsp + #%d], %s\t# spill",
1358 offset,
1359 Matcher::regName[src_first]);
1360 #endif
1361 }
1362 } else {
1363 // 32-bit
1364 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1365 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1366 int offset = ra_->reg2offset(dst_first);
1367 if (cbuf) {
1368 MacroAssembler _masm(cbuf);
1369 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1370 #ifndef PRODUCT
1371 } else {
1372 st->print("movss [rsp + #%d], %s\t# spill",
1373 offset,
1374 Matcher::regName[src_first]);
1375 #endif
1376 }
1377 }
1378 return 0;
1379 } else if (dst_first_rc == rc_int) {
1380 // xmm -> gpr
1381 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1382 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1383 // 64-bit
1384 if (cbuf) {
1385 MacroAssembler _masm(cbuf);
1386 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1387 #ifndef PRODUCT
1388 } else {
1389 st->print("movdq %s, %s\t# spill",
1390 Matcher::regName[dst_first],
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 if (cbuf) {
1399 MacroAssembler _masm(cbuf);
1400 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1401 #ifndef PRODUCT
1402 } else {
1403 st->print("movdl %s, %s\t# spill",
1404 Matcher::regName[dst_first],
1405 Matcher::regName[src_first]);
1406 #endif
1407 }
1408 }
1409 return 0;
1410 } else if (dst_first_rc == rc_float) {
1411 // xmm -> xmm
1412 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1413 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1414 // 64-bit
1415 if (cbuf) {
1416 MacroAssembler _masm(cbuf);
1417 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1418 #ifndef PRODUCT
1419 } else {
1420 st->print("%s %s, %s\t# spill",
1421 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
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 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1433 #ifndef PRODUCT
1434 } else {
1435 st->print("%s %s, %s\t# spill",
1436 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1437 Matcher::regName[dst_first],
1438 Matcher::regName[src_first]);
1439 #endif
1440 }
1441 }
1442 return 0;
1443 }
1444 }
1445
1446 assert(0," foo ");
1447 Unimplemented();
1448 return 0;
1449 }
1450
1451 #ifndef PRODUCT
1452 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const {
1453 implementation(NULL, ra_, false, st);
1454 }
1455 #endif
1456
1457 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1458 implementation(&cbuf, ra_, false, NULL);
1459 }
1460
1461 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1462 return MachNode::size(ra_);
1463 }
1464
1465 //=============================================================================
1466 #ifndef PRODUCT
1467 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1468 {
1469 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1470 int reg = ra_->get_reg_first(this);
1471 st->print("leaq %s, [rsp + #%d]\t# box lock",
1472 Matcher::regName[reg], offset);
1473 }
1474 #endif
1475
1476 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1477 {
1478 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1479 int reg = ra_->get_encode(this);
1480 if (offset >= 0x80) {
1481 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1482 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1483 emit_rm(cbuf, 0x2, reg & 7, 0x04);
1484 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1485 emit_d32(cbuf, offset);
1486 } else {
1487 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1488 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1489 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1490 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1491 emit_d8(cbuf, offset);
1492 }
1493 }
1494
1495 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1496 {
1497 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1498 return (offset < 0x80) ? 5 : 8; // REX
1499 }
1500
1501 //=============================================================================
1502 #ifndef PRODUCT
1503 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1504 {
1505 st->print_cr("MachVEPNode");
1506 }
1507 #endif
1508
1509 void MachVEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1510 {
1511 MacroAssembler masm(&cbuf);
1512 if (!_verified) {
1513 uint insts_size = cbuf.insts_size();
1514 if (UseCompressedClassPointers) {
1515 masm.load_klass(rscratch1, j_rarg0, rscratch2);
1516 masm.cmpptr(rax, rscratch1);
1517 } else {
1518 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1519 }
1520 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1521 } else {
1522 // Unpack inline type args passed as oop and then jump to
1523 // the verified entry point (skipping the unverified entry).
1524 masm.unpack_inline_args(ra_->C, _receiver_only);
1525 masm.jmp(*_verified_entry);
1526 }
1527 }
1528
1529 //=============================================================================
1530 #ifndef PRODUCT
1531 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1532 {
1533 if (UseCompressedClassPointers) {
1534 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1535 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1536 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1537 } else {
1538 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1539 "# Inline cache check");
1540 }
1541 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1542 st->print_cr("\tnop\t# nops to align entry point");
1543 }
1544 #endif
1545
1546 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1547 {
1548 MacroAssembler masm(&cbuf);
1549 uint insts_size = cbuf.insts_size();
1550 if (UseCompressedClassPointers) {
1551 masm.load_klass(rscratch1, j_rarg0, rscratch2);
1552 masm.cmpptr(rax, rscratch1);
1553 } else {
1554 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1555 }
1556
1557 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1558
1559 /* WARNING these NOPs are critical so that verified entry point is properly
1560 4 bytes aligned for patching by NativeJump::patch_verified_entry() */
1561 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
1562 if (OptoBreakpoint) {
1563 // Leave space for int3
1564 nops_cnt -= 1;
1565 }
1566 nops_cnt &= 0x3; // Do not add nops if code is aligned.
1567 if (nops_cnt > 0)
1568 masm.nop(nops_cnt);
1569 }
1570
1571 //=============================================================================
1572
1573 int Matcher::regnum_to_fpu_offset(int regnum)
1574 {
1575 return regnum - 32; // The FP registers are in the second chunk
1576 }
1577
1578 // This is UltraSparc specific, true just means we have fast l2f conversion
1579 const bool Matcher::convL2FSupported(void) {
1580 return true;
1581 }
1582
1583 // Is this branch offset short enough that a short branch can be used?
1584 //
1585 // NOTE: If the platform does not provide any short branch variants, then
1586 // this method should return false for offset 0.
1587 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1588 // The passed offset is relative to address of the branch.
1589 // On 86 a branch displacement is calculated relative to address
1590 // of a next instruction.
1591 offset -= br_size;
1592
1593 // the short version of jmpConUCF2 contains multiple branches,
1594 // making the reach slightly less
1595 if (rule == jmpConUCF2_rule)
1596 return (-126 <= offset && offset <= 125);
1597 return (-128 <= offset && offset <= 127);
1598 }
1599
1600 const bool Matcher::isSimpleConstant64(jlong value) {
1601 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1602 //return value == (int) value; // Cf. storeImmL and immL32.
1603
1604 // Probably always true, even if a temp register is required.
1605 return true;
1606 }
1607
1608 // The ecx parameter to rep stosq for the ClearArray node is in words.
1609 const bool Matcher::init_array_count_is_in_bytes = false;
1610
1611 // No additional cost for CMOVL.
1612 const int Matcher::long_cmove_cost() { return 0; }
1613
1614 // No CMOVF/CMOVD with SSE2
1615 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1616
1617 // Does the CPU require late expand (see block.cpp for description of late expand)?
1618 const bool Matcher::require_postalloc_expand = false;
1619
1620 // Do we need to mask the count passed to shift instructions or does
1621 // the cpu only look at the lower 5/6 bits anyway?
1622 const bool Matcher::need_masked_shift_count = false;
1623
1624 bool Matcher::narrow_oop_use_complex_address() {
1625 assert(UseCompressedOops, "only for compressed oops code");
1626 return (LogMinObjAlignmentInBytes <= 3);
1627 }
1628
1629 bool Matcher::narrow_klass_use_complex_address() {
1630 assert(UseCompressedClassPointers, "only for compressed klass code");
1631 return (LogKlassAlignmentInBytes <= 3);
1632 }
1633
1634 bool Matcher::const_oop_prefer_decode() {
1635 // Prefer ConN+DecodeN over ConP.
1636 return true;
1637 }
1638
1639 bool Matcher::const_klass_prefer_decode() {
1640 // Prefer ConP over ConNKlass+DecodeNKlass.
1641 return true;
1642 }
1643
1644 // Is it better to copy float constants, or load them directly from
1645 // memory? Intel can load a float constant from a direct address,
1646 // requiring no extra registers. Most RISCs will have to materialize
1647 // an address into a register first, so they would do better to copy
1648 // the constant from stack.
1649 const bool Matcher::rematerialize_float_constants = true; // XXX
1650
1651 // If CPU can load and store mis-aligned doubles directly then no
1652 // fixup is needed. Else we split the double into 2 integer pieces
1653 // and move it piece-by-piece. Only happens when passing doubles into
1654 // C code as the Java calling convention forces doubles to be aligned.
1655 const bool Matcher::misaligned_doubles_ok = true;
1656
1657 // No-op on amd64
1658 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {}
1659
1660 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode.
1661 const bool Matcher::strict_fp_requires_explicit_rounding = false;
1662
1663 // Are floats conerted to double when stored to stack during deoptimization?
1664 // On x64 it is stored without convertion so we can use normal access.
1665 bool Matcher::float_in_double() { return false; }
1666
1667 // Do ints take an entire long register or just half?
1668 const bool Matcher::int_in_long = true;
1669
1670 // Return whether or not this register is ever used as an argument.
1671 // This function is used on startup to build the trampoline stubs in
1672 // generateOptoStub. Registers not mentioned will be killed by the VM
1673 // call in the trampoline, and arguments in those registers not be
1674 // available to the callee.
1675 bool Matcher::can_be_java_arg(int reg)
1676 {
1677 return
1678 reg == RDI_num || reg == RDI_H_num ||
1679 reg == RSI_num || reg == RSI_H_num ||
1680 reg == RDX_num || reg == RDX_H_num ||
1681 reg == RCX_num || reg == RCX_H_num ||
1682 reg == R8_num || reg == R8_H_num ||
1683 reg == R9_num || reg == R9_H_num ||
1684 reg == R12_num || reg == R12_H_num ||
1685 reg == XMM0_num || reg == XMM0b_num ||
1686 reg == XMM1_num || reg == XMM1b_num ||
1687 reg == XMM2_num || reg == XMM2b_num ||
1688 reg == XMM3_num || reg == XMM3b_num ||
1689 reg == XMM4_num || reg == XMM4b_num ||
1690 reg == XMM5_num || reg == XMM5b_num ||
1691 reg == XMM6_num || reg == XMM6b_num ||
1692 reg == XMM7_num || reg == XMM7b_num;
1693 }
1694
1695 bool Matcher::is_spillable_arg(int reg)
1696 {
1697 return can_be_java_arg(reg);
1698 }
1699
1700 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1701 // In 64 bit mode a code which use multiply when
1702 // devisor is constant is faster than hardware
1703 // DIV instruction (it uses MulHiL).
1704 return false;
1705 }
1706
1707 // Register for DIVI projection of divmodI
1708 RegMask Matcher::divI_proj_mask() {
1709 return INT_RAX_REG_mask();
1710 }
1711
1712 // Register for MODI projection of divmodI
1713 RegMask Matcher::modI_proj_mask() {
1714 return INT_RDX_REG_mask();
1715 }
1716
1717 // Register for DIVL projection of divmodL
1718 RegMask Matcher::divL_proj_mask() {
1719 return LONG_RAX_REG_mask();
1720 }
1721
1722 // Register for MODL projection of divmodL
1723 RegMask Matcher::modL_proj_mask() {
1724 return LONG_RDX_REG_mask();
1725 }
1726
1727 // Register for saving SP into on method handle invokes. Not used on x86_64.
1728 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1729 return NO_REG_mask();
1730 }
1731
1732 %}
1733
1734 //----------ENCODING BLOCK-----------------------------------------------------
1735 // This block specifies the encoding classes used by the compiler to
1736 // output byte streams. Encoding classes are parameterized macros
1737 // used by Machine Instruction Nodes in order to generate the bit
1738 // encoding of the instruction. Operands specify their base encoding
1739 // interface with the interface keyword. There are currently
1740 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
1741 // COND_INTER. REG_INTER causes an operand to generate a function
1742 // which returns its register number when queried. CONST_INTER causes
1743 // an operand to generate a function which returns the value of the
1744 // constant when queried. MEMORY_INTER causes an operand to generate
1745 // four functions which return the Base Register, the Index Register,
1746 // the Scale Value, and the Offset Value of the operand when queried.
1747 // COND_INTER causes an operand to generate six functions which return
1748 // the encoding code (ie - encoding bits for the instruction)
1749 // associated with each basic boolean condition for a conditional
1750 // instruction.
1751 //
1752 // Instructions specify two basic values for encoding. Again, a
1753 // function is available to check if the constant displacement is an
1754 // oop. They use the ins_encode keyword to specify their encoding
1755 // classes (which must be a sequence of enc_class names, and their
1756 // parameters, specified in the encoding block), and they use the
1757 // opcode keyword to specify, in order, their primary, secondary, and
1758 // tertiary opcode. Only the opcode sections which a particular
1759 // instruction needs for encoding need to be specified.
1760 encode %{
1761 // Build emit functions for each basic byte or larger field in the
1762 // intel encoding scheme (opcode, rm, sib, immediate), and call them
1763 // from C++ code in the enc_class source block. Emit functions will
1764 // live in the main source block for now. In future, we can
1765 // generalize this by adding a syntax that specifies the sizes of
1766 // fields in an order, so that the adlc can build the emit functions
1767 // automagically
1768
1769 // Emit primary opcode
1770 enc_class OpcP
1771 %{
1772 emit_opcode(cbuf, $primary);
1773 %}
1774
1775 // Emit secondary opcode
1776 enc_class OpcS
1777 %{
1778 emit_opcode(cbuf, $secondary);
1779 %}
1780
1781 // Emit tertiary opcode
1782 enc_class OpcT
1783 %{
1784 emit_opcode(cbuf, $tertiary);
1785 %}
1786
1787 // Emit opcode directly
1788 enc_class Opcode(immI d8)
1789 %{
1790 emit_opcode(cbuf, $d8$$constant);
1791 %}
1792
1793 // Emit size prefix
1794 enc_class SizePrefix
1795 %{
1796 emit_opcode(cbuf, 0x66);
1797 %}
1798
1799 enc_class reg(rRegI reg)
1800 %{
1801 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
1802 %}
1803
1804 enc_class reg_reg(rRegI dst, rRegI src)
1805 %{
1806 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1807 %}
1808
1809 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
1810 %{
1811 emit_opcode(cbuf, $opcode$$constant);
1812 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1813 %}
1814
1815 enc_class cdql_enc(no_rax_rdx_RegI div)
1816 %{
1817 // Full implementation of Java idiv and irem; checks for
1818 // special case as described in JVM spec., p.243 & p.271.
1819 //
1820 // normal case special case
1821 //
1822 // input : rax: dividend min_int
1823 // reg: divisor -1
1824 //
1825 // output: rax: quotient (= rax idiv reg) min_int
1826 // rdx: remainder (= rax irem reg) 0
1827 //
1828 // Code sequnce:
1829 //
1830 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax
1831 // 5: 75 07/08 jne e <normal>
1832 // 7: 33 d2 xor %edx,%edx
1833 // [div >= 8 -> offset + 1]
1834 // [REX_B]
1835 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div
1836 // c: 74 03/04 je 11 <done>
1837 // 000000000000000e <normal>:
1838 // e: 99 cltd
1839 // [div >= 8 -> offset + 1]
1840 // [REX_B]
1841 // f: f7 f9 idiv $div
1842 // 0000000000000011 <done>:
1843
1844 // cmp $0x80000000,%eax
1845 emit_opcode(cbuf, 0x3d);
1846 emit_d8(cbuf, 0x00);
1847 emit_d8(cbuf, 0x00);
1848 emit_d8(cbuf, 0x00);
1849 emit_d8(cbuf, 0x80);
1850
1851 // jne e <normal>
1852 emit_opcode(cbuf, 0x75);
1853 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08);
1854
1855 // xor %edx,%edx
1856 emit_opcode(cbuf, 0x33);
1857 emit_d8(cbuf, 0xD2);
1858
1859 // cmp $0xffffffffffffffff,%ecx
1860 if ($div$$reg >= 8) {
1861 emit_opcode(cbuf, Assembler::REX_B);
1862 }
1863 emit_opcode(cbuf, 0x83);
1864 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
1865 emit_d8(cbuf, 0xFF);
1866
1867 // je 11 <done>
1868 emit_opcode(cbuf, 0x74);
1869 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04);
1870
1871 // <normal>
1872 // cltd
1873 emit_opcode(cbuf, 0x99);
1874
1875 // idivl (note: must be emitted by the user of this rule)
1876 // <done>
1877 %}
1878
1879 enc_class cdqq_enc(no_rax_rdx_RegL div)
1880 %{
1881 // Full implementation of Java ldiv and lrem; checks for
1882 // special case as described in JVM spec., p.243 & p.271.
1883 //
1884 // normal case special case
1885 //
1886 // input : rax: dividend min_long
1887 // reg: divisor -1
1888 //
1889 // output: rax: quotient (= rax idiv reg) min_long
1890 // rdx: remainder (= rax irem reg) 0
1891 //
1892 // Code sequnce:
1893 //
1894 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx
1895 // 7: 00 00 80
1896 // a: 48 39 d0 cmp %rdx,%rax
1897 // d: 75 08 jne 17 <normal>
1898 // f: 33 d2 xor %edx,%edx
1899 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div
1900 // 15: 74 05 je 1c <done>
1901 // 0000000000000017 <normal>:
1902 // 17: 48 99 cqto
1903 // 19: 48 f7 f9 idiv $div
1904 // 000000000000001c <done>:
1905
1906 // mov $0x8000000000000000,%rdx
1907 emit_opcode(cbuf, Assembler::REX_W);
1908 emit_opcode(cbuf, 0xBA);
1909 emit_d8(cbuf, 0x00);
1910 emit_d8(cbuf, 0x00);
1911 emit_d8(cbuf, 0x00);
1912 emit_d8(cbuf, 0x00);
1913 emit_d8(cbuf, 0x00);
1914 emit_d8(cbuf, 0x00);
1915 emit_d8(cbuf, 0x00);
1916 emit_d8(cbuf, 0x80);
1917
1918 // cmp %rdx,%rax
1919 emit_opcode(cbuf, Assembler::REX_W);
1920 emit_opcode(cbuf, 0x39);
1921 emit_d8(cbuf, 0xD0);
1922
1923 // jne 17 <normal>
1924 emit_opcode(cbuf, 0x75);
1925 emit_d8(cbuf, 0x08);
1926
1927 // xor %edx,%edx
1928 emit_opcode(cbuf, 0x33);
1929 emit_d8(cbuf, 0xD2);
1930
1931 // cmp $0xffffffffffffffff,$div
1932 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB);
1933 emit_opcode(cbuf, 0x83);
1934 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
1935 emit_d8(cbuf, 0xFF);
1936
1937 // je 1e <done>
1938 emit_opcode(cbuf, 0x74);
1939 emit_d8(cbuf, 0x05);
1940
1941 // <normal>
1942 // cqto
1943 emit_opcode(cbuf, Assembler::REX_W);
1944 emit_opcode(cbuf, 0x99);
1945
1946 // idivq (note: must be emitted by the user of this rule)
1947 // <done>
1948 %}
1949
1950 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
1951 enc_class OpcSE(immI imm)
1952 %{
1953 // Emit primary opcode and set sign-extend bit
1954 // Check for 8-bit immediate, and set sign extend bit in opcode
1955 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1956 emit_opcode(cbuf, $primary | 0x02);
1957 } else {
1958 // 32-bit immediate
1959 emit_opcode(cbuf, $primary);
1960 }
1961 %}
1962
1963 enc_class OpcSErm(rRegI dst, immI imm)
1964 %{
1965 // OpcSEr/m
1966 int dstenc = $dst$$reg;
1967 if (dstenc >= 8) {
1968 emit_opcode(cbuf, Assembler::REX_B);
1969 dstenc -= 8;
1970 }
1971 // Emit primary opcode and set sign-extend bit
1972 // Check for 8-bit immediate, and set sign extend bit in opcode
1973 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1974 emit_opcode(cbuf, $primary | 0x02);
1975 } else {
1976 // 32-bit immediate
1977 emit_opcode(cbuf, $primary);
1978 }
1979 // Emit r/m byte with secondary opcode, after primary opcode.
1980 emit_rm(cbuf, 0x3, $secondary, dstenc);
1981 %}
1982
1983 enc_class OpcSErm_wide(rRegL dst, immI imm)
1984 %{
1985 // OpcSEr/m
1986 int dstenc = $dst$$reg;
1987 if (dstenc < 8) {
1988 emit_opcode(cbuf, Assembler::REX_W);
1989 } else {
1990 emit_opcode(cbuf, Assembler::REX_WB);
1991 dstenc -= 8;
1992 }
1993 // Emit primary opcode and set sign-extend bit
1994 // Check for 8-bit immediate, and set sign extend bit in opcode
1995 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1996 emit_opcode(cbuf, $primary | 0x02);
1997 } else {
1998 // 32-bit immediate
1999 emit_opcode(cbuf, $primary);
2000 }
2001 // Emit r/m byte with secondary opcode, after primary opcode.
2002 emit_rm(cbuf, 0x3, $secondary, dstenc);
2003 %}
2004
2005 enc_class Con8or32(immI imm)
2006 %{
2007 // Check for 8-bit immediate, and set sign extend bit in opcode
2008 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2009 $$$emit8$imm$$constant;
2010 } else {
2011 // 32-bit immediate
2012 $$$emit32$imm$$constant;
2013 }
2014 %}
2015
2016 enc_class opc2_reg(rRegI dst)
2017 %{
2018 // BSWAP
2019 emit_cc(cbuf, $secondary, $dst$$reg);
2020 %}
2021
2022 enc_class opc3_reg(rRegI dst)
2023 %{
2024 // BSWAP
2025 emit_cc(cbuf, $tertiary, $dst$$reg);
2026 %}
2027
2028 enc_class reg_opc(rRegI div)
2029 %{
2030 // INC, DEC, IDIV, IMOD, JMP indirect, ...
2031 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
2032 %}
2033
2034 enc_class enc_cmov(cmpOp cop)
2035 %{
2036 // CMOV
2037 $$$emit8$primary;
2038 emit_cc(cbuf, $secondary, $cop$$cmpcode);
2039 %}
2040
2041 enc_class enc_PartialSubtypeCheck()
2042 %{
2043 Register Rrdi = as_Register(RDI_enc); // result register
2044 Register Rrax = as_Register(RAX_enc); // super class
2045 Register Rrcx = as_Register(RCX_enc); // killed
2046 Register Rrsi = as_Register(RSI_enc); // sub class
2047 Label miss;
2048 const bool set_cond_codes = true;
2049
2050 MacroAssembler _masm(&cbuf);
2051 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
2052 NULL, &miss,
2053 /*set_cond_codes:*/ true);
2054 if ($primary) {
2055 __ xorptr(Rrdi, Rrdi);
2056 }
2057 __ bind(miss);
2058 %}
2059
2060 enc_class clear_avx %{
2061 debug_only(int off0 = cbuf.insts_size());
2062 if (generate_vzeroupper(Compile::current())) {
2063 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty
2064 // Clear upper bits of YMM registers when current compiled code uses
2065 // wide vectors to avoid AVX <-> SSE transition penalty during call.
2066 MacroAssembler _masm(&cbuf);
2067 __ vzeroupper();
2068 }
2069 debug_only(int off1 = cbuf.insts_size());
2070 assert(off1 - off0 == clear_avx_size(), "correct size prediction");
2071 %}
2072
2073 enc_class Java_To_Runtime(method meth) %{
2074 // No relocation needed
2075 MacroAssembler _masm(&cbuf);
2076 __ mov64(r10, (int64_t) $meth$$method);
2077 __ call(r10);
2078 %}
2079
2080 enc_class Java_To_Interpreter(method meth)
2081 %{
2082 // CALL Java_To_Interpreter
2083 // This is the instruction starting address for relocation info.
2084 cbuf.set_insts_mark();
2085 $$$emit8$primary;
2086 // CALL directly to the runtime
2087 emit_d32_reloc(cbuf,
2088 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2089 runtime_call_Relocation::spec(),
2090 RELOC_DISP32);
2091 %}
2092
2093 enc_class Java_Static_Call(method meth)
2094 %{
2095 // JAVA STATIC CALL
2096 // CALL to fixup routine. Fixup routine uses ScopeDesc info to
2097 // determine who we intended to call.
2098 cbuf.set_insts_mark();
2099 $$$emit8$primary;
2100
2101 if (!_method) {
2102 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2103 runtime_call_Relocation::spec(),
2104 RELOC_DISP32);
2105 } else {
2106 int method_index = resolved_method_index(cbuf);
2107 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
2108 : static_call_Relocation::spec(method_index);
2109 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2110 rspec, RELOC_DISP32);
2111 // Emit stubs for static call.
2112 address mark = cbuf.insts_mark();
2113 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark);
2114 if (stub == NULL) {
2115 ciEnv::current()->record_failure("CodeCache is full");
2116 return;
2117 }
2118 #if INCLUDE_AOT
2119 CompiledStaticCall::emit_to_aot_stub(cbuf, mark);
2120 #endif
2121 }
2122 %}
2123
2124 enc_class Java_Dynamic_Call(method meth) %{
2125 MacroAssembler _masm(&cbuf);
2126 __ ic_call((address)$meth$$method, resolved_method_index(cbuf));
2127 %}
2128
2129 enc_class Java_Compiled_Call(method meth)
2130 %{
2131 // JAVA COMPILED CALL
2132 int disp = in_bytes(Method:: from_compiled_offset());
2133
2134 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
2135 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
2136
2137 // callq *disp(%rax)
2138 cbuf.set_insts_mark();
2139 $$$emit8$primary;
2140 if (disp < 0x80) {
2141 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
2142 emit_d8(cbuf, disp); // Displacement
2143 } else {
2144 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte
2145 emit_d32(cbuf, disp); // Displacement
2146 }
2147 %}
2148
2149 enc_class reg_opc_imm(rRegI dst, immI8 shift)
2150 %{
2151 // SAL, SAR, SHR
2152 int dstenc = $dst$$reg;
2153 if (dstenc >= 8) {
2154 emit_opcode(cbuf, Assembler::REX_B);
2155 dstenc -= 8;
2156 }
2157 $$$emit8$primary;
2158 emit_rm(cbuf, 0x3, $secondary, dstenc);
2159 $$$emit8$shift$$constant;
2160 %}
2161
2162 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift)
2163 %{
2164 // SAL, SAR, SHR
2165 int dstenc = $dst$$reg;
2166 if (dstenc < 8) {
2167 emit_opcode(cbuf, Assembler::REX_W);
2168 } else {
2169 emit_opcode(cbuf, Assembler::REX_WB);
2170 dstenc -= 8;
2171 }
2172 $$$emit8$primary;
2173 emit_rm(cbuf, 0x3, $secondary, dstenc);
2174 $$$emit8$shift$$constant;
2175 %}
2176
2177 enc_class load_immI(rRegI dst, immI src)
2178 %{
2179 int dstenc = $dst$$reg;
2180 if (dstenc >= 8) {
2181 emit_opcode(cbuf, Assembler::REX_B);
2182 dstenc -= 8;
2183 }
2184 emit_opcode(cbuf, 0xB8 | dstenc);
2185 $$$emit32$src$$constant;
2186 %}
2187
2188 enc_class load_immL(rRegL dst, immL src)
2189 %{
2190 int dstenc = $dst$$reg;
2191 if (dstenc < 8) {
2192 emit_opcode(cbuf, Assembler::REX_W);
2193 } else {
2194 emit_opcode(cbuf, Assembler::REX_WB);
2195 dstenc -= 8;
2196 }
2197 emit_opcode(cbuf, 0xB8 | dstenc);
2198 emit_d64(cbuf, $src$$constant);
2199 %}
2200
2201 enc_class load_immUL32(rRegL dst, immUL32 src)
2202 %{
2203 // same as load_immI, but this time we care about zeroes in the high word
2204 int dstenc = $dst$$reg;
2205 if (dstenc >= 8) {
2206 emit_opcode(cbuf, Assembler::REX_B);
2207 dstenc -= 8;
2208 }
2209 emit_opcode(cbuf, 0xB8 | dstenc);
2210 $$$emit32$src$$constant;
2211 %}
2212
2213 enc_class load_immL32(rRegL dst, immL32 src)
2214 %{
2215 int dstenc = $dst$$reg;
2216 if (dstenc < 8) {
2217 emit_opcode(cbuf, Assembler::REX_W);
2218 } else {
2219 emit_opcode(cbuf, Assembler::REX_WB);
2220 dstenc -= 8;
2221 }
2222 emit_opcode(cbuf, 0xC7);
2223 emit_rm(cbuf, 0x03, 0x00, dstenc);
2224 $$$emit32$src$$constant;
2225 %}
2226
2227 enc_class load_immP31(rRegP dst, immP32 src)
2228 %{
2229 // same as load_immI, but this time we care about zeroes in the high word
2230 int dstenc = $dst$$reg;
2231 if (dstenc >= 8) {
2232 emit_opcode(cbuf, Assembler::REX_B);
2233 dstenc -= 8;
2234 }
2235 emit_opcode(cbuf, 0xB8 | dstenc);
2236 $$$emit32$src$$constant;
2237 %}
2238
2239 enc_class load_immP(rRegP dst, immP src)
2240 %{
2241 int dstenc = $dst$$reg;
2242 if (dstenc < 8) {
2243 emit_opcode(cbuf, Assembler::REX_W);
2244 } else {
2245 emit_opcode(cbuf, Assembler::REX_WB);
2246 dstenc -= 8;
2247 }
2248 emit_opcode(cbuf, 0xB8 | dstenc);
2249 // This next line should be generated from ADLC
2250 if ($src->constant_reloc() != relocInfo::none) {
2251 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64);
2252 } else {
2253 emit_d64(cbuf, $src$$constant);
2254 }
2255 %}
2256
2257 enc_class Con32(immI src)
2258 %{
2259 // Output immediate
2260 $$$emit32$src$$constant;
2261 %}
2262
2263 enc_class Con32F_as_bits(immF src)
2264 %{
2265 // Output Float immediate bits
2266 jfloat jf = $src$$constant;
2267 jint jf_as_bits = jint_cast(jf);
2268 emit_d32(cbuf, jf_as_bits);
2269 %}
2270
2271 enc_class Con16(immI src)
2272 %{
2273 // Output immediate
2274 $$$emit16$src$$constant;
2275 %}
2276
2277 // How is this different from Con32??? XXX
2278 enc_class Con_d32(immI src)
2279 %{
2280 emit_d32(cbuf,$src$$constant);
2281 %}
2282
2283 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
2284 // Output immediate memory reference
2285 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2286 emit_d32(cbuf, 0x00);
2287 %}
2288
2289 enc_class lock_prefix()
2290 %{
2291 emit_opcode(cbuf, 0xF0); // lock
2292 %}
2293
2294 enc_class REX_mem(memory mem)
2295 %{
2296 if ($mem$$base >= 8) {
2297 if ($mem$$index < 8) {
2298 emit_opcode(cbuf, Assembler::REX_B);
2299 } else {
2300 emit_opcode(cbuf, Assembler::REX_XB);
2301 }
2302 } else {
2303 if ($mem$$index >= 8) {
2304 emit_opcode(cbuf, Assembler::REX_X);
2305 }
2306 }
2307 %}
2308
2309 enc_class REX_mem_wide(memory mem)
2310 %{
2311 if ($mem$$base >= 8) {
2312 if ($mem$$index < 8) {
2313 emit_opcode(cbuf, Assembler::REX_WB);
2314 } else {
2315 emit_opcode(cbuf, Assembler::REX_WXB);
2316 }
2317 } else {
2318 if ($mem$$index < 8) {
2319 emit_opcode(cbuf, Assembler::REX_W);
2320 } else {
2321 emit_opcode(cbuf, Assembler::REX_WX);
2322 }
2323 }
2324 %}
2325
2326 // for byte regs
2327 enc_class REX_breg(rRegI reg)
2328 %{
2329 if ($reg$$reg >= 4) {
2330 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2331 }
2332 %}
2333
2334 // for byte regs
2335 enc_class REX_reg_breg(rRegI dst, rRegI src)
2336 %{
2337 if ($dst$$reg < 8) {
2338 if ($src$$reg >= 4) {
2339 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2340 }
2341 } else {
2342 if ($src$$reg < 8) {
2343 emit_opcode(cbuf, Assembler::REX_R);
2344 } else {
2345 emit_opcode(cbuf, Assembler::REX_RB);
2346 }
2347 }
2348 %}
2349
2350 // for byte regs
2351 enc_class REX_breg_mem(rRegI reg, memory mem)
2352 %{
2353 if ($reg$$reg < 8) {
2354 if ($mem$$base < 8) {
2355 if ($mem$$index >= 8) {
2356 emit_opcode(cbuf, Assembler::REX_X);
2357 } else if ($reg$$reg >= 4) {
2358 emit_opcode(cbuf, Assembler::REX);
2359 }
2360 } else {
2361 if ($mem$$index < 8) {
2362 emit_opcode(cbuf, Assembler::REX_B);
2363 } else {
2364 emit_opcode(cbuf, Assembler::REX_XB);
2365 }
2366 }
2367 } else {
2368 if ($mem$$base < 8) {
2369 if ($mem$$index < 8) {
2370 emit_opcode(cbuf, Assembler::REX_R);
2371 } else {
2372 emit_opcode(cbuf, Assembler::REX_RX);
2373 }
2374 } else {
2375 if ($mem$$index < 8) {
2376 emit_opcode(cbuf, Assembler::REX_RB);
2377 } else {
2378 emit_opcode(cbuf, Assembler::REX_RXB);
2379 }
2380 }
2381 }
2382 %}
2383
2384 enc_class REX_reg(rRegI reg)
2385 %{
2386 if ($reg$$reg >= 8) {
2387 emit_opcode(cbuf, Assembler::REX_B);
2388 }
2389 %}
2390
2391 enc_class REX_reg_wide(rRegI reg)
2392 %{
2393 if ($reg$$reg < 8) {
2394 emit_opcode(cbuf, Assembler::REX_W);
2395 } else {
2396 emit_opcode(cbuf, Assembler::REX_WB);
2397 }
2398 %}
2399
2400 enc_class REX_reg_reg(rRegI dst, rRegI src)
2401 %{
2402 if ($dst$$reg < 8) {
2403 if ($src$$reg >= 8) {
2404 emit_opcode(cbuf, Assembler::REX_B);
2405 }
2406 } else {
2407 if ($src$$reg < 8) {
2408 emit_opcode(cbuf, Assembler::REX_R);
2409 } else {
2410 emit_opcode(cbuf, Assembler::REX_RB);
2411 }
2412 }
2413 %}
2414
2415 enc_class REX_reg_reg_wide(rRegI dst, rRegI src)
2416 %{
2417 if ($dst$$reg < 8) {
2418 if ($src$$reg < 8) {
2419 emit_opcode(cbuf, Assembler::REX_W);
2420 } else {
2421 emit_opcode(cbuf, Assembler::REX_WB);
2422 }
2423 } else {
2424 if ($src$$reg < 8) {
2425 emit_opcode(cbuf, Assembler::REX_WR);
2426 } else {
2427 emit_opcode(cbuf, Assembler::REX_WRB);
2428 }
2429 }
2430 %}
2431
2432 enc_class REX_reg_mem(rRegI reg, memory mem)
2433 %{
2434 if ($reg$$reg < 8) {
2435 if ($mem$$base < 8) {
2436 if ($mem$$index >= 8) {
2437 emit_opcode(cbuf, Assembler::REX_X);
2438 }
2439 } else {
2440 if ($mem$$index < 8) {
2441 emit_opcode(cbuf, Assembler::REX_B);
2442 } else {
2443 emit_opcode(cbuf, Assembler::REX_XB);
2444 }
2445 }
2446 } else {
2447 if ($mem$$base < 8) {
2448 if ($mem$$index < 8) {
2449 emit_opcode(cbuf, Assembler::REX_R);
2450 } else {
2451 emit_opcode(cbuf, Assembler::REX_RX);
2452 }
2453 } else {
2454 if ($mem$$index < 8) {
2455 emit_opcode(cbuf, Assembler::REX_RB);
2456 } else {
2457 emit_opcode(cbuf, Assembler::REX_RXB);
2458 }
2459 }
2460 }
2461 %}
2462
2463 enc_class REX_reg_mem_wide(rRegL reg, memory mem)
2464 %{
2465 if ($reg$$reg < 8) {
2466 if ($mem$$base < 8) {
2467 if ($mem$$index < 8) {
2468 emit_opcode(cbuf, Assembler::REX_W);
2469 } else {
2470 emit_opcode(cbuf, Assembler::REX_WX);
2471 }
2472 } else {
2473 if ($mem$$index < 8) {
2474 emit_opcode(cbuf, Assembler::REX_WB);
2475 } else {
2476 emit_opcode(cbuf, Assembler::REX_WXB);
2477 }
2478 }
2479 } else {
2480 if ($mem$$base < 8) {
2481 if ($mem$$index < 8) {
2482 emit_opcode(cbuf, Assembler::REX_WR);
2483 } else {
2484 emit_opcode(cbuf, Assembler::REX_WRX);
2485 }
2486 } else {
2487 if ($mem$$index < 8) {
2488 emit_opcode(cbuf, Assembler::REX_WRB);
2489 } else {
2490 emit_opcode(cbuf, Assembler::REX_WRXB);
2491 }
2492 }
2493 }
2494 %}
2495
2496 enc_class reg_mem(rRegI ereg, memory mem)
2497 %{
2498 // High registers handle in encode_RegMem
2499 int reg = $ereg$$reg;
2500 int base = $mem$$base;
2501 int index = $mem$$index;
2502 int scale = $mem$$scale;
2503 int disp = $mem$$disp;
2504 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2505
2506 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc);
2507 %}
2508
2509 enc_class RM_opc_mem(immI rm_opcode, memory mem)
2510 %{
2511 int rm_byte_opcode = $rm_opcode$$constant;
2512
2513 // High registers handle in encode_RegMem
2514 int base = $mem$$base;
2515 int index = $mem$$index;
2516 int scale = $mem$$scale;
2517 int displace = $mem$$disp;
2518
2519 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when
2520 // working with static
2521 // globals
2522 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace,
2523 disp_reloc);
2524 %}
2525
2526 enc_class reg_lea(rRegI dst, rRegI src0, immI src1)
2527 %{
2528 int reg_encoding = $dst$$reg;
2529 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
2530 int index = 0x04; // 0x04 indicates no index
2531 int scale = 0x00; // 0x00 indicates no scale
2532 int displace = $src1$$constant; // 0x00 indicates no displacement
2533 relocInfo::relocType disp_reloc = relocInfo::none;
2534 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace,
2535 disp_reloc);
2536 %}
2537
2538 enc_class neg_reg(rRegI dst)
2539 %{
2540 int dstenc = $dst$$reg;
2541 if (dstenc >= 8) {
2542 emit_opcode(cbuf, Assembler::REX_B);
2543 dstenc -= 8;
2544 }
2545 // NEG $dst
2546 emit_opcode(cbuf, 0xF7);
2547 emit_rm(cbuf, 0x3, 0x03, dstenc);
2548 %}
2549
2550 enc_class neg_reg_wide(rRegI dst)
2551 %{
2552 int dstenc = $dst$$reg;
2553 if (dstenc < 8) {
2554 emit_opcode(cbuf, Assembler::REX_W);
2555 } else {
2556 emit_opcode(cbuf, Assembler::REX_WB);
2557 dstenc -= 8;
2558 }
2559 // NEG $dst
2560 emit_opcode(cbuf, 0xF7);
2561 emit_rm(cbuf, 0x3, 0x03, dstenc);
2562 %}
2563
2564 enc_class setLT_reg(rRegI dst)
2565 %{
2566 int dstenc = $dst$$reg;
2567 if (dstenc >= 8) {
2568 emit_opcode(cbuf, Assembler::REX_B);
2569 dstenc -= 8;
2570 } else if (dstenc >= 4) {
2571 emit_opcode(cbuf, Assembler::REX);
2572 }
2573 // SETLT $dst
2574 emit_opcode(cbuf, 0x0F);
2575 emit_opcode(cbuf, 0x9C);
2576 emit_rm(cbuf, 0x3, 0x0, dstenc);
2577 %}
2578
2579 enc_class setNZ_reg(rRegI dst)
2580 %{
2581 int dstenc = $dst$$reg;
2582 if (dstenc >= 8) {
2583 emit_opcode(cbuf, Assembler::REX_B);
2584 dstenc -= 8;
2585 } else if (dstenc >= 4) {
2586 emit_opcode(cbuf, Assembler::REX);
2587 }
2588 // SETNZ $dst
2589 emit_opcode(cbuf, 0x0F);
2590 emit_opcode(cbuf, 0x95);
2591 emit_rm(cbuf, 0x3, 0x0, dstenc);
2592 %}
2593
2594
2595 // Compare the lonogs and set -1, 0, or 1 into dst
2596 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst)
2597 %{
2598 int src1enc = $src1$$reg;
2599 int src2enc = $src2$$reg;
2600 int dstenc = $dst$$reg;
2601
2602 // cmpq $src1, $src2
2603 if (src1enc < 8) {
2604 if (src2enc < 8) {
2605 emit_opcode(cbuf, Assembler::REX_W);
2606 } else {
2607 emit_opcode(cbuf, Assembler::REX_WB);
2608 }
2609 } else {
2610 if (src2enc < 8) {
2611 emit_opcode(cbuf, Assembler::REX_WR);
2612 } else {
2613 emit_opcode(cbuf, Assembler::REX_WRB);
2614 }
2615 }
2616 emit_opcode(cbuf, 0x3B);
2617 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7);
2618
2619 // movl $dst, -1
2620 if (dstenc >= 8) {
2621 emit_opcode(cbuf, Assembler::REX_B);
2622 }
2623 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
2624 emit_d32(cbuf, -1);
2625
2626 // jl,s done
2627 emit_opcode(cbuf, 0x7C);
2628 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
2629
2630 // setne $dst
2631 if (dstenc >= 4) {
2632 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
2633 }
2634 emit_opcode(cbuf, 0x0F);
2635 emit_opcode(cbuf, 0x95);
2636 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
2637
2638 // movzbl $dst, $dst
2639 if (dstenc >= 4) {
2640 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
2641 }
2642 emit_opcode(cbuf, 0x0F);
2643 emit_opcode(cbuf, 0xB6);
2644 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
2645 %}
2646
2647 enc_class Push_ResultXD(regD dst) %{
2648 MacroAssembler _masm(&cbuf);
2649 __ fstp_d(Address(rsp, 0));
2650 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
2651 __ addptr(rsp, 8);
2652 %}
2653
2654 enc_class Push_SrcXD(regD src) %{
2655 MacroAssembler _masm(&cbuf);
2656 __ subptr(rsp, 8);
2657 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
2658 __ fld_d(Address(rsp, 0));
2659 %}
2660
2661
2662 enc_class enc_rethrow()
2663 %{
2664 cbuf.set_insts_mark();
2665 emit_opcode(cbuf, 0xE9); // jmp entry
2666 emit_d32_reloc(cbuf,
2667 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
2668 runtime_call_Relocation::spec(),
2669 RELOC_DISP32);
2670 %}
2671
2672 %}
2673
2674
2675
2676 //----------FRAME--------------------------------------------------------------
2677 // Definition of frame structure and management information.
2678 //
2679 // S T A C K L A Y O U T Allocators stack-slot number
2680 // | (to get allocators register number
2681 // G Owned by | | v add OptoReg::stack0())
2682 // r CALLER | |
2683 // o | +--------+ pad to even-align allocators stack-slot
2684 // w V | pad0 | numbers; owned by CALLER
2685 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
2686 // h ^ | in | 5
2687 // | | args | 4 Holes in incoming args owned by SELF
2688 // | | | | 3
2689 // | | +--------+
2690 // V | | old out| Empty on Intel, window on Sparc
2691 // | old |preserve| Must be even aligned.
2692 // | SP-+--------+----> Matcher::_old_SP, even aligned
2693 // | | in | 3 area for Intel ret address
2694 // Owned by |preserve| Empty on Sparc.
2695 // SELF +--------+
2696 // | | pad2 | 2 pad to align old SP
2697 // | +--------+ 1
2698 // | | locks | 0
2699 // | +--------+----> OptoReg::stack0(), even aligned
2700 // | | pad1 | 11 pad to align new SP
2701 // | +--------+
2702 // | | | 10
2703 // | | spills | 9 spills
2704 // V | | 8 (pad0 slot for callee)
2705 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
2706 // ^ | out | 7
2707 // | | args | 6 Holes in outgoing args owned by CALLEE
2708 // Owned by +--------+
2709 // CALLEE | new out| 6 Empty on Intel, window on Sparc
2710 // | new |preserve| Must be even-aligned.
2711 // | SP-+--------+----> Matcher::_new_SP, even aligned
2712 // | | |
2713 //
2714 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
2715 // known from SELF's arguments and the Java calling convention.
2716 // Region 6-7 is determined per call site.
2717 // Note 2: If the calling convention leaves holes in the incoming argument
2718 // area, those holes are owned by SELF. Holes in the outgoing area
2719 // are owned by the CALLEE. Holes should not be nessecary in the
2720 // incoming area, as the Java calling convention is completely under
2721 // the control of the AD file. Doubles can be sorted and packed to
2722 // avoid holes. Holes in the outgoing arguments may be nessecary for
2723 // varargs C calling conventions.
2724 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
2725 // even aligned with pad0 as needed.
2726 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
2727 // region 6-11 is even aligned; it may be padded out more so that
2728 // the region from SP to FP meets the minimum stack alignment.
2729 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
2730 // alignment. Region 11, pad1, may be dynamically extended so that
2731 // SP meets the minimum alignment.
2732
2733 frame
2734 %{
2735 // What direction does stack grow in (assumed to be same for C & Java)
2736 stack_direction(TOWARDS_LOW);
2737
2738 // These three registers define part of the calling convention
2739 // between compiled code and the interpreter.
2740 inline_cache_reg(RAX); // Inline Cache Register
2741 interpreter_method_oop_reg(RBX); // Method Oop Register when
2742 // calling interpreter
2743
2744 // Optional: name the operand used by cisc-spilling to access
2745 // [stack_pointer + offset]
2746 cisc_spilling_operand_name(indOffset32);
2747
2748 // Number of stack slots consumed by locking an object
2749 sync_stack_slots(2);
2750
2751 // Compiled code's Frame Pointer
2752 frame_pointer(RSP);
2753
2754 // Interpreter stores its frame pointer in a register which is
2755 // stored to the stack by I2CAdaptors.
2756 // I2CAdaptors convert from interpreted java to compiled java.
2757 interpreter_frame_pointer(RBP);
2758
2759 // Stack alignment requirement
2760 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
2761
2762 // Number of stack slots between incoming argument block and the start of
2763 // a new frame. The PROLOG must add this many slots to the stack. The
2764 // EPILOG must remove this many slots. amd64 needs two slots for
2765 // return address.
2766 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls);
2767
2768 // Number of outgoing stack slots killed above the out_preserve_stack_slots
2769 // for calls to C. Supports the var-args backing area for register parms.
2770 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
2771
2772 // The after-PROLOG location of the return address. Location of
2773 // return address specifies a type (REG or STACK) and a number
2774 // representing the register number (i.e. - use a register name) or
2775 // stack slot.
2776 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
2777 // Otherwise, it is above the locks and verification slot and alignment word
2778 return_addr(STACK - 2 +
2779 align_up((Compile::current()->in_preserve_stack_slots() +
2780 Compile::current()->fixed_slots()),
2781 stack_alignment_in_slots()));
2782
2783 // Body of function which returns an integer array locating
2784 // arguments either in registers or in stack slots. Passed an array
2785 // of ideal registers called "sig" and a "length" count. Stack-slot
2786 // offsets are based on outgoing arguments, i.e. a CALLER setting up
2787 // arguments for a CALLEE. Incoming stack arguments are
2788 // automatically biased by the preserve_stack_slots field above.
2789
2790 calling_convention
2791 %{
2792 // No difference between ingoing/outgoing just pass false
2793 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
2794 %}
2795
2796 c_calling_convention
2797 %{
2798 // This is obviously always outgoing
2799 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
2800 %}
2801
2802 // Location of compiled Java return values. Same as C for now.
2803 return_value
2804 %{
2805 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
2806 "only return normal values");
2807
2808 static const int lo[Op_RegL + 1] = {
2809 0,
2810 0,
2811 RAX_num, // Op_RegN
2812 RAX_num, // Op_RegI
2813 RAX_num, // Op_RegP
2814 XMM0_num, // Op_RegF
2815 XMM0_num, // Op_RegD
2816 RAX_num // Op_RegL
2817 };
2818 static const int hi[Op_RegL + 1] = {
2819 0,
2820 0,
2821 OptoReg::Bad, // Op_RegN
2822 OptoReg::Bad, // Op_RegI
2823 RAX_H_num, // Op_RegP
2824 OptoReg::Bad, // Op_RegF
2825 XMM0b_num, // Op_RegD
2826 RAX_H_num // Op_RegL
2827 };
2828 // Excluded flags and vector registers.
2829 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type");
2830 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
2831 %}
2832 %}
2833
2834 //----------ATTRIBUTES---------------------------------------------------------
2835 //----------Operand Attributes-------------------------------------------------
2836 op_attrib op_cost(0); // Required cost attribute
2837
2838 //----------Instruction Attributes---------------------------------------------
2839 ins_attrib ins_cost(100); // Required cost attribute
2840 ins_attrib ins_size(8); // Required size attribute (in bits)
2841 ins_attrib ins_short_branch(0); // Required flag: is this instruction
2842 // a non-matching short branch variant
2843 // of some long branch?
2844 ins_attrib ins_alignment(1); // Required alignment attribute (must
2845 // be a power of 2) specifies the
2846 // alignment that some part of the
2847 // instruction (not necessarily the
2848 // start) requires. If > 1, a
2849 // compute_padding() function must be
2850 // provided for the instruction
2851
2852 //----------OPERANDS-----------------------------------------------------------
2853 // Operand definitions must precede instruction definitions for correct parsing
2854 // in the ADLC because operands constitute user defined types which are used in
2855 // instruction definitions.
2856
2857 //----------Simple Operands----------------------------------------------------
2858 // Immediate Operands
2859 // Integer Immediate
2860 operand immI()
2861 %{
2862 match(ConI);
2863
2864 op_cost(10);
2865 format %{ %}
2866 interface(CONST_INTER);
2867 %}
2868
2869 // Constant for test vs zero
2870 operand immI0()
2871 %{
2872 predicate(n->get_int() == 0);
2873 match(ConI);
2874
2875 op_cost(0);
2876 format %{ %}
2877 interface(CONST_INTER);
2878 %}
2879
2880 // Constant for increment
2881 operand immI1()
2882 %{
2883 predicate(n->get_int() == 1);
2884 match(ConI);
2885
2886 op_cost(0);
2887 format %{ %}
2888 interface(CONST_INTER);
2889 %}
2890
2891 // Constant for decrement
2892 operand immI_M1()
2893 %{
2894 predicate(n->get_int() == -1);
2895 match(ConI);
2896
2897 op_cost(0);
2898 format %{ %}
2899 interface(CONST_INTER);
2900 %}
2901
2902 // Valid scale values for addressing modes
2903 operand immI2()
2904 %{
2905 predicate(0 <= n->get_int() && (n->get_int() <= 3));
2906 match(ConI);
2907
2908 format %{ %}
2909 interface(CONST_INTER);
2910 %}
2911
2912 operand immI8()
2913 %{
2914 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80));
2915 match(ConI);
2916
2917 op_cost(5);
2918 format %{ %}
2919 interface(CONST_INTER);
2920 %}
2921
2922 operand immU8()
2923 %{
2924 predicate((0 <= n->get_int()) && (n->get_int() <= 255));
2925 match(ConI);
2926
2927 op_cost(5);
2928 format %{ %}
2929 interface(CONST_INTER);
2930 %}
2931
2932 operand immI16()
2933 %{
2934 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
2935 match(ConI);
2936
2937 op_cost(10);
2938 format %{ %}
2939 interface(CONST_INTER);
2940 %}
2941
2942 // Int Immediate non-negative
2943 operand immU31()
2944 %{
2945 predicate(n->get_int() >= 0);
2946 match(ConI);
2947
2948 op_cost(0);
2949 format %{ %}
2950 interface(CONST_INTER);
2951 %}
2952
2953 // Constant for long shifts
2954 operand immI_32()
2955 %{
2956 predicate( n->get_int() == 32 );
2957 match(ConI);
2958
2959 op_cost(0);
2960 format %{ %}
2961 interface(CONST_INTER);
2962 %}
2963
2964 // Constant for long shifts
2965 operand immI_64()
2966 %{
2967 predicate( n->get_int() == 64 );
2968 match(ConI);
2969
2970 op_cost(0);
2971 format %{ %}
2972 interface(CONST_INTER);
2973 %}
2974
2975 // Pointer Immediate
2976 operand immP()
2977 %{
2978 match(ConP);
2979
2980 op_cost(10);
2981 format %{ %}
2982 interface(CONST_INTER);
2983 %}
2984
2985 // NULL Pointer Immediate
2986 operand immP0()
2987 %{
2988 predicate(n->get_ptr() == 0);
2989 match(ConP);
2990
2991 op_cost(5);
2992 format %{ %}
2993 interface(CONST_INTER);
2994 %}
2995
2996 // Pointer Immediate
2997 operand immN() %{
2998 match(ConN);
2999
3000 op_cost(10);
3001 format %{ %}
3002 interface(CONST_INTER);
3003 %}
3004
3005 operand immNKlass() %{
3006 match(ConNKlass);
3007
3008 op_cost(10);
3009 format %{ %}
3010 interface(CONST_INTER);
3011 %}
3012
3013 // NULL Pointer Immediate
3014 operand immN0() %{
3015 predicate(n->get_narrowcon() == 0);
3016 match(ConN);
3017
3018 op_cost(5);
3019 format %{ %}
3020 interface(CONST_INTER);
3021 %}
3022
3023 operand immP31()
3024 %{
3025 predicate(n->as_Type()->type()->reloc() == relocInfo::none
3026 && (n->get_ptr() >> 31) == 0);
3027 match(ConP);
3028
3029 op_cost(5);
3030 format %{ %}
3031 interface(CONST_INTER);
3032 %}
3033
3034
3035 // Long Immediate
3036 operand immL()
3037 %{
3038 match(ConL);
3039
3040 op_cost(20);
3041 format %{ %}
3042 interface(CONST_INTER);
3043 %}
3044
3045 // Long Immediate 8-bit
3046 operand immL8()
3047 %{
3048 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3049 match(ConL);
3050
3051 op_cost(5);
3052 format %{ %}
3053 interface(CONST_INTER);
3054 %}
3055
3056 // Long Immediate 32-bit unsigned
3057 operand immUL32()
3058 %{
3059 predicate(n->get_long() == (unsigned int) (n->get_long()));
3060 match(ConL);
3061
3062 op_cost(10);
3063 format %{ %}
3064 interface(CONST_INTER);
3065 %}
3066
3067 // Long Immediate 32-bit signed
3068 operand immL32()
3069 %{
3070 predicate(n->get_long() == (int) (n->get_long()));
3071 match(ConL);
3072
3073 op_cost(15);
3074 format %{ %}
3075 interface(CONST_INTER);
3076 %}
3077
3078 operand immL_Pow2()
3079 %{
3080 predicate(is_power_of_2((julong)n->get_long()));
3081 match(ConL);
3082
3083 op_cost(15);
3084 format %{ %}
3085 interface(CONST_INTER);
3086 %}
3087
3088 operand immL_NotPow2()
3089 %{
3090 predicate(is_power_of_2((julong)~n->get_long()));
3091 match(ConL);
3092
3093 op_cost(15);
3094 format %{ %}
3095 interface(CONST_INTER);
3096 %}
3097
3098 // Long Immediate zero
3099 operand immL0()
3100 %{
3101 predicate(n->get_long() == 0L);
3102 match(ConL);
3103
3104 op_cost(10);
3105 format %{ %}
3106 interface(CONST_INTER);
3107 %}
3108
3109 // Constant for increment
3110 operand immL1()
3111 %{
3112 predicate(n->get_long() == 1);
3113 match(ConL);
3114
3115 format %{ %}
3116 interface(CONST_INTER);
3117 %}
3118
3119 // Constant for decrement
3120 operand immL_M1()
3121 %{
3122 predicate(n->get_long() == -1);
3123 match(ConL);
3124
3125 format %{ %}
3126 interface(CONST_INTER);
3127 %}
3128
3129 // Long Immediate: the value 10
3130 operand immL10()
3131 %{
3132 predicate(n->get_long() == 10);
3133 match(ConL);
3134
3135 format %{ %}
3136 interface(CONST_INTER);
3137 %}
3138
3139 // Long immediate from 0 to 127.
3140 // Used for a shorter form of long mul by 10.
3141 operand immL_127()
3142 %{
3143 predicate(0 <= n->get_long() && n->get_long() < 0x80);
3144 match(ConL);
3145
3146 op_cost(10);
3147 format %{ %}
3148 interface(CONST_INTER);
3149 %}
3150
3151 // Long Immediate: low 32-bit mask
3152 operand immL_32bits()
3153 %{
3154 predicate(n->get_long() == 0xFFFFFFFFL);
3155 match(ConL);
3156 op_cost(20);
3157
3158 format %{ %}
3159 interface(CONST_INTER);
3160 %}
3161
3162 // Float Immediate zero
3163 operand immF0()
3164 %{
3165 predicate(jint_cast(n->getf()) == 0);
3166 match(ConF);
3167
3168 op_cost(5);
3169 format %{ %}
3170 interface(CONST_INTER);
3171 %}
3172
3173 // Float Immediate
3174 operand immF()
3175 %{
3176 match(ConF);
3177
3178 op_cost(15);
3179 format %{ %}
3180 interface(CONST_INTER);
3181 %}
3182
3183 // Double Immediate zero
3184 operand immD0()
3185 %{
3186 predicate(jlong_cast(n->getd()) == 0);
3187 match(ConD);
3188
3189 op_cost(5);
3190 format %{ %}
3191 interface(CONST_INTER);
3192 %}
3193
3194 // Double Immediate
3195 operand immD()
3196 %{
3197 match(ConD);
3198
3199 op_cost(15);
3200 format %{ %}
3201 interface(CONST_INTER);
3202 %}
3203
3204 // Immediates for special shifts (sign extend)
3205
3206 // Constants for increment
3207 operand immI_16()
3208 %{
3209 predicate(n->get_int() == 16);
3210 match(ConI);
3211
3212 format %{ %}
3213 interface(CONST_INTER);
3214 %}
3215
3216 operand immI_24()
3217 %{
3218 predicate(n->get_int() == 24);
3219 match(ConI);
3220
3221 format %{ %}
3222 interface(CONST_INTER);
3223 %}
3224
3225 // Constant for byte-wide masking
3226 operand immI_255()
3227 %{
3228 predicate(n->get_int() == 255);
3229 match(ConI);
3230
3231 format %{ %}
3232 interface(CONST_INTER);
3233 %}
3234
3235 // Constant for short-wide masking
3236 operand immI_65535()
3237 %{
3238 predicate(n->get_int() == 65535);
3239 match(ConI);
3240
3241 format %{ %}
3242 interface(CONST_INTER);
3243 %}
3244
3245 // Constant for byte-wide masking
3246 operand immL_255()
3247 %{
3248 predicate(n->get_long() == 255);
3249 match(ConL);
3250
3251 format %{ %}
3252 interface(CONST_INTER);
3253 %}
3254
3255 // Constant for short-wide masking
3256 operand immL_65535()
3257 %{
3258 predicate(n->get_long() == 65535);
3259 match(ConL);
3260
3261 format %{ %}
3262 interface(CONST_INTER);
3263 %}
3264
3265 // Register Operands
3266 // Integer Register
3267 operand rRegI()
3268 %{
3269 constraint(ALLOC_IN_RC(int_reg));
3270 match(RegI);
3271
3272 match(rax_RegI);
3273 match(rbx_RegI);
3274 match(rcx_RegI);
3275 match(rdx_RegI);
3276 match(rdi_RegI);
3277
3278 format %{ %}
3279 interface(REG_INTER);
3280 %}
3281
3282 // Special Registers
3283 operand rax_RegI()
3284 %{
3285 constraint(ALLOC_IN_RC(int_rax_reg));
3286 match(RegI);
3287 match(rRegI);
3288
3289 format %{ "RAX" %}
3290 interface(REG_INTER);
3291 %}
3292
3293 // Special Registers
3294 operand rbx_RegI()
3295 %{
3296 constraint(ALLOC_IN_RC(int_rbx_reg));
3297 match(RegI);
3298 match(rRegI);
3299
3300 format %{ "RBX" %}
3301 interface(REG_INTER);
3302 %}
3303
3304 operand rcx_RegI()
3305 %{
3306 constraint(ALLOC_IN_RC(int_rcx_reg));
3307 match(RegI);
3308 match(rRegI);
3309
3310 format %{ "RCX" %}
3311 interface(REG_INTER);
3312 %}
3313
3314 operand rdx_RegI()
3315 %{
3316 constraint(ALLOC_IN_RC(int_rdx_reg));
3317 match(RegI);
3318 match(rRegI);
3319
3320 format %{ "RDX" %}
3321 interface(REG_INTER);
3322 %}
3323
3324 operand rdi_RegI()
3325 %{
3326 constraint(ALLOC_IN_RC(int_rdi_reg));
3327 match(RegI);
3328 match(rRegI);
3329
3330 format %{ "RDI" %}
3331 interface(REG_INTER);
3332 %}
3333
3334 operand no_rcx_RegI()
3335 %{
3336 constraint(ALLOC_IN_RC(int_no_rcx_reg));
3337 match(RegI);
3338 match(rax_RegI);
3339 match(rbx_RegI);
3340 match(rdx_RegI);
3341 match(rdi_RegI);
3342
3343 format %{ %}
3344 interface(REG_INTER);
3345 %}
3346
3347 operand no_rax_rdx_RegI()
3348 %{
3349 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg));
3350 match(RegI);
3351 match(rbx_RegI);
3352 match(rcx_RegI);
3353 match(rdi_RegI);
3354
3355 format %{ %}
3356 interface(REG_INTER);
3357 %}
3358
3359 // Pointer Register
3360 operand any_RegP()
3361 %{
3362 constraint(ALLOC_IN_RC(any_reg));
3363 match(RegP);
3364 match(rax_RegP);
3365 match(rbx_RegP);
3366 match(rdi_RegP);
3367 match(rsi_RegP);
3368 match(rbp_RegP);
3369 match(r15_RegP);
3370 match(rRegP);
3371
3372 format %{ %}
3373 interface(REG_INTER);
3374 %}
3375
3376 operand rRegP()
3377 %{
3378 constraint(ALLOC_IN_RC(ptr_reg));
3379 match(RegP);
3380 match(rax_RegP);
3381 match(rbx_RegP);
3382 match(rdi_RegP);
3383 match(rsi_RegP);
3384 match(rbp_RegP); // See Q&A below about
3385 match(r15_RegP); // r15_RegP and rbp_RegP.
3386
3387 format %{ %}
3388 interface(REG_INTER);
3389 %}
3390
3391 operand rRegN() %{
3392 constraint(ALLOC_IN_RC(int_reg));
3393 match(RegN);
3394
3395 format %{ %}
3396 interface(REG_INTER);
3397 %}
3398
3399 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
3400 // Answer: Operand match rules govern the DFA as it processes instruction inputs.
3401 // It's fine for an instruction input that expects rRegP to match a r15_RegP.
3402 // The output of an instruction is controlled by the allocator, which respects
3403 // register class masks, not match rules. Unless an instruction mentions
3404 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered
3405 // by the allocator as an input.
3406 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true,
3407 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a
3408 // result, RBP is not included in the output of the instruction either.
3409
3410 operand no_rax_RegP()
3411 %{
3412 constraint(ALLOC_IN_RC(ptr_no_rax_reg));
3413 match(RegP);
3414 match(rbx_RegP);
3415 match(rsi_RegP);
3416 match(rdi_RegP);
3417
3418 format %{ %}
3419 interface(REG_INTER);
3420 %}
3421
3422 // This operand is not allowed to use RBP even if
3423 // RBP is not used to hold the frame pointer.
3424 operand no_rbp_RegP()
3425 %{
3426 constraint(ALLOC_IN_RC(ptr_reg_no_rbp));
3427 match(RegP);
3428 match(rbx_RegP);
3429 match(rsi_RegP);
3430 match(rdi_RegP);
3431
3432 format %{ %}
3433 interface(REG_INTER);
3434 %}
3435
3436 operand no_rax_rbx_RegP()
3437 %{
3438 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg));
3439 match(RegP);
3440 match(rsi_RegP);
3441 match(rdi_RegP);
3442
3443 format %{ %}
3444 interface(REG_INTER);
3445 %}
3446
3447 // Special Registers
3448 // Return a pointer value
3449 operand rax_RegP()
3450 %{
3451 constraint(ALLOC_IN_RC(ptr_rax_reg));
3452 match(RegP);
3453 match(rRegP);
3454
3455 format %{ %}
3456 interface(REG_INTER);
3457 %}
3458
3459 // Special Registers
3460 // Return a compressed pointer value
3461 operand rax_RegN()
3462 %{
3463 constraint(ALLOC_IN_RC(int_rax_reg));
3464 match(RegN);
3465 match(rRegN);
3466
3467 format %{ %}
3468 interface(REG_INTER);
3469 %}
3470
3471 // Used in AtomicAdd
3472 operand rbx_RegP()
3473 %{
3474 constraint(ALLOC_IN_RC(ptr_rbx_reg));
3475 match(RegP);
3476 match(rRegP);
3477
3478 format %{ %}
3479 interface(REG_INTER);
3480 %}
3481
3482 operand rsi_RegP()
3483 %{
3484 constraint(ALLOC_IN_RC(ptr_rsi_reg));
3485 match(RegP);
3486 match(rRegP);
3487
3488 format %{ %}
3489 interface(REG_INTER);
3490 %}
3491
3492 operand rbp_RegP()
3493 %{
3494 constraint(ALLOC_IN_RC(ptr_rbp_reg));
3495 match(RegP);
3496 match(rRegP);
3497
3498 format %{ %}
3499 interface(REG_INTER);
3500 %}
3501
3502 // Used in rep stosq
3503 operand rdi_RegP()
3504 %{
3505 constraint(ALLOC_IN_RC(ptr_rdi_reg));
3506 match(RegP);
3507 match(rRegP);
3508
3509 format %{ %}
3510 interface(REG_INTER);
3511 %}
3512
3513 operand r15_RegP()
3514 %{
3515 constraint(ALLOC_IN_RC(ptr_r15_reg));
3516 match(RegP);
3517 match(rRegP);
3518
3519 format %{ %}
3520 interface(REG_INTER);
3521 %}
3522
3523 operand rRegL()
3524 %{
3525 constraint(ALLOC_IN_RC(long_reg));
3526 match(RegL);
3527 match(rax_RegL);
3528 match(rdx_RegL);
3529
3530 format %{ %}
3531 interface(REG_INTER);
3532 %}
3533
3534 // Special Registers
3535 operand no_rax_rdx_RegL()
3536 %{
3537 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3538 match(RegL);
3539 match(rRegL);
3540
3541 format %{ %}
3542 interface(REG_INTER);
3543 %}
3544
3545 operand no_rax_RegL()
3546 %{
3547 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3548 match(RegL);
3549 match(rRegL);
3550 match(rdx_RegL);
3551
3552 format %{ %}
3553 interface(REG_INTER);
3554 %}
3555
3556 operand no_rcx_RegL()
3557 %{
3558 constraint(ALLOC_IN_RC(long_no_rcx_reg));
3559 match(RegL);
3560 match(rRegL);
3561
3562 format %{ %}
3563 interface(REG_INTER);
3564 %}
3565
3566 operand rax_RegL()
3567 %{
3568 constraint(ALLOC_IN_RC(long_rax_reg));
3569 match(RegL);
3570 match(rRegL);
3571
3572 format %{ "RAX" %}
3573 interface(REG_INTER);
3574 %}
3575
3576 operand rcx_RegL()
3577 %{
3578 constraint(ALLOC_IN_RC(long_rcx_reg));
3579 match(RegL);
3580 match(rRegL);
3581
3582 format %{ %}
3583 interface(REG_INTER);
3584 %}
3585
3586 operand rdx_RegL()
3587 %{
3588 constraint(ALLOC_IN_RC(long_rdx_reg));
3589 match(RegL);
3590 match(rRegL);
3591
3592 format %{ %}
3593 interface(REG_INTER);
3594 %}
3595
3596 // Flags register, used as output of compare instructions
3597 operand rFlagsReg()
3598 %{
3599 constraint(ALLOC_IN_RC(int_flags));
3600 match(RegFlags);
3601
3602 format %{ "RFLAGS" %}
3603 interface(REG_INTER);
3604 %}
3605
3606 // Flags register, used as output of FLOATING POINT compare instructions
3607 operand rFlagsRegU()
3608 %{
3609 constraint(ALLOC_IN_RC(int_flags));
3610 match(RegFlags);
3611
3612 format %{ "RFLAGS_U" %}
3613 interface(REG_INTER);
3614 %}
3615
3616 operand rFlagsRegUCF() %{
3617 constraint(ALLOC_IN_RC(int_flags));
3618 match(RegFlags);
3619 predicate(false);
3620
3621 format %{ "RFLAGS_U_CF" %}
3622 interface(REG_INTER);
3623 %}
3624
3625 // Float register operands
3626 operand regF() %{
3627 constraint(ALLOC_IN_RC(float_reg));
3628 match(RegF);
3629
3630 format %{ %}
3631 interface(REG_INTER);
3632 %}
3633
3634 // Float register operands
3635 operand legRegF() %{
3636 constraint(ALLOC_IN_RC(float_reg_legacy));
3637 match(RegF);
3638
3639 format %{ %}
3640 interface(REG_INTER);
3641 %}
3642
3643 // Float register operands
3644 operand vlRegF() %{
3645 constraint(ALLOC_IN_RC(float_reg_vl));
3646 match(RegF);
3647
3648 format %{ %}
3649 interface(REG_INTER);
3650 %}
3651
3652 // Double register operands
3653 operand regD() %{
3654 constraint(ALLOC_IN_RC(double_reg));
3655 match(RegD);
3656
3657 format %{ %}
3658 interface(REG_INTER);
3659 %}
3660
3661 // Double register operands
3662 operand legRegD() %{
3663 constraint(ALLOC_IN_RC(double_reg_legacy));
3664 match(RegD);
3665
3666 format %{ %}
3667 interface(REG_INTER);
3668 %}
3669
3670 // Double register operands
3671 operand vlRegD() %{
3672 constraint(ALLOC_IN_RC(double_reg_vl));
3673 match(RegD);
3674
3675 format %{ %}
3676 interface(REG_INTER);
3677 %}
3678
3679 //----------Memory Operands----------------------------------------------------
3680 // Direct Memory Operand
3681 // operand direct(immP addr)
3682 // %{
3683 // match(addr);
3684
3685 // format %{ "[$addr]" %}
3686 // interface(MEMORY_INTER) %{
3687 // base(0xFFFFFFFF);
3688 // index(0x4);
3689 // scale(0x0);
3690 // disp($addr);
3691 // %}
3692 // %}
3693
3694 // Indirect Memory Operand
3695 operand indirect(any_RegP reg)
3696 %{
3697 constraint(ALLOC_IN_RC(ptr_reg));
3698 match(reg);
3699
3700 format %{ "[$reg]" %}
3701 interface(MEMORY_INTER) %{
3702 base($reg);
3703 index(0x4);
3704 scale(0x0);
3705 disp(0x0);
3706 %}
3707 %}
3708
3709 // Indirect Memory Plus Short Offset Operand
3710 operand indOffset8(any_RegP reg, immL8 off)
3711 %{
3712 constraint(ALLOC_IN_RC(ptr_reg));
3713 match(AddP reg off);
3714
3715 format %{ "[$reg + $off (8-bit)]" %}
3716 interface(MEMORY_INTER) %{
3717 base($reg);
3718 index(0x4);
3719 scale(0x0);
3720 disp($off);
3721 %}
3722 %}
3723
3724 // Indirect Memory Plus Long Offset Operand
3725 operand indOffset32(any_RegP reg, immL32 off)
3726 %{
3727 constraint(ALLOC_IN_RC(ptr_reg));
3728 match(AddP reg off);
3729
3730 format %{ "[$reg + $off (32-bit)]" %}
3731 interface(MEMORY_INTER) %{
3732 base($reg);
3733 index(0x4);
3734 scale(0x0);
3735 disp($off);
3736 %}
3737 %}
3738
3739 // Indirect Memory Plus Index Register Plus Offset Operand
3740 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off)
3741 %{
3742 constraint(ALLOC_IN_RC(ptr_reg));
3743 match(AddP (AddP reg lreg) off);
3744
3745 op_cost(10);
3746 format %{"[$reg + $off + $lreg]" %}
3747 interface(MEMORY_INTER) %{
3748 base($reg);
3749 index($lreg);
3750 scale(0x0);
3751 disp($off);
3752 %}
3753 %}
3754
3755 // Indirect Memory Plus Index Register Plus Offset Operand
3756 operand indIndex(any_RegP reg, rRegL lreg)
3757 %{
3758 constraint(ALLOC_IN_RC(ptr_reg));
3759 match(AddP reg lreg);
3760
3761 op_cost(10);
3762 format %{"[$reg + $lreg]" %}
3763 interface(MEMORY_INTER) %{
3764 base($reg);
3765 index($lreg);
3766 scale(0x0);
3767 disp(0x0);
3768 %}
3769 %}
3770
3771 // Indirect Memory Times Scale Plus Index Register
3772 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale)
3773 %{
3774 constraint(ALLOC_IN_RC(ptr_reg));
3775 match(AddP reg (LShiftL lreg scale));
3776
3777 op_cost(10);
3778 format %{"[$reg + $lreg << $scale]" %}
3779 interface(MEMORY_INTER) %{
3780 base($reg);
3781 index($lreg);
3782 scale($scale);
3783 disp(0x0);
3784 %}
3785 %}
3786
3787 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale)
3788 %{
3789 constraint(ALLOC_IN_RC(ptr_reg));
3790 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
3791 match(AddP reg (LShiftL (ConvI2L idx) scale));
3792
3793 op_cost(10);
3794 format %{"[$reg + pos $idx << $scale]" %}
3795 interface(MEMORY_INTER) %{
3796 base($reg);
3797 index($idx);
3798 scale($scale);
3799 disp(0x0);
3800 %}
3801 %}
3802
3803 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
3804 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
3805 %{
3806 constraint(ALLOC_IN_RC(ptr_reg));
3807 match(AddP (AddP reg (LShiftL lreg scale)) off);
3808
3809 op_cost(10);
3810 format %{"[$reg + $off + $lreg << $scale]" %}
3811 interface(MEMORY_INTER) %{
3812 base($reg);
3813 index($lreg);
3814 scale($scale);
3815 disp($off);
3816 %}
3817 %}
3818
3819 // Indirect Memory Plus Positive Index Register Plus Offset Operand
3820 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx)
3821 %{
3822 constraint(ALLOC_IN_RC(ptr_reg));
3823 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0);
3824 match(AddP (AddP reg (ConvI2L idx)) off);
3825
3826 op_cost(10);
3827 format %{"[$reg + $off + $idx]" %}
3828 interface(MEMORY_INTER) %{
3829 base($reg);
3830 index($idx);
3831 scale(0x0);
3832 disp($off);
3833 %}
3834 %}
3835
3836 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
3837 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale)
3838 %{
3839 constraint(ALLOC_IN_RC(ptr_reg));
3840 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
3841 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off);
3842
3843 op_cost(10);
3844 format %{"[$reg + $off + $idx << $scale]" %}
3845 interface(MEMORY_INTER) %{
3846 base($reg);
3847 index($idx);
3848 scale($scale);
3849 disp($off);
3850 %}
3851 %}
3852
3853 // Indirect Narrow Oop Operand
3854 operand indCompressedOop(rRegN reg) %{
3855 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8));
3856 constraint(ALLOC_IN_RC(ptr_reg));
3857 match(DecodeN reg);
3858
3859 op_cost(10);
3860 format %{"[R12 + $reg << 3] (compressed oop addressing)" %}
3861 interface(MEMORY_INTER) %{
3862 base(0xc); // R12
3863 index($reg);
3864 scale(0x3);
3865 disp(0x0);
3866 %}
3867 %}
3868
3869 // Indirect Narrow Oop Plus Offset Operand
3870 // Note: x86 architecture doesn't support "scale * index + offset" without a base
3871 // we can't free r12 even with CompressedOops::base() == NULL.
3872 operand indCompressedOopOffset(rRegN reg, immL32 off) %{
3873 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8));
3874 constraint(ALLOC_IN_RC(ptr_reg));
3875 match(AddP (DecodeN reg) off);
3876
3877 op_cost(10);
3878 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
3879 interface(MEMORY_INTER) %{
3880 base(0xc); // R12
3881 index($reg);
3882 scale(0x3);
3883 disp($off);
3884 %}
3885 %}
3886
3887 // Indirect Memory Operand
3888 operand indirectNarrow(rRegN reg)
3889 %{
3890 predicate(CompressedOops::shift() == 0);
3891 constraint(ALLOC_IN_RC(ptr_reg));
3892 match(DecodeN reg);
3893
3894 format %{ "[$reg]" %}
3895 interface(MEMORY_INTER) %{
3896 base($reg);
3897 index(0x4);
3898 scale(0x0);
3899 disp(0x0);
3900 %}
3901 %}
3902
3903 // Indirect Memory Plus Short Offset Operand
3904 operand indOffset8Narrow(rRegN reg, immL8 off)
3905 %{
3906 predicate(CompressedOops::shift() == 0);
3907 constraint(ALLOC_IN_RC(ptr_reg));
3908 match(AddP (DecodeN reg) off);
3909
3910 format %{ "[$reg + $off (8-bit)]" %}
3911 interface(MEMORY_INTER) %{
3912 base($reg);
3913 index(0x4);
3914 scale(0x0);
3915 disp($off);
3916 %}
3917 %}
3918
3919 // Indirect Memory Plus Long Offset Operand
3920 operand indOffset32Narrow(rRegN reg, immL32 off)
3921 %{
3922 predicate(CompressedOops::shift() == 0);
3923 constraint(ALLOC_IN_RC(ptr_reg));
3924 match(AddP (DecodeN reg) off);
3925
3926 format %{ "[$reg + $off (32-bit)]" %}
3927 interface(MEMORY_INTER) %{
3928 base($reg);
3929 index(0x4);
3930 scale(0x0);
3931 disp($off);
3932 %}
3933 %}
3934
3935 // Indirect Memory Plus Index Register Plus Offset Operand
3936 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off)
3937 %{
3938 predicate(CompressedOops::shift() == 0);
3939 constraint(ALLOC_IN_RC(ptr_reg));
3940 match(AddP (AddP (DecodeN reg) lreg) off);
3941
3942 op_cost(10);
3943 format %{"[$reg + $off + $lreg]" %}
3944 interface(MEMORY_INTER) %{
3945 base($reg);
3946 index($lreg);
3947 scale(0x0);
3948 disp($off);
3949 %}
3950 %}
3951
3952 // Indirect Memory Plus Index Register Plus Offset Operand
3953 operand indIndexNarrow(rRegN reg, rRegL lreg)
3954 %{
3955 predicate(CompressedOops::shift() == 0);
3956 constraint(ALLOC_IN_RC(ptr_reg));
3957 match(AddP (DecodeN reg) lreg);
3958
3959 op_cost(10);
3960 format %{"[$reg + $lreg]" %}
3961 interface(MEMORY_INTER) %{
3962 base($reg);
3963 index($lreg);
3964 scale(0x0);
3965 disp(0x0);
3966 %}
3967 %}
3968
3969 // Indirect Memory Times Scale Plus Index Register
3970 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale)
3971 %{
3972 predicate(CompressedOops::shift() == 0);
3973 constraint(ALLOC_IN_RC(ptr_reg));
3974 match(AddP (DecodeN reg) (LShiftL lreg scale));
3975
3976 op_cost(10);
3977 format %{"[$reg + $lreg << $scale]" %}
3978 interface(MEMORY_INTER) %{
3979 base($reg);
3980 index($lreg);
3981 scale($scale);
3982 disp(0x0);
3983 %}
3984 %}
3985
3986 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
3987 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
3988 %{
3989 predicate(CompressedOops::shift() == 0);
3990 constraint(ALLOC_IN_RC(ptr_reg));
3991 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
3992
3993 op_cost(10);
3994 format %{"[$reg + $off + $lreg << $scale]" %}
3995 interface(MEMORY_INTER) %{
3996 base($reg);
3997 index($lreg);
3998 scale($scale);
3999 disp($off);
4000 %}
4001 %}
4002
4003 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand
4004 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx)
4005 %{
4006 constraint(ALLOC_IN_RC(ptr_reg));
4007 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0);
4008 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off);
4009
4010 op_cost(10);
4011 format %{"[$reg + $off + $idx]" %}
4012 interface(MEMORY_INTER) %{
4013 base($reg);
4014 index($idx);
4015 scale(0x0);
4016 disp($off);
4017 %}
4018 %}
4019
4020 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
4021 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4022 %{
4023 constraint(ALLOC_IN_RC(ptr_reg));
4024 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4025 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
4026
4027 op_cost(10);
4028 format %{"[$reg + $off + $idx << $scale]" %}
4029 interface(MEMORY_INTER) %{
4030 base($reg);
4031 index($idx);
4032 scale($scale);
4033 disp($off);
4034 %}
4035 %}
4036
4037 //----------Special Memory Operands--------------------------------------------
4038 // Stack Slot Operand - This operand is used for loading and storing temporary
4039 // values on the stack where a match requires a value to
4040 // flow through memory.
4041 operand stackSlotP(sRegP reg)
4042 %{
4043 constraint(ALLOC_IN_RC(stack_slots));
4044 // No match rule because this operand is only generated in matching
4045
4046 format %{ "[$reg]" %}
4047 interface(MEMORY_INTER) %{
4048 base(0x4); // RSP
4049 index(0x4); // No Index
4050 scale(0x0); // No Scale
4051 disp($reg); // Stack Offset
4052 %}
4053 %}
4054
4055 operand stackSlotI(sRegI reg)
4056 %{
4057 constraint(ALLOC_IN_RC(stack_slots));
4058 // No match rule because this operand is only generated in matching
4059
4060 format %{ "[$reg]" %}
4061 interface(MEMORY_INTER) %{
4062 base(0x4); // RSP
4063 index(0x4); // No Index
4064 scale(0x0); // No Scale
4065 disp($reg); // Stack Offset
4066 %}
4067 %}
4068
4069 operand stackSlotF(sRegF reg)
4070 %{
4071 constraint(ALLOC_IN_RC(stack_slots));
4072 // No match rule because this operand is only generated in matching
4073
4074 format %{ "[$reg]" %}
4075 interface(MEMORY_INTER) %{
4076 base(0x4); // RSP
4077 index(0x4); // No Index
4078 scale(0x0); // No Scale
4079 disp($reg); // Stack Offset
4080 %}
4081 %}
4082
4083 operand stackSlotD(sRegD reg)
4084 %{
4085 constraint(ALLOC_IN_RC(stack_slots));
4086 // No match rule because this operand is only generated in matching
4087
4088 format %{ "[$reg]" %}
4089 interface(MEMORY_INTER) %{
4090 base(0x4); // RSP
4091 index(0x4); // No Index
4092 scale(0x0); // No Scale
4093 disp($reg); // Stack Offset
4094 %}
4095 %}
4096 operand stackSlotL(sRegL reg)
4097 %{
4098 constraint(ALLOC_IN_RC(stack_slots));
4099 // No match rule because this operand is only generated in matching
4100
4101 format %{ "[$reg]" %}
4102 interface(MEMORY_INTER) %{
4103 base(0x4); // RSP
4104 index(0x4); // No Index
4105 scale(0x0); // No Scale
4106 disp($reg); // Stack Offset
4107 %}
4108 %}
4109
4110 //----------Conditional Branch Operands----------------------------------------
4111 // Comparison Op - This is the operation of the comparison, and is limited to
4112 // the following set of codes:
4113 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
4114 //
4115 // Other attributes of the comparison, such as unsignedness, are specified
4116 // by the comparison instruction that sets a condition code flags register.
4117 // That result is represented by a flags operand whose subtype is appropriate
4118 // to the unsignedness (etc.) of the comparison.
4119 //
4120 // Later, the instruction which matches both the Comparison Op (a Bool) and
4121 // the flags (produced by the Cmp) specifies the coding of the comparison op
4122 // by matching a specific subtype of Bool operand below, such as cmpOpU.
4123
4124 // Comparision Code
4125 operand cmpOp()
4126 %{
4127 match(Bool);
4128
4129 format %{ "" %}
4130 interface(COND_INTER) %{
4131 equal(0x4, "e");
4132 not_equal(0x5, "ne");
4133 less(0xC, "l");
4134 greater_equal(0xD, "ge");
4135 less_equal(0xE, "le");
4136 greater(0xF, "g");
4137 overflow(0x0, "o");
4138 no_overflow(0x1, "no");
4139 %}
4140 %}
4141
4142 // Comparison Code, unsigned compare. Used by FP also, with
4143 // C2 (unordered) turned into GT or LT already. The other bits
4144 // C0 and C3 are turned into Carry & Zero flags.
4145 operand cmpOpU()
4146 %{
4147 match(Bool);
4148
4149 format %{ "" %}
4150 interface(COND_INTER) %{
4151 equal(0x4, "e");
4152 not_equal(0x5, "ne");
4153 less(0x2, "b");
4154 greater_equal(0x3, "nb");
4155 less_equal(0x6, "be");
4156 greater(0x7, "nbe");
4157 overflow(0x0, "o");
4158 no_overflow(0x1, "no");
4159 %}
4160 %}
4161
4162
4163 // Floating comparisons that don't require any fixup for the unordered case
4164 operand cmpOpUCF() %{
4165 match(Bool);
4166 predicate(n->as_Bool()->_test._test == BoolTest::lt ||
4167 n->as_Bool()->_test._test == BoolTest::ge ||
4168 n->as_Bool()->_test._test == BoolTest::le ||
4169 n->as_Bool()->_test._test == BoolTest::gt);
4170 format %{ "" %}
4171 interface(COND_INTER) %{
4172 equal(0x4, "e");
4173 not_equal(0x5, "ne");
4174 less(0x2, "b");
4175 greater_equal(0x3, "nb");
4176 less_equal(0x6, "be");
4177 greater(0x7, "nbe");
4178 overflow(0x0, "o");
4179 no_overflow(0x1, "no");
4180 %}
4181 %}
4182
4183
4184 // Floating comparisons that can be fixed up with extra conditional jumps
4185 operand cmpOpUCF2() %{
4186 match(Bool);
4187 predicate(n->as_Bool()->_test._test == BoolTest::ne ||
4188 n->as_Bool()->_test._test == BoolTest::eq);
4189 format %{ "" %}
4190 interface(COND_INTER) %{
4191 equal(0x4, "e");
4192 not_equal(0x5, "ne");
4193 less(0x2, "b");
4194 greater_equal(0x3, "nb");
4195 less_equal(0x6, "be");
4196 greater(0x7, "nbe");
4197 overflow(0x0, "o");
4198 no_overflow(0x1, "no");
4199 %}
4200 %}
4201
4202 //----------OPERAND CLASSES----------------------------------------------------
4203 // Operand Classes are groups of operands that are used as to simplify
4204 // instruction definitions by not requiring the AD writer to specify separate
4205 // instructions for every form of operand when the instruction accepts
4206 // multiple operand types with the same basic encoding and format. The classic
4207 // case of this is memory operands.
4208
4209 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
4210 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset,
4211 indCompressedOop, indCompressedOopOffset,
4212 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
4213 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
4214 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow);
4215
4216 //----------PIPELINE-----------------------------------------------------------
4217 // Rules which define the behavior of the target architectures pipeline.
4218 pipeline %{
4219
4220 //----------ATTRIBUTES---------------------------------------------------------
4221 attributes %{
4222 variable_size_instructions; // Fixed size instructions
4223 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
4224 instruction_unit_size = 1; // An instruction is 1 bytes long
4225 instruction_fetch_unit_size = 16; // The processor fetches one line
4226 instruction_fetch_units = 1; // of 16 bytes
4227
4228 // List of nop instructions
4229 nops( MachNop );
4230 %}
4231
4232 //----------RESOURCES----------------------------------------------------------
4233 // Resources are the functional units available to the machine
4234
4235 // Generic P2/P3 pipeline
4236 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of
4237 // 3 instructions decoded per cycle.
4238 // 2 load/store ops per cycle, 1 branch, 1 FPU,
4239 // 3 ALU op, only ALU0 handles mul instructions.
4240 resources( D0, D1, D2, DECODE = D0 | D1 | D2,
4241 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2,
4242 BR, FPU,
4243 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2);
4244
4245 //----------PIPELINE DESCRIPTION-----------------------------------------------
4246 // Pipeline Description specifies the stages in the machine's pipeline
4247
4248 // Generic P2/P3 pipeline
4249 pipe_desc(S0, S1, S2, S3, S4, S5);
4250
4251 //----------PIPELINE CLASSES---------------------------------------------------
4252 // Pipeline Classes describe the stages in which input and output are
4253 // referenced by the hardware pipeline.
4254
4255 // Naming convention: ialu or fpu
4256 // Then: _reg
4257 // Then: _reg if there is a 2nd register
4258 // Then: _long if it's a pair of instructions implementing a long
4259 // Then: _fat if it requires the big decoder
4260 // Or: _mem if it requires the big decoder and a memory unit.
4261
4262 // Integer ALU reg operation
4263 pipe_class ialu_reg(rRegI dst)
4264 %{
4265 single_instruction;
4266 dst : S4(write);
4267 dst : S3(read);
4268 DECODE : S0; // any decoder
4269 ALU : S3; // any alu
4270 %}
4271
4272 // Long ALU reg operation
4273 pipe_class ialu_reg_long(rRegL dst)
4274 %{
4275 instruction_count(2);
4276 dst : S4(write);
4277 dst : S3(read);
4278 DECODE : S0(2); // any 2 decoders
4279 ALU : S3(2); // both alus
4280 %}
4281
4282 // Integer ALU reg operation using big decoder
4283 pipe_class ialu_reg_fat(rRegI dst)
4284 %{
4285 single_instruction;
4286 dst : S4(write);
4287 dst : S3(read);
4288 D0 : S0; // big decoder only
4289 ALU : S3; // any alu
4290 %}
4291
4292 // Long ALU reg operation using big decoder
4293 pipe_class ialu_reg_long_fat(rRegL dst)
4294 %{
4295 instruction_count(2);
4296 dst : S4(write);
4297 dst : S3(read);
4298 D0 : S0(2); // big decoder only; twice
4299 ALU : S3(2); // any 2 alus
4300 %}
4301
4302 // Integer ALU reg-reg operation
4303 pipe_class ialu_reg_reg(rRegI dst, rRegI src)
4304 %{
4305 single_instruction;
4306 dst : S4(write);
4307 src : S3(read);
4308 DECODE : S0; // any decoder
4309 ALU : S3; // any alu
4310 %}
4311
4312 // Long ALU reg-reg operation
4313 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src)
4314 %{
4315 instruction_count(2);
4316 dst : S4(write);
4317 src : S3(read);
4318 DECODE : S0(2); // any 2 decoders
4319 ALU : S3(2); // both alus
4320 %}
4321
4322 // Integer ALU reg-reg operation
4323 pipe_class ialu_reg_reg_fat(rRegI dst, memory src)
4324 %{
4325 single_instruction;
4326 dst : S4(write);
4327 src : S3(read);
4328 D0 : S0; // big decoder only
4329 ALU : S3; // any alu
4330 %}
4331
4332 // Long ALU reg-reg operation
4333 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src)
4334 %{
4335 instruction_count(2);
4336 dst : S4(write);
4337 src : S3(read);
4338 D0 : S0(2); // big decoder only; twice
4339 ALU : S3(2); // both alus
4340 %}
4341
4342 // Integer ALU reg-mem operation
4343 pipe_class ialu_reg_mem(rRegI dst, memory mem)
4344 %{
4345 single_instruction;
4346 dst : S5(write);
4347 mem : S3(read);
4348 D0 : S0; // big decoder only
4349 ALU : S4; // any alu
4350 MEM : S3; // any mem
4351 %}
4352
4353 // Integer mem operation (prefetch)
4354 pipe_class ialu_mem(memory mem)
4355 %{
4356 single_instruction;
4357 mem : S3(read);
4358 D0 : S0; // big decoder only
4359 MEM : S3; // any mem
4360 %}
4361
4362 // Integer Store to Memory
4363 pipe_class ialu_mem_reg(memory mem, rRegI src)
4364 %{
4365 single_instruction;
4366 mem : S3(read);
4367 src : S5(read);
4368 D0 : S0; // big decoder only
4369 ALU : S4; // any alu
4370 MEM : S3;
4371 %}
4372
4373 // // Long Store to Memory
4374 // pipe_class ialu_mem_long_reg(memory mem, rRegL src)
4375 // %{
4376 // instruction_count(2);
4377 // mem : S3(read);
4378 // src : S5(read);
4379 // D0 : S0(2); // big decoder only; twice
4380 // ALU : S4(2); // any 2 alus
4381 // MEM : S3(2); // Both mems
4382 // %}
4383
4384 // Integer Store to Memory
4385 pipe_class ialu_mem_imm(memory mem)
4386 %{
4387 single_instruction;
4388 mem : S3(read);
4389 D0 : S0; // big decoder only
4390 ALU : S4; // any alu
4391 MEM : S3;
4392 %}
4393
4394 // Integer ALU0 reg-reg operation
4395 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src)
4396 %{
4397 single_instruction;
4398 dst : S4(write);
4399 src : S3(read);
4400 D0 : S0; // Big decoder only
4401 ALU0 : S3; // only alu0
4402 %}
4403
4404 // Integer ALU0 reg-mem operation
4405 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem)
4406 %{
4407 single_instruction;
4408 dst : S5(write);
4409 mem : S3(read);
4410 D0 : S0; // big decoder only
4411 ALU0 : S4; // ALU0 only
4412 MEM : S3; // any mem
4413 %}
4414
4415 // Integer ALU reg-reg operation
4416 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2)
4417 %{
4418 single_instruction;
4419 cr : S4(write);
4420 src1 : S3(read);
4421 src2 : S3(read);
4422 DECODE : S0; // any decoder
4423 ALU : S3; // any alu
4424 %}
4425
4426 // Integer ALU reg-imm operation
4427 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1)
4428 %{
4429 single_instruction;
4430 cr : S4(write);
4431 src1 : S3(read);
4432 DECODE : S0; // any decoder
4433 ALU : S3; // any alu
4434 %}
4435
4436 // Integer ALU reg-mem operation
4437 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2)
4438 %{
4439 single_instruction;
4440 cr : S4(write);
4441 src1 : S3(read);
4442 src2 : S3(read);
4443 D0 : S0; // big decoder only
4444 ALU : S4; // any alu
4445 MEM : S3;
4446 %}
4447
4448 // Conditional move reg-reg
4449 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y)
4450 %{
4451 instruction_count(4);
4452 y : S4(read);
4453 q : S3(read);
4454 p : S3(read);
4455 DECODE : S0(4); // any decoder
4456 %}
4457
4458 // Conditional move reg-reg
4459 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr)
4460 %{
4461 single_instruction;
4462 dst : S4(write);
4463 src : S3(read);
4464 cr : S3(read);
4465 DECODE : S0; // any decoder
4466 %}
4467
4468 // Conditional move reg-mem
4469 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src)
4470 %{
4471 single_instruction;
4472 dst : S4(write);
4473 src : S3(read);
4474 cr : S3(read);
4475 DECODE : S0; // any decoder
4476 MEM : S3;
4477 %}
4478
4479 // Conditional move reg-reg long
4480 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src)
4481 %{
4482 single_instruction;
4483 dst : S4(write);
4484 src : S3(read);
4485 cr : S3(read);
4486 DECODE : S0(2); // any 2 decoders
4487 %}
4488
4489 // XXX
4490 // // Conditional move double reg-reg
4491 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src)
4492 // %{
4493 // single_instruction;
4494 // dst : S4(write);
4495 // src : S3(read);
4496 // cr : S3(read);
4497 // DECODE : S0; // any decoder
4498 // %}
4499
4500 // Float reg-reg operation
4501 pipe_class fpu_reg(regD dst)
4502 %{
4503 instruction_count(2);
4504 dst : S3(read);
4505 DECODE : S0(2); // any 2 decoders
4506 FPU : S3;
4507 %}
4508
4509 // Float reg-reg operation
4510 pipe_class fpu_reg_reg(regD dst, regD src)
4511 %{
4512 instruction_count(2);
4513 dst : S4(write);
4514 src : S3(read);
4515 DECODE : S0(2); // any 2 decoders
4516 FPU : S3;
4517 %}
4518
4519 // Float reg-reg operation
4520 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2)
4521 %{
4522 instruction_count(3);
4523 dst : S4(write);
4524 src1 : S3(read);
4525 src2 : S3(read);
4526 DECODE : S0(3); // any 3 decoders
4527 FPU : S3(2);
4528 %}
4529
4530 // Float reg-reg operation
4531 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3)
4532 %{
4533 instruction_count(4);
4534 dst : S4(write);
4535 src1 : S3(read);
4536 src2 : S3(read);
4537 src3 : S3(read);
4538 DECODE : S0(4); // any 3 decoders
4539 FPU : S3(2);
4540 %}
4541
4542 // Float reg-reg operation
4543 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3)
4544 %{
4545 instruction_count(4);
4546 dst : S4(write);
4547 src1 : S3(read);
4548 src2 : S3(read);
4549 src3 : S3(read);
4550 DECODE : S1(3); // any 3 decoders
4551 D0 : S0; // Big decoder only
4552 FPU : S3(2);
4553 MEM : S3;
4554 %}
4555
4556 // Float reg-mem operation
4557 pipe_class fpu_reg_mem(regD dst, memory mem)
4558 %{
4559 instruction_count(2);
4560 dst : S5(write);
4561 mem : S3(read);
4562 D0 : S0; // big decoder only
4563 DECODE : S1; // any decoder for FPU POP
4564 FPU : S4;
4565 MEM : S3; // any mem
4566 %}
4567
4568 // Float reg-mem operation
4569 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem)
4570 %{
4571 instruction_count(3);
4572 dst : S5(write);
4573 src1 : S3(read);
4574 mem : S3(read);
4575 D0 : S0; // big decoder only
4576 DECODE : S1(2); // any decoder for FPU POP
4577 FPU : S4;
4578 MEM : S3; // any mem
4579 %}
4580
4581 // Float mem-reg operation
4582 pipe_class fpu_mem_reg(memory mem, regD src)
4583 %{
4584 instruction_count(2);
4585 src : S5(read);
4586 mem : S3(read);
4587 DECODE : S0; // any decoder for FPU PUSH
4588 D0 : S1; // big decoder only
4589 FPU : S4;
4590 MEM : S3; // any mem
4591 %}
4592
4593 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2)
4594 %{
4595 instruction_count(3);
4596 src1 : S3(read);
4597 src2 : S3(read);
4598 mem : S3(read);
4599 DECODE : S0(2); // any decoder for FPU PUSH
4600 D0 : S1; // big decoder only
4601 FPU : S4;
4602 MEM : S3; // any mem
4603 %}
4604
4605 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2)
4606 %{
4607 instruction_count(3);
4608 src1 : S3(read);
4609 src2 : S3(read);
4610 mem : S4(read);
4611 DECODE : S0; // any decoder for FPU PUSH
4612 D0 : S0(2); // big decoder only
4613 FPU : S4;
4614 MEM : S3(2); // any mem
4615 %}
4616
4617 pipe_class fpu_mem_mem(memory dst, memory src1)
4618 %{
4619 instruction_count(2);
4620 src1 : S3(read);
4621 dst : S4(read);
4622 D0 : S0(2); // big decoder only
4623 MEM : S3(2); // any mem
4624 %}
4625
4626 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2)
4627 %{
4628 instruction_count(3);
4629 src1 : S3(read);
4630 src2 : S3(read);
4631 dst : S4(read);
4632 D0 : S0(3); // big decoder only
4633 FPU : S4;
4634 MEM : S3(3); // any mem
4635 %}
4636
4637 pipe_class fpu_mem_reg_con(memory mem, regD src1)
4638 %{
4639 instruction_count(3);
4640 src1 : S4(read);
4641 mem : S4(read);
4642 DECODE : S0; // any decoder for FPU PUSH
4643 D0 : S0(2); // big decoder only
4644 FPU : S4;
4645 MEM : S3(2); // any mem
4646 %}
4647
4648 // Float load constant
4649 pipe_class fpu_reg_con(regD dst)
4650 %{
4651 instruction_count(2);
4652 dst : S5(write);
4653 D0 : S0; // big decoder only for the load
4654 DECODE : S1; // any decoder for FPU POP
4655 FPU : S4;
4656 MEM : S3; // any mem
4657 %}
4658
4659 // Float load constant
4660 pipe_class fpu_reg_reg_con(regD dst, regD src)
4661 %{
4662 instruction_count(3);
4663 dst : S5(write);
4664 src : S3(read);
4665 D0 : S0; // big decoder only for the load
4666 DECODE : S1(2); // any decoder for FPU POP
4667 FPU : S4;
4668 MEM : S3; // any mem
4669 %}
4670
4671 // UnConditional branch
4672 pipe_class pipe_jmp(label labl)
4673 %{
4674 single_instruction;
4675 BR : S3;
4676 %}
4677
4678 // Conditional branch
4679 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl)
4680 %{
4681 single_instruction;
4682 cr : S1(read);
4683 BR : S3;
4684 %}
4685
4686 // Allocation idiom
4687 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr)
4688 %{
4689 instruction_count(1); force_serialization;
4690 fixed_latency(6);
4691 heap_ptr : S3(read);
4692 DECODE : S0(3);
4693 D0 : S2;
4694 MEM : S3;
4695 ALU : S3(2);
4696 dst : S5(write);
4697 BR : S5;
4698 %}
4699
4700 // Generic big/slow expanded idiom
4701 pipe_class pipe_slow()
4702 %{
4703 instruction_count(10); multiple_bundles; force_serialization;
4704 fixed_latency(100);
4705 D0 : S0(2);
4706 MEM : S3(2);
4707 %}
4708
4709 // The real do-nothing guy
4710 pipe_class empty()
4711 %{
4712 instruction_count(0);
4713 %}
4714
4715 // Define the class for the Nop node
4716 define
4717 %{
4718 MachNop = empty;
4719 %}
4720
4721 %}
4722
4723 //----------INSTRUCTIONS-------------------------------------------------------
4724 //
4725 // match -- States which machine-independent subtree may be replaced
4726 // by this instruction.
4727 // ins_cost -- The estimated cost of this instruction is used by instruction
4728 // selection to identify a minimum cost tree of machine
4729 // instructions that matches a tree of machine-independent
4730 // instructions.
4731 // format -- A string providing the disassembly for this instruction.
4732 // The value of an instruction's operand may be inserted
4733 // by referring to it with a '$' prefix.
4734 // opcode -- Three instruction opcodes may be provided. These are referred
4735 // to within an encode class as $primary, $secondary, and $tertiary
4736 // rrspectively. The primary opcode is commonly used to
4737 // indicate the type of machine instruction, while secondary
4738 // and tertiary are often used for prefix options or addressing
4739 // modes.
4740 // ins_encode -- A list of encode classes with parameters. The encode class
4741 // name must have been defined in an 'enc_class' specification
4742 // in the encode section of the architecture description.
4743
4744
4745 //----------Load/Store/Move Instructions---------------------------------------
4746 //----------Load Instructions--------------------------------------------------
4747
4748 // Load Byte (8 bit signed)
4749 instruct loadB(rRegI dst, memory mem)
4750 %{
4751 match(Set dst (LoadB mem));
4752
4753 ins_cost(125);
4754 format %{ "movsbl $dst, $mem\t# byte" %}
4755
4756 ins_encode %{
4757 __ movsbl($dst$$Register, $mem$$Address);
4758 %}
4759
4760 ins_pipe(ialu_reg_mem);
4761 %}
4762
4763 // Load Byte (8 bit signed) into Long Register
4764 instruct loadB2L(rRegL dst, memory mem)
4765 %{
4766 match(Set dst (ConvI2L (LoadB mem)));
4767
4768 ins_cost(125);
4769 format %{ "movsbq $dst, $mem\t# byte -> long" %}
4770
4771 ins_encode %{
4772 __ movsbq($dst$$Register, $mem$$Address);
4773 %}
4774
4775 ins_pipe(ialu_reg_mem);
4776 %}
4777
4778 // Load Unsigned Byte (8 bit UNsigned)
4779 instruct loadUB(rRegI dst, memory mem)
4780 %{
4781 match(Set dst (LoadUB mem));
4782
4783 ins_cost(125);
4784 format %{ "movzbl $dst, $mem\t# ubyte" %}
4785
4786 ins_encode %{
4787 __ movzbl($dst$$Register, $mem$$Address);
4788 %}
4789
4790 ins_pipe(ialu_reg_mem);
4791 %}
4792
4793 // Load Unsigned Byte (8 bit UNsigned) into Long Register
4794 instruct loadUB2L(rRegL dst, memory mem)
4795 %{
4796 match(Set dst (ConvI2L (LoadUB mem)));
4797
4798 ins_cost(125);
4799 format %{ "movzbq $dst, $mem\t# ubyte -> long" %}
4800
4801 ins_encode %{
4802 __ movzbq($dst$$Register, $mem$$Address);
4803 %}
4804
4805 ins_pipe(ialu_reg_mem);
4806 %}
4807
4808 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register
4809 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
4810 match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
4811 effect(KILL cr);
4812
4813 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t"
4814 "andl $dst, right_n_bits($mask, 8)" %}
4815 ins_encode %{
4816 Register Rdst = $dst$$Register;
4817 __ movzbq(Rdst, $mem$$Address);
4818 __ andl(Rdst, $mask$$constant & right_n_bits(8));
4819 %}
4820 ins_pipe(ialu_reg_mem);
4821 %}
4822
4823 // Load Short (16 bit signed)
4824 instruct loadS(rRegI dst, memory mem)
4825 %{
4826 match(Set dst (LoadS mem));
4827
4828 ins_cost(125);
4829 format %{ "movswl $dst, $mem\t# short" %}
4830
4831 ins_encode %{
4832 __ movswl($dst$$Register, $mem$$Address);
4833 %}
4834
4835 ins_pipe(ialu_reg_mem);
4836 %}
4837
4838 // Load Short (16 bit signed) to Byte (8 bit signed)
4839 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4840 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
4841
4842 ins_cost(125);
4843 format %{ "movsbl $dst, $mem\t# short -> byte" %}
4844 ins_encode %{
4845 __ movsbl($dst$$Register, $mem$$Address);
4846 %}
4847 ins_pipe(ialu_reg_mem);
4848 %}
4849
4850 // Load Short (16 bit signed) into Long Register
4851 instruct loadS2L(rRegL dst, memory mem)
4852 %{
4853 match(Set dst (ConvI2L (LoadS mem)));
4854
4855 ins_cost(125);
4856 format %{ "movswq $dst, $mem\t# short -> long" %}
4857
4858 ins_encode %{
4859 __ movswq($dst$$Register, $mem$$Address);
4860 %}
4861
4862 ins_pipe(ialu_reg_mem);
4863 %}
4864
4865 // Load Unsigned Short/Char (16 bit UNsigned)
4866 instruct loadUS(rRegI dst, memory mem)
4867 %{
4868 match(Set dst (LoadUS mem));
4869
4870 ins_cost(125);
4871 format %{ "movzwl $dst, $mem\t# ushort/char" %}
4872
4873 ins_encode %{
4874 __ movzwl($dst$$Register, $mem$$Address);
4875 %}
4876
4877 ins_pipe(ialu_reg_mem);
4878 %}
4879
4880 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
4881 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4882 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
4883
4884 ins_cost(125);
4885 format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
4886 ins_encode %{
4887 __ movsbl($dst$$Register, $mem$$Address);
4888 %}
4889 ins_pipe(ialu_reg_mem);
4890 %}
4891
4892 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
4893 instruct loadUS2L(rRegL dst, memory mem)
4894 %{
4895 match(Set dst (ConvI2L (LoadUS mem)));
4896
4897 ins_cost(125);
4898 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %}
4899
4900 ins_encode %{
4901 __ movzwq($dst$$Register, $mem$$Address);
4902 %}
4903
4904 ins_pipe(ialu_reg_mem);
4905 %}
4906
4907 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register
4908 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
4909 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4910
4911 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %}
4912 ins_encode %{
4913 __ movzbq($dst$$Register, $mem$$Address);
4914 %}
4915 ins_pipe(ialu_reg_mem);
4916 %}
4917
4918 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register
4919 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
4920 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4921 effect(KILL cr);
4922
4923 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t"
4924 "andl $dst, right_n_bits($mask, 16)" %}
4925 ins_encode %{
4926 Register Rdst = $dst$$Register;
4927 __ movzwq(Rdst, $mem$$Address);
4928 __ andl(Rdst, $mask$$constant & right_n_bits(16));
4929 %}
4930 ins_pipe(ialu_reg_mem);
4931 %}
4932
4933 // Load Integer
4934 instruct loadI(rRegI dst, memory mem)
4935 %{
4936 match(Set dst (LoadI mem));
4937
4938 ins_cost(125);
4939 format %{ "movl $dst, $mem\t# int" %}
4940
4941 ins_encode %{
4942 __ movl($dst$$Register, $mem$$Address);
4943 %}
4944
4945 ins_pipe(ialu_reg_mem);
4946 %}
4947
4948 // Load Integer (32 bit signed) to Byte (8 bit signed)
4949 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4950 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
4951
4952 ins_cost(125);
4953 format %{ "movsbl $dst, $mem\t# int -> byte" %}
4954 ins_encode %{
4955 __ movsbl($dst$$Register, $mem$$Address);
4956 %}
4957 ins_pipe(ialu_reg_mem);
4958 %}
4959
4960 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
4961 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
4962 match(Set dst (AndI (LoadI mem) mask));
4963
4964 ins_cost(125);
4965 format %{ "movzbl $dst, $mem\t# int -> ubyte" %}
4966 ins_encode %{
4967 __ movzbl($dst$$Register, $mem$$Address);
4968 %}
4969 ins_pipe(ialu_reg_mem);
4970 %}
4971
4972 // Load Integer (32 bit signed) to Short (16 bit signed)
4973 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
4974 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
4975
4976 ins_cost(125);
4977 format %{ "movswl $dst, $mem\t# int -> short" %}
4978 ins_encode %{
4979 __ movswl($dst$$Register, $mem$$Address);
4980 %}
4981 ins_pipe(ialu_reg_mem);
4982 %}
4983
4984 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
4985 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
4986 match(Set dst (AndI (LoadI mem) mask));
4987
4988 ins_cost(125);
4989 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %}
4990 ins_encode %{
4991 __ movzwl($dst$$Register, $mem$$Address);
4992 %}
4993 ins_pipe(ialu_reg_mem);
4994 %}
4995
4996 // Load Integer into Long Register
4997 instruct loadI2L(rRegL dst, memory mem)
4998 %{
4999 match(Set dst (ConvI2L (LoadI mem)));
5000
5001 ins_cost(125);
5002 format %{ "movslq $dst, $mem\t# int -> long" %}
5003
5004 ins_encode %{
5005 __ movslq($dst$$Register, $mem$$Address);
5006 %}
5007
5008 ins_pipe(ialu_reg_mem);
5009 %}
5010
5011 // Load Integer with mask 0xFF into Long Register
5012 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
5013 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5014
5015 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %}
5016 ins_encode %{
5017 __ movzbq($dst$$Register, $mem$$Address);
5018 %}
5019 ins_pipe(ialu_reg_mem);
5020 %}
5021
5022 // Load Integer with mask 0xFFFF into Long Register
5023 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{
5024 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5025
5026 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %}
5027 ins_encode %{
5028 __ movzwq($dst$$Register, $mem$$Address);
5029 %}
5030 ins_pipe(ialu_reg_mem);
5031 %}
5032
5033 // Load Integer with a 31-bit mask into Long Register
5034 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{
5035 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5036 effect(KILL cr);
5037
5038 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t"
5039 "andl $dst, $mask" %}
5040 ins_encode %{
5041 Register Rdst = $dst$$Register;
5042 __ movl(Rdst, $mem$$Address);
5043 __ andl(Rdst, $mask$$constant);
5044 %}
5045 ins_pipe(ialu_reg_mem);
5046 %}
5047
5048 // Load Unsigned Integer into Long Register
5049 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask)
5050 %{
5051 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5052
5053 ins_cost(125);
5054 format %{ "movl $dst, $mem\t# uint -> long" %}
5055
5056 ins_encode %{
5057 __ movl($dst$$Register, $mem$$Address);
5058 %}
5059
5060 ins_pipe(ialu_reg_mem);
5061 %}
5062
5063 // Load Long
5064 instruct loadL(rRegL dst, memory mem)
5065 %{
5066 match(Set dst (LoadL mem));
5067
5068 ins_cost(125);
5069 format %{ "movq $dst, $mem\t# long" %}
5070
5071 ins_encode %{
5072 __ movq($dst$$Register, $mem$$Address);
5073 %}
5074
5075 ins_pipe(ialu_reg_mem); // XXX
5076 %}
5077
5078 // Load Range
5079 instruct loadRange(rRegI dst, memory mem)
5080 %{
5081 match(Set dst (LoadRange mem));
5082
5083 ins_cost(125); // XXX
5084 format %{ "movl $dst, $mem\t# range" %}
5085 opcode(0x8B);
5086 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem));
5087 ins_pipe(ialu_reg_mem);
5088 %}
5089
5090 // Load Pointer
5091 instruct loadP(rRegP dst, memory mem)
5092 %{
5093 match(Set dst (LoadP mem));
5094 predicate(n->as_Load()->barrier_data() == 0);
5095
5096 ins_cost(125); // XXX
5097 format %{ "movq $dst, $mem\t# ptr" %}
5098 opcode(0x8B);
5099 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5100 ins_pipe(ialu_reg_mem); // XXX
5101 %}
5102
5103 // Load Compressed Pointer
5104 instruct loadN(rRegN dst, memory mem)
5105 %{
5106 match(Set dst (LoadN mem));
5107
5108 ins_cost(125); // XXX
5109 format %{ "movl $dst, $mem\t# compressed ptr" %}
5110 ins_encode %{
5111 __ movl($dst$$Register, $mem$$Address);
5112 %}
5113 ins_pipe(ialu_reg_mem); // XXX
5114 %}
5115
5116
5117 // Load Klass Pointer
5118 instruct loadKlass(rRegP dst, memory mem)
5119 %{
5120 match(Set dst (LoadKlass mem));
5121
5122 ins_cost(125); // XXX
5123 format %{ "movq $dst, $mem\t# class" %}
5124 opcode(0x8B);
5125 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5126 ins_pipe(ialu_reg_mem); // XXX
5127 %}
5128
5129 // Load narrow Klass Pointer
5130 instruct loadNKlass(rRegN dst, memory mem)
5131 %{
5132 match(Set dst (LoadNKlass mem));
5133
5134 ins_cost(125); // XXX
5135 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
5136 ins_encode %{
5137 __ movl($dst$$Register, $mem$$Address);
5138 %}
5139 ins_pipe(ialu_reg_mem); // XXX
5140 %}
5141
5142 // Load Float
5143 instruct loadF(regF dst, memory mem)
5144 %{
5145 match(Set dst (LoadF mem));
5146
5147 ins_cost(145); // XXX
5148 format %{ "movss $dst, $mem\t# float" %}
5149 ins_encode %{
5150 __ movflt($dst$$XMMRegister, $mem$$Address);
5151 %}
5152 ins_pipe(pipe_slow); // XXX
5153 %}
5154
5155 // Load Float
5156 instruct MoveF2VL(vlRegF dst, regF src) %{
5157 match(Set dst src);
5158 format %{ "movss $dst,$src\t! load float (4 bytes)" %}
5159 ins_encode %{
5160 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
5161 %}
5162 ins_pipe( fpu_reg_reg );
5163 %}
5164
5165 // Load Float
5166 instruct MoveF2LEG(legRegF dst, regF src) %{
5167 match(Set dst src);
5168 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %}
5169 ins_encode %{
5170 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
5171 %}
5172 ins_pipe( fpu_reg_reg );
5173 %}
5174
5175 // Load Float
5176 instruct MoveVL2F(regF dst, vlRegF src) %{
5177 match(Set dst src);
5178 format %{ "movss $dst,$src\t! load float (4 bytes)" %}
5179 ins_encode %{
5180 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
5181 %}
5182 ins_pipe( fpu_reg_reg );
5183 %}
5184
5185 // Load Float
5186 instruct MoveLEG2F(regF dst, legRegF src) %{
5187 match(Set dst src);
5188 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %}
5189 ins_encode %{
5190 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
5191 %}
5192 ins_pipe( fpu_reg_reg );
5193 %}
5194
5195 // Load Double
5196 instruct loadD_partial(regD dst, memory mem)
5197 %{
5198 predicate(!UseXmmLoadAndClearUpper);
5199 match(Set dst (LoadD mem));
5200
5201 ins_cost(145); // XXX
5202 format %{ "movlpd $dst, $mem\t# double" %}
5203 ins_encode %{
5204 __ movdbl($dst$$XMMRegister, $mem$$Address);
5205 %}
5206 ins_pipe(pipe_slow); // XXX
5207 %}
5208
5209 instruct loadD(regD dst, memory mem)
5210 %{
5211 predicate(UseXmmLoadAndClearUpper);
5212 match(Set dst (LoadD mem));
5213
5214 ins_cost(145); // XXX
5215 format %{ "movsd $dst, $mem\t# double" %}
5216 ins_encode %{
5217 __ movdbl($dst$$XMMRegister, $mem$$Address);
5218 %}
5219 ins_pipe(pipe_slow); // XXX
5220 %}
5221
5222 // Load Double
5223 instruct MoveD2VL(vlRegD dst, regD src) %{
5224 match(Set dst src);
5225 format %{ "movsd $dst,$src\t! load double (8 bytes)" %}
5226 ins_encode %{
5227 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
5228 %}
5229 ins_pipe( fpu_reg_reg );
5230 %}
5231
5232 // Load Double
5233 instruct MoveD2LEG(legRegD dst, regD src) %{
5234 match(Set dst src);
5235 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %}
5236 ins_encode %{
5237 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
5238 %}
5239 ins_pipe( fpu_reg_reg );
5240 %}
5241
5242 // Load Double
5243 instruct MoveVL2D(regD dst, vlRegD src) %{
5244 match(Set dst src);
5245 format %{ "movsd $dst,$src\t! load double (8 bytes)" %}
5246 ins_encode %{
5247 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
5248 %}
5249 ins_pipe( fpu_reg_reg );
5250 %}
5251
5252 // Load Double
5253 instruct MoveLEG2D(regD dst, legRegD src) %{
5254 match(Set dst src);
5255 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %}
5256 ins_encode %{
5257 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
5258 %}
5259 ins_pipe( fpu_reg_reg );
5260 %}
5261
5262 // Following pseudo code describes the algorithm for max[FD]:
5263 // Min algorithm is on similar lines
5264 // btmp = (b < +0.0) ? a : b
5265 // atmp = (b < +0.0) ? b : a
5266 // Tmp = Max_Float(atmp , btmp)
5267 // Res = (atmp == NaN) ? atmp : Tmp
5268
5269 // max = java.lang.Math.max(float a, float b)
5270 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{
5271 predicate(UseAVX > 0 && !n->is_reduction());
5272 match(Set dst (MaxF a b));
5273 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
5274 format %{
5275 "blendvps $btmp,$b,$a,$b \n\t"
5276 "blendvps $atmp,$a,$b,$b \n\t"
5277 "vmaxss $tmp,$atmp,$btmp \n\t"
5278 "cmpps.unordered $btmp,$atmp,$atmp \n\t"
5279 "blendvps $dst,$tmp,$atmp,$btmp \n\t"
5280 %}
5281 ins_encode %{
5282 int vector_len = Assembler::AVX_128bit;
5283 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len);
5284 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len);
5285 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister);
5286 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len);
5287 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len);
5288 %}
5289 ins_pipe( pipe_slow );
5290 %}
5291
5292 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{
5293 predicate(UseAVX > 0 && n->is_reduction());
5294 match(Set dst (MaxF a b));
5295 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
5296
5297 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %}
5298 ins_encode %{
5299 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register,
5300 false /*min*/, true /*single*/);
5301 %}
5302 ins_pipe( pipe_slow );
5303 %}
5304
5305 // max = java.lang.Math.max(double a, double b)
5306 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{
5307 predicate(UseAVX > 0 && !n->is_reduction());
5308 match(Set dst (MaxD a b));
5309 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp);
5310 format %{
5311 "blendvpd $btmp,$b,$a,$b \n\t"
5312 "blendvpd $atmp,$a,$b,$b \n\t"
5313 "vmaxsd $tmp,$atmp,$btmp \n\t"
5314 "cmppd.unordered $btmp,$atmp,$atmp \n\t"
5315 "blendvpd $dst,$tmp,$atmp,$btmp \n\t"
5316 %}
5317 ins_encode %{
5318 int vector_len = Assembler::AVX_128bit;
5319 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len);
5320 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len);
5321 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister);
5322 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len);
5323 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len);
5324 %}
5325 ins_pipe( pipe_slow );
5326 %}
5327
5328 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{
5329 predicate(UseAVX > 0 && n->is_reduction());
5330 match(Set dst (MaxD a b));
5331 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
5332
5333 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %}
5334 ins_encode %{
5335 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register,
5336 false /*min*/, false /*single*/);
5337 %}
5338 ins_pipe( pipe_slow );
5339 %}
5340
5341 // min = java.lang.Math.min(float a, float b)
5342 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{
5343 predicate(UseAVX > 0 && !n->is_reduction());
5344 match(Set dst (MinF a b));
5345 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
5346 format %{
5347 "blendvps $atmp,$a,$b,$a \n\t"
5348 "blendvps $btmp,$b,$a,$a \n\t"
5349 "vminss $tmp,$atmp,$btmp \n\t"
5350 "cmpps.unordered $btmp,$atmp,$atmp \n\t"
5351 "blendvps $dst,$tmp,$atmp,$btmp \n\t"
5352 %}
5353 ins_encode %{
5354 int vector_len = Assembler::AVX_128bit;
5355 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len);
5356 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len);
5357 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister);
5358 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len);
5359 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len);
5360 %}
5361 ins_pipe( pipe_slow );
5362 %}
5363
5364 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{
5365 predicate(UseAVX > 0 && n->is_reduction());
5366 match(Set dst (MinF a b));
5367 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
5368
5369 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %}
5370 ins_encode %{
5371 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register,
5372 true /*min*/, true /*single*/);
5373 %}
5374 ins_pipe( pipe_slow );
5375 %}
5376
5377 // min = java.lang.Math.min(double a, double b)
5378 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{
5379 predicate(UseAVX > 0 && !n->is_reduction());
5380 match(Set dst (MinD a b));
5381 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
5382 format %{
5383 "blendvpd $atmp,$a,$b,$a \n\t"
5384 "blendvpd $btmp,$b,$a,$a \n\t"
5385 "vminsd $tmp,$atmp,$btmp \n\t"
5386 "cmppd.unordered $btmp,$atmp,$atmp \n\t"
5387 "blendvpd $dst,$tmp,$atmp,$btmp \n\t"
5388 %}
5389 ins_encode %{
5390 int vector_len = Assembler::AVX_128bit;
5391 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len);
5392 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len);
5393 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister);
5394 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len);
5395 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len);
5396 %}
5397 ins_pipe( pipe_slow );
5398 %}
5399
5400 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{
5401 predicate(UseAVX > 0 && n->is_reduction());
5402 match(Set dst (MinD a b));
5403 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
5404
5405 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %}
5406 ins_encode %{
5407 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register,
5408 true /*min*/, false /*single*/);
5409 %}
5410 ins_pipe( pipe_slow );
5411 %}
5412
5413 // Load Effective Address
5414 instruct leaP8(rRegP dst, indOffset8 mem)
5415 %{
5416 match(Set dst mem);
5417
5418 ins_cost(110); // XXX
5419 format %{ "leaq $dst, $mem\t# ptr 8" %}
5420 opcode(0x8D);
5421 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5422 ins_pipe(ialu_reg_reg_fat);
5423 %}
5424
5425 instruct leaP32(rRegP dst, indOffset32 mem)
5426 %{
5427 match(Set dst mem);
5428
5429 ins_cost(110);
5430 format %{ "leaq $dst, $mem\t# ptr 32" %}
5431 opcode(0x8D);
5432 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5433 ins_pipe(ialu_reg_reg_fat);
5434 %}
5435
5436 // instruct leaPIdx(rRegP dst, indIndex mem)
5437 // %{
5438 // match(Set dst mem);
5439
5440 // ins_cost(110);
5441 // format %{ "leaq $dst, $mem\t# ptr idx" %}
5442 // opcode(0x8D);
5443 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5444 // ins_pipe(ialu_reg_reg_fat);
5445 // %}
5446
5447 instruct leaPIdxOff(rRegP dst, indIndexOffset mem)
5448 %{
5449 match(Set dst mem);
5450
5451 ins_cost(110);
5452 format %{ "leaq $dst, $mem\t# ptr idxoff" %}
5453 opcode(0x8D);
5454 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5455 ins_pipe(ialu_reg_reg_fat);
5456 %}
5457
5458 instruct leaPIdxScale(rRegP dst, indIndexScale mem)
5459 %{
5460 match(Set dst mem);
5461
5462 ins_cost(110);
5463 format %{ "leaq $dst, $mem\t# ptr idxscale" %}
5464 opcode(0x8D);
5465 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5466 ins_pipe(ialu_reg_reg_fat);
5467 %}
5468
5469 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem)
5470 %{
5471 match(Set dst mem);
5472
5473 ins_cost(110);
5474 format %{ "leaq $dst, $mem\t# ptr idxscale" %}
5475 opcode(0x8D);
5476 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5477 ins_pipe(ialu_reg_reg_fat);
5478 %}
5479
5480 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem)
5481 %{
5482 match(Set dst mem);
5483
5484 ins_cost(110);
5485 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %}
5486 opcode(0x8D);
5487 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5488 ins_pipe(ialu_reg_reg_fat);
5489 %}
5490
5491 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem)
5492 %{
5493 match(Set dst mem);
5494
5495 ins_cost(110);
5496 format %{ "leaq $dst, $mem\t# ptr posidxoff" %}
5497 opcode(0x8D);
5498 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5499 ins_pipe(ialu_reg_reg_fat);
5500 %}
5501
5502 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem)
5503 %{
5504 match(Set dst mem);
5505
5506 ins_cost(110);
5507 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %}
5508 opcode(0x8D);
5509 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5510 ins_pipe(ialu_reg_reg_fat);
5511 %}
5512
5513 // Load Effective Address which uses Narrow (32-bits) oop
5514 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem)
5515 %{
5516 predicate(UseCompressedOops && (CompressedOops::shift() != 0));
5517 match(Set dst mem);
5518
5519 ins_cost(110);
5520 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %}
5521 opcode(0x8D);
5522 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5523 ins_pipe(ialu_reg_reg_fat);
5524 %}
5525
5526 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem)
5527 %{
5528 predicate(CompressedOops::shift() == 0);
5529 match(Set dst mem);
5530
5531 ins_cost(110); // XXX
5532 format %{ "leaq $dst, $mem\t# ptr off8narrow" %}
5533 opcode(0x8D);
5534 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5535 ins_pipe(ialu_reg_reg_fat);
5536 %}
5537
5538 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem)
5539 %{
5540 predicate(CompressedOops::shift() == 0);
5541 match(Set dst mem);
5542
5543 ins_cost(110);
5544 format %{ "leaq $dst, $mem\t# ptr off32narrow" %}
5545 opcode(0x8D);
5546 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5547 ins_pipe(ialu_reg_reg_fat);
5548 %}
5549
5550 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem)
5551 %{
5552 predicate(CompressedOops::shift() == 0);
5553 match(Set dst mem);
5554
5555 ins_cost(110);
5556 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %}
5557 opcode(0x8D);
5558 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5559 ins_pipe(ialu_reg_reg_fat);
5560 %}
5561
5562 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem)
5563 %{
5564 predicate(CompressedOops::shift() == 0);
5565 match(Set dst mem);
5566
5567 ins_cost(110);
5568 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %}
5569 opcode(0x8D);
5570 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5571 ins_pipe(ialu_reg_reg_fat);
5572 %}
5573
5574 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem)
5575 %{
5576 predicate(CompressedOops::shift() == 0);
5577 match(Set dst mem);
5578
5579 ins_cost(110);
5580 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %}
5581 opcode(0x8D);
5582 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5583 ins_pipe(ialu_reg_reg_fat);
5584 %}
5585
5586 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem)
5587 %{
5588 predicate(CompressedOops::shift() == 0);
5589 match(Set dst mem);
5590
5591 ins_cost(110);
5592 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %}
5593 opcode(0x8D);
5594 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5595 ins_pipe(ialu_reg_reg_fat);
5596 %}
5597
5598 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem)
5599 %{
5600 predicate(CompressedOops::shift() == 0);
5601 match(Set dst mem);
5602
5603 ins_cost(110);
5604 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %}
5605 opcode(0x8D);
5606 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5607 ins_pipe(ialu_reg_reg_fat);
5608 %}
5609
5610 instruct loadConI(rRegI dst, immI src)
5611 %{
5612 match(Set dst src);
5613
5614 format %{ "movl $dst, $src\t# int" %}
5615 ins_encode(load_immI(dst, src));
5616 ins_pipe(ialu_reg_fat); // XXX
5617 %}
5618
5619 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr)
5620 %{
5621 match(Set dst src);
5622 effect(KILL cr);
5623
5624 ins_cost(50);
5625 format %{ "xorl $dst, $dst\t# int" %}
5626 opcode(0x33); /* + rd */
5627 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5628 ins_pipe(ialu_reg);
5629 %}
5630
5631 instruct loadConL(rRegL dst, immL src)
5632 %{
5633 match(Set dst src);
5634
5635 ins_cost(150);
5636 format %{ "movq $dst, $src\t# long" %}
5637 ins_encode(load_immL(dst, src));
5638 ins_pipe(ialu_reg);
5639 %}
5640
5641 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr)
5642 %{
5643 match(Set dst src);
5644 effect(KILL cr);
5645
5646 ins_cost(50);
5647 format %{ "xorl $dst, $dst\t# long" %}
5648 opcode(0x33); /* + rd */
5649 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5650 ins_pipe(ialu_reg); // XXX
5651 %}
5652
5653 instruct loadConUL32(rRegL dst, immUL32 src)
5654 %{
5655 match(Set dst src);
5656
5657 ins_cost(60);
5658 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %}
5659 ins_encode(load_immUL32(dst, src));
5660 ins_pipe(ialu_reg);
5661 %}
5662
5663 instruct loadConL32(rRegL dst, immL32 src)
5664 %{
5665 match(Set dst src);
5666
5667 ins_cost(70);
5668 format %{ "movq $dst, $src\t# long (32-bit)" %}
5669 ins_encode(load_immL32(dst, src));
5670 ins_pipe(ialu_reg);
5671 %}
5672
5673 instruct loadConP(rRegP dst, immP con) %{
5674 match(Set dst con);
5675
5676 format %{ "movq $dst, $con\t# ptr" %}
5677 ins_encode(load_immP(dst, con));
5678 ins_pipe(ialu_reg_fat); // XXX
5679 %}
5680
5681 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
5682 %{
5683 match(Set dst src);
5684 effect(KILL cr);
5685
5686 ins_cost(50);
5687 format %{ "xorl $dst, $dst\t# ptr" %}
5688 opcode(0x33); /* + rd */
5689 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5690 ins_pipe(ialu_reg);
5691 %}
5692
5693 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
5694 %{
5695 match(Set dst src);
5696 effect(KILL cr);
5697
5698 ins_cost(60);
5699 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %}
5700 ins_encode(load_immP31(dst, src));
5701 ins_pipe(ialu_reg);
5702 %}
5703
5704 instruct loadConF(regF dst, immF con) %{
5705 match(Set dst con);
5706 ins_cost(125);
5707 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
5708 ins_encode %{
5709 __ movflt($dst$$XMMRegister, $constantaddress($con));
5710 %}
5711 ins_pipe(pipe_slow);
5712 %}
5713
5714 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
5715 match(Set dst src);
5716 effect(KILL cr);
5717 format %{ "xorq $dst, $src\t# compressed NULL ptr" %}
5718 ins_encode %{
5719 __ xorq($dst$$Register, $dst$$Register);
5720 %}
5721 ins_pipe(ialu_reg);
5722 %}
5723
5724 instruct loadConN(rRegN dst, immN src) %{
5725 match(Set dst src);
5726
5727 ins_cost(125);
5728 format %{ "movl $dst, $src\t# compressed ptr" %}
5729 ins_encode %{
5730 address con = (address)$src$$constant;
5731 if (con == NULL) {
5732 ShouldNotReachHere();
5733 } else {
5734 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
5735 }
5736 %}
5737 ins_pipe(ialu_reg_fat); // XXX
5738 %}
5739
5740 instruct loadConNKlass(rRegN dst, immNKlass src) %{
5741 match(Set dst src);
5742
5743 ins_cost(125);
5744 format %{ "movl $dst, $src\t# compressed klass ptr" %}
5745 ins_encode %{
5746 address con = (address)$src$$constant;
5747 if (con == NULL) {
5748 ShouldNotReachHere();
5749 } else {
5750 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant);
5751 }
5752 %}
5753 ins_pipe(ialu_reg_fat); // XXX
5754 %}
5755
5756 instruct loadConF0(regF dst, immF0 src)
5757 %{
5758 match(Set dst src);
5759 ins_cost(100);
5760
5761 format %{ "xorps $dst, $dst\t# float 0.0" %}
5762 ins_encode %{
5763 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
5764 %}
5765 ins_pipe(pipe_slow);
5766 %}
5767
5768 // Use the same format since predicate() can not be used here.
5769 instruct loadConD(regD dst, immD con) %{
5770 match(Set dst con);
5771 ins_cost(125);
5772 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
5773 ins_encode %{
5774 __ movdbl($dst$$XMMRegister, $constantaddress($con));
5775 %}
5776 ins_pipe(pipe_slow);
5777 %}
5778
5779 instruct loadConD0(regD dst, immD0 src)
5780 %{
5781 match(Set dst src);
5782 ins_cost(100);
5783
5784 format %{ "xorpd $dst, $dst\t# double 0.0" %}
5785 ins_encode %{
5786 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
5787 %}
5788 ins_pipe(pipe_slow);
5789 %}
5790
5791 instruct loadSSI(rRegI dst, stackSlotI src)
5792 %{
5793 match(Set dst src);
5794
5795 ins_cost(125);
5796 format %{ "movl $dst, $src\t# int stk" %}
5797 opcode(0x8B);
5798 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
5799 ins_pipe(ialu_reg_mem);
5800 %}
5801
5802 instruct loadSSL(rRegL dst, stackSlotL src)
5803 %{
5804 match(Set dst src);
5805
5806 ins_cost(125);
5807 format %{ "movq $dst, $src\t# long stk" %}
5808 opcode(0x8B);
5809 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5810 ins_pipe(ialu_reg_mem);
5811 %}
5812
5813 instruct loadSSP(rRegP dst, stackSlotP src)
5814 %{
5815 match(Set dst src);
5816
5817 ins_cost(125);
5818 format %{ "movq $dst, $src\t# ptr stk" %}
5819 opcode(0x8B);
5820 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5821 ins_pipe(ialu_reg_mem);
5822 %}
5823
5824 instruct loadSSF(regF dst, stackSlotF src)
5825 %{
5826 match(Set dst src);
5827
5828 ins_cost(125);
5829 format %{ "movss $dst, $src\t# float stk" %}
5830 ins_encode %{
5831 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
5832 %}
5833 ins_pipe(pipe_slow); // XXX
5834 %}
5835
5836 // Use the same format since predicate() can not be used here.
5837 instruct loadSSD(regD dst, stackSlotD src)
5838 %{
5839 match(Set dst src);
5840
5841 ins_cost(125);
5842 format %{ "movsd $dst, $src\t# double stk" %}
5843 ins_encode %{
5844 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
5845 %}
5846 ins_pipe(pipe_slow); // XXX
5847 %}
5848
5849 // Prefetch instructions for allocation.
5850 // Must be safe to execute with invalid address (cannot fault).
5851
5852 instruct prefetchAlloc( memory mem ) %{
5853 predicate(AllocatePrefetchInstr==3);
5854 match(PrefetchAllocation mem);
5855 ins_cost(125);
5856
5857 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %}
5858 ins_encode %{
5859 __ prefetchw($mem$$Address);
5860 %}
5861 ins_pipe(ialu_mem);
5862 %}
5863
5864 instruct prefetchAllocNTA( memory mem ) %{
5865 predicate(AllocatePrefetchInstr==0);
5866 match(PrefetchAllocation mem);
5867 ins_cost(125);
5868
5869 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %}
5870 ins_encode %{
5871 __ prefetchnta($mem$$Address);
5872 %}
5873 ins_pipe(ialu_mem);
5874 %}
5875
5876 instruct prefetchAllocT0( memory mem ) %{
5877 predicate(AllocatePrefetchInstr==1);
5878 match(PrefetchAllocation mem);
5879 ins_cost(125);
5880
5881 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %}
5882 ins_encode %{
5883 __ prefetcht0($mem$$Address);
5884 %}
5885 ins_pipe(ialu_mem);
5886 %}
5887
5888 instruct prefetchAllocT2( memory mem ) %{
5889 predicate(AllocatePrefetchInstr==2);
5890 match(PrefetchAllocation mem);
5891 ins_cost(125);
5892
5893 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %}
5894 ins_encode %{
5895 __ prefetcht2($mem$$Address);
5896 %}
5897 ins_pipe(ialu_mem);
5898 %}
5899
5900 //----------Store Instructions-------------------------------------------------
5901
5902 // Store Byte
5903 instruct storeB(memory mem, rRegI src)
5904 %{
5905 match(Set mem (StoreB mem src));
5906
5907 ins_cost(125); // XXX
5908 format %{ "movb $mem, $src\t# byte" %}
5909 opcode(0x88);
5910 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem));
5911 ins_pipe(ialu_mem_reg);
5912 %}
5913
5914 // Store Char/Short
5915 instruct storeC(memory mem, rRegI src)
5916 %{
5917 match(Set mem (StoreC mem src));
5918
5919 ins_cost(125); // XXX
5920 format %{ "movw $mem, $src\t# char/short" %}
5921 opcode(0x89);
5922 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
5923 ins_pipe(ialu_mem_reg);
5924 %}
5925
5926 // Store Integer
5927 instruct storeI(memory mem, rRegI src)
5928 %{
5929 match(Set mem (StoreI mem src));
5930
5931 ins_cost(125); // XXX
5932 format %{ "movl $mem, $src\t# int" %}
5933 opcode(0x89);
5934 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
5935 ins_pipe(ialu_mem_reg);
5936 %}
5937
5938 // Store Long
5939 instruct storeL(memory mem, rRegL src)
5940 %{
5941 match(Set mem (StoreL mem src));
5942
5943 ins_cost(125); // XXX
5944 format %{ "movq $mem, $src\t# long" %}
5945 opcode(0x89);
5946 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5947 ins_pipe(ialu_mem_reg); // XXX
5948 %}
5949
5950 // Store Pointer
5951 instruct storeP(memory mem, any_RegP src)
5952 %{
5953 match(Set mem (StoreP mem src));
5954
5955 ins_cost(125); // XXX
5956 format %{ "movq $mem, $src\t# ptr" %}
5957 opcode(0x89);
5958 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5959 ins_pipe(ialu_mem_reg);
5960 %}
5961
5962 instruct storeImmP0(memory mem, immP0 zero)
5963 %{
5964 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
5965 match(Set mem (StoreP mem zero));
5966
5967 ins_cost(125); // XXX
5968 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
5969 ins_encode %{
5970 __ movq($mem$$Address, r12);
5971 %}
5972 ins_pipe(ialu_mem_reg);
5973 %}
5974
5975 // Store NULL Pointer, mark word, or other simple pointer constant.
5976 instruct storeImmP(memory mem, immP31 src)
5977 %{
5978 match(Set mem (StoreP mem src));
5979
5980 ins_cost(150); // XXX
5981 format %{ "movq $mem, $src\t# ptr" %}
5982 opcode(0xC7); /* C7 /0 */
5983 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5984 ins_pipe(ialu_mem_imm);
5985 %}
5986
5987 // Store Compressed Pointer
5988 instruct storeN(memory mem, rRegN src)
5989 %{
5990 match(Set mem (StoreN mem src));
5991
5992 ins_cost(125); // XXX
5993 format %{ "movl $mem, $src\t# compressed ptr" %}
5994 ins_encode %{
5995 __ movl($mem$$Address, $src$$Register);
5996 %}
5997 ins_pipe(ialu_mem_reg);
5998 %}
5999
6000 instruct storeNKlass(memory mem, rRegN src)
6001 %{
6002 match(Set mem (StoreNKlass mem src));
6003
6004 ins_cost(125); // XXX
6005 format %{ "movl $mem, $src\t# compressed klass ptr" %}
6006 ins_encode %{
6007 __ movl($mem$$Address, $src$$Register);
6008 %}
6009 ins_pipe(ialu_mem_reg);
6010 %}
6011
6012 instruct storeImmN0(memory mem, immN0 zero)
6013 %{
6014 predicate(CompressedOops::base() == NULL);
6015 match(Set mem (StoreN mem zero));
6016
6017 ins_cost(125); // XXX
6018 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
6019 ins_encode %{
6020 __ movl($mem$$Address, r12);
6021 %}
6022 ins_pipe(ialu_mem_reg);
6023 %}
6024
6025 instruct storeImmN(memory mem, immN src)
6026 %{
6027 match(Set mem (StoreN mem src));
6028
6029 ins_cost(150); // XXX
6030 format %{ "movl $mem, $src\t# compressed ptr" %}
6031 ins_encode %{
6032 address con = (address)$src$$constant;
6033 if (con == NULL) {
6034 __ movl($mem$$Address, (int32_t)0);
6035 } else {
6036 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant);
6037 }
6038 %}
6039 ins_pipe(ialu_mem_imm);
6040 %}
6041
6042 instruct storeImmNKlass(memory mem, immNKlass src)
6043 %{
6044 match(Set mem (StoreNKlass mem src));
6045
6046 ins_cost(150); // XXX
6047 format %{ "movl $mem, $src\t# compressed klass ptr" %}
6048 ins_encode %{
6049 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant);
6050 %}
6051 ins_pipe(ialu_mem_imm);
6052 %}
6053
6054 // Store Integer Immediate
6055 instruct storeImmI0(memory mem, immI0 zero)
6056 %{
6057 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6058 match(Set mem (StoreI mem zero));
6059
6060 ins_cost(125); // XXX
6061 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
6062 ins_encode %{
6063 __ movl($mem$$Address, r12);
6064 %}
6065 ins_pipe(ialu_mem_reg);
6066 %}
6067
6068 instruct storeImmI(memory mem, immI src)
6069 %{
6070 match(Set mem (StoreI mem src));
6071
6072 ins_cost(150);
6073 format %{ "movl $mem, $src\t# int" %}
6074 opcode(0xC7); /* C7 /0 */
6075 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6076 ins_pipe(ialu_mem_imm);
6077 %}
6078
6079 // Store Long Immediate
6080 instruct storeImmL0(memory mem, immL0 zero)
6081 %{
6082 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6083 match(Set mem (StoreL mem zero));
6084
6085 ins_cost(125); // XXX
6086 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
6087 ins_encode %{
6088 __ movq($mem$$Address, r12);
6089 %}
6090 ins_pipe(ialu_mem_reg);
6091 %}
6092
6093 instruct storeImmL(memory mem, immL32 src)
6094 %{
6095 match(Set mem (StoreL mem src));
6096
6097 ins_cost(150);
6098 format %{ "movq $mem, $src\t# long" %}
6099 opcode(0xC7); /* C7 /0 */
6100 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6101 ins_pipe(ialu_mem_imm);
6102 %}
6103
6104 // Store Short/Char Immediate
6105 instruct storeImmC0(memory mem, immI0 zero)
6106 %{
6107 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6108 match(Set mem (StoreC mem zero));
6109
6110 ins_cost(125); // XXX
6111 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
6112 ins_encode %{
6113 __ movw($mem$$Address, r12);
6114 %}
6115 ins_pipe(ialu_mem_reg);
6116 %}
6117
6118 instruct storeImmI16(memory mem, immI16 src)
6119 %{
6120 predicate(UseStoreImmI16);
6121 match(Set mem (StoreC mem src));
6122
6123 ins_cost(150);
6124 format %{ "movw $mem, $src\t# short/char" %}
6125 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */
6126 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src));
6127 ins_pipe(ialu_mem_imm);
6128 %}
6129
6130 // Store Byte Immediate
6131 instruct storeImmB0(memory mem, immI0 zero)
6132 %{
6133 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6134 match(Set mem (StoreB mem zero));
6135
6136 ins_cost(125); // XXX
6137 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
6138 ins_encode %{
6139 __ movb($mem$$Address, r12);
6140 %}
6141 ins_pipe(ialu_mem_reg);
6142 %}
6143
6144 instruct storeImmB(memory mem, immI8 src)
6145 %{
6146 match(Set mem (StoreB mem src));
6147
6148 ins_cost(150); // XXX
6149 format %{ "movb $mem, $src\t# byte" %}
6150 opcode(0xC6); /* C6 /0 */
6151 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6152 ins_pipe(ialu_mem_imm);
6153 %}
6154
6155 // Store CMS card-mark Immediate
6156 instruct storeImmCM0_reg(memory mem, immI0 zero)
6157 %{
6158 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6159 match(Set mem (StoreCM mem zero));
6160
6161 ins_cost(125); // XXX
6162 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
6163 ins_encode %{
6164 __ movb($mem$$Address, r12);
6165 %}
6166 ins_pipe(ialu_mem_reg);
6167 %}
6168
6169 instruct storeImmCM0(memory mem, immI0 src)
6170 %{
6171 match(Set mem (StoreCM mem src));
6172
6173 ins_cost(150); // XXX
6174 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
6175 opcode(0xC6); /* C6 /0 */
6176 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6177 ins_pipe(ialu_mem_imm);
6178 %}
6179
6180 // Store Float
6181 instruct storeF(memory mem, regF src)
6182 %{
6183 match(Set mem (StoreF mem src));
6184
6185 ins_cost(95); // XXX
6186 format %{ "movss $mem, $src\t# float" %}
6187 ins_encode %{
6188 __ movflt($mem$$Address, $src$$XMMRegister);
6189 %}
6190 ins_pipe(pipe_slow); // XXX
6191 %}
6192
6193 // Store immediate Float value (it is faster than store from XMM register)
6194 instruct storeF0(memory mem, immF0 zero)
6195 %{
6196 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6197 match(Set mem (StoreF mem zero));
6198
6199 ins_cost(25); // XXX
6200 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
6201 ins_encode %{
6202 __ movl($mem$$Address, r12);
6203 %}
6204 ins_pipe(ialu_mem_reg);
6205 %}
6206
6207 instruct storeF_imm(memory mem, immF src)
6208 %{
6209 match(Set mem (StoreF mem src));
6210
6211 ins_cost(50);
6212 format %{ "movl $mem, $src\t# float" %}
6213 opcode(0xC7); /* C7 /0 */
6214 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6215 ins_pipe(ialu_mem_imm);
6216 %}
6217
6218 // Store Double
6219 instruct storeD(memory mem, regD src)
6220 %{
6221 match(Set mem (StoreD mem src));
6222
6223 ins_cost(95); // XXX
6224 format %{ "movsd $mem, $src\t# double" %}
6225 ins_encode %{
6226 __ movdbl($mem$$Address, $src$$XMMRegister);
6227 %}
6228 ins_pipe(pipe_slow); // XXX
6229 %}
6230
6231 // Store immediate double 0.0 (it is faster than store from XMM register)
6232 instruct storeD0_imm(memory mem, immD0 src)
6233 %{
6234 predicate(!UseCompressedOops || (CompressedOops::base() != NULL));
6235 match(Set mem (StoreD mem src));
6236
6237 ins_cost(50);
6238 format %{ "movq $mem, $src\t# double 0." %}
6239 opcode(0xC7); /* C7 /0 */
6240 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6241 ins_pipe(ialu_mem_imm);
6242 %}
6243
6244 instruct storeD0(memory mem, immD0 zero)
6245 %{
6246 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6247 match(Set mem (StoreD mem zero));
6248
6249 ins_cost(25); // XXX
6250 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
6251 ins_encode %{
6252 __ movq($mem$$Address, r12);
6253 %}
6254 ins_pipe(ialu_mem_reg);
6255 %}
6256
6257 instruct storeSSI(stackSlotI dst, rRegI src)
6258 %{
6259 match(Set dst src);
6260
6261 ins_cost(100);
6262 format %{ "movl $dst, $src\t# int stk" %}
6263 opcode(0x89);
6264 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
6265 ins_pipe( ialu_mem_reg );
6266 %}
6267
6268 instruct storeSSL(stackSlotL dst, rRegL src)
6269 %{
6270 match(Set dst src);
6271
6272 ins_cost(100);
6273 format %{ "movq $dst, $src\t# long stk" %}
6274 opcode(0x89);
6275 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6276 ins_pipe(ialu_mem_reg);
6277 %}
6278
6279 instruct storeSSP(stackSlotP dst, rRegP src)
6280 %{
6281 match(Set dst src);
6282
6283 ins_cost(100);
6284 format %{ "movq $dst, $src\t# ptr stk" %}
6285 opcode(0x89);
6286 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6287 ins_pipe(ialu_mem_reg);
6288 %}
6289
6290 instruct storeSSF(stackSlotF dst, regF src)
6291 %{
6292 match(Set dst src);
6293
6294 ins_cost(95); // XXX
6295 format %{ "movss $dst, $src\t# float stk" %}
6296 ins_encode %{
6297 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
6298 %}
6299 ins_pipe(pipe_slow); // XXX
6300 %}
6301
6302 instruct storeSSD(stackSlotD dst, regD src)
6303 %{
6304 match(Set dst src);
6305
6306 ins_cost(95); // XXX
6307 format %{ "movsd $dst, $src\t# double stk" %}
6308 ins_encode %{
6309 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
6310 %}
6311 ins_pipe(pipe_slow); // XXX
6312 %}
6313
6314 instruct cacheWB(indirect addr)
6315 %{
6316 predicate(VM_Version::supports_data_cache_line_flush());
6317 match(CacheWB addr);
6318
6319 ins_cost(100);
6320 format %{"cache wb $addr" %}
6321 ins_encode %{
6322 assert($addr->index_position() < 0, "should be");
6323 assert($addr$$disp == 0, "should be");
6324 __ cache_wb(Address($addr$$base$$Register, 0));
6325 %}
6326 ins_pipe(pipe_slow); // XXX
6327 %}
6328
6329 instruct cacheWBPreSync()
6330 %{
6331 predicate(VM_Version::supports_data_cache_line_flush());
6332 match(CacheWBPreSync);
6333
6334 ins_cost(100);
6335 format %{"cache wb presync" %}
6336 ins_encode %{
6337 __ cache_wbsync(true);
6338 %}
6339 ins_pipe(pipe_slow); // XXX
6340 %}
6341
6342 instruct cacheWBPostSync()
6343 %{
6344 predicate(VM_Version::supports_data_cache_line_flush());
6345 match(CacheWBPostSync);
6346
6347 ins_cost(100);
6348 format %{"cache wb postsync" %}
6349 ins_encode %{
6350 __ cache_wbsync(false);
6351 %}
6352 ins_pipe(pipe_slow); // XXX
6353 %}
6354
6355 //----------BSWAP Instructions-------------------------------------------------
6356 instruct bytes_reverse_int(rRegI dst) %{
6357 match(Set dst (ReverseBytesI dst));
6358
6359 format %{ "bswapl $dst" %}
6360 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */
6361 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) );
6362 ins_pipe( ialu_reg );
6363 %}
6364
6365 instruct bytes_reverse_long(rRegL dst) %{
6366 match(Set dst (ReverseBytesL dst));
6367
6368 format %{ "bswapq $dst" %}
6369 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */
6370 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) );
6371 ins_pipe( ialu_reg);
6372 %}
6373
6374 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{
6375 match(Set dst (ReverseBytesUS dst));
6376 effect(KILL cr);
6377
6378 format %{ "bswapl $dst\n\t"
6379 "shrl $dst,16\n\t" %}
6380 ins_encode %{
6381 __ bswapl($dst$$Register);
6382 __ shrl($dst$$Register, 16);
6383 %}
6384 ins_pipe( ialu_reg );
6385 %}
6386
6387 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{
6388 match(Set dst (ReverseBytesS dst));
6389 effect(KILL cr);
6390
6391 format %{ "bswapl $dst\n\t"
6392 "sar $dst,16\n\t" %}
6393 ins_encode %{
6394 __ bswapl($dst$$Register);
6395 __ sarl($dst$$Register, 16);
6396 %}
6397 ins_pipe( ialu_reg );
6398 %}
6399
6400 //---------- Zeros Count Instructions ------------------------------------------
6401
6402 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6403 predicate(UseCountLeadingZerosInstruction);
6404 match(Set dst (CountLeadingZerosI src));
6405 effect(KILL cr);
6406
6407 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %}
6408 ins_encode %{
6409 __ lzcntl($dst$$Register, $src$$Register);
6410 %}
6411 ins_pipe(ialu_reg);
6412 %}
6413
6414 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{
6415 predicate(!UseCountLeadingZerosInstruction);
6416 match(Set dst (CountLeadingZerosI src));
6417 effect(KILL cr);
6418
6419 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t"
6420 "jnz skip\n\t"
6421 "movl $dst, -1\n"
6422 "skip:\n\t"
6423 "negl $dst\n\t"
6424 "addl $dst, 31" %}
6425 ins_encode %{
6426 Register Rdst = $dst$$Register;
6427 Register Rsrc = $src$$Register;
6428 Label skip;
6429 __ bsrl(Rdst, Rsrc);
6430 __ jccb(Assembler::notZero, skip);
6431 __ movl(Rdst, -1);
6432 __ bind(skip);
6433 __ negl(Rdst);
6434 __ addl(Rdst, BitsPerInt - 1);
6435 %}
6436 ins_pipe(ialu_reg);
6437 %}
6438
6439 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6440 predicate(UseCountLeadingZerosInstruction);
6441 match(Set dst (CountLeadingZerosL src));
6442 effect(KILL cr);
6443
6444 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %}
6445 ins_encode %{
6446 __ lzcntq($dst$$Register, $src$$Register);
6447 %}
6448 ins_pipe(ialu_reg);
6449 %}
6450
6451 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{
6452 predicate(!UseCountLeadingZerosInstruction);
6453 match(Set dst (CountLeadingZerosL src));
6454 effect(KILL cr);
6455
6456 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t"
6457 "jnz skip\n\t"
6458 "movl $dst, -1\n"
6459 "skip:\n\t"
6460 "negl $dst\n\t"
6461 "addl $dst, 63" %}
6462 ins_encode %{
6463 Register Rdst = $dst$$Register;
6464 Register Rsrc = $src$$Register;
6465 Label skip;
6466 __ bsrq(Rdst, Rsrc);
6467 __ jccb(Assembler::notZero, skip);
6468 __ movl(Rdst, -1);
6469 __ bind(skip);
6470 __ negl(Rdst);
6471 __ addl(Rdst, BitsPerLong - 1);
6472 %}
6473 ins_pipe(ialu_reg);
6474 %}
6475
6476 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6477 predicate(UseCountTrailingZerosInstruction);
6478 match(Set dst (CountTrailingZerosI src));
6479 effect(KILL cr);
6480
6481 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %}
6482 ins_encode %{
6483 __ tzcntl($dst$$Register, $src$$Register);
6484 %}
6485 ins_pipe(ialu_reg);
6486 %}
6487
6488 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{
6489 predicate(!UseCountTrailingZerosInstruction);
6490 match(Set dst (CountTrailingZerosI src));
6491 effect(KILL cr);
6492
6493 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t"
6494 "jnz done\n\t"
6495 "movl $dst, 32\n"
6496 "done:" %}
6497 ins_encode %{
6498 Register Rdst = $dst$$Register;
6499 Label done;
6500 __ bsfl(Rdst, $src$$Register);
6501 __ jccb(Assembler::notZero, done);
6502 __ movl(Rdst, BitsPerInt);
6503 __ bind(done);
6504 %}
6505 ins_pipe(ialu_reg);
6506 %}
6507
6508 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6509 predicate(UseCountTrailingZerosInstruction);
6510 match(Set dst (CountTrailingZerosL src));
6511 effect(KILL cr);
6512
6513 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %}
6514 ins_encode %{
6515 __ tzcntq($dst$$Register, $src$$Register);
6516 %}
6517 ins_pipe(ialu_reg);
6518 %}
6519
6520 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{
6521 predicate(!UseCountTrailingZerosInstruction);
6522 match(Set dst (CountTrailingZerosL src));
6523 effect(KILL cr);
6524
6525 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t"
6526 "jnz done\n\t"
6527 "movl $dst, 64\n"
6528 "done:" %}
6529 ins_encode %{
6530 Register Rdst = $dst$$Register;
6531 Label done;
6532 __ bsfq(Rdst, $src$$Register);
6533 __ jccb(Assembler::notZero, done);
6534 __ movl(Rdst, BitsPerLong);
6535 __ bind(done);
6536 %}
6537 ins_pipe(ialu_reg);
6538 %}
6539
6540
6541 //---------- Population Count Instructions -------------------------------------
6542
6543 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{
6544 predicate(UsePopCountInstruction);
6545 match(Set dst (PopCountI src));
6546 effect(KILL cr);
6547
6548 format %{ "popcnt $dst, $src" %}
6549 ins_encode %{
6550 __ popcntl($dst$$Register, $src$$Register);
6551 %}
6552 ins_pipe(ialu_reg);
6553 %}
6554
6555 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{
6556 predicate(UsePopCountInstruction);
6557 match(Set dst (PopCountI (LoadI mem)));
6558 effect(KILL cr);
6559
6560 format %{ "popcnt $dst, $mem" %}
6561 ins_encode %{
6562 __ popcntl($dst$$Register, $mem$$Address);
6563 %}
6564 ins_pipe(ialu_reg);
6565 %}
6566
6567 // Note: Long.bitCount(long) returns an int.
6568 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{
6569 predicate(UsePopCountInstruction);
6570 match(Set dst (PopCountL src));
6571 effect(KILL cr);
6572
6573 format %{ "popcnt $dst, $src" %}
6574 ins_encode %{
6575 __ popcntq($dst$$Register, $src$$Register);
6576 %}
6577 ins_pipe(ialu_reg);
6578 %}
6579
6580 // Note: Long.bitCount(long) returns an int.
6581 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{
6582 predicate(UsePopCountInstruction);
6583 match(Set dst (PopCountL (LoadL mem)));
6584 effect(KILL cr);
6585
6586 format %{ "popcnt $dst, $mem" %}
6587 ins_encode %{
6588 __ popcntq($dst$$Register, $mem$$Address);
6589 %}
6590 ins_pipe(ialu_reg);
6591 %}
6592
6593
6594 //----------MemBar Instructions-----------------------------------------------
6595 // Memory barrier flavors
6596
6597 instruct membar_acquire()
6598 %{
6599 match(MemBarAcquire);
6600 match(LoadFence);
6601 ins_cost(0);
6602
6603 size(0);
6604 format %{ "MEMBAR-acquire ! (empty encoding)" %}
6605 ins_encode();
6606 ins_pipe(empty);
6607 %}
6608
6609 instruct membar_acquire_lock()
6610 %{
6611 match(MemBarAcquireLock);
6612 ins_cost(0);
6613
6614 size(0);
6615 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %}
6616 ins_encode();
6617 ins_pipe(empty);
6618 %}
6619
6620 instruct membar_release()
6621 %{
6622 match(MemBarRelease);
6623 match(StoreFence);
6624 ins_cost(0);
6625
6626 size(0);
6627 format %{ "MEMBAR-release ! (empty encoding)" %}
6628 ins_encode();
6629 ins_pipe(empty);
6630 %}
6631
6632 instruct membar_release_lock()
6633 %{
6634 match(MemBarReleaseLock);
6635 ins_cost(0);
6636
6637 size(0);
6638 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
6639 ins_encode();
6640 ins_pipe(empty);
6641 %}
6642
6643 instruct membar_volatile(rFlagsReg cr) %{
6644 match(MemBarVolatile);
6645 effect(KILL cr);
6646 ins_cost(400);
6647
6648 format %{
6649 $$template
6650 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
6651 %}
6652 ins_encode %{
6653 __ membar(Assembler::StoreLoad);
6654 %}
6655 ins_pipe(pipe_slow);
6656 %}
6657
6658 instruct unnecessary_membar_volatile()
6659 %{
6660 match(MemBarVolatile);
6661 predicate(Matcher::post_store_load_barrier(n));
6662 ins_cost(0);
6663
6664 size(0);
6665 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
6666 ins_encode();
6667 ins_pipe(empty);
6668 %}
6669
6670 instruct membar_storestore() %{
6671 match(MemBarStoreStore);
6672 ins_cost(0);
6673
6674 size(0);
6675 format %{ "MEMBAR-storestore (empty encoding)" %}
6676 ins_encode( );
6677 ins_pipe(empty);
6678 %}
6679
6680 //----------Move Instructions--------------------------------------------------
6681
6682 instruct castX2P(rRegP dst, rRegL src)
6683 %{
6684 match(Set dst (CastX2P src));
6685
6686 format %{ "movq $dst, $src\t# long->ptr" %}
6687 ins_encode %{
6688 if ($dst$$reg != $src$$reg) {
6689 __ movptr($dst$$Register, $src$$Register);
6690 }
6691 %}
6692 ins_pipe(ialu_reg_reg); // XXX
6693 %}
6694
6695 instruct castN2X(rRegL dst, rRegN src)
6696 %{
6697 match(Set dst (CastP2X src));
6698
6699 format %{ "movq $dst, $src\t# ptr -> long" %}
6700 ins_encode %{
6701 if ($dst$$reg != $src$$reg) {
6702 __ movptr($dst$$Register, $src$$Register);
6703 }
6704 %}
6705 ins_pipe(ialu_reg_reg); // XXX
6706 %}
6707
6708 instruct castP2X(rRegL dst, rRegP src)
6709 %{
6710 match(Set dst (CastP2X src));
6711
6712 format %{ "movq $dst, $src\t# ptr -> long" %}
6713 ins_encode %{
6714 if ($dst$$reg != $src$$reg) {
6715 __ movptr($dst$$Register, $src$$Register);
6716 }
6717 %}
6718 ins_pipe(ialu_reg_reg); // XXX
6719 %}
6720
6721 instruct castN2I(rRegI dst, rRegN src)
6722 %{
6723 match(Set dst (CastN2I src));
6724
6725 format %{ "movl $dst, $src\t# compressed ptr -> int" %}
6726 ins_encode %{
6727 if ($dst$$reg != $src$$reg) {
6728 __ movl($dst$$Register, $src$$Register);
6729 }
6730 %}
6731 ins_pipe(ialu_reg_reg); // XXX
6732 %}
6733
6734 instruct castI2N(rRegN dst, rRegI src)
6735 %{
6736 match(Set dst (CastI2N src));
6737
6738 format %{ "movl $dst, $src\t# int -> compressed ptr" %}
6739 ins_encode %{
6740 if ($dst$$reg != $src$$reg) {
6741 __ movl($dst$$Register, $src$$Register);
6742 }
6743 %}
6744 ins_pipe(ialu_reg_reg); // XXX
6745 %}
6746
6747
6748 // Convert oop into int for vectors alignment masking
6749 instruct convP2I(rRegI dst, rRegP src)
6750 %{
6751 match(Set dst (ConvL2I (CastP2X src)));
6752
6753 format %{ "movl $dst, $src\t# ptr -> int" %}
6754 ins_encode %{
6755 __ movl($dst$$Register, $src$$Register);
6756 %}
6757 ins_pipe(ialu_reg_reg); // XXX
6758 %}
6759
6760 // Convert compressed oop into int for vectors alignment masking
6761 // in case of 32bit oops (heap < 4Gb).
6762 instruct convN2I(rRegI dst, rRegN src)
6763 %{
6764 predicate(CompressedOops::shift() == 0);
6765 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6766
6767 format %{ "movl $dst, $src\t# compressed ptr -> int" %}
6768 ins_encode %{
6769 __ movl($dst$$Register, $src$$Register);
6770 %}
6771 ins_pipe(ialu_reg_reg); // XXX
6772 %}
6773
6774 // Convert oop pointer into compressed form
6775 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
6776 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
6777 match(Set dst (EncodeP src));
6778 effect(KILL cr);
6779 format %{ "encode_heap_oop $dst,$src" %}
6780 ins_encode %{
6781 Register s = $src$$Register;
6782 Register d = $dst$$Register;
6783 if (s != d) {
6784 __ movq(d, s);
6785 }
6786 __ encode_heap_oop(d);
6787 %}
6788 ins_pipe(ialu_reg_long);
6789 %}
6790
6791 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6792 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
6793 match(Set dst (EncodeP src));
6794 effect(KILL cr);
6795 format %{ "encode_heap_oop_not_null $dst,$src" %}
6796 ins_encode %{
6797 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
6798 %}
6799 ins_pipe(ialu_reg_long);
6800 %}
6801
6802 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
6803 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
6804 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
6805 match(Set dst (DecodeN src));
6806 effect(KILL cr);
6807 format %{ "decode_heap_oop $dst,$src" %}
6808 ins_encode %{
6809 Register s = $src$$Register;
6810 Register d = $dst$$Register;
6811 if (s != d) {
6812 __ movq(d, s);
6813 }
6814 __ decode_heap_oop(d);
6815 %}
6816 ins_pipe(ialu_reg_long);
6817 %}
6818
6819 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6820 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
6821 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
6822 match(Set dst (DecodeN src));
6823 effect(KILL cr);
6824 format %{ "decode_heap_oop_not_null $dst,$src" %}
6825 ins_encode %{
6826 Register s = $src$$Register;
6827 Register d = $dst$$Register;
6828 if (s != d) {
6829 __ decode_heap_oop_not_null(d, s);
6830 } else {
6831 __ decode_heap_oop_not_null(d);
6832 }
6833 %}
6834 ins_pipe(ialu_reg_long);
6835 %}
6836
6837 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6838 match(Set dst (EncodePKlass src));
6839 effect(TEMP dst, KILL cr);
6840 format %{ "encode_and_move_klass_not_null $dst,$src" %}
6841 ins_encode %{
6842 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register);
6843 %}
6844 ins_pipe(ialu_reg_long);
6845 %}
6846
6847 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6848 match(Set dst (DecodeNKlass src));
6849 effect(TEMP dst, KILL cr);
6850 format %{ "decode_and_move_klass_not_null $dst,$src" %}
6851 ins_encode %{
6852 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register);
6853 %}
6854 ins_pipe(ialu_reg_long);
6855 %}
6856
6857 //----------Conditional Move---------------------------------------------------
6858 // Jump
6859 // dummy instruction for generating temp registers
6860 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
6861 match(Jump (LShiftL switch_val shift));
6862 ins_cost(350);
6863 predicate(false);
6864 effect(TEMP dest);
6865
6866 format %{ "leaq $dest, [$constantaddress]\n\t"
6867 "jmp [$dest + $switch_val << $shift]\n\t" %}
6868 ins_encode %{
6869 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6870 // to do that and the compiler is using that register as one it can allocate.
6871 // So we build it all by hand.
6872 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
6873 // ArrayAddress dispatch(table, index);
6874 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
6875 __ lea($dest$$Register, $constantaddress);
6876 __ jmp(dispatch);
6877 %}
6878 ins_pipe(pipe_jmp);
6879 %}
6880
6881 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
6882 match(Jump (AddL (LShiftL switch_val shift) offset));
6883 ins_cost(350);
6884 effect(TEMP dest);
6885
6886 format %{ "leaq $dest, [$constantaddress]\n\t"
6887 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %}
6888 ins_encode %{
6889 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6890 // to do that and the compiler is using that register as one it can allocate.
6891 // So we build it all by hand.
6892 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6893 // ArrayAddress dispatch(table, index);
6894 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6895 __ lea($dest$$Register, $constantaddress);
6896 __ jmp(dispatch);
6897 %}
6898 ins_pipe(pipe_jmp);
6899 %}
6900
6901 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
6902 match(Jump switch_val);
6903 ins_cost(350);
6904 effect(TEMP dest);
6905
6906 format %{ "leaq $dest, [$constantaddress]\n\t"
6907 "jmp [$dest + $switch_val]\n\t" %}
6908 ins_encode %{
6909 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6910 // to do that and the compiler is using that register as one it can allocate.
6911 // So we build it all by hand.
6912 // Address index(noreg, switch_reg, Address::times_1);
6913 // ArrayAddress dispatch(table, index);
6914 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1);
6915 __ lea($dest$$Register, $constantaddress);
6916 __ jmp(dispatch);
6917 %}
6918 ins_pipe(pipe_jmp);
6919 %}
6920
6921 // Conditional move
6922 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
6923 %{
6924 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6925
6926 ins_cost(200); // XXX
6927 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
6928 opcode(0x0F, 0x40);
6929 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6930 ins_pipe(pipe_cmov_reg);
6931 %}
6932
6933 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
6934 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6935
6936 ins_cost(200); // XXX
6937 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
6938 opcode(0x0F, 0x40);
6939 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6940 ins_pipe(pipe_cmov_reg);
6941 %}
6942
6943 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
6944 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6945 ins_cost(200);
6946 expand %{
6947 cmovI_regU(cop, cr, dst, src);
6948 %}
6949 %}
6950
6951 // Conditional move
6952 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
6953 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6954
6955 ins_cost(250); // XXX
6956 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
6957 opcode(0x0F, 0x40);
6958 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
6959 ins_pipe(pipe_cmov_mem);
6960 %}
6961
6962 // Conditional move
6963 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
6964 %{
6965 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6966
6967 ins_cost(250); // XXX
6968 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
6969 opcode(0x0F, 0x40);
6970 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
6971 ins_pipe(pipe_cmov_mem);
6972 %}
6973
6974 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
6975 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6976 ins_cost(250);
6977 expand %{
6978 cmovI_memU(cop, cr, dst, src);
6979 %}
6980 %}
6981
6982 // Conditional move
6983 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
6984 %{
6985 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6986
6987 ins_cost(200); // XXX
6988 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
6989 opcode(0x0F, 0x40);
6990 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6991 ins_pipe(pipe_cmov_reg);
6992 %}
6993
6994 // Conditional move
6995 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
6996 %{
6997 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6998
6999 ins_cost(200); // XXX
7000 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
7001 opcode(0x0F, 0x40);
7002 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7003 ins_pipe(pipe_cmov_reg);
7004 %}
7005
7006 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
7007 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7008 ins_cost(200);
7009 expand %{
7010 cmovN_regU(cop, cr, dst, src);
7011 %}
7012 %}
7013
7014 // Conditional move
7015 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
7016 %{
7017 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7018
7019 ins_cost(200); // XXX
7020 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %}
7021 opcode(0x0F, 0x40);
7022 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7023 ins_pipe(pipe_cmov_reg); // XXX
7024 %}
7025
7026 // Conditional move
7027 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
7028 %{
7029 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7030
7031 ins_cost(200); // XXX
7032 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %}
7033 opcode(0x0F, 0x40);
7034 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7035 ins_pipe(pipe_cmov_reg); // XXX
7036 %}
7037
7038 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
7039 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7040 ins_cost(200);
7041 expand %{
7042 cmovP_regU(cop, cr, dst, src);
7043 %}
7044 %}
7045
7046 // DISABLED: Requires the ADLC to emit a bottom_type call that
7047 // correctly meets the two pointer arguments; one is an incoming
7048 // register but the other is a memory operand. ALSO appears to
7049 // be buggy with implicit null checks.
7050 //
7051 //// Conditional move
7052 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src)
7053 //%{
7054 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
7055 // ins_cost(250);
7056 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
7057 // opcode(0x0F,0x40);
7058 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
7059 // ins_pipe( pipe_cmov_mem );
7060 //%}
7061 //
7062 //// Conditional move
7063 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src)
7064 //%{
7065 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
7066 // ins_cost(250);
7067 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
7068 // opcode(0x0F,0x40);
7069 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
7070 // ins_pipe( pipe_cmov_mem );
7071 //%}
7072
7073 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src)
7074 %{
7075 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7076
7077 ins_cost(200); // XXX
7078 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
7079 opcode(0x0F, 0x40);
7080 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7081 ins_pipe(pipe_cmov_reg); // XXX
7082 %}
7083
7084 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src)
7085 %{
7086 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7087
7088 ins_cost(200); // XXX
7089 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
7090 opcode(0x0F, 0x40);
7091 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7092 ins_pipe(pipe_cmov_mem); // XXX
7093 %}
7094
7095 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src)
7096 %{
7097 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7098
7099 ins_cost(200); // XXX
7100 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7101 opcode(0x0F, 0x40);
7102 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7103 ins_pipe(pipe_cmov_reg); // XXX
7104 %}
7105
7106 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
7107 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7108 ins_cost(200);
7109 expand %{
7110 cmovL_regU(cop, cr, dst, src);
7111 %}
7112 %}
7113
7114 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
7115 %{
7116 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7117
7118 ins_cost(200); // XXX
7119 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7120 opcode(0x0F, 0x40);
7121 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7122 ins_pipe(pipe_cmov_mem); // XXX
7123 %}
7124
7125 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
7126 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7127 ins_cost(200);
7128 expand %{
7129 cmovL_memU(cop, cr, dst, src);
7130 %}
7131 %}
7132
7133 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
7134 %{
7135 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7136
7137 ins_cost(200); // XXX
7138 format %{ "jn$cop skip\t# signed cmove float\n\t"
7139 "movss $dst, $src\n"
7140 "skip:" %}
7141 ins_encode %{
7142 Label Lskip;
7143 // Invert sense of branch from sense of CMOV
7144 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7145 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7146 __ bind(Lskip);
7147 %}
7148 ins_pipe(pipe_slow);
7149 %}
7150
7151 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
7152 // %{
7153 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src))));
7154
7155 // ins_cost(200); // XXX
7156 // format %{ "jn$cop skip\t# signed cmove float\n\t"
7157 // "movss $dst, $src\n"
7158 // "skip:" %}
7159 // ins_encode(enc_cmovf_mem_branch(cop, dst, src));
7160 // ins_pipe(pipe_slow);
7161 // %}
7162
7163 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
7164 %{
7165 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7166
7167 ins_cost(200); // XXX
7168 format %{ "jn$cop skip\t# unsigned cmove float\n\t"
7169 "movss $dst, $src\n"
7170 "skip:" %}
7171 ins_encode %{
7172 Label Lskip;
7173 // Invert sense of branch from sense of CMOV
7174 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7175 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7176 __ bind(Lskip);
7177 %}
7178 ins_pipe(pipe_slow);
7179 %}
7180
7181 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
7182 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7183 ins_cost(200);
7184 expand %{
7185 cmovF_regU(cop, cr, dst, src);
7186 %}
7187 %}
7188
7189 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
7190 %{
7191 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7192
7193 ins_cost(200); // XXX
7194 format %{ "jn$cop skip\t# signed cmove double\n\t"
7195 "movsd $dst, $src\n"
7196 "skip:" %}
7197 ins_encode %{
7198 Label Lskip;
7199 // Invert sense of branch from sense of CMOV
7200 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7201 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7202 __ bind(Lskip);
7203 %}
7204 ins_pipe(pipe_slow);
7205 %}
7206
7207 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
7208 %{
7209 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7210
7211 ins_cost(200); // XXX
7212 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
7213 "movsd $dst, $src\n"
7214 "skip:" %}
7215 ins_encode %{
7216 Label Lskip;
7217 // Invert sense of branch from sense of CMOV
7218 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7219 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7220 __ bind(Lskip);
7221 %}
7222 ins_pipe(pipe_slow);
7223 %}
7224
7225 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
7226 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7227 ins_cost(200);
7228 expand %{
7229 cmovD_regU(cop, cr, dst, src);
7230 %}
7231 %}
7232
7233 //----------Arithmetic Instructions--------------------------------------------
7234 //----------Addition Instructions----------------------------------------------
7235
7236 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7237 %{
7238 match(Set dst (AddI dst src));
7239 effect(KILL cr);
7240
7241 format %{ "addl $dst, $src\t# int" %}
7242 opcode(0x03);
7243 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
7244 ins_pipe(ialu_reg_reg);
7245 %}
7246
7247 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7248 %{
7249 match(Set dst (AddI dst src));
7250 effect(KILL cr);
7251
7252 format %{ "addl $dst, $src\t# int" %}
7253 opcode(0x81, 0x00); /* /0 id */
7254 ins_encode(OpcSErm(dst, src), Con8or32(src));
7255 ins_pipe( ialu_reg );
7256 %}
7257
7258 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
7259 %{
7260 match(Set dst (AddI dst (LoadI src)));
7261 effect(KILL cr);
7262
7263 ins_cost(125); // XXX
7264 format %{ "addl $dst, $src\t# int" %}
7265 opcode(0x03);
7266 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
7267 ins_pipe(ialu_reg_mem);
7268 %}
7269
7270 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
7271 %{
7272 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7273 effect(KILL cr);
7274
7275 ins_cost(150); // XXX
7276 format %{ "addl $dst, $src\t# int" %}
7277 opcode(0x01); /* Opcode 01 /r */
7278 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
7279 ins_pipe(ialu_mem_reg);
7280 %}
7281
7282 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr)
7283 %{
7284 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7285 effect(KILL cr);
7286
7287 ins_cost(125); // XXX
7288 format %{ "addl $dst, $src\t# int" %}
7289 opcode(0x81); /* Opcode 81 /0 id */
7290 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
7291 ins_pipe(ialu_mem_imm);
7292 %}
7293
7294 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
7295 %{
7296 predicate(UseIncDec);
7297 match(Set dst (AddI dst src));
7298 effect(KILL cr);
7299
7300 format %{ "incl $dst\t# int" %}
7301 opcode(0xFF, 0x00); // FF /0
7302 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7303 ins_pipe(ialu_reg);
7304 %}
7305
7306 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr)
7307 %{
7308 predicate(UseIncDec);
7309 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7310 effect(KILL cr);
7311
7312 ins_cost(125); // XXX
7313 format %{ "incl $dst\t# int" %}
7314 opcode(0xFF); /* Opcode FF /0 */
7315 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst));
7316 ins_pipe(ialu_mem_imm);
7317 %}
7318
7319 // XXX why does that use AddI
7320 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr)
7321 %{
7322 predicate(UseIncDec);
7323 match(Set dst (AddI dst src));
7324 effect(KILL cr);
7325
7326 format %{ "decl $dst\t# int" %}
7327 opcode(0xFF, 0x01); // FF /1
7328 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7329 ins_pipe(ialu_reg);
7330 %}
7331
7332 // XXX why does that use AddI
7333 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr)
7334 %{
7335 predicate(UseIncDec);
7336 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7337 effect(KILL cr);
7338
7339 ins_cost(125); // XXX
7340 format %{ "decl $dst\t# int" %}
7341 opcode(0xFF); /* Opcode FF /1 */
7342 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst));
7343 ins_pipe(ialu_mem_imm);
7344 %}
7345
7346 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1)
7347 %{
7348 match(Set dst (AddI src0 src1));
7349
7350 ins_cost(110);
7351 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %}
7352 opcode(0x8D); /* 0x8D /r */
7353 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
7354 ins_pipe(ialu_reg_reg);
7355 %}
7356
7357 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7358 %{
7359 match(Set dst (AddL dst src));
7360 effect(KILL cr);
7361
7362 format %{ "addq $dst, $src\t# long" %}
7363 opcode(0x03);
7364 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7365 ins_pipe(ialu_reg_reg);
7366 %}
7367
7368 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
7369 %{
7370 match(Set dst (AddL dst src));
7371 effect(KILL cr);
7372
7373 format %{ "addq $dst, $src\t# long" %}
7374 opcode(0x81, 0x00); /* /0 id */
7375 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7376 ins_pipe( ialu_reg );
7377 %}
7378
7379 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
7380 %{
7381 match(Set dst (AddL dst (LoadL src)));
7382 effect(KILL cr);
7383
7384 ins_cost(125); // XXX
7385 format %{ "addq $dst, $src\t# long" %}
7386 opcode(0x03);
7387 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
7388 ins_pipe(ialu_reg_mem);
7389 %}
7390
7391 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
7392 %{
7393 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7394 effect(KILL cr);
7395
7396 ins_cost(150); // XXX
7397 format %{ "addq $dst, $src\t# long" %}
7398 opcode(0x01); /* Opcode 01 /r */
7399 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7400 ins_pipe(ialu_mem_reg);
7401 %}
7402
7403 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
7404 %{
7405 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7406 effect(KILL cr);
7407
7408 ins_cost(125); // XXX
7409 format %{ "addq $dst, $src\t# long" %}
7410 opcode(0x81); /* Opcode 81 /0 id */
7411 ins_encode(REX_mem_wide(dst),
7412 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
7413 ins_pipe(ialu_mem_imm);
7414 %}
7415
7416 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr)
7417 %{
7418 predicate(UseIncDec);
7419 match(Set dst (AddL dst src));
7420 effect(KILL cr);
7421
7422 format %{ "incq $dst\t# long" %}
7423 opcode(0xFF, 0x00); // FF /0
7424 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7425 ins_pipe(ialu_reg);
7426 %}
7427
7428 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr)
7429 %{
7430 predicate(UseIncDec);
7431 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7432 effect(KILL cr);
7433
7434 ins_cost(125); // XXX
7435 format %{ "incq $dst\t# long" %}
7436 opcode(0xFF); /* Opcode FF /0 */
7437 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst));
7438 ins_pipe(ialu_mem_imm);
7439 %}
7440
7441 // XXX why does that use AddL
7442 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr)
7443 %{
7444 predicate(UseIncDec);
7445 match(Set dst (AddL dst src));
7446 effect(KILL cr);
7447
7448 format %{ "decq $dst\t# long" %}
7449 opcode(0xFF, 0x01); // FF /1
7450 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7451 ins_pipe(ialu_reg);
7452 %}
7453
7454 // XXX why does that use AddL
7455 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr)
7456 %{
7457 predicate(UseIncDec);
7458 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7459 effect(KILL cr);
7460
7461 ins_cost(125); // XXX
7462 format %{ "decq $dst\t# long" %}
7463 opcode(0xFF); /* Opcode FF /1 */
7464 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst));
7465 ins_pipe(ialu_mem_imm);
7466 %}
7467
7468 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1)
7469 %{
7470 match(Set dst (AddL src0 src1));
7471
7472 ins_cost(110);
7473 format %{ "leaq $dst, [$src0 + $src1]\t# long" %}
7474 opcode(0x8D); /* 0x8D /r */
7475 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
7476 ins_pipe(ialu_reg_reg);
7477 %}
7478
7479 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr)
7480 %{
7481 match(Set dst (AddP dst src));
7482 effect(KILL cr);
7483
7484 format %{ "addq $dst, $src\t# ptr" %}
7485 opcode(0x03);
7486 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7487 ins_pipe(ialu_reg_reg);
7488 %}
7489
7490 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr)
7491 %{
7492 match(Set dst (AddP dst src));
7493 effect(KILL cr);
7494
7495 format %{ "addq $dst, $src\t# ptr" %}
7496 opcode(0x81, 0x00); /* /0 id */
7497 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7498 ins_pipe( ialu_reg );
7499 %}
7500
7501 // XXX addP mem ops ????
7502
7503 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1)
7504 %{
7505 match(Set dst (AddP src0 src1));
7506
7507 ins_cost(110);
7508 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %}
7509 opcode(0x8D); /* 0x8D /r */
7510 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX
7511 ins_pipe(ialu_reg_reg);
7512 %}
7513
7514 instruct checkCastPP(rRegP dst)
7515 %{
7516 match(Set dst (CheckCastPP dst));
7517
7518 size(0);
7519 format %{ "# checkcastPP of $dst" %}
7520 ins_encode(/* empty encoding */);
7521 ins_pipe(empty);
7522 %}
7523
7524 instruct castPP(rRegP dst)
7525 %{
7526 match(Set dst (CastPP dst));
7527
7528 size(0);
7529 format %{ "# castPP of $dst" %}
7530 ins_encode(/* empty encoding */);
7531 ins_pipe(empty);
7532 %}
7533
7534 instruct castII(rRegI dst)
7535 %{
7536 match(Set dst (CastII dst));
7537
7538 size(0);
7539 format %{ "# castII of $dst" %}
7540 ins_encode(/* empty encoding */);
7541 ins_cost(0);
7542 ins_pipe(empty);
7543 %}
7544
7545 // LoadP-locked same as a regular LoadP when used with compare-swap
7546 instruct loadPLocked(rRegP dst, memory mem)
7547 %{
7548 match(Set dst (LoadPLocked mem));
7549
7550 ins_cost(125); // XXX
7551 format %{ "movq $dst, $mem\t# ptr locked" %}
7552 opcode(0x8B);
7553 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
7554 ins_pipe(ialu_reg_mem); // XXX
7555 %}
7556
7557 // Conditional-store of the updated heap-top.
7558 // Used during allocation of the shared heap.
7559 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
7560
7561 instruct storePConditional(memory heap_top_ptr,
7562 rax_RegP oldval, rRegP newval,
7563 rFlagsReg cr)
7564 %{
7565 predicate(n->as_LoadStore()->barrier_data() == 0);
7566 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
7567
7568 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
7569 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
7570 opcode(0x0F, 0xB1);
7571 ins_encode(lock_prefix,
7572 REX_reg_mem_wide(newval, heap_top_ptr),
7573 OpcP, OpcS,
7574 reg_mem(newval, heap_top_ptr));
7575 ins_pipe(pipe_cmpxchg);
7576 %}
7577
7578 // Conditional-store of an int value.
7579 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
7580 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
7581 %{
7582 match(Set cr (StoreIConditional mem (Binary oldval newval)));
7583 effect(KILL oldval);
7584
7585 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7586 opcode(0x0F, 0xB1);
7587 ins_encode(lock_prefix,
7588 REX_reg_mem(newval, mem),
7589 OpcP, OpcS,
7590 reg_mem(newval, mem));
7591 ins_pipe(pipe_cmpxchg);
7592 %}
7593
7594 // Conditional-store of a long value.
7595 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
7596 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
7597 %{
7598 match(Set cr (StoreLConditional mem (Binary oldval newval)));
7599 effect(KILL oldval);
7600
7601 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7602 opcode(0x0F, 0xB1);
7603 ins_encode(lock_prefix,
7604 REX_reg_mem_wide(newval, mem),
7605 OpcP, OpcS,
7606 reg_mem(newval, mem));
7607 ins_pipe(pipe_cmpxchg);
7608 %}
7609
7610
7611 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7612 instruct compareAndSwapP(rRegI res,
7613 memory mem_ptr,
7614 rax_RegP oldval, rRegP newval,
7615 rFlagsReg cr)
7616 %{
7617 predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0);
7618 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7619 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
7620 effect(KILL cr, KILL oldval);
7621
7622 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7623 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7624 "sete $res\n\t"
7625 "movzbl $res, $res" %}
7626 opcode(0x0F, 0xB1);
7627 ins_encode(lock_prefix,
7628 REX_reg_mem_wide(newval, mem_ptr),
7629 OpcP, OpcS,
7630 reg_mem(newval, mem_ptr),
7631 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7632 REX_reg_breg(res, res), // movzbl
7633 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7634 ins_pipe( pipe_cmpxchg );
7635 %}
7636
7637 instruct compareAndSwapL(rRegI res,
7638 memory mem_ptr,
7639 rax_RegL oldval, rRegL newval,
7640 rFlagsReg cr)
7641 %{
7642 predicate(VM_Version::supports_cx8());
7643 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7644 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
7645 effect(KILL cr, KILL oldval);
7646
7647 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7648 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7649 "sete $res\n\t"
7650 "movzbl $res, $res" %}
7651 opcode(0x0F, 0xB1);
7652 ins_encode(lock_prefix,
7653 REX_reg_mem_wide(newval, mem_ptr),
7654 OpcP, OpcS,
7655 reg_mem(newval, mem_ptr),
7656 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7657 REX_reg_breg(res, res), // movzbl
7658 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7659 ins_pipe( pipe_cmpxchg );
7660 %}
7661
7662 instruct compareAndSwapI(rRegI res,
7663 memory mem_ptr,
7664 rax_RegI oldval, rRegI newval,
7665 rFlagsReg cr)
7666 %{
7667 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
7668 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval)));
7669 effect(KILL cr, KILL oldval);
7670
7671 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7672 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7673 "sete $res\n\t"
7674 "movzbl $res, $res" %}
7675 opcode(0x0F, 0xB1);
7676 ins_encode(lock_prefix,
7677 REX_reg_mem(newval, mem_ptr),
7678 OpcP, OpcS,
7679 reg_mem(newval, mem_ptr),
7680 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7681 REX_reg_breg(res, res), // movzbl
7682 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7683 ins_pipe( pipe_cmpxchg );
7684 %}
7685
7686 instruct compareAndSwapB(rRegI res,
7687 memory mem_ptr,
7688 rax_RegI oldval, rRegI newval,
7689 rFlagsReg cr)
7690 %{
7691 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval)));
7692 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval)));
7693 effect(KILL cr, KILL oldval);
7694
7695 format %{ "cmpxchgb $mem_ptr,$newval\t# "
7696 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7697 "sete $res\n\t"
7698 "movzbl $res, $res" %}
7699 opcode(0x0F, 0xB0);
7700 ins_encode(lock_prefix,
7701 REX_breg_mem(newval, mem_ptr),
7702 OpcP, OpcS,
7703 reg_mem(newval, mem_ptr),
7704 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7705 REX_reg_breg(res, res), // movzbl
7706 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7707 ins_pipe( pipe_cmpxchg );
7708 %}
7709
7710 instruct compareAndSwapS(rRegI res,
7711 memory mem_ptr,
7712 rax_RegI oldval, rRegI newval,
7713 rFlagsReg cr)
7714 %{
7715 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval)));
7716 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval)));
7717 effect(KILL cr, KILL oldval);
7718
7719 format %{ "cmpxchgw $mem_ptr,$newval\t# "
7720 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7721 "sete $res\n\t"
7722 "movzbl $res, $res" %}
7723 opcode(0x0F, 0xB1);
7724 ins_encode(lock_prefix,
7725 SizePrefix,
7726 REX_reg_mem(newval, mem_ptr),
7727 OpcP, OpcS,
7728 reg_mem(newval, mem_ptr),
7729 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7730 REX_reg_breg(res, res), // movzbl
7731 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7732 ins_pipe( pipe_cmpxchg );
7733 %}
7734
7735 instruct compareAndSwapN(rRegI res,
7736 memory mem_ptr,
7737 rax_RegN oldval, rRegN newval,
7738 rFlagsReg cr) %{
7739 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7740 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval)));
7741 effect(KILL cr, KILL oldval);
7742
7743 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7744 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7745 "sete $res\n\t"
7746 "movzbl $res, $res" %}
7747 opcode(0x0F, 0xB1);
7748 ins_encode(lock_prefix,
7749 REX_reg_mem(newval, mem_ptr),
7750 OpcP, OpcS,
7751 reg_mem(newval, mem_ptr),
7752 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7753 REX_reg_breg(res, res), // movzbl
7754 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7755 ins_pipe( pipe_cmpxchg );
7756 %}
7757
7758 instruct compareAndExchangeB(
7759 memory mem_ptr,
7760 rax_RegI oldval, rRegI newval,
7761 rFlagsReg cr)
7762 %{
7763 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval)));
7764 effect(KILL cr);
7765
7766 format %{ "cmpxchgb $mem_ptr,$newval\t# "
7767 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7768 opcode(0x0F, 0xB0);
7769 ins_encode(lock_prefix,
7770 REX_breg_mem(newval, mem_ptr),
7771 OpcP, OpcS,
7772 reg_mem(newval, mem_ptr) // lock cmpxchg
7773 );
7774 ins_pipe( pipe_cmpxchg );
7775 %}
7776
7777 instruct compareAndExchangeS(
7778 memory mem_ptr,
7779 rax_RegI oldval, rRegI newval,
7780 rFlagsReg cr)
7781 %{
7782 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval)));
7783 effect(KILL cr);
7784
7785 format %{ "cmpxchgw $mem_ptr,$newval\t# "
7786 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7787 opcode(0x0F, 0xB1);
7788 ins_encode(lock_prefix,
7789 SizePrefix,
7790 REX_reg_mem(newval, mem_ptr),
7791 OpcP, OpcS,
7792 reg_mem(newval, mem_ptr) // lock cmpxchg
7793 );
7794 ins_pipe( pipe_cmpxchg );
7795 %}
7796
7797 instruct compareAndExchangeI(
7798 memory mem_ptr,
7799 rax_RegI oldval, rRegI newval,
7800 rFlagsReg cr)
7801 %{
7802 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval)));
7803 effect(KILL cr);
7804
7805 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7806 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7807 opcode(0x0F, 0xB1);
7808 ins_encode(lock_prefix,
7809 REX_reg_mem(newval, mem_ptr),
7810 OpcP, OpcS,
7811 reg_mem(newval, mem_ptr) // lock cmpxchg
7812 );
7813 ins_pipe( pipe_cmpxchg );
7814 %}
7815
7816 instruct compareAndExchangeL(
7817 memory mem_ptr,
7818 rax_RegL oldval, rRegL newval,
7819 rFlagsReg cr)
7820 %{
7821 predicate(VM_Version::supports_cx8());
7822 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval)));
7823 effect(KILL cr);
7824
7825 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7826 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7827 opcode(0x0F, 0xB1);
7828 ins_encode(lock_prefix,
7829 REX_reg_mem_wide(newval, mem_ptr),
7830 OpcP, OpcS,
7831 reg_mem(newval, mem_ptr) // lock cmpxchg
7832 );
7833 ins_pipe( pipe_cmpxchg );
7834 %}
7835
7836 instruct compareAndExchangeN(
7837 memory mem_ptr,
7838 rax_RegN oldval, rRegN newval,
7839 rFlagsReg cr) %{
7840 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval)));
7841 effect(KILL cr);
7842
7843 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7844 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7845 opcode(0x0F, 0xB1);
7846 ins_encode(lock_prefix,
7847 REX_reg_mem(newval, mem_ptr),
7848 OpcP, OpcS,
7849 reg_mem(newval, mem_ptr) // lock cmpxchg
7850 );
7851 ins_pipe( pipe_cmpxchg );
7852 %}
7853
7854 instruct compareAndExchangeP(
7855 memory mem_ptr,
7856 rax_RegP oldval, rRegP newval,
7857 rFlagsReg cr)
7858 %{
7859 predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0);
7860 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
7861 effect(KILL cr);
7862
7863 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7864 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7865 opcode(0x0F, 0xB1);
7866 ins_encode(lock_prefix,
7867 REX_reg_mem_wide(newval, mem_ptr),
7868 OpcP, OpcS,
7869 reg_mem(newval, mem_ptr) // lock cmpxchg
7870 );
7871 ins_pipe( pipe_cmpxchg );
7872 %}
7873
7874 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
7875 predicate(n->as_LoadStore()->result_not_used());
7876 match(Set dummy (GetAndAddB mem add));
7877 effect(KILL cr);
7878 format %{ "ADDB [$mem],$add" %}
7879 ins_encode %{
7880 __ lock();
7881 __ addb($mem$$Address, $add$$constant);
7882 %}
7883 ins_pipe( pipe_cmpxchg );
7884 %}
7885
7886 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{
7887 match(Set newval (GetAndAddB mem newval));
7888 effect(KILL cr);
7889 format %{ "XADDB [$mem],$newval" %}
7890 ins_encode %{
7891 __ lock();
7892 __ xaddb($mem$$Address, $newval$$Register);
7893 %}
7894 ins_pipe( pipe_cmpxchg );
7895 %}
7896
7897 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
7898 predicate(n->as_LoadStore()->result_not_used());
7899 match(Set dummy (GetAndAddS mem add));
7900 effect(KILL cr);
7901 format %{ "ADDW [$mem],$add" %}
7902 ins_encode %{
7903 __ lock();
7904 __ addw($mem$$Address, $add$$constant);
7905 %}
7906 ins_pipe( pipe_cmpxchg );
7907 %}
7908
7909 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{
7910 match(Set newval (GetAndAddS mem newval));
7911 effect(KILL cr);
7912 format %{ "XADDW [$mem],$newval" %}
7913 ins_encode %{
7914 __ lock();
7915 __ xaddw($mem$$Address, $newval$$Register);
7916 %}
7917 ins_pipe( pipe_cmpxchg );
7918 %}
7919
7920 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
7921 predicate(n->as_LoadStore()->result_not_used());
7922 match(Set dummy (GetAndAddI mem add));
7923 effect(KILL cr);
7924 format %{ "ADDL [$mem],$add" %}
7925 ins_encode %{
7926 __ lock();
7927 __ addl($mem$$Address, $add$$constant);
7928 %}
7929 ins_pipe( pipe_cmpxchg );
7930 %}
7931
7932 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{
7933 match(Set newval (GetAndAddI mem newval));
7934 effect(KILL cr);
7935 format %{ "XADDL [$mem],$newval" %}
7936 ins_encode %{
7937 __ lock();
7938 __ xaddl($mem$$Address, $newval$$Register);
7939 %}
7940 ins_pipe( pipe_cmpxchg );
7941 %}
7942
7943 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{
7944 predicate(n->as_LoadStore()->result_not_used());
7945 match(Set dummy (GetAndAddL mem add));
7946 effect(KILL cr);
7947 format %{ "ADDQ [$mem],$add" %}
7948 ins_encode %{
7949 __ lock();
7950 __ addq($mem$$Address, $add$$constant);
7951 %}
7952 ins_pipe( pipe_cmpxchg );
7953 %}
7954
7955 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{
7956 match(Set newval (GetAndAddL mem newval));
7957 effect(KILL cr);
7958 format %{ "XADDQ [$mem],$newval" %}
7959 ins_encode %{
7960 __ lock();
7961 __ xaddq($mem$$Address, $newval$$Register);
7962 %}
7963 ins_pipe( pipe_cmpxchg );
7964 %}
7965
7966 instruct xchgB( memory mem, rRegI newval) %{
7967 match(Set newval (GetAndSetB mem newval));
7968 format %{ "XCHGB $newval,[$mem]" %}
7969 ins_encode %{
7970 __ xchgb($newval$$Register, $mem$$Address);
7971 %}
7972 ins_pipe( pipe_cmpxchg );
7973 %}
7974
7975 instruct xchgS( memory mem, rRegI newval) %{
7976 match(Set newval (GetAndSetS mem newval));
7977 format %{ "XCHGW $newval,[$mem]" %}
7978 ins_encode %{
7979 __ xchgw($newval$$Register, $mem$$Address);
7980 %}
7981 ins_pipe( pipe_cmpxchg );
7982 %}
7983
7984 instruct xchgI( memory mem, rRegI newval) %{
7985 match(Set newval (GetAndSetI mem newval));
7986 format %{ "XCHGL $newval,[$mem]" %}
7987 ins_encode %{
7988 __ xchgl($newval$$Register, $mem$$Address);
7989 %}
7990 ins_pipe( pipe_cmpxchg );
7991 %}
7992
7993 instruct xchgL( memory mem, rRegL newval) %{
7994 match(Set newval (GetAndSetL mem newval));
7995 format %{ "XCHGL $newval,[$mem]" %}
7996 ins_encode %{
7997 __ xchgq($newval$$Register, $mem$$Address);
7998 %}
7999 ins_pipe( pipe_cmpxchg );
8000 %}
8001
8002 instruct xchgP( memory mem, rRegP newval) %{
8003 match(Set newval (GetAndSetP mem newval));
8004 predicate(n->as_LoadStore()->barrier_data() == 0);
8005 format %{ "XCHGQ $newval,[$mem]" %}
8006 ins_encode %{
8007 __ xchgq($newval$$Register, $mem$$Address);
8008 %}
8009 ins_pipe( pipe_cmpxchg );
8010 %}
8011
8012 instruct xchgN( memory mem, rRegN newval) %{
8013 match(Set newval (GetAndSetN mem newval));
8014 format %{ "XCHGL $newval,$mem]" %}
8015 ins_encode %{
8016 __ xchgl($newval$$Register, $mem$$Address);
8017 %}
8018 ins_pipe( pipe_cmpxchg );
8019 %}
8020
8021 //----------Abs Instructions-------------------------------------------
8022
8023 // Integer Absolute Instructions
8024 instruct absI_rReg(rRegI dst, rRegI src, rRegI tmp, rFlagsReg cr)
8025 %{
8026 match(Set dst (AbsI src));
8027 effect(TEMP dst, TEMP tmp, KILL cr);
8028 format %{ "movl $tmp, $src\n\t"
8029 "sarl $tmp, 31\n\t"
8030 "movl $dst, $src\n\t"
8031 "xorl $dst, $tmp\n\t"
8032 "subl $dst, $tmp\n"
8033 %}
8034 ins_encode %{
8035 __ movl($tmp$$Register, $src$$Register);
8036 __ sarl($tmp$$Register, 31);
8037 __ movl($dst$$Register, $src$$Register);
8038 __ xorl($dst$$Register, $tmp$$Register);
8039 __ subl($dst$$Register, $tmp$$Register);
8040 %}
8041
8042 ins_pipe(ialu_reg_reg);
8043 %}
8044
8045 // Long Absolute Instructions
8046 instruct absL_rReg(rRegL dst, rRegL src, rRegL tmp, rFlagsReg cr)
8047 %{
8048 match(Set dst (AbsL src));
8049 effect(TEMP dst, TEMP tmp, KILL cr);
8050 format %{ "movq $tmp, $src\n\t"
8051 "sarq $tmp, 63\n\t"
8052 "movq $dst, $src\n\t"
8053 "xorq $dst, $tmp\n\t"
8054 "subq $dst, $tmp\n"
8055 %}
8056 ins_encode %{
8057 __ movq($tmp$$Register, $src$$Register);
8058 __ sarq($tmp$$Register, 63);
8059 __ movq($dst$$Register, $src$$Register);
8060 __ xorq($dst$$Register, $tmp$$Register);
8061 __ subq($dst$$Register, $tmp$$Register);
8062 %}
8063
8064 ins_pipe(ialu_reg_reg);
8065 %}
8066
8067 //----------Subtraction Instructions-------------------------------------------
8068
8069 // Integer Subtraction Instructions
8070 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8071 %{
8072 match(Set dst (SubI dst src));
8073 effect(KILL cr);
8074
8075 format %{ "subl $dst, $src\t# int" %}
8076 opcode(0x2B);
8077 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8078 ins_pipe(ialu_reg_reg);
8079 %}
8080
8081 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8082 %{
8083 match(Set dst (SubI dst src));
8084 effect(KILL cr);
8085
8086 format %{ "subl $dst, $src\t# int" %}
8087 opcode(0x81, 0x05); /* Opcode 81 /5 */
8088 ins_encode(OpcSErm(dst, src), Con8or32(src));
8089 ins_pipe(ialu_reg);
8090 %}
8091
8092 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8093 %{
8094 match(Set dst (SubI dst (LoadI src)));
8095 effect(KILL cr);
8096
8097 ins_cost(125);
8098 format %{ "subl $dst, $src\t# int" %}
8099 opcode(0x2B);
8100 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
8101 ins_pipe(ialu_reg_mem);
8102 %}
8103
8104 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8105 %{
8106 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
8107 effect(KILL cr);
8108
8109 ins_cost(150);
8110 format %{ "subl $dst, $src\t# int" %}
8111 opcode(0x29); /* Opcode 29 /r */
8112 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
8113 ins_pipe(ialu_mem_reg);
8114 %}
8115
8116 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr)
8117 %{
8118 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
8119 effect(KILL cr);
8120
8121 ins_cost(125); // XXX
8122 format %{ "subl $dst, $src\t# int" %}
8123 opcode(0x81); /* Opcode 81 /5 id */
8124 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
8125 ins_pipe(ialu_mem_imm);
8126 %}
8127
8128 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8129 %{
8130 match(Set dst (SubL dst src));
8131 effect(KILL cr);
8132
8133 format %{ "subq $dst, $src\t# long" %}
8134 opcode(0x2B);
8135 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8136 ins_pipe(ialu_reg_reg);
8137 %}
8138
8139 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr)
8140 %{
8141 match(Set dst (SubL dst src));
8142 effect(KILL cr);
8143
8144 format %{ "subq $dst, $src\t# long" %}
8145 opcode(0x81, 0x05); /* Opcode 81 /5 */
8146 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
8147 ins_pipe(ialu_reg);
8148 %}
8149
8150 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
8151 %{
8152 match(Set dst (SubL dst (LoadL src)));
8153 effect(KILL cr);
8154
8155 ins_cost(125);
8156 format %{ "subq $dst, $src\t# long" %}
8157 opcode(0x2B);
8158 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
8159 ins_pipe(ialu_reg_mem);
8160 %}
8161
8162 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
8163 %{
8164 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
8165 effect(KILL cr);
8166
8167 ins_cost(150);
8168 format %{ "subq $dst, $src\t# long" %}
8169 opcode(0x29); /* Opcode 29 /r */
8170 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
8171 ins_pipe(ialu_mem_reg);
8172 %}
8173
8174 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
8175 %{
8176 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
8177 effect(KILL cr);
8178
8179 ins_cost(125); // XXX
8180 format %{ "subq $dst, $src\t# long" %}
8181 opcode(0x81); /* Opcode 81 /5 id */
8182 ins_encode(REX_mem_wide(dst),
8183 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
8184 ins_pipe(ialu_mem_imm);
8185 %}
8186
8187 // Subtract from a pointer
8188 // XXX hmpf???
8189 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr)
8190 %{
8191 match(Set dst (AddP dst (SubI zero src)));
8192 effect(KILL cr);
8193
8194 format %{ "subq $dst, $src\t# ptr - int" %}
8195 opcode(0x2B);
8196 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8197 ins_pipe(ialu_reg_reg);
8198 %}
8199
8200 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr)
8201 %{
8202 match(Set dst (SubI zero dst));
8203 effect(KILL cr);
8204
8205 format %{ "negl $dst\t# int" %}
8206 opcode(0xF7, 0x03); // Opcode F7 /3
8207 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8208 ins_pipe(ialu_reg);
8209 %}
8210
8211 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr)
8212 %{
8213 match(Set dst (StoreI dst (SubI zero (LoadI dst))));
8214 effect(KILL cr);
8215
8216 format %{ "negl $dst\t# int" %}
8217 opcode(0xF7, 0x03); // Opcode F7 /3
8218 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8219 ins_pipe(ialu_reg);
8220 %}
8221
8222 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr)
8223 %{
8224 match(Set dst (SubL zero dst));
8225 effect(KILL cr);
8226
8227 format %{ "negq $dst\t# long" %}
8228 opcode(0xF7, 0x03); // Opcode F7 /3
8229 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8230 ins_pipe(ialu_reg);
8231 %}
8232
8233 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr)
8234 %{
8235 match(Set dst (StoreL dst (SubL zero (LoadL dst))));
8236 effect(KILL cr);
8237
8238 format %{ "negq $dst\t# long" %}
8239 opcode(0xF7, 0x03); // Opcode F7 /3
8240 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8241 ins_pipe(ialu_reg);
8242 %}
8243
8244 //----------Multiplication/Division Instructions-------------------------------
8245 // Integer Multiplication Instructions
8246 // Multiply Register
8247
8248 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8249 %{
8250 match(Set dst (MulI dst src));
8251 effect(KILL cr);
8252
8253 ins_cost(300);
8254 format %{ "imull $dst, $src\t# int" %}
8255 opcode(0x0F, 0xAF);
8256 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8257 ins_pipe(ialu_reg_reg_alu0);
8258 %}
8259
8260 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr)
8261 %{
8262 match(Set dst (MulI src imm));
8263 effect(KILL cr);
8264
8265 ins_cost(300);
8266 format %{ "imull $dst, $src, $imm\t# int" %}
8267 opcode(0x69); /* 69 /r id */
8268 ins_encode(REX_reg_reg(dst, src),
8269 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
8270 ins_pipe(ialu_reg_reg_alu0);
8271 %}
8272
8273 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr)
8274 %{
8275 match(Set dst (MulI dst (LoadI src)));
8276 effect(KILL cr);
8277
8278 ins_cost(350);
8279 format %{ "imull $dst, $src\t# int" %}
8280 opcode(0x0F, 0xAF);
8281 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src));
8282 ins_pipe(ialu_reg_mem_alu0);
8283 %}
8284
8285 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr)
8286 %{
8287 match(Set dst (MulI (LoadI src) imm));
8288 effect(KILL cr);
8289
8290 ins_cost(300);
8291 format %{ "imull $dst, $src, $imm\t# int" %}
8292 opcode(0x69); /* 69 /r id */
8293 ins_encode(REX_reg_mem(dst, src),
8294 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
8295 ins_pipe(ialu_reg_mem_alu0);
8296 %}
8297
8298 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr)
8299 %{
8300 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3)));
8301 effect(KILL cr, KILL src2);
8302
8303 expand %{ mulI_rReg(dst, src1, cr);
8304 mulI_rReg(src2, src3, cr);
8305 addI_rReg(dst, src2, cr); %}
8306 %}
8307
8308 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8309 %{
8310 match(Set dst (MulL dst src));
8311 effect(KILL cr);
8312
8313 ins_cost(300);
8314 format %{ "imulq $dst, $src\t# long" %}
8315 opcode(0x0F, 0xAF);
8316 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src));
8317 ins_pipe(ialu_reg_reg_alu0);
8318 %}
8319
8320 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr)
8321 %{
8322 match(Set dst (MulL src imm));
8323 effect(KILL cr);
8324
8325 ins_cost(300);
8326 format %{ "imulq $dst, $src, $imm\t# long" %}
8327 opcode(0x69); /* 69 /r id */
8328 ins_encode(REX_reg_reg_wide(dst, src),
8329 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
8330 ins_pipe(ialu_reg_reg_alu0);
8331 %}
8332
8333 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr)
8334 %{
8335 match(Set dst (MulL dst (LoadL src)));
8336 effect(KILL cr);
8337
8338 ins_cost(350);
8339 format %{ "imulq $dst, $src\t# long" %}
8340 opcode(0x0F, 0xAF);
8341 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src));
8342 ins_pipe(ialu_reg_mem_alu0);
8343 %}
8344
8345 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr)
8346 %{
8347 match(Set dst (MulL (LoadL src) imm));
8348 effect(KILL cr);
8349
8350 ins_cost(300);
8351 format %{ "imulq $dst, $src, $imm\t# long" %}
8352 opcode(0x69); /* 69 /r id */
8353 ins_encode(REX_reg_mem_wide(dst, src),
8354 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
8355 ins_pipe(ialu_reg_mem_alu0);
8356 %}
8357
8358 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8359 %{
8360 match(Set dst (MulHiL src rax));
8361 effect(USE_KILL rax, KILL cr);
8362
8363 ins_cost(300);
8364 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %}
8365 opcode(0xF7, 0x5); /* Opcode F7 /5 */
8366 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
8367 ins_pipe(ialu_reg_reg_alu0);
8368 %}
8369
8370 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8371 rFlagsReg cr)
8372 %{
8373 match(Set rax (DivI rax div));
8374 effect(KILL rdx, KILL cr);
8375
8376 ins_cost(30*100+10*100); // XXX
8377 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
8378 "jne,s normal\n\t"
8379 "xorl rdx, rdx\n\t"
8380 "cmpl $div, -1\n\t"
8381 "je,s done\n"
8382 "normal: cdql\n\t"
8383 "idivl $div\n"
8384 "done:" %}
8385 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8386 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8387 ins_pipe(ialu_reg_reg_alu0);
8388 %}
8389
8390 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8391 rFlagsReg cr)
8392 %{
8393 match(Set rax (DivL rax div));
8394 effect(KILL rdx, KILL cr);
8395
8396 ins_cost(30*100+10*100); // XXX
8397 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8398 "cmpq rax, rdx\n\t"
8399 "jne,s normal\n\t"
8400 "xorl rdx, rdx\n\t"
8401 "cmpq $div, -1\n\t"
8402 "je,s done\n"
8403 "normal: cdqq\n\t"
8404 "idivq $div\n"
8405 "done:" %}
8406 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8407 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8408 ins_pipe(ialu_reg_reg_alu0);
8409 %}
8410
8411 // Integer DIVMOD with Register, both quotient and mod results
8412 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8413 rFlagsReg cr)
8414 %{
8415 match(DivModI rax div);
8416 effect(KILL cr);
8417
8418 ins_cost(30*100+10*100); // XXX
8419 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
8420 "jne,s normal\n\t"
8421 "xorl rdx, rdx\n\t"
8422 "cmpl $div, -1\n\t"
8423 "je,s done\n"
8424 "normal: cdql\n\t"
8425 "idivl $div\n"
8426 "done:" %}
8427 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8428 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8429 ins_pipe(pipe_slow);
8430 %}
8431
8432 // Long DIVMOD with Register, both quotient and mod results
8433 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8434 rFlagsReg cr)
8435 %{
8436 match(DivModL rax div);
8437 effect(KILL cr);
8438
8439 ins_cost(30*100+10*100); // XXX
8440 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8441 "cmpq rax, rdx\n\t"
8442 "jne,s normal\n\t"
8443 "xorl rdx, rdx\n\t"
8444 "cmpq $div, -1\n\t"
8445 "je,s done\n"
8446 "normal: cdqq\n\t"
8447 "idivq $div\n"
8448 "done:" %}
8449 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8450 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8451 ins_pipe(pipe_slow);
8452 %}
8453
8454 //----------- DivL-By-Constant-Expansions--------------------------------------
8455 // DivI cases are handled by the compiler
8456
8457 // Magic constant, reciprocal of 10
8458 instruct loadConL_0x6666666666666667(rRegL dst)
8459 %{
8460 effect(DEF dst);
8461
8462 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %}
8463 ins_encode(load_immL(dst, 0x6666666666666667));
8464 ins_pipe(ialu_reg);
8465 %}
8466
8467 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8468 %{
8469 effect(DEF dst, USE src, USE_KILL rax, KILL cr);
8470
8471 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %}
8472 opcode(0xF7, 0x5); /* Opcode F7 /5 */
8473 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
8474 ins_pipe(ialu_reg_reg_alu0);
8475 %}
8476
8477 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr)
8478 %{
8479 effect(USE_DEF dst, KILL cr);
8480
8481 format %{ "sarq $dst, #63\t# Used in div-by-10" %}
8482 opcode(0xC1, 0x7); /* C1 /7 ib */
8483 ins_encode(reg_opc_imm_wide(dst, 0x3F));
8484 ins_pipe(ialu_reg);
8485 %}
8486
8487 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr)
8488 %{
8489 effect(USE_DEF dst, KILL cr);
8490
8491 format %{ "sarq $dst, #2\t# Used in div-by-10" %}
8492 opcode(0xC1, 0x7); /* C1 /7 ib */
8493 ins_encode(reg_opc_imm_wide(dst, 0x2));
8494 ins_pipe(ialu_reg);
8495 %}
8496
8497 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div)
8498 %{
8499 match(Set dst (DivL src div));
8500
8501 ins_cost((5+8)*100);
8502 expand %{
8503 rax_RegL rax; // Killed temp
8504 rFlagsReg cr; // Killed
8505 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667
8506 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src
8507 sarL_rReg_63(src, cr); // sarq src, 63
8508 sarL_rReg_2(dst, cr); // sarq rdx, 2
8509 subL_rReg(dst, src, cr); // subl rdx, src
8510 %}
8511 %}
8512
8513 //-----------------------------------------------------------------------------
8514
8515 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div,
8516 rFlagsReg cr)
8517 %{
8518 match(Set rdx (ModI rax div));
8519 effect(KILL rax, KILL cr);
8520
8521 ins_cost(300); // XXX
8522 format %{ "cmpl rax, 0x80000000\t# irem\n\t"
8523 "jne,s normal\n\t"
8524 "xorl rdx, rdx\n\t"
8525 "cmpl $div, -1\n\t"
8526 "je,s done\n"
8527 "normal: cdql\n\t"
8528 "idivl $div\n"
8529 "done:" %}
8530 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8531 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8532 ins_pipe(ialu_reg_reg_alu0);
8533 %}
8534
8535 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div,
8536 rFlagsReg cr)
8537 %{
8538 match(Set rdx (ModL rax div));
8539 effect(KILL rax, KILL cr);
8540
8541 ins_cost(300); // XXX
8542 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t"
8543 "cmpq rax, rdx\n\t"
8544 "jne,s normal\n\t"
8545 "xorl rdx, rdx\n\t"
8546 "cmpq $div, -1\n\t"
8547 "je,s done\n"
8548 "normal: cdqq\n\t"
8549 "idivq $div\n"
8550 "done:" %}
8551 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8552 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8553 ins_pipe(ialu_reg_reg_alu0);
8554 %}
8555
8556 // Integer Shift Instructions
8557 // Shift Left by one
8558 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8559 %{
8560 match(Set dst (LShiftI dst shift));
8561 effect(KILL cr);
8562
8563 format %{ "sall $dst, $shift" %}
8564 opcode(0xD1, 0x4); /* D1 /4 */
8565 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8566 ins_pipe(ialu_reg);
8567 %}
8568
8569 // Shift Left by one
8570 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8571 %{
8572 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8573 effect(KILL cr);
8574
8575 format %{ "sall $dst, $shift\t" %}
8576 opcode(0xD1, 0x4); /* D1 /4 */
8577 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8578 ins_pipe(ialu_mem_imm);
8579 %}
8580
8581 // Shift Left by 8-bit immediate
8582 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8583 %{
8584 match(Set dst (LShiftI dst shift));
8585 effect(KILL cr);
8586
8587 format %{ "sall $dst, $shift" %}
8588 opcode(0xC1, 0x4); /* C1 /4 ib */
8589 ins_encode(reg_opc_imm(dst, shift));
8590 ins_pipe(ialu_reg);
8591 %}
8592
8593 // Shift Left by 8-bit immediate
8594 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8595 %{
8596 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8597 effect(KILL cr);
8598
8599 format %{ "sall $dst, $shift" %}
8600 opcode(0xC1, 0x4); /* C1 /4 ib */
8601 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8602 ins_pipe(ialu_mem_imm);
8603 %}
8604
8605 // Shift Left by variable
8606 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8607 %{
8608 match(Set dst (LShiftI dst shift));
8609 effect(KILL cr);
8610
8611 format %{ "sall $dst, $shift" %}
8612 opcode(0xD3, 0x4); /* D3 /4 */
8613 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8614 ins_pipe(ialu_reg_reg);
8615 %}
8616
8617 // Shift Left by variable
8618 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8619 %{
8620 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8621 effect(KILL cr);
8622
8623 format %{ "sall $dst, $shift" %}
8624 opcode(0xD3, 0x4); /* D3 /4 */
8625 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8626 ins_pipe(ialu_mem_reg);
8627 %}
8628
8629 // Arithmetic shift right by one
8630 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8631 %{
8632 match(Set dst (RShiftI dst shift));
8633 effect(KILL cr);
8634
8635 format %{ "sarl $dst, $shift" %}
8636 opcode(0xD1, 0x7); /* D1 /7 */
8637 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8638 ins_pipe(ialu_reg);
8639 %}
8640
8641 // Arithmetic shift right by one
8642 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8643 %{
8644 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8645 effect(KILL cr);
8646
8647 format %{ "sarl $dst, $shift" %}
8648 opcode(0xD1, 0x7); /* D1 /7 */
8649 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8650 ins_pipe(ialu_mem_imm);
8651 %}
8652
8653 // Arithmetic Shift Right by 8-bit immediate
8654 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8655 %{
8656 match(Set dst (RShiftI dst shift));
8657 effect(KILL cr);
8658
8659 format %{ "sarl $dst, $shift" %}
8660 opcode(0xC1, 0x7); /* C1 /7 ib */
8661 ins_encode(reg_opc_imm(dst, shift));
8662 ins_pipe(ialu_mem_imm);
8663 %}
8664
8665 // Arithmetic Shift Right by 8-bit immediate
8666 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8667 %{
8668 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8669 effect(KILL cr);
8670
8671 format %{ "sarl $dst, $shift" %}
8672 opcode(0xC1, 0x7); /* C1 /7 ib */
8673 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8674 ins_pipe(ialu_mem_imm);
8675 %}
8676
8677 // Arithmetic Shift Right by variable
8678 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8679 %{
8680 match(Set dst (RShiftI dst shift));
8681 effect(KILL cr);
8682
8683 format %{ "sarl $dst, $shift" %}
8684 opcode(0xD3, 0x7); /* D3 /7 */
8685 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8686 ins_pipe(ialu_reg_reg);
8687 %}
8688
8689 // Arithmetic Shift Right by variable
8690 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8691 %{
8692 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8693 effect(KILL cr);
8694
8695 format %{ "sarl $dst, $shift" %}
8696 opcode(0xD3, 0x7); /* D3 /7 */
8697 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8698 ins_pipe(ialu_mem_reg);
8699 %}
8700
8701 // Logical shift right by one
8702 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8703 %{
8704 match(Set dst (URShiftI dst shift));
8705 effect(KILL cr);
8706
8707 format %{ "shrl $dst, $shift" %}
8708 opcode(0xD1, 0x5); /* D1 /5 */
8709 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8710 ins_pipe(ialu_reg);
8711 %}
8712
8713 // Logical shift right by one
8714 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8715 %{
8716 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8717 effect(KILL cr);
8718
8719 format %{ "shrl $dst, $shift" %}
8720 opcode(0xD1, 0x5); /* D1 /5 */
8721 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8722 ins_pipe(ialu_mem_imm);
8723 %}
8724
8725 // Logical Shift Right by 8-bit immediate
8726 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8727 %{
8728 match(Set dst (URShiftI dst shift));
8729 effect(KILL cr);
8730
8731 format %{ "shrl $dst, $shift" %}
8732 opcode(0xC1, 0x5); /* C1 /5 ib */
8733 ins_encode(reg_opc_imm(dst, shift));
8734 ins_pipe(ialu_reg);
8735 %}
8736
8737 // Logical Shift Right by 8-bit immediate
8738 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8739 %{
8740 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8741 effect(KILL cr);
8742
8743 format %{ "shrl $dst, $shift" %}
8744 opcode(0xC1, 0x5); /* C1 /5 ib */
8745 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8746 ins_pipe(ialu_mem_imm);
8747 %}
8748
8749 // Logical Shift Right by variable
8750 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8751 %{
8752 match(Set dst (URShiftI dst shift));
8753 effect(KILL cr);
8754
8755 format %{ "shrl $dst, $shift" %}
8756 opcode(0xD3, 0x5); /* D3 /5 */
8757 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8758 ins_pipe(ialu_reg_reg);
8759 %}
8760
8761 // Logical Shift Right by variable
8762 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8763 %{
8764 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8765 effect(KILL cr);
8766
8767 format %{ "shrl $dst, $shift" %}
8768 opcode(0xD3, 0x5); /* D3 /5 */
8769 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8770 ins_pipe(ialu_mem_reg);
8771 %}
8772
8773 // Long Shift Instructions
8774 // Shift Left by one
8775 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8776 %{
8777 match(Set dst (LShiftL dst shift));
8778 effect(KILL cr);
8779
8780 format %{ "salq $dst, $shift" %}
8781 opcode(0xD1, 0x4); /* D1 /4 */
8782 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8783 ins_pipe(ialu_reg);
8784 %}
8785
8786 // Shift Left by one
8787 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8788 %{
8789 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8790 effect(KILL cr);
8791
8792 format %{ "salq $dst, $shift" %}
8793 opcode(0xD1, 0x4); /* D1 /4 */
8794 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8795 ins_pipe(ialu_mem_imm);
8796 %}
8797
8798 // Shift Left by 8-bit immediate
8799 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8800 %{
8801 match(Set dst (LShiftL dst shift));
8802 effect(KILL cr);
8803
8804 format %{ "salq $dst, $shift" %}
8805 opcode(0xC1, 0x4); /* C1 /4 ib */
8806 ins_encode(reg_opc_imm_wide(dst, shift));
8807 ins_pipe(ialu_reg);
8808 %}
8809
8810 // Shift Left by 8-bit immediate
8811 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8812 %{
8813 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8814 effect(KILL cr);
8815
8816 format %{ "salq $dst, $shift" %}
8817 opcode(0xC1, 0x4); /* C1 /4 ib */
8818 ins_encode(REX_mem_wide(dst), OpcP,
8819 RM_opc_mem(secondary, dst), Con8or32(shift));
8820 ins_pipe(ialu_mem_imm);
8821 %}
8822
8823 // Shift Left by variable
8824 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8825 %{
8826 match(Set dst (LShiftL dst shift));
8827 effect(KILL cr);
8828
8829 format %{ "salq $dst, $shift" %}
8830 opcode(0xD3, 0x4); /* D3 /4 */
8831 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8832 ins_pipe(ialu_reg_reg);
8833 %}
8834
8835 // Shift Left by variable
8836 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8837 %{
8838 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8839 effect(KILL cr);
8840
8841 format %{ "salq $dst, $shift" %}
8842 opcode(0xD3, 0x4); /* D3 /4 */
8843 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8844 ins_pipe(ialu_mem_reg);
8845 %}
8846
8847 // Arithmetic shift right by one
8848 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8849 %{
8850 match(Set dst (RShiftL dst shift));
8851 effect(KILL cr);
8852
8853 format %{ "sarq $dst, $shift" %}
8854 opcode(0xD1, 0x7); /* D1 /7 */
8855 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8856 ins_pipe(ialu_reg);
8857 %}
8858
8859 // Arithmetic shift right by one
8860 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8861 %{
8862 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8863 effect(KILL cr);
8864
8865 format %{ "sarq $dst, $shift" %}
8866 opcode(0xD1, 0x7); /* D1 /7 */
8867 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8868 ins_pipe(ialu_mem_imm);
8869 %}
8870
8871 // Arithmetic Shift Right by 8-bit immediate
8872 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8873 %{
8874 match(Set dst (RShiftL dst shift));
8875 effect(KILL cr);
8876
8877 format %{ "sarq $dst, $shift" %}
8878 opcode(0xC1, 0x7); /* C1 /7 ib */
8879 ins_encode(reg_opc_imm_wide(dst, shift));
8880 ins_pipe(ialu_mem_imm);
8881 %}
8882
8883 // Arithmetic Shift Right by 8-bit immediate
8884 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8885 %{
8886 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8887 effect(KILL cr);
8888
8889 format %{ "sarq $dst, $shift" %}
8890 opcode(0xC1, 0x7); /* C1 /7 ib */
8891 ins_encode(REX_mem_wide(dst), OpcP,
8892 RM_opc_mem(secondary, dst), Con8or32(shift));
8893 ins_pipe(ialu_mem_imm);
8894 %}
8895
8896 // Arithmetic Shift Right by variable
8897 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8898 %{
8899 match(Set dst (RShiftL dst shift));
8900 effect(KILL cr);
8901
8902 format %{ "sarq $dst, $shift" %}
8903 opcode(0xD3, 0x7); /* D3 /7 */
8904 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8905 ins_pipe(ialu_reg_reg);
8906 %}
8907
8908 // Arithmetic Shift Right by variable
8909 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8910 %{
8911 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8912 effect(KILL cr);
8913
8914 format %{ "sarq $dst, $shift" %}
8915 opcode(0xD3, 0x7); /* D3 /7 */
8916 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8917 ins_pipe(ialu_mem_reg);
8918 %}
8919
8920 // Logical shift right by one
8921 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8922 %{
8923 match(Set dst (URShiftL dst shift));
8924 effect(KILL cr);
8925
8926 format %{ "shrq $dst, $shift" %}
8927 opcode(0xD1, 0x5); /* D1 /5 */
8928 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst ));
8929 ins_pipe(ialu_reg);
8930 %}
8931
8932 // Logical shift right by one
8933 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8934 %{
8935 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8936 effect(KILL cr);
8937
8938 format %{ "shrq $dst, $shift" %}
8939 opcode(0xD1, 0x5); /* D1 /5 */
8940 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8941 ins_pipe(ialu_mem_imm);
8942 %}
8943
8944 // Logical Shift Right by 8-bit immediate
8945 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8946 %{
8947 match(Set dst (URShiftL dst shift));
8948 effect(KILL cr);
8949
8950 format %{ "shrq $dst, $shift" %}
8951 opcode(0xC1, 0x5); /* C1 /5 ib */
8952 ins_encode(reg_opc_imm_wide(dst, shift));
8953 ins_pipe(ialu_reg);
8954 %}
8955
8956
8957 // Logical Shift Right by 8-bit immediate
8958 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8959 %{
8960 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8961 effect(KILL cr);
8962
8963 format %{ "shrq $dst, $shift" %}
8964 opcode(0xC1, 0x5); /* C1 /5 ib */
8965 ins_encode(REX_mem_wide(dst), OpcP,
8966 RM_opc_mem(secondary, dst), Con8or32(shift));
8967 ins_pipe(ialu_mem_imm);
8968 %}
8969
8970 // Logical Shift Right by variable
8971 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8972 %{
8973 match(Set dst (URShiftL dst shift));
8974 effect(KILL cr);
8975
8976 format %{ "shrq $dst, $shift" %}
8977 opcode(0xD3, 0x5); /* D3 /5 */
8978 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8979 ins_pipe(ialu_reg_reg);
8980 %}
8981
8982 // Logical Shift Right by variable
8983 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8984 %{
8985 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8986 effect(KILL cr);
8987
8988 format %{ "shrq $dst, $shift" %}
8989 opcode(0xD3, 0x5); /* D3 /5 */
8990 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8991 ins_pipe(ialu_mem_reg);
8992 %}
8993
8994 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
8995 // This idiom is used by the compiler for the i2b bytecode.
8996 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour)
8997 %{
8998 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
8999
9000 format %{ "movsbl $dst, $src\t# i2b" %}
9001 opcode(0x0F, 0xBE);
9002 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9003 ins_pipe(ialu_reg_reg);
9004 %}
9005
9006 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
9007 // This idiom is used by the compiler the i2s bytecode.
9008 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen)
9009 %{
9010 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
9011
9012 format %{ "movswl $dst, $src\t# i2s" %}
9013 opcode(0x0F, 0xBF);
9014 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9015 ins_pipe(ialu_reg_reg);
9016 %}
9017
9018 // ROL/ROR instructions
9019
9020 // ROL expand
9021 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{
9022 effect(KILL cr, USE_DEF dst);
9023
9024 format %{ "roll $dst" %}
9025 opcode(0xD1, 0x0); /* Opcode D1 /0 */
9026 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9027 ins_pipe(ialu_reg);
9028 %}
9029
9030 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{
9031 effect(USE_DEF dst, USE shift, KILL cr);
9032
9033 format %{ "roll $dst, $shift" %}
9034 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
9035 ins_encode( reg_opc_imm(dst, shift) );
9036 ins_pipe(ialu_reg);
9037 %}
9038
9039 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
9040 %{
9041 effect(USE_DEF dst, USE shift, KILL cr);
9042
9043 format %{ "roll $dst, $shift" %}
9044 opcode(0xD3, 0x0); /* Opcode D3 /0 */
9045 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9046 ins_pipe(ialu_reg_reg);
9047 %}
9048 // end of ROL expand
9049
9050 // Rotate Left by one
9051 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
9052 %{
9053 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
9054
9055 expand %{
9056 rolI_rReg_imm1(dst, cr);
9057 %}
9058 %}
9059
9060 // Rotate Left by 8-bit immediate
9061 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
9062 %{
9063 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9064 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
9065
9066 expand %{
9067 rolI_rReg_imm8(dst, lshift, cr);
9068 %}
9069 %}
9070
9071 // Rotate Left by variable
9072 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9073 %{
9074 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift))));
9075
9076 expand %{
9077 rolI_rReg_CL(dst, shift, cr);
9078 %}
9079 %}
9080
9081 // Rotate Left by variable
9082 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
9083 %{
9084 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift))));
9085
9086 expand %{
9087 rolI_rReg_CL(dst, shift, cr);
9088 %}
9089 %}
9090
9091 // ROR expand
9092 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr)
9093 %{
9094 effect(USE_DEF dst, KILL cr);
9095
9096 format %{ "rorl $dst" %}
9097 opcode(0xD1, 0x1); /* D1 /1 */
9098 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9099 ins_pipe(ialu_reg);
9100 %}
9101
9102 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr)
9103 %{
9104 effect(USE_DEF dst, USE shift, KILL cr);
9105
9106 format %{ "rorl $dst, $shift" %}
9107 opcode(0xC1, 0x1); /* C1 /1 ib */
9108 ins_encode(reg_opc_imm(dst, shift));
9109 ins_pipe(ialu_reg);
9110 %}
9111
9112 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
9113 %{
9114 effect(USE_DEF dst, USE shift, KILL cr);
9115
9116 format %{ "rorl $dst, $shift" %}
9117 opcode(0xD3, 0x1); /* D3 /1 */
9118 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9119 ins_pipe(ialu_reg_reg);
9120 %}
9121 // end of ROR expand
9122
9123 // Rotate Right by one
9124 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
9125 %{
9126 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
9127
9128 expand %{
9129 rorI_rReg_imm1(dst, cr);
9130 %}
9131 %}
9132
9133 // Rotate Right by 8-bit immediate
9134 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
9135 %{
9136 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9137 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
9138
9139 expand %{
9140 rorI_rReg_imm8(dst, rshift, cr);
9141 %}
9142 %}
9143
9144 // Rotate Right by variable
9145 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9146 %{
9147 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift))));
9148
9149 expand %{
9150 rorI_rReg_CL(dst, shift, cr);
9151 %}
9152 %}
9153
9154 // Rotate Right by variable
9155 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
9156 %{
9157 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift))));
9158
9159 expand %{
9160 rorI_rReg_CL(dst, shift, cr);
9161 %}
9162 %}
9163
9164 // for long rotate
9165 // ROL expand
9166 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{
9167 effect(USE_DEF dst, KILL cr);
9168
9169 format %{ "rolq $dst" %}
9170 opcode(0xD1, 0x0); /* Opcode D1 /0 */
9171 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9172 ins_pipe(ialu_reg);
9173 %}
9174
9175 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{
9176 effect(USE_DEF dst, USE shift, KILL cr);
9177
9178 format %{ "rolq $dst, $shift" %}
9179 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
9180 ins_encode( reg_opc_imm_wide(dst, shift) );
9181 ins_pipe(ialu_reg);
9182 %}
9183
9184 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
9185 %{
9186 effect(USE_DEF dst, USE shift, KILL cr);
9187
9188 format %{ "rolq $dst, $shift" %}
9189 opcode(0xD3, 0x0); /* Opcode D3 /0 */
9190 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9191 ins_pipe(ialu_reg_reg);
9192 %}
9193 // end of ROL expand
9194
9195 // Rotate Left by one
9196 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
9197 %{
9198 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
9199
9200 expand %{
9201 rolL_rReg_imm1(dst, cr);
9202 %}
9203 %}
9204
9205 // Rotate Left by 8-bit immediate
9206 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
9207 %{
9208 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9209 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
9210
9211 expand %{
9212 rolL_rReg_imm8(dst, lshift, cr);
9213 %}
9214 %}
9215
9216 // Rotate Left by variable
9217 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9218 %{
9219 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift))));
9220
9221 expand %{
9222 rolL_rReg_CL(dst, shift, cr);
9223 %}
9224 %}
9225
9226 // Rotate Left by variable
9227 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
9228 %{
9229 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift))));
9230
9231 expand %{
9232 rolL_rReg_CL(dst, shift, cr);
9233 %}
9234 %}
9235
9236 // ROR expand
9237 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr)
9238 %{
9239 effect(USE_DEF dst, KILL cr);
9240
9241 format %{ "rorq $dst" %}
9242 opcode(0xD1, 0x1); /* D1 /1 */
9243 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9244 ins_pipe(ialu_reg);
9245 %}
9246
9247 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr)
9248 %{
9249 effect(USE_DEF dst, USE shift, KILL cr);
9250
9251 format %{ "rorq $dst, $shift" %}
9252 opcode(0xC1, 0x1); /* C1 /1 ib */
9253 ins_encode(reg_opc_imm_wide(dst, shift));
9254 ins_pipe(ialu_reg);
9255 %}
9256
9257 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
9258 %{
9259 effect(USE_DEF dst, USE shift, KILL cr);
9260
9261 format %{ "rorq $dst, $shift" %}
9262 opcode(0xD3, 0x1); /* D3 /1 */
9263 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9264 ins_pipe(ialu_reg_reg);
9265 %}
9266 // end of ROR expand
9267
9268 // Rotate Right by one
9269 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
9270 %{
9271 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
9272
9273 expand %{
9274 rorL_rReg_imm1(dst, cr);
9275 %}
9276 %}
9277
9278 // Rotate Right by 8-bit immediate
9279 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
9280 %{
9281 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9282 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
9283
9284 expand %{
9285 rorL_rReg_imm8(dst, rshift, cr);
9286 %}
9287 %}
9288
9289 // Rotate Right by variable
9290 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9291 %{
9292 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift))));
9293
9294 expand %{
9295 rorL_rReg_CL(dst, shift, cr);
9296 %}
9297 %}
9298
9299 // Rotate Right by variable
9300 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
9301 %{
9302 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift))));
9303
9304 expand %{
9305 rorL_rReg_CL(dst, shift, cr);
9306 %}
9307 %}
9308
9309 // Logical Instructions
9310
9311 // Integer Logical Instructions
9312
9313 // And Instructions
9314 // And Register with Register
9315 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9316 %{
9317 match(Set dst (AndI dst src));
9318 effect(KILL cr);
9319
9320 format %{ "andl $dst, $src\t# int" %}
9321 opcode(0x23);
9322 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9323 ins_pipe(ialu_reg_reg);
9324 %}
9325
9326 // And Register with Immediate 255
9327 instruct andI_rReg_imm255(rRegI dst, immI_255 src)
9328 %{
9329 match(Set dst (AndI dst src));
9330
9331 format %{ "movzbl $dst, $dst\t# int & 0xFF" %}
9332 opcode(0x0F, 0xB6);
9333 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9334 ins_pipe(ialu_reg);
9335 %}
9336
9337 // And Register with Immediate 255 and promote to long
9338 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask)
9339 %{
9340 match(Set dst (ConvI2L (AndI src mask)));
9341
9342 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %}
9343 opcode(0x0F, 0xB6);
9344 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9345 ins_pipe(ialu_reg);
9346 %}
9347
9348 // And Register with Immediate 65535
9349 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src)
9350 %{
9351 match(Set dst (AndI dst src));
9352
9353 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %}
9354 opcode(0x0F, 0xB7);
9355 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9356 ins_pipe(ialu_reg);
9357 %}
9358
9359 // And Register with Immediate 65535 and promote to long
9360 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask)
9361 %{
9362 match(Set dst (ConvI2L (AndI src mask)));
9363
9364 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %}
9365 opcode(0x0F, 0xB7);
9366 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9367 ins_pipe(ialu_reg);
9368 %}
9369
9370 // And Register with Immediate
9371 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9372 %{
9373 match(Set dst (AndI dst src));
9374 effect(KILL cr);
9375
9376 format %{ "andl $dst, $src\t# int" %}
9377 opcode(0x81, 0x04); /* Opcode 81 /4 */
9378 ins_encode(OpcSErm(dst, src), Con8or32(src));
9379 ins_pipe(ialu_reg);
9380 %}
9381
9382 // And Register with Memory
9383 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9384 %{
9385 match(Set dst (AndI dst (LoadI src)));
9386 effect(KILL cr);
9387
9388 ins_cost(125);
9389 format %{ "andl $dst, $src\t# int" %}
9390 opcode(0x23);
9391 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9392 ins_pipe(ialu_reg_mem);
9393 %}
9394
9395 // And Memory with Register
9396 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9397 %{
9398 match(Set dst (StoreB dst (AndI (LoadB dst) src)));
9399 effect(KILL cr);
9400
9401 ins_cost(150);
9402 format %{ "andb $dst, $src\t# byte" %}
9403 opcode(0x20);
9404 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst));
9405 ins_pipe(ialu_mem_reg);
9406 %}
9407
9408 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9409 %{
9410 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9411 effect(KILL cr);
9412
9413 ins_cost(150);
9414 format %{ "andl $dst, $src\t# int" %}
9415 opcode(0x21); /* Opcode 21 /r */
9416 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9417 ins_pipe(ialu_mem_reg);
9418 %}
9419
9420 // And Memory with Immediate
9421 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr)
9422 %{
9423 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9424 effect(KILL cr);
9425
9426 ins_cost(125);
9427 format %{ "andl $dst, $src\t# int" %}
9428 opcode(0x81, 0x4); /* Opcode 81 /4 id */
9429 ins_encode(REX_mem(dst), OpcSE(src),
9430 RM_opc_mem(secondary, dst), Con8or32(src));
9431 ins_pipe(ialu_mem_imm);
9432 %}
9433
9434 // BMI1 instructions
9435 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{
9436 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2)));
9437 predicate(UseBMI1Instructions);
9438 effect(KILL cr);
9439
9440 ins_cost(125);
9441 format %{ "andnl $dst, $src1, $src2" %}
9442
9443 ins_encode %{
9444 __ andnl($dst$$Register, $src1$$Register, $src2$$Address);
9445 %}
9446 ins_pipe(ialu_reg_mem);
9447 %}
9448
9449 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{
9450 match(Set dst (AndI (XorI src1 minus_1) src2));
9451 predicate(UseBMI1Instructions);
9452 effect(KILL cr);
9453
9454 format %{ "andnl $dst, $src1, $src2" %}
9455
9456 ins_encode %{
9457 __ andnl($dst$$Register, $src1$$Register, $src2$$Register);
9458 %}
9459 ins_pipe(ialu_reg);
9460 %}
9461
9462 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{
9463 match(Set dst (AndI (SubI imm_zero src) src));
9464 predicate(UseBMI1Instructions);
9465 effect(KILL cr);
9466
9467 format %{ "blsil $dst, $src" %}
9468
9469 ins_encode %{
9470 __ blsil($dst$$Register, $src$$Register);
9471 %}
9472 ins_pipe(ialu_reg);
9473 %}
9474
9475 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{
9476 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) ));
9477 predicate(UseBMI1Instructions);
9478 effect(KILL cr);
9479
9480 ins_cost(125);
9481 format %{ "blsil $dst, $src" %}
9482
9483 ins_encode %{
9484 __ blsil($dst$$Register, $src$$Address);
9485 %}
9486 ins_pipe(ialu_reg_mem);
9487 %}
9488
9489 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr)
9490 %{
9491 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) );
9492 predicate(UseBMI1Instructions);
9493 effect(KILL cr);
9494
9495 ins_cost(125);
9496 format %{ "blsmskl $dst, $src" %}
9497
9498 ins_encode %{
9499 __ blsmskl($dst$$Register, $src$$Address);
9500 %}
9501 ins_pipe(ialu_reg_mem);
9502 %}
9503
9504 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr)
9505 %{
9506 match(Set dst (XorI (AddI src minus_1) src));
9507 predicate(UseBMI1Instructions);
9508 effect(KILL cr);
9509
9510 format %{ "blsmskl $dst, $src" %}
9511
9512 ins_encode %{
9513 __ blsmskl($dst$$Register, $src$$Register);
9514 %}
9515
9516 ins_pipe(ialu_reg);
9517 %}
9518
9519 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr)
9520 %{
9521 match(Set dst (AndI (AddI src minus_1) src) );
9522 predicate(UseBMI1Instructions);
9523 effect(KILL cr);
9524
9525 format %{ "blsrl $dst, $src" %}
9526
9527 ins_encode %{
9528 __ blsrl($dst$$Register, $src$$Register);
9529 %}
9530
9531 ins_pipe(ialu_reg_mem);
9532 %}
9533
9534 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr)
9535 %{
9536 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) );
9537 predicate(UseBMI1Instructions);
9538 effect(KILL cr);
9539
9540 ins_cost(125);
9541 format %{ "blsrl $dst, $src" %}
9542
9543 ins_encode %{
9544 __ blsrl($dst$$Register, $src$$Address);
9545 %}
9546
9547 ins_pipe(ialu_reg);
9548 %}
9549
9550 // Or Instructions
9551 // Or Register with Register
9552 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9553 %{
9554 match(Set dst (OrI dst src));
9555 effect(KILL cr);
9556
9557 format %{ "orl $dst, $src\t# int" %}
9558 opcode(0x0B);
9559 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9560 ins_pipe(ialu_reg_reg);
9561 %}
9562
9563 // Or Register with Immediate
9564 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9565 %{
9566 match(Set dst (OrI dst src));
9567 effect(KILL cr);
9568
9569 format %{ "orl $dst, $src\t# int" %}
9570 opcode(0x81, 0x01); /* Opcode 81 /1 id */
9571 ins_encode(OpcSErm(dst, src), Con8or32(src));
9572 ins_pipe(ialu_reg);
9573 %}
9574
9575 // Or Register with Memory
9576 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9577 %{
9578 match(Set dst (OrI dst (LoadI src)));
9579 effect(KILL cr);
9580
9581 ins_cost(125);
9582 format %{ "orl $dst, $src\t# int" %}
9583 opcode(0x0B);
9584 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9585 ins_pipe(ialu_reg_mem);
9586 %}
9587
9588 // Or Memory with Register
9589 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9590 %{
9591 match(Set dst (StoreB dst (OrI (LoadB dst) src)));
9592 effect(KILL cr);
9593
9594 ins_cost(150);
9595 format %{ "orb $dst, $src\t# byte" %}
9596 opcode(0x08);
9597 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst));
9598 ins_pipe(ialu_mem_reg);
9599 %}
9600
9601 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9602 %{
9603 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9604 effect(KILL cr);
9605
9606 ins_cost(150);
9607 format %{ "orl $dst, $src\t# int" %}
9608 opcode(0x09); /* Opcode 09 /r */
9609 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9610 ins_pipe(ialu_mem_reg);
9611 %}
9612
9613 // Or Memory with Immediate
9614 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr)
9615 %{
9616 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9617 effect(KILL cr);
9618
9619 ins_cost(125);
9620 format %{ "orl $dst, $src\t# int" %}
9621 opcode(0x81, 0x1); /* Opcode 81 /1 id */
9622 ins_encode(REX_mem(dst), OpcSE(src),
9623 RM_opc_mem(secondary, dst), Con8or32(src));
9624 ins_pipe(ialu_mem_imm);
9625 %}
9626
9627 // Xor Instructions
9628 // Xor Register with Register
9629 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9630 %{
9631 match(Set dst (XorI dst src));
9632 effect(KILL cr);
9633
9634 format %{ "xorl $dst, $src\t# int" %}
9635 opcode(0x33);
9636 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9637 ins_pipe(ialu_reg_reg);
9638 %}
9639
9640 // Xor Register with Immediate -1
9641 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
9642 match(Set dst (XorI dst imm));
9643
9644 format %{ "not $dst" %}
9645 ins_encode %{
9646 __ notl($dst$$Register);
9647 %}
9648 ins_pipe(ialu_reg);
9649 %}
9650
9651 // Xor Register with Immediate
9652 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9653 %{
9654 match(Set dst (XorI dst src));
9655 effect(KILL cr);
9656
9657 format %{ "xorl $dst, $src\t# int" %}
9658 opcode(0x81, 0x06); /* Opcode 81 /6 id */
9659 ins_encode(OpcSErm(dst, src), Con8or32(src));
9660 ins_pipe(ialu_reg);
9661 %}
9662
9663 // Xor Register with Memory
9664 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9665 %{
9666 match(Set dst (XorI dst (LoadI src)));
9667 effect(KILL cr);
9668
9669 ins_cost(125);
9670 format %{ "xorl $dst, $src\t# int" %}
9671 opcode(0x33);
9672 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9673 ins_pipe(ialu_reg_mem);
9674 %}
9675
9676 // Xor Memory with Register
9677 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9678 %{
9679 match(Set dst (StoreB dst (XorI (LoadB dst) src)));
9680 effect(KILL cr);
9681
9682 ins_cost(150);
9683 format %{ "xorb $dst, $src\t# byte" %}
9684 opcode(0x30);
9685 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst));
9686 ins_pipe(ialu_mem_reg);
9687 %}
9688
9689 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9690 %{
9691 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9692 effect(KILL cr);
9693
9694 ins_cost(150);
9695 format %{ "xorl $dst, $src\t# int" %}
9696 opcode(0x31); /* Opcode 31 /r */
9697 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9698 ins_pipe(ialu_mem_reg);
9699 %}
9700
9701 // Xor Memory with Immediate
9702 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr)
9703 %{
9704 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9705 effect(KILL cr);
9706
9707 ins_cost(125);
9708 format %{ "xorl $dst, $src\t# int" %}
9709 opcode(0x81, 0x6); /* Opcode 81 /6 id */
9710 ins_encode(REX_mem(dst), OpcSE(src),
9711 RM_opc_mem(secondary, dst), Con8or32(src));
9712 ins_pipe(ialu_mem_imm);
9713 %}
9714
9715
9716 // Long Logical Instructions
9717
9718 // And Instructions
9719 // And Register with Register
9720 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9721 %{
9722 match(Set dst (AndL dst src));
9723 effect(KILL cr);
9724
9725 format %{ "andq $dst, $src\t# long" %}
9726 opcode(0x23);
9727 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9728 ins_pipe(ialu_reg_reg);
9729 %}
9730
9731 // And Register with Immediate 255
9732 instruct andL_rReg_imm255(rRegL dst, immL_255 src)
9733 %{
9734 match(Set dst (AndL dst src));
9735
9736 format %{ "movzbq $dst, $dst\t# long & 0xFF" %}
9737 opcode(0x0F, 0xB6);
9738 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9739 ins_pipe(ialu_reg);
9740 %}
9741
9742 // And Register with Immediate 65535
9743 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
9744 %{
9745 match(Set dst (AndL dst src));
9746
9747 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %}
9748 opcode(0x0F, 0xB7);
9749 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9750 ins_pipe(ialu_reg);
9751 %}
9752
9753 // And Register with Immediate
9754 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9755 %{
9756 match(Set dst (AndL dst src));
9757 effect(KILL cr);
9758
9759 format %{ "andq $dst, $src\t# long" %}
9760 opcode(0x81, 0x04); /* Opcode 81 /4 */
9761 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9762 ins_pipe(ialu_reg);
9763 %}
9764
9765 // And Register with Memory
9766 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9767 %{
9768 match(Set dst (AndL dst (LoadL src)));
9769 effect(KILL cr);
9770
9771 ins_cost(125);
9772 format %{ "andq $dst, $src\t# long" %}
9773 opcode(0x23);
9774 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9775 ins_pipe(ialu_reg_mem);
9776 %}
9777
9778 // And Memory with Register
9779 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9780 %{
9781 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9782 effect(KILL cr);
9783
9784 ins_cost(150);
9785 format %{ "andq $dst, $src\t# long" %}
9786 opcode(0x21); /* Opcode 21 /r */
9787 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9788 ins_pipe(ialu_mem_reg);
9789 %}
9790
9791 // And Memory with Immediate
9792 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9793 %{
9794 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9795 effect(KILL cr);
9796
9797 ins_cost(125);
9798 format %{ "andq $dst, $src\t# long" %}
9799 opcode(0x81, 0x4); /* Opcode 81 /4 id */
9800 ins_encode(REX_mem_wide(dst), OpcSE(src),
9801 RM_opc_mem(secondary, dst), Con8or32(src));
9802 ins_pipe(ialu_mem_imm);
9803 %}
9804
9805 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr)
9806 %{
9807 // con should be a pure 64-bit immediate given that not(con) is a power of 2
9808 // because AND/OR works well enough for 8/32-bit values.
9809 predicate(log2_long(~n->in(3)->in(2)->get_long()) > 30);
9810
9811 match(Set dst (StoreL dst (AndL (LoadL dst) con)));
9812 effect(KILL cr);
9813
9814 ins_cost(125);
9815 format %{ "btrq $dst, log2(not($con))\t# long" %}
9816 ins_encode %{
9817 __ btrq($dst$$Address, log2_long(~$con$$constant));
9818 %}
9819 ins_pipe(ialu_mem_imm);
9820 %}
9821
9822 // BMI1 instructions
9823 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{
9824 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2)));
9825 predicate(UseBMI1Instructions);
9826 effect(KILL cr);
9827
9828 ins_cost(125);
9829 format %{ "andnq $dst, $src1, $src2" %}
9830
9831 ins_encode %{
9832 __ andnq($dst$$Register, $src1$$Register, $src2$$Address);
9833 %}
9834 ins_pipe(ialu_reg_mem);
9835 %}
9836
9837 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{
9838 match(Set dst (AndL (XorL src1 minus_1) src2));
9839 predicate(UseBMI1Instructions);
9840 effect(KILL cr);
9841
9842 format %{ "andnq $dst, $src1, $src2" %}
9843
9844 ins_encode %{
9845 __ andnq($dst$$Register, $src1$$Register, $src2$$Register);
9846 %}
9847 ins_pipe(ialu_reg_mem);
9848 %}
9849
9850 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{
9851 match(Set dst (AndL (SubL imm_zero src) src));
9852 predicate(UseBMI1Instructions);
9853 effect(KILL cr);
9854
9855 format %{ "blsiq $dst, $src" %}
9856
9857 ins_encode %{
9858 __ blsiq($dst$$Register, $src$$Register);
9859 %}
9860 ins_pipe(ialu_reg);
9861 %}
9862
9863 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{
9864 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) ));
9865 predicate(UseBMI1Instructions);
9866 effect(KILL cr);
9867
9868 ins_cost(125);
9869 format %{ "blsiq $dst, $src" %}
9870
9871 ins_encode %{
9872 __ blsiq($dst$$Register, $src$$Address);
9873 %}
9874 ins_pipe(ialu_reg_mem);
9875 %}
9876
9877 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr)
9878 %{
9879 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) );
9880 predicate(UseBMI1Instructions);
9881 effect(KILL cr);
9882
9883 ins_cost(125);
9884 format %{ "blsmskq $dst, $src" %}
9885
9886 ins_encode %{
9887 __ blsmskq($dst$$Register, $src$$Address);
9888 %}
9889 ins_pipe(ialu_reg_mem);
9890 %}
9891
9892 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr)
9893 %{
9894 match(Set dst (XorL (AddL src minus_1) src));
9895 predicate(UseBMI1Instructions);
9896 effect(KILL cr);
9897
9898 format %{ "blsmskq $dst, $src" %}
9899
9900 ins_encode %{
9901 __ blsmskq($dst$$Register, $src$$Register);
9902 %}
9903
9904 ins_pipe(ialu_reg);
9905 %}
9906
9907 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr)
9908 %{
9909 match(Set dst (AndL (AddL src minus_1) src) );
9910 predicate(UseBMI1Instructions);
9911 effect(KILL cr);
9912
9913 format %{ "blsrq $dst, $src" %}
9914
9915 ins_encode %{
9916 __ blsrq($dst$$Register, $src$$Register);
9917 %}
9918
9919 ins_pipe(ialu_reg);
9920 %}
9921
9922 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr)
9923 %{
9924 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) );
9925 predicate(UseBMI1Instructions);
9926 effect(KILL cr);
9927
9928 ins_cost(125);
9929 format %{ "blsrq $dst, $src" %}
9930
9931 ins_encode %{
9932 __ blsrq($dst$$Register, $src$$Address);
9933 %}
9934
9935 ins_pipe(ialu_reg);
9936 %}
9937
9938 // Or Instructions
9939 // Or Register with Register
9940 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9941 %{
9942 match(Set dst (OrL dst src));
9943 effect(KILL cr);
9944
9945 format %{ "orq $dst, $src\t# long" %}
9946 opcode(0x0B);
9947 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9948 ins_pipe(ialu_reg_reg);
9949 %}
9950
9951 // Use any_RegP to match R15 (TLS register) without spilling.
9952 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
9953 match(Set dst (OrL dst (CastP2X src)));
9954 effect(KILL cr);
9955
9956 format %{ "orq $dst, $src\t# long" %}
9957 opcode(0x0B);
9958 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9959 ins_pipe(ialu_reg_reg);
9960 %}
9961
9962
9963 // Or Register with Immediate
9964 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9965 %{
9966 match(Set dst (OrL dst src));
9967 effect(KILL cr);
9968
9969 format %{ "orq $dst, $src\t# long" %}
9970 opcode(0x81, 0x01); /* Opcode 81 /1 id */
9971 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9972 ins_pipe(ialu_reg);
9973 %}
9974
9975 // Or Register with Memory
9976 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9977 %{
9978 match(Set dst (OrL dst (LoadL src)));
9979 effect(KILL cr);
9980
9981 ins_cost(125);
9982 format %{ "orq $dst, $src\t# long" %}
9983 opcode(0x0B);
9984 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9985 ins_pipe(ialu_reg_mem);
9986 %}
9987
9988 // Or Memory with Register
9989 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9990 %{
9991 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
9992 effect(KILL cr);
9993
9994 ins_cost(150);
9995 format %{ "orq $dst, $src\t# long" %}
9996 opcode(0x09); /* Opcode 09 /r */
9997 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9998 ins_pipe(ialu_mem_reg);
9999 %}
10000
10001 // Or Memory with Immediate
10002 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
10003 %{
10004 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
10005 effect(KILL cr);
10006
10007 ins_cost(125);
10008 format %{ "orq $dst, $src\t# long" %}
10009 opcode(0x81, 0x1); /* Opcode 81 /1 id */
10010 ins_encode(REX_mem_wide(dst), OpcSE(src),
10011 RM_opc_mem(secondary, dst), Con8or32(src));
10012 ins_pipe(ialu_mem_imm);
10013 %}
10014
10015 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr)
10016 %{
10017 // con should be a pure 64-bit power of 2 immediate
10018 // because AND/OR works well enough for 8/32-bit values.
10019 predicate(log2_long(n->in(3)->in(2)->get_long()) > 31);
10020
10021 match(Set dst (StoreL dst (OrL (LoadL dst) con)));
10022 effect(KILL cr);
10023
10024 ins_cost(125);
10025 format %{ "btsq $dst, log2($con)\t# long" %}
10026 ins_encode %{
10027 __ btsq($dst$$Address, log2_long((julong)$con$$constant));
10028 %}
10029 ins_pipe(ialu_mem_imm);
10030 %}
10031
10032 // Xor Instructions
10033 // Xor Register with Register
10034 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
10035 %{
10036 match(Set dst (XorL dst src));
10037 effect(KILL cr);
10038
10039 format %{ "xorq $dst, $src\t# long" %}
10040 opcode(0x33);
10041 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
10042 ins_pipe(ialu_reg_reg);
10043 %}
10044
10045 // Xor Register with Immediate -1
10046 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
10047 match(Set dst (XorL dst imm));
10048
10049 format %{ "notq $dst" %}
10050 ins_encode %{
10051 __ notq($dst$$Register);
10052 %}
10053 ins_pipe(ialu_reg);
10054 %}
10055
10056 // Xor Register with Immediate
10057 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
10058 %{
10059 match(Set dst (XorL dst src));
10060 effect(KILL cr);
10061
10062 format %{ "xorq $dst, $src\t# long" %}
10063 opcode(0x81, 0x06); /* Opcode 81 /6 id */
10064 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
10065 ins_pipe(ialu_reg);
10066 %}
10067
10068 // Xor Register with Memory
10069 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
10070 %{
10071 match(Set dst (XorL dst (LoadL src)));
10072 effect(KILL cr);
10073
10074 ins_cost(125);
10075 format %{ "xorq $dst, $src\t# long" %}
10076 opcode(0x33);
10077 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
10078 ins_pipe(ialu_reg_mem);
10079 %}
10080
10081 // Xor Memory with Register
10082 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
10083 %{
10084 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
10085 effect(KILL cr);
10086
10087 ins_cost(150);
10088 format %{ "xorq $dst, $src\t# long" %}
10089 opcode(0x31); /* Opcode 31 /r */
10090 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
10091 ins_pipe(ialu_mem_reg);
10092 %}
10093
10094 // Xor Memory with Immediate
10095 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
10096 %{
10097 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
10098 effect(KILL cr);
10099
10100 ins_cost(125);
10101 format %{ "xorq $dst, $src\t# long" %}
10102 opcode(0x81, 0x6); /* Opcode 81 /6 id */
10103 ins_encode(REX_mem_wide(dst), OpcSE(src),
10104 RM_opc_mem(secondary, dst), Con8or32(src));
10105 ins_pipe(ialu_mem_imm);
10106 %}
10107
10108 // Convert Int to Boolean
10109 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr)
10110 %{
10111 match(Set dst (Conv2B src));
10112 effect(KILL cr);
10113
10114 format %{ "testl $src, $src\t# ci2b\n\t"
10115 "setnz $dst\n\t"
10116 "movzbl $dst, $dst" %}
10117 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl
10118 setNZ_reg(dst),
10119 REX_reg_breg(dst, dst), // movzbl
10120 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
10121 ins_pipe(pipe_slow); // XXX
10122 %}
10123
10124 // Convert Pointer to Boolean
10125 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr)
10126 %{
10127 match(Set dst (Conv2B src));
10128 effect(KILL cr);
10129
10130 format %{ "testq $src, $src\t# cp2b\n\t"
10131 "setnz $dst\n\t"
10132 "movzbl $dst, $dst" %}
10133 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq
10134 setNZ_reg(dst),
10135 REX_reg_breg(dst, dst), // movzbl
10136 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
10137 ins_pipe(pipe_slow); // XXX
10138 %}
10139
10140 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr)
10141 %{
10142 match(Set dst (CmpLTMask p q));
10143 effect(KILL cr);
10144
10145 ins_cost(400);
10146 format %{ "cmpl $p, $q\t# cmpLTMask\n\t"
10147 "setlt $dst\n\t"
10148 "movzbl $dst, $dst\n\t"
10149 "negl $dst" %}
10150 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl
10151 setLT_reg(dst),
10152 REX_reg_breg(dst, dst), // movzbl
10153 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst),
10154 neg_reg(dst));
10155 ins_pipe(pipe_slow);
10156 %}
10157
10158 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr)
10159 %{
10160 match(Set dst (CmpLTMask dst zero));
10161 effect(KILL cr);
10162
10163 ins_cost(100);
10164 format %{ "sarl $dst, #31\t# cmpLTMask0" %}
10165 ins_encode %{
10166 __ sarl($dst$$Register, 31);
10167 %}
10168 ins_pipe(ialu_reg);
10169 %}
10170
10171 /* Better to save a register than avoid a branch */
10172 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr)
10173 %{
10174 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
10175 effect(KILL cr);
10176 ins_cost(300);
10177 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t"
10178 "jge done\n\t"
10179 "addl $p,$y\n"
10180 "done: " %}
10181 ins_encode %{
10182 Register Rp = $p$$Register;
10183 Register Rq = $q$$Register;
10184 Register Ry = $y$$Register;
10185 Label done;
10186 __ subl(Rp, Rq);
10187 __ jccb(Assembler::greaterEqual, done);
10188 __ addl(Rp, Ry);
10189 __ bind(done);
10190 %}
10191 ins_pipe(pipe_cmplt);
10192 %}
10193
10194 /* Better to save a register than avoid a branch */
10195 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr)
10196 %{
10197 match(Set y (AndI (CmpLTMask p q) y));
10198 effect(KILL cr);
10199
10200 ins_cost(300);
10201
10202 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t"
10203 "jlt done\n\t"
10204 "xorl $y, $y\n"
10205 "done: " %}
10206 ins_encode %{
10207 Register Rp = $p$$Register;
10208 Register Rq = $q$$Register;
10209 Register Ry = $y$$Register;
10210 Label done;
10211 __ cmpl(Rp, Rq);
10212 __ jccb(Assembler::less, done);
10213 __ xorl(Ry, Ry);
10214 __ bind(done);
10215 %}
10216 ins_pipe(pipe_cmplt);
10217 %}
10218
10219
10220 //---------- FP Instructions------------------------------------------------
10221
10222 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
10223 %{
10224 match(Set cr (CmpF src1 src2));
10225
10226 ins_cost(145);
10227 format %{ "ucomiss $src1, $src2\n\t"
10228 "jnp,s exit\n\t"
10229 "pushfq\t# saw NaN, set CF\n\t"
10230 "andq [rsp], #0xffffff2b\n\t"
10231 "popfq\n"
10232 "exit:" %}
10233 ins_encode %{
10234 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10235 emit_cmpfp_fixup(_masm);
10236 %}
10237 ins_pipe(pipe_slow);
10238 %}
10239
10240 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
10241 match(Set cr (CmpF src1 src2));
10242
10243 ins_cost(100);
10244 format %{ "ucomiss $src1, $src2" %}
10245 ins_encode %{
10246 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10247 %}
10248 ins_pipe(pipe_slow);
10249 %}
10250
10251 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
10252 %{
10253 match(Set cr (CmpF src1 (LoadF src2)));
10254
10255 ins_cost(145);
10256 format %{ "ucomiss $src1, $src2\n\t"
10257 "jnp,s exit\n\t"
10258 "pushfq\t# saw NaN, set CF\n\t"
10259 "andq [rsp], #0xffffff2b\n\t"
10260 "popfq\n"
10261 "exit:" %}
10262 ins_encode %{
10263 __ ucomiss($src1$$XMMRegister, $src2$$Address);
10264 emit_cmpfp_fixup(_masm);
10265 %}
10266 ins_pipe(pipe_slow);
10267 %}
10268
10269 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
10270 match(Set cr (CmpF src1 (LoadF src2)));
10271
10272 ins_cost(100);
10273 format %{ "ucomiss $src1, $src2" %}
10274 ins_encode %{
10275 __ ucomiss($src1$$XMMRegister, $src2$$Address);
10276 %}
10277 ins_pipe(pipe_slow);
10278 %}
10279
10280 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
10281 match(Set cr (CmpF src con));
10282
10283 ins_cost(145);
10284 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10285 "jnp,s exit\n\t"
10286 "pushfq\t# saw NaN, set CF\n\t"
10287 "andq [rsp], #0xffffff2b\n\t"
10288 "popfq\n"
10289 "exit:" %}
10290 ins_encode %{
10291 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10292 emit_cmpfp_fixup(_masm);
10293 %}
10294 ins_pipe(pipe_slow);
10295 %}
10296
10297 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
10298 match(Set cr (CmpF src con));
10299 ins_cost(100);
10300 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
10301 ins_encode %{
10302 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10303 %}
10304 ins_pipe(pipe_slow);
10305 %}
10306
10307 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
10308 %{
10309 match(Set cr (CmpD src1 src2));
10310
10311 ins_cost(145);
10312 format %{ "ucomisd $src1, $src2\n\t"
10313 "jnp,s exit\n\t"
10314 "pushfq\t# saw NaN, set CF\n\t"
10315 "andq [rsp], #0xffffff2b\n\t"
10316 "popfq\n"
10317 "exit:" %}
10318 ins_encode %{
10319 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10320 emit_cmpfp_fixup(_masm);
10321 %}
10322 ins_pipe(pipe_slow);
10323 %}
10324
10325 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
10326 match(Set cr (CmpD src1 src2));
10327
10328 ins_cost(100);
10329 format %{ "ucomisd $src1, $src2 test" %}
10330 ins_encode %{
10331 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10332 %}
10333 ins_pipe(pipe_slow);
10334 %}
10335
10336 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
10337 %{
10338 match(Set cr (CmpD src1 (LoadD src2)));
10339
10340 ins_cost(145);
10341 format %{ "ucomisd $src1, $src2\n\t"
10342 "jnp,s exit\n\t"
10343 "pushfq\t# saw NaN, set CF\n\t"
10344 "andq [rsp], #0xffffff2b\n\t"
10345 "popfq\n"
10346 "exit:" %}
10347 ins_encode %{
10348 __ ucomisd($src1$$XMMRegister, $src2$$Address);
10349 emit_cmpfp_fixup(_masm);
10350 %}
10351 ins_pipe(pipe_slow);
10352 %}
10353
10354 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
10355 match(Set cr (CmpD src1 (LoadD src2)));
10356
10357 ins_cost(100);
10358 format %{ "ucomisd $src1, $src2" %}
10359 ins_encode %{
10360 __ ucomisd($src1$$XMMRegister, $src2$$Address);
10361 %}
10362 ins_pipe(pipe_slow);
10363 %}
10364
10365 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
10366 match(Set cr (CmpD src con));
10367
10368 ins_cost(145);
10369 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10370 "jnp,s exit\n\t"
10371 "pushfq\t# saw NaN, set CF\n\t"
10372 "andq [rsp], #0xffffff2b\n\t"
10373 "popfq\n"
10374 "exit:" %}
10375 ins_encode %{
10376 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10377 emit_cmpfp_fixup(_masm);
10378 %}
10379 ins_pipe(pipe_slow);
10380 %}
10381
10382 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
10383 match(Set cr (CmpD src con));
10384 ins_cost(100);
10385 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
10386 ins_encode %{
10387 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10388 %}
10389 ins_pipe(pipe_slow);
10390 %}
10391
10392 // Compare into -1,0,1
10393 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
10394 %{
10395 match(Set dst (CmpF3 src1 src2));
10396 effect(KILL cr);
10397
10398 ins_cost(275);
10399 format %{ "ucomiss $src1, $src2\n\t"
10400 "movl $dst, #-1\n\t"
10401 "jp,s done\n\t"
10402 "jb,s done\n\t"
10403 "setne $dst\n\t"
10404 "movzbl $dst, $dst\n"
10405 "done:" %}
10406 ins_encode %{
10407 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10408 emit_cmpfp3(_masm, $dst$$Register);
10409 %}
10410 ins_pipe(pipe_slow);
10411 %}
10412
10413 // Compare into -1,0,1
10414 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
10415 %{
10416 match(Set dst (CmpF3 src1 (LoadF src2)));
10417 effect(KILL cr);
10418
10419 ins_cost(275);
10420 format %{ "ucomiss $src1, $src2\n\t"
10421 "movl $dst, #-1\n\t"
10422 "jp,s done\n\t"
10423 "jb,s done\n\t"
10424 "setne $dst\n\t"
10425 "movzbl $dst, $dst\n"
10426 "done:" %}
10427 ins_encode %{
10428 __ ucomiss($src1$$XMMRegister, $src2$$Address);
10429 emit_cmpfp3(_masm, $dst$$Register);
10430 %}
10431 ins_pipe(pipe_slow);
10432 %}
10433
10434 // Compare into -1,0,1
10435 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
10436 match(Set dst (CmpF3 src con));
10437 effect(KILL cr);
10438
10439 ins_cost(275);
10440 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10441 "movl $dst, #-1\n\t"
10442 "jp,s done\n\t"
10443 "jb,s done\n\t"
10444 "setne $dst\n\t"
10445 "movzbl $dst, $dst\n"
10446 "done:" %}
10447 ins_encode %{
10448 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10449 emit_cmpfp3(_masm, $dst$$Register);
10450 %}
10451 ins_pipe(pipe_slow);
10452 %}
10453
10454 // Compare into -1,0,1
10455 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
10456 %{
10457 match(Set dst (CmpD3 src1 src2));
10458 effect(KILL cr);
10459
10460 ins_cost(275);
10461 format %{ "ucomisd $src1, $src2\n\t"
10462 "movl $dst, #-1\n\t"
10463 "jp,s done\n\t"
10464 "jb,s done\n\t"
10465 "setne $dst\n\t"
10466 "movzbl $dst, $dst\n"
10467 "done:" %}
10468 ins_encode %{
10469 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10470 emit_cmpfp3(_masm, $dst$$Register);
10471 %}
10472 ins_pipe(pipe_slow);
10473 %}
10474
10475 // Compare into -1,0,1
10476 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
10477 %{
10478 match(Set dst (CmpD3 src1 (LoadD src2)));
10479 effect(KILL cr);
10480
10481 ins_cost(275);
10482 format %{ "ucomisd $src1, $src2\n\t"
10483 "movl $dst, #-1\n\t"
10484 "jp,s done\n\t"
10485 "jb,s done\n\t"
10486 "setne $dst\n\t"
10487 "movzbl $dst, $dst\n"
10488 "done:" %}
10489 ins_encode %{
10490 __ ucomisd($src1$$XMMRegister, $src2$$Address);
10491 emit_cmpfp3(_masm, $dst$$Register);
10492 %}
10493 ins_pipe(pipe_slow);
10494 %}
10495
10496 // Compare into -1,0,1
10497 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
10498 match(Set dst (CmpD3 src con));
10499 effect(KILL cr);
10500
10501 ins_cost(275);
10502 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10503 "movl $dst, #-1\n\t"
10504 "jp,s done\n\t"
10505 "jb,s done\n\t"
10506 "setne $dst\n\t"
10507 "movzbl $dst, $dst\n"
10508 "done:" %}
10509 ins_encode %{
10510 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10511 emit_cmpfp3(_masm, $dst$$Register);
10512 %}
10513 ins_pipe(pipe_slow);
10514 %}
10515
10516 //----------Arithmetic Conversion Instructions---------------------------------
10517
10518 instruct convF2D_reg_reg(regD dst, regF src)
10519 %{
10520 match(Set dst (ConvF2D src));
10521
10522 format %{ "cvtss2sd $dst, $src" %}
10523 ins_encode %{
10524 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister);
10525 %}
10526 ins_pipe(pipe_slow); // XXX
10527 %}
10528
10529 instruct convF2D_reg_mem(regD dst, memory src)
10530 %{
10531 match(Set dst (ConvF2D (LoadF src)));
10532
10533 format %{ "cvtss2sd $dst, $src" %}
10534 ins_encode %{
10535 __ cvtss2sd ($dst$$XMMRegister, $src$$Address);
10536 %}
10537 ins_pipe(pipe_slow); // XXX
10538 %}
10539
10540 instruct convD2F_reg_reg(regF dst, regD src)
10541 %{
10542 match(Set dst (ConvD2F src));
10543
10544 format %{ "cvtsd2ss $dst, $src" %}
10545 ins_encode %{
10546 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister);
10547 %}
10548 ins_pipe(pipe_slow); // XXX
10549 %}
10550
10551 instruct convD2F_reg_mem(regF dst, memory src)
10552 %{
10553 match(Set dst (ConvD2F (LoadD src)));
10554
10555 format %{ "cvtsd2ss $dst, $src" %}
10556 ins_encode %{
10557 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address);
10558 %}
10559 ins_pipe(pipe_slow); // XXX
10560 %}
10561
10562 // XXX do mem variants
10563 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
10564 %{
10565 match(Set dst (ConvF2I src));
10566 effect(KILL cr);
10567 format %{ "convert_f2i $dst,$src" %}
10568 ins_encode %{
10569 __ convert_f2i($dst$$Register, $src$$XMMRegister);
10570 %}
10571 ins_pipe(pipe_slow);
10572 %}
10573
10574 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
10575 %{
10576 match(Set dst (ConvF2L src));
10577 effect(KILL cr);
10578 format %{ "convert_f2l $dst,$src"%}
10579 ins_encode %{
10580 __ convert_f2l($dst$$Register, $src$$XMMRegister);
10581 %}
10582 ins_pipe(pipe_slow);
10583 %}
10584
10585 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
10586 %{
10587 match(Set dst (ConvD2I src));
10588 effect(KILL cr);
10589 format %{ "convert_d2i $dst,$src"%}
10590 ins_encode %{
10591 __ convert_d2i($dst$$Register, $src$$XMMRegister);
10592 %}
10593 ins_pipe(pipe_slow);
10594 %}
10595
10596 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
10597 %{
10598 match(Set dst (ConvD2L src));
10599 effect(KILL cr);
10600 format %{ "convert_d2l $dst,$src"%}
10601 ins_encode %{
10602 __ convert_d2l($dst$$Register, $src$$XMMRegister);
10603 %}
10604 ins_pipe(pipe_slow);
10605 %}
10606
10607 instruct convI2F_reg_reg(regF dst, rRegI src)
10608 %{
10609 predicate(!UseXmmI2F);
10610 match(Set dst (ConvI2F src));
10611
10612 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10613 ins_encode %{
10614 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
10615 %}
10616 ins_pipe(pipe_slow); // XXX
10617 %}
10618
10619 instruct convI2F_reg_mem(regF dst, memory src)
10620 %{
10621 match(Set dst (ConvI2F (LoadI src)));
10622
10623 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10624 ins_encode %{
10625 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address);
10626 %}
10627 ins_pipe(pipe_slow); // XXX
10628 %}
10629
10630 instruct convI2D_reg_reg(regD dst, rRegI src)
10631 %{
10632 predicate(!UseXmmI2D);
10633 match(Set dst (ConvI2D src));
10634
10635 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10636 ins_encode %{
10637 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
10638 %}
10639 ins_pipe(pipe_slow); // XXX
10640 %}
10641
10642 instruct convI2D_reg_mem(regD dst, memory src)
10643 %{
10644 match(Set dst (ConvI2D (LoadI src)));
10645
10646 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10647 ins_encode %{
10648 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address);
10649 %}
10650 ins_pipe(pipe_slow); // XXX
10651 %}
10652
10653 instruct convXI2F_reg(regF dst, rRegI src)
10654 %{
10655 predicate(UseXmmI2F);
10656 match(Set dst (ConvI2F src));
10657
10658 format %{ "movdl $dst, $src\n\t"
10659 "cvtdq2psl $dst, $dst\t# i2f" %}
10660 ins_encode %{
10661 __ movdl($dst$$XMMRegister, $src$$Register);
10662 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
10663 %}
10664 ins_pipe(pipe_slow); // XXX
10665 %}
10666
10667 instruct convXI2D_reg(regD dst, rRegI src)
10668 %{
10669 predicate(UseXmmI2D);
10670 match(Set dst (ConvI2D src));
10671
10672 format %{ "movdl $dst, $src\n\t"
10673 "cvtdq2pdl $dst, $dst\t# i2d" %}
10674 ins_encode %{
10675 __ movdl($dst$$XMMRegister, $src$$Register);
10676 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
10677 %}
10678 ins_pipe(pipe_slow); // XXX
10679 %}
10680
10681 instruct convL2F_reg_reg(regF dst, rRegL src)
10682 %{
10683 match(Set dst (ConvL2F src));
10684
10685 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10686 ins_encode %{
10687 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register);
10688 %}
10689 ins_pipe(pipe_slow); // XXX
10690 %}
10691
10692 instruct convL2F_reg_mem(regF dst, memory src)
10693 %{
10694 match(Set dst (ConvL2F (LoadL src)));
10695
10696 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10697 ins_encode %{
10698 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address);
10699 %}
10700 ins_pipe(pipe_slow); // XXX
10701 %}
10702
10703 instruct convL2D_reg_reg(regD dst, rRegL src)
10704 %{
10705 match(Set dst (ConvL2D src));
10706
10707 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10708 ins_encode %{
10709 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register);
10710 %}
10711 ins_pipe(pipe_slow); // XXX
10712 %}
10713
10714 instruct convL2D_reg_mem(regD dst, memory src)
10715 %{
10716 match(Set dst (ConvL2D (LoadL src)));
10717
10718 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10719 ins_encode %{
10720 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address);
10721 %}
10722 ins_pipe(pipe_slow); // XXX
10723 %}
10724
10725 instruct convI2L_reg_reg(rRegL dst, rRegI src)
10726 %{
10727 match(Set dst (ConvI2L src));
10728
10729 ins_cost(125);
10730 format %{ "movslq $dst, $src\t# i2l" %}
10731 ins_encode %{
10732 __ movslq($dst$$Register, $src$$Register);
10733 %}
10734 ins_pipe(ialu_reg_reg);
10735 %}
10736
10737 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src)
10738 // %{
10739 // match(Set dst (ConvI2L src));
10740 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 &&
10741 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0);
10742 // predicate(((const TypeNode*) n)->type()->is_long()->_hi ==
10743 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi &&
10744 // ((const TypeNode*) n)->type()->is_long()->_lo ==
10745 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo);
10746
10747 // format %{ "movl $dst, $src\t# unsigned i2l" %}
10748 // ins_encode(enc_copy(dst, src));
10749 // // opcode(0x63); // needs REX.W
10750 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
10751 // ins_pipe(ialu_reg_reg);
10752 // %}
10753
10754 // Zero-extend convert int to long
10755 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
10756 %{
10757 match(Set dst (AndL (ConvI2L src) mask));
10758
10759 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10760 ins_encode %{
10761 if ($dst$$reg != $src$$reg) {
10762 __ movl($dst$$Register, $src$$Register);
10763 }
10764 %}
10765 ins_pipe(ialu_reg_reg);
10766 %}
10767
10768 // Zero-extend convert int to long
10769 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
10770 %{
10771 match(Set dst (AndL (ConvI2L (LoadI src)) mask));
10772
10773 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10774 ins_encode %{
10775 __ movl($dst$$Register, $src$$Address);
10776 %}
10777 ins_pipe(ialu_reg_mem);
10778 %}
10779
10780 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
10781 %{
10782 match(Set dst (AndL src mask));
10783
10784 format %{ "movl $dst, $src\t# zero-extend long" %}
10785 ins_encode %{
10786 __ movl($dst$$Register, $src$$Register);
10787 %}
10788 ins_pipe(ialu_reg_reg);
10789 %}
10790
10791 instruct convL2I_reg_reg(rRegI dst, rRegL src)
10792 %{
10793 match(Set dst (ConvL2I src));
10794
10795 format %{ "movl $dst, $src\t# l2i" %}
10796 ins_encode %{
10797 __ movl($dst$$Register, $src$$Register);
10798 %}
10799 ins_pipe(ialu_reg_reg);
10800 %}
10801
10802
10803 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
10804 match(Set dst (MoveF2I src));
10805 effect(DEF dst, USE src);
10806
10807 ins_cost(125);
10808 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %}
10809 ins_encode %{
10810 __ movl($dst$$Register, Address(rsp, $src$$disp));
10811 %}
10812 ins_pipe(ialu_reg_mem);
10813 %}
10814
10815 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
10816 match(Set dst (MoveI2F src));
10817 effect(DEF dst, USE src);
10818
10819 ins_cost(125);
10820 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %}
10821 ins_encode %{
10822 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
10823 %}
10824 ins_pipe(pipe_slow);
10825 %}
10826
10827 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
10828 match(Set dst (MoveD2L src));
10829 effect(DEF dst, USE src);
10830
10831 ins_cost(125);
10832 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %}
10833 ins_encode %{
10834 __ movq($dst$$Register, Address(rsp, $src$$disp));
10835 %}
10836 ins_pipe(ialu_reg_mem);
10837 %}
10838
10839 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
10840 predicate(!UseXmmLoadAndClearUpper);
10841 match(Set dst (MoveL2D src));
10842 effect(DEF dst, USE src);
10843
10844 ins_cost(125);
10845 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %}
10846 ins_encode %{
10847 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10848 %}
10849 ins_pipe(pipe_slow);
10850 %}
10851
10852 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
10853 predicate(UseXmmLoadAndClearUpper);
10854 match(Set dst (MoveL2D src));
10855 effect(DEF dst, USE src);
10856
10857 ins_cost(125);
10858 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %}
10859 ins_encode %{
10860 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10861 %}
10862 ins_pipe(pipe_slow);
10863 %}
10864
10865
10866 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
10867 match(Set dst (MoveF2I src));
10868 effect(DEF dst, USE src);
10869
10870 ins_cost(95); // XXX
10871 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %}
10872 ins_encode %{
10873 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
10874 %}
10875 ins_pipe(pipe_slow);
10876 %}
10877
10878 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
10879 match(Set dst (MoveI2F src));
10880 effect(DEF dst, USE src);
10881
10882 ins_cost(100);
10883 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %}
10884 ins_encode %{
10885 __ movl(Address(rsp, $dst$$disp), $src$$Register);
10886 %}
10887 ins_pipe( ialu_mem_reg );
10888 %}
10889
10890 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
10891 match(Set dst (MoveD2L src));
10892 effect(DEF dst, USE src);
10893
10894 ins_cost(95); // XXX
10895 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %}
10896 ins_encode %{
10897 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
10898 %}
10899 ins_pipe(pipe_slow);
10900 %}
10901
10902 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
10903 match(Set dst (MoveL2D src));
10904 effect(DEF dst, USE src);
10905
10906 ins_cost(100);
10907 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %}
10908 ins_encode %{
10909 __ movq(Address(rsp, $dst$$disp), $src$$Register);
10910 %}
10911 ins_pipe(ialu_mem_reg);
10912 %}
10913
10914 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
10915 match(Set dst (MoveF2I src));
10916 effect(DEF dst, USE src);
10917 ins_cost(85);
10918 format %{ "movd $dst,$src\t# MoveF2I" %}
10919 ins_encode %{
10920 __ movdl($dst$$Register, $src$$XMMRegister);
10921 %}
10922 ins_pipe( pipe_slow );
10923 %}
10924
10925 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
10926 match(Set dst (MoveD2L src));
10927 effect(DEF dst, USE src);
10928 ins_cost(85);
10929 format %{ "movd $dst,$src\t# MoveD2L" %}
10930 ins_encode %{
10931 __ movdq($dst$$Register, $src$$XMMRegister);
10932 %}
10933 ins_pipe( pipe_slow );
10934 %}
10935
10936 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
10937 match(Set dst (MoveI2F src));
10938 effect(DEF dst, USE src);
10939 ins_cost(100);
10940 format %{ "movd $dst,$src\t# MoveI2F" %}
10941 ins_encode %{
10942 __ movdl($dst$$XMMRegister, $src$$Register);
10943 %}
10944 ins_pipe( pipe_slow );
10945 %}
10946
10947 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
10948 match(Set dst (MoveL2D src));
10949 effect(DEF dst, USE src);
10950 ins_cost(100);
10951 format %{ "movd $dst,$src\t# MoveL2D" %}
10952 ins_encode %{
10953 __ movdq($dst$$XMMRegister, $src$$Register);
10954 %}
10955 ins_pipe( pipe_slow );
10956 %}
10957
10958
10959 // =======================================================================
10960 // fast clearing of an array
10961 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val,
10962 Universe dummy, rFlagsReg cr)
10963 %{
10964 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only());
10965 match(Set dummy (ClearArray (Binary cnt base) val));
10966 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr);
10967
10968 format %{ $$template
10969 $$emit$$"cmp InitArrayShortSize,rcx\n\t"
10970 $$emit$$"jg LARGE\n\t"
10971 $$emit$$"dec rcx\n\t"
10972 $$emit$$"js DONE\t# Zero length\n\t"
10973 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t"
10974 $$emit$$"dec rcx\n\t"
10975 $$emit$$"jge LOOP\n\t"
10976 $$emit$$"jmp DONE\n\t"
10977 $$emit$$"# LARGE:\n\t"
10978 if (UseFastStosb) {
10979 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t"
10980 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t"
10981 } else if (UseXMMForObjInit) {
10982 $$emit$$"movdq $tmp, $val\n\t"
10983 $$emit$$"punpcklqdq $tmp, $tmp\n\t"
10984 $$emit$$"vinserti128_high $tmp, $tmp\n\t"
10985 $$emit$$"jmpq L_zero_64_bytes\n\t"
10986 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
10987 $$emit$$"vmovdqu $tmp,(rax)\n\t"
10988 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t"
10989 $$emit$$"add 0x40,rax\n\t"
10990 $$emit$$"# L_zero_64_bytes:\n\t"
10991 $$emit$$"sub 0x8,rcx\n\t"
10992 $$emit$$"jge L_loop\n\t"
10993 $$emit$$"add 0x4,rcx\n\t"
10994 $$emit$$"jl L_tail\n\t"
10995 $$emit$$"vmovdqu $tmp,(rax)\n\t"
10996 $$emit$$"add 0x20,rax\n\t"
10997 $$emit$$"sub 0x4,rcx\n\t"
10998 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
10999 $$emit$$"add 0x4,rcx\n\t"
11000 $$emit$$"jle L_end\n\t"
11001 $$emit$$"dec rcx\n\t"
11002 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
11003 $$emit$$"vmovq xmm0,(rax)\n\t"
11004 $$emit$$"add 0x8,rax\n\t"
11005 $$emit$$"dec rcx\n\t"
11006 $$emit$$"jge L_sloop\n\t"
11007 $$emit$$"# L_end:\n\t"
11008 } else {
11009 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t"
11010 }
11011 $$emit$$"# DONE"
11012 %}
11013 ins_encode %{
11014 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register,
11015 $tmp$$XMMRegister, false, false);
11016 %}
11017 ins_pipe(pipe_slow);
11018 %}
11019
11020 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val,
11021 Universe dummy, rFlagsReg cr)
11022 %{
11023 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only());
11024 match(Set dummy (ClearArray (Binary cnt base) val));
11025 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr);
11026
11027 format %{ $$template
11028 $$emit$$"cmp InitArrayShortSize,rcx\n\t"
11029 $$emit$$"jg LARGE\n\t"
11030 $$emit$$"dec rcx\n\t"
11031 $$emit$$"js DONE\t# Zero length\n\t"
11032 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t"
11033 $$emit$$"dec rcx\n\t"
11034 $$emit$$"jge LOOP\n\t"
11035 $$emit$$"jmp DONE\n\t"
11036 $$emit$$"# LARGE:\n\t"
11037 if (UseXMMForObjInit) {
11038 $$emit$$"movdq $tmp, $val\n\t"
11039 $$emit$$"punpcklqdq $tmp, $tmp\n\t"
11040 $$emit$$"vinserti128_high $tmp, $tmp\n\t"
11041 $$emit$$"jmpq L_zero_64_bytes\n\t"
11042 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
11043 $$emit$$"vmovdqu $tmp,(rax)\n\t"
11044 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t"
11045 $$emit$$"add 0x40,rax\n\t"
11046 $$emit$$"# L_zero_64_bytes:\n\t"
11047 $$emit$$"sub 0x8,rcx\n\t"
11048 $$emit$$"jge L_loop\n\t"
11049 $$emit$$"add 0x4,rcx\n\t"
11050 $$emit$$"jl L_tail\n\t"
11051 $$emit$$"vmovdqu $tmp,(rax)\n\t"
11052 $$emit$$"add 0x20,rax\n\t"
11053 $$emit$$"sub 0x4,rcx\n\t"
11054 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
11055 $$emit$$"add 0x4,rcx\n\t"
11056 $$emit$$"jle L_end\n\t"
11057 $$emit$$"dec rcx\n\t"
11058 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
11059 $$emit$$"vmovq xmm0,(rax)\n\t"
11060 $$emit$$"add 0x8,rax\n\t"
11061 $$emit$$"dec rcx\n\t"
11062 $$emit$$"jge L_sloop\n\t"
11063 $$emit$$"# L_end:\n\t"
11064 } else {
11065 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t"
11066 }
11067 $$emit$$"# DONE"
11068 %}
11069 ins_encode %{
11070 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register,
11071 $tmp$$XMMRegister, false, true);
11072 %}
11073 ins_pipe(pipe_slow);
11074 %}
11075
11076 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val,
11077 Universe dummy, rFlagsReg cr)
11078 %{
11079 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only());
11080 match(Set dummy (ClearArray (Binary cnt base) val));
11081 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr);
11082
11083 format %{ $$template
11084 if (UseFastStosb) {
11085 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t"
11086 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--"
11087 } else if (UseXMMForObjInit) {
11088 $$emit$$"movdq $tmp, $val\n\t"
11089 $$emit$$"punpcklqdq $tmp, $tmp\n\t"
11090 $$emit$$"vinserti128_high $tmp, $tmp\n\t"
11091 $$emit$$"jmpq L_zero_64_bytes\n\t"
11092 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
11093 $$emit$$"vmovdqu $tmp,(rax)\n\t"
11094 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t"
11095 $$emit$$"add 0x40,rax\n\t"
11096 $$emit$$"# L_zero_64_bytes:\n\t"
11097 $$emit$$"sub 0x8,rcx\n\t"
11098 $$emit$$"jge L_loop\n\t"
11099 $$emit$$"add 0x4,rcx\n\t"
11100 $$emit$$"jl L_tail\n\t"
11101 $$emit$$"vmovdqu $tmp,(rax)\n\t"
11102 $$emit$$"add 0x20,rax\n\t"
11103 $$emit$$"sub 0x4,rcx\n\t"
11104 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
11105 $$emit$$"add 0x4,rcx\n\t"
11106 $$emit$$"jle L_end\n\t"
11107 $$emit$$"dec rcx\n\t"
11108 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
11109 $$emit$$"vmovq xmm0,(rax)\n\t"
11110 $$emit$$"add 0x8,rax\n\t"
11111 $$emit$$"dec rcx\n\t"
11112 $$emit$$"jge L_sloop\n\t"
11113 $$emit$$"# L_end:\n\t"
11114 } else {
11115 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--"
11116 }
11117 %}
11118 ins_encode %{
11119 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register,
11120 $tmp$$XMMRegister, true, false);
11121 %}
11122 ins_pipe(pipe_slow);
11123 %}
11124
11125 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val,
11126 Universe dummy, rFlagsReg cr)
11127 %{
11128 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only());
11129 match(Set dummy (ClearArray (Binary cnt base) val));
11130 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr);
11131
11132 format %{ $$template
11133 if (UseXMMForObjInit) {
11134 $$emit$$"movdq $tmp, $val\n\t"
11135 $$emit$$"punpcklqdq $tmp, $tmp\n\t"
11136 $$emit$$"vinserti128_high $tmp, $tmp\n\t"
11137 $$emit$$"jmpq L_zero_64_bytes\n\t"
11138 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
11139 $$emit$$"vmovdqu $tmp,(rax)\n\t"
11140 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t"
11141 $$emit$$"add 0x40,rax\n\t"
11142 $$emit$$"# L_zero_64_bytes:\n\t"
11143 $$emit$$"sub 0x8,rcx\n\t"
11144 $$emit$$"jge L_loop\n\t"
11145 $$emit$$"add 0x4,rcx\n\t"
11146 $$emit$$"jl L_tail\n\t"
11147 $$emit$$"vmovdqu $tmp,(rax)\n\t"
11148 $$emit$$"add 0x20,rax\n\t"
11149 $$emit$$"sub 0x4,rcx\n\t"
11150 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
11151 $$emit$$"add 0x4,rcx\n\t"
11152 $$emit$$"jle L_end\n\t"
11153 $$emit$$"dec rcx\n\t"
11154 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
11155 $$emit$$"vmovq xmm0,(rax)\n\t"
11156 $$emit$$"add 0x8,rax\n\t"
11157 $$emit$$"dec rcx\n\t"
11158 $$emit$$"jge L_sloop\n\t"
11159 $$emit$$"# L_end:\n\t"
11160 } else {
11161 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--"
11162 }
11163 %}
11164 ins_encode %{
11165 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register,
11166 $tmp$$XMMRegister, true, true);
11167 %}
11168 ins_pipe(pipe_slow);
11169 %}
11170
11171 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
11172 rax_RegI result, legRegD tmp1, rFlagsReg cr)
11173 %{
11174 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11175 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11176 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11177
11178 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11179 ins_encode %{
11180 __ string_compare($str1$$Register, $str2$$Register,
11181 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11182 $tmp1$$XMMRegister, StrIntrinsicNode::LL);
11183 %}
11184 ins_pipe( pipe_slow );
11185 %}
11186
11187 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
11188 rax_RegI result, legRegD tmp1, rFlagsReg cr)
11189 %{
11190 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11191 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11192 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11193
11194 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11195 ins_encode %{
11196 __ string_compare($str1$$Register, $str2$$Register,
11197 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11198 $tmp1$$XMMRegister, StrIntrinsicNode::UU);
11199 %}
11200 ins_pipe( pipe_slow );
11201 %}
11202
11203 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
11204 rax_RegI result, legRegD tmp1, rFlagsReg cr)
11205 %{
11206 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11207 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11208 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11209
11210 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11211 ins_encode %{
11212 __ string_compare($str1$$Register, $str2$$Register,
11213 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11214 $tmp1$$XMMRegister, StrIntrinsicNode::LU);
11215 %}
11216 ins_pipe( pipe_slow );
11217 %}
11218
11219 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2,
11220 rax_RegI result, legRegD tmp1, rFlagsReg cr)
11221 %{
11222 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11223 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11224 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11225
11226 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11227 ins_encode %{
11228 __ string_compare($str2$$Register, $str1$$Register,
11229 $cnt2$$Register, $cnt1$$Register, $result$$Register,
11230 $tmp1$$XMMRegister, StrIntrinsicNode::UL);
11231 %}
11232 ins_pipe( pipe_slow );
11233 %}
11234
11235 // fast search of substring with known size.
11236 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
11237 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
11238 %{
11239 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
11240 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
11241 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
11242
11243 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %}
11244 ins_encode %{
11245 int icnt2 = (int)$int_cnt2$$constant;
11246 if (icnt2 >= 16) {
11247 // IndexOf for constant substrings with size >= 16 elements
11248 // which don't need to be loaded through stack.
11249 __ string_indexofC8($str1$$Register, $str2$$Register,
11250 $cnt1$$Register, $cnt2$$Register,
11251 icnt2, $result$$Register,
11252 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
11253 } else {
11254 // Small strings are loaded through stack if they cross page boundary.
11255 __ string_indexof($str1$$Register, $str2$$Register,
11256 $cnt1$$Register, $cnt2$$Register,
11257 icnt2, $result$$Register,
11258 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
11259 }
11260 %}
11261 ins_pipe( pipe_slow );
11262 %}
11263
11264 // fast search of substring with known size.
11265 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
11266 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
11267 %{
11268 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
11269 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
11270 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
11271
11272 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %}
11273 ins_encode %{
11274 int icnt2 = (int)$int_cnt2$$constant;
11275 if (icnt2 >= 8) {
11276 // IndexOf for constant substrings with size >= 8 elements
11277 // which don't need to be loaded through stack.
11278 __ string_indexofC8($str1$$Register, $str2$$Register,
11279 $cnt1$$Register, $cnt2$$Register,
11280 icnt2, $result$$Register,
11281 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
11282 } else {
11283 // Small strings are loaded through stack if they cross page boundary.
11284 __ string_indexof($str1$$Register, $str2$$Register,
11285 $cnt1$$Register, $cnt2$$Register,
11286 icnt2, $result$$Register,
11287 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
11288 }
11289 %}
11290 ins_pipe( pipe_slow );
11291 %}
11292
11293 // fast search of substring with known size.
11294 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
11295 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
11296 %{
11297 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
11298 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
11299 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
11300
11301 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %}
11302 ins_encode %{
11303 int icnt2 = (int)$int_cnt2$$constant;
11304 if (icnt2 >= 8) {
11305 // IndexOf for constant substrings with size >= 8 elements
11306 // which don't need to be loaded through stack.
11307 __ string_indexofC8($str1$$Register, $str2$$Register,
11308 $cnt1$$Register, $cnt2$$Register,
11309 icnt2, $result$$Register,
11310 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
11311 } else {
11312 // Small strings are loaded through stack if they cross page boundary.
11313 __ string_indexof($str1$$Register, $str2$$Register,
11314 $cnt1$$Register, $cnt2$$Register,
11315 icnt2, $result$$Register,
11316 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
11317 }
11318 %}
11319 ins_pipe( pipe_slow );
11320 %}
11321
11322 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
11323 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr)
11324 %{
11325 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
11326 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11327 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
11328
11329 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
11330 ins_encode %{
11331 __ string_indexof($str1$$Register, $str2$$Register,
11332 $cnt1$$Register, $cnt2$$Register,
11333 (-1), $result$$Register,
11334 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
11335 %}
11336 ins_pipe( pipe_slow );
11337 %}
11338
11339 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
11340 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr)
11341 %{
11342 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
11343 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11344 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
11345
11346 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
11347 ins_encode %{
11348 __ string_indexof($str1$$Register, $str2$$Register,
11349 $cnt1$$Register, $cnt2$$Register,
11350 (-1), $result$$Register,
11351 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
11352 %}
11353 ins_pipe( pipe_slow );
11354 %}
11355
11356 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
11357 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr)
11358 %{
11359 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
11360 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11361 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
11362
11363 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
11364 ins_encode %{
11365 __ string_indexof($str1$$Register, $str2$$Register,
11366 $cnt1$$Register, $cnt2$$Register,
11367 (-1), $result$$Register,
11368 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
11369 %}
11370 ins_pipe( pipe_slow );
11371 %}
11372
11373 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch,
11374 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr)
11375 %{
11376 predicate(UseSSE42Intrinsics);
11377 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
11378 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr);
11379 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %}
11380 ins_encode %{
11381 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register,
11382 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register);
11383 %}
11384 ins_pipe( pipe_slow );
11385 %}
11386
11387 // fast string equals
11388 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
11389 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr)
11390 %{
11391 match(Set result (StrEquals (Binary str1 str2) cnt));
11392 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
11393
11394 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
11395 ins_encode %{
11396 __ arrays_equals(false, $str1$$Register, $str2$$Register,
11397 $cnt$$Register, $result$$Register, $tmp3$$Register,
11398 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */);
11399 %}
11400 ins_pipe( pipe_slow );
11401 %}
11402
11403 // fast array equals
11404 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
11405 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
11406 %{
11407 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11408 match(Set result (AryEq ary1 ary2));
11409 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
11410
11411 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
11412 ins_encode %{
11413 __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
11414 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11415 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */);
11416 %}
11417 ins_pipe( pipe_slow );
11418 %}
11419
11420 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
11421 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
11422 %{
11423 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11424 match(Set result (AryEq ary1 ary2));
11425 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
11426
11427 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
11428 ins_encode %{
11429 __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
11430 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11431 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */);
11432 %}
11433 ins_pipe( pipe_slow );
11434 %}
11435
11436 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result,
11437 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr)
11438 %{
11439 match(Set result (HasNegatives ary1 len));
11440 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr);
11441
11442 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %}
11443 ins_encode %{
11444 __ has_negatives($ary1$$Register, $len$$Register,
11445 $result$$Register, $tmp3$$Register,
11446 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11447 %}
11448 ins_pipe( pipe_slow );
11449 %}
11450
11451 // fast char[] to byte[] compression
11452 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4,
11453 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
11454 match(Set result (StrCompressedCopy src (Binary dst len)));
11455 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
11456
11457 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %}
11458 ins_encode %{
11459 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
11460 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
11461 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
11462 %}
11463 ins_pipe( pipe_slow );
11464 %}
11465
11466 // fast byte[] to char[] inflation
11467 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len,
11468 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{
11469 match(Set dummy (StrInflatedCopy src (Binary dst len)));
11470 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
11471
11472 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %}
11473 ins_encode %{
11474 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
11475 $tmp1$$XMMRegister, $tmp2$$Register);
11476 %}
11477 ins_pipe( pipe_slow );
11478 %}
11479
11480 // encode char[] to byte[] in ISO_8859_1
11481 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len,
11482 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4,
11483 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
11484 match(Set result (EncodeISOArray src (Binary dst len)));
11485 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
11486
11487 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %}
11488 ins_encode %{
11489 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
11490 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
11491 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
11492 %}
11493 ins_pipe( pipe_slow );
11494 %}
11495
11496 //----------Overflow Math Instructions-----------------------------------------
11497
11498 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2)
11499 %{
11500 match(Set cr (OverflowAddI op1 op2));
11501 effect(DEF cr, USE_KILL op1, USE op2);
11502
11503 format %{ "addl $op1, $op2\t# overflow check int" %}
11504
11505 ins_encode %{
11506 __ addl($op1$$Register, $op2$$Register);
11507 %}
11508 ins_pipe(ialu_reg_reg);
11509 %}
11510
11511 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2)
11512 %{
11513 match(Set cr (OverflowAddI op1 op2));
11514 effect(DEF cr, USE_KILL op1, USE op2);
11515
11516 format %{ "addl $op1, $op2\t# overflow check int" %}
11517
11518 ins_encode %{
11519 __ addl($op1$$Register, $op2$$constant);
11520 %}
11521 ins_pipe(ialu_reg_reg);
11522 %}
11523
11524 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2)
11525 %{
11526 match(Set cr (OverflowAddL op1 op2));
11527 effect(DEF cr, USE_KILL op1, USE op2);
11528
11529 format %{ "addq $op1, $op2\t# overflow check long" %}
11530 ins_encode %{
11531 __ addq($op1$$Register, $op2$$Register);
11532 %}
11533 ins_pipe(ialu_reg_reg);
11534 %}
11535
11536 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2)
11537 %{
11538 match(Set cr (OverflowAddL op1 op2));
11539 effect(DEF cr, USE_KILL op1, USE op2);
11540
11541 format %{ "addq $op1, $op2\t# overflow check long" %}
11542 ins_encode %{
11543 __ addq($op1$$Register, $op2$$constant);
11544 %}
11545 ins_pipe(ialu_reg_reg);
11546 %}
11547
11548 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
11549 %{
11550 match(Set cr (OverflowSubI op1 op2));
11551
11552 format %{ "cmpl $op1, $op2\t# overflow check int" %}
11553 ins_encode %{
11554 __ cmpl($op1$$Register, $op2$$Register);
11555 %}
11556 ins_pipe(ialu_reg_reg);
11557 %}
11558
11559 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
11560 %{
11561 match(Set cr (OverflowSubI op1 op2));
11562
11563 format %{ "cmpl $op1, $op2\t# overflow check int" %}
11564 ins_encode %{
11565 __ cmpl($op1$$Register, $op2$$constant);
11566 %}
11567 ins_pipe(ialu_reg_reg);
11568 %}
11569
11570 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
11571 %{
11572 match(Set cr (OverflowSubL op1 op2));
11573
11574 format %{ "cmpq $op1, $op2\t# overflow check long" %}
11575 ins_encode %{
11576 __ cmpq($op1$$Register, $op2$$Register);
11577 %}
11578 ins_pipe(ialu_reg_reg);
11579 %}
11580
11581 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
11582 %{
11583 match(Set cr (OverflowSubL op1 op2));
11584
11585 format %{ "cmpq $op1, $op2\t# overflow check long" %}
11586 ins_encode %{
11587 __ cmpq($op1$$Register, $op2$$constant);
11588 %}
11589 ins_pipe(ialu_reg_reg);
11590 %}
11591
11592 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2)
11593 %{
11594 match(Set cr (OverflowSubI zero op2));
11595 effect(DEF cr, USE_KILL op2);
11596
11597 format %{ "negl $op2\t# overflow check int" %}
11598 ins_encode %{
11599 __ negl($op2$$Register);
11600 %}
11601 ins_pipe(ialu_reg_reg);
11602 %}
11603
11604 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2)
11605 %{
11606 match(Set cr (OverflowSubL zero op2));
11607 effect(DEF cr, USE_KILL op2);
11608
11609 format %{ "negq $op2\t# overflow check long" %}
11610 ins_encode %{
11611 __ negq($op2$$Register);
11612 %}
11613 ins_pipe(ialu_reg_reg);
11614 %}
11615
11616 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2)
11617 %{
11618 match(Set cr (OverflowMulI op1 op2));
11619 effect(DEF cr, USE_KILL op1, USE op2);
11620
11621 format %{ "imull $op1, $op2\t# overflow check int" %}
11622 ins_encode %{
11623 __ imull($op1$$Register, $op2$$Register);
11624 %}
11625 ins_pipe(ialu_reg_reg_alu0);
11626 %}
11627
11628 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp)
11629 %{
11630 match(Set cr (OverflowMulI op1 op2));
11631 effect(DEF cr, TEMP tmp, USE op1, USE op2);
11632
11633 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %}
11634 ins_encode %{
11635 __ imull($tmp$$Register, $op1$$Register, $op2$$constant);
11636 %}
11637 ins_pipe(ialu_reg_reg_alu0);
11638 %}
11639
11640 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2)
11641 %{
11642 match(Set cr (OverflowMulL op1 op2));
11643 effect(DEF cr, USE_KILL op1, USE op2);
11644
11645 format %{ "imulq $op1, $op2\t# overflow check long" %}
11646 ins_encode %{
11647 __ imulq($op1$$Register, $op2$$Register);
11648 %}
11649 ins_pipe(ialu_reg_reg_alu0);
11650 %}
11651
11652 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp)
11653 %{
11654 match(Set cr (OverflowMulL op1 op2));
11655 effect(DEF cr, TEMP tmp, USE op1, USE op2);
11656
11657 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %}
11658 ins_encode %{
11659 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant);
11660 %}
11661 ins_pipe(ialu_reg_reg_alu0);
11662 %}
11663
11664
11665 //----------Control Flow Instructions------------------------------------------
11666 // Signed compare Instructions
11667
11668 // XXX more variants!!
11669 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
11670 %{
11671 match(Set cr (CmpI op1 op2));
11672 effect(DEF cr, USE op1, USE op2);
11673
11674 format %{ "cmpl $op1, $op2" %}
11675 opcode(0x3B); /* Opcode 3B /r */
11676 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
11677 ins_pipe(ialu_cr_reg_reg);
11678 %}
11679
11680 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
11681 %{
11682 match(Set cr (CmpI op1 op2));
11683
11684 format %{ "cmpl $op1, $op2" %}
11685 opcode(0x81, 0x07); /* Opcode 81 /7 */
11686 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
11687 ins_pipe(ialu_cr_reg_imm);
11688 %}
11689
11690 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2)
11691 %{
11692 match(Set cr (CmpI op1 (LoadI op2)));
11693
11694 ins_cost(500); // XXX
11695 format %{ "cmpl $op1, $op2" %}
11696 opcode(0x3B); /* Opcode 3B /r */
11697 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
11698 ins_pipe(ialu_cr_reg_mem);
11699 %}
11700
11701 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero)
11702 %{
11703 match(Set cr (CmpI src zero));
11704
11705 format %{ "testl $src, $src" %}
11706 opcode(0x85);
11707 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
11708 ins_pipe(ialu_cr_reg_imm);
11709 %}
11710
11711 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero)
11712 %{
11713 match(Set cr (CmpI (AndI src con) zero));
11714
11715 format %{ "testl $src, $con" %}
11716 opcode(0xF7, 0x00);
11717 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con));
11718 ins_pipe(ialu_cr_reg_imm);
11719 %}
11720
11721 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero)
11722 %{
11723 match(Set cr (CmpI (AndI src (LoadI mem)) zero));
11724
11725 format %{ "testl $src, $mem" %}
11726 opcode(0x85);
11727 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
11728 ins_pipe(ialu_cr_reg_mem);
11729 %}
11730
11731 // Fold array properties check
11732 instruct testI_mem_imm(rFlagsReg cr, memory mem, immI con, immI0 zero)
11733 %{
11734 match(Set cr (CmpI (AndI (CastN2I (LoadNKlass mem)) con) zero));
11735
11736 format %{ "testl $mem, $con" %}
11737 opcode(0xF7, 0x00);
11738 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(con));
11739 ins_pipe(ialu_mem_imm);
11740 %}
11741
11742 // Unsigned compare Instructions; really, same as signed except they
11743 // produce an rFlagsRegU instead of rFlagsReg.
11744 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2)
11745 %{
11746 match(Set cr (CmpU op1 op2));
11747
11748 format %{ "cmpl $op1, $op2\t# unsigned" %}
11749 opcode(0x3B); /* Opcode 3B /r */
11750 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
11751 ins_pipe(ialu_cr_reg_reg);
11752 %}
11753
11754 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2)
11755 %{
11756 match(Set cr (CmpU op1 op2));
11757
11758 format %{ "cmpl $op1, $op2\t# unsigned" %}
11759 opcode(0x81,0x07); /* Opcode 81 /7 */
11760 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
11761 ins_pipe(ialu_cr_reg_imm);
11762 %}
11763
11764 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2)
11765 %{
11766 match(Set cr (CmpU op1 (LoadI op2)));
11767
11768 ins_cost(500); // XXX
11769 format %{ "cmpl $op1, $op2\t# unsigned" %}
11770 opcode(0x3B); /* Opcode 3B /r */
11771 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
11772 ins_pipe(ialu_cr_reg_mem);
11773 %}
11774
11775 // // // Cisc-spilled version of cmpU_rReg
11776 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2)
11777 // //%{
11778 // // match(Set cr (CmpU (LoadI op1) op2));
11779 // //
11780 // // format %{ "CMPu $op1,$op2" %}
11781 // // ins_cost(500);
11782 // // opcode(0x39); /* Opcode 39 /r */
11783 // // ins_encode( OpcP, reg_mem( op1, op2) );
11784 // //%}
11785
11786 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero)
11787 %{
11788 match(Set cr (CmpU src zero));
11789
11790 format %{ "testl $src, $src\t# unsigned" %}
11791 opcode(0x85);
11792 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
11793 ins_pipe(ialu_cr_reg_imm);
11794 %}
11795
11796 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2)
11797 %{
11798 match(Set cr (CmpP op1 op2));
11799
11800 format %{ "cmpq $op1, $op2\t# ptr" %}
11801 opcode(0x3B); /* Opcode 3B /r */
11802 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
11803 ins_pipe(ialu_cr_reg_reg);
11804 %}
11805
11806 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
11807 %{
11808 match(Set cr (CmpP op1 (LoadP op2)));
11809 predicate(n->in(2)->as_Load()->barrier_data() == 0);
11810
11811 ins_cost(500); // XXX
11812 format %{ "cmpq $op1, $op2\t# ptr" %}
11813 opcode(0x3B); /* Opcode 3B /r */
11814 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
11815 ins_pipe(ialu_cr_reg_mem);
11816 %}
11817
11818 // // // Cisc-spilled version of cmpP_rReg
11819 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2)
11820 // //%{
11821 // // match(Set cr (CmpP (LoadP op1) op2));
11822 // //
11823 // // format %{ "CMPu $op1,$op2" %}
11824 // // ins_cost(500);
11825 // // opcode(0x39); /* Opcode 39 /r */
11826 // // ins_encode( OpcP, reg_mem( op1, op2) );
11827 // //%}
11828
11829 // XXX this is generalized by compP_rReg_mem???
11830 // Compare raw pointer (used in out-of-heap check).
11831 // Only works because non-oop pointers must be raw pointers
11832 // and raw pointers have no anti-dependencies.
11833 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
11834 %{
11835 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none &&
11836 n->in(2)->as_Load()->barrier_data() == 0);
11837 match(Set cr (CmpP op1 (LoadP op2)));
11838
11839 format %{ "cmpq $op1, $op2\t# raw ptr" %}
11840 opcode(0x3B); /* Opcode 3B /r */
11841 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
11842 ins_pipe(ialu_cr_reg_mem);
11843 %}
11844
11845 // This will generate a signed flags result. This should be OK since
11846 // any compare to a zero should be eq/neq.
11847 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero)
11848 %{
11849 match(Set cr (CmpP src zero));
11850
11851 format %{ "testq $src, $src\t# ptr" %}
11852 opcode(0x85);
11853 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
11854 ins_pipe(ialu_cr_reg_imm);
11855 %}
11856
11857 // This will generate a signed flags result. This should be OK since
11858 // any compare to a zero should be eq/neq.
11859 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
11860 %{
11861 predicate((!UseCompressedOops || (CompressedOops::base() != NULL)) &&
11862 n->in(1)->as_Load()->barrier_data() == 0);
11863 match(Set cr (CmpP (LoadP op) zero));
11864
11865 ins_cost(500); // XXX
11866 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %}
11867 opcode(0xF7); /* Opcode F7 /0 */
11868 ins_encode(REX_mem_wide(op),
11869 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
11870 ins_pipe(ialu_cr_reg_imm);
11871 %}
11872
11873 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
11874 %{
11875 predicate(UseCompressedOops && (CompressedOops::base() == NULL) &&
11876 n->in(1)->as_Load()->barrier_data() == 0);
11877 match(Set cr (CmpP (LoadP mem) zero));
11878
11879 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
11880 ins_encode %{
11881 __ cmpq(r12, $mem$$Address);
11882 %}
11883 ins_pipe(ialu_cr_reg_mem);
11884 %}
11885
11886 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
11887 %{
11888 match(Set cr (CmpN op1 op2));
11889
11890 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
11891 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %}
11892 ins_pipe(ialu_cr_reg_reg);
11893 %}
11894
11895 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
11896 %{
11897 match(Set cr (CmpN src (LoadN mem)));
11898
11899 format %{ "cmpl $src, $mem\t# compressed ptr" %}
11900 ins_encode %{
11901 __ cmpl($src$$Register, $mem$$Address);
11902 %}
11903 ins_pipe(ialu_cr_reg_mem);
11904 %}
11905
11906 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{
11907 match(Set cr (CmpN op1 op2));
11908
11909 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
11910 ins_encode %{
11911 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant);
11912 %}
11913 ins_pipe(ialu_cr_reg_imm);
11914 %}
11915
11916 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src)
11917 %{
11918 match(Set cr (CmpN src (LoadN mem)));
11919
11920 format %{ "cmpl $mem, $src\t# compressed ptr" %}
11921 ins_encode %{
11922 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
11923 %}
11924 ins_pipe(ialu_cr_reg_mem);
11925 %}
11926
11927 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{
11928 match(Set cr (CmpN op1 op2));
11929
11930 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %}
11931 ins_encode %{
11932 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant);
11933 %}
11934 ins_pipe(ialu_cr_reg_imm);
11935 %}
11936
11937 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src)
11938 %{
11939 match(Set cr (CmpN src (LoadNKlass mem)));
11940
11941 format %{ "cmpl $mem, $src\t# compressed klass ptr" %}
11942 ins_encode %{
11943 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant);
11944 %}
11945 ins_pipe(ialu_cr_reg_mem);
11946 %}
11947
11948 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
11949 match(Set cr (CmpN src zero));
11950
11951 format %{ "testl $src, $src\t# compressed ptr" %}
11952 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
11953 ins_pipe(ialu_cr_reg_imm);
11954 %}
11955
11956 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
11957 %{
11958 predicate(CompressedOops::base() != NULL);
11959 match(Set cr (CmpN (LoadN mem) zero));
11960
11961 ins_cost(500); // XXX
11962 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
11963 ins_encode %{
11964 __ cmpl($mem$$Address, (int)0xFFFFFFFF);
11965 %}
11966 ins_pipe(ialu_cr_reg_mem);
11967 %}
11968
11969 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
11970 %{
11971 predicate(CompressedOops::base() == NULL);
11972 match(Set cr (CmpN (LoadN mem) zero));
11973
11974 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
11975 ins_encode %{
11976 __ cmpl(r12, $mem$$Address);
11977 %}
11978 ins_pipe(ialu_cr_reg_mem);
11979 %}
11980
11981 // Yanked all unsigned pointer compare operations.
11982 // Pointer compares are done with CmpP which is already unsigned.
11983
11984 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
11985 %{
11986 match(Set cr (CmpL op1 op2));
11987
11988 format %{ "cmpq $op1, $op2" %}
11989 opcode(0x3B); /* Opcode 3B /r */
11990 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
11991 ins_pipe(ialu_cr_reg_reg);
11992 %}
11993
11994 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
11995 %{
11996 match(Set cr (CmpL op1 op2));
11997
11998 format %{ "cmpq $op1, $op2" %}
11999 opcode(0x81, 0x07); /* Opcode 81 /7 */
12000 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2));
12001 ins_pipe(ialu_cr_reg_imm);
12002 %}
12003
12004 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2)
12005 %{
12006 match(Set cr (CmpL op1 (LoadL op2)));
12007
12008 format %{ "cmpq $op1, $op2" %}
12009 opcode(0x3B); /* Opcode 3B /r */
12010 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
12011 ins_pipe(ialu_cr_reg_mem);
12012 %}
12013
12014 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero)
12015 %{
12016 match(Set cr (CmpL src zero));
12017
12018 format %{ "testq $src, $src" %}
12019 opcode(0x85);
12020 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
12021 ins_pipe(ialu_cr_reg_imm);
12022 %}
12023
12024 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero)
12025 %{
12026 match(Set cr (CmpL (AndL src con) zero));
12027
12028 format %{ "testq $src, $con\t# long" %}
12029 opcode(0xF7, 0x00);
12030 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con));
12031 ins_pipe(ialu_cr_reg_imm);
12032 %}
12033
12034 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero)
12035 %{
12036 match(Set cr (CmpL (AndL src (LoadL mem)) zero));
12037
12038 format %{ "testq $src, $mem" %}
12039 opcode(0x85);
12040 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
12041 ins_pipe(ialu_cr_reg_mem);
12042 %}
12043
12044 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero)
12045 %{
12046 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero));
12047
12048 format %{ "testq $src, $mem" %}
12049 opcode(0x85);
12050 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
12051 ins_pipe(ialu_cr_reg_mem);
12052 %}
12053
12054 // Fold array properties check
12055 instruct testL_reg_mem3(rFlagsReg cr, memory mem, rRegL src, immL0 zero)
12056 %{
12057 match(Set cr (CmpL (AndL (CastP2X (LoadKlass mem)) src) zero));
12058
12059 format %{ "testq $src, $mem\t# test array properties" %}
12060 opcode(0x85);
12061 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
12062 ins_pipe(ialu_cr_reg_mem);
12063 %}
12064
12065 // Manifest a CmpL result in an integer register. Very painful.
12066 // This is the test to avoid.
12067 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
12068 %{
12069 match(Set dst (CmpL3 src1 src2));
12070 effect(KILL flags);
12071
12072 ins_cost(275); // XXX
12073 format %{ "cmpq $src1, $src2\t# CmpL3\n\t"
12074 "movl $dst, -1\n\t"
12075 "jl,s done\n\t"
12076 "setne $dst\n\t"
12077 "movzbl $dst, $dst\n\t"
12078 "done:" %}
12079 ins_encode(cmpl3_flag(src1, src2, dst));
12080 ins_pipe(pipe_slow);
12081 %}
12082
12083 // Unsigned long compare Instructions; really, same as signed long except they
12084 // produce an rFlagsRegU instead of rFlagsReg.
12085 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2)
12086 %{
12087 match(Set cr (CmpUL op1 op2));
12088
12089 format %{ "cmpq $op1, $op2\t# unsigned" %}
12090 opcode(0x3B); /* Opcode 3B /r */
12091 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
12092 ins_pipe(ialu_cr_reg_reg);
12093 %}
12094
12095 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2)
12096 %{
12097 match(Set cr (CmpUL op1 op2));
12098
12099 format %{ "cmpq $op1, $op2\t# unsigned" %}
12100 opcode(0x81, 0x07); /* Opcode 81 /7 */
12101 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2));
12102 ins_pipe(ialu_cr_reg_imm);
12103 %}
12104
12105 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2)
12106 %{
12107 match(Set cr (CmpUL op1 (LoadL op2)));
12108
12109 format %{ "cmpq $op1, $op2\t# unsigned" %}
12110 opcode(0x3B); /* Opcode 3B /r */
12111 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
12112 ins_pipe(ialu_cr_reg_mem);
12113 %}
12114
12115 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero)
12116 %{
12117 match(Set cr (CmpUL src zero));
12118
12119 format %{ "testq $src, $src\t# unsigned" %}
12120 opcode(0x85);
12121 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
12122 ins_pipe(ialu_cr_reg_imm);
12123 %}
12124
12125 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm)
12126 %{
12127 match(Set cr (CmpI (LoadB mem) imm));
12128
12129 ins_cost(125);
12130 format %{ "cmpb $mem, $imm" %}
12131 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %}
12132 ins_pipe(ialu_cr_reg_mem);
12133 %}
12134
12135 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU8 imm, immI0 zero)
12136 %{
12137 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero));
12138
12139 ins_cost(125);
12140 format %{ "testb $mem, $imm\t# ubyte" %}
12141 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %}
12142 ins_pipe(ialu_cr_reg_mem);
12143 %}
12144
12145 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero)
12146 %{
12147 match(Set cr (CmpI (AndI (LoadB mem) imm) zero));
12148
12149 ins_cost(125);
12150 format %{ "testb $mem, $imm\t# byte" %}
12151 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %}
12152 ins_pipe(ialu_cr_reg_mem);
12153 %}
12154
12155 //----------Max and Min--------------------------------------------------------
12156 // Min Instructions
12157
12158 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr)
12159 %{
12160 effect(USE_DEF dst, USE src, USE cr);
12161
12162 format %{ "cmovlgt $dst, $src\t# min" %}
12163 opcode(0x0F, 0x4F);
12164 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
12165 ins_pipe(pipe_cmov_reg);
12166 %}
12167
12168
12169 instruct minI_rReg(rRegI dst, rRegI src)
12170 %{
12171 match(Set dst (MinI dst src));
12172
12173 ins_cost(200);
12174 expand %{
12175 rFlagsReg cr;
12176 compI_rReg(cr, dst, src);
12177 cmovI_reg_g(dst, src, cr);
12178 %}
12179 %}
12180
12181 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr)
12182 %{
12183 effect(USE_DEF dst, USE src, USE cr);
12184
12185 format %{ "cmovllt $dst, $src\t# max" %}
12186 opcode(0x0F, 0x4C);
12187 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
12188 ins_pipe(pipe_cmov_reg);
12189 %}
12190
12191
12192 instruct maxI_rReg(rRegI dst, rRegI src)
12193 %{
12194 match(Set dst (MaxI dst src));
12195
12196 ins_cost(200);
12197 expand %{
12198 rFlagsReg cr;
12199 compI_rReg(cr, dst, src);
12200 cmovI_reg_l(dst, src, cr);
12201 %}
12202 %}
12203
12204 // ============================================================================
12205 // Branch Instructions
12206
12207 // Jump Direct - Label defines a relative address from JMP+1
12208 instruct jmpDir(label labl)
12209 %{
12210 match(Goto);
12211 effect(USE labl);
12212
12213 ins_cost(300);
12214 format %{ "jmp $labl" %}
12215 size(5);
12216 ins_encode %{
12217 Label* L = $labl$$label;
12218 __ jmp(*L, false); // Always long jump
12219 %}
12220 ins_pipe(pipe_jmp);
12221 %}
12222
12223 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12224 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl)
12225 %{
12226 match(If cop cr);
12227 effect(USE labl);
12228
12229 ins_cost(300);
12230 format %{ "j$cop $labl" %}
12231 size(6);
12232 ins_encode %{
12233 Label* L = $labl$$label;
12234 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12235 %}
12236 ins_pipe(pipe_jcc);
12237 %}
12238
12239 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12240 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
12241 %{
12242 predicate(!n->has_vector_mask_set());
12243 match(CountedLoopEnd cop cr);
12244 effect(USE labl);
12245
12246 ins_cost(300);
12247 format %{ "j$cop $labl\t# loop end" %}
12248 size(6);
12249 ins_encode %{
12250 Label* L = $labl$$label;
12251 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12252 %}
12253 ins_pipe(pipe_jcc);
12254 %}
12255
12256 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12257 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12258 predicate(!n->has_vector_mask_set());
12259 match(CountedLoopEnd cop cmp);
12260 effect(USE labl);
12261
12262 ins_cost(300);
12263 format %{ "j$cop,u $labl\t# loop end" %}
12264 size(6);
12265 ins_encode %{
12266 Label* L = $labl$$label;
12267 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12268 %}
12269 ins_pipe(pipe_jcc);
12270 %}
12271
12272 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12273 predicate(!n->has_vector_mask_set());
12274 match(CountedLoopEnd cop cmp);
12275 effect(USE labl);
12276
12277 ins_cost(200);
12278 format %{ "j$cop,u $labl\t# loop end" %}
12279 size(6);
12280 ins_encode %{
12281 Label* L = $labl$$label;
12282 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12283 %}
12284 ins_pipe(pipe_jcc);
12285 %}
12286
12287 // mask version
12288 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12289 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl)
12290 %{
12291 predicate(n->has_vector_mask_set());
12292 match(CountedLoopEnd cop cr);
12293 effect(USE labl);
12294
12295 ins_cost(400);
12296 format %{ "j$cop $labl\t# loop end\n\t"
12297 "restorevectmask \t# vector mask restore for loops" %}
12298 size(10);
12299 ins_encode %{
12300 Label* L = $labl$$label;
12301 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12302 __ restorevectmask();
12303 %}
12304 ins_pipe(pipe_jcc);
12305 %}
12306
12307 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12308 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12309 predicate(n->has_vector_mask_set());
12310 match(CountedLoopEnd cop cmp);
12311 effect(USE labl);
12312
12313 ins_cost(400);
12314 format %{ "j$cop,u $labl\t# loop end\n\t"
12315 "restorevectmask \t# vector mask restore for loops" %}
12316 size(10);
12317 ins_encode %{
12318 Label* L = $labl$$label;
12319 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12320 __ restorevectmask();
12321 %}
12322 ins_pipe(pipe_jcc);
12323 %}
12324
12325 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12326 predicate(n->has_vector_mask_set());
12327 match(CountedLoopEnd cop cmp);
12328 effect(USE labl);
12329
12330 ins_cost(300);
12331 format %{ "j$cop,u $labl\t# loop end\n\t"
12332 "restorevectmask \t# vector mask restore for loops" %}
12333 size(10);
12334 ins_encode %{
12335 Label* L = $labl$$label;
12336 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12337 __ restorevectmask();
12338 %}
12339 ins_pipe(pipe_jcc);
12340 %}
12341
12342 // Jump Direct Conditional - using unsigned comparison
12343 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12344 match(If cop cmp);
12345 effect(USE labl);
12346
12347 ins_cost(300);
12348 format %{ "j$cop,u $labl" %}
12349 size(6);
12350 ins_encode %{
12351 Label* L = $labl$$label;
12352 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12353 %}
12354 ins_pipe(pipe_jcc);
12355 %}
12356
12357 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12358 match(If cop cmp);
12359 effect(USE labl);
12360
12361 ins_cost(200);
12362 format %{ "j$cop,u $labl" %}
12363 size(6);
12364 ins_encode %{
12365 Label* L = $labl$$label;
12366 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12367 %}
12368 ins_pipe(pipe_jcc);
12369 %}
12370
12371 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
12372 match(If cop cmp);
12373 effect(USE labl);
12374
12375 ins_cost(200);
12376 format %{ $$template
12377 if ($cop$$cmpcode == Assembler::notEqual) {
12378 $$emit$$"jp,u $labl\n\t"
12379 $$emit$$"j$cop,u $labl"
12380 } else {
12381 $$emit$$"jp,u done\n\t"
12382 $$emit$$"j$cop,u $labl\n\t"
12383 $$emit$$"done:"
12384 }
12385 %}
12386 ins_encode %{
12387 Label* l = $labl$$label;
12388 if ($cop$$cmpcode == Assembler::notEqual) {
12389 __ jcc(Assembler::parity, *l, false);
12390 __ jcc(Assembler::notEqual, *l, false);
12391 } else if ($cop$$cmpcode == Assembler::equal) {
12392 Label done;
12393 __ jccb(Assembler::parity, done);
12394 __ jcc(Assembler::equal, *l, false);
12395 __ bind(done);
12396 } else {
12397 ShouldNotReachHere();
12398 }
12399 %}
12400 ins_pipe(pipe_jcc);
12401 %}
12402
12403 // ============================================================================
12404 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
12405 // superklass array for an instance of the superklass. Set a hidden
12406 // internal cache on a hit (cache is checked with exposed code in
12407 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The
12408 // encoding ALSO sets flags.
12409
12410 instruct partialSubtypeCheck(rdi_RegP result,
12411 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
12412 rFlagsReg cr)
12413 %{
12414 match(Set result (PartialSubtypeCheck sub super));
12415 effect(KILL rcx, KILL cr);
12416
12417 ins_cost(1100); // slightly larger than the next version
12418 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
12419 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t"
12420 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t"
12421 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t"
12422 "jne,s miss\t\t# Missed: rdi not-zero\n\t"
12423 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
12424 "xorq $result, $result\t\t Hit: rdi zero\n\t"
12425 "miss:\t" %}
12426
12427 opcode(0x1); // Force a XOR of RDI
12428 ins_encode(enc_PartialSubtypeCheck());
12429 ins_pipe(pipe_slow);
12430 %}
12431
12432 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr,
12433 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
12434 immP0 zero,
12435 rdi_RegP result)
12436 %{
12437 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
12438 effect(KILL rcx, KILL result);
12439
12440 ins_cost(1000);
12441 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
12442 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t"
12443 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t"
12444 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t"
12445 "jne,s miss\t\t# Missed: flags nz\n\t"
12446 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
12447 "miss:\t" %}
12448
12449 opcode(0x0); // No need to XOR RDI
12450 ins_encode(enc_PartialSubtypeCheck());
12451 ins_pipe(pipe_slow);
12452 %}
12453
12454 // ============================================================================
12455 // Branch Instructions -- short offset versions
12456 //
12457 // These instructions are used to replace jumps of a long offset (the default
12458 // match) with jumps of a shorter offset. These instructions are all tagged
12459 // with the ins_short_branch attribute, which causes the ADLC to suppress the
12460 // match rules in general matching. Instead, the ADLC generates a conversion
12461 // method in the MachNode which can be used to do in-place replacement of the
12462 // long variant with the shorter variant. The compiler will determine if a
12463 // branch can be taken by the is_short_branch_offset() predicate in the machine
12464 // specific code section of the file.
12465
12466 // Jump Direct - Label defines a relative address from JMP+1
12467 instruct jmpDir_short(label labl) %{
12468 match(Goto);
12469 effect(USE labl);
12470
12471 ins_cost(300);
12472 format %{ "jmp,s $labl" %}
12473 size(2);
12474 ins_encode %{
12475 Label* L = $labl$$label;
12476 __ jmpb(*L);
12477 %}
12478 ins_pipe(pipe_jmp);
12479 ins_short_branch(1);
12480 %}
12481
12482 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12483 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
12484 match(If cop cr);
12485 effect(USE labl);
12486
12487 ins_cost(300);
12488 format %{ "j$cop,s $labl" %}
12489 size(2);
12490 ins_encode %{
12491 Label* L = $labl$$label;
12492 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12493 %}
12494 ins_pipe(pipe_jcc);
12495 ins_short_branch(1);
12496 %}
12497
12498 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12499 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
12500 match(CountedLoopEnd cop cr);
12501 effect(USE labl);
12502
12503 ins_cost(300);
12504 format %{ "j$cop,s $labl\t# loop end" %}
12505 size(2);
12506 ins_encode %{
12507 Label* L = $labl$$label;
12508 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12509 %}
12510 ins_pipe(pipe_jcc);
12511 ins_short_branch(1);
12512 %}
12513
12514 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12515 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12516 match(CountedLoopEnd cop cmp);
12517 effect(USE labl);
12518
12519 ins_cost(300);
12520 format %{ "j$cop,us $labl\t# loop end" %}
12521 size(2);
12522 ins_encode %{
12523 Label* L = $labl$$label;
12524 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12525 %}
12526 ins_pipe(pipe_jcc);
12527 ins_short_branch(1);
12528 %}
12529
12530 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12531 match(CountedLoopEnd cop cmp);
12532 effect(USE labl);
12533
12534 ins_cost(300);
12535 format %{ "j$cop,us $labl\t# loop end" %}
12536 size(2);
12537 ins_encode %{
12538 Label* L = $labl$$label;
12539 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12540 %}
12541 ins_pipe(pipe_jcc);
12542 ins_short_branch(1);
12543 %}
12544
12545 // Jump Direct Conditional - using unsigned comparison
12546 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12547 match(If cop cmp);
12548 effect(USE labl);
12549
12550 ins_cost(300);
12551 format %{ "j$cop,us $labl" %}
12552 size(2);
12553 ins_encode %{
12554 Label* L = $labl$$label;
12555 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12556 %}
12557 ins_pipe(pipe_jcc);
12558 ins_short_branch(1);
12559 %}
12560
12561 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12562 match(If cop cmp);
12563 effect(USE labl);
12564
12565 ins_cost(300);
12566 format %{ "j$cop,us $labl" %}
12567 size(2);
12568 ins_encode %{
12569 Label* L = $labl$$label;
12570 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12571 %}
12572 ins_pipe(pipe_jcc);
12573 ins_short_branch(1);
12574 %}
12575
12576 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
12577 match(If cop cmp);
12578 effect(USE labl);
12579
12580 ins_cost(300);
12581 format %{ $$template
12582 if ($cop$$cmpcode == Assembler::notEqual) {
12583 $$emit$$"jp,u,s $labl\n\t"
12584 $$emit$$"j$cop,u,s $labl"
12585 } else {
12586 $$emit$$"jp,u,s done\n\t"
12587 $$emit$$"j$cop,u,s $labl\n\t"
12588 $$emit$$"done:"
12589 }
12590 %}
12591 size(4);
12592 ins_encode %{
12593 Label* l = $labl$$label;
12594 if ($cop$$cmpcode == Assembler::notEqual) {
12595 __ jccb(Assembler::parity, *l);
12596 __ jccb(Assembler::notEqual, *l);
12597 } else if ($cop$$cmpcode == Assembler::equal) {
12598 Label done;
12599 __ jccb(Assembler::parity, done);
12600 __ jccb(Assembler::equal, *l);
12601 __ bind(done);
12602 } else {
12603 ShouldNotReachHere();
12604 }
12605 %}
12606 ins_pipe(pipe_jcc);
12607 ins_short_branch(1);
12608 %}
12609
12610 // ============================================================================
12611 // inlined locking and unlocking
12612
12613 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{
12614 predicate(Compile::current()->use_rtm());
12615 match(Set cr (FastLock object box));
12616 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box);
12617 ins_cost(300);
12618 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %}
12619 ins_encode %{
12620 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
12621 $scr$$Register, $cx1$$Register, $cx2$$Register,
12622 _counters, _rtm_counters, _stack_rtm_counters,
12623 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(),
12624 true, ra_->C->profile_rtm());
12625 %}
12626 ins_pipe(pipe_slow);
12627 %}
12628
12629 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr, rRegP cx1) %{
12630 predicate(!Compile::current()->use_rtm());
12631 match(Set cr (FastLock object box));
12632 effect(TEMP tmp, TEMP scr, TEMP cx1, USE_KILL box);
12633 ins_cost(300);
12634 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
12635 ins_encode %{
12636 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
12637 $scr$$Register, $cx1$$Register, noreg, _counters, NULL, NULL, NULL, false, false);
12638 %}
12639 ins_pipe(pipe_slow);
12640 %}
12641
12642 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{
12643 match(Set cr (FastUnlock object box));
12644 effect(TEMP tmp, USE_KILL box);
12645 ins_cost(300);
12646 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
12647 ins_encode %{
12648 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm());
12649 %}
12650 ins_pipe(pipe_slow);
12651 %}
12652
12653
12654 // ============================================================================
12655 // Safepoint Instructions
12656 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll)
12657 %{
12658 match(SafePoint poll);
12659 effect(KILL cr, USE poll);
12660
12661 format %{ "testl rax, [$poll]\t"
12662 "# Safepoint: poll for GC" %}
12663 ins_cost(125);
12664 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */
12665 ins_encode %{
12666 __ relocate(relocInfo::poll_type);
12667 address pre_pc = __ pc();
12668 __ testl(rax, Address($poll$$Register, 0));
12669 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]");
12670 %}
12671 ins_pipe(ialu_reg_mem);
12672 %}
12673
12674 // ============================================================================
12675 // Procedure Call/Return Instructions
12676 // Call Java Static Instruction
12677 // Note: If this code changes, the corresponding ret_addr_offset() and
12678 // compute_padding() functions will have to be adjusted.
12679 instruct CallStaticJavaDirect(method meth) %{
12680 match(CallStaticJava);
12681 effect(USE meth);
12682
12683 ins_cost(300);
12684 format %{ "call,static " %}
12685 opcode(0xE8); /* E8 cd */
12686 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog);
12687 ins_pipe(pipe_slow);
12688 ins_alignment(4);
12689 %}
12690
12691 // Call Java Dynamic Instruction
12692 // Note: If this code changes, the corresponding ret_addr_offset() and
12693 // compute_padding() functions will have to be adjusted.
12694 instruct CallDynamicJavaDirect(method meth)
12695 %{
12696 match(CallDynamicJava);
12697 effect(USE meth);
12698
12699 ins_cost(300);
12700 format %{ "movq rax, #Universe::non_oop_word()\n\t"
12701 "call,dynamic " %}
12702 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog);
12703 ins_pipe(pipe_slow);
12704 ins_alignment(4);
12705 %}
12706
12707 // Call Runtime Instruction
12708 instruct CallRuntimeDirect(method meth)
12709 %{
12710 match(CallRuntime);
12711 effect(USE meth);
12712
12713 ins_cost(300);
12714 format %{ "call,runtime " %}
12715 ins_encode(clear_avx, Java_To_Runtime(meth));
12716 ins_pipe(pipe_slow);
12717 %}
12718
12719 // Call runtime without safepoint
12720 instruct CallLeafDirect(method meth)
12721 %{
12722 match(CallLeaf);
12723 effect(USE meth);
12724
12725 ins_cost(300);
12726 format %{ "call_leaf,runtime " %}
12727 ins_encode(clear_avx, Java_To_Runtime(meth));
12728 ins_pipe(pipe_slow);
12729 %}
12730
12731 // Call runtime without safepoint
12732 // entry point is null, target holds the address to call
12733 instruct CallLeafNoFPInDirect(rRegP target)
12734 %{
12735 predicate(n->as_Call()->entry_point() == NULL);
12736 match(CallLeafNoFP target);
12737
12738 ins_cost(300);
12739 format %{ "call_leaf_nofp,runtime indirect " %}
12740 ins_encode %{
12741 __ call($target$$Register);
12742 %}
12743
12744 ins_pipe(pipe_slow);
12745 %}
12746
12747 instruct CallLeafNoFPDirect(method meth)
12748 %{
12749 predicate(n->as_Call()->entry_point() != NULL);
12750 match(CallLeafNoFP);
12751 effect(USE meth);
12752
12753 ins_cost(300);
12754 format %{ "call_leaf_nofp,runtime " %}
12755 ins_encode(clear_avx, Java_To_Runtime(meth));
12756 ins_pipe(pipe_slow);
12757 %}
12758
12759 // Return Instruction
12760 // Remove the return address & jump to it.
12761 // Notice: We always emit a nop after a ret to make sure there is room
12762 // for safepoint patching
12763 instruct Ret()
12764 %{
12765 match(Return);
12766
12767 format %{ "ret" %}
12768 opcode(0xC3);
12769 ins_encode(OpcP);
12770 ins_pipe(pipe_jmp);
12771 %}
12772
12773 // Tail Call; Jump from runtime stub to Java code.
12774 // Also known as an 'interprocedural jump'.
12775 // Target of jump will eventually return to caller.
12776 // TailJump below removes the return address.
12777 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop)
12778 %{
12779 match(TailCall jump_target method_oop);
12780
12781 ins_cost(300);
12782 format %{ "jmp $jump_target\t# rbx holds method oop" %}
12783 opcode(0xFF, 0x4); /* Opcode FF /4 */
12784 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target));
12785 ins_pipe(pipe_jmp);
12786 %}
12787
12788 // Tail Jump; remove the return address; jump to target.
12789 // TailCall above leaves the return address around.
12790 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop)
12791 %{
12792 match(TailJump jump_target ex_oop);
12793
12794 ins_cost(300);
12795 format %{ "popq rdx\t# pop return address\n\t"
12796 "jmp $jump_target" %}
12797 opcode(0xFF, 0x4); /* Opcode FF /4 */
12798 ins_encode(Opcode(0x5a), // popq rdx
12799 REX_reg(jump_target), OpcP, reg_opc(jump_target));
12800 ins_pipe(pipe_jmp);
12801 %}
12802
12803 // Create exception oop: created by stack-crawling runtime code.
12804 // Created exception is now available to this handler, and is setup
12805 // just prior to jumping to this handler. No code emitted.
12806 instruct CreateException(rax_RegP ex_oop)
12807 %{
12808 match(Set ex_oop (CreateEx));
12809
12810 size(0);
12811 // use the following format syntax
12812 format %{ "# exception oop is in rax; no code emitted" %}
12813 ins_encode();
12814 ins_pipe(empty);
12815 %}
12816
12817 // Rethrow exception:
12818 // The exception oop will come in the first argument position.
12819 // Then JUMP (not call) to the rethrow stub code.
12820 instruct RethrowException()
12821 %{
12822 match(Rethrow);
12823
12824 // use the following format syntax
12825 format %{ "jmp rethrow_stub" %}
12826 ins_encode(enc_rethrow);
12827 ins_pipe(pipe_jmp);
12828 %}
12829
12830 // ============================================================================
12831 // This name is KNOWN by the ADLC and cannot be changed.
12832 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
12833 // for this guy.
12834 instruct tlsLoadP(r15_RegP dst) %{
12835 match(Set dst (ThreadLocal));
12836 effect(DEF dst);
12837
12838 size(0);
12839 format %{ "# TLS is in R15" %}
12840 ins_encode( /*empty encoding*/ );
12841 ins_pipe(ialu_reg_reg);
12842 %}
12843
12844
12845 //----------PEEPHOLE RULES-----------------------------------------------------
12846 // These must follow all instruction definitions as they use the names
12847 // defined in the instructions definitions.
12848 //
12849 // peepmatch ( root_instr_name [preceding_instruction]* );
12850 //
12851 // peepconstraint %{
12852 // (instruction_number.operand_name relational_op instruction_number.operand_name
12853 // [, ...] );
12854 // // instruction numbers are zero-based using left to right order in peepmatch
12855 //
12856 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
12857 // // provide an instruction_number.operand_name for each operand that appears
12858 // // in the replacement instruction's match rule
12859 //
12860 // ---------VM FLAGS---------------------------------------------------------
12861 //
12862 // All peephole optimizations can be turned off using -XX:-OptoPeephole
12863 //
12864 // Each peephole rule is given an identifying number starting with zero and
12865 // increasing by one in the order seen by the parser. An individual peephole
12866 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
12867 // on the command-line.
12868 //
12869 // ---------CURRENT LIMITATIONS----------------------------------------------
12870 //
12871 // Only match adjacent instructions in same basic block
12872 // Only equality constraints
12873 // Only constraints between operands, not (0.dest_reg == RAX_enc)
12874 // Only one replacement instruction
12875 //
12876 // ---------EXAMPLE----------------------------------------------------------
12877 //
12878 // // pertinent parts of existing instructions in architecture description
12879 // instruct movI(rRegI dst, rRegI src)
12880 // %{
12881 // match(Set dst (CopyI src));
12882 // %}
12883 //
12884 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
12885 // %{
12886 // match(Set dst (AddI dst src));
12887 // effect(KILL cr);
12888 // %}
12889 //
12890 // // Change (inc mov) to lea
12891 // peephole %{
12892 // // increment preceeded by register-register move
12893 // peepmatch ( incI_rReg movI );
12894 // // require that the destination register of the increment
12895 // // match the destination register of the move
12896 // peepconstraint ( 0.dst == 1.dst );
12897 // // construct a replacement instruction that sets
12898 // // the destination to ( move's source register + one )
12899 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) );
12900 // %}
12901 //
12902
12903 // Implementation no longer uses movX instructions since
12904 // machine-independent system no longer uses CopyX nodes.
12905 //
12906 // peephole
12907 // %{
12908 // peepmatch (incI_rReg movI);
12909 // peepconstraint (0.dst == 1.dst);
12910 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
12911 // %}
12912
12913 // peephole
12914 // %{
12915 // peepmatch (decI_rReg movI);
12916 // peepconstraint (0.dst == 1.dst);
12917 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
12918 // %}
12919
12920 // peephole
12921 // %{
12922 // peepmatch (addI_rReg_imm movI);
12923 // peepconstraint (0.dst == 1.dst);
12924 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
12925 // %}
12926
12927 // peephole
12928 // %{
12929 // peepmatch (incL_rReg movL);
12930 // peepconstraint (0.dst == 1.dst);
12931 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
12932 // %}
12933
12934 // peephole
12935 // %{
12936 // peepmatch (decL_rReg movL);
12937 // peepconstraint (0.dst == 1.dst);
12938 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
12939 // %}
12940
12941 // peephole
12942 // %{
12943 // peepmatch (addL_rReg_imm movL);
12944 // peepconstraint (0.dst == 1.dst);
12945 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
12946 // %}
12947
12948 // peephole
12949 // %{
12950 // peepmatch (addP_rReg_imm movP);
12951 // peepconstraint (0.dst == 1.dst);
12952 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src));
12953 // %}
12954
12955 // // Change load of spilled value to only a spill
12956 // instruct storeI(memory mem, rRegI src)
12957 // %{
12958 // match(Set mem (StoreI mem src));
12959 // %}
12960 //
12961 // instruct loadI(rRegI dst, memory mem)
12962 // %{
12963 // match(Set dst (LoadI mem));
12964 // %}
12965 //
12966
12967 peephole
12968 %{
12969 peepmatch (loadI storeI);
12970 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
12971 peepreplace (storeI(1.mem 1.mem 1.src));
12972 %}
12973
12974 peephole
12975 %{
12976 peepmatch (loadL storeL);
12977 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
12978 peepreplace (storeL(1.mem 1.mem 1.src));
12979 %}
12980
12981 //----------SMARTSPILL RULES---------------------------------------------------
12982 // These must follow all instruction definitions as they use the names
12983 // defined in the instructions definitions.