1 //
2 // Copyright (c) 2003, 2021, 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 stack_slots( /* one chunk of stack-based "registers" */ )
165 //
166
167 // Empty register class.
168 reg_class no_reg();
169
170 // Class for all pointer/long registers
171 reg_class all_reg(RAX, RAX_H,
172 RDX, RDX_H,
173 RBP, RBP_H,
174 RDI, RDI_H,
175 RSI, RSI_H,
176 RCX, RCX_H,
177 RBX, RBX_H,
178 RSP, RSP_H,
179 R8, R8_H,
180 R9, R9_H,
181 R10, R10_H,
182 R11, R11_H,
183 R12, R12_H,
184 R13, R13_H,
185 R14, R14_H,
186 R15, R15_H);
187
188 // Class for all int registers
189 reg_class all_int_reg(RAX
190 RDX,
191 RBP,
192 RDI,
193 RSI,
194 RCX,
195 RBX,
196 R8,
197 R9,
198 R10,
199 R11,
200 R12,
201 R13,
202 R14);
203
204 // Class for all pointer registers
205 reg_class any_reg %{
206 return _ANY_REG_mask;
207 %}
208
209 // Class for all pointer registers (excluding RSP)
210 reg_class ptr_reg %{
211 return _PTR_REG_mask;
212 %}
213
214 // Class for all pointer registers (excluding RSP and RBP)
215 reg_class ptr_reg_no_rbp %{
216 return _PTR_REG_NO_RBP_mask;
217 %}
218
219 // Class for all pointer registers (excluding RAX and RSP)
220 reg_class ptr_no_rax_reg %{
221 return _PTR_NO_RAX_REG_mask;
222 %}
223
224 // Class for all pointer registers (excluding RAX, RBX, and RSP)
225 reg_class ptr_no_rax_rbx_reg %{
226 return _PTR_NO_RAX_RBX_REG_mask;
227 %}
228
229 // Class for all long registers (excluding RSP)
230 reg_class long_reg %{
231 return _LONG_REG_mask;
232 %}
233
234 // Class for all long registers (excluding RAX, RDX and RSP)
235 reg_class long_no_rax_rdx_reg %{
236 return _LONG_NO_RAX_RDX_REG_mask;
237 %}
238
239 // Class for all long registers (excluding RCX and RSP)
240 reg_class long_no_rcx_reg %{
241 return _LONG_NO_RCX_REG_mask;
242 %}
243
244 // Class for all int registers (excluding RSP)
245 reg_class int_reg %{
246 return _INT_REG_mask;
247 %}
248
249 // Class for all int registers (excluding RAX, RDX, and RSP)
250 reg_class int_no_rax_rdx_reg %{
251 return _INT_NO_RAX_RDX_REG_mask;
252 %}
253
254 // Class for all int registers (excluding RCX and RSP)
255 reg_class int_no_rcx_reg %{
256 return _INT_NO_RCX_REG_mask;
257 %}
258
259 // Singleton class for RAX pointer register
260 reg_class ptr_rax_reg(RAX, RAX_H);
261
262 // Singleton class for RBX pointer register
263 reg_class ptr_rbx_reg(RBX, RBX_H);
264
265 // Singleton class for RSI pointer register
266 reg_class ptr_rsi_reg(RSI, RSI_H);
267
268 // Singleton class for RBP pointer register
269 reg_class ptr_rbp_reg(RBP, RBP_H);
270
271 // Singleton class for RDI pointer register
272 reg_class ptr_rdi_reg(RDI, RDI_H);
273
274 // Singleton class for stack pointer
275 reg_class ptr_rsp_reg(RSP, RSP_H);
276
277 // Singleton class for TLS pointer
278 reg_class ptr_r15_reg(R15, R15_H);
279
280 // Singleton class for RAX long register
281 reg_class long_rax_reg(RAX, RAX_H);
282
283 // Singleton class for RCX long register
284 reg_class long_rcx_reg(RCX, RCX_H);
285
286 // Singleton class for RDX long register
287 reg_class long_rdx_reg(RDX, RDX_H);
288
289 // Singleton class for RAX int register
290 reg_class int_rax_reg(RAX);
291
292 // Singleton class for RBX int register
293 reg_class int_rbx_reg(RBX);
294
295 // Singleton class for RCX int register
296 reg_class int_rcx_reg(RCX);
297
298 // Singleton class for RCX int register
299 reg_class int_rdx_reg(RDX);
300
301 // Singleton class for RCX int register
302 reg_class int_rdi_reg(RDI);
303
304 // Singleton class for instruction pointer
305 // reg_class ip_reg(RIP);
306
307 %}
308
309 //----------SOURCE BLOCK-------------------------------------------------------
310 // This is a block of C++ code which provides values, functions, and
311 // definitions necessary in the rest of the architecture description
312 source_hpp %{
313
314 extern RegMask _ANY_REG_mask;
315 extern RegMask _PTR_REG_mask;
316 extern RegMask _PTR_REG_NO_RBP_mask;
317 extern RegMask _PTR_NO_RAX_REG_mask;
318 extern RegMask _PTR_NO_RAX_RBX_REG_mask;
319 extern RegMask _LONG_REG_mask;
320 extern RegMask _LONG_NO_RAX_RDX_REG_mask;
321 extern RegMask _LONG_NO_RCX_REG_mask;
322 extern RegMask _INT_REG_mask;
323 extern RegMask _INT_NO_RAX_RDX_REG_mask;
324 extern RegMask _INT_NO_RCX_REG_mask;
325
326 extern RegMask _STACK_OR_PTR_REG_mask;
327 extern RegMask _STACK_OR_LONG_REG_mask;
328 extern RegMask _STACK_OR_INT_REG_mask;
329
330 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; }
331 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; }
332 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; }
333
334 %}
335
336 source %{
337 #define RELOC_IMM64 Assembler::imm_operand
338 #define RELOC_DISP32 Assembler::disp32_operand
339
340 #define __ _masm.
341
342 RegMask _ANY_REG_mask;
343 RegMask _PTR_REG_mask;
344 RegMask _PTR_REG_NO_RBP_mask;
345 RegMask _PTR_NO_RAX_REG_mask;
346 RegMask _PTR_NO_RAX_RBX_REG_mask;
347 RegMask _LONG_REG_mask;
348 RegMask _LONG_NO_RAX_RDX_REG_mask;
349 RegMask _LONG_NO_RCX_REG_mask;
350 RegMask _INT_REG_mask;
351 RegMask _INT_NO_RAX_RDX_REG_mask;
352 RegMask _INT_NO_RCX_REG_mask;
353 RegMask _STACK_OR_PTR_REG_mask;
354 RegMask _STACK_OR_LONG_REG_mask;
355 RegMask _STACK_OR_INT_REG_mask;
356
357 static bool need_r12_heapbase() {
358 return UseCompressedOops;
359 }
360
361 void reg_mask_init() {
362 // _ALL_REG_mask is generated by adlc from the all_reg register class below.
363 // We derive a number of subsets from it.
364 _ANY_REG_mask = _ALL_REG_mask;
365
366 if (PreserveFramePointer) {
367 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()));
368 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next()));
369 }
370 if (need_r12_heapbase()) {
371 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()));
372 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next()));
373 }
374
375 _PTR_REG_mask = _ANY_REG_mask;
376 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()));
377 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next()));
378 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()));
379 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next()));
380
381 _STACK_OR_PTR_REG_mask = _PTR_REG_mask;
382 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask());
383
384 _PTR_REG_NO_RBP_mask = _PTR_REG_mask;
385 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()));
386 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next()));
387
388 _PTR_NO_RAX_REG_mask = _PTR_REG_mask;
389 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()));
390 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next()));
391
392 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask;
393 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()));
394 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next()));
395
396 _LONG_REG_mask = _PTR_REG_mask;
397 _STACK_OR_LONG_REG_mask = _LONG_REG_mask;
398 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask());
399
400 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask;
401 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()));
402 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next()));
403 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()));
404 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next()));
405
406 _LONG_NO_RCX_REG_mask = _LONG_REG_mask;
407 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()));
408 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next()));
409
410 _INT_REG_mask = _ALL_INT_REG_mask;
411 if (PreserveFramePointer) {
412 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()));
413 }
414 if (need_r12_heapbase()) {
415 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()));
416 }
417
418 _STACK_OR_INT_REG_mask = _INT_REG_mask;
419 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask());
420
421 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask;
422 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()));
423 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()));
424
425 _INT_NO_RCX_REG_mask = _INT_REG_mask;
426 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()));
427
428 if (Matcher::has_predicated_vectors()) {
429 // Post-loop multi-versioning expects mask to be present in K1 register, till the time
430 // its fixed, RA should not be allocting K1 register, this shall prevent any accidental
431 // curruption of value held in K1 register.
432 if (PostLoopMultiversioning) {
433 const_cast<RegMask*>(&_VECTMASK_REG_mask)->Remove(OptoReg::as_OptoReg(k1->as_VMReg()));
434 const_cast<RegMask*>(&_VECTMASK_REG_mask)->Remove(OptoReg::as_OptoReg(k1->as_VMReg()->next()));
435 }
436 }
437 }
438
439 static bool generate_vzeroupper(Compile* C) {
440 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper
441 }
442
443 static int clear_avx_size() {
444 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper
445 }
446
447 // !!!!! Special hack to get all types of calls to specify the byte offset
448 // from the start of the call to the point where the return address
449 // will point.
450 int MachCallStaticJavaNode::ret_addr_offset()
451 {
452 int offset = 5; // 5 bytes from start of call to where return address points
453 offset += clear_avx_size();
454 return offset;
455 }
456
457 int MachCallDynamicJavaNode::ret_addr_offset()
458 {
459 int offset = 15; // 15 bytes from start of call to where return address points
460 offset += clear_avx_size();
461 return offset;
462 }
463
464 int MachCallRuntimeNode::ret_addr_offset() {
465 int offset = 13; // movq r10,#addr; callq (r10)
466 if (this->ideal_Opcode() != Op_CallLeafVector) {
467 offset += clear_avx_size();
468 }
469 return offset;
470 }
471
472 int MachCallNativeNode::ret_addr_offset() {
473 int offset = 13; // movq r10,#addr; callq (r10)
474 offset += clear_avx_size();
475 return offset;
476 }
477 //
478 // Compute padding required for nodes which need alignment
479 //
480
481 // The address of the call instruction needs to be 4-byte aligned to
482 // ensure that it does not span a cache line so that it can be patched.
483 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
484 {
485 current_offset += clear_avx_size(); // skip vzeroupper
486 current_offset += 1; // skip call opcode byte
487 return align_up(current_offset, alignment_required()) - current_offset;
488 }
489
490 // The address of the call instruction needs to be 4-byte aligned to
491 // ensure that it does not span a cache line so that it can be patched.
492 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
493 {
494 current_offset += clear_avx_size(); // skip vzeroupper
495 current_offset += 11; // skip movq instruction + call opcode byte
496 return align_up(current_offset, alignment_required()) - current_offset;
497 }
498
499 // EMIT_RM()
500 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
501 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
502 cbuf.insts()->emit_int8(c);
503 }
504
505 // EMIT_CC()
506 void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
507 unsigned char c = (unsigned char) (f1 | f2);
508 cbuf.insts()->emit_int8(c);
509 }
510
511 // EMIT_OPCODE()
512 void emit_opcode(CodeBuffer &cbuf, int code) {
513 cbuf.insts()->emit_int8((unsigned char) code);
514 }
515
516 // EMIT_OPCODE() w/ relocation information
517 void emit_opcode(CodeBuffer &cbuf,
518 int code, relocInfo::relocType reloc, int offset, int format)
519 {
520 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format);
521 emit_opcode(cbuf, code);
522 }
523
524 // EMIT_D8()
525 void emit_d8(CodeBuffer &cbuf, int d8) {
526 cbuf.insts()->emit_int8((unsigned char) d8);
527 }
528
529 // EMIT_D16()
530 void emit_d16(CodeBuffer &cbuf, int d16) {
531 cbuf.insts()->emit_int16(d16);
532 }
533
534 // EMIT_D32()
535 void emit_d32(CodeBuffer &cbuf, int d32) {
536 cbuf.insts()->emit_int32(d32);
537 }
538
539 // EMIT_D64()
540 void emit_d64(CodeBuffer &cbuf, int64_t d64) {
541 cbuf.insts()->emit_int64(d64);
542 }
543
544 // emit 32 bit value and construct relocation entry from relocInfo::relocType
545 void emit_d32_reloc(CodeBuffer& cbuf,
546 int d32,
547 relocInfo::relocType reloc,
548 int format)
549 {
550 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
551 cbuf.relocate(cbuf.insts_mark(), reloc, format);
552 cbuf.insts()->emit_int32(d32);
553 }
554
555 // emit 32 bit value and construct relocation entry from RelocationHolder
556 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) {
557 #ifdef ASSERT
558 if (rspec.reloc()->type() == relocInfo::oop_type &&
559 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
560 assert(Universe::heap()->is_in((address)(intptr_t)d32), "should be real oop");
561 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)), "cannot embed broken oops in code");
562 }
563 #endif
564 cbuf.relocate(cbuf.insts_mark(), rspec, format);
565 cbuf.insts()->emit_int32(d32);
566 }
567
568 void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
569 address next_ip = cbuf.insts_end() + 4;
570 emit_d32_reloc(cbuf, (int) (addr - next_ip),
571 external_word_Relocation::spec(addr),
572 RELOC_DISP32);
573 }
574
575
576 // emit 64 bit value and construct relocation entry from relocInfo::relocType
577 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) {
578 cbuf.relocate(cbuf.insts_mark(), reloc, format);
579 cbuf.insts()->emit_int64(d64);
580 }
581
582 // emit 64 bit value and construct relocation entry from RelocationHolder
583 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) {
584 #ifdef ASSERT
585 if (rspec.reloc()->type() == relocInfo::oop_type &&
586 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
587 assert(Universe::heap()->is_in((address)d64), "should be real oop");
588 assert(oopDesc::is_oop(cast_to_oop(d64)), "cannot embed broken oops in code");
589 }
590 #endif
591 cbuf.relocate(cbuf.insts_mark(), rspec, format);
592 cbuf.insts()->emit_int64(d64);
593 }
594
595 // Access stack slot for load or store
596 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp)
597 {
598 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src])
599 if (-0x80 <= disp && disp < 0x80) {
600 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte
601 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
602 emit_d8(cbuf, disp); // Displacement // R/M byte
603 } else {
604 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte
605 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
606 emit_d32(cbuf, disp); // Displacement // R/M byte
607 }
608 }
609
610 // rRegI ereg, memory mem) %{ // emit_reg_mem
611 void encode_RegMem(CodeBuffer &cbuf,
612 int reg,
613 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc)
614 {
615 assert(disp_reloc == relocInfo::none, "cannot have disp");
616 int regenc = reg & 7;
617 int baseenc = base & 7;
618 int indexenc = index & 7;
619
620 // There is no index & no scale, use form without SIB byte
621 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) {
622 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
623 if (disp == 0 && base != RBP_enc && base != R13_enc) {
624 emit_rm(cbuf, 0x0, regenc, baseenc); // *
625 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
626 // If 8-bit displacement, mode 0x1
627 emit_rm(cbuf, 0x1, regenc, baseenc); // *
628 emit_d8(cbuf, disp);
629 } else {
630 // If 32-bit displacement
631 if (base == -1) { // Special flag for absolute address
632 emit_rm(cbuf, 0x0, regenc, 0x5); // *
633 if (disp_reloc != relocInfo::none) {
634 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
635 } else {
636 emit_d32(cbuf, disp);
637 }
638 } else {
639 // Normal base + offset
640 emit_rm(cbuf, 0x2, regenc, baseenc); // *
641 if (disp_reloc != relocInfo::none) {
642 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
643 } else {
644 emit_d32(cbuf, disp);
645 }
646 }
647 }
648 } else {
649 // Else, encode with the SIB byte
650 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
651 if (disp == 0 && base != RBP_enc && base != R13_enc) {
652 // If no displacement
653 emit_rm(cbuf, 0x0, regenc, 0x4); // *
654 emit_rm(cbuf, scale, indexenc, baseenc);
655 } else {
656 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
657 // If 8-bit displacement, mode 0x1
658 emit_rm(cbuf, 0x1, regenc, 0x4); // *
659 emit_rm(cbuf, scale, indexenc, baseenc);
660 emit_d8(cbuf, disp);
661 } else {
662 // If 32-bit displacement
663 if (base == 0x04 ) {
664 emit_rm(cbuf, 0x2, regenc, 0x4);
665 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
666 } else {
667 emit_rm(cbuf, 0x2, regenc, 0x4);
668 emit_rm(cbuf, scale, indexenc, baseenc); // *
669 }
670 if (disp_reloc != relocInfo::none) {
671 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
672 } else {
673 emit_d32(cbuf, disp);
674 }
675 }
676 }
677 }
678 }
679
680 // This could be in MacroAssembler but it's fairly C2 specific
681 void emit_cmpfp_fixup(MacroAssembler& _masm) {
682 Label exit;
683 __ jccb(Assembler::noParity, exit);
684 __ pushf();
685 //
686 // comiss/ucomiss instructions set ZF,PF,CF flags and
687 // zero OF,AF,SF for NaN values.
688 // Fixup flags by zeroing ZF,PF so that compare of NaN
689 // values returns 'less than' result (CF is set).
690 // Leave the rest of flags unchanged.
691 //
692 // 7 6 5 4 3 2 1 0
693 // |S|Z|r|A|r|P|r|C| (r - reserved bit)
694 // 0 0 1 0 1 0 1 1 (0x2B)
695 //
696 __ andq(Address(rsp, 0), 0xffffff2b);
697 __ popf();
698 __ bind(exit);
699 }
700
701 void emit_cmpfp3(MacroAssembler& _masm, Register dst) {
702 Label done;
703 __ movl(dst, -1);
704 __ jcc(Assembler::parity, done);
705 __ jcc(Assembler::below, done);
706 __ setb(Assembler::notEqual, dst);
707 __ movzbl(dst, dst);
708 __ bind(done);
709 }
710
711 // Math.min() # Math.max()
712 // --------------------------
713 // ucomis[s/d] #
714 // ja -> b # a
715 // jp -> NaN # NaN
716 // jb -> a # b
717 // je #
718 // |-jz -> a | b # a & b
719 // | -> a #
720 void emit_fp_min_max(MacroAssembler& _masm, XMMRegister dst,
721 XMMRegister a, XMMRegister b,
722 XMMRegister xmmt, Register rt,
723 bool min, bool single) {
724
725 Label nan, zero, below, above, done;
726
727 if (single)
728 __ ucomiss(a, b);
729 else
730 __ ucomisd(a, b);
731
732 if (dst->encoding() != (min ? b : a)->encoding())
733 __ jccb(Assembler::above, above); // CF=0 & ZF=0
734 else
735 __ jccb(Assembler::above, done);
736
737 __ jccb(Assembler::parity, nan); // PF=1
738 __ jccb(Assembler::below, below); // CF=1
739
740 // equal
741 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit);
742 if (single) {
743 __ ucomiss(a, xmmt);
744 __ jccb(Assembler::equal, zero);
745
746 __ movflt(dst, a);
747 __ jmp(done);
748 }
749 else {
750 __ ucomisd(a, xmmt);
751 __ jccb(Assembler::equal, zero);
752
753 __ movdbl(dst, a);
754 __ jmp(done);
755 }
756
757 __ bind(zero);
758 if (min)
759 __ vpor(dst, a, b, Assembler::AVX_128bit);
760 else
761 __ vpand(dst, a, b, Assembler::AVX_128bit);
762
763 __ jmp(done);
764
765 __ bind(above);
766 if (single)
767 __ movflt(dst, min ? b : a);
768 else
769 __ movdbl(dst, min ? b : a);
770
771 __ jmp(done);
772
773 __ bind(nan);
774 if (single) {
775 __ movl(rt, 0x7fc00000); // Float.NaN
776 __ movdl(dst, rt);
777 }
778 else {
779 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN
780 __ movdq(dst, rt);
781 }
782 __ jmp(done);
783
784 __ bind(below);
785 if (single)
786 __ movflt(dst, min ? a : b);
787 else
788 __ movdbl(dst, min ? a : b);
789
790 __ bind(done);
791 }
792
793 //=============================================================================
794 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
795
796 int ConstantTable::calculate_table_base_offset() const {
797 return 0; // absolute addressing, no offset
798 }
799
800 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
801 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
802 ShouldNotReachHere();
803 }
804
805 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
806 // Empty encoding
807 }
808
809 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
810 return 0;
811 }
812
813 #ifndef PRODUCT
814 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
815 st->print("# MachConstantBaseNode (empty encoding)");
816 }
817 #endif
818
819
820 //=============================================================================
821 #ifndef PRODUCT
822 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
823 Compile* C = ra_->C;
824
825 int framesize = C->output()->frame_size_in_bytes();
826 int bangsize = C->output()->bang_size_in_bytes();
827 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
828 // Remove wordSize for return addr which is already pushed.
829 framesize -= wordSize;
830
831 if (C->output()->need_stack_bang(bangsize)) {
832 framesize -= wordSize;
833 st->print("# stack bang (%d bytes)", bangsize);
834 st->print("\n\t");
835 st->print("pushq rbp\t# Save rbp");
836 if (PreserveFramePointer) {
837 st->print("\n\t");
838 st->print("movq rbp, rsp\t# Save the caller's SP into rbp");
839 }
840 if (framesize) {
841 st->print("\n\t");
842 st->print("subq rsp, #%d\t# Create frame",framesize);
843 }
844 } else {
845 st->print("subq rsp, #%d\t# Create frame",framesize);
846 st->print("\n\t");
847 framesize -= wordSize;
848 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
849 if (PreserveFramePointer) {
850 st->print("\n\t");
851 st->print("movq rbp, rsp\t# Save the caller's SP into rbp");
852 if (framesize > 0) {
853 st->print("\n\t");
854 st->print("addq rbp, #%d", framesize);
855 }
856 }
857 }
858
859 if (VerifyStackAtCalls) {
860 st->print("\n\t");
861 framesize -= wordSize;
862 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize);
863 #ifdef ASSERT
864 st->print("\n\t");
865 st->print("# stack alignment check");
866 #endif
867 }
868 if (C->stub_function() != NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) {
869 st->print("\n\t");
870 st->print("cmpl [r15_thread + #disarmed_offset], #disarmed_value\t");
871 st->print("\n\t");
872 st->print("je fast_entry\t");
873 st->print("\n\t");
874 st->print("call #nmethod_entry_barrier_stub\t");
875 st->print("\n\tfast_entry:");
876 }
877 st->cr();
878 }
879 #endif
880
881 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
882 Compile* C = ra_->C;
883 MacroAssembler _masm(&cbuf);
884
885 int framesize = C->output()->frame_size_in_bytes();
886 int bangsize = C->output()->bang_size_in_bytes();
887
888 if (C->clinit_barrier_on_entry()) {
889 assert(VM_Version::supports_fast_class_init_checks(), "sanity");
890 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
891
892 Label L_skip_barrier;
893 Register klass = rscratch1;
894
895 __ mov_metadata(klass, C->method()->holder()->constant_encoding());
896 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/);
897
898 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path
899
900 __ bind(L_skip_barrier);
901 }
902
903 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != NULL);
904
905 C->output()->set_frame_complete(cbuf.insts_size());
906
907 if (C->has_mach_constant_base_node()) {
908 // NOTE: We set the table base offset here because users might be
909 // emitted before MachConstantBaseNode.
910 ConstantTable& constant_table = C->output()->constant_table();
911 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
912 }
913 }
914
915 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
916 {
917 return MachNode::size(ra_); // too many variables; just compute it
918 // the hard way
919 }
920
921 int MachPrologNode::reloc() const
922 {
923 return 0; // a large enough number
924 }
925
926 //=============================================================================
927 #ifndef PRODUCT
928 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
929 {
930 Compile* C = ra_->C;
931 if (generate_vzeroupper(C)) {
932 st->print("vzeroupper");
933 st->cr(); st->print("\t");
934 }
935
936 int framesize = C->output()->frame_size_in_bytes();
937 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
938 // Remove word for return adr already pushed
939 // and RBP
940 framesize -= 2*wordSize;
941
942 if (framesize) {
943 st->print_cr("addq rsp, %d\t# Destroy frame", framesize);
944 st->print("\t");
945 }
946
947 st->print_cr("popq rbp");
948 if (do_polling() && C->is_method_compilation()) {
949 st->print("\t");
950 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t"
951 "ja #safepoint_stub\t"
952 "# Safepoint: poll for GC");
953 }
954 }
955 #endif
956
957 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
958 {
959 Compile* C = ra_->C;
960 MacroAssembler _masm(&cbuf);
961
962 if (generate_vzeroupper(C)) {
963 // Clear upper bits of YMM registers when current compiled code uses
964 // wide vectors to avoid AVX <-> SSE transition penalty during call.
965 __ vzeroupper();
966 }
967
968 int framesize = C->output()->frame_size_in_bytes();
969 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
970 // Remove word for return adr already pushed
971 // and RBP
972 framesize -= 2*wordSize;
973
974 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here
975
976 if (framesize) {
977 emit_opcode(cbuf, Assembler::REX_W);
978 if (framesize < 0x80) {
979 emit_opcode(cbuf, 0x83); // addq rsp, #framesize
980 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
981 emit_d8(cbuf, framesize);
982 } else {
983 emit_opcode(cbuf, 0x81); // addq rsp, #framesize
984 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
985 emit_d32(cbuf, framesize);
986 }
987 }
988
989 // popq rbp
990 emit_opcode(cbuf, 0x58 | RBP_enc);
991
992 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
993 __ reserved_stack_check();
994 }
995
996 if (do_polling() && C->is_method_compilation()) {
997 MacroAssembler _masm(&cbuf);
998 Label dummy_label;
999 Label* code_stub = &dummy_label;
1000 if (!C->output()->in_scratch_emit_size()) {
1001 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1002 C->output()->add_stub(stub);
1003 code_stub = &stub->entry();
1004 }
1005 __ relocate(relocInfo::poll_return_type);
1006 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */);
1007 }
1008 }
1009
1010 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
1011 {
1012 return MachNode::size(ra_); // too many variables; just compute it
1013 // the hard way
1014 }
1015
1016 int MachEpilogNode::reloc() const
1017 {
1018 return 2; // a large enough number
1019 }
1020
1021 const Pipeline* MachEpilogNode::pipeline() const
1022 {
1023 return MachNode::pipeline_class();
1024 }
1025
1026 //=============================================================================
1027
1028 enum RC {
1029 rc_bad,
1030 rc_int,
1031 rc_kreg,
1032 rc_float,
1033 rc_stack
1034 };
1035
1036 static enum RC rc_class(OptoReg::Name reg)
1037 {
1038 if( !OptoReg::is_valid(reg) ) return rc_bad;
1039
1040 if (OptoReg::is_stack(reg)) return rc_stack;
1041
1042 VMReg r = OptoReg::as_VMReg(reg);
1043
1044 if (r->is_Register()) return rc_int;
1045
1046 if (r->is_KRegister()) return rc_kreg;
1047
1048 assert(r->is_XMMRegister(), "must be");
1049 return rc_float;
1050 }
1051
1052 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad.
1053 static void vec_mov_helper(CodeBuffer *cbuf, int src_lo, int dst_lo,
1054 int src_hi, int dst_hi, uint ireg, outputStream* st);
1055
1056 void vec_spill_helper(CodeBuffer *cbuf, bool is_load,
1057 int stack_offset, int reg, uint ireg, outputStream* st);
1058
1059 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
1060 int dst_offset, uint ireg, outputStream* st) {
1061 if (cbuf) {
1062 MacroAssembler _masm(cbuf);
1063 switch (ireg) {
1064 case Op_VecS:
1065 __ movq(Address(rsp, -8), rax);
1066 __ movl(rax, Address(rsp, src_offset));
1067 __ movl(Address(rsp, dst_offset), rax);
1068 __ movq(rax, Address(rsp, -8));
1069 break;
1070 case Op_VecD:
1071 __ pushq(Address(rsp, src_offset));
1072 __ popq (Address(rsp, dst_offset));
1073 break;
1074 case Op_VecX:
1075 __ pushq(Address(rsp, src_offset));
1076 __ popq (Address(rsp, dst_offset));
1077 __ pushq(Address(rsp, src_offset+8));
1078 __ popq (Address(rsp, dst_offset+8));
1079 break;
1080 case Op_VecY:
1081 __ vmovdqu(Address(rsp, -32), xmm0);
1082 __ vmovdqu(xmm0, Address(rsp, src_offset));
1083 __ vmovdqu(Address(rsp, dst_offset), xmm0);
1084 __ vmovdqu(xmm0, Address(rsp, -32));
1085 break;
1086 case Op_VecZ:
1087 __ evmovdquq(Address(rsp, -64), xmm0, 2);
1088 __ evmovdquq(xmm0, Address(rsp, src_offset), 2);
1089 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2);
1090 __ evmovdquq(xmm0, Address(rsp, -64), 2);
1091 break;
1092 default:
1093 ShouldNotReachHere();
1094 }
1095 #ifndef PRODUCT
1096 } else {
1097 switch (ireg) {
1098 case Op_VecS:
1099 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1100 "movl rax, [rsp + #%d]\n\t"
1101 "movl [rsp + #%d], rax\n\t"
1102 "movq rax, [rsp - #8]",
1103 src_offset, dst_offset);
1104 break;
1105 case Op_VecD:
1106 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1107 "popq [rsp + #%d]",
1108 src_offset, dst_offset);
1109 break;
1110 case Op_VecX:
1111 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t"
1112 "popq [rsp + #%d]\n\t"
1113 "pushq [rsp + #%d]\n\t"
1114 "popq [rsp + #%d]",
1115 src_offset, dst_offset, src_offset+8, dst_offset+8);
1116 break;
1117 case Op_VecY:
1118 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
1119 "vmovdqu xmm0, [rsp + #%d]\n\t"
1120 "vmovdqu [rsp + #%d], xmm0\n\t"
1121 "vmovdqu xmm0, [rsp - #32]",
1122 src_offset, dst_offset);
1123 break;
1124 case Op_VecZ:
1125 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t"
1126 "vmovdqu xmm0, [rsp + #%d]\n\t"
1127 "vmovdqu [rsp + #%d], xmm0\n\t"
1128 "vmovdqu xmm0, [rsp - #64]",
1129 src_offset, dst_offset);
1130 break;
1131 default:
1132 ShouldNotReachHere();
1133 }
1134 #endif
1135 }
1136 }
1137
1138 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
1139 PhaseRegAlloc* ra_,
1140 bool do_size,
1141 outputStream* st) const {
1142 assert(cbuf != NULL || st != NULL, "sanity");
1143 // Get registers to move
1144 OptoReg::Name src_second = ra_->get_reg_second(in(1));
1145 OptoReg::Name src_first = ra_->get_reg_first(in(1));
1146 OptoReg::Name dst_second = ra_->get_reg_second(this);
1147 OptoReg::Name dst_first = ra_->get_reg_first(this);
1148
1149 enum RC src_second_rc = rc_class(src_second);
1150 enum RC src_first_rc = rc_class(src_first);
1151 enum RC dst_second_rc = rc_class(dst_second);
1152 enum RC dst_first_rc = rc_class(dst_first);
1153
1154 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
1155 "must move at least 1 register" );
1156
1157 if (src_first == dst_first && src_second == dst_second) {
1158 // Self copy, no move
1159 return 0;
1160 }
1161 if (bottom_type()->isa_vect() != NULL && bottom_type()->isa_vectmask() == NULL) {
1162 uint ireg = ideal_reg();
1163 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
1164 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity");
1165 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
1166 // mem -> mem
1167 int src_offset = ra_->reg2offset(src_first);
1168 int dst_offset = ra_->reg2offset(dst_first);
1169 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st);
1170 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) {
1171 vec_mov_helper(cbuf, src_first, dst_first, src_second, dst_second, ireg, st);
1172 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) {
1173 int stack_offset = ra_->reg2offset(dst_first);
1174 vec_spill_helper(cbuf, false, stack_offset, src_first, ireg, st);
1175 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) {
1176 int stack_offset = ra_->reg2offset(src_first);
1177 vec_spill_helper(cbuf, true, stack_offset, dst_first, ireg, st);
1178 } else {
1179 ShouldNotReachHere();
1180 }
1181 return 0;
1182 }
1183 if (src_first_rc == rc_stack) {
1184 // mem ->
1185 if (dst_first_rc == rc_stack) {
1186 // mem -> mem
1187 assert(src_second != dst_first, "overlap");
1188 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1189 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1190 // 64-bit
1191 int src_offset = ra_->reg2offset(src_first);
1192 int dst_offset = ra_->reg2offset(dst_first);
1193 if (cbuf) {
1194 MacroAssembler _masm(cbuf);
1195 __ pushq(Address(rsp, src_offset));
1196 __ popq (Address(rsp, dst_offset));
1197 #ifndef PRODUCT
1198 } else {
1199 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1200 "popq [rsp + #%d]",
1201 src_offset, dst_offset);
1202 #endif
1203 }
1204 } else {
1205 // 32-bit
1206 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1207 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1208 // No pushl/popl, so:
1209 int src_offset = ra_->reg2offset(src_first);
1210 int dst_offset = ra_->reg2offset(dst_first);
1211 if (cbuf) {
1212 MacroAssembler _masm(cbuf);
1213 __ movq(Address(rsp, -8), rax);
1214 __ movl(rax, Address(rsp, src_offset));
1215 __ movl(Address(rsp, dst_offset), rax);
1216 __ movq(rax, Address(rsp, -8));
1217 #ifndef PRODUCT
1218 } else {
1219 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1220 "movl rax, [rsp + #%d]\n\t"
1221 "movl [rsp + #%d], rax\n\t"
1222 "movq rax, [rsp - #8]",
1223 src_offset, dst_offset);
1224 #endif
1225 }
1226 }
1227 return 0;
1228 } else if (dst_first_rc == rc_int) {
1229 // mem -> gpr
1230 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1231 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1232 // 64-bit
1233 int offset = ra_->reg2offset(src_first);
1234 if (cbuf) {
1235 MacroAssembler _masm(cbuf);
1236 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1237 #ifndef PRODUCT
1238 } else {
1239 st->print("movq %s, [rsp + #%d]\t# spill",
1240 Matcher::regName[dst_first],
1241 offset);
1242 #endif
1243 }
1244 } else {
1245 // 32-bit
1246 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1247 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1248 int offset = ra_->reg2offset(src_first);
1249 if (cbuf) {
1250 MacroAssembler _masm(cbuf);
1251 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1252 #ifndef PRODUCT
1253 } else {
1254 st->print("movl %s, [rsp + #%d]\t# spill",
1255 Matcher::regName[dst_first],
1256 offset);
1257 #endif
1258 }
1259 }
1260 return 0;
1261 } else if (dst_first_rc == rc_float) {
1262 // mem-> xmm
1263 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1264 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1265 // 64-bit
1266 int offset = ra_->reg2offset(src_first);
1267 if (cbuf) {
1268 MacroAssembler _masm(cbuf);
1269 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1270 #ifndef PRODUCT
1271 } else {
1272 st->print("%s %s, [rsp + #%d]\t# spill",
1273 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1274 Matcher::regName[dst_first],
1275 offset);
1276 #endif
1277 }
1278 } else {
1279 // 32-bit
1280 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1281 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1282 int offset = ra_->reg2offset(src_first);
1283 if (cbuf) {
1284 MacroAssembler _masm(cbuf);
1285 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1286 #ifndef PRODUCT
1287 } else {
1288 st->print("movss %s, [rsp + #%d]\t# spill",
1289 Matcher::regName[dst_first],
1290 offset);
1291 #endif
1292 }
1293 }
1294 return 0;
1295 } else if (dst_first_rc == rc_kreg) {
1296 // mem -> kreg
1297 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1298 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1299 // 64-bit
1300 int offset = ra_->reg2offset(src_first);
1301 if (cbuf) {
1302 MacroAssembler _masm(cbuf);
1303 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1304 #ifndef PRODUCT
1305 } else {
1306 st->print("kmovq %s, [rsp + #%d]\t# spill",
1307 Matcher::regName[dst_first],
1308 offset);
1309 #endif
1310 }
1311 }
1312 return 0;
1313 }
1314 } else if (src_first_rc == rc_int) {
1315 // gpr ->
1316 if (dst_first_rc == rc_stack) {
1317 // gpr -> mem
1318 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1319 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1320 // 64-bit
1321 int offset = ra_->reg2offset(dst_first);
1322 if (cbuf) {
1323 MacroAssembler _masm(cbuf);
1324 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
1325 #ifndef PRODUCT
1326 } else {
1327 st->print("movq [rsp + #%d], %s\t# spill",
1328 offset,
1329 Matcher::regName[src_first]);
1330 #endif
1331 }
1332 } else {
1333 // 32-bit
1334 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1335 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1336 int offset = ra_->reg2offset(dst_first);
1337 if (cbuf) {
1338 MacroAssembler _masm(cbuf);
1339 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
1340 #ifndef PRODUCT
1341 } else {
1342 st->print("movl [rsp + #%d], %s\t# spill",
1343 offset,
1344 Matcher::regName[src_first]);
1345 #endif
1346 }
1347 }
1348 return 0;
1349 } else if (dst_first_rc == rc_int) {
1350 // gpr -> gpr
1351 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1352 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1353 // 64-bit
1354 if (cbuf) {
1355 MacroAssembler _masm(cbuf);
1356 __ movq(as_Register(Matcher::_regEncode[dst_first]),
1357 as_Register(Matcher::_regEncode[src_first]));
1358 #ifndef PRODUCT
1359 } else {
1360 st->print("movq %s, %s\t# spill",
1361 Matcher::regName[dst_first],
1362 Matcher::regName[src_first]);
1363 #endif
1364 }
1365 return 0;
1366 } else {
1367 // 32-bit
1368 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1369 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1370 if (cbuf) {
1371 MacroAssembler _masm(cbuf);
1372 __ movl(as_Register(Matcher::_regEncode[dst_first]),
1373 as_Register(Matcher::_regEncode[src_first]));
1374 #ifndef PRODUCT
1375 } else {
1376 st->print("movl %s, %s\t# spill",
1377 Matcher::regName[dst_first],
1378 Matcher::regName[src_first]);
1379 #endif
1380 }
1381 return 0;
1382 }
1383 } else if (dst_first_rc == rc_float) {
1384 // gpr -> xmm
1385 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1386 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1387 // 64-bit
1388 if (cbuf) {
1389 MacroAssembler _masm(cbuf);
1390 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1391 #ifndef PRODUCT
1392 } else {
1393 st->print("movdq %s, %s\t# spill",
1394 Matcher::regName[dst_first],
1395 Matcher::regName[src_first]);
1396 #endif
1397 }
1398 } else {
1399 // 32-bit
1400 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1401 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1402 if (cbuf) {
1403 MacroAssembler _masm(cbuf);
1404 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1405 #ifndef PRODUCT
1406 } else {
1407 st->print("movdl %s, %s\t# spill",
1408 Matcher::regName[dst_first],
1409 Matcher::regName[src_first]);
1410 #endif
1411 }
1412 }
1413 return 0;
1414 } else if (dst_first_rc == rc_kreg) {
1415 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1416 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1417 // 64-bit
1418 if (cbuf) {
1419 MacroAssembler _masm(cbuf);
1420 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1421 #ifndef PRODUCT
1422 } else {
1423 st->print("kmovq %s, %s\t# spill",
1424 Matcher::regName[dst_first],
1425 Matcher::regName[src_first]);
1426 #endif
1427 }
1428 }
1429 Unimplemented();
1430 return 0;
1431 }
1432 } else if (src_first_rc == rc_float) {
1433 // xmm ->
1434 if (dst_first_rc == rc_stack) {
1435 // xmm -> mem
1436 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1437 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1438 // 64-bit
1439 int offset = ra_->reg2offset(dst_first);
1440 if (cbuf) {
1441 MacroAssembler _masm(cbuf);
1442 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1443 #ifndef PRODUCT
1444 } else {
1445 st->print("movsd [rsp + #%d], %s\t# spill",
1446 offset,
1447 Matcher::regName[src_first]);
1448 #endif
1449 }
1450 } else {
1451 // 32-bit
1452 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1453 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1454 int offset = ra_->reg2offset(dst_first);
1455 if (cbuf) {
1456 MacroAssembler _masm(cbuf);
1457 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1458 #ifndef PRODUCT
1459 } else {
1460 st->print("movss [rsp + #%d], %s\t# spill",
1461 offset,
1462 Matcher::regName[src_first]);
1463 #endif
1464 }
1465 }
1466 return 0;
1467 } else if (dst_first_rc == rc_int) {
1468 // xmm -> gpr
1469 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1470 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1471 // 64-bit
1472 if (cbuf) {
1473 MacroAssembler _masm(cbuf);
1474 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1475 #ifndef PRODUCT
1476 } else {
1477 st->print("movdq %s, %s\t# spill",
1478 Matcher::regName[dst_first],
1479 Matcher::regName[src_first]);
1480 #endif
1481 }
1482 } else {
1483 // 32-bit
1484 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1485 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1486 if (cbuf) {
1487 MacroAssembler _masm(cbuf);
1488 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1489 #ifndef PRODUCT
1490 } else {
1491 st->print("movdl %s, %s\t# spill",
1492 Matcher::regName[dst_first],
1493 Matcher::regName[src_first]);
1494 #endif
1495 }
1496 }
1497 return 0;
1498 } else if (dst_first_rc == rc_float) {
1499 // xmm -> xmm
1500 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1501 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1502 // 64-bit
1503 if (cbuf) {
1504 MacroAssembler _masm(cbuf);
1505 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1506 #ifndef PRODUCT
1507 } else {
1508 st->print("%s %s, %s\t# spill",
1509 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
1510 Matcher::regName[dst_first],
1511 Matcher::regName[src_first]);
1512 #endif
1513 }
1514 } else {
1515 // 32-bit
1516 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1517 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1518 if (cbuf) {
1519 MacroAssembler _masm(cbuf);
1520 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1521 #ifndef PRODUCT
1522 } else {
1523 st->print("%s %s, %s\t# spill",
1524 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1525 Matcher::regName[dst_first],
1526 Matcher::regName[src_first]);
1527 #endif
1528 }
1529 }
1530 return 0;
1531 } else if (dst_first_rc == rc_kreg) {
1532 assert(false, "Illegal spilling");
1533 return 0;
1534 }
1535 } else if (src_first_rc == rc_kreg) {
1536 if (dst_first_rc == rc_stack) {
1537 // mem -> kreg
1538 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1539 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1540 // 64-bit
1541 int offset = ra_->reg2offset(dst_first);
1542 if (cbuf) {
1543 MacroAssembler _masm(cbuf);
1544 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first]));
1545 #ifndef PRODUCT
1546 } else {
1547 st->print("kmovq [rsp + #%d] , %s\t# spill",
1548 offset,
1549 Matcher::regName[src_first]);
1550 #endif
1551 }
1552 }
1553 return 0;
1554 } else if (dst_first_rc == rc_int) {
1555 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1556 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1557 // 64-bit
1558 if (cbuf) {
1559 MacroAssembler _masm(cbuf);
1560 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first]));
1561 #ifndef PRODUCT
1562 } else {
1563 st->print("kmovq %s, %s\t# spill",
1564 Matcher::regName[dst_first],
1565 Matcher::regName[src_first]);
1566 #endif
1567 }
1568 }
1569 Unimplemented();
1570 return 0;
1571 } else if (dst_first_rc == rc_kreg) {
1572 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1573 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1574 // 64-bit
1575 if (cbuf) {
1576 MacroAssembler _masm(cbuf);
1577 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first]));
1578 #ifndef PRODUCT
1579 } else {
1580 st->print("kmovq %s, %s\t# spill",
1581 Matcher::regName[dst_first],
1582 Matcher::regName[src_first]);
1583 #endif
1584 }
1585 }
1586 return 0;
1587 } else if (dst_first_rc == rc_float) {
1588 assert(false, "Illegal spill");
1589 return 0;
1590 }
1591 }
1592
1593 assert(0," foo ");
1594 Unimplemented();
1595 return 0;
1596 }
1597
1598 #ifndef PRODUCT
1599 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const {
1600 implementation(NULL, ra_, false, st);
1601 }
1602 #endif
1603
1604 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1605 implementation(&cbuf, ra_, false, NULL);
1606 }
1607
1608 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1609 return MachNode::size(ra_);
1610 }
1611
1612 //=============================================================================
1613 #ifndef PRODUCT
1614 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1615 {
1616 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1617 int reg = ra_->get_reg_first(this);
1618 st->print("leaq %s, [rsp + #%d]\t# box lock",
1619 Matcher::regName[reg], offset);
1620 }
1621 #endif
1622
1623 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1624 {
1625 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1626 int reg = ra_->get_encode(this);
1627 if (offset >= 0x80) {
1628 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1629 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1630 emit_rm(cbuf, 0x2, reg & 7, 0x04);
1631 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1632 emit_d32(cbuf, offset);
1633 } else {
1634 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1635 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1636 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1637 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1638 emit_d8(cbuf, offset);
1639 }
1640 }
1641
1642 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1643 {
1644 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1645 return (offset < 0x80) ? 5 : 8; // REX
1646 }
1647
1648 //=============================================================================
1649 #ifndef PRODUCT
1650 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1651 {
1652 if (UseCompressedClassPointers) {
1653 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1654 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1655 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1656 } else {
1657 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1658 "# Inline cache check");
1659 }
1660 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1661 st->print_cr("\tnop\t# nops to align entry point");
1662 }
1663 #endif
1664
1665 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1666 {
1667 MacroAssembler masm(&cbuf);
1668 uint insts_size = cbuf.insts_size();
1669 if (UseCompressedClassPointers) {
1670 masm.load_klass(rscratch1, j_rarg0, rscratch2);
1671 masm.cmpptr(rax, rscratch1);
1672 } else {
1673 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1674 }
1675
1676 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1677
1678 /* WARNING these NOPs are critical so that verified entry point is properly
1679 4 bytes aligned for patching by NativeJump::patch_verified_entry() */
1680 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
1681 if (OptoBreakpoint) {
1682 // Leave space for int3
1683 nops_cnt -= 1;
1684 }
1685 nops_cnt &= 0x3; // Do not add nops if code is aligned.
1686 if (nops_cnt > 0)
1687 masm.nop(nops_cnt);
1688 }
1689
1690 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1691 {
1692 return MachNode::size(ra_); // too many variables; just compute it
1693 // the hard way
1694 }
1695
1696
1697 //=============================================================================
1698
1699 const bool Matcher::supports_vector_calling_convention(void) {
1700 if (EnableVectorSupport && UseVectorStubs) {
1701 return true;
1702 }
1703 return false;
1704 }
1705
1706 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
1707 assert(EnableVectorSupport && UseVectorStubs, "sanity");
1708 int lo = XMM0_num;
1709 int hi = XMM0b_num;
1710 if (ideal_reg == Op_VecX) hi = XMM0d_num;
1711 else if (ideal_reg == Op_VecY) hi = XMM0h_num;
1712 else if (ideal_reg == Op_VecZ) hi = XMM0p_num;
1713 return OptoRegPair(hi, lo);
1714 }
1715
1716 // Is this branch offset short enough that a short branch can be used?
1717 //
1718 // NOTE: If the platform does not provide any short branch variants, then
1719 // this method should return false for offset 0.
1720 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1721 // The passed offset is relative to address of the branch.
1722 // On 86 a branch displacement is calculated relative to address
1723 // of a next instruction.
1724 offset -= br_size;
1725
1726 // the short version of jmpConUCF2 contains multiple branches,
1727 // making the reach slightly less
1728 if (rule == jmpConUCF2_rule)
1729 return (-126 <= offset && offset <= 125);
1730 return (-128 <= offset && offset <= 127);
1731 }
1732
1733 // Return whether or not this register is ever used as an argument.
1734 // This function is used on startup to build the trampoline stubs in
1735 // generateOptoStub. Registers not mentioned will be killed by the VM
1736 // call in the trampoline, and arguments in those registers not be
1737 // available to the callee.
1738 bool Matcher::can_be_java_arg(int reg)
1739 {
1740 return
1741 reg == RDI_num || reg == RDI_H_num ||
1742 reg == RSI_num || reg == RSI_H_num ||
1743 reg == RDX_num || reg == RDX_H_num ||
1744 reg == RCX_num || reg == RCX_H_num ||
1745 reg == R8_num || reg == R8_H_num ||
1746 reg == R9_num || reg == R9_H_num ||
1747 reg == R12_num || reg == R12_H_num ||
1748 reg == XMM0_num || reg == XMM0b_num ||
1749 reg == XMM1_num || reg == XMM1b_num ||
1750 reg == XMM2_num || reg == XMM2b_num ||
1751 reg == XMM3_num || reg == XMM3b_num ||
1752 reg == XMM4_num || reg == XMM4b_num ||
1753 reg == XMM5_num || reg == XMM5b_num ||
1754 reg == XMM6_num || reg == XMM6b_num ||
1755 reg == XMM7_num || reg == XMM7b_num;
1756 }
1757
1758 bool Matcher::is_spillable_arg(int reg)
1759 {
1760 return can_be_java_arg(reg);
1761 }
1762
1763 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1764 // In 64 bit mode a code which use multiply when
1765 // devisor is constant is faster than hardware
1766 // DIV instruction (it uses MulHiL).
1767 return false;
1768 }
1769
1770 // Register for DIVI projection of divmodI
1771 RegMask Matcher::divI_proj_mask() {
1772 return INT_RAX_REG_mask();
1773 }
1774
1775 // Register for MODI projection of divmodI
1776 RegMask Matcher::modI_proj_mask() {
1777 return INT_RDX_REG_mask();
1778 }
1779
1780 // Register for DIVL projection of divmodL
1781 RegMask Matcher::divL_proj_mask() {
1782 return LONG_RAX_REG_mask();
1783 }
1784
1785 // Register for MODL projection of divmodL
1786 RegMask Matcher::modL_proj_mask() {
1787 return LONG_RDX_REG_mask();
1788 }
1789
1790 // Register for saving SP into on method handle invokes. Not used on x86_64.
1791 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1792 return NO_REG_mask();
1793 }
1794
1795 %}
1796
1797 //----------ENCODING BLOCK-----------------------------------------------------
1798 // This block specifies the encoding classes used by the compiler to
1799 // output byte streams. Encoding classes are parameterized macros
1800 // used by Machine Instruction Nodes in order to generate the bit
1801 // encoding of the instruction. Operands specify their base encoding
1802 // interface with the interface keyword. There are currently
1803 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
1804 // COND_INTER. REG_INTER causes an operand to generate a function
1805 // which returns its register number when queried. CONST_INTER causes
1806 // an operand to generate a function which returns the value of the
1807 // constant when queried. MEMORY_INTER causes an operand to generate
1808 // four functions which return the Base Register, the Index Register,
1809 // the Scale Value, and the Offset Value of the operand when queried.
1810 // COND_INTER causes an operand to generate six functions which return
1811 // the encoding code (ie - encoding bits for the instruction)
1812 // associated with each basic boolean condition for a conditional
1813 // instruction.
1814 //
1815 // Instructions specify two basic values for encoding. Again, a
1816 // function is available to check if the constant displacement is an
1817 // oop. They use the ins_encode keyword to specify their encoding
1818 // classes (which must be a sequence of enc_class names, and their
1819 // parameters, specified in the encoding block), and they use the
1820 // opcode keyword to specify, in order, their primary, secondary, and
1821 // tertiary opcode. Only the opcode sections which a particular
1822 // instruction needs for encoding need to be specified.
1823 encode %{
1824 // Build emit functions for each basic byte or larger field in the
1825 // intel encoding scheme (opcode, rm, sib, immediate), and call them
1826 // from C++ code in the enc_class source block. Emit functions will
1827 // live in the main source block for now. In future, we can
1828 // generalize this by adding a syntax that specifies the sizes of
1829 // fields in an order, so that the adlc can build the emit functions
1830 // automagically
1831
1832 // Emit primary opcode
1833 enc_class OpcP
1834 %{
1835 emit_opcode(cbuf, $primary);
1836 %}
1837
1838 // Emit secondary opcode
1839 enc_class OpcS
1840 %{
1841 emit_opcode(cbuf, $secondary);
1842 %}
1843
1844 // Emit tertiary opcode
1845 enc_class OpcT
1846 %{
1847 emit_opcode(cbuf, $tertiary);
1848 %}
1849
1850 // Emit opcode directly
1851 enc_class Opcode(immI d8)
1852 %{
1853 emit_opcode(cbuf, $d8$$constant);
1854 %}
1855
1856 // Emit size prefix
1857 enc_class SizePrefix
1858 %{
1859 emit_opcode(cbuf, 0x66);
1860 %}
1861
1862 enc_class reg(rRegI reg)
1863 %{
1864 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
1865 %}
1866
1867 enc_class reg_reg(rRegI dst, rRegI src)
1868 %{
1869 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1870 %}
1871
1872 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
1873 %{
1874 emit_opcode(cbuf, $opcode$$constant);
1875 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1876 %}
1877
1878 enc_class cdql_enc(no_rax_rdx_RegI div)
1879 %{
1880 // Full implementation of Java idiv and irem; checks for
1881 // special case as described in JVM spec., p.243 & p.271.
1882 //
1883 // normal case special case
1884 //
1885 // input : rax: dividend min_int
1886 // reg: divisor -1
1887 //
1888 // output: rax: quotient (= rax idiv reg) min_int
1889 // rdx: remainder (= rax irem reg) 0
1890 //
1891 // Code sequnce:
1892 //
1893 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax
1894 // 5: 75 07/08 jne e <normal>
1895 // 7: 33 d2 xor %edx,%edx
1896 // [div >= 8 -> offset + 1]
1897 // [REX_B]
1898 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div
1899 // c: 74 03/04 je 11 <done>
1900 // 000000000000000e <normal>:
1901 // e: 99 cltd
1902 // [div >= 8 -> offset + 1]
1903 // [REX_B]
1904 // f: f7 f9 idiv $div
1905 // 0000000000000011 <done>:
1906 MacroAssembler _masm(&cbuf);
1907 Label normal;
1908 Label done;
1909
1910 // cmp $0x80000000,%eax
1911 __ cmp(as_Register(RAX_enc), 0x80000000);
1912
1913 // jne e <normal>
1914 __ jccb(Assembler::notEqual, normal);
1915
1916 // xor %edx,%edx
1917 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc));
1918
1919 // cmp $0xffffffffffffffff,%ecx
1920 __ cmpl($div$$Register, -1);
1921
1922 // je 11 <done>
1923 __ jccb(Assembler::equal, done);
1924
1925 // <normal>
1926 // cltd
1927 __ bind(normal);
1928 __ cdql();
1929
1930 // idivl
1931 // <done>
1932 __ idivl($div$$Register);
1933 __ bind(done);
1934 %}
1935
1936 enc_class cdqq_enc(no_rax_rdx_RegL div)
1937 %{
1938 // Full implementation of Java ldiv and lrem; checks for
1939 // special case as described in JVM spec., p.243 & p.271.
1940 //
1941 // normal case special case
1942 //
1943 // input : rax: dividend min_long
1944 // reg: divisor -1
1945 //
1946 // output: rax: quotient (= rax idiv reg) min_long
1947 // rdx: remainder (= rax irem reg) 0
1948 //
1949 // Code sequnce:
1950 //
1951 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx
1952 // 7: 00 00 80
1953 // a: 48 39 d0 cmp %rdx,%rax
1954 // d: 75 08 jne 17 <normal>
1955 // f: 33 d2 xor %edx,%edx
1956 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div
1957 // 15: 74 05 je 1c <done>
1958 // 0000000000000017 <normal>:
1959 // 17: 48 99 cqto
1960 // 19: 48 f7 f9 idiv $div
1961 // 000000000000001c <done>:
1962 MacroAssembler _masm(&cbuf);
1963 Label normal;
1964 Label done;
1965
1966 // mov $0x8000000000000000,%rdx
1967 __ mov64(as_Register(RDX_enc), 0x8000000000000000);
1968
1969 // cmp %rdx,%rax
1970 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc));
1971
1972 // jne 17 <normal>
1973 __ jccb(Assembler::notEqual, normal);
1974
1975 // xor %edx,%edx
1976 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc));
1977
1978 // cmp $0xffffffffffffffff,$div
1979 __ cmpq($div$$Register, -1);
1980
1981 // je 1e <done>
1982 __ jccb(Assembler::equal, done);
1983
1984 // <normal>
1985 // cqto
1986 __ bind(normal);
1987 __ cdqq();
1988
1989 // idivq (note: must be emitted by the user of this rule)
1990 // <done>
1991 __ idivq($div$$Register);
1992 __ bind(done);
1993 %}
1994
1995 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
1996 enc_class OpcSE(immI imm)
1997 %{
1998 // Emit primary opcode and set sign-extend bit
1999 // Check for 8-bit immediate, and set sign extend bit in opcode
2000 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2001 emit_opcode(cbuf, $primary | 0x02);
2002 } else {
2003 // 32-bit immediate
2004 emit_opcode(cbuf, $primary);
2005 }
2006 %}
2007
2008 enc_class OpcSErm(rRegI dst, immI imm)
2009 %{
2010 // OpcSEr/m
2011 int dstenc = $dst$$reg;
2012 if (dstenc >= 8) {
2013 emit_opcode(cbuf, Assembler::REX_B);
2014 dstenc -= 8;
2015 }
2016 // Emit primary opcode and set sign-extend bit
2017 // Check for 8-bit immediate, and set sign extend bit in opcode
2018 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2019 emit_opcode(cbuf, $primary | 0x02);
2020 } else {
2021 // 32-bit immediate
2022 emit_opcode(cbuf, $primary);
2023 }
2024 // Emit r/m byte with secondary opcode, after primary opcode.
2025 emit_rm(cbuf, 0x3, $secondary, dstenc);
2026 %}
2027
2028 enc_class OpcSErm_wide(rRegL dst, immI imm)
2029 %{
2030 // OpcSEr/m
2031 int dstenc = $dst$$reg;
2032 if (dstenc < 8) {
2033 emit_opcode(cbuf, Assembler::REX_W);
2034 } else {
2035 emit_opcode(cbuf, Assembler::REX_WB);
2036 dstenc -= 8;
2037 }
2038 // Emit primary opcode and set sign-extend bit
2039 // Check for 8-bit immediate, and set sign extend bit in opcode
2040 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2041 emit_opcode(cbuf, $primary | 0x02);
2042 } else {
2043 // 32-bit immediate
2044 emit_opcode(cbuf, $primary);
2045 }
2046 // Emit r/m byte with secondary opcode, after primary opcode.
2047 emit_rm(cbuf, 0x3, $secondary, dstenc);
2048 %}
2049
2050 enc_class Con8or32(immI imm)
2051 %{
2052 // Check for 8-bit immediate, and set sign extend bit in opcode
2053 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2054 $$$emit8$imm$$constant;
2055 } else {
2056 // 32-bit immediate
2057 $$$emit32$imm$$constant;
2058 }
2059 %}
2060
2061 enc_class opc2_reg(rRegI dst)
2062 %{
2063 // BSWAP
2064 emit_cc(cbuf, $secondary, $dst$$reg);
2065 %}
2066
2067 enc_class opc3_reg(rRegI dst)
2068 %{
2069 // BSWAP
2070 emit_cc(cbuf, $tertiary, $dst$$reg);
2071 %}
2072
2073 enc_class reg_opc(rRegI div)
2074 %{
2075 // INC, DEC, IDIV, IMOD, JMP indirect, ...
2076 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
2077 %}
2078
2079 enc_class enc_cmov(cmpOp cop)
2080 %{
2081 // CMOV
2082 $$$emit8$primary;
2083 emit_cc(cbuf, $secondary, $cop$$cmpcode);
2084 %}
2085
2086 enc_class enc_PartialSubtypeCheck()
2087 %{
2088 Register Rrdi = as_Register(RDI_enc); // result register
2089 Register Rrax = as_Register(RAX_enc); // super class
2090 Register Rrcx = as_Register(RCX_enc); // killed
2091 Register Rrsi = as_Register(RSI_enc); // sub class
2092 Label miss;
2093 const bool set_cond_codes = true;
2094
2095 MacroAssembler _masm(&cbuf);
2096 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
2097 NULL, &miss,
2098 /*set_cond_codes:*/ true);
2099 if ($primary) {
2100 __ xorptr(Rrdi, Rrdi);
2101 }
2102 __ bind(miss);
2103 %}
2104
2105 enc_class clear_avx %{
2106 debug_only(int off0 = cbuf.insts_size());
2107 if (generate_vzeroupper(Compile::current())) {
2108 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty
2109 // Clear upper bits of YMM registers when current compiled code uses
2110 // wide vectors to avoid AVX <-> SSE transition penalty during call.
2111 MacroAssembler _masm(&cbuf);
2112 __ vzeroupper();
2113 }
2114 debug_only(int off1 = cbuf.insts_size());
2115 assert(off1 - off0 == clear_avx_size(), "correct size prediction");
2116 %}
2117
2118 enc_class Java_To_Runtime(method meth) %{
2119 // No relocation needed
2120 MacroAssembler _masm(&cbuf);
2121 __ mov64(r10, (int64_t) $meth$$method);
2122 __ call(r10);
2123 %}
2124
2125 enc_class Java_To_Interpreter(method meth)
2126 %{
2127 // CALL Java_To_Interpreter
2128 // This is the instruction starting address for relocation info.
2129 cbuf.set_insts_mark();
2130 $$$emit8$primary;
2131 // CALL directly to the runtime
2132 emit_d32_reloc(cbuf,
2133 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2134 runtime_call_Relocation::spec(),
2135 RELOC_DISP32);
2136 %}
2137
2138 enc_class Java_Static_Call(method meth)
2139 %{
2140 // JAVA STATIC CALL
2141 // CALL to fixup routine. Fixup routine uses ScopeDesc info to
2142 // determine who we intended to call.
2143 cbuf.set_insts_mark();
2144 $$$emit8$primary;
2145
2146 if (!_method) {
2147 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2148 runtime_call_Relocation::spec(),
2149 RELOC_DISP32);
2150 } else {
2151 int method_index = resolved_method_index(cbuf);
2152 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
2153 : static_call_Relocation::spec(method_index);
2154 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2155 rspec, RELOC_DISP32);
2156 // Emit stubs for static call.
2157 address mark = cbuf.insts_mark();
2158 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark);
2159 if (stub == NULL) {
2160 ciEnv::current()->record_failure("CodeCache is full");
2161 return;
2162 }
2163 }
2164 %}
2165
2166 enc_class Java_Dynamic_Call(method meth) %{
2167 MacroAssembler _masm(&cbuf);
2168 __ ic_call((address)$meth$$method, resolved_method_index(cbuf));
2169 %}
2170
2171 enc_class Java_Compiled_Call(method meth)
2172 %{
2173 // JAVA COMPILED CALL
2174 int disp = in_bytes(Method:: from_compiled_offset());
2175
2176 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
2177 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
2178
2179 // callq *disp(%rax)
2180 cbuf.set_insts_mark();
2181 $$$emit8$primary;
2182 if (disp < 0x80) {
2183 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
2184 emit_d8(cbuf, disp); // Displacement
2185 } else {
2186 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte
2187 emit_d32(cbuf, disp); // Displacement
2188 }
2189 %}
2190
2191 enc_class reg_opc_imm(rRegI dst, immI8 shift)
2192 %{
2193 // SAL, SAR, SHR
2194 int dstenc = $dst$$reg;
2195 if (dstenc >= 8) {
2196 emit_opcode(cbuf, Assembler::REX_B);
2197 dstenc -= 8;
2198 }
2199 $$$emit8$primary;
2200 emit_rm(cbuf, 0x3, $secondary, dstenc);
2201 $$$emit8$shift$$constant;
2202 %}
2203
2204 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift)
2205 %{
2206 // SAL, SAR, SHR
2207 int dstenc = $dst$$reg;
2208 if (dstenc < 8) {
2209 emit_opcode(cbuf, Assembler::REX_W);
2210 } else {
2211 emit_opcode(cbuf, Assembler::REX_WB);
2212 dstenc -= 8;
2213 }
2214 $$$emit8$primary;
2215 emit_rm(cbuf, 0x3, $secondary, dstenc);
2216 $$$emit8$shift$$constant;
2217 %}
2218
2219 enc_class load_immI(rRegI dst, immI src)
2220 %{
2221 int dstenc = $dst$$reg;
2222 if (dstenc >= 8) {
2223 emit_opcode(cbuf, Assembler::REX_B);
2224 dstenc -= 8;
2225 }
2226 emit_opcode(cbuf, 0xB8 | dstenc);
2227 $$$emit32$src$$constant;
2228 %}
2229
2230 enc_class load_immL(rRegL dst, immL src)
2231 %{
2232 int dstenc = $dst$$reg;
2233 if (dstenc < 8) {
2234 emit_opcode(cbuf, Assembler::REX_W);
2235 } else {
2236 emit_opcode(cbuf, Assembler::REX_WB);
2237 dstenc -= 8;
2238 }
2239 emit_opcode(cbuf, 0xB8 | dstenc);
2240 emit_d64(cbuf, $src$$constant);
2241 %}
2242
2243 enc_class load_immUL32(rRegL dst, immUL32 src)
2244 %{
2245 // same as load_immI, but this time we care about zeroes in the high word
2246 int dstenc = $dst$$reg;
2247 if (dstenc >= 8) {
2248 emit_opcode(cbuf, Assembler::REX_B);
2249 dstenc -= 8;
2250 }
2251 emit_opcode(cbuf, 0xB8 | dstenc);
2252 $$$emit32$src$$constant;
2253 %}
2254
2255 enc_class load_immL32(rRegL dst, immL32 src)
2256 %{
2257 int dstenc = $dst$$reg;
2258 if (dstenc < 8) {
2259 emit_opcode(cbuf, Assembler::REX_W);
2260 } else {
2261 emit_opcode(cbuf, Assembler::REX_WB);
2262 dstenc -= 8;
2263 }
2264 emit_opcode(cbuf, 0xC7);
2265 emit_rm(cbuf, 0x03, 0x00, dstenc);
2266 $$$emit32$src$$constant;
2267 %}
2268
2269 enc_class load_immP31(rRegP dst, immP32 src)
2270 %{
2271 // same as load_immI, but this time we care about zeroes in the high word
2272 int dstenc = $dst$$reg;
2273 if (dstenc >= 8) {
2274 emit_opcode(cbuf, Assembler::REX_B);
2275 dstenc -= 8;
2276 }
2277 emit_opcode(cbuf, 0xB8 | dstenc);
2278 $$$emit32$src$$constant;
2279 %}
2280
2281 enc_class load_immP(rRegP dst, immP src)
2282 %{
2283 int dstenc = $dst$$reg;
2284 if (dstenc < 8) {
2285 emit_opcode(cbuf, Assembler::REX_W);
2286 } else {
2287 emit_opcode(cbuf, Assembler::REX_WB);
2288 dstenc -= 8;
2289 }
2290 emit_opcode(cbuf, 0xB8 | dstenc);
2291 // This next line should be generated from ADLC
2292 if ($src->constant_reloc() != relocInfo::none) {
2293 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64);
2294 } else {
2295 emit_d64(cbuf, $src$$constant);
2296 }
2297 %}
2298
2299 enc_class Con32(immI src)
2300 %{
2301 // Output immediate
2302 $$$emit32$src$$constant;
2303 %}
2304
2305 enc_class Con32F_as_bits(immF src)
2306 %{
2307 // Output Float immediate bits
2308 jfloat jf = $src$$constant;
2309 jint jf_as_bits = jint_cast(jf);
2310 emit_d32(cbuf, jf_as_bits);
2311 %}
2312
2313 enc_class Con16(immI src)
2314 %{
2315 // Output immediate
2316 $$$emit16$src$$constant;
2317 %}
2318
2319 // How is this different from Con32??? XXX
2320 enc_class Con_d32(immI src)
2321 %{
2322 emit_d32(cbuf,$src$$constant);
2323 %}
2324
2325 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
2326 // Output immediate memory reference
2327 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2328 emit_d32(cbuf, 0x00);
2329 %}
2330
2331 enc_class lock_prefix()
2332 %{
2333 emit_opcode(cbuf, 0xF0); // lock
2334 %}
2335
2336 enc_class REX_mem(memory mem)
2337 %{
2338 if ($mem$$base >= 8) {
2339 if ($mem$$index < 8) {
2340 emit_opcode(cbuf, Assembler::REX_B);
2341 } else {
2342 emit_opcode(cbuf, Assembler::REX_XB);
2343 }
2344 } else {
2345 if ($mem$$index >= 8) {
2346 emit_opcode(cbuf, Assembler::REX_X);
2347 }
2348 }
2349 %}
2350
2351 enc_class REX_mem_wide(memory mem)
2352 %{
2353 if ($mem$$base >= 8) {
2354 if ($mem$$index < 8) {
2355 emit_opcode(cbuf, Assembler::REX_WB);
2356 } else {
2357 emit_opcode(cbuf, Assembler::REX_WXB);
2358 }
2359 } else {
2360 if ($mem$$index < 8) {
2361 emit_opcode(cbuf, Assembler::REX_W);
2362 } else {
2363 emit_opcode(cbuf, Assembler::REX_WX);
2364 }
2365 }
2366 %}
2367
2368 // for byte regs
2369 enc_class REX_breg(rRegI reg)
2370 %{
2371 if ($reg$$reg >= 4) {
2372 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2373 }
2374 %}
2375
2376 // for byte regs
2377 enc_class REX_reg_breg(rRegI dst, rRegI src)
2378 %{
2379 if ($dst$$reg < 8) {
2380 if ($src$$reg >= 4) {
2381 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2382 }
2383 } else {
2384 if ($src$$reg < 8) {
2385 emit_opcode(cbuf, Assembler::REX_R);
2386 } else {
2387 emit_opcode(cbuf, Assembler::REX_RB);
2388 }
2389 }
2390 %}
2391
2392 // for byte regs
2393 enc_class REX_breg_mem(rRegI reg, memory mem)
2394 %{
2395 if ($reg$$reg < 8) {
2396 if ($mem$$base < 8) {
2397 if ($mem$$index >= 8) {
2398 emit_opcode(cbuf, Assembler::REX_X);
2399 } else if ($reg$$reg >= 4) {
2400 emit_opcode(cbuf, Assembler::REX);
2401 }
2402 } else {
2403 if ($mem$$index < 8) {
2404 emit_opcode(cbuf, Assembler::REX_B);
2405 } else {
2406 emit_opcode(cbuf, Assembler::REX_XB);
2407 }
2408 }
2409 } else {
2410 if ($mem$$base < 8) {
2411 if ($mem$$index < 8) {
2412 emit_opcode(cbuf, Assembler::REX_R);
2413 } else {
2414 emit_opcode(cbuf, Assembler::REX_RX);
2415 }
2416 } else {
2417 if ($mem$$index < 8) {
2418 emit_opcode(cbuf, Assembler::REX_RB);
2419 } else {
2420 emit_opcode(cbuf, Assembler::REX_RXB);
2421 }
2422 }
2423 }
2424 %}
2425
2426 enc_class REX_reg(rRegI reg)
2427 %{
2428 if ($reg$$reg >= 8) {
2429 emit_opcode(cbuf, Assembler::REX_B);
2430 }
2431 %}
2432
2433 enc_class REX_reg_wide(rRegI reg)
2434 %{
2435 if ($reg$$reg < 8) {
2436 emit_opcode(cbuf, Assembler::REX_W);
2437 } else {
2438 emit_opcode(cbuf, Assembler::REX_WB);
2439 }
2440 %}
2441
2442 enc_class REX_reg_reg(rRegI dst, rRegI src)
2443 %{
2444 if ($dst$$reg < 8) {
2445 if ($src$$reg >= 8) {
2446 emit_opcode(cbuf, Assembler::REX_B);
2447 }
2448 } else {
2449 if ($src$$reg < 8) {
2450 emit_opcode(cbuf, Assembler::REX_R);
2451 } else {
2452 emit_opcode(cbuf, Assembler::REX_RB);
2453 }
2454 }
2455 %}
2456
2457 enc_class REX_reg_reg_wide(rRegI dst, rRegI src)
2458 %{
2459 if ($dst$$reg < 8) {
2460 if ($src$$reg < 8) {
2461 emit_opcode(cbuf, Assembler::REX_W);
2462 } else {
2463 emit_opcode(cbuf, Assembler::REX_WB);
2464 }
2465 } else {
2466 if ($src$$reg < 8) {
2467 emit_opcode(cbuf, Assembler::REX_WR);
2468 } else {
2469 emit_opcode(cbuf, Assembler::REX_WRB);
2470 }
2471 }
2472 %}
2473
2474 enc_class REX_reg_mem(rRegI reg, memory mem)
2475 %{
2476 if ($reg$$reg < 8) {
2477 if ($mem$$base < 8) {
2478 if ($mem$$index >= 8) {
2479 emit_opcode(cbuf, Assembler::REX_X);
2480 }
2481 } else {
2482 if ($mem$$index < 8) {
2483 emit_opcode(cbuf, Assembler::REX_B);
2484 } else {
2485 emit_opcode(cbuf, Assembler::REX_XB);
2486 }
2487 }
2488 } else {
2489 if ($mem$$base < 8) {
2490 if ($mem$$index < 8) {
2491 emit_opcode(cbuf, Assembler::REX_R);
2492 } else {
2493 emit_opcode(cbuf, Assembler::REX_RX);
2494 }
2495 } else {
2496 if ($mem$$index < 8) {
2497 emit_opcode(cbuf, Assembler::REX_RB);
2498 } else {
2499 emit_opcode(cbuf, Assembler::REX_RXB);
2500 }
2501 }
2502 }
2503 %}
2504
2505 enc_class REX_reg_mem_wide(rRegL reg, memory mem)
2506 %{
2507 if ($reg$$reg < 8) {
2508 if ($mem$$base < 8) {
2509 if ($mem$$index < 8) {
2510 emit_opcode(cbuf, Assembler::REX_W);
2511 } else {
2512 emit_opcode(cbuf, Assembler::REX_WX);
2513 }
2514 } else {
2515 if ($mem$$index < 8) {
2516 emit_opcode(cbuf, Assembler::REX_WB);
2517 } else {
2518 emit_opcode(cbuf, Assembler::REX_WXB);
2519 }
2520 }
2521 } else {
2522 if ($mem$$base < 8) {
2523 if ($mem$$index < 8) {
2524 emit_opcode(cbuf, Assembler::REX_WR);
2525 } else {
2526 emit_opcode(cbuf, Assembler::REX_WRX);
2527 }
2528 } else {
2529 if ($mem$$index < 8) {
2530 emit_opcode(cbuf, Assembler::REX_WRB);
2531 } else {
2532 emit_opcode(cbuf, Assembler::REX_WRXB);
2533 }
2534 }
2535 }
2536 %}
2537
2538 enc_class reg_mem(rRegI ereg, memory mem)
2539 %{
2540 // High registers handle in encode_RegMem
2541 int reg = $ereg$$reg;
2542 int base = $mem$$base;
2543 int index = $mem$$index;
2544 int scale = $mem$$scale;
2545 int disp = $mem$$disp;
2546 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2547
2548 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc);
2549 %}
2550
2551 enc_class RM_opc_mem(immI rm_opcode, memory mem)
2552 %{
2553 int rm_byte_opcode = $rm_opcode$$constant;
2554
2555 // High registers handle in encode_RegMem
2556 int base = $mem$$base;
2557 int index = $mem$$index;
2558 int scale = $mem$$scale;
2559 int displace = $mem$$disp;
2560
2561 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when
2562 // working with static
2563 // globals
2564 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace,
2565 disp_reloc);
2566 %}
2567
2568 enc_class reg_lea(rRegI dst, rRegI src0, immI src1)
2569 %{
2570 int reg_encoding = $dst$$reg;
2571 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
2572 int index = 0x04; // 0x04 indicates no index
2573 int scale = 0x00; // 0x00 indicates no scale
2574 int displace = $src1$$constant; // 0x00 indicates no displacement
2575 relocInfo::relocType disp_reloc = relocInfo::none;
2576 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace,
2577 disp_reloc);
2578 %}
2579
2580 enc_class neg_reg(rRegI dst)
2581 %{
2582 int dstenc = $dst$$reg;
2583 if (dstenc >= 8) {
2584 emit_opcode(cbuf, Assembler::REX_B);
2585 dstenc -= 8;
2586 }
2587 // NEG $dst
2588 emit_opcode(cbuf, 0xF7);
2589 emit_rm(cbuf, 0x3, 0x03, dstenc);
2590 %}
2591
2592 enc_class neg_reg_wide(rRegI dst)
2593 %{
2594 int dstenc = $dst$$reg;
2595 if (dstenc < 8) {
2596 emit_opcode(cbuf, Assembler::REX_W);
2597 } else {
2598 emit_opcode(cbuf, Assembler::REX_WB);
2599 dstenc -= 8;
2600 }
2601 // NEG $dst
2602 emit_opcode(cbuf, 0xF7);
2603 emit_rm(cbuf, 0x3, 0x03, dstenc);
2604 %}
2605
2606 enc_class setLT_reg(rRegI dst)
2607 %{
2608 int dstenc = $dst$$reg;
2609 if (dstenc >= 8) {
2610 emit_opcode(cbuf, Assembler::REX_B);
2611 dstenc -= 8;
2612 } else if (dstenc >= 4) {
2613 emit_opcode(cbuf, Assembler::REX);
2614 }
2615 // SETLT $dst
2616 emit_opcode(cbuf, 0x0F);
2617 emit_opcode(cbuf, 0x9C);
2618 emit_rm(cbuf, 0x3, 0x0, dstenc);
2619 %}
2620
2621 enc_class setNZ_reg(rRegI dst)
2622 %{
2623 int dstenc = $dst$$reg;
2624 if (dstenc >= 8) {
2625 emit_opcode(cbuf, Assembler::REX_B);
2626 dstenc -= 8;
2627 } else if (dstenc >= 4) {
2628 emit_opcode(cbuf, Assembler::REX);
2629 }
2630 // SETNZ $dst
2631 emit_opcode(cbuf, 0x0F);
2632 emit_opcode(cbuf, 0x95);
2633 emit_rm(cbuf, 0x3, 0x0, dstenc);
2634 %}
2635
2636
2637 // Compare the lonogs and set -1, 0, or 1 into dst
2638 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst)
2639 %{
2640 int src1enc = $src1$$reg;
2641 int src2enc = $src2$$reg;
2642 int dstenc = $dst$$reg;
2643
2644 // cmpq $src1, $src2
2645 if (src1enc < 8) {
2646 if (src2enc < 8) {
2647 emit_opcode(cbuf, Assembler::REX_W);
2648 } else {
2649 emit_opcode(cbuf, Assembler::REX_WB);
2650 }
2651 } else {
2652 if (src2enc < 8) {
2653 emit_opcode(cbuf, Assembler::REX_WR);
2654 } else {
2655 emit_opcode(cbuf, Assembler::REX_WRB);
2656 }
2657 }
2658 emit_opcode(cbuf, 0x3B);
2659 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7);
2660
2661 // movl $dst, -1
2662 if (dstenc >= 8) {
2663 emit_opcode(cbuf, Assembler::REX_B);
2664 }
2665 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
2666 emit_d32(cbuf, -1);
2667
2668 // jl,s done
2669 emit_opcode(cbuf, 0x7C);
2670 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
2671
2672 // setne $dst
2673 if (dstenc >= 4) {
2674 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
2675 }
2676 emit_opcode(cbuf, 0x0F);
2677 emit_opcode(cbuf, 0x95);
2678 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
2679
2680 // movzbl $dst, $dst
2681 if (dstenc >= 4) {
2682 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
2683 }
2684 emit_opcode(cbuf, 0x0F);
2685 emit_opcode(cbuf, 0xB6);
2686 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
2687 %}
2688
2689 enc_class Push_ResultXD(regD dst) %{
2690 MacroAssembler _masm(&cbuf);
2691 __ fstp_d(Address(rsp, 0));
2692 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
2693 __ addptr(rsp, 8);
2694 %}
2695
2696 enc_class Push_SrcXD(regD src) %{
2697 MacroAssembler _masm(&cbuf);
2698 __ subptr(rsp, 8);
2699 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
2700 __ fld_d(Address(rsp, 0));
2701 %}
2702
2703
2704 enc_class enc_rethrow()
2705 %{
2706 cbuf.set_insts_mark();
2707 emit_opcode(cbuf, 0xE9); // jmp entry
2708 emit_d32_reloc(cbuf,
2709 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
2710 runtime_call_Relocation::spec(),
2711 RELOC_DISP32);
2712 %}
2713
2714 %}
2715
2716
2717
2718 //----------FRAME--------------------------------------------------------------
2719 // Definition of frame structure and management information.
2720 //
2721 // S T A C K L A Y O U T Allocators stack-slot number
2722 // | (to get allocators register number
2723 // G Owned by | | v add OptoReg::stack0())
2724 // r CALLER | |
2725 // o | +--------+ pad to even-align allocators stack-slot
2726 // w V | pad0 | numbers; owned by CALLER
2727 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
2728 // h ^ | in | 5
2729 // | | args | 4 Holes in incoming args owned by SELF
2730 // | | | | 3
2731 // | | +--------+
2732 // V | | old out| Empty on Intel, window on Sparc
2733 // | old |preserve| Must be even aligned.
2734 // | SP-+--------+----> Matcher::_old_SP, even aligned
2735 // | | in | 3 area for Intel ret address
2736 // Owned by |preserve| Empty on Sparc.
2737 // SELF +--------+
2738 // | | pad2 | 2 pad to align old SP
2739 // | +--------+ 1
2740 // | | locks | 0
2741 // | +--------+----> OptoReg::stack0(), even aligned
2742 // | | pad1 | 11 pad to align new SP
2743 // | +--------+
2744 // | | | 10
2745 // | | spills | 9 spills
2746 // V | | 8 (pad0 slot for callee)
2747 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
2748 // ^ | out | 7
2749 // | | args | 6 Holes in outgoing args owned by CALLEE
2750 // Owned by +--------+
2751 // CALLEE | new out| 6 Empty on Intel, window on Sparc
2752 // | new |preserve| Must be even-aligned.
2753 // | SP-+--------+----> Matcher::_new_SP, even aligned
2754 // | | |
2755 //
2756 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
2757 // known from SELF's arguments and the Java calling convention.
2758 // Region 6-7 is determined per call site.
2759 // Note 2: If the calling convention leaves holes in the incoming argument
2760 // area, those holes are owned by SELF. Holes in the outgoing area
2761 // are owned by the CALLEE. Holes should not be nessecary in the
2762 // incoming area, as the Java calling convention is completely under
2763 // the control of the AD file. Doubles can be sorted and packed to
2764 // avoid holes. Holes in the outgoing arguments may be nessecary for
2765 // varargs C calling conventions.
2766 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
2767 // even aligned with pad0 as needed.
2768 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
2769 // region 6-11 is even aligned; it may be padded out more so that
2770 // the region from SP to FP meets the minimum stack alignment.
2771 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
2772 // alignment. Region 11, pad1, may be dynamically extended so that
2773 // SP meets the minimum alignment.
2774
2775 frame
2776 %{
2777 // These three registers define part of the calling convention
2778 // between compiled code and the interpreter.
2779 inline_cache_reg(RAX); // Inline Cache Register
2780
2781 // Optional: name the operand used by cisc-spilling to access
2782 // [stack_pointer + offset]
2783 cisc_spilling_operand_name(indOffset32);
2784
2785 // Number of stack slots consumed by locking an object
2786 sync_stack_slots(2);
2787
2788 // Compiled code's Frame Pointer
2789 frame_pointer(RSP);
2790
2791 // Interpreter stores its frame pointer in a register which is
2792 // stored to the stack by I2CAdaptors.
2793 // I2CAdaptors convert from interpreted java to compiled java.
2794 interpreter_frame_pointer(RBP);
2795
2796 // Stack alignment requirement
2797 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
2798
2799 // Number of outgoing stack slots killed above the out_preserve_stack_slots
2800 // for calls to C. Supports the var-args backing area for register parms.
2801 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
2802
2803 // The after-PROLOG location of the return address. Location of
2804 // return address specifies a type (REG or STACK) and a number
2805 // representing the register number (i.e. - use a register name) or
2806 // stack slot.
2807 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
2808 // Otherwise, it is above the locks and verification slot and alignment word
2809 return_addr(STACK - 2 +
2810 align_up((Compile::current()->in_preserve_stack_slots() +
2811 Compile::current()->fixed_slots()),
2812 stack_alignment_in_slots()));
2813
2814 // Location of compiled Java return values. Same as C for now.
2815 return_value
2816 %{
2817 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
2818 "only return normal values");
2819
2820 static const int lo[Op_RegL + 1] = {
2821 0,
2822 0,
2823 RAX_num, // Op_RegN
2824 RAX_num, // Op_RegI
2825 RAX_num, // Op_RegP
2826 XMM0_num, // Op_RegF
2827 XMM0_num, // Op_RegD
2828 RAX_num // Op_RegL
2829 };
2830 static const int hi[Op_RegL + 1] = {
2831 0,
2832 0,
2833 OptoReg::Bad, // Op_RegN
2834 OptoReg::Bad, // Op_RegI
2835 RAX_H_num, // Op_RegP
2836 OptoReg::Bad, // Op_RegF
2837 XMM0b_num, // Op_RegD
2838 RAX_H_num // Op_RegL
2839 };
2840 // Excluded flags and vector registers.
2841 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type");
2842 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
2843 %}
2844 %}
2845
2846 //----------ATTRIBUTES---------------------------------------------------------
2847 //----------Operand Attributes-------------------------------------------------
2848 op_attrib op_cost(0); // Required cost attribute
2849
2850 //----------Instruction Attributes---------------------------------------------
2851 ins_attrib ins_cost(100); // Required cost attribute
2852 ins_attrib ins_size(8); // Required size attribute (in bits)
2853 ins_attrib ins_short_branch(0); // Required flag: is this instruction
2854 // a non-matching short branch variant
2855 // of some long branch?
2856 ins_attrib ins_alignment(1); // Required alignment attribute (must
2857 // be a power of 2) specifies the
2858 // alignment that some part of the
2859 // instruction (not necessarily the
2860 // start) requires. If > 1, a
2861 // compute_padding() function must be
2862 // provided for the instruction
2863
2864 //----------OPERANDS-----------------------------------------------------------
2865 // Operand definitions must precede instruction definitions for correct parsing
2866 // in the ADLC because operands constitute user defined types which are used in
2867 // instruction definitions.
2868
2869 //----------Simple Operands----------------------------------------------------
2870 // Immediate Operands
2871 // Integer Immediate
2872 operand immI()
2873 %{
2874 match(ConI);
2875
2876 op_cost(10);
2877 format %{ %}
2878 interface(CONST_INTER);
2879 %}
2880
2881 // Constant for test vs zero
2882 operand immI_0()
2883 %{
2884 predicate(n->get_int() == 0);
2885 match(ConI);
2886
2887 op_cost(0);
2888 format %{ %}
2889 interface(CONST_INTER);
2890 %}
2891
2892 // Constant for increment
2893 operand immI_1()
2894 %{
2895 predicate(n->get_int() == 1);
2896 match(ConI);
2897
2898 op_cost(0);
2899 format %{ %}
2900 interface(CONST_INTER);
2901 %}
2902
2903 // Constant for decrement
2904 operand immI_M1()
2905 %{
2906 predicate(n->get_int() == -1);
2907 match(ConI);
2908
2909 op_cost(0);
2910 format %{ %}
2911 interface(CONST_INTER);
2912 %}
2913
2914 operand immI_2()
2915 %{
2916 predicate(n->get_int() == 2);
2917 match(ConI);
2918
2919 op_cost(0);
2920 format %{ %}
2921 interface(CONST_INTER);
2922 %}
2923
2924 operand immI_4()
2925 %{
2926 predicate(n->get_int() == 4);
2927 match(ConI);
2928
2929 op_cost(0);
2930 format %{ %}
2931 interface(CONST_INTER);
2932 %}
2933
2934 operand immI_8()
2935 %{
2936 predicate(n->get_int() == 8);
2937 match(ConI);
2938
2939 op_cost(0);
2940 format %{ %}
2941 interface(CONST_INTER);
2942 %}
2943
2944 // Valid scale values for addressing modes
2945 operand immI2()
2946 %{
2947 predicate(0 <= n->get_int() && (n->get_int() <= 3));
2948 match(ConI);
2949
2950 format %{ %}
2951 interface(CONST_INTER);
2952 %}
2953
2954 operand immU7()
2955 %{
2956 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F));
2957 match(ConI);
2958
2959 op_cost(5);
2960 format %{ %}
2961 interface(CONST_INTER);
2962 %}
2963
2964 operand immI8()
2965 %{
2966 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80));
2967 match(ConI);
2968
2969 op_cost(5);
2970 format %{ %}
2971 interface(CONST_INTER);
2972 %}
2973
2974 operand immU8()
2975 %{
2976 predicate((0 <= n->get_int()) && (n->get_int() <= 255));
2977 match(ConI);
2978
2979 op_cost(5);
2980 format %{ %}
2981 interface(CONST_INTER);
2982 %}
2983
2984 operand immI16()
2985 %{
2986 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
2987 match(ConI);
2988
2989 op_cost(10);
2990 format %{ %}
2991 interface(CONST_INTER);
2992 %}
2993
2994 // Int Immediate non-negative
2995 operand immU31()
2996 %{
2997 predicate(n->get_int() >= 0);
2998 match(ConI);
2999
3000 op_cost(0);
3001 format %{ %}
3002 interface(CONST_INTER);
3003 %}
3004
3005 // Constant for long shifts
3006 operand immI_32()
3007 %{
3008 predicate( n->get_int() == 32 );
3009 match(ConI);
3010
3011 op_cost(0);
3012 format %{ %}
3013 interface(CONST_INTER);
3014 %}
3015
3016 // Constant for long shifts
3017 operand immI_64()
3018 %{
3019 predicate( n->get_int() == 64 );
3020 match(ConI);
3021
3022 op_cost(0);
3023 format %{ %}
3024 interface(CONST_INTER);
3025 %}
3026
3027 // Pointer Immediate
3028 operand immP()
3029 %{
3030 match(ConP);
3031
3032 op_cost(10);
3033 format %{ %}
3034 interface(CONST_INTER);
3035 %}
3036
3037 // NULL Pointer Immediate
3038 operand immP0()
3039 %{
3040 predicate(n->get_ptr() == 0);
3041 match(ConP);
3042
3043 op_cost(5);
3044 format %{ %}
3045 interface(CONST_INTER);
3046 %}
3047
3048 // Pointer Immediate
3049 operand immN() %{
3050 match(ConN);
3051
3052 op_cost(10);
3053 format %{ %}
3054 interface(CONST_INTER);
3055 %}
3056
3057 operand immNKlass() %{
3058 match(ConNKlass);
3059
3060 op_cost(10);
3061 format %{ %}
3062 interface(CONST_INTER);
3063 %}
3064
3065 // NULL Pointer Immediate
3066 operand immN0() %{
3067 predicate(n->get_narrowcon() == 0);
3068 match(ConN);
3069
3070 op_cost(5);
3071 format %{ %}
3072 interface(CONST_INTER);
3073 %}
3074
3075 operand immP31()
3076 %{
3077 predicate(n->as_Type()->type()->reloc() == relocInfo::none
3078 && (n->get_ptr() >> 31) == 0);
3079 match(ConP);
3080
3081 op_cost(5);
3082 format %{ %}
3083 interface(CONST_INTER);
3084 %}
3085
3086
3087 // Long Immediate
3088 operand immL()
3089 %{
3090 match(ConL);
3091
3092 op_cost(20);
3093 format %{ %}
3094 interface(CONST_INTER);
3095 %}
3096
3097 // Long Immediate 8-bit
3098 operand immL8()
3099 %{
3100 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3101 match(ConL);
3102
3103 op_cost(5);
3104 format %{ %}
3105 interface(CONST_INTER);
3106 %}
3107
3108 // Long Immediate 32-bit unsigned
3109 operand immUL32()
3110 %{
3111 predicate(n->get_long() == (unsigned int) (n->get_long()));
3112 match(ConL);
3113
3114 op_cost(10);
3115 format %{ %}
3116 interface(CONST_INTER);
3117 %}
3118
3119 // Long Immediate 32-bit signed
3120 operand immL32()
3121 %{
3122 predicate(n->get_long() == (int) (n->get_long()));
3123 match(ConL);
3124
3125 op_cost(15);
3126 format %{ %}
3127 interface(CONST_INTER);
3128 %}
3129
3130 operand immL_Pow2()
3131 %{
3132 predicate(is_power_of_2((julong)n->get_long()));
3133 match(ConL);
3134
3135 op_cost(15);
3136 format %{ %}
3137 interface(CONST_INTER);
3138 %}
3139
3140 operand immL_NotPow2()
3141 %{
3142 predicate(is_power_of_2((julong)~n->get_long()));
3143 match(ConL);
3144
3145 op_cost(15);
3146 format %{ %}
3147 interface(CONST_INTER);
3148 %}
3149
3150 // Long Immediate zero
3151 operand immL0()
3152 %{
3153 predicate(n->get_long() == 0L);
3154 match(ConL);
3155
3156 op_cost(10);
3157 format %{ %}
3158 interface(CONST_INTER);
3159 %}
3160
3161 // Constant for increment
3162 operand immL1()
3163 %{
3164 predicate(n->get_long() == 1);
3165 match(ConL);
3166
3167 format %{ %}
3168 interface(CONST_INTER);
3169 %}
3170
3171 // Constant for decrement
3172 operand immL_M1()
3173 %{
3174 predicate(n->get_long() == -1);
3175 match(ConL);
3176
3177 format %{ %}
3178 interface(CONST_INTER);
3179 %}
3180
3181 // Long Immediate: the value 10
3182 operand immL10()
3183 %{
3184 predicate(n->get_long() == 10);
3185 match(ConL);
3186
3187 format %{ %}
3188 interface(CONST_INTER);
3189 %}
3190
3191 // Long immediate from 0 to 127.
3192 // Used for a shorter form of long mul by 10.
3193 operand immL_127()
3194 %{
3195 predicate(0 <= n->get_long() && n->get_long() < 0x80);
3196 match(ConL);
3197
3198 op_cost(10);
3199 format %{ %}
3200 interface(CONST_INTER);
3201 %}
3202
3203 // Long Immediate: low 32-bit mask
3204 operand immL_32bits()
3205 %{
3206 predicate(n->get_long() == 0xFFFFFFFFL);
3207 match(ConL);
3208 op_cost(20);
3209
3210 format %{ %}
3211 interface(CONST_INTER);
3212 %}
3213
3214 // Int Immediate: 2^n-1, postive
3215 operand immI_Pow2M1()
3216 %{
3217 predicate((n->get_int() > 0)
3218 && is_power_of_2(n->get_int() + 1));
3219 match(ConI);
3220
3221 op_cost(20);
3222 format %{ %}
3223 interface(CONST_INTER);
3224 %}
3225
3226 // Float Immediate zero
3227 operand immF0()
3228 %{
3229 predicate(jint_cast(n->getf()) == 0);
3230 match(ConF);
3231
3232 op_cost(5);
3233 format %{ %}
3234 interface(CONST_INTER);
3235 %}
3236
3237 // Float Immediate
3238 operand immF()
3239 %{
3240 match(ConF);
3241
3242 op_cost(15);
3243 format %{ %}
3244 interface(CONST_INTER);
3245 %}
3246
3247 // Double Immediate zero
3248 operand immD0()
3249 %{
3250 predicate(jlong_cast(n->getd()) == 0);
3251 match(ConD);
3252
3253 op_cost(5);
3254 format %{ %}
3255 interface(CONST_INTER);
3256 %}
3257
3258 // Double Immediate
3259 operand immD()
3260 %{
3261 match(ConD);
3262
3263 op_cost(15);
3264 format %{ %}
3265 interface(CONST_INTER);
3266 %}
3267
3268 // Immediates for special shifts (sign extend)
3269
3270 // Constants for increment
3271 operand immI_16()
3272 %{
3273 predicate(n->get_int() == 16);
3274 match(ConI);
3275
3276 format %{ %}
3277 interface(CONST_INTER);
3278 %}
3279
3280 operand immI_24()
3281 %{
3282 predicate(n->get_int() == 24);
3283 match(ConI);
3284
3285 format %{ %}
3286 interface(CONST_INTER);
3287 %}
3288
3289 // Constant for byte-wide masking
3290 operand immI_255()
3291 %{
3292 predicate(n->get_int() == 255);
3293 match(ConI);
3294
3295 format %{ %}
3296 interface(CONST_INTER);
3297 %}
3298
3299 // Constant for short-wide masking
3300 operand immI_65535()
3301 %{
3302 predicate(n->get_int() == 65535);
3303 match(ConI);
3304
3305 format %{ %}
3306 interface(CONST_INTER);
3307 %}
3308
3309 // Constant for byte-wide masking
3310 operand immL_255()
3311 %{
3312 predicate(n->get_long() == 255);
3313 match(ConL);
3314
3315 format %{ %}
3316 interface(CONST_INTER);
3317 %}
3318
3319 // Constant for short-wide masking
3320 operand immL_65535()
3321 %{
3322 predicate(n->get_long() == 65535);
3323 match(ConL);
3324
3325 format %{ %}
3326 interface(CONST_INTER);
3327 %}
3328
3329 operand kReg()
3330 %{
3331 constraint(ALLOC_IN_RC(vectmask_reg));
3332 match(RegVectMask);
3333 format %{%}
3334 interface(REG_INTER);
3335 %}
3336
3337 operand kReg_K1()
3338 %{
3339 constraint(ALLOC_IN_RC(vectmask_reg_K1));
3340 match(RegVectMask);
3341 format %{%}
3342 interface(REG_INTER);
3343 %}
3344
3345 operand kReg_K2()
3346 %{
3347 constraint(ALLOC_IN_RC(vectmask_reg_K2));
3348 match(RegVectMask);
3349 format %{%}
3350 interface(REG_INTER);
3351 %}
3352
3353 // Special Registers
3354 operand kReg_K3()
3355 %{
3356 constraint(ALLOC_IN_RC(vectmask_reg_K3));
3357 match(RegVectMask);
3358 format %{%}
3359 interface(REG_INTER);
3360 %}
3361
3362 operand kReg_K4()
3363 %{
3364 constraint(ALLOC_IN_RC(vectmask_reg_K4));
3365 match(RegVectMask);
3366 format %{%}
3367 interface(REG_INTER);
3368 %}
3369
3370 operand kReg_K5()
3371 %{
3372 constraint(ALLOC_IN_RC(vectmask_reg_K5));
3373 match(RegVectMask);
3374 format %{%}
3375 interface(REG_INTER);
3376 %}
3377
3378 operand kReg_K6()
3379 %{
3380 constraint(ALLOC_IN_RC(vectmask_reg_K6));
3381 match(RegVectMask);
3382 format %{%}
3383 interface(REG_INTER);
3384 %}
3385
3386 // Special Registers
3387 operand kReg_K7()
3388 %{
3389 constraint(ALLOC_IN_RC(vectmask_reg_K7));
3390 match(RegVectMask);
3391 format %{%}
3392 interface(REG_INTER);
3393 %}
3394
3395 // Register Operands
3396 // Integer Register
3397 operand rRegI()
3398 %{
3399 constraint(ALLOC_IN_RC(int_reg));
3400 match(RegI);
3401
3402 match(rax_RegI);
3403 match(rbx_RegI);
3404 match(rcx_RegI);
3405 match(rdx_RegI);
3406 match(rdi_RegI);
3407
3408 format %{ %}
3409 interface(REG_INTER);
3410 %}
3411
3412 // Special Registers
3413 operand rax_RegI()
3414 %{
3415 constraint(ALLOC_IN_RC(int_rax_reg));
3416 match(RegI);
3417 match(rRegI);
3418
3419 format %{ "RAX" %}
3420 interface(REG_INTER);
3421 %}
3422
3423 // Special Registers
3424 operand rbx_RegI()
3425 %{
3426 constraint(ALLOC_IN_RC(int_rbx_reg));
3427 match(RegI);
3428 match(rRegI);
3429
3430 format %{ "RBX" %}
3431 interface(REG_INTER);
3432 %}
3433
3434 operand rcx_RegI()
3435 %{
3436 constraint(ALLOC_IN_RC(int_rcx_reg));
3437 match(RegI);
3438 match(rRegI);
3439
3440 format %{ "RCX" %}
3441 interface(REG_INTER);
3442 %}
3443
3444 operand rdx_RegI()
3445 %{
3446 constraint(ALLOC_IN_RC(int_rdx_reg));
3447 match(RegI);
3448 match(rRegI);
3449
3450 format %{ "RDX" %}
3451 interface(REG_INTER);
3452 %}
3453
3454 operand rdi_RegI()
3455 %{
3456 constraint(ALLOC_IN_RC(int_rdi_reg));
3457 match(RegI);
3458 match(rRegI);
3459
3460 format %{ "RDI" %}
3461 interface(REG_INTER);
3462 %}
3463
3464 operand no_rax_rdx_RegI()
3465 %{
3466 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg));
3467 match(RegI);
3468 match(rbx_RegI);
3469 match(rcx_RegI);
3470 match(rdi_RegI);
3471
3472 format %{ %}
3473 interface(REG_INTER);
3474 %}
3475
3476 // Pointer Register
3477 operand any_RegP()
3478 %{
3479 constraint(ALLOC_IN_RC(any_reg));
3480 match(RegP);
3481 match(rax_RegP);
3482 match(rbx_RegP);
3483 match(rdi_RegP);
3484 match(rsi_RegP);
3485 match(rbp_RegP);
3486 match(r15_RegP);
3487 match(rRegP);
3488
3489 format %{ %}
3490 interface(REG_INTER);
3491 %}
3492
3493 operand rRegP()
3494 %{
3495 constraint(ALLOC_IN_RC(ptr_reg));
3496 match(RegP);
3497 match(rax_RegP);
3498 match(rbx_RegP);
3499 match(rdi_RegP);
3500 match(rsi_RegP);
3501 match(rbp_RegP); // See Q&A below about
3502 match(r15_RegP); // r15_RegP and rbp_RegP.
3503
3504 format %{ %}
3505 interface(REG_INTER);
3506 %}
3507
3508 operand rRegN() %{
3509 constraint(ALLOC_IN_RC(int_reg));
3510 match(RegN);
3511
3512 format %{ %}
3513 interface(REG_INTER);
3514 %}
3515
3516 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
3517 // Answer: Operand match rules govern the DFA as it processes instruction inputs.
3518 // It's fine for an instruction input that expects rRegP to match a r15_RegP.
3519 // The output of an instruction is controlled by the allocator, which respects
3520 // register class masks, not match rules. Unless an instruction mentions
3521 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered
3522 // by the allocator as an input.
3523 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true,
3524 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a
3525 // result, RBP is not included in the output of the instruction either.
3526
3527 operand no_rax_RegP()
3528 %{
3529 constraint(ALLOC_IN_RC(ptr_no_rax_reg));
3530 match(RegP);
3531 match(rbx_RegP);
3532 match(rsi_RegP);
3533 match(rdi_RegP);
3534
3535 format %{ %}
3536 interface(REG_INTER);
3537 %}
3538
3539 // This operand is not allowed to use RBP even if
3540 // RBP is not used to hold the frame pointer.
3541 operand no_rbp_RegP()
3542 %{
3543 constraint(ALLOC_IN_RC(ptr_reg_no_rbp));
3544 match(RegP);
3545 match(rbx_RegP);
3546 match(rsi_RegP);
3547 match(rdi_RegP);
3548
3549 format %{ %}
3550 interface(REG_INTER);
3551 %}
3552
3553 operand no_rax_rbx_RegP()
3554 %{
3555 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg));
3556 match(RegP);
3557 match(rsi_RegP);
3558 match(rdi_RegP);
3559
3560 format %{ %}
3561 interface(REG_INTER);
3562 %}
3563
3564 // Special Registers
3565 // Return a pointer value
3566 operand rax_RegP()
3567 %{
3568 constraint(ALLOC_IN_RC(ptr_rax_reg));
3569 match(RegP);
3570 match(rRegP);
3571
3572 format %{ %}
3573 interface(REG_INTER);
3574 %}
3575
3576 // Special Registers
3577 // Return a compressed pointer value
3578 operand rax_RegN()
3579 %{
3580 constraint(ALLOC_IN_RC(int_rax_reg));
3581 match(RegN);
3582 match(rRegN);
3583
3584 format %{ %}
3585 interface(REG_INTER);
3586 %}
3587
3588 // Used in AtomicAdd
3589 operand rbx_RegP()
3590 %{
3591 constraint(ALLOC_IN_RC(ptr_rbx_reg));
3592 match(RegP);
3593 match(rRegP);
3594
3595 format %{ %}
3596 interface(REG_INTER);
3597 %}
3598
3599 operand rsi_RegP()
3600 %{
3601 constraint(ALLOC_IN_RC(ptr_rsi_reg));
3602 match(RegP);
3603 match(rRegP);
3604
3605 format %{ %}
3606 interface(REG_INTER);
3607 %}
3608
3609 operand rbp_RegP()
3610 %{
3611 constraint(ALLOC_IN_RC(ptr_rbp_reg));
3612 match(RegP);
3613 match(rRegP);
3614
3615 format %{ %}
3616 interface(REG_INTER);
3617 %}
3618
3619 // Used in rep stosq
3620 operand rdi_RegP()
3621 %{
3622 constraint(ALLOC_IN_RC(ptr_rdi_reg));
3623 match(RegP);
3624 match(rRegP);
3625
3626 format %{ %}
3627 interface(REG_INTER);
3628 %}
3629
3630 operand r15_RegP()
3631 %{
3632 constraint(ALLOC_IN_RC(ptr_r15_reg));
3633 match(RegP);
3634 match(rRegP);
3635
3636 format %{ %}
3637 interface(REG_INTER);
3638 %}
3639
3640 operand rRegL()
3641 %{
3642 constraint(ALLOC_IN_RC(long_reg));
3643 match(RegL);
3644 match(rax_RegL);
3645 match(rdx_RegL);
3646
3647 format %{ %}
3648 interface(REG_INTER);
3649 %}
3650
3651 // Special Registers
3652 operand no_rax_rdx_RegL()
3653 %{
3654 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3655 match(RegL);
3656 match(rRegL);
3657
3658 format %{ %}
3659 interface(REG_INTER);
3660 %}
3661
3662 operand no_rax_RegL()
3663 %{
3664 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3665 match(RegL);
3666 match(rRegL);
3667 match(rdx_RegL);
3668
3669 format %{ %}
3670 interface(REG_INTER);
3671 %}
3672
3673 operand rax_RegL()
3674 %{
3675 constraint(ALLOC_IN_RC(long_rax_reg));
3676 match(RegL);
3677 match(rRegL);
3678
3679 format %{ "RAX" %}
3680 interface(REG_INTER);
3681 %}
3682
3683 operand rcx_RegL()
3684 %{
3685 constraint(ALLOC_IN_RC(long_rcx_reg));
3686 match(RegL);
3687 match(rRegL);
3688
3689 format %{ %}
3690 interface(REG_INTER);
3691 %}
3692
3693 operand rdx_RegL()
3694 %{
3695 constraint(ALLOC_IN_RC(long_rdx_reg));
3696 match(RegL);
3697 match(rRegL);
3698
3699 format %{ %}
3700 interface(REG_INTER);
3701 %}
3702
3703 // Flags register, used as output of compare instructions
3704 operand rFlagsReg()
3705 %{
3706 constraint(ALLOC_IN_RC(int_flags));
3707 match(RegFlags);
3708
3709 format %{ "RFLAGS" %}
3710 interface(REG_INTER);
3711 %}
3712
3713 // Flags register, used as output of FLOATING POINT compare instructions
3714 operand rFlagsRegU()
3715 %{
3716 constraint(ALLOC_IN_RC(int_flags));
3717 match(RegFlags);
3718
3719 format %{ "RFLAGS_U" %}
3720 interface(REG_INTER);
3721 %}
3722
3723 operand rFlagsRegUCF() %{
3724 constraint(ALLOC_IN_RC(int_flags));
3725 match(RegFlags);
3726 predicate(false);
3727
3728 format %{ "RFLAGS_U_CF" %}
3729 interface(REG_INTER);
3730 %}
3731
3732 // Float register operands
3733 operand regF() %{
3734 constraint(ALLOC_IN_RC(float_reg));
3735 match(RegF);
3736
3737 format %{ %}
3738 interface(REG_INTER);
3739 %}
3740
3741 // Float register operands
3742 operand legRegF() %{
3743 constraint(ALLOC_IN_RC(float_reg_legacy));
3744 match(RegF);
3745
3746 format %{ %}
3747 interface(REG_INTER);
3748 %}
3749
3750 // Float register operands
3751 operand vlRegF() %{
3752 constraint(ALLOC_IN_RC(float_reg_vl));
3753 match(RegF);
3754
3755 format %{ %}
3756 interface(REG_INTER);
3757 %}
3758
3759 // Double register operands
3760 operand regD() %{
3761 constraint(ALLOC_IN_RC(double_reg));
3762 match(RegD);
3763
3764 format %{ %}
3765 interface(REG_INTER);
3766 %}
3767
3768 // Double register operands
3769 operand legRegD() %{
3770 constraint(ALLOC_IN_RC(double_reg_legacy));
3771 match(RegD);
3772
3773 format %{ %}
3774 interface(REG_INTER);
3775 %}
3776
3777 // Double register operands
3778 operand vlRegD() %{
3779 constraint(ALLOC_IN_RC(double_reg_vl));
3780 match(RegD);
3781
3782 format %{ %}
3783 interface(REG_INTER);
3784 %}
3785
3786 //----------Memory Operands----------------------------------------------------
3787 // Direct Memory Operand
3788 // operand direct(immP addr)
3789 // %{
3790 // match(addr);
3791
3792 // format %{ "[$addr]" %}
3793 // interface(MEMORY_INTER) %{
3794 // base(0xFFFFFFFF);
3795 // index(0x4);
3796 // scale(0x0);
3797 // disp($addr);
3798 // %}
3799 // %}
3800
3801 // Indirect Memory Operand
3802 operand indirect(any_RegP reg)
3803 %{
3804 constraint(ALLOC_IN_RC(ptr_reg));
3805 match(reg);
3806
3807 format %{ "[$reg]" %}
3808 interface(MEMORY_INTER) %{
3809 base($reg);
3810 index(0x4);
3811 scale(0x0);
3812 disp(0x0);
3813 %}
3814 %}
3815
3816 // Indirect Memory Plus Short Offset Operand
3817 operand indOffset8(any_RegP reg, immL8 off)
3818 %{
3819 constraint(ALLOC_IN_RC(ptr_reg));
3820 match(AddP reg off);
3821
3822 format %{ "[$reg + $off (8-bit)]" %}
3823 interface(MEMORY_INTER) %{
3824 base($reg);
3825 index(0x4);
3826 scale(0x0);
3827 disp($off);
3828 %}
3829 %}
3830
3831 // Indirect Memory Plus Long Offset Operand
3832 operand indOffset32(any_RegP reg, immL32 off)
3833 %{
3834 constraint(ALLOC_IN_RC(ptr_reg));
3835 match(AddP reg off);
3836
3837 format %{ "[$reg + $off (32-bit)]" %}
3838 interface(MEMORY_INTER) %{
3839 base($reg);
3840 index(0x4);
3841 scale(0x0);
3842 disp($off);
3843 %}
3844 %}
3845
3846 // Indirect Memory Plus Index Register Plus Offset Operand
3847 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off)
3848 %{
3849 constraint(ALLOC_IN_RC(ptr_reg));
3850 match(AddP (AddP reg lreg) off);
3851
3852 op_cost(10);
3853 format %{"[$reg + $off + $lreg]" %}
3854 interface(MEMORY_INTER) %{
3855 base($reg);
3856 index($lreg);
3857 scale(0x0);
3858 disp($off);
3859 %}
3860 %}
3861
3862 // Indirect Memory Plus Index Register Plus Offset Operand
3863 operand indIndex(any_RegP reg, rRegL lreg)
3864 %{
3865 constraint(ALLOC_IN_RC(ptr_reg));
3866 match(AddP reg lreg);
3867
3868 op_cost(10);
3869 format %{"[$reg + $lreg]" %}
3870 interface(MEMORY_INTER) %{
3871 base($reg);
3872 index($lreg);
3873 scale(0x0);
3874 disp(0x0);
3875 %}
3876 %}
3877
3878 // Indirect Memory Times Scale Plus Index Register
3879 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale)
3880 %{
3881 constraint(ALLOC_IN_RC(ptr_reg));
3882 match(AddP reg (LShiftL lreg scale));
3883
3884 op_cost(10);
3885 format %{"[$reg + $lreg << $scale]" %}
3886 interface(MEMORY_INTER) %{
3887 base($reg);
3888 index($lreg);
3889 scale($scale);
3890 disp(0x0);
3891 %}
3892 %}
3893
3894 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale)
3895 %{
3896 constraint(ALLOC_IN_RC(ptr_reg));
3897 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
3898 match(AddP reg (LShiftL (ConvI2L idx) scale));
3899
3900 op_cost(10);
3901 format %{"[$reg + pos $idx << $scale]" %}
3902 interface(MEMORY_INTER) %{
3903 base($reg);
3904 index($idx);
3905 scale($scale);
3906 disp(0x0);
3907 %}
3908 %}
3909
3910 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
3911 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
3912 %{
3913 constraint(ALLOC_IN_RC(ptr_reg));
3914 match(AddP (AddP reg (LShiftL lreg scale)) off);
3915
3916 op_cost(10);
3917 format %{"[$reg + $off + $lreg << $scale]" %}
3918 interface(MEMORY_INTER) %{
3919 base($reg);
3920 index($lreg);
3921 scale($scale);
3922 disp($off);
3923 %}
3924 %}
3925
3926 // Indirect Memory Plus Positive Index Register Plus Offset Operand
3927 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx)
3928 %{
3929 constraint(ALLOC_IN_RC(ptr_reg));
3930 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0);
3931 match(AddP (AddP reg (ConvI2L idx)) off);
3932
3933 op_cost(10);
3934 format %{"[$reg + $off + $idx]" %}
3935 interface(MEMORY_INTER) %{
3936 base($reg);
3937 index($idx);
3938 scale(0x0);
3939 disp($off);
3940 %}
3941 %}
3942
3943 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
3944 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale)
3945 %{
3946 constraint(ALLOC_IN_RC(ptr_reg));
3947 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
3948 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off);
3949
3950 op_cost(10);
3951 format %{"[$reg + $off + $idx << $scale]" %}
3952 interface(MEMORY_INTER) %{
3953 base($reg);
3954 index($idx);
3955 scale($scale);
3956 disp($off);
3957 %}
3958 %}
3959
3960 // Indirect Narrow Oop Plus Offset Operand
3961 // Note: x86 architecture doesn't support "scale * index + offset" without a base
3962 // we can't free r12 even with CompressedOops::base() == NULL.
3963 operand indCompressedOopOffset(rRegN reg, immL32 off) %{
3964 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8));
3965 constraint(ALLOC_IN_RC(ptr_reg));
3966 match(AddP (DecodeN reg) off);
3967
3968 op_cost(10);
3969 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
3970 interface(MEMORY_INTER) %{
3971 base(0xc); // R12
3972 index($reg);
3973 scale(0x3);
3974 disp($off);
3975 %}
3976 %}
3977
3978 // Indirect Memory Operand
3979 operand indirectNarrow(rRegN reg)
3980 %{
3981 predicate(CompressedOops::shift() == 0);
3982 constraint(ALLOC_IN_RC(ptr_reg));
3983 match(DecodeN reg);
3984
3985 format %{ "[$reg]" %}
3986 interface(MEMORY_INTER) %{
3987 base($reg);
3988 index(0x4);
3989 scale(0x0);
3990 disp(0x0);
3991 %}
3992 %}
3993
3994 // Indirect Memory Plus Short Offset Operand
3995 operand indOffset8Narrow(rRegN reg, immL8 off)
3996 %{
3997 predicate(CompressedOops::shift() == 0);
3998 constraint(ALLOC_IN_RC(ptr_reg));
3999 match(AddP (DecodeN reg) off);
4000
4001 format %{ "[$reg + $off (8-bit)]" %}
4002 interface(MEMORY_INTER) %{
4003 base($reg);
4004 index(0x4);
4005 scale(0x0);
4006 disp($off);
4007 %}
4008 %}
4009
4010 // Indirect Memory Plus Long Offset Operand
4011 operand indOffset32Narrow(rRegN reg, immL32 off)
4012 %{
4013 predicate(CompressedOops::shift() == 0);
4014 constraint(ALLOC_IN_RC(ptr_reg));
4015 match(AddP (DecodeN reg) off);
4016
4017 format %{ "[$reg + $off (32-bit)]" %}
4018 interface(MEMORY_INTER) %{
4019 base($reg);
4020 index(0x4);
4021 scale(0x0);
4022 disp($off);
4023 %}
4024 %}
4025
4026 // Indirect Memory Plus Index Register Plus Offset Operand
4027 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off)
4028 %{
4029 predicate(CompressedOops::shift() == 0);
4030 constraint(ALLOC_IN_RC(ptr_reg));
4031 match(AddP (AddP (DecodeN reg) lreg) off);
4032
4033 op_cost(10);
4034 format %{"[$reg + $off + $lreg]" %}
4035 interface(MEMORY_INTER) %{
4036 base($reg);
4037 index($lreg);
4038 scale(0x0);
4039 disp($off);
4040 %}
4041 %}
4042
4043 // Indirect Memory Plus Index Register Plus Offset Operand
4044 operand indIndexNarrow(rRegN reg, rRegL lreg)
4045 %{
4046 predicate(CompressedOops::shift() == 0);
4047 constraint(ALLOC_IN_RC(ptr_reg));
4048 match(AddP (DecodeN reg) lreg);
4049
4050 op_cost(10);
4051 format %{"[$reg + $lreg]" %}
4052 interface(MEMORY_INTER) %{
4053 base($reg);
4054 index($lreg);
4055 scale(0x0);
4056 disp(0x0);
4057 %}
4058 %}
4059
4060 // Indirect Memory Times Scale Plus Index Register
4061 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale)
4062 %{
4063 predicate(CompressedOops::shift() == 0);
4064 constraint(ALLOC_IN_RC(ptr_reg));
4065 match(AddP (DecodeN reg) (LShiftL lreg scale));
4066
4067 op_cost(10);
4068 format %{"[$reg + $lreg << $scale]" %}
4069 interface(MEMORY_INTER) %{
4070 base($reg);
4071 index($lreg);
4072 scale($scale);
4073 disp(0x0);
4074 %}
4075 %}
4076
4077 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
4078 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
4079 %{
4080 predicate(CompressedOops::shift() == 0);
4081 constraint(ALLOC_IN_RC(ptr_reg));
4082 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
4083
4084 op_cost(10);
4085 format %{"[$reg + $off + $lreg << $scale]" %}
4086 interface(MEMORY_INTER) %{
4087 base($reg);
4088 index($lreg);
4089 scale($scale);
4090 disp($off);
4091 %}
4092 %}
4093
4094 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand
4095 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx)
4096 %{
4097 constraint(ALLOC_IN_RC(ptr_reg));
4098 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0);
4099 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off);
4100
4101 op_cost(10);
4102 format %{"[$reg + $off + $idx]" %}
4103 interface(MEMORY_INTER) %{
4104 base($reg);
4105 index($idx);
4106 scale(0x0);
4107 disp($off);
4108 %}
4109 %}
4110
4111 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
4112 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4113 %{
4114 constraint(ALLOC_IN_RC(ptr_reg));
4115 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4116 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
4117
4118 op_cost(10);
4119 format %{"[$reg + $off + $idx << $scale]" %}
4120 interface(MEMORY_INTER) %{
4121 base($reg);
4122 index($idx);
4123 scale($scale);
4124 disp($off);
4125 %}
4126 %}
4127
4128 //----------Special Memory Operands--------------------------------------------
4129 // Stack Slot Operand - This operand is used for loading and storing temporary
4130 // values on the stack where a match requires a value to
4131 // flow through memory.
4132 operand stackSlotP(sRegP reg)
4133 %{
4134 constraint(ALLOC_IN_RC(stack_slots));
4135 // No match rule because this operand is only generated in matching
4136
4137 format %{ "[$reg]" %}
4138 interface(MEMORY_INTER) %{
4139 base(0x4); // RSP
4140 index(0x4); // No Index
4141 scale(0x0); // No Scale
4142 disp($reg); // Stack Offset
4143 %}
4144 %}
4145
4146 operand stackSlotI(sRegI reg)
4147 %{
4148 constraint(ALLOC_IN_RC(stack_slots));
4149 // No match rule because this operand is only generated in matching
4150
4151 format %{ "[$reg]" %}
4152 interface(MEMORY_INTER) %{
4153 base(0x4); // RSP
4154 index(0x4); // No Index
4155 scale(0x0); // No Scale
4156 disp($reg); // Stack Offset
4157 %}
4158 %}
4159
4160 operand stackSlotF(sRegF reg)
4161 %{
4162 constraint(ALLOC_IN_RC(stack_slots));
4163 // No match rule because this operand is only generated in matching
4164
4165 format %{ "[$reg]" %}
4166 interface(MEMORY_INTER) %{
4167 base(0x4); // RSP
4168 index(0x4); // No Index
4169 scale(0x0); // No Scale
4170 disp($reg); // Stack Offset
4171 %}
4172 %}
4173
4174 operand stackSlotD(sRegD reg)
4175 %{
4176 constraint(ALLOC_IN_RC(stack_slots));
4177 // No match rule because this operand is only generated in matching
4178
4179 format %{ "[$reg]" %}
4180 interface(MEMORY_INTER) %{
4181 base(0x4); // RSP
4182 index(0x4); // No Index
4183 scale(0x0); // No Scale
4184 disp($reg); // Stack Offset
4185 %}
4186 %}
4187 operand stackSlotL(sRegL reg)
4188 %{
4189 constraint(ALLOC_IN_RC(stack_slots));
4190 // No match rule because this operand is only generated in matching
4191
4192 format %{ "[$reg]" %}
4193 interface(MEMORY_INTER) %{
4194 base(0x4); // RSP
4195 index(0x4); // No Index
4196 scale(0x0); // No Scale
4197 disp($reg); // Stack Offset
4198 %}
4199 %}
4200
4201 //----------Conditional Branch Operands----------------------------------------
4202 // Comparison Op - This is the operation of the comparison, and is limited to
4203 // the following set of codes:
4204 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
4205 //
4206 // Other attributes of the comparison, such as unsignedness, are specified
4207 // by the comparison instruction that sets a condition code flags register.
4208 // That result is represented by a flags operand whose subtype is appropriate
4209 // to the unsignedness (etc.) of the comparison.
4210 //
4211 // Later, the instruction which matches both the Comparison Op (a Bool) and
4212 // the flags (produced by the Cmp) specifies the coding of the comparison op
4213 // by matching a specific subtype of Bool operand below, such as cmpOpU.
4214
4215 // Comparision Code
4216 operand cmpOp()
4217 %{
4218 match(Bool);
4219
4220 format %{ "" %}
4221 interface(COND_INTER) %{
4222 equal(0x4, "e");
4223 not_equal(0x5, "ne");
4224 less(0xC, "l");
4225 greater_equal(0xD, "ge");
4226 less_equal(0xE, "le");
4227 greater(0xF, "g");
4228 overflow(0x0, "o");
4229 no_overflow(0x1, "no");
4230 %}
4231 %}
4232
4233 // Comparison Code, unsigned compare. Used by FP also, with
4234 // C2 (unordered) turned into GT or LT already. The other bits
4235 // C0 and C3 are turned into Carry & Zero flags.
4236 operand cmpOpU()
4237 %{
4238 match(Bool);
4239
4240 format %{ "" %}
4241 interface(COND_INTER) %{
4242 equal(0x4, "e");
4243 not_equal(0x5, "ne");
4244 less(0x2, "b");
4245 greater_equal(0x3, "nb");
4246 less_equal(0x6, "be");
4247 greater(0x7, "nbe");
4248 overflow(0x0, "o");
4249 no_overflow(0x1, "no");
4250 %}
4251 %}
4252
4253
4254 // Floating comparisons that don't require any fixup for the unordered case
4255 operand cmpOpUCF() %{
4256 match(Bool);
4257 predicate(n->as_Bool()->_test._test == BoolTest::lt ||
4258 n->as_Bool()->_test._test == BoolTest::ge ||
4259 n->as_Bool()->_test._test == BoolTest::le ||
4260 n->as_Bool()->_test._test == BoolTest::gt);
4261 format %{ "" %}
4262 interface(COND_INTER) %{
4263 equal(0x4, "e");
4264 not_equal(0x5, "ne");
4265 less(0x2, "b");
4266 greater_equal(0x3, "nb");
4267 less_equal(0x6, "be");
4268 greater(0x7, "nbe");
4269 overflow(0x0, "o");
4270 no_overflow(0x1, "no");
4271 %}
4272 %}
4273
4274
4275 // Floating comparisons that can be fixed up with extra conditional jumps
4276 operand cmpOpUCF2() %{
4277 match(Bool);
4278 predicate(n->as_Bool()->_test._test == BoolTest::ne ||
4279 n->as_Bool()->_test._test == BoolTest::eq);
4280 format %{ "" %}
4281 interface(COND_INTER) %{
4282 equal(0x4, "e");
4283 not_equal(0x5, "ne");
4284 less(0x2, "b");
4285 greater_equal(0x3, "nb");
4286 less_equal(0x6, "be");
4287 greater(0x7, "nbe");
4288 overflow(0x0, "o");
4289 no_overflow(0x1, "no");
4290 %}
4291 %}
4292
4293 //----------OPERAND CLASSES----------------------------------------------------
4294 // Operand Classes are groups of operands that are used as to simplify
4295 // instruction definitions by not requiring the AD writer to specify separate
4296 // instructions for every form of operand when the instruction accepts
4297 // multiple operand types with the same basic encoding and format. The classic
4298 // case of this is memory operands.
4299
4300 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
4301 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset,
4302 indCompressedOopOffset,
4303 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
4304 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
4305 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow);
4306
4307 //----------PIPELINE-----------------------------------------------------------
4308 // Rules which define the behavior of the target architectures pipeline.
4309 pipeline %{
4310
4311 //----------ATTRIBUTES---------------------------------------------------------
4312 attributes %{
4313 variable_size_instructions; // Fixed size instructions
4314 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
4315 instruction_unit_size = 1; // An instruction is 1 bytes long
4316 instruction_fetch_unit_size = 16; // The processor fetches one line
4317 instruction_fetch_units = 1; // of 16 bytes
4318
4319 // List of nop instructions
4320 nops( MachNop );
4321 %}
4322
4323 //----------RESOURCES----------------------------------------------------------
4324 // Resources are the functional units available to the machine
4325
4326 // Generic P2/P3 pipeline
4327 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of
4328 // 3 instructions decoded per cycle.
4329 // 2 load/store ops per cycle, 1 branch, 1 FPU,
4330 // 3 ALU op, only ALU0 handles mul instructions.
4331 resources( D0, D1, D2, DECODE = D0 | D1 | D2,
4332 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2,
4333 BR, FPU,
4334 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2);
4335
4336 //----------PIPELINE DESCRIPTION-----------------------------------------------
4337 // Pipeline Description specifies the stages in the machine's pipeline
4338
4339 // Generic P2/P3 pipeline
4340 pipe_desc(S0, S1, S2, S3, S4, S5);
4341
4342 //----------PIPELINE CLASSES---------------------------------------------------
4343 // Pipeline Classes describe the stages in which input and output are
4344 // referenced by the hardware pipeline.
4345
4346 // Naming convention: ialu or fpu
4347 // Then: _reg
4348 // Then: _reg if there is a 2nd register
4349 // Then: _long if it's a pair of instructions implementing a long
4350 // Then: _fat if it requires the big decoder
4351 // Or: _mem if it requires the big decoder and a memory unit.
4352
4353 // Integer ALU reg operation
4354 pipe_class ialu_reg(rRegI dst)
4355 %{
4356 single_instruction;
4357 dst : S4(write);
4358 dst : S3(read);
4359 DECODE : S0; // any decoder
4360 ALU : S3; // any alu
4361 %}
4362
4363 // Long ALU reg operation
4364 pipe_class ialu_reg_long(rRegL dst)
4365 %{
4366 instruction_count(2);
4367 dst : S4(write);
4368 dst : S3(read);
4369 DECODE : S0(2); // any 2 decoders
4370 ALU : S3(2); // both alus
4371 %}
4372
4373 // Integer ALU reg operation using big decoder
4374 pipe_class ialu_reg_fat(rRegI dst)
4375 %{
4376 single_instruction;
4377 dst : S4(write);
4378 dst : S3(read);
4379 D0 : S0; // big decoder only
4380 ALU : S3; // any alu
4381 %}
4382
4383 // Integer ALU reg-reg operation
4384 pipe_class ialu_reg_reg(rRegI dst, rRegI src)
4385 %{
4386 single_instruction;
4387 dst : S4(write);
4388 src : S3(read);
4389 DECODE : S0; // any decoder
4390 ALU : S3; // any alu
4391 %}
4392
4393 // Integer ALU reg-reg operation
4394 pipe_class ialu_reg_reg_fat(rRegI dst, memory src)
4395 %{
4396 single_instruction;
4397 dst : S4(write);
4398 src : S3(read);
4399 D0 : S0; // big decoder only
4400 ALU : S3; // any alu
4401 %}
4402
4403 // Integer ALU reg-mem operation
4404 pipe_class ialu_reg_mem(rRegI dst, memory mem)
4405 %{
4406 single_instruction;
4407 dst : S5(write);
4408 mem : S3(read);
4409 D0 : S0; // big decoder only
4410 ALU : S4; // any alu
4411 MEM : S3; // any mem
4412 %}
4413
4414 // Integer mem operation (prefetch)
4415 pipe_class ialu_mem(memory mem)
4416 %{
4417 single_instruction;
4418 mem : S3(read);
4419 D0 : S0; // big decoder only
4420 MEM : S3; // any mem
4421 %}
4422
4423 // Integer Store to Memory
4424 pipe_class ialu_mem_reg(memory mem, rRegI src)
4425 %{
4426 single_instruction;
4427 mem : S3(read);
4428 src : S5(read);
4429 D0 : S0; // big decoder only
4430 ALU : S4; // any alu
4431 MEM : S3;
4432 %}
4433
4434 // // Long Store to Memory
4435 // pipe_class ialu_mem_long_reg(memory mem, rRegL src)
4436 // %{
4437 // instruction_count(2);
4438 // mem : S3(read);
4439 // src : S5(read);
4440 // D0 : S0(2); // big decoder only; twice
4441 // ALU : S4(2); // any 2 alus
4442 // MEM : S3(2); // Both mems
4443 // %}
4444
4445 // Integer Store to Memory
4446 pipe_class ialu_mem_imm(memory mem)
4447 %{
4448 single_instruction;
4449 mem : S3(read);
4450 D0 : S0; // big decoder only
4451 ALU : S4; // any alu
4452 MEM : S3;
4453 %}
4454
4455 // Integer ALU0 reg-reg operation
4456 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src)
4457 %{
4458 single_instruction;
4459 dst : S4(write);
4460 src : S3(read);
4461 D0 : S0; // Big decoder only
4462 ALU0 : S3; // only alu0
4463 %}
4464
4465 // Integer ALU0 reg-mem operation
4466 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem)
4467 %{
4468 single_instruction;
4469 dst : S5(write);
4470 mem : S3(read);
4471 D0 : S0; // big decoder only
4472 ALU0 : S4; // ALU0 only
4473 MEM : S3; // any mem
4474 %}
4475
4476 // Integer ALU reg-reg operation
4477 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2)
4478 %{
4479 single_instruction;
4480 cr : S4(write);
4481 src1 : S3(read);
4482 src2 : S3(read);
4483 DECODE : S0; // any decoder
4484 ALU : S3; // any alu
4485 %}
4486
4487 // Integer ALU reg-imm operation
4488 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1)
4489 %{
4490 single_instruction;
4491 cr : S4(write);
4492 src1 : S3(read);
4493 DECODE : S0; // any decoder
4494 ALU : S3; // any alu
4495 %}
4496
4497 // Integer ALU reg-mem operation
4498 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2)
4499 %{
4500 single_instruction;
4501 cr : S4(write);
4502 src1 : S3(read);
4503 src2 : S3(read);
4504 D0 : S0; // big decoder only
4505 ALU : S4; // any alu
4506 MEM : S3;
4507 %}
4508
4509 // Conditional move reg-reg
4510 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y)
4511 %{
4512 instruction_count(4);
4513 y : S4(read);
4514 q : S3(read);
4515 p : S3(read);
4516 DECODE : S0(4); // any decoder
4517 %}
4518
4519 // Conditional move reg-reg
4520 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr)
4521 %{
4522 single_instruction;
4523 dst : S4(write);
4524 src : S3(read);
4525 cr : S3(read);
4526 DECODE : S0; // any decoder
4527 %}
4528
4529 // Conditional move reg-mem
4530 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src)
4531 %{
4532 single_instruction;
4533 dst : S4(write);
4534 src : S3(read);
4535 cr : S3(read);
4536 DECODE : S0; // any decoder
4537 MEM : S3;
4538 %}
4539
4540 // Conditional move reg-reg long
4541 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src)
4542 %{
4543 single_instruction;
4544 dst : S4(write);
4545 src : S3(read);
4546 cr : S3(read);
4547 DECODE : S0(2); // any 2 decoders
4548 %}
4549
4550 // XXX
4551 // // Conditional move double reg-reg
4552 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src)
4553 // %{
4554 // single_instruction;
4555 // dst : S4(write);
4556 // src : S3(read);
4557 // cr : S3(read);
4558 // DECODE : S0; // any decoder
4559 // %}
4560
4561 // Float reg-reg operation
4562 pipe_class fpu_reg(regD dst)
4563 %{
4564 instruction_count(2);
4565 dst : S3(read);
4566 DECODE : S0(2); // any 2 decoders
4567 FPU : S3;
4568 %}
4569
4570 // Float reg-reg operation
4571 pipe_class fpu_reg_reg(regD dst, regD src)
4572 %{
4573 instruction_count(2);
4574 dst : S4(write);
4575 src : S3(read);
4576 DECODE : S0(2); // any 2 decoders
4577 FPU : S3;
4578 %}
4579
4580 // Float reg-reg operation
4581 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2)
4582 %{
4583 instruction_count(3);
4584 dst : S4(write);
4585 src1 : S3(read);
4586 src2 : S3(read);
4587 DECODE : S0(3); // any 3 decoders
4588 FPU : S3(2);
4589 %}
4590
4591 // Float reg-reg operation
4592 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3)
4593 %{
4594 instruction_count(4);
4595 dst : S4(write);
4596 src1 : S3(read);
4597 src2 : S3(read);
4598 src3 : S3(read);
4599 DECODE : S0(4); // any 3 decoders
4600 FPU : S3(2);
4601 %}
4602
4603 // Float reg-reg operation
4604 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3)
4605 %{
4606 instruction_count(4);
4607 dst : S4(write);
4608 src1 : S3(read);
4609 src2 : S3(read);
4610 src3 : S3(read);
4611 DECODE : S1(3); // any 3 decoders
4612 D0 : S0; // Big decoder only
4613 FPU : S3(2);
4614 MEM : S3;
4615 %}
4616
4617 // Float reg-mem operation
4618 pipe_class fpu_reg_mem(regD dst, memory mem)
4619 %{
4620 instruction_count(2);
4621 dst : S5(write);
4622 mem : S3(read);
4623 D0 : S0; // big decoder only
4624 DECODE : S1; // any decoder for FPU POP
4625 FPU : S4;
4626 MEM : S3; // any mem
4627 %}
4628
4629 // Float reg-mem operation
4630 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem)
4631 %{
4632 instruction_count(3);
4633 dst : S5(write);
4634 src1 : S3(read);
4635 mem : S3(read);
4636 D0 : S0; // big decoder only
4637 DECODE : S1(2); // any decoder for FPU POP
4638 FPU : S4;
4639 MEM : S3; // any mem
4640 %}
4641
4642 // Float mem-reg operation
4643 pipe_class fpu_mem_reg(memory mem, regD src)
4644 %{
4645 instruction_count(2);
4646 src : S5(read);
4647 mem : S3(read);
4648 DECODE : S0; // any decoder for FPU PUSH
4649 D0 : S1; // big decoder only
4650 FPU : S4;
4651 MEM : S3; // any mem
4652 %}
4653
4654 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2)
4655 %{
4656 instruction_count(3);
4657 src1 : S3(read);
4658 src2 : S3(read);
4659 mem : S3(read);
4660 DECODE : S0(2); // any decoder for FPU PUSH
4661 D0 : S1; // big decoder only
4662 FPU : S4;
4663 MEM : S3; // any mem
4664 %}
4665
4666 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2)
4667 %{
4668 instruction_count(3);
4669 src1 : S3(read);
4670 src2 : S3(read);
4671 mem : S4(read);
4672 DECODE : S0; // any decoder for FPU PUSH
4673 D0 : S0(2); // big decoder only
4674 FPU : S4;
4675 MEM : S3(2); // any mem
4676 %}
4677
4678 pipe_class fpu_mem_mem(memory dst, memory src1)
4679 %{
4680 instruction_count(2);
4681 src1 : S3(read);
4682 dst : S4(read);
4683 D0 : S0(2); // big decoder only
4684 MEM : S3(2); // any mem
4685 %}
4686
4687 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2)
4688 %{
4689 instruction_count(3);
4690 src1 : S3(read);
4691 src2 : S3(read);
4692 dst : S4(read);
4693 D0 : S0(3); // big decoder only
4694 FPU : S4;
4695 MEM : S3(3); // any mem
4696 %}
4697
4698 pipe_class fpu_mem_reg_con(memory mem, regD src1)
4699 %{
4700 instruction_count(3);
4701 src1 : S4(read);
4702 mem : S4(read);
4703 DECODE : S0; // any decoder for FPU PUSH
4704 D0 : S0(2); // big decoder only
4705 FPU : S4;
4706 MEM : S3(2); // any mem
4707 %}
4708
4709 // Float load constant
4710 pipe_class fpu_reg_con(regD dst)
4711 %{
4712 instruction_count(2);
4713 dst : S5(write);
4714 D0 : S0; // big decoder only for the load
4715 DECODE : S1; // any decoder for FPU POP
4716 FPU : S4;
4717 MEM : S3; // any mem
4718 %}
4719
4720 // Float load constant
4721 pipe_class fpu_reg_reg_con(regD dst, regD src)
4722 %{
4723 instruction_count(3);
4724 dst : S5(write);
4725 src : S3(read);
4726 D0 : S0; // big decoder only for the load
4727 DECODE : S1(2); // any decoder for FPU POP
4728 FPU : S4;
4729 MEM : S3; // any mem
4730 %}
4731
4732 // UnConditional branch
4733 pipe_class pipe_jmp(label labl)
4734 %{
4735 single_instruction;
4736 BR : S3;
4737 %}
4738
4739 // Conditional branch
4740 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl)
4741 %{
4742 single_instruction;
4743 cr : S1(read);
4744 BR : S3;
4745 %}
4746
4747 // Allocation idiom
4748 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr)
4749 %{
4750 instruction_count(1); force_serialization;
4751 fixed_latency(6);
4752 heap_ptr : S3(read);
4753 DECODE : S0(3);
4754 D0 : S2;
4755 MEM : S3;
4756 ALU : S3(2);
4757 dst : S5(write);
4758 BR : S5;
4759 %}
4760
4761 // Generic big/slow expanded idiom
4762 pipe_class pipe_slow()
4763 %{
4764 instruction_count(10); multiple_bundles; force_serialization;
4765 fixed_latency(100);
4766 D0 : S0(2);
4767 MEM : S3(2);
4768 %}
4769
4770 // The real do-nothing guy
4771 pipe_class empty()
4772 %{
4773 instruction_count(0);
4774 %}
4775
4776 // Define the class for the Nop node
4777 define
4778 %{
4779 MachNop = empty;
4780 %}
4781
4782 %}
4783
4784 //----------INSTRUCTIONS-------------------------------------------------------
4785 //
4786 // match -- States which machine-independent subtree may be replaced
4787 // by this instruction.
4788 // ins_cost -- The estimated cost of this instruction is used by instruction
4789 // selection to identify a minimum cost tree of machine
4790 // instructions that matches a tree of machine-independent
4791 // instructions.
4792 // format -- A string providing the disassembly for this instruction.
4793 // The value of an instruction's operand may be inserted
4794 // by referring to it with a '$' prefix.
4795 // opcode -- Three instruction opcodes may be provided. These are referred
4796 // to within an encode class as $primary, $secondary, and $tertiary
4797 // rrspectively. The primary opcode is commonly used to
4798 // indicate the type of machine instruction, while secondary
4799 // and tertiary are often used for prefix options or addressing
4800 // modes.
4801 // ins_encode -- A list of encode classes with parameters. The encode class
4802 // name must have been defined in an 'enc_class' specification
4803 // in the encode section of the architecture description.
4804
4805 //----------Load/Store/Move Instructions---------------------------------------
4806 //----------Load Instructions--------------------------------------------------
4807
4808 // Load Byte (8 bit signed)
4809 instruct loadB(rRegI dst, memory mem)
4810 %{
4811 match(Set dst (LoadB mem));
4812
4813 ins_cost(125);
4814 format %{ "movsbl $dst, $mem\t# byte" %}
4815
4816 ins_encode %{
4817 __ movsbl($dst$$Register, $mem$$Address);
4818 %}
4819
4820 ins_pipe(ialu_reg_mem);
4821 %}
4822
4823 // Load Byte (8 bit signed) into Long Register
4824 instruct loadB2L(rRegL dst, memory mem)
4825 %{
4826 match(Set dst (ConvI2L (LoadB mem)));
4827
4828 ins_cost(125);
4829 format %{ "movsbq $dst, $mem\t# byte -> long" %}
4830
4831 ins_encode %{
4832 __ movsbq($dst$$Register, $mem$$Address);
4833 %}
4834
4835 ins_pipe(ialu_reg_mem);
4836 %}
4837
4838 // Load Unsigned Byte (8 bit UNsigned)
4839 instruct loadUB(rRegI dst, memory mem)
4840 %{
4841 match(Set dst (LoadUB mem));
4842
4843 ins_cost(125);
4844 format %{ "movzbl $dst, $mem\t# ubyte" %}
4845
4846 ins_encode %{
4847 __ movzbl($dst$$Register, $mem$$Address);
4848 %}
4849
4850 ins_pipe(ialu_reg_mem);
4851 %}
4852
4853 // Load Unsigned Byte (8 bit UNsigned) into Long Register
4854 instruct loadUB2L(rRegL dst, memory mem)
4855 %{
4856 match(Set dst (ConvI2L (LoadUB mem)));
4857
4858 ins_cost(125);
4859 format %{ "movzbq $dst, $mem\t# ubyte -> long" %}
4860
4861 ins_encode %{
4862 __ movzbq($dst$$Register, $mem$$Address);
4863 %}
4864
4865 ins_pipe(ialu_reg_mem);
4866 %}
4867
4868 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register
4869 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
4870 match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
4871 effect(KILL cr);
4872
4873 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t"
4874 "andl $dst, right_n_bits($mask, 8)" %}
4875 ins_encode %{
4876 Register Rdst = $dst$$Register;
4877 __ movzbq(Rdst, $mem$$Address);
4878 __ andl(Rdst, $mask$$constant & right_n_bits(8));
4879 %}
4880 ins_pipe(ialu_reg_mem);
4881 %}
4882
4883 // Load Short (16 bit signed)
4884 instruct loadS(rRegI dst, memory mem)
4885 %{
4886 match(Set dst (LoadS mem));
4887
4888 ins_cost(125);
4889 format %{ "movswl $dst, $mem\t# short" %}
4890
4891 ins_encode %{
4892 __ movswl($dst$$Register, $mem$$Address);
4893 %}
4894
4895 ins_pipe(ialu_reg_mem);
4896 %}
4897
4898 // Load Short (16 bit signed) to Byte (8 bit signed)
4899 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4900 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
4901
4902 ins_cost(125);
4903 format %{ "movsbl $dst, $mem\t# short -> byte" %}
4904 ins_encode %{
4905 __ movsbl($dst$$Register, $mem$$Address);
4906 %}
4907 ins_pipe(ialu_reg_mem);
4908 %}
4909
4910 // Load Short (16 bit signed) into Long Register
4911 instruct loadS2L(rRegL dst, memory mem)
4912 %{
4913 match(Set dst (ConvI2L (LoadS mem)));
4914
4915 ins_cost(125);
4916 format %{ "movswq $dst, $mem\t# short -> long" %}
4917
4918 ins_encode %{
4919 __ movswq($dst$$Register, $mem$$Address);
4920 %}
4921
4922 ins_pipe(ialu_reg_mem);
4923 %}
4924
4925 // Load Unsigned Short/Char (16 bit UNsigned)
4926 instruct loadUS(rRegI dst, memory mem)
4927 %{
4928 match(Set dst (LoadUS mem));
4929
4930 ins_cost(125);
4931 format %{ "movzwl $dst, $mem\t# ushort/char" %}
4932
4933 ins_encode %{
4934 __ movzwl($dst$$Register, $mem$$Address);
4935 %}
4936
4937 ins_pipe(ialu_reg_mem);
4938 %}
4939
4940 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
4941 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4942 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
4943
4944 ins_cost(125);
4945 format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
4946 ins_encode %{
4947 __ movsbl($dst$$Register, $mem$$Address);
4948 %}
4949 ins_pipe(ialu_reg_mem);
4950 %}
4951
4952 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
4953 instruct loadUS2L(rRegL dst, memory mem)
4954 %{
4955 match(Set dst (ConvI2L (LoadUS mem)));
4956
4957 ins_cost(125);
4958 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %}
4959
4960 ins_encode %{
4961 __ movzwq($dst$$Register, $mem$$Address);
4962 %}
4963
4964 ins_pipe(ialu_reg_mem);
4965 %}
4966
4967 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register
4968 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
4969 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4970
4971 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %}
4972 ins_encode %{
4973 __ movzbq($dst$$Register, $mem$$Address);
4974 %}
4975 ins_pipe(ialu_reg_mem);
4976 %}
4977
4978 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register
4979 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
4980 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4981 effect(KILL cr);
4982
4983 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t"
4984 "andl $dst, right_n_bits($mask, 16)" %}
4985 ins_encode %{
4986 Register Rdst = $dst$$Register;
4987 __ movzwq(Rdst, $mem$$Address);
4988 __ andl(Rdst, $mask$$constant & right_n_bits(16));
4989 %}
4990 ins_pipe(ialu_reg_mem);
4991 %}
4992
4993 // Load Integer
4994 instruct loadI(rRegI dst, memory mem)
4995 %{
4996 match(Set dst (LoadI mem));
4997
4998 ins_cost(125);
4999 format %{ "movl $dst, $mem\t# int" %}
5000
5001 ins_encode %{
5002 __ movl($dst$$Register, $mem$$Address);
5003 %}
5004
5005 ins_pipe(ialu_reg_mem);
5006 %}
5007
5008 // Load Integer (32 bit signed) to Byte (8 bit signed)
5009 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
5010 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
5011
5012 ins_cost(125);
5013 format %{ "movsbl $dst, $mem\t# int -> byte" %}
5014 ins_encode %{
5015 __ movsbl($dst$$Register, $mem$$Address);
5016 %}
5017 ins_pipe(ialu_reg_mem);
5018 %}
5019
5020 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
5021 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
5022 match(Set dst (AndI (LoadI mem) mask));
5023
5024 ins_cost(125);
5025 format %{ "movzbl $dst, $mem\t# int -> ubyte" %}
5026 ins_encode %{
5027 __ movzbl($dst$$Register, $mem$$Address);
5028 %}
5029 ins_pipe(ialu_reg_mem);
5030 %}
5031
5032 // Load Integer (32 bit signed) to Short (16 bit signed)
5033 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
5034 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
5035
5036 ins_cost(125);
5037 format %{ "movswl $dst, $mem\t# int -> short" %}
5038 ins_encode %{
5039 __ movswl($dst$$Register, $mem$$Address);
5040 %}
5041 ins_pipe(ialu_reg_mem);
5042 %}
5043
5044 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
5045 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
5046 match(Set dst (AndI (LoadI mem) mask));
5047
5048 ins_cost(125);
5049 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %}
5050 ins_encode %{
5051 __ movzwl($dst$$Register, $mem$$Address);
5052 %}
5053 ins_pipe(ialu_reg_mem);
5054 %}
5055
5056 // Load Integer into Long Register
5057 instruct loadI2L(rRegL dst, memory mem)
5058 %{
5059 match(Set dst (ConvI2L (LoadI mem)));
5060
5061 ins_cost(125);
5062 format %{ "movslq $dst, $mem\t# int -> long" %}
5063
5064 ins_encode %{
5065 __ movslq($dst$$Register, $mem$$Address);
5066 %}
5067
5068 ins_pipe(ialu_reg_mem);
5069 %}
5070
5071 // Load Integer with mask 0xFF into Long Register
5072 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
5073 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5074
5075 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %}
5076 ins_encode %{
5077 __ movzbq($dst$$Register, $mem$$Address);
5078 %}
5079 ins_pipe(ialu_reg_mem);
5080 %}
5081
5082 // Load Integer with mask 0xFFFF into Long Register
5083 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{
5084 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5085
5086 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %}
5087 ins_encode %{
5088 __ movzwq($dst$$Register, $mem$$Address);
5089 %}
5090 ins_pipe(ialu_reg_mem);
5091 %}
5092
5093 // Load Integer with a 31-bit mask into Long Register
5094 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{
5095 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5096 effect(KILL cr);
5097
5098 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t"
5099 "andl $dst, $mask" %}
5100 ins_encode %{
5101 Register Rdst = $dst$$Register;
5102 __ movl(Rdst, $mem$$Address);
5103 __ andl(Rdst, $mask$$constant);
5104 %}
5105 ins_pipe(ialu_reg_mem);
5106 %}
5107
5108 // Load Unsigned Integer into Long Register
5109 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask)
5110 %{
5111 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5112
5113 ins_cost(125);
5114 format %{ "movl $dst, $mem\t# uint -> long" %}
5115
5116 ins_encode %{
5117 __ movl($dst$$Register, $mem$$Address);
5118 %}
5119
5120 ins_pipe(ialu_reg_mem);
5121 %}
5122
5123 // Load Long
5124 instruct loadL(rRegL dst, memory mem)
5125 %{
5126 match(Set dst (LoadL mem));
5127
5128 ins_cost(125);
5129 format %{ "movq $dst, $mem\t# long" %}
5130
5131 ins_encode %{
5132 __ movq($dst$$Register, $mem$$Address);
5133 %}
5134
5135 ins_pipe(ialu_reg_mem); // XXX
5136 %}
5137
5138 // Load Range
5139 instruct loadRange(rRegI dst, memory mem)
5140 %{
5141 match(Set dst (LoadRange mem));
5142
5143 ins_cost(125); // XXX
5144 format %{ "movl $dst, $mem\t# range" %}
5145 ins_encode %{
5146 __ movl($dst$$Register, $mem$$Address);
5147 %}
5148 ins_pipe(ialu_reg_mem);
5149 %}
5150
5151 // Load Pointer
5152 instruct loadP(rRegP dst, memory mem)
5153 %{
5154 match(Set dst (LoadP mem));
5155 predicate(n->as_Load()->barrier_data() == 0);
5156
5157 ins_cost(125); // XXX
5158 format %{ "movq $dst, $mem\t# ptr" %}
5159 ins_encode %{
5160 __ movq($dst$$Register, $mem$$Address);
5161 %}
5162 ins_pipe(ialu_reg_mem); // XXX
5163 %}
5164
5165 // Load Compressed Pointer
5166 instruct loadN(rRegN dst, memory mem)
5167 %{
5168 match(Set dst (LoadN mem));
5169
5170 ins_cost(125); // XXX
5171 format %{ "movl $dst, $mem\t# compressed ptr" %}
5172 ins_encode %{
5173 __ movl($dst$$Register, $mem$$Address);
5174 %}
5175 ins_pipe(ialu_reg_mem); // XXX
5176 %}
5177
5178
5179 // Load Klass Pointer
5180 instruct loadKlass(rRegP dst, memory mem)
5181 %{
5182 match(Set dst (LoadKlass mem));
5183
5184 ins_cost(125); // XXX
5185 format %{ "movq $dst, $mem\t# class" %}
5186 ins_encode %{
5187 __ movq($dst$$Register, $mem$$Address);
5188 %}
5189 ins_pipe(ialu_reg_mem); // XXX
5190 %}
5191
5192 // Load narrow Klass Pointer
5193 instruct loadNKlass(rRegN dst, memory mem)
5194 %{
5195 predicate(!UseCompactObjectHeaders);
5196 match(Set dst (LoadNKlass mem));
5197
5198 ins_cost(125); // XXX
5199 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
5200 ins_encode %{
5201 __ movl($dst$$Register, $mem$$Address);
5202 %}
5203 ins_pipe(ialu_reg_mem); // XXX
5204 %}
5205
5206 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr)
5207 %{
5208 predicate(UseCompactObjectHeaders);
5209 match(Set dst (LoadNKlass mem));
5210 effect(KILL cr);
5211 ins_cost(125); // XXX
5212 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
5213 ins_encode %{
5214 Register index = $mem$$index != 4 ? $mem$$index$$Register : noreg;
5215 Address::ScaleFactor sf = (index != noreg) ? static_cast<Address::ScaleFactor>($mem$$scale) : Address::no_scale;
5216 __ load_nklass_compact_c2($dst$$Register, $mem$$base$$Register, index, sf, $mem$$disp);
5217 %}
5218 ins_pipe(pipe_slow); // XXX
5219 %}
5220
5221 // Load Float
5222 instruct loadF(regF dst, memory mem)
5223 %{
5224 match(Set dst (LoadF mem));
5225
5226 ins_cost(145); // XXX
5227 format %{ "movss $dst, $mem\t# float" %}
5228 ins_encode %{
5229 __ movflt($dst$$XMMRegister, $mem$$Address);
5230 %}
5231 ins_pipe(pipe_slow); // XXX
5232 %}
5233
5234 // Load Float
5235 instruct MoveF2VL(vlRegF dst, regF src) %{
5236 match(Set dst src);
5237 format %{ "movss $dst,$src\t! load float (4 bytes)" %}
5238 ins_encode %{
5239 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
5240 %}
5241 ins_pipe( fpu_reg_reg );
5242 %}
5243
5244 // Load Float
5245 instruct MoveF2LEG(legRegF dst, regF src) %{
5246 match(Set dst src);
5247 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %}
5248 ins_encode %{
5249 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
5250 %}
5251 ins_pipe( fpu_reg_reg );
5252 %}
5253
5254 // Load Float
5255 instruct MoveVL2F(regF dst, vlRegF src) %{
5256 match(Set dst src);
5257 format %{ "movss $dst,$src\t! load float (4 bytes)" %}
5258 ins_encode %{
5259 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
5260 %}
5261 ins_pipe( fpu_reg_reg );
5262 %}
5263
5264 // Load Float
5265 instruct MoveLEG2F(regF dst, legRegF src) %{
5266 match(Set dst src);
5267 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %}
5268 ins_encode %{
5269 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
5270 %}
5271 ins_pipe( fpu_reg_reg );
5272 %}
5273
5274 // Load Double
5275 instruct loadD_partial(regD dst, memory mem)
5276 %{
5277 predicate(!UseXmmLoadAndClearUpper);
5278 match(Set dst (LoadD mem));
5279
5280 ins_cost(145); // XXX
5281 format %{ "movlpd $dst, $mem\t# double" %}
5282 ins_encode %{
5283 __ movdbl($dst$$XMMRegister, $mem$$Address);
5284 %}
5285 ins_pipe(pipe_slow); // XXX
5286 %}
5287
5288 instruct loadD(regD dst, memory mem)
5289 %{
5290 predicate(UseXmmLoadAndClearUpper);
5291 match(Set dst (LoadD mem));
5292
5293 ins_cost(145); // XXX
5294 format %{ "movsd $dst, $mem\t# double" %}
5295 ins_encode %{
5296 __ movdbl($dst$$XMMRegister, $mem$$Address);
5297 %}
5298 ins_pipe(pipe_slow); // XXX
5299 %}
5300
5301 // Load Double
5302 instruct MoveD2VL(vlRegD dst, regD src) %{
5303 match(Set dst src);
5304 format %{ "movsd $dst,$src\t! load double (8 bytes)" %}
5305 ins_encode %{
5306 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
5307 %}
5308 ins_pipe( fpu_reg_reg );
5309 %}
5310
5311 // Load Double
5312 instruct MoveD2LEG(legRegD dst, regD src) %{
5313 match(Set dst src);
5314 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %}
5315 ins_encode %{
5316 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
5317 %}
5318 ins_pipe( fpu_reg_reg );
5319 %}
5320
5321 // Load Double
5322 instruct MoveVL2D(regD dst, vlRegD src) %{
5323 match(Set dst src);
5324 format %{ "movsd $dst,$src\t! load double (8 bytes)" %}
5325 ins_encode %{
5326 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
5327 %}
5328 ins_pipe( fpu_reg_reg );
5329 %}
5330
5331 // Load Double
5332 instruct MoveLEG2D(regD dst, legRegD src) %{
5333 match(Set dst src);
5334 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %}
5335 ins_encode %{
5336 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
5337 %}
5338 ins_pipe( fpu_reg_reg );
5339 %}
5340
5341 // Following pseudo code describes the algorithm for max[FD]:
5342 // Min algorithm is on similar lines
5343 // btmp = (b < +0.0) ? a : b
5344 // atmp = (b < +0.0) ? b : a
5345 // Tmp = Max_Float(atmp , btmp)
5346 // Res = (atmp == NaN) ? atmp : Tmp
5347
5348 // max = java.lang.Math.max(float a, float b)
5349 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{
5350 predicate(UseAVX > 0 && !n->is_reduction());
5351 match(Set dst (MaxF a b));
5352 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
5353 format %{
5354 "vblendvps $btmp,$b,$a,$b \n\t"
5355 "vblendvps $atmp,$a,$b,$b \n\t"
5356 "vmaxss $tmp,$atmp,$btmp \n\t"
5357 "vcmpps.unordered $btmp,$atmp,$atmp \n\t"
5358 "vblendvps $dst,$tmp,$atmp,$btmp \n\t"
5359 %}
5360 ins_encode %{
5361 int vector_len = Assembler::AVX_128bit;
5362 __ vblendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len);
5363 __ vblendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len);
5364 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister);
5365 __ vcmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len);
5366 __ vblendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len);
5367 %}
5368 ins_pipe( pipe_slow );
5369 %}
5370
5371 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{
5372 predicate(UseAVX > 0 && n->is_reduction());
5373 match(Set dst (MaxF a b));
5374 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
5375
5376 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %}
5377 ins_encode %{
5378 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register,
5379 false /*min*/, true /*single*/);
5380 %}
5381 ins_pipe( pipe_slow );
5382 %}
5383
5384 // max = java.lang.Math.max(double a, double b)
5385 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{
5386 predicate(UseAVX > 0 && !n->is_reduction());
5387 match(Set dst (MaxD a b));
5388 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp);
5389 format %{
5390 "vblendvpd $btmp,$b,$a,$b \n\t"
5391 "vblendvpd $atmp,$a,$b,$b \n\t"
5392 "vmaxsd $tmp,$atmp,$btmp \n\t"
5393 "vcmppd.unordered $btmp,$atmp,$atmp \n\t"
5394 "vblendvpd $dst,$tmp,$atmp,$btmp \n\t"
5395 %}
5396 ins_encode %{
5397 int vector_len = Assembler::AVX_128bit;
5398 __ vblendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len);
5399 __ vblendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len);
5400 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister);
5401 __ vcmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len);
5402 __ vblendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len);
5403 %}
5404 ins_pipe( pipe_slow );
5405 %}
5406
5407 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{
5408 predicate(UseAVX > 0 && n->is_reduction());
5409 match(Set dst (MaxD a b));
5410 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
5411
5412 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %}
5413 ins_encode %{
5414 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register,
5415 false /*min*/, false /*single*/);
5416 %}
5417 ins_pipe( pipe_slow );
5418 %}
5419
5420 // min = java.lang.Math.min(float a, float b)
5421 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{
5422 predicate(UseAVX > 0 && !n->is_reduction());
5423 match(Set dst (MinF a b));
5424 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
5425 format %{
5426 "vblendvps $atmp,$a,$b,$a \n\t"
5427 "vblendvps $btmp,$b,$a,$a \n\t"
5428 "vminss $tmp,$atmp,$btmp \n\t"
5429 "vcmpps.unordered $btmp,$atmp,$atmp \n\t"
5430 "vblendvps $dst,$tmp,$atmp,$btmp \n\t"
5431 %}
5432 ins_encode %{
5433 int vector_len = Assembler::AVX_128bit;
5434 __ vblendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len);
5435 __ vblendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len);
5436 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister);
5437 __ vcmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len);
5438 __ vblendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len);
5439 %}
5440 ins_pipe( pipe_slow );
5441 %}
5442
5443 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{
5444 predicate(UseAVX > 0 && n->is_reduction());
5445 match(Set dst (MinF a b));
5446 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
5447
5448 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %}
5449 ins_encode %{
5450 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register,
5451 true /*min*/, true /*single*/);
5452 %}
5453 ins_pipe( pipe_slow );
5454 %}
5455
5456 // min = java.lang.Math.min(double a, double b)
5457 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{
5458 predicate(UseAVX > 0 && !n->is_reduction());
5459 match(Set dst (MinD a b));
5460 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
5461 format %{
5462 "vblendvpd $atmp,$a,$b,$a \n\t"
5463 "vblendvpd $btmp,$b,$a,$a \n\t"
5464 "vminsd $tmp,$atmp,$btmp \n\t"
5465 "vcmppd.unordered $btmp,$atmp,$atmp \n\t"
5466 "vblendvpd $dst,$tmp,$atmp,$btmp \n\t"
5467 %}
5468 ins_encode %{
5469 int vector_len = Assembler::AVX_128bit;
5470 __ vblendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len);
5471 __ vblendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len);
5472 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister);
5473 __ vcmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len);
5474 __ vblendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len);
5475 %}
5476 ins_pipe( pipe_slow );
5477 %}
5478
5479 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{
5480 predicate(UseAVX > 0 && n->is_reduction());
5481 match(Set dst (MinD a b));
5482 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr);
5483
5484 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %}
5485 ins_encode %{
5486 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register,
5487 true /*min*/, false /*single*/);
5488 %}
5489 ins_pipe( pipe_slow );
5490 %}
5491
5492 // Load Effective Address
5493 instruct leaP8(rRegP dst, indOffset8 mem)
5494 %{
5495 match(Set dst mem);
5496
5497 ins_cost(110); // XXX
5498 format %{ "leaq $dst, $mem\t# ptr 8" %}
5499 ins_encode %{
5500 __ leaq($dst$$Register, $mem$$Address);
5501 %}
5502 ins_pipe(ialu_reg_reg_fat);
5503 %}
5504
5505 instruct leaP32(rRegP dst, indOffset32 mem)
5506 %{
5507 match(Set dst mem);
5508
5509 ins_cost(110);
5510 format %{ "leaq $dst, $mem\t# ptr 32" %}
5511 ins_encode %{
5512 __ leaq($dst$$Register, $mem$$Address);
5513 %}
5514 ins_pipe(ialu_reg_reg_fat);
5515 %}
5516
5517 instruct leaPIdxOff(rRegP dst, indIndexOffset mem)
5518 %{
5519 match(Set dst mem);
5520
5521 ins_cost(110);
5522 format %{ "leaq $dst, $mem\t# ptr idxoff" %}
5523 ins_encode %{
5524 __ leaq($dst$$Register, $mem$$Address);
5525 %}
5526 ins_pipe(ialu_reg_reg_fat);
5527 %}
5528
5529 instruct leaPIdxScale(rRegP dst, indIndexScale mem)
5530 %{
5531 match(Set dst mem);
5532
5533 ins_cost(110);
5534 format %{ "leaq $dst, $mem\t# ptr idxscale" %}
5535 ins_encode %{
5536 __ leaq($dst$$Register, $mem$$Address);
5537 %}
5538 ins_pipe(ialu_reg_reg_fat);
5539 %}
5540
5541 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem)
5542 %{
5543 match(Set dst mem);
5544
5545 ins_cost(110);
5546 format %{ "leaq $dst, $mem\t# ptr idxscale" %}
5547 ins_encode %{
5548 __ leaq($dst$$Register, $mem$$Address);
5549 %}
5550 ins_pipe(ialu_reg_reg_fat);
5551 %}
5552
5553 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem)
5554 %{
5555 match(Set dst mem);
5556
5557 ins_cost(110);
5558 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %}
5559 ins_encode %{
5560 __ leaq($dst$$Register, $mem$$Address);
5561 %}
5562 ins_pipe(ialu_reg_reg_fat);
5563 %}
5564
5565 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem)
5566 %{
5567 match(Set dst mem);
5568
5569 ins_cost(110);
5570 format %{ "leaq $dst, $mem\t# ptr posidxoff" %}
5571 ins_encode %{
5572 __ leaq($dst$$Register, $mem$$Address);
5573 %}
5574 ins_pipe(ialu_reg_reg_fat);
5575 %}
5576
5577 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem)
5578 %{
5579 match(Set dst mem);
5580
5581 ins_cost(110);
5582 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %}
5583 ins_encode %{
5584 __ leaq($dst$$Register, $mem$$Address);
5585 %}
5586 ins_pipe(ialu_reg_reg_fat);
5587 %}
5588
5589 // Load Effective Address which uses Narrow (32-bits) oop
5590 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem)
5591 %{
5592 predicate(UseCompressedOops && (CompressedOops::shift() != 0));
5593 match(Set dst mem);
5594
5595 ins_cost(110);
5596 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %}
5597 ins_encode %{
5598 __ leaq($dst$$Register, $mem$$Address);
5599 %}
5600 ins_pipe(ialu_reg_reg_fat);
5601 %}
5602
5603 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem)
5604 %{
5605 predicate(CompressedOops::shift() == 0);
5606 match(Set dst mem);
5607
5608 ins_cost(110); // XXX
5609 format %{ "leaq $dst, $mem\t# ptr off8narrow" %}
5610 ins_encode %{
5611 __ leaq($dst$$Register, $mem$$Address);
5612 %}
5613 ins_pipe(ialu_reg_reg_fat);
5614 %}
5615
5616 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem)
5617 %{
5618 predicate(CompressedOops::shift() == 0);
5619 match(Set dst mem);
5620
5621 ins_cost(110);
5622 format %{ "leaq $dst, $mem\t# ptr off32narrow" %}
5623 ins_encode %{
5624 __ leaq($dst$$Register, $mem$$Address);
5625 %}
5626 ins_pipe(ialu_reg_reg_fat);
5627 %}
5628
5629 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem)
5630 %{
5631 predicate(CompressedOops::shift() == 0);
5632 match(Set dst mem);
5633
5634 ins_cost(110);
5635 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %}
5636 ins_encode %{
5637 __ leaq($dst$$Register, $mem$$Address);
5638 %}
5639 ins_pipe(ialu_reg_reg_fat);
5640 %}
5641
5642 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem)
5643 %{
5644 predicate(CompressedOops::shift() == 0);
5645 match(Set dst mem);
5646
5647 ins_cost(110);
5648 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %}
5649 ins_encode %{
5650 __ leaq($dst$$Register, $mem$$Address);
5651 %}
5652 ins_pipe(ialu_reg_reg_fat);
5653 %}
5654
5655 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem)
5656 %{
5657 predicate(CompressedOops::shift() == 0);
5658 match(Set dst mem);
5659
5660 ins_cost(110);
5661 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %}
5662 ins_encode %{
5663 __ leaq($dst$$Register, $mem$$Address);
5664 %}
5665 ins_pipe(ialu_reg_reg_fat);
5666 %}
5667
5668 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem)
5669 %{
5670 predicate(CompressedOops::shift() == 0);
5671 match(Set dst mem);
5672
5673 ins_cost(110);
5674 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %}
5675 ins_encode %{
5676 __ leaq($dst$$Register, $mem$$Address);
5677 %}
5678 ins_pipe(ialu_reg_reg_fat);
5679 %}
5680
5681 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem)
5682 %{
5683 predicate(CompressedOops::shift() == 0);
5684 match(Set dst mem);
5685
5686 ins_cost(110);
5687 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %}
5688 ins_encode %{
5689 __ leaq($dst$$Register, $mem$$Address);
5690 %}
5691 ins_pipe(ialu_reg_reg_fat);
5692 %}
5693
5694 instruct loadConI(rRegI dst, immI src)
5695 %{
5696 match(Set dst src);
5697
5698 format %{ "movl $dst, $src\t# int" %}
5699 ins_encode %{
5700 __ movl($dst$$Register, $src$$constant);
5701 %}
5702 ins_pipe(ialu_reg_fat); // XXX
5703 %}
5704
5705 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr)
5706 %{
5707 match(Set dst src);
5708 effect(KILL cr);
5709
5710 ins_cost(50);
5711 format %{ "xorl $dst, $dst\t# int" %}
5712 ins_encode %{
5713 __ xorl($dst$$Register, $dst$$Register);
5714 %}
5715 ins_pipe(ialu_reg);
5716 %}
5717
5718 instruct loadConL(rRegL dst, immL src)
5719 %{
5720 match(Set dst src);
5721
5722 ins_cost(150);
5723 format %{ "movq $dst, $src\t# long" %}
5724 ins_encode %{
5725 __ mov64($dst$$Register, $src$$constant);
5726 %}
5727 ins_pipe(ialu_reg);
5728 %}
5729
5730 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr)
5731 %{
5732 match(Set dst src);
5733 effect(KILL cr);
5734
5735 ins_cost(50);
5736 format %{ "xorl $dst, $dst\t# long" %}
5737 ins_encode %{
5738 __ xorl($dst$$Register, $dst$$Register);
5739 %}
5740 ins_pipe(ialu_reg); // XXX
5741 %}
5742
5743 instruct loadConUL32(rRegL dst, immUL32 src)
5744 %{
5745 match(Set dst src);
5746
5747 ins_cost(60);
5748 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %}
5749 ins_encode %{
5750 __ movl($dst$$Register, $src$$constant);
5751 %}
5752 ins_pipe(ialu_reg);
5753 %}
5754
5755 instruct loadConL32(rRegL dst, immL32 src)
5756 %{
5757 match(Set dst src);
5758
5759 ins_cost(70);
5760 format %{ "movq $dst, $src\t# long (32-bit)" %}
5761 ins_encode %{
5762 __ movq($dst$$Register, $src$$constant);
5763 %}
5764 ins_pipe(ialu_reg);
5765 %}
5766
5767 instruct loadConP(rRegP dst, immP con) %{
5768 match(Set dst con);
5769
5770 format %{ "movq $dst, $con\t# ptr" %}
5771 ins_encode %{
5772 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64);
5773 %}
5774 ins_pipe(ialu_reg_fat); // XXX
5775 %}
5776
5777 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
5778 %{
5779 match(Set dst src);
5780 effect(KILL cr);
5781
5782 ins_cost(50);
5783 format %{ "xorl $dst, $dst\t# ptr" %}
5784 ins_encode %{
5785 __ xorl($dst$$Register, $dst$$Register);
5786 %}
5787 ins_pipe(ialu_reg);
5788 %}
5789
5790 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
5791 %{
5792 match(Set dst src);
5793 effect(KILL cr);
5794
5795 ins_cost(60);
5796 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %}
5797 ins_encode %{
5798 __ movl($dst$$Register, $src$$constant);
5799 %}
5800 ins_pipe(ialu_reg);
5801 %}
5802
5803 instruct loadConF(regF dst, immF con) %{
5804 match(Set dst con);
5805 ins_cost(125);
5806 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
5807 ins_encode %{
5808 __ movflt($dst$$XMMRegister, $constantaddress($con));
5809 %}
5810 ins_pipe(pipe_slow);
5811 %}
5812
5813 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
5814 match(Set dst src);
5815 effect(KILL cr);
5816 format %{ "xorq $dst, $src\t# compressed NULL ptr" %}
5817 ins_encode %{
5818 __ xorq($dst$$Register, $dst$$Register);
5819 %}
5820 ins_pipe(ialu_reg);
5821 %}
5822
5823 instruct loadConN(rRegN dst, immN src) %{
5824 match(Set dst src);
5825
5826 ins_cost(125);
5827 format %{ "movl $dst, $src\t# compressed ptr" %}
5828 ins_encode %{
5829 address con = (address)$src$$constant;
5830 if (con == NULL) {
5831 ShouldNotReachHere();
5832 } else {
5833 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
5834 }
5835 %}
5836 ins_pipe(ialu_reg_fat); // XXX
5837 %}
5838
5839 instruct loadConNKlass(rRegN dst, immNKlass src) %{
5840 match(Set dst src);
5841
5842 ins_cost(125);
5843 format %{ "movl $dst, $src\t# compressed klass ptr" %}
5844 ins_encode %{
5845 address con = (address)$src$$constant;
5846 if (con == NULL) {
5847 ShouldNotReachHere();
5848 } else {
5849 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant);
5850 }
5851 %}
5852 ins_pipe(ialu_reg_fat); // XXX
5853 %}
5854
5855 instruct loadConF0(regF dst, immF0 src)
5856 %{
5857 match(Set dst src);
5858 ins_cost(100);
5859
5860 format %{ "xorps $dst, $dst\t# float 0.0" %}
5861 ins_encode %{
5862 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
5863 %}
5864 ins_pipe(pipe_slow);
5865 %}
5866
5867 // Use the same format since predicate() can not be used here.
5868 instruct loadConD(regD dst, immD con) %{
5869 match(Set dst con);
5870 ins_cost(125);
5871 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
5872 ins_encode %{
5873 __ movdbl($dst$$XMMRegister, $constantaddress($con));
5874 %}
5875 ins_pipe(pipe_slow);
5876 %}
5877
5878 instruct loadConD0(regD dst, immD0 src)
5879 %{
5880 match(Set dst src);
5881 ins_cost(100);
5882
5883 format %{ "xorpd $dst, $dst\t# double 0.0" %}
5884 ins_encode %{
5885 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
5886 %}
5887 ins_pipe(pipe_slow);
5888 %}
5889
5890 instruct loadSSI(rRegI dst, stackSlotI src)
5891 %{
5892 match(Set dst src);
5893
5894 ins_cost(125);
5895 format %{ "movl $dst, $src\t# int stk" %}
5896 opcode(0x8B);
5897 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
5898 ins_pipe(ialu_reg_mem);
5899 %}
5900
5901 instruct loadSSL(rRegL dst, stackSlotL src)
5902 %{
5903 match(Set dst src);
5904
5905 ins_cost(125);
5906 format %{ "movq $dst, $src\t# long stk" %}
5907 opcode(0x8B);
5908 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5909 ins_pipe(ialu_reg_mem);
5910 %}
5911
5912 instruct loadSSP(rRegP dst, stackSlotP src)
5913 %{
5914 match(Set dst src);
5915
5916 ins_cost(125);
5917 format %{ "movq $dst, $src\t# ptr stk" %}
5918 opcode(0x8B);
5919 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5920 ins_pipe(ialu_reg_mem);
5921 %}
5922
5923 instruct loadSSF(regF dst, stackSlotF src)
5924 %{
5925 match(Set dst src);
5926
5927 ins_cost(125);
5928 format %{ "movss $dst, $src\t# float stk" %}
5929 ins_encode %{
5930 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
5931 %}
5932 ins_pipe(pipe_slow); // XXX
5933 %}
5934
5935 // Use the same format since predicate() can not be used here.
5936 instruct loadSSD(regD dst, stackSlotD src)
5937 %{
5938 match(Set dst src);
5939
5940 ins_cost(125);
5941 format %{ "movsd $dst, $src\t# double stk" %}
5942 ins_encode %{
5943 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
5944 %}
5945 ins_pipe(pipe_slow); // XXX
5946 %}
5947
5948 // Prefetch instructions for allocation.
5949 // Must be safe to execute with invalid address (cannot fault).
5950
5951 instruct prefetchAlloc( memory mem ) %{
5952 predicate(AllocatePrefetchInstr==3);
5953 match(PrefetchAllocation mem);
5954 ins_cost(125);
5955
5956 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %}
5957 ins_encode %{
5958 __ prefetchw($mem$$Address);
5959 %}
5960 ins_pipe(ialu_mem);
5961 %}
5962
5963 instruct prefetchAllocNTA( memory mem ) %{
5964 predicate(AllocatePrefetchInstr==0);
5965 match(PrefetchAllocation mem);
5966 ins_cost(125);
5967
5968 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %}
5969 ins_encode %{
5970 __ prefetchnta($mem$$Address);
5971 %}
5972 ins_pipe(ialu_mem);
5973 %}
5974
5975 instruct prefetchAllocT0( memory mem ) %{
5976 predicate(AllocatePrefetchInstr==1);
5977 match(PrefetchAllocation mem);
5978 ins_cost(125);
5979
5980 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %}
5981 ins_encode %{
5982 __ prefetcht0($mem$$Address);
5983 %}
5984 ins_pipe(ialu_mem);
5985 %}
5986
5987 instruct prefetchAllocT2( memory mem ) %{
5988 predicate(AllocatePrefetchInstr==2);
5989 match(PrefetchAllocation mem);
5990 ins_cost(125);
5991
5992 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %}
5993 ins_encode %{
5994 __ prefetcht2($mem$$Address);
5995 %}
5996 ins_pipe(ialu_mem);
5997 %}
5998
5999 //----------Store Instructions-------------------------------------------------
6000
6001 // Store Byte
6002 instruct storeB(memory mem, rRegI src)
6003 %{
6004 match(Set mem (StoreB mem src));
6005
6006 ins_cost(125); // XXX
6007 format %{ "movb $mem, $src\t# byte" %}
6008 ins_encode %{
6009 __ movb($mem$$Address, $src$$Register);
6010 %}
6011 ins_pipe(ialu_mem_reg);
6012 %}
6013
6014 // Store Char/Short
6015 instruct storeC(memory mem, rRegI src)
6016 %{
6017 match(Set mem (StoreC mem src));
6018
6019 ins_cost(125); // XXX
6020 format %{ "movw $mem, $src\t# char/short" %}
6021 ins_encode %{
6022 __ movw($mem$$Address, $src$$Register);
6023 %}
6024 ins_pipe(ialu_mem_reg);
6025 %}
6026
6027 // Store Integer
6028 instruct storeI(memory mem, rRegI src)
6029 %{
6030 match(Set mem (StoreI mem src));
6031
6032 ins_cost(125); // XXX
6033 format %{ "movl $mem, $src\t# int" %}
6034 ins_encode %{
6035 __ movl($mem$$Address, $src$$Register);
6036 %}
6037 ins_pipe(ialu_mem_reg);
6038 %}
6039
6040 // Store Long
6041 instruct storeL(memory mem, rRegL src)
6042 %{
6043 match(Set mem (StoreL mem src));
6044
6045 ins_cost(125); // XXX
6046 format %{ "movq $mem, $src\t# long" %}
6047 ins_encode %{
6048 __ movq($mem$$Address, $src$$Register);
6049 %}
6050 ins_pipe(ialu_mem_reg); // XXX
6051 %}
6052
6053 // Store Pointer
6054 instruct storeP(memory mem, any_RegP src)
6055 %{
6056 match(Set mem (StoreP mem src));
6057
6058 ins_cost(125); // XXX
6059 format %{ "movq $mem, $src\t# ptr" %}
6060 ins_encode %{
6061 __ movq($mem$$Address, $src$$Register);
6062 %}
6063 ins_pipe(ialu_mem_reg);
6064 %}
6065
6066 instruct storeImmP0(memory mem, immP0 zero)
6067 %{
6068 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6069 match(Set mem (StoreP mem zero));
6070
6071 ins_cost(125); // XXX
6072 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
6073 ins_encode %{
6074 __ movq($mem$$Address, r12);
6075 %}
6076 ins_pipe(ialu_mem_reg);
6077 %}
6078
6079 // Store NULL Pointer, mark word, or other simple pointer constant.
6080 instruct storeImmP(memory mem, immP31 src)
6081 %{
6082 match(Set mem (StoreP mem src));
6083
6084 ins_cost(150); // XXX
6085 format %{ "movq $mem, $src\t# ptr" %}
6086 ins_encode %{
6087 __ movq($mem$$Address, $src$$constant);
6088 %}
6089 ins_pipe(ialu_mem_imm);
6090 %}
6091
6092 // Store Compressed Pointer
6093 instruct storeN(memory mem, rRegN src)
6094 %{
6095 match(Set mem (StoreN mem src));
6096
6097 ins_cost(125); // XXX
6098 format %{ "movl $mem, $src\t# compressed ptr" %}
6099 ins_encode %{
6100 __ movl($mem$$Address, $src$$Register);
6101 %}
6102 ins_pipe(ialu_mem_reg);
6103 %}
6104
6105 instruct storeNKlass(memory mem, rRegN src)
6106 %{
6107 match(Set mem (StoreNKlass mem src));
6108
6109 ins_cost(125); // XXX
6110 format %{ "movl $mem, $src\t# compressed klass ptr" %}
6111 ins_encode %{
6112 __ movl($mem$$Address, $src$$Register);
6113 %}
6114 ins_pipe(ialu_mem_reg);
6115 %}
6116
6117 instruct storeImmN0(memory mem, immN0 zero)
6118 %{
6119 predicate(CompressedOops::base() == NULL);
6120 match(Set mem (StoreN mem zero));
6121
6122 ins_cost(125); // XXX
6123 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
6124 ins_encode %{
6125 __ movl($mem$$Address, r12);
6126 %}
6127 ins_pipe(ialu_mem_reg);
6128 %}
6129
6130 instruct storeImmN(memory mem, immN src)
6131 %{
6132 match(Set mem (StoreN mem src));
6133
6134 ins_cost(150); // XXX
6135 format %{ "movl $mem, $src\t# compressed ptr" %}
6136 ins_encode %{
6137 address con = (address)$src$$constant;
6138 if (con == NULL) {
6139 __ movl($mem$$Address, (int32_t)0);
6140 } else {
6141 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant);
6142 }
6143 %}
6144 ins_pipe(ialu_mem_imm);
6145 %}
6146
6147 instruct storeImmNKlass(memory mem, immNKlass src)
6148 %{
6149 match(Set mem (StoreNKlass mem src));
6150
6151 ins_cost(150); // XXX
6152 format %{ "movl $mem, $src\t# compressed klass ptr" %}
6153 ins_encode %{
6154 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant);
6155 %}
6156 ins_pipe(ialu_mem_imm);
6157 %}
6158
6159 // Store Integer Immediate
6160 instruct storeImmI0(memory mem, immI_0 zero)
6161 %{
6162 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6163 match(Set mem (StoreI mem zero));
6164
6165 ins_cost(125); // XXX
6166 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
6167 ins_encode %{
6168 __ movl($mem$$Address, r12);
6169 %}
6170 ins_pipe(ialu_mem_reg);
6171 %}
6172
6173 instruct storeImmI(memory mem, immI src)
6174 %{
6175 match(Set mem (StoreI mem src));
6176
6177 ins_cost(150);
6178 format %{ "movl $mem, $src\t# int" %}
6179 ins_encode %{
6180 __ movl($mem$$Address, $src$$constant);
6181 %}
6182 ins_pipe(ialu_mem_imm);
6183 %}
6184
6185 // Store Long Immediate
6186 instruct storeImmL0(memory mem, immL0 zero)
6187 %{
6188 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6189 match(Set mem (StoreL mem zero));
6190
6191 ins_cost(125); // XXX
6192 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
6193 ins_encode %{
6194 __ movq($mem$$Address, r12);
6195 %}
6196 ins_pipe(ialu_mem_reg);
6197 %}
6198
6199 instruct storeImmL(memory mem, immL32 src)
6200 %{
6201 match(Set mem (StoreL mem src));
6202
6203 ins_cost(150);
6204 format %{ "movq $mem, $src\t# long" %}
6205 ins_encode %{
6206 __ movq($mem$$Address, $src$$constant);
6207 %}
6208 ins_pipe(ialu_mem_imm);
6209 %}
6210
6211 // Store Short/Char Immediate
6212 instruct storeImmC0(memory mem, immI_0 zero)
6213 %{
6214 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6215 match(Set mem (StoreC mem zero));
6216
6217 ins_cost(125); // XXX
6218 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
6219 ins_encode %{
6220 __ movw($mem$$Address, r12);
6221 %}
6222 ins_pipe(ialu_mem_reg);
6223 %}
6224
6225 instruct storeImmI16(memory mem, immI16 src)
6226 %{
6227 predicate(UseStoreImmI16);
6228 match(Set mem (StoreC mem src));
6229
6230 ins_cost(150);
6231 format %{ "movw $mem, $src\t# short/char" %}
6232 ins_encode %{
6233 __ movw($mem$$Address, $src$$constant);
6234 %}
6235 ins_pipe(ialu_mem_imm);
6236 %}
6237
6238 // Store Byte Immediate
6239 instruct storeImmB0(memory mem, immI_0 zero)
6240 %{
6241 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6242 match(Set mem (StoreB mem zero));
6243
6244 ins_cost(125); // XXX
6245 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
6246 ins_encode %{
6247 __ movb($mem$$Address, r12);
6248 %}
6249 ins_pipe(ialu_mem_reg);
6250 %}
6251
6252 instruct storeImmB(memory mem, immI8 src)
6253 %{
6254 match(Set mem (StoreB mem src));
6255
6256 ins_cost(150); // XXX
6257 format %{ "movb $mem, $src\t# byte" %}
6258 ins_encode %{
6259 __ movb($mem$$Address, $src$$constant);
6260 %}
6261 ins_pipe(ialu_mem_imm);
6262 %}
6263
6264 // Store CMS card-mark Immediate
6265 instruct storeImmCM0_reg(memory mem, immI_0 zero)
6266 %{
6267 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6268 match(Set mem (StoreCM mem zero));
6269
6270 ins_cost(125); // XXX
6271 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
6272 ins_encode %{
6273 __ movb($mem$$Address, r12);
6274 %}
6275 ins_pipe(ialu_mem_reg);
6276 %}
6277
6278 instruct storeImmCM0(memory mem, immI_0 src)
6279 %{
6280 match(Set mem (StoreCM mem src));
6281
6282 ins_cost(150); // XXX
6283 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
6284 ins_encode %{
6285 __ movb($mem$$Address, $src$$constant);
6286 %}
6287 ins_pipe(ialu_mem_imm);
6288 %}
6289
6290 // Store Float
6291 instruct storeF(memory mem, regF src)
6292 %{
6293 match(Set mem (StoreF mem src));
6294
6295 ins_cost(95); // XXX
6296 format %{ "movss $mem, $src\t# float" %}
6297 ins_encode %{
6298 __ movflt($mem$$Address, $src$$XMMRegister);
6299 %}
6300 ins_pipe(pipe_slow); // XXX
6301 %}
6302
6303 // Store immediate Float value (it is faster than store from XMM register)
6304 instruct storeF0(memory mem, immF0 zero)
6305 %{
6306 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6307 match(Set mem (StoreF mem zero));
6308
6309 ins_cost(25); // XXX
6310 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
6311 ins_encode %{
6312 __ movl($mem$$Address, r12);
6313 %}
6314 ins_pipe(ialu_mem_reg);
6315 %}
6316
6317 instruct storeF_imm(memory mem, immF src)
6318 %{
6319 match(Set mem (StoreF mem src));
6320
6321 ins_cost(50);
6322 format %{ "movl $mem, $src\t# float" %}
6323 ins_encode %{
6324 __ movl($mem$$Address, jint_cast($src$$constant));
6325 %}
6326 ins_pipe(ialu_mem_imm);
6327 %}
6328
6329 // Store Double
6330 instruct storeD(memory mem, regD src)
6331 %{
6332 match(Set mem (StoreD mem src));
6333
6334 ins_cost(95); // XXX
6335 format %{ "movsd $mem, $src\t# double" %}
6336 ins_encode %{
6337 __ movdbl($mem$$Address, $src$$XMMRegister);
6338 %}
6339 ins_pipe(pipe_slow); // XXX
6340 %}
6341
6342 // Store immediate double 0.0 (it is faster than store from XMM register)
6343 instruct storeD0_imm(memory mem, immD0 src)
6344 %{
6345 predicate(!UseCompressedOops || (CompressedOops::base() != NULL));
6346 match(Set mem (StoreD mem src));
6347
6348 ins_cost(50);
6349 format %{ "movq $mem, $src\t# double 0." %}
6350 ins_encode %{
6351 __ movq($mem$$Address, $src$$constant);
6352 %}
6353 ins_pipe(ialu_mem_imm);
6354 %}
6355
6356 instruct storeD0(memory mem, immD0 zero)
6357 %{
6358 predicate(UseCompressedOops && (CompressedOops::base() == NULL));
6359 match(Set mem (StoreD mem zero));
6360
6361 ins_cost(25); // XXX
6362 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
6363 ins_encode %{
6364 __ movq($mem$$Address, r12);
6365 %}
6366 ins_pipe(ialu_mem_reg);
6367 %}
6368
6369 instruct storeSSI(stackSlotI dst, rRegI src)
6370 %{
6371 match(Set dst src);
6372
6373 ins_cost(100);
6374 format %{ "movl $dst, $src\t# int stk" %}
6375 opcode(0x89);
6376 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
6377 ins_pipe( ialu_mem_reg );
6378 %}
6379
6380 instruct storeSSL(stackSlotL dst, rRegL src)
6381 %{
6382 match(Set dst src);
6383
6384 ins_cost(100);
6385 format %{ "movq $dst, $src\t# long stk" %}
6386 opcode(0x89);
6387 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6388 ins_pipe(ialu_mem_reg);
6389 %}
6390
6391 instruct storeSSP(stackSlotP dst, rRegP src)
6392 %{
6393 match(Set dst src);
6394
6395 ins_cost(100);
6396 format %{ "movq $dst, $src\t# ptr stk" %}
6397 opcode(0x89);
6398 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6399 ins_pipe(ialu_mem_reg);
6400 %}
6401
6402 instruct storeSSF(stackSlotF dst, regF src)
6403 %{
6404 match(Set dst src);
6405
6406 ins_cost(95); // XXX
6407 format %{ "movss $dst, $src\t# float stk" %}
6408 ins_encode %{
6409 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
6410 %}
6411 ins_pipe(pipe_slow); // XXX
6412 %}
6413
6414 instruct storeSSD(stackSlotD dst, regD src)
6415 %{
6416 match(Set dst src);
6417
6418 ins_cost(95); // XXX
6419 format %{ "movsd $dst, $src\t# double stk" %}
6420 ins_encode %{
6421 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
6422 %}
6423 ins_pipe(pipe_slow); // XXX
6424 %}
6425
6426 instruct cacheWB(indirect addr)
6427 %{
6428 predicate(VM_Version::supports_data_cache_line_flush());
6429 match(CacheWB addr);
6430
6431 ins_cost(100);
6432 format %{"cache wb $addr" %}
6433 ins_encode %{
6434 assert($addr->index_position() < 0, "should be");
6435 assert($addr$$disp == 0, "should be");
6436 __ cache_wb(Address($addr$$base$$Register, 0));
6437 %}
6438 ins_pipe(pipe_slow); // XXX
6439 %}
6440
6441 instruct cacheWBPreSync()
6442 %{
6443 predicate(VM_Version::supports_data_cache_line_flush());
6444 match(CacheWBPreSync);
6445
6446 ins_cost(100);
6447 format %{"cache wb presync" %}
6448 ins_encode %{
6449 __ cache_wbsync(true);
6450 %}
6451 ins_pipe(pipe_slow); // XXX
6452 %}
6453
6454 instruct cacheWBPostSync()
6455 %{
6456 predicate(VM_Version::supports_data_cache_line_flush());
6457 match(CacheWBPostSync);
6458
6459 ins_cost(100);
6460 format %{"cache wb postsync" %}
6461 ins_encode %{
6462 __ cache_wbsync(false);
6463 %}
6464 ins_pipe(pipe_slow); // XXX
6465 %}
6466
6467 //----------BSWAP Instructions-------------------------------------------------
6468 instruct bytes_reverse_int(rRegI dst) %{
6469 match(Set dst (ReverseBytesI dst));
6470
6471 format %{ "bswapl $dst" %}
6472 ins_encode %{
6473 __ bswapl($dst$$Register);
6474 %}
6475 ins_pipe( ialu_reg );
6476 %}
6477
6478 instruct bytes_reverse_long(rRegL dst) %{
6479 match(Set dst (ReverseBytesL dst));
6480
6481 format %{ "bswapq $dst" %}
6482 ins_encode %{
6483 __ bswapq($dst$$Register);
6484 %}
6485 ins_pipe( ialu_reg);
6486 %}
6487
6488 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{
6489 match(Set dst (ReverseBytesUS dst));
6490 effect(KILL cr);
6491
6492 format %{ "bswapl $dst\n\t"
6493 "shrl $dst,16\n\t" %}
6494 ins_encode %{
6495 __ bswapl($dst$$Register);
6496 __ shrl($dst$$Register, 16);
6497 %}
6498 ins_pipe( ialu_reg );
6499 %}
6500
6501 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{
6502 match(Set dst (ReverseBytesS dst));
6503 effect(KILL cr);
6504
6505 format %{ "bswapl $dst\n\t"
6506 "sar $dst,16\n\t" %}
6507 ins_encode %{
6508 __ bswapl($dst$$Register);
6509 __ sarl($dst$$Register, 16);
6510 %}
6511 ins_pipe( ialu_reg );
6512 %}
6513
6514 //---------- Zeros Count Instructions ------------------------------------------
6515
6516 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6517 predicate(UseCountLeadingZerosInstruction);
6518 match(Set dst (CountLeadingZerosI src));
6519 effect(KILL cr);
6520
6521 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %}
6522 ins_encode %{
6523 __ lzcntl($dst$$Register, $src$$Register);
6524 %}
6525 ins_pipe(ialu_reg);
6526 %}
6527
6528 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{
6529 predicate(!UseCountLeadingZerosInstruction);
6530 match(Set dst (CountLeadingZerosI src));
6531 effect(KILL cr);
6532
6533 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t"
6534 "jnz skip\n\t"
6535 "movl $dst, -1\n"
6536 "skip:\n\t"
6537 "negl $dst\n\t"
6538 "addl $dst, 31" %}
6539 ins_encode %{
6540 Register Rdst = $dst$$Register;
6541 Register Rsrc = $src$$Register;
6542 Label skip;
6543 __ bsrl(Rdst, Rsrc);
6544 __ jccb(Assembler::notZero, skip);
6545 __ movl(Rdst, -1);
6546 __ bind(skip);
6547 __ negl(Rdst);
6548 __ addl(Rdst, BitsPerInt - 1);
6549 %}
6550 ins_pipe(ialu_reg);
6551 %}
6552
6553 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6554 predicate(UseCountLeadingZerosInstruction);
6555 match(Set dst (CountLeadingZerosL src));
6556 effect(KILL cr);
6557
6558 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %}
6559 ins_encode %{
6560 __ lzcntq($dst$$Register, $src$$Register);
6561 %}
6562 ins_pipe(ialu_reg);
6563 %}
6564
6565 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{
6566 predicate(!UseCountLeadingZerosInstruction);
6567 match(Set dst (CountLeadingZerosL src));
6568 effect(KILL cr);
6569
6570 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t"
6571 "jnz skip\n\t"
6572 "movl $dst, -1\n"
6573 "skip:\n\t"
6574 "negl $dst\n\t"
6575 "addl $dst, 63" %}
6576 ins_encode %{
6577 Register Rdst = $dst$$Register;
6578 Register Rsrc = $src$$Register;
6579 Label skip;
6580 __ bsrq(Rdst, Rsrc);
6581 __ jccb(Assembler::notZero, skip);
6582 __ movl(Rdst, -1);
6583 __ bind(skip);
6584 __ negl(Rdst);
6585 __ addl(Rdst, BitsPerLong - 1);
6586 %}
6587 ins_pipe(ialu_reg);
6588 %}
6589
6590 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6591 predicate(UseCountTrailingZerosInstruction);
6592 match(Set dst (CountTrailingZerosI src));
6593 effect(KILL cr);
6594
6595 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %}
6596 ins_encode %{
6597 __ tzcntl($dst$$Register, $src$$Register);
6598 %}
6599 ins_pipe(ialu_reg);
6600 %}
6601
6602 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{
6603 predicate(!UseCountTrailingZerosInstruction);
6604 match(Set dst (CountTrailingZerosI src));
6605 effect(KILL cr);
6606
6607 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t"
6608 "jnz done\n\t"
6609 "movl $dst, 32\n"
6610 "done:" %}
6611 ins_encode %{
6612 Register Rdst = $dst$$Register;
6613 Label done;
6614 __ bsfl(Rdst, $src$$Register);
6615 __ jccb(Assembler::notZero, done);
6616 __ movl(Rdst, BitsPerInt);
6617 __ bind(done);
6618 %}
6619 ins_pipe(ialu_reg);
6620 %}
6621
6622 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6623 predicate(UseCountTrailingZerosInstruction);
6624 match(Set dst (CountTrailingZerosL src));
6625 effect(KILL cr);
6626
6627 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %}
6628 ins_encode %{
6629 __ tzcntq($dst$$Register, $src$$Register);
6630 %}
6631 ins_pipe(ialu_reg);
6632 %}
6633
6634 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{
6635 predicate(!UseCountTrailingZerosInstruction);
6636 match(Set dst (CountTrailingZerosL src));
6637 effect(KILL cr);
6638
6639 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t"
6640 "jnz done\n\t"
6641 "movl $dst, 64\n"
6642 "done:" %}
6643 ins_encode %{
6644 Register Rdst = $dst$$Register;
6645 Label done;
6646 __ bsfq(Rdst, $src$$Register);
6647 __ jccb(Assembler::notZero, done);
6648 __ movl(Rdst, BitsPerLong);
6649 __ bind(done);
6650 %}
6651 ins_pipe(ialu_reg);
6652 %}
6653
6654
6655 //---------- Population Count Instructions -------------------------------------
6656
6657 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{
6658 predicate(UsePopCountInstruction);
6659 match(Set dst (PopCountI src));
6660 effect(KILL cr);
6661
6662 format %{ "popcnt $dst, $src" %}
6663 ins_encode %{
6664 __ popcntl($dst$$Register, $src$$Register);
6665 %}
6666 ins_pipe(ialu_reg);
6667 %}
6668
6669 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{
6670 predicate(UsePopCountInstruction);
6671 match(Set dst (PopCountI (LoadI mem)));
6672 effect(KILL cr);
6673
6674 format %{ "popcnt $dst, $mem" %}
6675 ins_encode %{
6676 __ popcntl($dst$$Register, $mem$$Address);
6677 %}
6678 ins_pipe(ialu_reg);
6679 %}
6680
6681 // Note: Long.bitCount(long) returns an int.
6682 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{
6683 predicate(UsePopCountInstruction);
6684 match(Set dst (PopCountL src));
6685 effect(KILL cr);
6686
6687 format %{ "popcnt $dst, $src" %}
6688 ins_encode %{
6689 __ popcntq($dst$$Register, $src$$Register);
6690 %}
6691 ins_pipe(ialu_reg);
6692 %}
6693
6694 // Note: Long.bitCount(long) returns an int.
6695 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{
6696 predicate(UsePopCountInstruction);
6697 match(Set dst (PopCountL (LoadL mem)));
6698 effect(KILL cr);
6699
6700 format %{ "popcnt $dst, $mem" %}
6701 ins_encode %{
6702 __ popcntq($dst$$Register, $mem$$Address);
6703 %}
6704 ins_pipe(ialu_reg);
6705 %}
6706
6707
6708 //----------MemBar Instructions-----------------------------------------------
6709 // Memory barrier flavors
6710
6711 instruct membar_acquire()
6712 %{
6713 match(MemBarAcquire);
6714 match(LoadFence);
6715 ins_cost(0);
6716
6717 size(0);
6718 format %{ "MEMBAR-acquire ! (empty encoding)" %}
6719 ins_encode();
6720 ins_pipe(empty);
6721 %}
6722
6723 instruct membar_acquire_lock()
6724 %{
6725 match(MemBarAcquireLock);
6726 ins_cost(0);
6727
6728 size(0);
6729 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %}
6730 ins_encode();
6731 ins_pipe(empty);
6732 %}
6733
6734 instruct membar_release()
6735 %{
6736 match(MemBarRelease);
6737 match(StoreFence);
6738 ins_cost(0);
6739
6740 size(0);
6741 format %{ "MEMBAR-release ! (empty encoding)" %}
6742 ins_encode();
6743 ins_pipe(empty);
6744 %}
6745
6746 instruct membar_release_lock()
6747 %{
6748 match(MemBarReleaseLock);
6749 ins_cost(0);
6750
6751 size(0);
6752 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
6753 ins_encode();
6754 ins_pipe(empty);
6755 %}
6756
6757 instruct membar_volatile(rFlagsReg cr) %{
6758 match(MemBarVolatile);
6759 effect(KILL cr);
6760 ins_cost(400);
6761
6762 format %{
6763 $$template
6764 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
6765 %}
6766 ins_encode %{
6767 __ membar(Assembler::StoreLoad);
6768 %}
6769 ins_pipe(pipe_slow);
6770 %}
6771
6772 instruct unnecessary_membar_volatile()
6773 %{
6774 match(MemBarVolatile);
6775 predicate(Matcher::post_store_load_barrier(n));
6776 ins_cost(0);
6777
6778 size(0);
6779 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
6780 ins_encode();
6781 ins_pipe(empty);
6782 %}
6783
6784 instruct membar_storestore() %{
6785 match(MemBarStoreStore);
6786 match(StoreStoreFence);
6787 ins_cost(0);
6788
6789 size(0);
6790 format %{ "MEMBAR-storestore (empty encoding)" %}
6791 ins_encode( );
6792 ins_pipe(empty);
6793 %}
6794
6795 //----------Move Instructions--------------------------------------------------
6796
6797 instruct castX2P(rRegP dst, rRegL src)
6798 %{
6799 match(Set dst (CastX2P src));
6800
6801 format %{ "movq $dst, $src\t# long->ptr" %}
6802 ins_encode %{
6803 if ($dst$$reg != $src$$reg) {
6804 __ movptr($dst$$Register, $src$$Register);
6805 }
6806 %}
6807 ins_pipe(ialu_reg_reg); // XXX
6808 %}
6809
6810 instruct castP2X(rRegL dst, rRegP src)
6811 %{
6812 match(Set dst (CastP2X src));
6813
6814 format %{ "movq $dst, $src\t# ptr -> long" %}
6815 ins_encode %{
6816 if ($dst$$reg != $src$$reg) {
6817 __ movptr($dst$$Register, $src$$Register);
6818 }
6819 %}
6820 ins_pipe(ialu_reg_reg); // XXX
6821 %}
6822
6823 // Convert oop into int for vectors alignment masking
6824 instruct convP2I(rRegI dst, rRegP src)
6825 %{
6826 match(Set dst (ConvL2I (CastP2X src)));
6827
6828 format %{ "movl $dst, $src\t# ptr -> int" %}
6829 ins_encode %{
6830 __ movl($dst$$Register, $src$$Register);
6831 %}
6832 ins_pipe(ialu_reg_reg); // XXX
6833 %}
6834
6835 // Convert compressed oop into int for vectors alignment masking
6836 // in case of 32bit oops (heap < 4Gb).
6837 instruct convN2I(rRegI dst, rRegN src)
6838 %{
6839 predicate(CompressedOops::shift() == 0);
6840 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6841
6842 format %{ "movl $dst, $src\t# compressed ptr -> int" %}
6843 ins_encode %{
6844 __ movl($dst$$Register, $src$$Register);
6845 %}
6846 ins_pipe(ialu_reg_reg); // XXX
6847 %}
6848
6849 // Convert oop pointer into compressed form
6850 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
6851 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
6852 match(Set dst (EncodeP src));
6853 effect(KILL cr);
6854 format %{ "encode_heap_oop $dst,$src" %}
6855 ins_encode %{
6856 Register s = $src$$Register;
6857 Register d = $dst$$Register;
6858 if (s != d) {
6859 __ movq(d, s);
6860 }
6861 __ encode_heap_oop(d);
6862 %}
6863 ins_pipe(ialu_reg_long);
6864 %}
6865
6866 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6867 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
6868 match(Set dst (EncodeP src));
6869 effect(KILL cr);
6870 format %{ "encode_heap_oop_not_null $dst,$src" %}
6871 ins_encode %{
6872 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
6873 %}
6874 ins_pipe(ialu_reg_long);
6875 %}
6876
6877 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
6878 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
6879 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
6880 match(Set dst (DecodeN src));
6881 effect(KILL cr);
6882 format %{ "decode_heap_oop $dst,$src" %}
6883 ins_encode %{
6884 Register s = $src$$Register;
6885 Register d = $dst$$Register;
6886 if (s != d) {
6887 __ movq(d, s);
6888 }
6889 __ decode_heap_oop(d);
6890 %}
6891 ins_pipe(ialu_reg_long);
6892 %}
6893
6894 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6895 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
6896 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
6897 match(Set dst (DecodeN src));
6898 effect(KILL cr);
6899 format %{ "decode_heap_oop_not_null $dst,$src" %}
6900 ins_encode %{
6901 Register s = $src$$Register;
6902 Register d = $dst$$Register;
6903 if (s != d) {
6904 __ decode_heap_oop_not_null(d, s);
6905 } else {
6906 __ decode_heap_oop_not_null(d);
6907 }
6908 %}
6909 ins_pipe(ialu_reg_long);
6910 %}
6911
6912 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6913 match(Set dst (EncodePKlass src));
6914 effect(TEMP dst, KILL cr);
6915 format %{ "encode_and_move_klass_not_null $dst,$src" %}
6916 ins_encode %{
6917 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register);
6918 %}
6919 ins_pipe(ialu_reg_long);
6920 %}
6921
6922 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6923 match(Set dst (DecodeNKlass src));
6924 effect(TEMP dst, KILL cr);
6925 format %{ "decode_and_move_klass_not_null $dst,$src" %}
6926 ins_encode %{
6927 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register);
6928 %}
6929 ins_pipe(ialu_reg_long);
6930 %}
6931
6932 //----------Conditional Move---------------------------------------------------
6933 // Jump
6934 // dummy instruction for generating temp registers
6935 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
6936 match(Jump (LShiftL switch_val shift));
6937 ins_cost(350);
6938 predicate(false);
6939 effect(TEMP dest);
6940
6941 format %{ "leaq $dest, [$constantaddress]\n\t"
6942 "jmp [$dest + $switch_val << $shift]\n\t" %}
6943 ins_encode %{
6944 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6945 // to do that and the compiler is using that register as one it can allocate.
6946 // So we build it all by hand.
6947 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
6948 // ArrayAddress dispatch(table, index);
6949 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
6950 __ lea($dest$$Register, $constantaddress);
6951 __ jmp(dispatch);
6952 %}
6953 ins_pipe(pipe_jmp);
6954 %}
6955
6956 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
6957 match(Jump (AddL (LShiftL switch_val shift) offset));
6958 ins_cost(350);
6959 effect(TEMP dest);
6960
6961 format %{ "leaq $dest, [$constantaddress]\n\t"
6962 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %}
6963 ins_encode %{
6964 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6965 // to do that and the compiler is using that register as one it can allocate.
6966 // So we build it all by hand.
6967 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6968 // ArrayAddress dispatch(table, index);
6969 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6970 __ lea($dest$$Register, $constantaddress);
6971 __ jmp(dispatch);
6972 %}
6973 ins_pipe(pipe_jmp);
6974 %}
6975
6976 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
6977 match(Jump switch_val);
6978 ins_cost(350);
6979 effect(TEMP dest);
6980
6981 format %{ "leaq $dest, [$constantaddress]\n\t"
6982 "jmp [$dest + $switch_val]\n\t" %}
6983 ins_encode %{
6984 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6985 // to do that and the compiler is using that register as one it can allocate.
6986 // So we build it all by hand.
6987 // Address index(noreg, switch_reg, Address::times_1);
6988 // ArrayAddress dispatch(table, index);
6989 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1);
6990 __ lea($dest$$Register, $constantaddress);
6991 __ jmp(dispatch);
6992 %}
6993 ins_pipe(pipe_jmp);
6994 %}
6995
6996 // Conditional move
6997 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
6998 %{
6999 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7000
7001 ins_cost(200); // XXX
7002 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
7003 ins_encode %{
7004 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register);
7005 %}
7006 ins_pipe(pipe_cmov_reg);
7007 %}
7008
7009 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
7010 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7011
7012 ins_cost(200); // XXX
7013 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
7014 ins_encode %{
7015 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register);
7016 %}
7017 ins_pipe(pipe_cmov_reg);
7018 %}
7019
7020 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
7021 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7022 ins_cost(200);
7023 expand %{
7024 cmovI_regU(cop, cr, dst, src);
7025 %}
7026 %}
7027
7028 // Conditional move
7029 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
7030 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7031
7032 ins_cost(250); // XXX
7033 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
7034 ins_encode %{
7035 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address);
7036 %}
7037 ins_pipe(pipe_cmov_mem);
7038 %}
7039
7040 // Conditional move
7041 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
7042 %{
7043 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7044
7045 ins_cost(250); // XXX
7046 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
7047 ins_encode %{
7048 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address);
7049 %}
7050 ins_pipe(pipe_cmov_mem);
7051 %}
7052
7053 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
7054 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7055 ins_cost(250);
7056 expand %{
7057 cmovI_memU(cop, cr, dst, src);
7058 %}
7059 %}
7060
7061 // Conditional move
7062 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
7063 %{
7064 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7065
7066 ins_cost(200); // XXX
7067 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
7068 ins_encode %{
7069 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register);
7070 %}
7071 ins_pipe(pipe_cmov_reg);
7072 %}
7073
7074 // Conditional move
7075 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
7076 %{
7077 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7078
7079 ins_cost(200); // XXX
7080 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
7081 ins_encode %{
7082 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register);
7083 %}
7084 ins_pipe(pipe_cmov_reg);
7085 %}
7086
7087 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
7088 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7089 ins_cost(200);
7090 expand %{
7091 cmovN_regU(cop, cr, dst, src);
7092 %}
7093 %}
7094
7095 // Conditional move
7096 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
7097 %{
7098 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7099
7100 ins_cost(200); // XXX
7101 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %}
7102 ins_encode %{
7103 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register);
7104 %}
7105 ins_pipe(pipe_cmov_reg); // XXX
7106 %}
7107
7108 // Conditional move
7109 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
7110 %{
7111 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7112
7113 ins_cost(200); // XXX
7114 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %}
7115 ins_encode %{
7116 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register);
7117 %}
7118 ins_pipe(pipe_cmov_reg); // XXX
7119 %}
7120
7121 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
7122 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7123 ins_cost(200);
7124 expand %{
7125 cmovP_regU(cop, cr, dst, src);
7126 %}
7127 %}
7128
7129 // DISABLED: Requires the ADLC to emit a bottom_type call that
7130 // correctly meets the two pointer arguments; one is an incoming
7131 // register but the other is a memory operand. ALSO appears to
7132 // be buggy with implicit null checks.
7133 //
7134 //// Conditional move
7135 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src)
7136 //%{
7137 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
7138 // ins_cost(250);
7139 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
7140 // opcode(0x0F,0x40);
7141 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
7142 // ins_pipe( pipe_cmov_mem );
7143 //%}
7144 //
7145 //// Conditional move
7146 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src)
7147 //%{
7148 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
7149 // ins_cost(250);
7150 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
7151 // opcode(0x0F,0x40);
7152 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
7153 // ins_pipe( pipe_cmov_mem );
7154 //%}
7155
7156 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src)
7157 %{
7158 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7159
7160 ins_cost(200); // XXX
7161 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
7162 ins_encode %{
7163 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register);
7164 %}
7165 ins_pipe(pipe_cmov_reg); // XXX
7166 %}
7167
7168 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src)
7169 %{
7170 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7171
7172 ins_cost(200); // XXX
7173 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
7174 ins_encode %{
7175 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address);
7176 %}
7177 ins_pipe(pipe_cmov_mem); // XXX
7178 %}
7179
7180 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src)
7181 %{
7182 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7183
7184 ins_cost(200); // XXX
7185 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7186 ins_encode %{
7187 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register);
7188 %}
7189 ins_pipe(pipe_cmov_reg); // XXX
7190 %}
7191
7192 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
7193 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7194 ins_cost(200);
7195 expand %{
7196 cmovL_regU(cop, cr, dst, src);
7197 %}
7198 %}
7199
7200 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
7201 %{
7202 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7203
7204 ins_cost(200); // XXX
7205 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7206 ins_encode %{
7207 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address);
7208 %}
7209 ins_pipe(pipe_cmov_mem); // XXX
7210 %}
7211
7212 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
7213 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7214 ins_cost(200);
7215 expand %{
7216 cmovL_memU(cop, cr, dst, src);
7217 %}
7218 %}
7219
7220 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
7221 %{
7222 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7223
7224 ins_cost(200); // XXX
7225 format %{ "jn$cop skip\t# signed cmove float\n\t"
7226 "movss $dst, $src\n"
7227 "skip:" %}
7228 ins_encode %{
7229 Label Lskip;
7230 // Invert sense of branch from sense of CMOV
7231 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7232 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7233 __ bind(Lskip);
7234 %}
7235 ins_pipe(pipe_slow);
7236 %}
7237
7238 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
7239 // %{
7240 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src))));
7241
7242 // ins_cost(200); // XXX
7243 // format %{ "jn$cop skip\t# signed cmove float\n\t"
7244 // "movss $dst, $src\n"
7245 // "skip:" %}
7246 // ins_encode(enc_cmovf_mem_branch(cop, dst, src));
7247 // ins_pipe(pipe_slow);
7248 // %}
7249
7250 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
7251 %{
7252 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7253
7254 ins_cost(200); // XXX
7255 format %{ "jn$cop skip\t# unsigned cmove float\n\t"
7256 "movss $dst, $src\n"
7257 "skip:" %}
7258 ins_encode %{
7259 Label Lskip;
7260 // Invert sense of branch from sense of CMOV
7261 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7262 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7263 __ bind(Lskip);
7264 %}
7265 ins_pipe(pipe_slow);
7266 %}
7267
7268 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
7269 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7270 ins_cost(200);
7271 expand %{
7272 cmovF_regU(cop, cr, dst, src);
7273 %}
7274 %}
7275
7276 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
7277 %{
7278 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7279
7280 ins_cost(200); // XXX
7281 format %{ "jn$cop skip\t# signed cmove double\n\t"
7282 "movsd $dst, $src\n"
7283 "skip:" %}
7284 ins_encode %{
7285 Label Lskip;
7286 // Invert sense of branch from sense of CMOV
7287 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7288 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7289 __ bind(Lskip);
7290 %}
7291 ins_pipe(pipe_slow);
7292 %}
7293
7294 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
7295 %{
7296 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7297
7298 ins_cost(200); // XXX
7299 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
7300 "movsd $dst, $src\n"
7301 "skip:" %}
7302 ins_encode %{
7303 Label Lskip;
7304 // Invert sense of branch from sense of CMOV
7305 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7306 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7307 __ bind(Lskip);
7308 %}
7309 ins_pipe(pipe_slow);
7310 %}
7311
7312 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
7313 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7314 ins_cost(200);
7315 expand %{
7316 cmovD_regU(cop, cr, dst, src);
7317 %}
7318 %}
7319
7320 //----------Arithmetic Instructions--------------------------------------------
7321 //----------Addition Instructions----------------------------------------------
7322
7323 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7324 %{
7325 match(Set dst (AddI dst src));
7326 effect(KILL cr);
7327
7328 format %{ "addl $dst, $src\t# int" %}
7329 ins_encode %{
7330 __ addl($dst$$Register, $src$$Register);
7331 %}
7332 ins_pipe(ialu_reg_reg);
7333 %}
7334
7335 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7336 %{
7337 match(Set dst (AddI dst src));
7338 effect(KILL cr);
7339
7340 format %{ "addl $dst, $src\t# int" %}
7341 ins_encode %{
7342 __ addl($dst$$Register, $src$$constant);
7343 %}
7344 ins_pipe( ialu_reg );
7345 %}
7346
7347 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
7348 %{
7349 match(Set dst (AddI dst (LoadI src)));
7350 effect(KILL cr);
7351
7352 ins_cost(125); // XXX
7353 format %{ "addl $dst, $src\t# int" %}
7354 ins_encode %{
7355 __ addl($dst$$Register, $src$$Address);
7356 %}
7357 ins_pipe(ialu_reg_mem);
7358 %}
7359
7360 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
7361 %{
7362 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7363 effect(KILL cr);
7364
7365 ins_cost(150); // XXX
7366 format %{ "addl $dst, $src\t# int" %}
7367 ins_encode %{
7368 __ addl($dst$$Address, $src$$Register);
7369 %}
7370 ins_pipe(ialu_mem_reg);
7371 %}
7372
7373 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr)
7374 %{
7375 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7376 effect(KILL cr);
7377
7378 ins_cost(125); // XXX
7379 format %{ "addl $dst, $src\t# int" %}
7380 ins_encode %{
7381 __ addl($dst$$Address, $src$$constant);
7382 %}
7383 ins_pipe(ialu_mem_imm);
7384 %}
7385
7386 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr)
7387 %{
7388 predicate(UseIncDec);
7389 match(Set dst (AddI dst src));
7390 effect(KILL cr);
7391
7392 format %{ "incl $dst\t# int" %}
7393 ins_encode %{
7394 __ incrementl($dst$$Register);
7395 %}
7396 ins_pipe(ialu_reg);
7397 %}
7398
7399 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr)
7400 %{
7401 predicate(UseIncDec);
7402 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7403 effect(KILL cr);
7404
7405 ins_cost(125); // XXX
7406 format %{ "incl $dst\t# int" %}
7407 ins_encode %{
7408 __ incrementl($dst$$Address);
7409 %}
7410 ins_pipe(ialu_mem_imm);
7411 %}
7412
7413 // XXX why does that use AddI
7414 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr)
7415 %{
7416 predicate(UseIncDec);
7417 match(Set dst (AddI dst src));
7418 effect(KILL cr);
7419
7420 format %{ "decl $dst\t# int" %}
7421 ins_encode %{
7422 __ decrementl($dst$$Register);
7423 %}
7424 ins_pipe(ialu_reg);
7425 %}
7426
7427 // XXX why does that use AddI
7428 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr)
7429 %{
7430 predicate(UseIncDec);
7431 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7432 effect(KILL cr);
7433
7434 ins_cost(125); // XXX
7435 format %{ "decl $dst\t# int" %}
7436 ins_encode %{
7437 __ decrementl($dst$$Address);
7438 %}
7439 ins_pipe(ialu_mem_imm);
7440 %}
7441
7442 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1)
7443 %{
7444 match(Set dst (AddI src0 src1));
7445
7446 ins_cost(110);
7447 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %}
7448 ins_encode %{
7449 __ leal($dst$$Register, Address($src0$$Register, $src1$$constant));
7450 %}
7451 ins_pipe(ialu_reg_reg);
7452 %}
7453
7454 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7455 %{
7456 match(Set dst (AddL dst src));
7457 effect(KILL cr);
7458
7459 format %{ "addq $dst, $src\t# long" %}
7460 ins_encode %{
7461 __ addq($dst$$Register, $src$$Register);
7462 %}
7463 ins_pipe(ialu_reg_reg);
7464 %}
7465
7466 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
7467 %{
7468 match(Set dst (AddL dst src));
7469 effect(KILL cr);
7470
7471 format %{ "addq $dst, $src\t# long" %}
7472 ins_encode %{
7473 __ addq($dst$$Register, $src$$constant);
7474 %}
7475 ins_pipe( ialu_reg );
7476 %}
7477
7478 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
7479 %{
7480 match(Set dst (AddL dst (LoadL src)));
7481 effect(KILL cr);
7482
7483 ins_cost(125); // XXX
7484 format %{ "addq $dst, $src\t# long" %}
7485 ins_encode %{
7486 __ addq($dst$$Register, $src$$Address);
7487 %}
7488 ins_pipe(ialu_reg_mem);
7489 %}
7490
7491 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
7492 %{
7493 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7494 effect(KILL cr);
7495
7496 ins_cost(150); // XXX
7497 format %{ "addq $dst, $src\t# long" %}
7498 ins_encode %{
7499 __ addq($dst$$Address, $src$$Register);
7500 %}
7501 ins_pipe(ialu_mem_reg);
7502 %}
7503
7504 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
7505 %{
7506 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7507 effect(KILL cr);
7508
7509 ins_cost(125); // XXX
7510 format %{ "addq $dst, $src\t# long" %}
7511 ins_encode %{
7512 __ addq($dst$$Address, $src$$constant);
7513 %}
7514 ins_pipe(ialu_mem_imm);
7515 %}
7516
7517 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr)
7518 %{
7519 predicate(UseIncDec);
7520 match(Set dst (AddL dst src));
7521 effect(KILL cr);
7522
7523 format %{ "incq $dst\t# long" %}
7524 ins_encode %{
7525 __ incrementq($dst$$Register);
7526 %}
7527 ins_pipe(ialu_reg);
7528 %}
7529
7530 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr)
7531 %{
7532 predicate(UseIncDec);
7533 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7534 effect(KILL cr);
7535
7536 ins_cost(125); // XXX
7537 format %{ "incq $dst\t# long" %}
7538 ins_encode %{
7539 __ incrementq($dst$$Address);
7540 %}
7541 ins_pipe(ialu_mem_imm);
7542 %}
7543
7544 // XXX why does that use AddL
7545 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr)
7546 %{
7547 predicate(UseIncDec);
7548 match(Set dst (AddL dst src));
7549 effect(KILL cr);
7550
7551 format %{ "decq $dst\t# long" %}
7552 ins_encode %{
7553 __ decrementq($dst$$Register);
7554 %}
7555 ins_pipe(ialu_reg);
7556 %}
7557
7558 // XXX why does that use AddL
7559 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr)
7560 %{
7561 predicate(UseIncDec);
7562 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7563 effect(KILL cr);
7564
7565 ins_cost(125); // XXX
7566 format %{ "decq $dst\t# long" %}
7567 ins_encode %{
7568 __ decrementq($dst$$Address);
7569 %}
7570 ins_pipe(ialu_mem_imm);
7571 %}
7572
7573 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1)
7574 %{
7575 match(Set dst (AddL src0 src1));
7576
7577 ins_cost(110);
7578 format %{ "leaq $dst, [$src0 + $src1]\t# long" %}
7579 ins_encode %{
7580 __ leaq($dst$$Register, Address($src0$$Register, $src1$$constant));
7581 %}
7582 ins_pipe(ialu_reg_reg);
7583 %}
7584
7585 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr)
7586 %{
7587 match(Set dst (AddP dst src));
7588 effect(KILL cr);
7589
7590 format %{ "addq $dst, $src\t# ptr" %}
7591 ins_encode %{
7592 __ addq($dst$$Register, $src$$Register);
7593 %}
7594 ins_pipe(ialu_reg_reg);
7595 %}
7596
7597 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr)
7598 %{
7599 match(Set dst (AddP dst src));
7600 effect(KILL cr);
7601
7602 format %{ "addq $dst, $src\t# ptr" %}
7603 ins_encode %{
7604 __ addq($dst$$Register, $src$$constant);
7605 %}
7606 ins_pipe( ialu_reg );
7607 %}
7608
7609 // XXX addP mem ops ????
7610
7611 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1)
7612 %{
7613 match(Set dst (AddP src0 src1));
7614
7615 ins_cost(110);
7616 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %}
7617 ins_encode %{
7618 __ leaq($dst$$Register, Address($src0$$Register, $src1$$constant));
7619 %}
7620 ins_pipe(ialu_reg_reg);
7621 %}
7622
7623 instruct checkCastPP(rRegP dst)
7624 %{
7625 match(Set dst (CheckCastPP dst));
7626
7627 size(0);
7628 format %{ "# checkcastPP of $dst" %}
7629 ins_encode(/* empty encoding */);
7630 ins_pipe(empty);
7631 %}
7632
7633 instruct castPP(rRegP dst)
7634 %{
7635 match(Set dst (CastPP dst));
7636
7637 size(0);
7638 format %{ "# castPP of $dst" %}
7639 ins_encode(/* empty encoding */);
7640 ins_pipe(empty);
7641 %}
7642
7643 instruct castII(rRegI dst)
7644 %{
7645 match(Set dst (CastII dst));
7646
7647 size(0);
7648 format %{ "# castII of $dst" %}
7649 ins_encode(/* empty encoding */);
7650 ins_cost(0);
7651 ins_pipe(empty);
7652 %}
7653
7654 instruct castLL(rRegL dst)
7655 %{
7656 match(Set dst (CastLL dst));
7657
7658 size(0);
7659 format %{ "# castLL of $dst" %}
7660 ins_encode(/* empty encoding */);
7661 ins_cost(0);
7662 ins_pipe(empty);
7663 %}
7664
7665 instruct castFF(regF dst)
7666 %{
7667 match(Set dst (CastFF dst));
7668
7669 size(0);
7670 format %{ "# castFF of $dst" %}
7671 ins_encode(/* empty encoding */);
7672 ins_cost(0);
7673 ins_pipe(empty);
7674 %}
7675
7676 instruct castDD(regD dst)
7677 %{
7678 match(Set dst (CastDD dst));
7679
7680 size(0);
7681 format %{ "# castDD of $dst" %}
7682 ins_encode(/* empty encoding */);
7683 ins_cost(0);
7684 ins_pipe(empty);
7685 %}
7686
7687 // LoadP-locked same as a regular LoadP when used with compare-swap
7688 instruct loadPLocked(rRegP dst, memory mem)
7689 %{
7690 match(Set dst (LoadPLocked mem));
7691
7692 ins_cost(125); // XXX
7693 format %{ "movq $dst, $mem\t# ptr locked" %}
7694 ins_encode %{
7695 __ movq($dst$$Register, $mem$$Address);
7696 %}
7697 ins_pipe(ialu_reg_mem); // XXX
7698 %}
7699
7700 // Conditional-store of the updated heap-top.
7701 // Used during allocation of the shared heap.
7702 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
7703
7704 instruct storePConditional(memory heap_top_ptr,
7705 rax_RegP oldval, rRegP newval,
7706 rFlagsReg cr)
7707 %{
7708 predicate(n->as_LoadStore()->barrier_data() == 0);
7709 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
7710
7711 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
7712 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
7713 ins_encode %{
7714 __ lock();
7715 __ cmpxchgq($newval$$Register, $heap_top_ptr$$Address);
7716 %}
7717 ins_pipe(pipe_cmpxchg);
7718 %}
7719
7720 // Conditional-store of an int value.
7721 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
7722 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
7723 %{
7724 match(Set cr (StoreIConditional mem (Binary oldval newval)));
7725 effect(KILL oldval);
7726
7727 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7728 opcode(0x0F, 0xB1);
7729 ins_encode(lock_prefix,
7730 REX_reg_mem(newval, mem),
7731 OpcP, OpcS,
7732 reg_mem(newval, mem));
7733 ins_pipe(pipe_cmpxchg);
7734 %}
7735
7736 // Conditional-store of a long value.
7737 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
7738 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
7739 %{
7740 match(Set cr (StoreLConditional mem (Binary oldval newval)));
7741 effect(KILL oldval);
7742
7743 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7744 ins_encode %{
7745 __ lock();
7746 __ cmpxchgq($newval$$Register, $mem$$Address);
7747 %}
7748 ins_pipe(pipe_cmpxchg);
7749 %}
7750
7751
7752 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7753 instruct compareAndSwapP(rRegI res,
7754 memory mem_ptr,
7755 rax_RegP oldval, rRegP newval,
7756 rFlagsReg cr)
7757 %{
7758 predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0);
7759 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7760 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
7761 effect(KILL cr, KILL oldval);
7762
7763 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7764 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7765 "sete $res\n\t"
7766 "movzbl $res, $res" %}
7767 ins_encode %{
7768 __ lock();
7769 __ cmpxchgq($newval$$Register, $mem_ptr$$Address);
7770 __ sete($res$$Register);
7771 __ movzbl($res$$Register, $res$$Register);
7772 %}
7773 ins_pipe( pipe_cmpxchg );
7774 %}
7775
7776 instruct compareAndSwapL(rRegI res,
7777 memory mem_ptr,
7778 rax_RegL oldval, rRegL newval,
7779 rFlagsReg cr)
7780 %{
7781 predicate(VM_Version::supports_cx8());
7782 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7783 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
7784 effect(KILL cr, KILL oldval);
7785
7786 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7787 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7788 "sete $res\n\t"
7789 "movzbl $res, $res" %}
7790 ins_encode %{
7791 __ lock();
7792 __ cmpxchgq($newval$$Register, $mem_ptr$$Address);
7793 __ sete($res$$Register);
7794 __ movzbl($res$$Register, $res$$Register);
7795 %}
7796 ins_pipe( pipe_cmpxchg );
7797 %}
7798
7799 instruct compareAndSwapI(rRegI res,
7800 memory mem_ptr,
7801 rax_RegI oldval, rRegI newval,
7802 rFlagsReg cr)
7803 %{
7804 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
7805 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval)));
7806 effect(KILL cr, KILL oldval);
7807
7808 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7809 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7810 "sete $res\n\t"
7811 "movzbl $res, $res" %}
7812 ins_encode %{
7813 __ lock();
7814 __ cmpxchgl($newval$$Register, $mem_ptr$$Address);
7815 __ sete($res$$Register);
7816 __ movzbl($res$$Register, $res$$Register);
7817 %}
7818 ins_pipe( pipe_cmpxchg );
7819 %}
7820
7821 instruct compareAndSwapB(rRegI res,
7822 memory mem_ptr,
7823 rax_RegI oldval, rRegI newval,
7824 rFlagsReg cr)
7825 %{
7826 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval)));
7827 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval)));
7828 effect(KILL cr, KILL oldval);
7829
7830 format %{ "cmpxchgb $mem_ptr,$newval\t# "
7831 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7832 "sete $res\n\t"
7833 "movzbl $res, $res" %}
7834 ins_encode %{
7835 __ lock();
7836 __ cmpxchgb($newval$$Register, $mem_ptr$$Address);
7837 __ sete($res$$Register);
7838 __ movzbl($res$$Register, $res$$Register);
7839 %}
7840 ins_pipe( pipe_cmpxchg );
7841 %}
7842
7843 instruct compareAndSwapS(rRegI res,
7844 memory mem_ptr,
7845 rax_RegI oldval, rRegI newval,
7846 rFlagsReg cr)
7847 %{
7848 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval)));
7849 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval)));
7850 effect(KILL cr, KILL oldval);
7851
7852 format %{ "cmpxchgw $mem_ptr,$newval\t# "
7853 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7854 "sete $res\n\t"
7855 "movzbl $res, $res" %}
7856 ins_encode %{
7857 __ lock();
7858 __ cmpxchgw($newval$$Register, $mem_ptr$$Address);
7859 __ sete($res$$Register);
7860 __ movzbl($res$$Register, $res$$Register);
7861 %}
7862 ins_pipe( pipe_cmpxchg );
7863 %}
7864
7865 instruct compareAndSwapN(rRegI res,
7866 memory mem_ptr,
7867 rax_RegN oldval, rRegN newval,
7868 rFlagsReg cr) %{
7869 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7870 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval)));
7871 effect(KILL cr, KILL oldval);
7872
7873 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7874 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7875 "sete $res\n\t"
7876 "movzbl $res, $res" %}
7877 ins_encode %{
7878 __ lock();
7879 __ cmpxchgl($newval$$Register, $mem_ptr$$Address);
7880 __ sete($res$$Register);
7881 __ movzbl($res$$Register, $res$$Register);
7882 %}
7883 ins_pipe( pipe_cmpxchg );
7884 %}
7885
7886 instruct compareAndExchangeB(
7887 memory mem_ptr,
7888 rax_RegI oldval, rRegI newval,
7889 rFlagsReg cr)
7890 %{
7891 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval)));
7892 effect(KILL cr);
7893
7894 format %{ "cmpxchgb $mem_ptr,$newval\t# "
7895 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7896 ins_encode %{
7897 __ lock();
7898 __ cmpxchgb($newval$$Register, $mem_ptr$$Address);
7899 %}
7900 ins_pipe( pipe_cmpxchg );
7901 %}
7902
7903 instruct compareAndExchangeS(
7904 memory mem_ptr,
7905 rax_RegI oldval, rRegI newval,
7906 rFlagsReg cr)
7907 %{
7908 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval)));
7909 effect(KILL cr);
7910
7911 format %{ "cmpxchgw $mem_ptr,$newval\t# "
7912 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7913 ins_encode %{
7914 __ lock();
7915 __ cmpxchgw($newval$$Register, $mem_ptr$$Address);
7916 %}
7917 ins_pipe( pipe_cmpxchg );
7918 %}
7919
7920 instruct compareAndExchangeI(
7921 memory mem_ptr,
7922 rax_RegI oldval, rRegI newval,
7923 rFlagsReg cr)
7924 %{
7925 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval)));
7926 effect(KILL cr);
7927
7928 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7929 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7930 ins_encode %{
7931 __ lock();
7932 __ cmpxchgl($newval$$Register, $mem_ptr$$Address);
7933 %}
7934 ins_pipe( pipe_cmpxchg );
7935 %}
7936
7937 instruct compareAndExchangeL(
7938 memory mem_ptr,
7939 rax_RegL oldval, rRegL newval,
7940 rFlagsReg cr)
7941 %{
7942 predicate(VM_Version::supports_cx8());
7943 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval)));
7944 effect(KILL cr);
7945
7946 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7947 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7948 ins_encode %{
7949 __ lock();
7950 __ cmpxchgq($newval$$Register, $mem_ptr$$Address);
7951 %}
7952 ins_pipe( pipe_cmpxchg );
7953 %}
7954
7955 instruct compareAndExchangeN(
7956 memory mem_ptr,
7957 rax_RegN oldval, rRegN newval,
7958 rFlagsReg cr) %{
7959 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval)));
7960 effect(KILL cr);
7961
7962 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7963 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7964 ins_encode %{
7965 __ lock();
7966 __ cmpxchgl($newval$$Register, $mem_ptr$$Address);
7967 %}
7968 ins_pipe( pipe_cmpxchg );
7969 %}
7970
7971 instruct compareAndExchangeP(
7972 memory mem_ptr,
7973 rax_RegP oldval, rRegP newval,
7974 rFlagsReg cr)
7975 %{
7976 predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0);
7977 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
7978 effect(KILL cr);
7979
7980 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7981 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7982 ins_encode %{
7983 __ lock();
7984 __ cmpxchgq($newval$$Register, $mem_ptr$$Address);
7985 %}
7986 ins_pipe( pipe_cmpxchg );
7987 %}
7988
7989 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
7990 predicate(n->as_LoadStore()->result_not_used());
7991 match(Set dummy (GetAndAddB mem add));
7992 effect(KILL cr);
7993 format %{ "ADDB [$mem],$add" %}
7994 ins_encode %{
7995 __ lock();
7996 __ addb($mem$$Address, $add$$constant);
7997 %}
7998 ins_pipe( pipe_cmpxchg );
7999 %}
8000
8001 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{
8002 match(Set newval (GetAndAddB mem newval));
8003 effect(KILL cr);
8004 format %{ "XADDB [$mem],$newval" %}
8005 ins_encode %{
8006 __ lock();
8007 __ xaddb($mem$$Address, $newval$$Register);
8008 %}
8009 ins_pipe( pipe_cmpxchg );
8010 %}
8011
8012 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
8013 predicate(n->as_LoadStore()->result_not_used());
8014 match(Set dummy (GetAndAddS mem add));
8015 effect(KILL cr);
8016 format %{ "ADDW [$mem],$add" %}
8017 ins_encode %{
8018 __ lock();
8019 __ addw($mem$$Address, $add$$constant);
8020 %}
8021 ins_pipe( pipe_cmpxchg );
8022 %}
8023
8024 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{
8025 match(Set newval (GetAndAddS mem newval));
8026 effect(KILL cr);
8027 format %{ "XADDW [$mem],$newval" %}
8028 ins_encode %{
8029 __ lock();
8030 __ xaddw($mem$$Address, $newval$$Register);
8031 %}
8032 ins_pipe( pipe_cmpxchg );
8033 %}
8034
8035 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
8036 predicate(n->as_LoadStore()->result_not_used());
8037 match(Set dummy (GetAndAddI mem add));
8038 effect(KILL cr);
8039 format %{ "ADDL [$mem],$add" %}
8040 ins_encode %{
8041 __ lock();
8042 __ addl($mem$$Address, $add$$constant);
8043 %}
8044 ins_pipe( pipe_cmpxchg );
8045 %}
8046
8047 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{
8048 match(Set newval (GetAndAddI mem newval));
8049 effect(KILL cr);
8050 format %{ "XADDL [$mem],$newval" %}
8051 ins_encode %{
8052 __ lock();
8053 __ xaddl($mem$$Address, $newval$$Register);
8054 %}
8055 ins_pipe( pipe_cmpxchg );
8056 %}
8057
8058 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{
8059 predicate(n->as_LoadStore()->result_not_used());
8060 match(Set dummy (GetAndAddL mem add));
8061 effect(KILL cr);
8062 format %{ "ADDQ [$mem],$add" %}
8063 ins_encode %{
8064 __ lock();
8065 __ addq($mem$$Address, $add$$constant);
8066 %}
8067 ins_pipe( pipe_cmpxchg );
8068 %}
8069
8070 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{
8071 match(Set newval (GetAndAddL mem newval));
8072 effect(KILL cr);
8073 format %{ "XADDQ [$mem],$newval" %}
8074 ins_encode %{
8075 __ lock();
8076 __ xaddq($mem$$Address, $newval$$Register);
8077 %}
8078 ins_pipe( pipe_cmpxchg );
8079 %}
8080
8081 instruct xchgB( memory mem, rRegI newval) %{
8082 match(Set newval (GetAndSetB mem newval));
8083 format %{ "XCHGB $newval,[$mem]" %}
8084 ins_encode %{
8085 __ xchgb($newval$$Register, $mem$$Address);
8086 %}
8087 ins_pipe( pipe_cmpxchg );
8088 %}
8089
8090 instruct xchgS( memory mem, rRegI newval) %{
8091 match(Set newval (GetAndSetS mem newval));
8092 format %{ "XCHGW $newval,[$mem]" %}
8093 ins_encode %{
8094 __ xchgw($newval$$Register, $mem$$Address);
8095 %}
8096 ins_pipe( pipe_cmpxchg );
8097 %}
8098
8099 instruct xchgI( memory mem, rRegI newval) %{
8100 match(Set newval (GetAndSetI mem newval));
8101 format %{ "XCHGL $newval,[$mem]" %}
8102 ins_encode %{
8103 __ xchgl($newval$$Register, $mem$$Address);
8104 %}
8105 ins_pipe( pipe_cmpxchg );
8106 %}
8107
8108 instruct xchgL( memory mem, rRegL newval) %{
8109 match(Set newval (GetAndSetL mem newval));
8110 format %{ "XCHGL $newval,[$mem]" %}
8111 ins_encode %{
8112 __ xchgq($newval$$Register, $mem$$Address);
8113 %}
8114 ins_pipe( pipe_cmpxchg );
8115 %}
8116
8117 instruct xchgP( memory mem, rRegP newval) %{
8118 match(Set newval (GetAndSetP mem newval));
8119 predicate(n->as_LoadStore()->barrier_data() == 0);
8120 format %{ "XCHGQ $newval,[$mem]" %}
8121 ins_encode %{
8122 __ xchgq($newval$$Register, $mem$$Address);
8123 %}
8124 ins_pipe( pipe_cmpxchg );
8125 %}
8126
8127 instruct xchgN( memory mem, rRegN newval) %{
8128 match(Set newval (GetAndSetN mem newval));
8129 format %{ "XCHGL $newval,$mem]" %}
8130 ins_encode %{
8131 __ xchgl($newval$$Register, $mem$$Address);
8132 %}
8133 ins_pipe( pipe_cmpxchg );
8134 %}
8135
8136 //----------Abs Instructions-------------------------------------------
8137
8138 // Integer Absolute Instructions
8139 instruct absI_rReg(rRegI dst, rRegI src, rRegI tmp, rFlagsReg cr)
8140 %{
8141 match(Set dst (AbsI src));
8142 effect(TEMP dst, TEMP tmp, KILL cr);
8143 format %{ "movl $tmp, $src\n\t"
8144 "sarl $tmp, 31\n\t"
8145 "movl $dst, $src\n\t"
8146 "xorl $dst, $tmp\n\t"
8147 "subl $dst, $tmp\n"
8148 %}
8149 ins_encode %{
8150 __ movl($tmp$$Register, $src$$Register);
8151 __ sarl($tmp$$Register, 31);
8152 __ movl($dst$$Register, $src$$Register);
8153 __ xorl($dst$$Register, $tmp$$Register);
8154 __ subl($dst$$Register, $tmp$$Register);
8155 %}
8156
8157 ins_pipe(ialu_reg_reg);
8158 %}
8159
8160 // Long Absolute Instructions
8161 instruct absL_rReg(rRegL dst, rRegL src, rRegL tmp, rFlagsReg cr)
8162 %{
8163 match(Set dst (AbsL src));
8164 effect(TEMP dst, TEMP tmp, KILL cr);
8165 format %{ "movq $tmp, $src\n\t"
8166 "sarq $tmp, 63\n\t"
8167 "movq $dst, $src\n\t"
8168 "xorq $dst, $tmp\n\t"
8169 "subq $dst, $tmp\n"
8170 %}
8171 ins_encode %{
8172 __ movq($tmp$$Register, $src$$Register);
8173 __ sarq($tmp$$Register, 63);
8174 __ movq($dst$$Register, $src$$Register);
8175 __ xorq($dst$$Register, $tmp$$Register);
8176 __ subq($dst$$Register, $tmp$$Register);
8177 %}
8178
8179 ins_pipe(ialu_reg_reg);
8180 %}
8181
8182 //----------Subtraction Instructions-------------------------------------------
8183
8184 // Integer Subtraction Instructions
8185 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8186 %{
8187 match(Set dst (SubI dst src));
8188 effect(KILL cr);
8189
8190 format %{ "subl $dst, $src\t# int" %}
8191 ins_encode %{
8192 __ subl($dst$$Register, $src$$Register);
8193 %}
8194 ins_pipe(ialu_reg_reg);
8195 %}
8196
8197 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8198 %{
8199 match(Set dst (SubI dst src));
8200 effect(KILL cr);
8201
8202 format %{ "subl $dst, $src\t# int" %}
8203 ins_encode %{
8204 __ subl($dst$$Register, $src$$constant);
8205 %}
8206 ins_pipe(ialu_reg);
8207 %}
8208
8209 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8210 %{
8211 match(Set dst (SubI dst (LoadI src)));
8212 effect(KILL cr);
8213
8214 ins_cost(125);
8215 format %{ "subl $dst, $src\t# int" %}
8216 ins_encode %{
8217 __ subl($dst$$Register, $src$$Address);
8218 %}
8219 ins_pipe(ialu_reg_mem);
8220 %}
8221
8222 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8223 %{
8224 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
8225 effect(KILL cr);
8226
8227 ins_cost(150);
8228 format %{ "subl $dst, $src\t# int" %}
8229 ins_encode %{
8230 __ subl($dst$$Address, $src$$Register);
8231 %}
8232 ins_pipe(ialu_mem_reg);
8233 %}
8234
8235 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr)
8236 %{
8237 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
8238 effect(KILL cr);
8239
8240 ins_cost(125); // XXX
8241 format %{ "subl $dst, $src\t# int" %}
8242 ins_encode %{
8243 __ subl($dst$$Address, $src$$constant);
8244 %}
8245 ins_pipe(ialu_mem_imm);
8246 %}
8247
8248 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8249 %{
8250 match(Set dst (SubL dst src));
8251 effect(KILL cr);
8252
8253 format %{ "subq $dst, $src\t# long" %}
8254 ins_encode %{
8255 __ subq($dst$$Register, $src$$Register);
8256 %}
8257 ins_pipe(ialu_reg_reg);
8258 %}
8259
8260 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr)
8261 %{
8262 match(Set dst (SubL dst src));
8263 effect(KILL cr);
8264
8265 format %{ "subq $dst, $src\t# long" %}
8266 ins_encode %{
8267 __ subq($dst$$Register, $src$$constant);
8268 %}
8269 ins_pipe(ialu_reg);
8270 %}
8271
8272 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
8273 %{
8274 match(Set dst (SubL dst (LoadL src)));
8275 effect(KILL cr);
8276
8277 ins_cost(125);
8278 format %{ "subq $dst, $src\t# long" %}
8279 ins_encode %{
8280 __ subq($dst$$Register, $src$$Address);
8281 %}
8282 ins_pipe(ialu_reg_mem);
8283 %}
8284
8285 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
8286 %{
8287 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
8288 effect(KILL cr);
8289
8290 ins_cost(150);
8291 format %{ "subq $dst, $src\t# long" %}
8292 ins_encode %{
8293 __ subq($dst$$Address, $src$$Register);
8294 %}
8295 ins_pipe(ialu_mem_reg);
8296 %}
8297
8298 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
8299 %{
8300 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
8301 effect(KILL cr);
8302
8303 ins_cost(125); // XXX
8304 format %{ "subq $dst, $src\t# long" %}
8305 ins_encode %{
8306 __ subq($dst$$Address, $src$$constant);
8307 %}
8308 ins_pipe(ialu_mem_imm);
8309 %}
8310
8311 // Subtract from a pointer
8312 // XXX hmpf???
8313 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr)
8314 %{
8315 match(Set dst (AddP dst (SubI zero src)));
8316 effect(KILL cr);
8317
8318 format %{ "subq $dst, $src\t# ptr - int" %}
8319 opcode(0x2B);
8320 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8321 ins_pipe(ialu_reg_reg);
8322 %}
8323
8324 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr)
8325 %{
8326 match(Set dst (SubI zero dst));
8327 effect(KILL cr);
8328
8329 format %{ "negl $dst\t# int" %}
8330 ins_encode %{
8331 __ negl($dst$$Register);
8332 %}
8333 ins_pipe(ialu_reg);
8334 %}
8335
8336 instruct negI_rReg_2(rRegI dst, rFlagsReg cr)
8337 %{
8338 match(Set dst (NegI dst));
8339 effect(KILL cr);
8340
8341 format %{ "negl $dst\t# int" %}
8342 ins_encode %{
8343 __ negl($dst$$Register);
8344 %}
8345 ins_pipe(ialu_reg);
8346 %}
8347
8348 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr)
8349 %{
8350 match(Set dst (StoreI dst (SubI zero (LoadI dst))));
8351 effect(KILL cr);
8352
8353 format %{ "negl $dst\t# int" %}
8354 ins_encode %{
8355 __ negl($dst$$Address);
8356 %}
8357 ins_pipe(ialu_reg);
8358 %}
8359
8360 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr)
8361 %{
8362 match(Set dst (SubL zero dst));
8363 effect(KILL cr);
8364
8365 format %{ "negq $dst\t# long" %}
8366 ins_encode %{
8367 __ negq($dst$$Register);
8368 %}
8369 ins_pipe(ialu_reg);
8370 %}
8371
8372 instruct negL_rReg_2(rRegL dst, rFlagsReg cr)
8373 %{
8374 match(Set dst (NegL dst));
8375 effect(KILL cr);
8376
8377 format %{ "negq $dst\t# int" %}
8378 ins_encode %{
8379 __ negq($dst$$Register);
8380 %}
8381 ins_pipe(ialu_reg);
8382 %}
8383
8384 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr)
8385 %{
8386 match(Set dst (StoreL dst (SubL zero (LoadL dst))));
8387 effect(KILL cr);
8388
8389 format %{ "negq $dst\t# long" %}
8390 ins_encode %{
8391 __ negq($dst$$Address);
8392 %}
8393 ins_pipe(ialu_reg);
8394 %}
8395
8396 //----------Multiplication/Division Instructions-------------------------------
8397 // Integer Multiplication Instructions
8398 // Multiply Register
8399
8400 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8401 %{
8402 match(Set dst (MulI dst src));
8403 effect(KILL cr);
8404
8405 ins_cost(300);
8406 format %{ "imull $dst, $src\t# int" %}
8407 ins_encode %{
8408 __ imull($dst$$Register, $src$$Register);
8409 %}
8410 ins_pipe(ialu_reg_reg_alu0);
8411 %}
8412
8413 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr)
8414 %{
8415 match(Set dst (MulI src imm));
8416 effect(KILL cr);
8417
8418 ins_cost(300);
8419 format %{ "imull $dst, $src, $imm\t# int" %}
8420 ins_encode %{
8421 __ imull($dst$$Register, $src$$Register, $imm$$constant);
8422 %}
8423 ins_pipe(ialu_reg_reg_alu0);
8424 %}
8425
8426 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr)
8427 %{
8428 match(Set dst (MulI dst (LoadI src)));
8429 effect(KILL cr);
8430
8431 ins_cost(350);
8432 format %{ "imull $dst, $src\t# int" %}
8433 ins_encode %{
8434 __ imull($dst$$Register, $src$$Address);
8435 %}
8436 ins_pipe(ialu_reg_mem_alu0);
8437 %}
8438
8439 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr)
8440 %{
8441 match(Set dst (MulI (LoadI src) imm));
8442 effect(KILL cr);
8443
8444 ins_cost(300);
8445 format %{ "imull $dst, $src, $imm\t# int" %}
8446 ins_encode %{
8447 __ imull($dst$$Register, $src$$Address, $imm$$constant);
8448 %}
8449 ins_pipe(ialu_reg_mem_alu0);
8450 %}
8451
8452 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr)
8453 %{
8454 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3)));
8455 effect(KILL cr, KILL src2);
8456
8457 expand %{ mulI_rReg(dst, src1, cr);
8458 mulI_rReg(src2, src3, cr);
8459 addI_rReg(dst, src2, cr); %}
8460 %}
8461
8462 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8463 %{
8464 match(Set dst (MulL dst src));
8465 effect(KILL cr);
8466
8467 ins_cost(300);
8468 format %{ "imulq $dst, $src\t# long" %}
8469 ins_encode %{
8470 __ imulq($dst$$Register, $src$$Register);
8471 %}
8472 ins_pipe(ialu_reg_reg_alu0);
8473 %}
8474
8475 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr)
8476 %{
8477 match(Set dst (MulL src imm));
8478 effect(KILL cr);
8479
8480 ins_cost(300);
8481 format %{ "imulq $dst, $src, $imm\t# long" %}
8482 ins_encode %{
8483 __ imulq($dst$$Register, $src$$Register, $imm$$constant);
8484 %}
8485 ins_pipe(ialu_reg_reg_alu0);
8486 %}
8487
8488 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr)
8489 %{
8490 match(Set dst (MulL dst (LoadL src)));
8491 effect(KILL cr);
8492
8493 ins_cost(350);
8494 format %{ "imulq $dst, $src\t# long" %}
8495 ins_encode %{
8496 __ imulq($dst$$Register, $src$$Address);
8497 %}
8498 ins_pipe(ialu_reg_mem_alu0);
8499 %}
8500
8501 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr)
8502 %{
8503 match(Set dst (MulL (LoadL src) imm));
8504 effect(KILL cr);
8505
8506 ins_cost(300);
8507 format %{ "imulq $dst, $src, $imm\t# long" %}
8508 ins_encode %{
8509 __ imulq($dst$$Register, $src$$Address, $imm$$constant);
8510 %}
8511 ins_pipe(ialu_reg_mem_alu0);
8512 %}
8513
8514 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8515 %{
8516 match(Set dst (MulHiL src rax));
8517 effect(USE_KILL rax, KILL cr);
8518
8519 ins_cost(300);
8520 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %}
8521 ins_encode %{
8522 __ imulq($src$$Register);
8523 %}
8524 ins_pipe(ialu_reg_reg_alu0);
8525 %}
8526
8527 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8528 rFlagsReg cr)
8529 %{
8530 match(Set rax (DivI rax div));
8531 effect(KILL rdx, KILL cr);
8532
8533 ins_cost(30*100+10*100); // XXX
8534 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
8535 "jne,s normal\n\t"
8536 "xorl rdx, rdx\n\t"
8537 "cmpl $div, -1\n\t"
8538 "je,s done\n"
8539 "normal: cdql\n\t"
8540 "idivl $div\n"
8541 "done:" %}
8542 ins_encode(cdql_enc(div));
8543 ins_pipe(ialu_reg_reg_alu0);
8544 %}
8545
8546 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8547 rFlagsReg cr)
8548 %{
8549 match(Set rax (DivL rax div));
8550 effect(KILL rdx, KILL cr);
8551
8552 ins_cost(30*100+10*100); // XXX
8553 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8554 "cmpq rax, rdx\n\t"
8555 "jne,s normal\n\t"
8556 "xorl rdx, rdx\n\t"
8557 "cmpq $div, -1\n\t"
8558 "je,s done\n"
8559 "normal: cdqq\n\t"
8560 "idivq $div\n"
8561 "done:" %}
8562 ins_encode(cdqq_enc(div));
8563 ins_pipe(ialu_reg_reg_alu0);
8564 %}
8565
8566 // Integer DIVMOD with Register, both quotient and mod results
8567 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8568 rFlagsReg cr)
8569 %{
8570 match(DivModI rax div);
8571 effect(KILL cr);
8572
8573 ins_cost(30*100+10*100); // XXX
8574 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
8575 "jne,s normal\n\t"
8576 "xorl rdx, rdx\n\t"
8577 "cmpl $div, -1\n\t"
8578 "je,s done\n"
8579 "normal: cdql\n\t"
8580 "idivl $div\n"
8581 "done:" %}
8582 ins_encode(cdql_enc(div));
8583 ins_pipe(pipe_slow);
8584 %}
8585
8586 // Long DIVMOD with Register, both quotient and mod results
8587 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8588 rFlagsReg cr)
8589 %{
8590 match(DivModL rax div);
8591 effect(KILL cr);
8592
8593 ins_cost(30*100+10*100); // XXX
8594 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8595 "cmpq rax, rdx\n\t"
8596 "jne,s normal\n\t"
8597 "xorl rdx, rdx\n\t"
8598 "cmpq $div, -1\n\t"
8599 "je,s done\n"
8600 "normal: cdqq\n\t"
8601 "idivq $div\n"
8602 "done:" %}
8603 ins_encode(cdqq_enc(div));
8604 ins_pipe(pipe_slow);
8605 %}
8606
8607 //----------- DivL-By-Constant-Expansions--------------------------------------
8608 // DivI cases are handled by the compiler
8609
8610 // Magic constant, reciprocal of 10
8611 instruct loadConL_0x6666666666666667(rRegL dst)
8612 %{
8613 effect(DEF dst);
8614
8615 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %}
8616 ins_encode(load_immL(dst, 0x6666666666666667));
8617 ins_pipe(ialu_reg);
8618 %}
8619
8620 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8621 %{
8622 effect(DEF dst, USE src, USE_KILL rax, KILL cr);
8623
8624 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %}
8625 ins_encode %{
8626 __ imulq($src$$Register);
8627 %}
8628 ins_pipe(ialu_reg_reg_alu0);
8629 %}
8630
8631 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr)
8632 %{
8633 effect(USE_DEF dst, KILL cr);
8634
8635 format %{ "sarq $dst, #63\t# Used in div-by-10" %}
8636 ins_encode %{
8637 __ sarq($dst$$Register, 63);
8638 %}
8639 ins_pipe(ialu_reg);
8640 %}
8641
8642 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr)
8643 %{
8644 effect(USE_DEF dst, KILL cr);
8645
8646 format %{ "sarq $dst, #2\t# Used in div-by-10" %}
8647 ins_encode %{
8648 __ sarq($dst$$Register, 2);
8649 %}
8650 ins_pipe(ialu_reg);
8651 %}
8652
8653 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div)
8654 %{
8655 match(Set dst (DivL src div));
8656
8657 ins_cost((5+8)*100);
8658 expand %{
8659 rax_RegL rax; // Killed temp
8660 rFlagsReg cr; // Killed
8661 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667
8662 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src
8663 sarL_rReg_63(src, cr); // sarq src, 63
8664 sarL_rReg_2(dst, cr); // sarq rdx, 2
8665 subL_rReg(dst, src, cr); // subl rdx, src
8666 %}
8667 %}
8668
8669 //-----------------------------------------------------------------------------
8670
8671 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div,
8672 rFlagsReg cr)
8673 %{
8674 match(Set rdx (ModI rax div));
8675 effect(KILL rax, KILL cr);
8676
8677 ins_cost(300); // XXX
8678 format %{ "cmpl rax, 0x80000000\t# irem\n\t"
8679 "jne,s normal\n\t"
8680 "xorl rdx, rdx\n\t"
8681 "cmpl $div, -1\n\t"
8682 "je,s done\n"
8683 "normal: cdql\n\t"
8684 "idivl $div\n"
8685 "done:" %}
8686 ins_encode(cdql_enc(div));
8687 ins_pipe(ialu_reg_reg_alu0);
8688 %}
8689
8690 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div,
8691 rFlagsReg cr)
8692 %{
8693 match(Set rdx (ModL rax div));
8694 effect(KILL rax, KILL cr);
8695
8696 ins_cost(300); // XXX
8697 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t"
8698 "cmpq rax, rdx\n\t"
8699 "jne,s normal\n\t"
8700 "xorl rdx, rdx\n\t"
8701 "cmpq $div, -1\n\t"
8702 "je,s done\n"
8703 "normal: cdqq\n\t"
8704 "idivq $div\n"
8705 "done:" %}
8706 ins_encode(cdqq_enc(div));
8707 ins_pipe(ialu_reg_reg_alu0);
8708 %}
8709
8710 // Integer Shift Instructions
8711 // Shift Left by one
8712 instruct salI_rReg_1(rRegI dst, immI_1 shift, rFlagsReg cr)
8713 %{
8714 match(Set dst (LShiftI dst shift));
8715 effect(KILL cr);
8716
8717 format %{ "sall $dst, $shift" %}
8718 ins_encode %{
8719 __ sall($dst$$Register, $shift$$constant);
8720 %}
8721 ins_pipe(ialu_reg);
8722 %}
8723
8724 // Shift Left by one
8725 instruct salI_mem_1(memory dst, immI_1 shift, rFlagsReg cr)
8726 %{
8727 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8728 effect(KILL cr);
8729
8730 format %{ "sall $dst, $shift\t" %}
8731 ins_encode %{
8732 __ sall($dst$$Address, $shift$$constant);
8733 %}
8734 ins_pipe(ialu_mem_imm);
8735 %}
8736
8737 // Shift Left by 8-bit immediate
8738 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8739 %{
8740 match(Set dst (LShiftI dst shift));
8741 effect(KILL cr);
8742
8743 format %{ "sall $dst, $shift" %}
8744 ins_encode %{
8745 __ sall($dst$$Register, $shift$$constant);
8746 %}
8747 ins_pipe(ialu_reg);
8748 %}
8749
8750 // Shift Left by 8-bit immediate
8751 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8752 %{
8753 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8754 effect(KILL cr);
8755
8756 format %{ "sall $dst, $shift" %}
8757 ins_encode %{
8758 __ sall($dst$$Address, $shift$$constant);
8759 %}
8760 ins_pipe(ialu_mem_imm);
8761 %}
8762
8763 // Shift Left by variable
8764 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8765 %{
8766 match(Set dst (LShiftI dst shift));
8767 effect(KILL cr);
8768
8769 format %{ "sall $dst, $shift" %}
8770 ins_encode %{
8771 __ sall($dst$$Register);
8772 %}
8773 ins_pipe(ialu_reg_reg);
8774 %}
8775
8776 // Shift Left by variable
8777 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8778 %{
8779 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8780 effect(KILL cr);
8781
8782 format %{ "sall $dst, $shift" %}
8783 ins_encode %{
8784 __ sall($dst$$Address);
8785 %}
8786 ins_pipe(ialu_mem_reg);
8787 %}
8788
8789 // Arithmetic shift right by one
8790 instruct sarI_rReg_1(rRegI dst, immI_1 shift, rFlagsReg cr)
8791 %{
8792 match(Set dst (RShiftI dst shift));
8793 effect(KILL cr);
8794
8795 format %{ "sarl $dst, $shift" %}
8796 ins_encode %{
8797 __ sarl($dst$$Register, $shift$$constant);
8798 %}
8799 ins_pipe(ialu_reg);
8800 %}
8801
8802 // Arithmetic shift right by one
8803 instruct sarI_mem_1(memory dst, immI_1 shift, rFlagsReg cr)
8804 %{
8805 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8806 effect(KILL cr);
8807
8808 format %{ "sarl $dst, $shift" %}
8809 ins_encode %{
8810 __ sarl($dst$$Address, $shift$$constant);
8811 %}
8812 ins_pipe(ialu_mem_imm);
8813 %}
8814
8815 // Arithmetic Shift Right by 8-bit immediate
8816 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8817 %{
8818 match(Set dst (RShiftI dst shift));
8819 effect(KILL cr);
8820
8821 format %{ "sarl $dst, $shift" %}
8822 ins_encode %{
8823 __ sarl($dst$$Register, $shift$$constant);
8824 %}
8825 ins_pipe(ialu_mem_imm);
8826 %}
8827
8828 // Arithmetic Shift Right by 8-bit immediate
8829 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8830 %{
8831 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8832 effect(KILL cr);
8833
8834 format %{ "sarl $dst, $shift" %}
8835 ins_encode %{
8836 __ sarl($dst$$Address, $shift$$constant);
8837 %}
8838 ins_pipe(ialu_mem_imm);
8839 %}
8840
8841 // Arithmetic Shift Right by variable
8842 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8843 %{
8844 match(Set dst (RShiftI dst shift));
8845 effect(KILL cr);
8846 format %{ "sarl $dst, $shift" %}
8847 ins_encode %{
8848 __ sarl($dst$$Register);
8849 %}
8850 ins_pipe(ialu_reg_reg);
8851 %}
8852
8853 // Arithmetic Shift Right by variable
8854 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8855 %{
8856 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8857 effect(KILL cr);
8858
8859 format %{ "sarl $dst, $shift" %}
8860 ins_encode %{
8861 __ sarl($dst$$Address);
8862 %}
8863 ins_pipe(ialu_mem_reg);
8864 %}
8865
8866 // Logical shift right by one
8867 instruct shrI_rReg_1(rRegI dst, immI_1 shift, rFlagsReg cr)
8868 %{
8869 match(Set dst (URShiftI dst shift));
8870 effect(KILL cr);
8871
8872 format %{ "shrl $dst, $shift" %}
8873 ins_encode %{
8874 __ shrl($dst$$Register, $shift$$constant);
8875 %}
8876 ins_pipe(ialu_reg);
8877 %}
8878
8879 // Logical shift right by one
8880 instruct shrI_mem_1(memory dst, immI_1 shift, rFlagsReg cr)
8881 %{
8882 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8883 effect(KILL cr);
8884
8885 format %{ "shrl $dst, $shift" %}
8886 ins_encode %{
8887 __ shrl($dst$$Address, $shift$$constant);
8888 %}
8889 ins_pipe(ialu_mem_imm);
8890 %}
8891
8892 // Logical Shift Right by 8-bit immediate
8893 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8894 %{
8895 match(Set dst (URShiftI dst shift));
8896 effect(KILL cr);
8897
8898 format %{ "shrl $dst, $shift" %}
8899 ins_encode %{
8900 __ shrl($dst$$Register, $shift$$constant);
8901 %}
8902 ins_pipe(ialu_reg);
8903 %}
8904
8905 // Logical Shift Right by 8-bit immediate
8906 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8907 %{
8908 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8909 effect(KILL cr);
8910
8911 format %{ "shrl $dst, $shift" %}
8912 ins_encode %{
8913 __ shrl($dst$$Address, $shift$$constant);
8914 %}
8915 ins_pipe(ialu_mem_imm);
8916 %}
8917
8918 // Logical Shift Right by variable
8919 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8920 %{
8921 match(Set dst (URShiftI dst shift));
8922 effect(KILL cr);
8923
8924 format %{ "shrl $dst, $shift" %}
8925 ins_encode %{
8926 __ shrl($dst$$Register);
8927 %}
8928 ins_pipe(ialu_reg_reg);
8929 %}
8930
8931 // Logical Shift Right by variable
8932 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8933 %{
8934 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8935 effect(KILL cr);
8936
8937 format %{ "shrl $dst, $shift" %}
8938 ins_encode %{
8939 __ shrl($dst$$Address);
8940 %}
8941 ins_pipe(ialu_mem_reg);
8942 %}
8943
8944 // Long Shift Instructions
8945 // Shift Left by one
8946 instruct salL_rReg_1(rRegL dst, immI_1 shift, rFlagsReg cr)
8947 %{
8948 match(Set dst (LShiftL dst shift));
8949 effect(KILL cr);
8950
8951 format %{ "salq $dst, $shift" %}
8952 ins_encode %{
8953 __ salq($dst$$Register, $shift$$constant);
8954 %}
8955 ins_pipe(ialu_reg);
8956 %}
8957
8958 // Shift Left by one
8959 instruct salL_mem_1(memory dst, immI_1 shift, rFlagsReg cr)
8960 %{
8961 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8962 effect(KILL cr);
8963
8964 format %{ "salq $dst, $shift" %}
8965 ins_encode %{
8966 __ salq($dst$$Address, $shift$$constant);
8967 %}
8968 ins_pipe(ialu_mem_imm);
8969 %}
8970
8971 // Shift Left by 8-bit immediate
8972 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8973 %{
8974 match(Set dst (LShiftL dst shift));
8975 effect(KILL cr);
8976
8977 format %{ "salq $dst, $shift" %}
8978 ins_encode %{
8979 __ salq($dst$$Register, $shift$$constant);
8980 %}
8981 ins_pipe(ialu_reg);
8982 %}
8983
8984 // Shift Left by 8-bit immediate
8985 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8986 %{
8987 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8988 effect(KILL cr);
8989
8990 format %{ "salq $dst, $shift" %}
8991 ins_encode %{
8992 __ salq($dst$$Address, $shift$$constant);
8993 %}
8994 ins_pipe(ialu_mem_imm);
8995 %}
8996
8997 // Shift Left by variable
8998 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8999 %{
9000 match(Set dst (LShiftL dst shift));
9001 effect(KILL cr);
9002
9003 format %{ "salq $dst, $shift" %}
9004 ins_encode %{
9005 __ salq($dst$$Register);
9006 %}
9007 ins_pipe(ialu_reg_reg);
9008 %}
9009
9010 // Shift Left by variable
9011 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9012 %{
9013 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
9014 effect(KILL cr);
9015
9016 format %{ "salq $dst, $shift" %}
9017 ins_encode %{
9018 __ salq($dst$$Address);
9019 %}
9020 ins_pipe(ialu_mem_reg);
9021 %}
9022
9023 // Arithmetic shift right by one
9024 instruct sarL_rReg_1(rRegL dst, immI_1 shift, rFlagsReg cr)
9025 %{
9026 match(Set dst (RShiftL dst shift));
9027 effect(KILL cr);
9028
9029 format %{ "sarq $dst, $shift" %}
9030 ins_encode %{
9031 __ sarq($dst$$Register, $shift$$constant);
9032 %}
9033 ins_pipe(ialu_reg);
9034 %}
9035
9036 // Arithmetic shift right by one
9037 instruct sarL_mem_1(memory dst, immI_1 shift, rFlagsReg cr)
9038 %{
9039 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
9040 effect(KILL cr);
9041
9042 format %{ "sarq $dst, $shift" %}
9043 ins_encode %{
9044 __ sarq($dst$$Address, $shift$$constant);
9045 %}
9046 ins_pipe(ialu_mem_imm);
9047 %}
9048
9049 // Arithmetic Shift Right by 8-bit immediate
9050 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
9051 %{
9052 match(Set dst (RShiftL dst shift));
9053 effect(KILL cr);
9054
9055 format %{ "sarq $dst, $shift" %}
9056 ins_encode %{
9057 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F));
9058 %}
9059 ins_pipe(ialu_mem_imm);
9060 %}
9061
9062 // Arithmetic Shift Right by 8-bit immediate
9063 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9064 %{
9065 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
9066 effect(KILL cr);
9067
9068 format %{ "sarq $dst, $shift" %}
9069 ins_encode %{
9070 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F));
9071 %}
9072 ins_pipe(ialu_mem_imm);
9073 %}
9074
9075 // Arithmetic Shift Right by variable
9076 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
9077 %{
9078 match(Set dst (RShiftL dst shift));
9079 effect(KILL cr);
9080
9081 format %{ "sarq $dst, $shift" %}
9082 ins_encode %{
9083 __ sarq($dst$$Register);
9084 %}
9085 ins_pipe(ialu_reg_reg);
9086 %}
9087
9088 // Arithmetic Shift Right by variable
9089 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9090 %{
9091 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
9092 effect(KILL cr);
9093
9094 format %{ "sarq $dst, $shift" %}
9095 ins_encode %{
9096 __ sarq($dst$$Address);
9097 %}
9098 ins_pipe(ialu_mem_reg);
9099 %}
9100
9101 // Logical shift right by one
9102 instruct shrL_rReg_1(rRegL dst, immI_1 shift, rFlagsReg cr)
9103 %{
9104 match(Set dst (URShiftL dst shift));
9105 effect(KILL cr);
9106
9107 format %{ "shrq $dst, $shift" %}
9108 ins_encode %{
9109 __ shrq($dst$$Register, $shift$$constant);
9110 %}
9111 ins_pipe(ialu_reg);
9112 %}
9113
9114 // Logical shift right by one
9115 instruct shrL_mem_1(memory dst, immI_1 shift, rFlagsReg cr)
9116 %{
9117 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
9118 effect(KILL cr);
9119
9120 format %{ "shrq $dst, $shift" %}
9121 ins_encode %{
9122 __ shrq($dst$$Address, $shift$$constant);
9123 %}
9124 ins_pipe(ialu_mem_imm);
9125 %}
9126
9127 // Logical Shift Right by 8-bit immediate
9128 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
9129 %{
9130 match(Set dst (URShiftL dst shift));
9131 effect(KILL cr);
9132
9133 format %{ "shrq $dst, $shift" %}
9134 ins_encode %{
9135 __ shrq($dst$$Register, $shift$$constant);
9136 %}
9137 ins_pipe(ialu_reg);
9138 %}
9139
9140 // Logical Shift Right by 8-bit immediate
9141 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9142 %{
9143 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
9144 effect(KILL cr);
9145
9146 format %{ "shrq $dst, $shift" %}
9147 ins_encode %{
9148 __ shrq($dst$$Address, $shift$$constant);
9149 %}
9150 ins_pipe(ialu_mem_imm);
9151 %}
9152
9153 // Logical Shift Right by variable
9154 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
9155 %{
9156 match(Set dst (URShiftL dst shift));
9157 effect(KILL cr);
9158
9159 format %{ "shrq $dst, $shift" %}
9160 ins_encode %{
9161 __ shrq($dst$$Register);
9162 %}
9163 ins_pipe(ialu_reg_reg);
9164 %}
9165
9166 // Logical Shift Right by variable
9167 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9168 %{
9169 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
9170 effect(KILL cr);
9171
9172 format %{ "shrq $dst, $shift" %}
9173 ins_encode %{
9174 __ shrq($dst$$Address);
9175 %}
9176 ins_pipe(ialu_mem_reg);
9177 %}
9178
9179 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
9180 // This idiom is used by the compiler for the i2b bytecode.
9181 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour)
9182 %{
9183 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
9184
9185 format %{ "movsbl $dst, $src\t# i2b" %}
9186 ins_encode %{
9187 __ movsbl($dst$$Register, $src$$Register);
9188 %}
9189 ins_pipe(ialu_reg_reg);
9190 %}
9191
9192 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
9193 // This idiom is used by the compiler the i2s bytecode.
9194 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen)
9195 %{
9196 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
9197
9198 format %{ "movswl $dst, $src\t# i2s" %}
9199 ins_encode %{
9200 __ movswl($dst$$Register, $src$$Register);
9201 %}
9202 ins_pipe(ialu_reg_reg);
9203 %}
9204
9205 // ROL/ROR instructions
9206
9207 // Rotate left by constant.
9208 instruct rolI_imm(rRegI dst, immI8 shift, rFlagsReg cr)
9209 %{
9210 predicate(n->bottom_type()->basic_type() == T_INT);
9211 match(Set dst (RotateLeft dst shift));
9212 effect(KILL cr);
9213 format %{ "roll $dst, $shift" %}
9214 ins_encode %{
9215 __ roll($dst$$Register, $shift$$constant);
9216 %}
9217 ins_pipe(ialu_reg);
9218 %}
9219
9220 // Rotate Left by variable
9221 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr)
9222 %{
9223 predicate(n->bottom_type()->basic_type() == T_INT);
9224 match(Set dst (RotateLeft dst shift));
9225 effect(KILL cr);
9226 format %{ "roll $dst, $shift" %}
9227 ins_encode %{
9228 __ roll($dst$$Register);
9229 %}
9230 ins_pipe(ialu_reg_reg);
9231 %}
9232
9233 // Rotate Right by constant.
9234 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr)
9235 %{
9236 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT);
9237 match(Set dst (RotateRight dst shift));
9238 effect(KILL cr);
9239 format %{ "rorl $dst, $shift" %}
9240 ins_encode %{
9241 __ rorl($dst$$Register, $shift$$constant);
9242 %}
9243 ins_pipe(ialu_reg);
9244 %}
9245
9246 // Rotate Right by constant.
9247 instruct rorI_immI8(rRegI dst, immI8 shift)
9248 %{
9249 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT);
9250 match(Set dst (RotateRight dst shift));
9251 format %{ "rorxd $dst, $shift" %}
9252 ins_encode %{
9253 __ rorxd($dst$$Register, $dst$$Register, $shift$$constant);
9254 %}
9255 ins_pipe(ialu_reg_reg);
9256 %}
9257
9258 // Rotate Right by variable
9259 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr)
9260 %{
9261 predicate(n->bottom_type()->basic_type() == T_INT);
9262 match(Set dst (RotateRight dst shift));
9263 effect(KILL cr);
9264 format %{ "rorl $dst, $shift" %}
9265 ins_encode %{
9266 __ rorl($dst$$Register);
9267 %}
9268 ins_pipe(ialu_reg_reg);
9269 %}
9270
9271
9272 // Rotate Left by constant.
9273 instruct rolL_immI8(rRegL dst, immI8 shift, rFlagsReg cr)
9274 %{
9275 predicate(n->bottom_type()->basic_type() == T_LONG);
9276 match(Set dst (RotateLeft dst shift));
9277 effect(KILL cr);
9278 format %{ "rolq $dst, $shift" %}
9279 ins_encode %{
9280 __ rolq($dst$$Register, $shift$$constant);
9281 %}
9282 ins_pipe(ialu_reg);
9283 %}
9284
9285 // Rotate Left by variable
9286 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr)
9287 %{
9288 predicate(n->bottom_type()->basic_type() == T_LONG);
9289 match(Set dst (RotateLeft dst shift));
9290 effect(KILL cr);
9291 format %{ "rolq $dst, $shift" %}
9292 ins_encode %{
9293 __ rolq($dst$$Register);
9294 %}
9295 ins_pipe(ialu_reg_reg);
9296 %}
9297
9298
9299 // Rotate Right by constant.
9300 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr)
9301 %{
9302 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG);
9303 match(Set dst (RotateRight dst shift));
9304 effect(KILL cr);
9305 format %{ "rorq $dst, $shift" %}
9306 ins_encode %{
9307 __ rorq($dst$$Register, $shift$$constant);
9308 %}
9309 ins_pipe(ialu_reg);
9310 %}
9311
9312
9313 // Rotate Right by constant
9314 instruct rorL_immI8(rRegL dst, immI8 shift)
9315 %{
9316 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG);
9317 match(Set dst (RotateRight dst shift));
9318 format %{ "rorxq $dst, $shift" %}
9319 ins_encode %{
9320 __ rorxq($dst$$Register, $dst$$Register, $shift$$constant);
9321 %}
9322 ins_pipe(ialu_reg_reg);
9323 %}
9324
9325 // Rotate Right by variable
9326 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr)
9327 %{
9328 predicate(n->bottom_type()->basic_type() == T_LONG);
9329 match(Set dst (RotateRight dst shift));
9330 effect(KILL cr);
9331 format %{ "rorq $dst, $shift" %}
9332 ins_encode %{
9333 __ rorq($dst$$Register);
9334 %}
9335 ins_pipe(ialu_reg_reg);
9336 %}
9337
9338
9339 // Logical Instructions
9340
9341 // Integer Logical Instructions
9342
9343 // And Instructions
9344 // And Register with Register
9345 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9346 %{
9347 match(Set dst (AndI dst src));
9348 effect(KILL cr);
9349
9350 format %{ "andl $dst, $src\t# int" %}
9351 ins_encode %{
9352 __ andl($dst$$Register, $src$$Register);
9353 %}
9354 ins_pipe(ialu_reg_reg);
9355 %}
9356
9357 // And Register with Immediate 255
9358 instruct andI_rReg_imm255(rRegI dst, immI_255 src)
9359 %{
9360 match(Set dst (AndI dst src));
9361
9362 format %{ "movzbl $dst, $dst\t# int & 0xFF" %}
9363 ins_encode %{
9364 __ movzbl($dst$$Register, $dst$$Register);
9365 %}
9366 ins_pipe(ialu_reg);
9367 %}
9368
9369 // And Register with Immediate 255 and promote to long
9370 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask)
9371 %{
9372 match(Set dst (ConvI2L (AndI src mask)));
9373
9374 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %}
9375 ins_encode %{
9376 __ movzbl($dst$$Register, $src$$Register);
9377 %}
9378 ins_pipe(ialu_reg);
9379 %}
9380
9381 // And Register with Immediate 65535
9382 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src)
9383 %{
9384 match(Set dst (AndI dst src));
9385
9386 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %}
9387 ins_encode %{
9388 __ movzwl($dst$$Register, $dst$$Register);
9389 %}
9390 ins_pipe(ialu_reg);
9391 %}
9392
9393 // And Register with Immediate 65535 and promote to long
9394 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask)
9395 %{
9396 match(Set dst (ConvI2L (AndI src mask)));
9397
9398 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %}
9399 ins_encode %{
9400 __ movzwl($dst$$Register, $src$$Register);
9401 %}
9402 ins_pipe(ialu_reg);
9403 %}
9404
9405 // Can skip int2long conversions after AND with small bitmask
9406 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr)
9407 %{
9408 predicate(VM_Version::supports_bmi2());
9409 ins_cost(125);
9410 effect(TEMP tmp, KILL cr);
9411 match(Set dst (ConvI2L (AndI src mask)));
9412 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %}
9413 ins_encode %{
9414 __ movl($tmp$$Register, exact_log2($mask$$constant + 1));
9415 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register);
9416 %}
9417 ins_pipe(ialu_reg_reg);
9418 %}
9419
9420 // And Register with Immediate
9421 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9422 %{
9423 match(Set dst (AndI dst src));
9424 effect(KILL cr);
9425
9426 format %{ "andl $dst, $src\t# int" %}
9427 ins_encode %{
9428 __ andl($dst$$Register, $src$$constant);
9429 %}
9430 ins_pipe(ialu_reg);
9431 %}
9432
9433 // And Register with Memory
9434 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9435 %{
9436 match(Set dst (AndI dst (LoadI src)));
9437 effect(KILL cr);
9438
9439 ins_cost(125);
9440 format %{ "andl $dst, $src\t# int" %}
9441 ins_encode %{
9442 __ andl($dst$$Register, $src$$Address);
9443 %}
9444 ins_pipe(ialu_reg_mem);
9445 %}
9446
9447 // And Memory with Register
9448 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9449 %{
9450 match(Set dst (StoreB dst (AndI (LoadB dst) src)));
9451 effect(KILL cr);
9452
9453 ins_cost(150);
9454 format %{ "andb $dst, $src\t# byte" %}
9455 ins_encode %{
9456 __ andb($dst$$Address, $src$$Register);
9457 %}
9458 ins_pipe(ialu_mem_reg);
9459 %}
9460
9461 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9462 %{
9463 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9464 effect(KILL cr);
9465
9466 ins_cost(150);
9467 format %{ "andl $dst, $src\t# int" %}
9468 ins_encode %{
9469 __ andl($dst$$Address, $src$$Register);
9470 %}
9471 ins_pipe(ialu_mem_reg);
9472 %}
9473
9474 // And Memory with Immediate
9475 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr)
9476 %{
9477 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9478 effect(KILL cr);
9479
9480 ins_cost(125);
9481 format %{ "andl $dst, $src\t# int" %}
9482 ins_encode %{
9483 __ andl($dst$$Address, $src$$constant);
9484 %}
9485 ins_pipe(ialu_mem_imm);
9486 %}
9487
9488 // BMI1 instructions
9489 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{
9490 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2)));
9491 predicate(UseBMI1Instructions);
9492 effect(KILL cr);
9493
9494 ins_cost(125);
9495 format %{ "andnl $dst, $src1, $src2" %}
9496
9497 ins_encode %{
9498 __ andnl($dst$$Register, $src1$$Register, $src2$$Address);
9499 %}
9500 ins_pipe(ialu_reg_mem);
9501 %}
9502
9503 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{
9504 match(Set dst (AndI (XorI src1 minus_1) src2));
9505 predicate(UseBMI1Instructions);
9506 effect(KILL cr);
9507
9508 format %{ "andnl $dst, $src1, $src2" %}
9509
9510 ins_encode %{
9511 __ andnl($dst$$Register, $src1$$Register, $src2$$Register);
9512 %}
9513 ins_pipe(ialu_reg);
9514 %}
9515
9516 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{
9517 match(Set dst (AndI (SubI imm_zero src) src));
9518 predicate(UseBMI1Instructions);
9519 effect(KILL cr);
9520
9521 format %{ "blsil $dst, $src" %}
9522
9523 ins_encode %{
9524 __ blsil($dst$$Register, $src$$Register);
9525 %}
9526 ins_pipe(ialu_reg);
9527 %}
9528
9529 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{
9530 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) ));
9531 predicate(UseBMI1Instructions);
9532 effect(KILL cr);
9533
9534 ins_cost(125);
9535 format %{ "blsil $dst, $src" %}
9536
9537 ins_encode %{
9538 __ blsil($dst$$Register, $src$$Address);
9539 %}
9540 ins_pipe(ialu_reg_mem);
9541 %}
9542
9543 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr)
9544 %{
9545 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) );
9546 predicate(UseBMI1Instructions);
9547 effect(KILL cr);
9548
9549 ins_cost(125);
9550 format %{ "blsmskl $dst, $src" %}
9551
9552 ins_encode %{
9553 __ blsmskl($dst$$Register, $src$$Address);
9554 %}
9555 ins_pipe(ialu_reg_mem);
9556 %}
9557
9558 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr)
9559 %{
9560 match(Set dst (XorI (AddI src minus_1) src));
9561 predicate(UseBMI1Instructions);
9562 effect(KILL cr);
9563
9564 format %{ "blsmskl $dst, $src" %}
9565
9566 ins_encode %{
9567 __ blsmskl($dst$$Register, $src$$Register);
9568 %}
9569
9570 ins_pipe(ialu_reg);
9571 %}
9572
9573 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr)
9574 %{
9575 match(Set dst (AndI (AddI src minus_1) src) );
9576 predicate(UseBMI1Instructions);
9577 effect(KILL cr);
9578
9579 format %{ "blsrl $dst, $src" %}
9580
9581 ins_encode %{
9582 __ blsrl($dst$$Register, $src$$Register);
9583 %}
9584
9585 ins_pipe(ialu_reg_mem);
9586 %}
9587
9588 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr)
9589 %{
9590 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) );
9591 predicate(UseBMI1Instructions);
9592 effect(KILL cr);
9593
9594 ins_cost(125);
9595 format %{ "blsrl $dst, $src" %}
9596
9597 ins_encode %{
9598 __ blsrl($dst$$Register, $src$$Address);
9599 %}
9600
9601 ins_pipe(ialu_reg);
9602 %}
9603
9604 // Or Instructions
9605 // Or Register with Register
9606 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9607 %{
9608 match(Set dst (OrI dst src));
9609 effect(KILL cr);
9610
9611 format %{ "orl $dst, $src\t# int" %}
9612 ins_encode %{
9613 __ orl($dst$$Register, $src$$Register);
9614 %}
9615 ins_pipe(ialu_reg_reg);
9616 %}
9617
9618 // Or Register with Immediate
9619 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9620 %{
9621 match(Set dst (OrI dst src));
9622 effect(KILL cr);
9623
9624 format %{ "orl $dst, $src\t# int" %}
9625 ins_encode %{
9626 __ orl($dst$$Register, $src$$constant);
9627 %}
9628 ins_pipe(ialu_reg);
9629 %}
9630
9631 // Or Register with Memory
9632 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9633 %{
9634 match(Set dst (OrI dst (LoadI src)));
9635 effect(KILL cr);
9636
9637 ins_cost(125);
9638 format %{ "orl $dst, $src\t# int" %}
9639 ins_encode %{
9640 __ orl($dst$$Register, $src$$Address);
9641 %}
9642 ins_pipe(ialu_reg_mem);
9643 %}
9644
9645 // Or Memory with Register
9646 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9647 %{
9648 match(Set dst (StoreB dst (OrI (LoadB dst) src)));
9649 effect(KILL cr);
9650
9651 ins_cost(150);
9652 format %{ "orb $dst, $src\t# byte" %}
9653 ins_encode %{
9654 __ orb($dst$$Address, $src$$Register);
9655 %}
9656 ins_pipe(ialu_mem_reg);
9657 %}
9658
9659 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9660 %{
9661 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9662 effect(KILL cr);
9663
9664 ins_cost(150);
9665 format %{ "orl $dst, $src\t# int" %}
9666 ins_encode %{
9667 __ orl($dst$$Address, $src$$Register);
9668 %}
9669 ins_pipe(ialu_mem_reg);
9670 %}
9671
9672 // Or Memory with Immediate
9673 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr)
9674 %{
9675 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9676 effect(KILL cr);
9677
9678 ins_cost(125);
9679 format %{ "orl $dst, $src\t# int" %}
9680 ins_encode %{
9681 __ orl($dst$$Address, $src$$constant);
9682 %}
9683 ins_pipe(ialu_mem_imm);
9684 %}
9685
9686 // Xor Instructions
9687 // Xor Register with Register
9688 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9689 %{
9690 match(Set dst (XorI dst src));
9691 effect(KILL cr);
9692
9693 format %{ "xorl $dst, $src\t# int" %}
9694 ins_encode %{
9695 __ xorl($dst$$Register, $src$$Register);
9696 %}
9697 ins_pipe(ialu_reg_reg);
9698 %}
9699
9700 // Xor Register with Immediate -1
9701 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
9702 match(Set dst (XorI dst imm));
9703
9704 format %{ "not $dst" %}
9705 ins_encode %{
9706 __ notl($dst$$Register);
9707 %}
9708 ins_pipe(ialu_reg);
9709 %}
9710
9711 // Xor Register with Immediate
9712 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9713 %{
9714 match(Set dst (XorI dst src));
9715 effect(KILL cr);
9716
9717 format %{ "xorl $dst, $src\t# int" %}
9718 ins_encode %{
9719 __ xorl($dst$$Register, $src$$constant);
9720 %}
9721 ins_pipe(ialu_reg);
9722 %}
9723
9724 // Xor Register with Memory
9725 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9726 %{
9727 match(Set dst (XorI dst (LoadI src)));
9728 effect(KILL cr);
9729
9730 ins_cost(125);
9731 format %{ "xorl $dst, $src\t# int" %}
9732 ins_encode %{
9733 __ xorl($dst$$Register, $src$$Address);
9734 %}
9735 ins_pipe(ialu_reg_mem);
9736 %}
9737
9738 // Xor Memory with Register
9739 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9740 %{
9741 match(Set dst (StoreB dst (XorI (LoadB dst) src)));
9742 effect(KILL cr);
9743
9744 ins_cost(150);
9745 format %{ "xorb $dst, $src\t# byte" %}
9746 ins_encode %{
9747 __ xorb($dst$$Address, $src$$Register);
9748 %}
9749 ins_pipe(ialu_mem_reg);
9750 %}
9751
9752 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9753 %{
9754 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9755 effect(KILL cr);
9756
9757 ins_cost(150);
9758 format %{ "xorl $dst, $src\t# int" %}
9759 ins_encode %{
9760 __ xorl($dst$$Address, $src$$Register);
9761 %}
9762 ins_pipe(ialu_mem_reg);
9763 %}
9764
9765 // Xor Memory with Immediate
9766 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr)
9767 %{
9768 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9769 effect(KILL cr);
9770
9771 ins_cost(125);
9772 format %{ "xorl $dst, $src\t# int" %}
9773 ins_encode %{
9774 __ xorl($dst$$Address, $src$$constant);
9775 %}
9776 ins_pipe(ialu_mem_imm);
9777 %}
9778
9779
9780 // Long Logical Instructions
9781
9782 // And Instructions
9783 // And Register with Register
9784 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9785 %{
9786 match(Set dst (AndL dst src));
9787 effect(KILL cr);
9788
9789 format %{ "andq $dst, $src\t# long" %}
9790 ins_encode %{
9791 __ andq($dst$$Register, $src$$Register);
9792 %}
9793 ins_pipe(ialu_reg_reg);
9794 %}
9795
9796 // And Register with Immediate 255
9797 instruct andL_rReg_imm255(rRegL dst, immL_255 src)
9798 %{
9799 match(Set dst (AndL dst src));
9800
9801 format %{ "movzbq $dst, $dst\t# long & 0xFF" %}
9802 ins_encode %{
9803 __ movzbq($dst$$Register, $dst$$Register);
9804 %}
9805 ins_pipe(ialu_reg);
9806 %}
9807
9808 // And Register with Immediate 65535
9809 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
9810 %{
9811 match(Set dst (AndL dst src));
9812
9813 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %}
9814 ins_encode %{
9815 __ movzwq($dst$$Register, $dst$$Register);
9816 %}
9817 ins_pipe(ialu_reg);
9818 %}
9819
9820 // And Register with Immediate
9821 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9822 %{
9823 match(Set dst (AndL dst src));
9824 effect(KILL cr);
9825
9826 format %{ "andq $dst, $src\t# long" %}
9827 ins_encode %{
9828 __ andq($dst$$Register, $src$$constant);
9829 %}
9830 ins_pipe(ialu_reg);
9831 %}
9832
9833 // And Register with Memory
9834 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9835 %{
9836 match(Set dst (AndL dst (LoadL src)));
9837 effect(KILL cr);
9838
9839 ins_cost(125);
9840 format %{ "andq $dst, $src\t# long" %}
9841 ins_encode %{
9842 __ andq($dst$$Register, $src$$Address);
9843 %}
9844 ins_pipe(ialu_reg_mem);
9845 %}
9846
9847 // And Memory with Register
9848 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9849 %{
9850 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9851 effect(KILL cr);
9852
9853 ins_cost(150);
9854 format %{ "andq $dst, $src\t# long" %}
9855 ins_encode %{
9856 __ andq($dst$$Address, $src$$Register);
9857 %}
9858 ins_pipe(ialu_mem_reg);
9859 %}
9860
9861 // And Memory with Immediate
9862 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9863 %{
9864 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9865 effect(KILL cr);
9866
9867 ins_cost(125);
9868 format %{ "andq $dst, $src\t# long" %}
9869 ins_encode %{
9870 __ andq($dst$$Address, $src$$constant);
9871 %}
9872 ins_pipe(ialu_mem_imm);
9873 %}
9874
9875 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr)
9876 %{
9877 // con should be a pure 64-bit immediate given that not(con) is a power of 2
9878 // because AND/OR works well enough for 8/32-bit values.
9879 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30);
9880
9881 match(Set dst (StoreL dst (AndL (LoadL dst) con)));
9882 effect(KILL cr);
9883
9884 ins_cost(125);
9885 format %{ "btrq $dst, log2(not($con))\t# long" %}
9886 ins_encode %{
9887 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant));
9888 %}
9889 ins_pipe(ialu_mem_imm);
9890 %}
9891
9892 // BMI1 instructions
9893 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{
9894 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2)));
9895 predicate(UseBMI1Instructions);
9896 effect(KILL cr);
9897
9898 ins_cost(125);
9899 format %{ "andnq $dst, $src1, $src2" %}
9900
9901 ins_encode %{
9902 __ andnq($dst$$Register, $src1$$Register, $src2$$Address);
9903 %}
9904 ins_pipe(ialu_reg_mem);
9905 %}
9906
9907 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{
9908 match(Set dst (AndL (XorL src1 minus_1) src2));
9909 predicate(UseBMI1Instructions);
9910 effect(KILL cr);
9911
9912 format %{ "andnq $dst, $src1, $src2" %}
9913
9914 ins_encode %{
9915 __ andnq($dst$$Register, $src1$$Register, $src2$$Register);
9916 %}
9917 ins_pipe(ialu_reg_mem);
9918 %}
9919
9920 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{
9921 match(Set dst (AndL (SubL imm_zero src) src));
9922 predicate(UseBMI1Instructions);
9923 effect(KILL cr);
9924
9925 format %{ "blsiq $dst, $src" %}
9926
9927 ins_encode %{
9928 __ blsiq($dst$$Register, $src$$Register);
9929 %}
9930 ins_pipe(ialu_reg);
9931 %}
9932
9933 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{
9934 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) ));
9935 predicate(UseBMI1Instructions);
9936 effect(KILL cr);
9937
9938 ins_cost(125);
9939 format %{ "blsiq $dst, $src" %}
9940
9941 ins_encode %{
9942 __ blsiq($dst$$Register, $src$$Address);
9943 %}
9944 ins_pipe(ialu_reg_mem);
9945 %}
9946
9947 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr)
9948 %{
9949 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) );
9950 predicate(UseBMI1Instructions);
9951 effect(KILL cr);
9952
9953 ins_cost(125);
9954 format %{ "blsmskq $dst, $src" %}
9955
9956 ins_encode %{
9957 __ blsmskq($dst$$Register, $src$$Address);
9958 %}
9959 ins_pipe(ialu_reg_mem);
9960 %}
9961
9962 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr)
9963 %{
9964 match(Set dst (XorL (AddL src minus_1) src));
9965 predicate(UseBMI1Instructions);
9966 effect(KILL cr);
9967
9968 format %{ "blsmskq $dst, $src" %}
9969
9970 ins_encode %{
9971 __ blsmskq($dst$$Register, $src$$Register);
9972 %}
9973
9974 ins_pipe(ialu_reg);
9975 %}
9976
9977 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr)
9978 %{
9979 match(Set dst (AndL (AddL src minus_1) src) );
9980 predicate(UseBMI1Instructions);
9981 effect(KILL cr);
9982
9983 format %{ "blsrq $dst, $src" %}
9984
9985 ins_encode %{
9986 __ blsrq($dst$$Register, $src$$Register);
9987 %}
9988
9989 ins_pipe(ialu_reg);
9990 %}
9991
9992 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr)
9993 %{
9994 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) );
9995 predicate(UseBMI1Instructions);
9996 effect(KILL cr);
9997
9998 ins_cost(125);
9999 format %{ "blsrq $dst, $src" %}
10000
10001 ins_encode %{
10002 __ blsrq($dst$$Register, $src$$Address);
10003 %}
10004
10005 ins_pipe(ialu_reg);
10006 %}
10007
10008 // Or Instructions
10009 // Or Register with Register
10010 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
10011 %{
10012 match(Set dst (OrL dst src));
10013 effect(KILL cr);
10014
10015 format %{ "orq $dst, $src\t# long" %}
10016 ins_encode %{
10017 __ orq($dst$$Register, $src$$Register);
10018 %}
10019 ins_pipe(ialu_reg_reg);
10020 %}
10021
10022 // Use any_RegP to match R15 (TLS register) without spilling.
10023 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
10024 match(Set dst (OrL dst (CastP2X src)));
10025 effect(KILL cr);
10026
10027 format %{ "orq $dst, $src\t# long" %}
10028 ins_encode %{
10029 __ orq($dst$$Register, $src$$Register);
10030 %}
10031 ins_pipe(ialu_reg_reg);
10032 %}
10033
10034
10035 // Or Register with Immediate
10036 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
10037 %{
10038 match(Set dst (OrL dst src));
10039 effect(KILL cr);
10040
10041 format %{ "orq $dst, $src\t# long" %}
10042 ins_encode %{
10043 __ orq($dst$$Register, $src$$constant);
10044 %}
10045 ins_pipe(ialu_reg);
10046 %}
10047
10048 // Or Register with Memory
10049 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
10050 %{
10051 match(Set dst (OrL dst (LoadL src)));
10052 effect(KILL cr);
10053
10054 ins_cost(125);
10055 format %{ "orq $dst, $src\t# long" %}
10056 ins_encode %{
10057 __ orq($dst$$Register, $src$$Address);
10058 %}
10059 ins_pipe(ialu_reg_mem);
10060 %}
10061
10062 // Or Memory with Register
10063 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
10064 %{
10065 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
10066 effect(KILL cr);
10067
10068 ins_cost(150);
10069 format %{ "orq $dst, $src\t# long" %}
10070 ins_encode %{
10071 __ orq($dst$$Address, $src$$Register);
10072 %}
10073 ins_pipe(ialu_mem_reg);
10074 %}
10075
10076 // Or Memory with Immediate
10077 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
10078 %{
10079 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
10080 effect(KILL cr);
10081
10082 ins_cost(125);
10083 format %{ "orq $dst, $src\t# long" %}
10084 ins_encode %{
10085 __ orq($dst$$Address, $src$$constant);
10086 %}
10087 ins_pipe(ialu_mem_imm);
10088 %}
10089
10090 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr)
10091 %{
10092 // con should be a pure 64-bit power of 2 immediate
10093 // because AND/OR works well enough for 8/32-bit values.
10094 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31);
10095
10096 match(Set dst (StoreL dst (OrL (LoadL dst) con)));
10097 effect(KILL cr);
10098
10099 ins_cost(125);
10100 format %{ "btsq $dst, log2($con)\t# long" %}
10101 ins_encode %{
10102 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant));
10103 %}
10104 ins_pipe(ialu_mem_imm);
10105 %}
10106
10107 // Xor Instructions
10108 // Xor Register with Register
10109 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
10110 %{
10111 match(Set dst (XorL dst src));
10112 effect(KILL cr);
10113
10114 format %{ "xorq $dst, $src\t# long" %}
10115 ins_encode %{
10116 __ xorq($dst$$Register, $src$$Register);
10117 %}
10118 ins_pipe(ialu_reg_reg);
10119 %}
10120
10121 // Xor Register with Immediate -1
10122 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
10123 match(Set dst (XorL dst imm));
10124
10125 format %{ "notq $dst" %}
10126 ins_encode %{
10127 __ notq($dst$$Register);
10128 %}
10129 ins_pipe(ialu_reg);
10130 %}
10131
10132 // Xor Register with Immediate
10133 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
10134 %{
10135 match(Set dst (XorL dst src));
10136 effect(KILL cr);
10137
10138 format %{ "xorq $dst, $src\t# long" %}
10139 ins_encode %{
10140 __ xorq($dst$$Register, $src$$constant);
10141 %}
10142 ins_pipe(ialu_reg);
10143 %}
10144
10145 // Xor Register with Memory
10146 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
10147 %{
10148 match(Set dst (XorL dst (LoadL src)));
10149 effect(KILL cr);
10150
10151 ins_cost(125);
10152 format %{ "xorq $dst, $src\t# long" %}
10153 ins_encode %{
10154 __ xorq($dst$$Register, $src$$Address);
10155 %}
10156 ins_pipe(ialu_reg_mem);
10157 %}
10158
10159 // Xor Memory with Register
10160 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
10161 %{
10162 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
10163 effect(KILL cr);
10164
10165 ins_cost(150);
10166 format %{ "xorq $dst, $src\t# long" %}
10167 ins_encode %{
10168 __ xorq($dst$$Address, $src$$Register);
10169 %}
10170 ins_pipe(ialu_mem_reg);
10171 %}
10172
10173 // Xor Memory with Immediate
10174 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
10175 %{
10176 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
10177 effect(KILL cr);
10178
10179 ins_cost(125);
10180 format %{ "xorq $dst, $src\t# long" %}
10181 ins_encode %{
10182 __ xorq($dst$$Address, $src$$constant);
10183 %}
10184 ins_pipe(ialu_mem_imm);
10185 %}
10186
10187 // Convert Int to Boolean
10188 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr)
10189 %{
10190 match(Set dst (Conv2B src));
10191 effect(KILL cr);
10192
10193 format %{ "testl $src, $src\t# ci2b\n\t"
10194 "setnz $dst\n\t"
10195 "movzbl $dst, $dst" %}
10196 ins_encode %{
10197 __ testl($src$$Register, $src$$Register);
10198 __ set_byte_if_not_zero($dst$$Register);
10199 __ movzbl($dst$$Register, $dst$$Register);
10200 %}
10201 ins_pipe(pipe_slow); // XXX
10202 %}
10203
10204 // Convert Pointer to Boolean
10205 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr)
10206 %{
10207 match(Set dst (Conv2B src));
10208 effect(KILL cr);
10209
10210 format %{ "testq $src, $src\t# cp2b\n\t"
10211 "setnz $dst\n\t"
10212 "movzbl $dst, $dst" %}
10213 ins_encode %{
10214 __ testq($src$$Register, $src$$Register);
10215 __ set_byte_if_not_zero($dst$$Register);
10216 __ movzbl($dst$$Register, $dst$$Register);
10217 %}
10218 ins_pipe(pipe_slow); // XXX
10219 %}
10220
10221 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr)
10222 %{
10223 match(Set dst (CmpLTMask p q));
10224 effect(KILL cr);
10225
10226 ins_cost(400);
10227 format %{ "cmpl $p, $q\t# cmpLTMask\n\t"
10228 "setlt $dst\n\t"
10229 "movzbl $dst, $dst\n\t"
10230 "negl $dst" %}
10231 ins_encode %{
10232 __ cmpl($p$$Register, $q$$Register);
10233 __ setl($dst$$Register);
10234 __ movzbl($dst$$Register, $dst$$Register);
10235 __ negl($dst$$Register);
10236 %}
10237 ins_pipe(pipe_slow);
10238 %}
10239
10240 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr)
10241 %{
10242 match(Set dst (CmpLTMask dst zero));
10243 effect(KILL cr);
10244
10245 ins_cost(100);
10246 format %{ "sarl $dst, #31\t# cmpLTMask0" %}
10247 ins_encode %{
10248 __ sarl($dst$$Register, 31);
10249 %}
10250 ins_pipe(ialu_reg);
10251 %}
10252
10253 /* Better to save a register than avoid a branch */
10254 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr)
10255 %{
10256 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
10257 effect(KILL cr);
10258 ins_cost(300);
10259 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t"
10260 "jge done\n\t"
10261 "addl $p,$y\n"
10262 "done: " %}
10263 ins_encode %{
10264 Register Rp = $p$$Register;
10265 Register Rq = $q$$Register;
10266 Register Ry = $y$$Register;
10267 Label done;
10268 __ subl(Rp, Rq);
10269 __ jccb(Assembler::greaterEqual, done);
10270 __ addl(Rp, Ry);
10271 __ bind(done);
10272 %}
10273 ins_pipe(pipe_cmplt);
10274 %}
10275
10276 /* Better to save a register than avoid a branch */
10277 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr)
10278 %{
10279 match(Set y (AndI (CmpLTMask p q) y));
10280 effect(KILL cr);
10281
10282 ins_cost(300);
10283
10284 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t"
10285 "jlt done\n\t"
10286 "xorl $y, $y\n"
10287 "done: " %}
10288 ins_encode %{
10289 Register Rp = $p$$Register;
10290 Register Rq = $q$$Register;
10291 Register Ry = $y$$Register;
10292 Label done;
10293 __ cmpl(Rp, Rq);
10294 __ jccb(Assembler::less, done);
10295 __ xorl(Ry, Ry);
10296 __ bind(done);
10297 %}
10298 ins_pipe(pipe_cmplt);
10299 %}
10300
10301
10302 //---------- FP Instructions------------------------------------------------
10303
10304 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
10305 %{
10306 match(Set cr (CmpF src1 src2));
10307
10308 ins_cost(145);
10309 format %{ "ucomiss $src1, $src2\n\t"
10310 "jnp,s exit\n\t"
10311 "pushfq\t# saw NaN, set CF\n\t"
10312 "andq [rsp], #0xffffff2b\n\t"
10313 "popfq\n"
10314 "exit:" %}
10315 ins_encode %{
10316 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10317 emit_cmpfp_fixup(_masm);
10318 %}
10319 ins_pipe(pipe_slow);
10320 %}
10321
10322 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
10323 match(Set cr (CmpF src1 src2));
10324
10325 ins_cost(100);
10326 format %{ "ucomiss $src1, $src2" %}
10327 ins_encode %{
10328 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10329 %}
10330 ins_pipe(pipe_slow);
10331 %}
10332
10333 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
10334 %{
10335 match(Set cr (CmpF src1 (LoadF src2)));
10336
10337 ins_cost(145);
10338 format %{ "ucomiss $src1, $src2\n\t"
10339 "jnp,s exit\n\t"
10340 "pushfq\t# saw NaN, set CF\n\t"
10341 "andq [rsp], #0xffffff2b\n\t"
10342 "popfq\n"
10343 "exit:" %}
10344 ins_encode %{
10345 __ ucomiss($src1$$XMMRegister, $src2$$Address);
10346 emit_cmpfp_fixup(_masm);
10347 %}
10348 ins_pipe(pipe_slow);
10349 %}
10350
10351 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
10352 match(Set cr (CmpF src1 (LoadF src2)));
10353
10354 ins_cost(100);
10355 format %{ "ucomiss $src1, $src2" %}
10356 ins_encode %{
10357 __ ucomiss($src1$$XMMRegister, $src2$$Address);
10358 %}
10359 ins_pipe(pipe_slow);
10360 %}
10361
10362 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
10363 match(Set cr (CmpF src con));
10364
10365 ins_cost(145);
10366 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10367 "jnp,s exit\n\t"
10368 "pushfq\t# saw NaN, set CF\n\t"
10369 "andq [rsp], #0xffffff2b\n\t"
10370 "popfq\n"
10371 "exit:" %}
10372 ins_encode %{
10373 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10374 emit_cmpfp_fixup(_masm);
10375 %}
10376 ins_pipe(pipe_slow);
10377 %}
10378
10379 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
10380 match(Set cr (CmpF src con));
10381 ins_cost(100);
10382 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
10383 ins_encode %{
10384 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10385 %}
10386 ins_pipe(pipe_slow);
10387 %}
10388
10389 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
10390 %{
10391 match(Set cr (CmpD src1 src2));
10392
10393 ins_cost(145);
10394 format %{ "ucomisd $src1, $src2\n\t"
10395 "jnp,s exit\n\t"
10396 "pushfq\t# saw NaN, set CF\n\t"
10397 "andq [rsp], #0xffffff2b\n\t"
10398 "popfq\n"
10399 "exit:" %}
10400 ins_encode %{
10401 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10402 emit_cmpfp_fixup(_masm);
10403 %}
10404 ins_pipe(pipe_slow);
10405 %}
10406
10407 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
10408 match(Set cr (CmpD src1 src2));
10409
10410 ins_cost(100);
10411 format %{ "ucomisd $src1, $src2 test" %}
10412 ins_encode %{
10413 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10414 %}
10415 ins_pipe(pipe_slow);
10416 %}
10417
10418 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
10419 %{
10420 match(Set cr (CmpD src1 (LoadD src2)));
10421
10422 ins_cost(145);
10423 format %{ "ucomisd $src1, $src2\n\t"
10424 "jnp,s exit\n\t"
10425 "pushfq\t# saw NaN, set CF\n\t"
10426 "andq [rsp], #0xffffff2b\n\t"
10427 "popfq\n"
10428 "exit:" %}
10429 ins_encode %{
10430 __ ucomisd($src1$$XMMRegister, $src2$$Address);
10431 emit_cmpfp_fixup(_masm);
10432 %}
10433 ins_pipe(pipe_slow);
10434 %}
10435
10436 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
10437 match(Set cr (CmpD src1 (LoadD src2)));
10438
10439 ins_cost(100);
10440 format %{ "ucomisd $src1, $src2" %}
10441 ins_encode %{
10442 __ ucomisd($src1$$XMMRegister, $src2$$Address);
10443 %}
10444 ins_pipe(pipe_slow);
10445 %}
10446
10447 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
10448 match(Set cr (CmpD src con));
10449
10450 ins_cost(145);
10451 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10452 "jnp,s exit\n\t"
10453 "pushfq\t# saw NaN, set CF\n\t"
10454 "andq [rsp], #0xffffff2b\n\t"
10455 "popfq\n"
10456 "exit:" %}
10457 ins_encode %{
10458 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10459 emit_cmpfp_fixup(_masm);
10460 %}
10461 ins_pipe(pipe_slow);
10462 %}
10463
10464 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
10465 match(Set cr (CmpD src con));
10466 ins_cost(100);
10467 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
10468 ins_encode %{
10469 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10470 %}
10471 ins_pipe(pipe_slow);
10472 %}
10473
10474 // Compare into -1,0,1
10475 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
10476 %{
10477 match(Set dst (CmpF3 src1 src2));
10478 effect(KILL cr);
10479
10480 ins_cost(275);
10481 format %{ "ucomiss $src1, $src2\n\t"
10482 "movl $dst, #-1\n\t"
10483 "jp,s done\n\t"
10484 "jb,s done\n\t"
10485 "setne $dst\n\t"
10486 "movzbl $dst, $dst\n"
10487 "done:" %}
10488 ins_encode %{
10489 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10490 emit_cmpfp3(_masm, $dst$$Register);
10491 %}
10492 ins_pipe(pipe_slow);
10493 %}
10494
10495 // Compare into -1,0,1
10496 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
10497 %{
10498 match(Set dst (CmpF3 src1 (LoadF src2)));
10499 effect(KILL cr);
10500
10501 ins_cost(275);
10502 format %{ "ucomiss $src1, $src2\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 __ ucomiss($src1$$XMMRegister, $src2$$Address);
10511 emit_cmpfp3(_masm, $dst$$Register);
10512 %}
10513 ins_pipe(pipe_slow);
10514 %}
10515
10516 // Compare into -1,0,1
10517 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
10518 match(Set dst (CmpF3 src con));
10519 effect(KILL cr);
10520
10521 ins_cost(275);
10522 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
10523 "movl $dst, #-1\n\t"
10524 "jp,s done\n\t"
10525 "jb,s done\n\t"
10526 "setne $dst\n\t"
10527 "movzbl $dst, $dst\n"
10528 "done:" %}
10529 ins_encode %{
10530 __ ucomiss($src$$XMMRegister, $constantaddress($con));
10531 emit_cmpfp3(_masm, $dst$$Register);
10532 %}
10533 ins_pipe(pipe_slow);
10534 %}
10535
10536 // Compare into -1,0,1
10537 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
10538 %{
10539 match(Set dst (CmpD3 src1 src2));
10540 effect(KILL cr);
10541
10542 ins_cost(275);
10543 format %{ "ucomisd $src1, $src2\n\t"
10544 "movl $dst, #-1\n\t"
10545 "jp,s done\n\t"
10546 "jb,s done\n\t"
10547 "setne $dst\n\t"
10548 "movzbl $dst, $dst\n"
10549 "done:" %}
10550 ins_encode %{
10551 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10552 emit_cmpfp3(_masm, $dst$$Register);
10553 %}
10554 ins_pipe(pipe_slow);
10555 %}
10556
10557 // Compare into -1,0,1
10558 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
10559 %{
10560 match(Set dst (CmpD3 src1 (LoadD src2)));
10561 effect(KILL cr);
10562
10563 ins_cost(275);
10564 format %{ "ucomisd $src1, $src2\n\t"
10565 "movl $dst, #-1\n\t"
10566 "jp,s done\n\t"
10567 "jb,s done\n\t"
10568 "setne $dst\n\t"
10569 "movzbl $dst, $dst\n"
10570 "done:" %}
10571 ins_encode %{
10572 __ ucomisd($src1$$XMMRegister, $src2$$Address);
10573 emit_cmpfp3(_masm, $dst$$Register);
10574 %}
10575 ins_pipe(pipe_slow);
10576 %}
10577
10578 // Compare into -1,0,1
10579 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
10580 match(Set dst (CmpD3 src con));
10581 effect(KILL cr);
10582
10583 ins_cost(275);
10584 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
10585 "movl $dst, #-1\n\t"
10586 "jp,s done\n\t"
10587 "jb,s done\n\t"
10588 "setne $dst\n\t"
10589 "movzbl $dst, $dst\n"
10590 "done:" %}
10591 ins_encode %{
10592 __ ucomisd($src$$XMMRegister, $constantaddress($con));
10593 emit_cmpfp3(_masm, $dst$$Register);
10594 %}
10595 ins_pipe(pipe_slow);
10596 %}
10597
10598 //----------Arithmetic Conversion Instructions---------------------------------
10599
10600 instruct convF2D_reg_reg(regD dst, regF src)
10601 %{
10602 match(Set dst (ConvF2D src));
10603
10604 format %{ "cvtss2sd $dst, $src" %}
10605 ins_encode %{
10606 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister);
10607 %}
10608 ins_pipe(pipe_slow); // XXX
10609 %}
10610
10611 instruct convF2D_reg_mem(regD dst, memory src)
10612 %{
10613 match(Set dst (ConvF2D (LoadF src)));
10614
10615 format %{ "cvtss2sd $dst, $src" %}
10616 ins_encode %{
10617 __ cvtss2sd ($dst$$XMMRegister, $src$$Address);
10618 %}
10619 ins_pipe(pipe_slow); // XXX
10620 %}
10621
10622 instruct convD2F_reg_reg(regF dst, regD src)
10623 %{
10624 match(Set dst (ConvD2F src));
10625
10626 format %{ "cvtsd2ss $dst, $src" %}
10627 ins_encode %{
10628 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister);
10629 %}
10630 ins_pipe(pipe_slow); // XXX
10631 %}
10632
10633 instruct convD2F_reg_mem(regF dst, memory src)
10634 %{
10635 match(Set dst (ConvD2F (LoadD src)));
10636
10637 format %{ "cvtsd2ss $dst, $src" %}
10638 ins_encode %{
10639 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address);
10640 %}
10641 ins_pipe(pipe_slow); // XXX
10642 %}
10643
10644 // XXX do mem variants
10645 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
10646 %{
10647 match(Set dst (ConvF2I src));
10648 effect(KILL cr);
10649 format %{ "convert_f2i $dst,$src" %}
10650 ins_encode %{
10651 __ convert_f2i($dst$$Register, $src$$XMMRegister);
10652 %}
10653 ins_pipe(pipe_slow);
10654 %}
10655
10656 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
10657 %{
10658 match(Set dst (ConvF2L src));
10659 effect(KILL cr);
10660 format %{ "convert_f2l $dst,$src"%}
10661 ins_encode %{
10662 __ convert_f2l($dst$$Register, $src$$XMMRegister);
10663 %}
10664 ins_pipe(pipe_slow);
10665 %}
10666
10667 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
10668 %{
10669 match(Set dst (ConvD2I src));
10670 effect(KILL cr);
10671 format %{ "convert_d2i $dst,$src"%}
10672 ins_encode %{
10673 __ convert_d2i($dst$$Register, $src$$XMMRegister);
10674 %}
10675 ins_pipe(pipe_slow);
10676 %}
10677
10678 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
10679 %{
10680 match(Set dst (ConvD2L src));
10681 effect(KILL cr);
10682 format %{ "convert_d2l $dst,$src"%}
10683 ins_encode %{
10684 __ convert_d2l($dst$$Register, $src$$XMMRegister);
10685 %}
10686 ins_pipe(pipe_slow);
10687 %}
10688
10689 instruct convI2F_reg_reg(regF dst, rRegI src)
10690 %{
10691 predicate(!UseXmmI2F);
10692 match(Set dst (ConvI2F src));
10693
10694 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10695 ins_encode %{
10696 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
10697 %}
10698 ins_pipe(pipe_slow); // XXX
10699 %}
10700
10701 instruct convI2F_reg_mem(regF dst, memory src)
10702 %{
10703 match(Set dst (ConvI2F (LoadI src)));
10704
10705 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10706 ins_encode %{
10707 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address);
10708 %}
10709 ins_pipe(pipe_slow); // XXX
10710 %}
10711
10712 instruct convI2D_reg_reg(regD dst, rRegI src)
10713 %{
10714 predicate(!UseXmmI2D);
10715 match(Set dst (ConvI2D src));
10716
10717 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10718 ins_encode %{
10719 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
10720 %}
10721 ins_pipe(pipe_slow); // XXX
10722 %}
10723
10724 instruct convI2D_reg_mem(regD dst, memory src)
10725 %{
10726 match(Set dst (ConvI2D (LoadI src)));
10727
10728 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10729 ins_encode %{
10730 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address);
10731 %}
10732 ins_pipe(pipe_slow); // XXX
10733 %}
10734
10735 instruct convXI2F_reg(regF dst, rRegI src)
10736 %{
10737 predicate(UseXmmI2F);
10738 match(Set dst (ConvI2F src));
10739
10740 format %{ "movdl $dst, $src\n\t"
10741 "cvtdq2psl $dst, $dst\t# i2f" %}
10742 ins_encode %{
10743 __ movdl($dst$$XMMRegister, $src$$Register);
10744 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
10745 %}
10746 ins_pipe(pipe_slow); // XXX
10747 %}
10748
10749 instruct convXI2D_reg(regD dst, rRegI src)
10750 %{
10751 predicate(UseXmmI2D);
10752 match(Set dst (ConvI2D src));
10753
10754 format %{ "movdl $dst, $src\n\t"
10755 "cvtdq2pdl $dst, $dst\t# i2d" %}
10756 ins_encode %{
10757 __ movdl($dst$$XMMRegister, $src$$Register);
10758 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
10759 %}
10760 ins_pipe(pipe_slow); // XXX
10761 %}
10762
10763 instruct convL2F_reg_reg(regF dst, rRegL src)
10764 %{
10765 match(Set dst (ConvL2F src));
10766
10767 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10768 ins_encode %{
10769 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register);
10770 %}
10771 ins_pipe(pipe_slow); // XXX
10772 %}
10773
10774 instruct convL2F_reg_mem(regF dst, memory src)
10775 %{
10776 match(Set dst (ConvL2F (LoadL src)));
10777
10778 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10779 ins_encode %{
10780 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address);
10781 %}
10782 ins_pipe(pipe_slow); // XXX
10783 %}
10784
10785 instruct convL2D_reg_reg(regD dst, rRegL src)
10786 %{
10787 match(Set dst (ConvL2D src));
10788
10789 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10790 ins_encode %{
10791 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register);
10792 %}
10793 ins_pipe(pipe_slow); // XXX
10794 %}
10795
10796 instruct convL2D_reg_mem(regD dst, memory src)
10797 %{
10798 match(Set dst (ConvL2D (LoadL src)));
10799
10800 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10801 ins_encode %{
10802 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address);
10803 %}
10804 ins_pipe(pipe_slow); // XXX
10805 %}
10806
10807 instruct convI2L_reg_reg(rRegL dst, rRegI src)
10808 %{
10809 match(Set dst (ConvI2L src));
10810
10811 ins_cost(125);
10812 format %{ "movslq $dst, $src\t# i2l" %}
10813 ins_encode %{
10814 __ movslq($dst$$Register, $src$$Register);
10815 %}
10816 ins_pipe(ialu_reg_reg);
10817 %}
10818
10819 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src)
10820 // %{
10821 // match(Set dst (ConvI2L src));
10822 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 &&
10823 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0);
10824 // predicate(((const TypeNode*) n)->type()->is_long()->_hi ==
10825 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi &&
10826 // ((const TypeNode*) n)->type()->is_long()->_lo ==
10827 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo);
10828
10829 // format %{ "movl $dst, $src\t# unsigned i2l" %}
10830 // ins_encode(enc_copy(dst, src));
10831 // // opcode(0x63); // needs REX.W
10832 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
10833 // ins_pipe(ialu_reg_reg);
10834 // %}
10835
10836 // Zero-extend convert int to long
10837 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
10838 %{
10839 match(Set dst (AndL (ConvI2L src) mask));
10840
10841 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10842 ins_encode %{
10843 if ($dst$$reg != $src$$reg) {
10844 __ movl($dst$$Register, $src$$Register);
10845 }
10846 %}
10847 ins_pipe(ialu_reg_reg);
10848 %}
10849
10850 // Zero-extend convert int to long
10851 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
10852 %{
10853 match(Set dst (AndL (ConvI2L (LoadI src)) mask));
10854
10855 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10856 ins_encode %{
10857 __ movl($dst$$Register, $src$$Address);
10858 %}
10859 ins_pipe(ialu_reg_mem);
10860 %}
10861
10862 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
10863 %{
10864 match(Set dst (AndL src mask));
10865
10866 format %{ "movl $dst, $src\t# zero-extend long" %}
10867 ins_encode %{
10868 __ movl($dst$$Register, $src$$Register);
10869 %}
10870 ins_pipe(ialu_reg_reg);
10871 %}
10872
10873 instruct convL2I_reg_reg(rRegI dst, rRegL src)
10874 %{
10875 match(Set dst (ConvL2I src));
10876
10877 format %{ "movl $dst, $src\t# l2i" %}
10878 ins_encode %{
10879 __ movl($dst$$Register, $src$$Register);
10880 %}
10881 ins_pipe(ialu_reg_reg);
10882 %}
10883
10884
10885 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
10886 match(Set dst (MoveF2I src));
10887 effect(DEF dst, USE src);
10888
10889 ins_cost(125);
10890 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %}
10891 ins_encode %{
10892 __ movl($dst$$Register, Address(rsp, $src$$disp));
10893 %}
10894 ins_pipe(ialu_reg_mem);
10895 %}
10896
10897 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
10898 match(Set dst (MoveI2F src));
10899 effect(DEF dst, USE src);
10900
10901 ins_cost(125);
10902 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %}
10903 ins_encode %{
10904 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
10905 %}
10906 ins_pipe(pipe_slow);
10907 %}
10908
10909 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
10910 match(Set dst (MoveD2L src));
10911 effect(DEF dst, USE src);
10912
10913 ins_cost(125);
10914 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %}
10915 ins_encode %{
10916 __ movq($dst$$Register, Address(rsp, $src$$disp));
10917 %}
10918 ins_pipe(ialu_reg_mem);
10919 %}
10920
10921 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
10922 predicate(!UseXmmLoadAndClearUpper);
10923 match(Set dst (MoveL2D src));
10924 effect(DEF dst, USE src);
10925
10926 ins_cost(125);
10927 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %}
10928 ins_encode %{
10929 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10930 %}
10931 ins_pipe(pipe_slow);
10932 %}
10933
10934 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
10935 predicate(UseXmmLoadAndClearUpper);
10936 match(Set dst (MoveL2D src));
10937 effect(DEF dst, USE src);
10938
10939 ins_cost(125);
10940 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %}
10941 ins_encode %{
10942 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10943 %}
10944 ins_pipe(pipe_slow);
10945 %}
10946
10947
10948 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
10949 match(Set dst (MoveF2I src));
10950 effect(DEF dst, USE src);
10951
10952 ins_cost(95); // XXX
10953 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %}
10954 ins_encode %{
10955 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
10956 %}
10957 ins_pipe(pipe_slow);
10958 %}
10959
10960 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
10961 match(Set dst (MoveI2F src));
10962 effect(DEF dst, USE src);
10963
10964 ins_cost(100);
10965 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %}
10966 ins_encode %{
10967 __ movl(Address(rsp, $dst$$disp), $src$$Register);
10968 %}
10969 ins_pipe( ialu_mem_reg );
10970 %}
10971
10972 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
10973 match(Set dst (MoveD2L src));
10974 effect(DEF dst, USE src);
10975
10976 ins_cost(95); // XXX
10977 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %}
10978 ins_encode %{
10979 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
10980 %}
10981 ins_pipe(pipe_slow);
10982 %}
10983
10984 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
10985 match(Set dst (MoveL2D src));
10986 effect(DEF dst, USE src);
10987
10988 ins_cost(100);
10989 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %}
10990 ins_encode %{
10991 __ movq(Address(rsp, $dst$$disp), $src$$Register);
10992 %}
10993 ins_pipe(ialu_mem_reg);
10994 %}
10995
10996 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
10997 match(Set dst (MoveF2I src));
10998 effect(DEF dst, USE src);
10999 ins_cost(85);
11000 format %{ "movd $dst,$src\t# MoveF2I" %}
11001 ins_encode %{
11002 __ movdl($dst$$Register, $src$$XMMRegister);
11003 %}
11004 ins_pipe( pipe_slow );
11005 %}
11006
11007 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
11008 match(Set dst (MoveD2L src));
11009 effect(DEF dst, USE src);
11010 ins_cost(85);
11011 format %{ "movd $dst,$src\t# MoveD2L" %}
11012 ins_encode %{
11013 __ movdq($dst$$Register, $src$$XMMRegister);
11014 %}
11015 ins_pipe( pipe_slow );
11016 %}
11017
11018 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
11019 match(Set dst (MoveI2F src));
11020 effect(DEF dst, USE src);
11021 ins_cost(100);
11022 format %{ "movd $dst,$src\t# MoveI2F" %}
11023 ins_encode %{
11024 __ movdl($dst$$XMMRegister, $src$$Register);
11025 %}
11026 ins_pipe( pipe_slow );
11027 %}
11028
11029 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
11030 match(Set dst (MoveL2D src));
11031 effect(DEF dst, USE src);
11032 ins_cost(100);
11033 format %{ "movd $dst,$src\t# MoveL2D" %}
11034 ins_encode %{
11035 __ movdq($dst$$XMMRegister, $src$$Register);
11036 %}
11037 ins_pipe( pipe_slow );
11038 %}
11039
11040 // Fast clearing of an array
11041 // Small ClearArray non-AVX512.
11042 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero,
11043 Universe dummy, rFlagsReg cr)
11044 %{
11045 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2));
11046 match(Set dummy (ClearArray cnt base));
11047 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
11048
11049 format %{ $$template
11050 $$emit$$"xorq rax, rax\t# ClearArray:\n\t"
11051 $$emit$$"cmp InitArrayShortSize,rcx\n\t"
11052 $$emit$$"jg LARGE\n\t"
11053 $$emit$$"dec rcx\n\t"
11054 $$emit$$"js DONE\t# Zero length\n\t"
11055 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t"
11056 $$emit$$"dec rcx\n\t"
11057 $$emit$$"jge LOOP\n\t"
11058 $$emit$$"jmp DONE\n\t"
11059 $$emit$$"# LARGE:\n\t"
11060 if (UseFastStosb) {
11061 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t"
11062 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t"
11063 } else if (UseXMMForObjInit) {
11064 $$emit$$"mov rdi,rax\n\t"
11065 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t"
11066 $$emit$$"jmpq L_zero_64_bytes\n\t"
11067 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
11068 $$emit$$"vmovdqu ymm0,(rax)\n\t"
11069 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t"
11070 $$emit$$"add 0x40,rax\n\t"
11071 $$emit$$"# L_zero_64_bytes:\n\t"
11072 $$emit$$"sub 0x8,rcx\n\t"
11073 $$emit$$"jge L_loop\n\t"
11074 $$emit$$"add 0x4,rcx\n\t"
11075 $$emit$$"jl L_tail\n\t"
11076 $$emit$$"vmovdqu ymm0,(rax)\n\t"
11077 $$emit$$"add 0x20,rax\n\t"
11078 $$emit$$"sub 0x4,rcx\n\t"
11079 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
11080 $$emit$$"add 0x4,rcx\n\t"
11081 $$emit$$"jle L_end\n\t"
11082 $$emit$$"dec rcx\n\t"
11083 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
11084 $$emit$$"vmovq xmm0,(rax)\n\t"
11085 $$emit$$"add 0x8,rax\n\t"
11086 $$emit$$"dec rcx\n\t"
11087 $$emit$$"jge L_sloop\n\t"
11088 $$emit$$"# L_end:\n\t"
11089 } else {
11090 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t"
11091 }
11092 $$emit$$"# DONE"
11093 %}
11094 ins_encode %{
11095 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register,
11096 $tmp$$XMMRegister, false, knoreg);
11097 %}
11098 ins_pipe(pipe_slow);
11099 %}
11100
11101 // Small ClearArray AVX512 non-constant length.
11102 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero,
11103 Universe dummy, rFlagsReg cr)
11104 %{
11105 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2));
11106 match(Set dummy (ClearArray cnt base));
11107 ins_cost(125);
11108 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr);
11109
11110 format %{ $$template
11111 $$emit$$"xorq rax, rax\t# ClearArray:\n\t"
11112 $$emit$$"cmp InitArrayShortSize,rcx\n\t"
11113 $$emit$$"jg LARGE\n\t"
11114 $$emit$$"dec rcx\n\t"
11115 $$emit$$"js DONE\t# Zero length\n\t"
11116 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t"
11117 $$emit$$"dec rcx\n\t"
11118 $$emit$$"jge LOOP\n\t"
11119 $$emit$$"jmp DONE\n\t"
11120 $$emit$$"# LARGE:\n\t"
11121 if (UseFastStosb) {
11122 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t"
11123 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t"
11124 } else if (UseXMMForObjInit) {
11125 $$emit$$"mov rdi,rax\n\t"
11126 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t"
11127 $$emit$$"jmpq L_zero_64_bytes\n\t"
11128 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
11129 $$emit$$"vmovdqu ymm0,(rax)\n\t"
11130 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t"
11131 $$emit$$"add 0x40,rax\n\t"
11132 $$emit$$"# L_zero_64_bytes:\n\t"
11133 $$emit$$"sub 0x8,rcx\n\t"
11134 $$emit$$"jge L_loop\n\t"
11135 $$emit$$"add 0x4,rcx\n\t"
11136 $$emit$$"jl L_tail\n\t"
11137 $$emit$$"vmovdqu ymm0,(rax)\n\t"
11138 $$emit$$"add 0x20,rax\n\t"
11139 $$emit$$"sub 0x4,rcx\n\t"
11140 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
11141 $$emit$$"add 0x4,rcx\n\t"
11142 $$emit$$"jle L_end\n\t"
11143 $$emit$$"dec rcx\n\t"
11144 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
11145 $$emit$$"vmovq xmm0,(rax)\n\t"
11146 $$emit$$"add 0x8,rax\n\t"
11147 $$emit$$"dec rcx\n\t"
11148 $$emit$$"jge L_sloop\n\t"
11149 $$emit$$"# L_end:\n\t"
11150 } else {
11151 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t"
11152 }
11153 $$emit$$"# DONE"
11154 %}
11155 ins_encode %{
11156 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register,
11157 $tmp$$XMMRegister, false, $ktmp$$KRegister);
11158 %}
11159 ins_pipe(pipe_slow);
11160 %}
11161
11162 // Large ClearArray non-AVX512.
11163 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero,
11164 Universe dummy, rFlagsReg cr)
11165 %{
11166 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large());
11167 match(Set dummy (ClearArray cnt base));
11168 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
11169
11170 format %{ $$template
11171 if (UseFastStosb) {
11172 $$emit$$"xorq rax, rax\t# ClearArray:\n\t"
11173 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t"
11174 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--"
11175 } else if (UseXMMForObjInit) {
11176 $$emit$$"mov rdi,rax\t# ClearArray:\n\t"
11177 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t"
11178 $$emit$$"jmpq L_zero_64_bytes\n\t"
11179 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
11180 $$emit$$"vmovdqu ymm0,(rax)\n\t"
11181 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t"
11182 $$emit$$"add 0x40,rax\n\t"
11183 $$emit$$"# L_zero_64_bytes:\n\t"
11184 $$emit$$"sub 0x8,rcx\n\t"
11185 $$emit$$"jge L_loop\n\t"
11186 $$emit$$"add 0x4,rcx\n\t"
11187 $$emit$$"jl L_tail\n\t"
11188 $$emit$$"vmovdqu ymm0,(rax)\n\t"
11189 $$emit$$"add 0x20,rax\n\t"
11190 $$emit$$"sub 0x4,rcx\n\t"
11191 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
11192 $$emit$$"add 0x4,rcx\n\t"
11193 $$emit$$"jle L_end\n\t"
11194 $$emit$$"dec rcx\n\t"
11195 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
11196 $$emit$$"vmovq xmm0,(rax)\n\t"
11197 $$emit$$"add 0x8,rax\n\t"
11198 $$emit$$"dec rcx\n\t"
11199 $$emit$$"jge L_sloop\n\t"
11200 $$emit$$"# L_end:\n\t"
11201 } else {
11202 $$emit$$"xorq rax, rax\t# ClearArray:\n\t"
11203 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--"
11204 }
11205 %}
11206 ins_encode %{
11207 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register,
11208 $tmp$$XMMRegister, true, knoreg);
11209 %}
11210 ins_pipe(pipe_slow);
11211 %}
11212
11213 // Large ClearArray AVX512.
11214 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero,
11215 Universe dummy, rFlagsReg cr)
11216 %{
11217 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large());
11218 match(Set dummy (ClearArray cnt base));
11219 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr);
11220
11221 format %{ $$template
11222 if (UseFastStosb) {
11223 $$emit$$"xorq rax, rax\t# ClearArray:\n\t"
11224 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t"
11225 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--"
11226 } else if (UseXMMForObjInit) {
11227 $$emit$$"mov rdi,rax\t# ClearArray:\n\t"
11228 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t"
11229 $$emit$$"jmpq L_zero_64_bytes\n\t"
11230 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
11231 $$emit$$"vmovdqu ymm0,(rax)\n\t"
11232 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t"
11233 $$emit$$"add 0x40,rax\n\t"
11234 $$emit$$"# L_zero_64_bytes:\n\t"
11235 $$emit$$"sub 0x8,rcx\n\t"
11236 $$emit$$"jge L_loop\n\t"
11237 $$emit$$"add 0x4,rcx\n\t"
11238 $$emit$$"jl L_tail\n\t"
11239 $$emit$$"vmovdqu ymm0,(rax)\n\t"
11240 $$emit$$"add 0x20,rax\n\t"
11241 $$emit$$"sub 0x4,rcx\n\t"
11242 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
11243 $$emit$$"add 0x4,rcx\n\t"
11244 $$emit$$"jle L_end\n\t"
11245 $$emit$$"dec rcx\n\t"
11246 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
11247 $$emit$$"vmovq xmm0,(rax)\n\t"
11248 $$emit$$"add 0x8,rax\n\t"
11249 $$emit$$"dec rcx\n\t"
11250 $$emit$$"jge L_sloop\n\t"
11251 $$emit$$"# L_end:\n\t"
11252 } else {
11253 $$emit$$"xorq rax, rax\t# ClearArray:\n\t"
11254 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--"
11255 }
11256 %}
11257 ins_encode %{
11258 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register,
11259 $tmp$$XMMRegister, true, $ktmp$$KRegister);
11260 %}
11261 ins_pipe(pipe_slow);
11262 %}
11263
11264 // Small ClearArray AVX512 constant length.
11265 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr)
11266 %{
11267 predicate(!((ClearArrayNode*)n)->is_large() &&
11268 ((UseAVX > 2) && VM_Version::supports_avx512vlbw()));
11269 match(Set dummy (ClearArray cnt base));
11270 ins_cost(100);
11271 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr);
11272 format %{ "clear_mem_imm $base , $cnt \n\t" %}
11273 ins_encode %{
11274 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister);
11275 %}
11276 ins_pipe(pipe_slow);
11277 %}
11278
11279 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
11280 rax_RegI result, legRegD tmp1, rFlagsReg cr)
11281 %{
11282 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11283 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11284 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11285
11286 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11287 ins_encode %{
11288 __ string_compare($str1$$Register, $str2$$Register,
11289 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11290 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg);
11291 %}
11292 ins_pipe( pipe_slow );
11293 %}
11294
11295 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
11296 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr)
11297 %{
11298 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11299 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11300 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11301
11302 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11303 ins_encode %{
11304 __ string_compare($str1$$Register, $str2$$Register,
11305 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11306 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister);
11307 %}
11308 ins_pipe( pipe_slow );
11309 %}
11310
11311 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
11312 rax_RegI result, legRegD tmp1, rFlagsReg cr)
11313 %{
11314 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11315 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11316 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11317
11318 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11319 ins_encode %{
11320 __ string_compare($str1$$Register, $str2$$Register,
11321 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11322 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg);
11323 %}
11324 ins_pipe( pipe_slow );
11325 %}
11326
11327 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
11328 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr)
11329 %{
11330 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11331 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11332 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11333
11334 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11335 ins_encode %{
11336 __ string_compare($str1$$Register, $str2$$Register,
11337 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11338 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister);
11339 %}
11340 ins_pipe( pipe_slow );
11341 %}
11342
11343 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
11344 rax_RegI result, legRegD tmp1, rFlagsReg cr)
11345 %{
11346 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11347 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11348 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11349
11350 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11351 ins_encode %{
11352 __ string_compare($str1$$Register, $str2$$Register,
11353 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11354 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg);
11355 %}
11356 ins_pipe( pipe_slow );
11357 %}
11358
11359 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
11360 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr)
11361 %{
11362 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11363 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11364 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11365
11366 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11367 ins_encode %{
11368 __ string_compare($str1$$Register, $str2$$Register,
11369 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11370 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister);
11371 %}
11372 ins_pipe( pipe_slow );
11373 %}
11374
11375 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2,
11376 rax_RegI result, legRegD tmp1, rFlagsReg cr)
11377 %{
11378 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11379 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11380 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11381
11382 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11383 ins_encode %{
11384 __ string_compare($str2$$Register, $str1$$Register,
11385 $cnt2$$Register, $cnt1$$Register, $result$$Register,
11386 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg);
11387 %}
11388 ins_pipe( pipe_slow );
11389 %}
11390
11391 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2,
11392 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr)
11393 %{
11394 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11395 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11396 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11397
11398 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
11399 ins_encode %{
11400 __ string_compare($str2$$Register, $str1$$Register,
11401 $cnt2$$Register, $cnt1$$Register, $result$$Register,
11402 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister);
11403 %}
11404 ins_pipe( pipe_slow );
11405 %}
11406
11407 // fast search of substring with known size.
11408 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
11409 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
11410 %{
11411 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
11412 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
11413 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
11414
11415 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %}
11416 ins_encode %{
11417 int icnt2 = (int)$int_cnt2$$constant;
11418 if (icnt2 >= 16) {
11419 // IndexOf for constant substrings with size >= 16 elements
11420 // which don't need to be loaded through stack.
11421 __ string_indexofC8($str1$$Register, $str2$$Register,
11422 $cnt1$$Register, $cnt2$$Register,
11423 icnt2, $result$$Register,
11424 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
11425 } else {
11426 // Small strings are loaded through stack if they cross page boundary.
11427 __ string_indexof($str1$$Register, $str2$$Register,
11428 $cnt1$$Register, $cnt2$$Register,
11429 icnt2, $result$$Register,
11430 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
11431 }
11432 %}
11433 ins_pipe( pipe_slow );
11434 %}
11435
11436 // fast search of substring with known size.
11437 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
11438 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
11439 %{
11440 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
11441 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
11442 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
11443
11444 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %}
11445 ins_encode %{
11446 int icnt2 = (int)$int_cnt2$$constant;
11447 if (icnt2 >= 8) {
11448 // IndexOf for constant substrings with size >= 8 elements
11449 // which don't need to be loaded through stack.
11450 __ string_indexofC8($str1$$Register, $str2$$Register,
11451 $cnt1$$Register, $cnt2$$Register,
11452 icnt2, $result$$Register,
11453 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
11454 } else {
11455 // Small strings are loaded through stack if they cross page boundary.
11456 __ string_indexof($str1$$Register, $str2$$Register,
11457 $cnt1$$Register, $cnt2$$Register,
11458 icnt2, $result$$Register,
11459 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
11460 }
11461 %}
11462 ins_pipe( pipe_slow );
11463 %}
11464
11465 // fast search of substring with known size.
11466 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
11467 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
11468 %{
11469 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
11470 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
11471 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
11472
11473 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %}
11474 ins_encode %{
11475 int icnt2 = (int)$int_cnt2$$constant;
11476 if (icnt2 >= 8) {
11477 // IndexOf for constant substrings with size >= 8 elements
11478 // which don't need to be loaded through stack.
11479 __ string_indexofC8($str1$$Register, $str2$$Register,
11480 $cnt1$$Register, $cnt2$$Register,
11481 icnt2, $result$$Register,
11482 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
11483 } else {
11484 // Small strings are loaded through stack if they cross page boundary.
11485 __ string_indexof($str1$$Register, $str2$$Register,
11486 $cnt1$$Register, $cnt2$$Register,
11487 icnt2, $result$$Register,
11488 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
11489 }
11490 %}
11491 ins_pipe( pipe_slow );
11492 %}
11493
11494 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
11495 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr)
11496 %{
11497 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
11498 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11499 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
11500
11501 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
11502 ins_encode %{
11503 __ string_indexof($str1$$Register, $str2$$Register,
11504 $cnt1$$Register, $cnt2$$Register,
11505 (-1), $result$$Register,
11506 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
11507 %}
11508 ins_pipe( pipe_slow );
11509 %}
11510
11511 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
11512 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr)
11513 %{
11514 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
11515 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11516 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
11517
11518 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
11519 ins_encode %{
11520 __ string_indexof($str1$$Register, $str2$$Register,
11521 $cnt1$$Register, $cnt2$$Register,
11522 (-1), $result$$Register,
11523 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
11524 %}
11525 ins_pipe( pipe_slow );
11526 %}
11527
11528 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
11529 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr)
11530 %{
11531 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
11532 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11533 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
11534
11535 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
11536 ins_encode %{
11537 __ string_indexof($str1$$Register, $str2$$Register,
11538 $cnt1$$Register, $cnt2$$Register,
11539 (-1), $result$$Register,
11540 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
11541 %}
11542 ins_pipe( pipe_slow );
11543 %}
11544
11545 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch,
11546 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr)
11547 %{
11548 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U));
11549 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
11550 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr);
11551 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %}
11552 ins_encode %{
11553 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register,
11554 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register);
11555 %}
11556 ins_pipe( pipe_slow );
11557 %}
11558
11559 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch,
11560 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr)
11561 %{
11562 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
11563 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
11564 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr);
11565 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %}
11566 ins_encode %{
11567 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register,
11568 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register);
11569 %}
11570 ins_pipe( pipe_slow );
11571 %}
11572
11573 // fast string equals
11574 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
11575 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr)
11576 %{
11577 predicate(!VM_Version::supports_avx512vlbw());
11578 match(Set result (StrEquals (Binary str1 str2) cnt));
11579 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
11580
11581 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
11582 ins_encode %{
11583 __ arrays_equals(false, $str1$$Register, $str2$$Register,
11584 $cnt$$Register, $result$$Register, $tmp3$$Register,
11585 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg);
11586 %}
11587 ins_pipe( pipe_slow );
11588 %}
11589
11590 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
11591 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr)
11592 %{
11593 predicate(VM_Version::supports_avx512vlbw());
11594 match(Set result (StrEquals (Binary str1 str2) cnt));
11595 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
11596
11597 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
11598 ins_encode %{
11599 __ arrays_equals(false, $str1$$Register, $str2$$Register,
11600 $cnt$$Register, $result$$Register, $tmp3$$Register,
11601 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister);
11602 %}
11603 ins_pipe( pipe_slow );
11604 %}
11605
11606 // fast array equals
11607 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
11608 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
11609 %{
11610 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11611 match(Set result (AryEq ary1 ary2));
11612 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
11613
11614 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
11615 ins_encode %{
11616 __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
11617 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11618 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg);
11619 %}
11620 ins_pipe( pipe_slow );
11621 %}
11622
11623 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
11624 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
11625 %{
11626 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11627 match(Set result (AryEq ary1 ary2));
11628 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
11629
11630 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
11631 ins_encode %{
11632 __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
11633 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11634 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister);
11635 %}
11636 ins_pipe( pipe_slow );
11637 %}
11638
11639 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
11640 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
11641 %{
11642 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11643 match(Set result (AryEq ary1 ary2));
11644 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
11645
11646 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
11647 ins_encode %{
11648 __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
11649 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11650 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg);
11651 %}
11652 ins_pipe( pipe_slow );
11653 %}
11654
11655 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
11656 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
11657 %{
11658 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11659 match(Set result (AryEq ary1 ary2));
11660 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
11661
11662 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
11663 ins_encode %{
11664 __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
11665 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11666 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister);
11667 %}
11668 ins_pipe( pipe_slow );
11669 %}
11670
11671 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result,
11672 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,)
11673 %{
11674 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2());
11675 match(Set result (HasNegatives ary1 len));
11676 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr);
11677
11678 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %}
11679 ins_encode %{
11680 __ has_negatives($ary1$$Register, $len$$Register,
11681 $result$$Register, $tmp3$$Register,
11682 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg);
11683 %}
11684 ins_pipe( pipe_slow );
11685 %}
11686
11687 instruct has_negatives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result,
11688 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,)
11689 %{
11690 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2());
11691 match(Set result (HasNegatives ary1 len));
11692 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr);
11693
11694 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %}
11695 ins_encode %{
11696 __ has_negatives($ary1$$Register, $len$$Register,
11697 $result$$Register, $tmp3$$Register,
11698 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister);
11699 %}
11700 ins_pipe( pipe_slow );
11701 %}
11702
11703 // fast char[] to byte[] compression
11704 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3,
11705 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
11706 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2());
11707 match(Set result (StrCompressedCopy src (Binary dst len)));
11708 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst,
11709 USE_KILL len, KILL tmp5, KILL cr);
11710
11711 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %}
11712 ins_encode %{
11713 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
11714 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
11715 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register,
11716 knoreg, knoreg);
11717 %}
11718 ins_pipe( pipe_slow );
11719 %}
11720
11721 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3,
11722 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
11723 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2());
11724 match(Set result (StrCompressedCopy src (Binary dst len)));
11725 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst,
11726 USE_KILL len, KILL tmp5, KILL cr);
11727
11728 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %}
11729 ins_encode %{
11730 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
11731 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
11732 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register,
11733 $ktmp1$$KRegister, $ktmp2$$KRegister);
11734 %}
11735 ins_pipe( pipe_slow );
11736 %}
11737 // fast byte[] to char[] inflation
11738 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len,
11739 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{
11740 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2());
11741 match(Set dummy (StrInflatedCopy src (Binary dst len)));
11742 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
11743
11744 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %}
11745 ins_encode %{
11746 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
11747 $tmp1$$XMMRegister, $tmp2$$Register, knoreg);
11748 %}
11749 ins_pipe( pipe_slow );
11750 %}
11751
11752 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len,
11753 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{
11754 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2());
11755 match(Set dummy (StrInflatedCopy src (Binary dst len)));
11756 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
11757
11758 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %}
11759 ins_encode %{
11760 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
11761 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister);
11762 %}
11763 ins_pipe( pipe_slow );
11764 %}
11765
11766 // encode char[] to byte[] in ISO_8859_1
11767 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len,
11768 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4,
11769 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
11770 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
11771 match(Set result (EncodeISOArray src (Binary dst len)));
11772 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
11773
11774 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %}
11775 ins_encode %{
11776 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
11777 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
11778 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false);
11779 %}
11780 ins_pipe( pipe_slow );
11781 %}
11782
11783 // encode char[] to byte[] in ASCII
11784 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len,
11785 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4,
11786 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
11787 predicate(((EncodeISOArrayNode*)n)->is_ascii());
11788 match(Set result (EncodeISOArray src (Binary dst len)));
11789 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
11790
11791 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %}
11792 ins_encode %{
11793 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
11794 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
11795 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true);
11796 %}
11797 ins_pipe( pipe_slow );
11798 %}
11799
11800 //----------Overflow Math Instructions-----------------------------------------
11801
11802 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2)
11803 %{
11804 match(Set cr (OverflowAddI op1 op2));
11805 effect(DEF cr, USE_KILL op1, USE op2);
11806
11807 format %{ "addl $op1, $op2\t# overflow check int" %}
11808
11809 ins_encode %{
11810 __ addl($op1$$Register, $op2$$Register);
11811 %}
11812 ins_pipe(ialu_reg_reg);
11813 %}
11814
11815 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2)
11816 %{
11817 match(Set cr (OverflowAddI op1 op2));
11818 effect(DEF cr, USE_KILL op1, USE op2);
11819
11820 format %{ "addl $op1, $op2\t# overflow check int" %}
11821
11822 ins_encode %{
11823 __ addl($op1$$Register, $op2$$constant);
11824 %}
11825 ins_pipe(ialu_reg_reg);
11826 %}
11827
11828 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2)
11829 %{
11830 match(Set cr (OverflowAddL op1 op2));
11831 effect(DEF cr, USE_KILL op1, USE op2);
11832
11833 format %{ "addq $op1, $op2\t# overflow check long" %}
11834 ins_encode %{
11835 __ addq($op1$$Register, $op2$$Register);
11836 %}
11837 ins_pipe(ialu_reg_reg);
11838 %}
11839
11840 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2)
11841 %{
11842 match(Set cr (OverflowAddL op1 op2));
11843 effect(DEF cr, USE_KILL op1, USE op2);
11844
11845 format %{ "addq $op1, $op2\t# overflow check long" %}
11846 ins_encode %{
11847 __ addq($op1$$Register, $op2$$constant);
11848 %}
11849 ins_pipe(ialu_reg_reg);
11850 %}
11851
11852 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
11853 %{
11854 match(Set cr (OverflowSubI op1 op2));
11855
11856 format %{ "cmpl $op1, $op2\t# overflow check int" %}
11857 ins_encode %{
11858 __ cmpl($op1$$Register, $op2$$Register);
11859 %}
11860 ins_pipe(ialu_reg_reg);
11861 %}
11862
11863 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
11864 %{
11865 match(Set cr (OverflowSubI op1 op2));
11866
11867 format %{ "cmpl $op1, $op2\t# overflow check int" %}
11868 ins_encode %{
11869 __ cmpl($op1$$Register, $op2$$constant);
11870 %}
11871 ins_pipe(ialu_reg_reg);
11872 %}
11873
11874 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
11875 %{
11876 match(Set cr (OverflowSubL op1 op2));
11877
11878 format %{ "cmpq $op1, $op2\t# overflow check long" %}
11879 ins_encode %{
11880 __ cmpq($op1$$Register, $op2$$Register);
11881 %}
11882 ins_pipe(ialu_reg_reg);
11883 %}
11884
11885 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
11886 %{
11887 match(Set cr (OverflowSubL op1 op2));
11888
11889 format %{ "cmpq $op1, $op2\t# overflow check long" %}
11890 ins_encode %{
11891 __ cmpq($op1$$Register, $op2$$constant);
11892 %}
11893 ins_pipe(ialu_reg_reg);
11894 %}
11895
11896 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2)
11897 %{
11898 match(Set cr (OverflowSubI zero op2));
11899 effect(DEF cr, USE_KILL op2);
11900
11901 format %{ "negl $op2\t# overflow check int" %}
11902 ins_encode %{
11903 __ negl($op2$$Register);
11904 %}
11905 ins_pipe(ialu_reg_reg);
11906 %}
11907
11908 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2)
11909 %{
11910 match(Set cr (OverflowSubL zero op2));
11911 effect(DEF cr, USE_KILL op2);
11912
11913 format %{ "negq $op2\t# overflow check long" %}
11914 ins_encode %{
11915 __ negq($op2$$Register);
11916 %}
11917 ins_pipe(ialu_reg_reg);
11918 %}
11919
11920 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2)
11921 %{
11922 match(Set cr (OverflowMulI op1 op2));
11923 effect(DEF cr, USE_KILL op1, USE op2);
11924
11925 format %{ "imull $op1, $op2\t# overflow check int" %}
11926 ins_encode %{
11927 __ imull($op1$$Register, $op2$$Register);
11928 %}
11929 ins_pipe(ialu_reg_reg_alu0);
11930 %}
11931
11932 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp)
11933 %{
11934 match(Set cr (OverflowMulI op1 op2));
11935 effect(DEF cr, TEMP tmp, USE op1, USE op2);
11936
11937 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %}
11938 ins_encode %{
11939 __ imull($tmp$$Register, $op1$$Register, $op2$$constant);
11940 %}
11941 ins_pipe(ialu_reg_reg_alu0);
11942 %}
11943
11944 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2)
11945 %{
11946 match(Set cr (OverflowMulL op1 op2));
11947 effect(DEF cr, USE_KILL op1, USE op2);
11948
11949 format %{ "imulq $op1, $op2\t# overflow check long" %}
11950 ins_encode %{
11951 __ imulq($op1$$Register, $op2$$Register);
11952 %}
11953 ins_pipe(ialu_reg_reg_alu0);
11954 %}
11955
11956 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp)
11957 %{
11958 match(Set cr (OverflowMulL op1 op2));
11959 effect(DEF cr, TEMP tmp, USE op1, USE op2);
11960
11961 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %}
11962 ins_encode %{
11963 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant);
11964 %}
11965 ins_pipe(ialu_reg_reg_alu0);
11966 %}
11967
11968
11969 //----------Control Flow Instructions------------------------------------------
11970 // Signed compare Instructions
11971
11972 // XXX more variants!!
11973 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
11974 %{
11975 match(Set cr (CmpI op1 op2));
11976 effect(DEF cr, USE op1, USE op2);
11977
11978 format %{ "cmpl $op1, $op2" %}
11979 ins_encode %{
11980 __ cmpl($op1$$Register, $op2$$Register);
11981 %}
11982 ins_pipe(ialu_cr_reg_reg);
11983 %}
11984
11985 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
11986 %{
11987 match(Set cr (CmpI op1 op2));
11988
11989 format %{ "cmpl $op1, $op2" %}
11990 ins_encode %{
11991 __ cmpl($op1$$Register, $op2$$constant);
11992 %}
11993 ins_pipe(ialu_cr_reg_imm);
11994 %}
11995
11996 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2)
11997 %{
11998 match(Set cr (CmpI op1 (LoadI op2)));
11999
12000 ins_cost(500); // XXX
12001 format %{ "cmpl $op1, $op2" %}
12002 ins_encode %{
12003 __ cmpl($op1$$Register, $op2$$Address);
12004 %}
12005 ins_pipe(ialu_cr_reg_mem);
12006 %}
12007
12008 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero)
12009 %{
12010 match(Set cr (CmpI src zero));
12011
12012 format %{ "testl $src, $src" %}
12013 ins_encode %{
12014 __ testl($src$$Register, $src$$Register);
12015 %}
12016 ins_pipe(ialu_cr_reg_imm);
12017 %}
12018
12019 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero)
12020 %{
12021 match(Set cr (CmpI (AndI src con) zero));
12022
12023 format %{ "testl $src, $con" %}
12024 ins_encode %{
12025 __ testl($src$$Register, $con$$constant);
12026 %}
12027 ins_pipe(ialu_cr_reg_imm);
12028 %}
12029
12030 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero)
12031 %{
12032 match(Set cr (CmpI (AndI src (LoadI mem)) zero));
12033
12034 format %{ "testl $src, $mem" %}
12035 ins_encode %{
12036 __ testl($src$$Register, $mem$$Address);
12037 %}
12038 ins_pipe(ialu_cr_reg_mem);
12039 %}
12040
12041 // Unsigned compare Instructions; really, same as signed except they
12042 // produce an rFlagsRegU instead of rFlagsReg.
12043 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2)
12044 %{
12045 match(Set cr (CmpU op1 op2));
12046
12047 format %{ "cmpl $op1, $op2\t# unsigned" %}
12048 ins_encode %{
12049 __ cmpl($op1$$Register, $op2$$Register);
12050 %}
12051 ins_pipe(ialu_cr_reg_reg);
12052 %}
12053
12054 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2)
12055 %{
12056 match(Set cr (CmpU op1 op2));
12057
12058 format %{ "cmpl $op1, $op2\t# unsigned" %}
12059 ins_encode %{
12060 __ cmpl($op1$$Register, $op2$$constant);
12061 %}
12062 ins_pipe(ialu_cr_reg_imm);
12063 %}
12064
12065 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2)
12066 %{
12067 match(Set cr (CmpU op1 (LoadI op2)));
12068
12069 ins_cost(500); // XXX
12070 format %{ "cmpl $op1, $op2\t# unsigned" %}
12071 ins_encode %{
12072 __ cmpl($op1$$Register, $op2$$Address);
12073 %}
12074 ins_pipe(ialu_cr_reg_mem);
12075 %}
12076
12077 // // // Cisc-spilled version of cmpU_rReg
12078 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2)
12079 // //%{
12080 // // match(Set cr (CmpU (LoadI op1) op2));
12081 // //
12082 // // format %{ "CMPu $op1,$op2" %}
12083 // // ins_cost(500);
12084 // // opcode(0x39); /* Opcode 39 /r */
12085 // // ins_encode( OpcP, reg_mem( op1, op2) );
12086 // //%}
12087
12088 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero)
12089 %{
12090 match(Set cr (CmpU src zero));
12091
12092 format %{ "testl $src, $src\t# unsigned" %}
12093 ins_encode %{
12094 __ testl($src$$Register, $src$$Register);
12095 %}
12096 ins_pipe(ialu_cr_reg_imm);
12097 %}
12098
12099 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2)
12100 %{
12101 match(Set cr (CmpP op1 op2));
12102
12103 format %{ "cmpq $op1, $op2\t# ptr" %}
12104 ins_encode %{
12105 __ cmpq($op1$$Register, $op2$$Register);
12106 %}
12107 ins_pipe(ialu_cr_reg_reg);
12108 %}
12109
12110 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
12111 %{
12112 match(Set cr (CmpP op1 (LoadP op2)));
12113 predicate(n->in(2)->as_Load()->barrier_data() == 0);
12114
12115 ins_cost(500); // XXX
12116 format %{ "cmpq $op1, $op2\t# ptr" %}
12117 ins_encode %{
12118 __ cmpq($op1$$Register, $op2$$Address);
12119 %}
12120 ins_pipe(ialu_cr_reg_mem);
12121 %}
12122
12123 // // // Cisc-spilled version of cmpP_rReg
12124 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2)
12125 // //%{
12126 // // match(Set cr (CmpP (LoadP op1) op2));
12127 // //
12128 // // format %{ "CMPu $op1,$op2" %}
12129 // // ins_cost(500);
12130 // // opcode(0x39); /* Opcode 39 /r */
12131 // // ins_encode( OpcP, reg_mem( op1, op2) );
12132 // //%}
12133
12134 // XXX this is generalized by compP_rReg_mem???
12135 // Compare raw pointer (used in out-of-heap check).
12136 // Only works because non-oop pointers must be raw pointers
12137 // and raw pointers have no anti-dependencies.
12138 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
12139 %{
12140 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none &&
12141 n->in(2)->as_Load()->barrier_data() == 0);
12142 match(Set cr (CmpP op1 (LoadP op2)));
12143
12144 format %{ "cmpq $op1, $op2\t# raw ptr" %}
12145 ins_encode %{
12146 __ cmpq($op1$$Register, $op2$$Address);
12147 %}
12148 ins_pipe(ialu_cr_reg_mem);
12149 %}
12150
12151 // This will generate a signed flags result. This should be OK since
12152 // any compare to a zero should be eq/neq.
12153 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero)
12154 %{
12155 match(Set cr (CmpP src zero));
12156
12157 format %{ "testq $src, $src\t# ptr" %}
12158 ins_encode %{
12159 __ testq($src$$Register, $src$$Register);
12160 %}
12161 ins_pipe(ialu_cr_reg_imm);
12162 %}
12163
12164 // This will generate a signed flags result. This should be OK since
12165 // any compare to a zero should be eq/neq.
12166 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
12167 %{
12168 predicate((!UseCompressedOops || (CompressedOops::base() != NULL)) &&
12169 n->in(1)->as_Load()->barrier_data() == 0);
12170 match(Set cr (CmpP (LoadP op) zero));
12171
12172 ins_cost(500); // XXX
12173 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %}
12174 ins_encode %{
12175 __ testq($op$$Address, 0xFFFFFFFF);
12176 %}
12177 ins_pipe(ialu_cr_reg_imm);
12178 %}
12179
12180 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
12181 %{
12182 predicate(UseCompressedOops && (CompressedOops::base() == NULL) &&
12183 n->in(1)->as_Load()->barrier_data() == 0);
12184 match(Set cr (CmpP (LoadP mem) zero));
12185
12186 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
12187 ins_encode %{
12188 __ cmpq(r12, $mem$$Address);
12189 %}
12190 ins_pipe(ialu_cr_reg_mem);
12191 %}
12192
12193 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
12194 %{
12195 match(Set cr (CmpN op1 op2));
12196
12197 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
12198 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %}
12199 ins_pipe(ialu_cr_reg_reg);
12200 %}
12201
12202 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
12203 %{
12204 match(Set cr (CmpN src (LoadN mem)));
12205
12206 format %{ "cmpl $src, $mem\t# compressed ptr" %}
12207 ins_encode %{
12208 __ cmpl($src$$Register, $mem$$Address);
12209 %}
12210 ins_pipe(ialu_cr_reg_mem);
12211 %}
12212
12213 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{
12214 match(Set cr (CmpN op1 op2));
12215
12216 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
12217 ins_encode %{
12218 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant);
12219 %}
12220 ins_pipe(ialu_cr_reg_imm);
12221 %}
12222
12223 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src)
12224 %{
12225 match(Set cr (CmpN src (LoadN mem)));
12226
12227 format %{ "cmpl $mem, $src\t# compressed ptr" %}
12228 ins_encode %{
12229 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
12230 %}
12231 ins_pipe(ialu_cr_reg_mem);
12232 %}
12233
12234 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{
12235 match(Set cr (CmpN op1 op2));
12236
12237 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %}
12238 ins_encode %{
12239 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant);
12240 %}
12241 ins_pipe(ialu_cr_reg_imm);
12242 %}
12243
12244 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src)
12245 %{
12246 predicate(!UseCompactObjectHeaders);
12247 match(Set cr (CmpN src (LoadNKlass mem)));
12248
12249 format %{ "cmpl $mem, $src\t# compressed klass ptr" %}
12250 ins_encode %{
12251 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant);
12252 %}
12253 ins_pipe(ialu_cr_reg_mem);
12254 %}
12255
12256 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
12257 match(Set cr (CmpN src zero));
12258
12259 format %{ "testl $src, $src\t# compressed ptr" %}
12260 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
12261 ins_pipe(ialu_cr_reg_imm);
12262 %}
12263
12264 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
12265 %{
12266 predicate(CompressedOops::base() != NULL);
12267 match(Set cr (CmpN (LoadN mem) zero));
12268
12269 ins_cost(500); // XXX
12270 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
12271 ins_encode %{
12272 __ cmpl($mem$$Address, (int)0xFFFFFFFF);
12273 %}
12274 ins_pipe(ialu_cr_reg_mem);
12275 %}
12276
12277 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
12278 %{
12279 predicate(CompressedOops::base() == NULL);
12280 match(Set cr (CmpN (LoadN mem) zero));
12281
12282 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
12283 ins_encode %{
12284 __ cmpl(r12, $mem$$Address);
12285 %}
12286 ins_pipe(ialu_cr_reg_mem);
12287 %}
12288
12289 // Yanked all unsigned pointer compare operations.
12290 // Pointer compares are done with CmpP which is already unsigned.
12291
12292 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
12293 %{
12294 match(Set cr (CmpL op1 op2));
12295
12296 format %{ "cmpq $op1, $op2" %}
12297 ins_encode %{
12298 __ cmpq($op1$$Register, $op2$$Register);
12299 %}
12300 ins_pipe(ialu_cr_reg_reg);
12301 %}
12302
12303 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
12304 %{
12305 match(Set cr (CmpL op1 op2));
12306
12307 format %{ "cmpq $op1, $op2" %}
12308 ins_encode %{
12309 __ cmpq($op1$$Register, $op2$$constant);
12310 %}
12311 ins_pipe(ialu_cr_reg_imm);
12312 %}
12313
12314 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2)
12315 %{
12316 match(Set cr (CmpL op1 (LoadL op2)));
12317
12318 format %{ "cmpq $op1, $op2" %}
12319 ins_encode %{
12320 __ cmpq($op1$$Register, $op2$$Address);
12321 %}
12322 ins_pipe(ialu_cr_reg_mem);
12323 %}
12324
12325 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero)
12326 %{
12327 match(Set cr (CmpL src zero));
12328
12329 format %{ "testq $src, $src" %}
12330 ins_encode %{
12331 __ testq($src$$Register, $src$$Register);
12332 %}
12333 ins_pipe(ialu_cr_reg_imm);
12334 %}
12335
12336 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero)
12337 %{
12338 match(Set cr (CmpL (AndL src con) zero));
12339
12340 format %{ "testq $src, $con\t# long" %}
12341 ins_encode %{
12342 __ testq($src$$Register, $con$$constant);
12343 %}
12344 ins_pipe(ialu_cr_reg_imm);
12345 %}
12346
12347 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero)
12348 %{
12349 match(Set cr (CmpL (AndL src (LoadL mem)) zero));
12350
12351 format %{ "testq $src, $mem" %}
12352 ins_encode %{
12353 __ testq($src$$Register, $mem$$Address);
12354 %}
12355 ins_pipe(ialu_cr_reg_mem);
12356 %}
12357
12358 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero)
12359 %{
12360 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero));
12361
12362 format %{ "testq $src, $mem" %}
12363 ins_encode %{
12364 __ testq($src$$Register, $mem$$Address);
12365 %}
12366 ins_pipe(ialu_cr_reg_mem);
12367 %}
12368
12369 // Manifest a CmpL result in an integer register. Very painful.
12370 // This is the test to avoid.
12371 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
12372 %{
12373 match(Set dst (CmpL3 src1 src2));
12374 effect(KILL flags);
12375
12376 ins_cost(275); // XXX
12377 format %{ "cmpq $src1, $src2\t# CmpL3\n\t"
12378 "movl $dst, -1\n\t"
12379 "jl,s done\n\t"
12380 "setne $dst\n\t"
12381 "movzbl $dst, $dst\n\t"
12382 "done:" %}
12383 ins_encode %{
12384 Label done;
12385 __ cmpq($src1$$Register, $src2$$Register);
12386 __ movl($dst$$Register, -1);
12387 __ jccb(Assembler::less, done);
12388 __ setne($dst$$Register);
12389 __ movzbl($dst$$Register, $dst$$Register);
12390 __ bind(done);
12391 %}
12392 ins_pipe(pipe_slow);
12393 %}
12394
12395 // Unsigned long compare Instructions; really, same as signed long except they
12396 // produce an rFlagsRegU instead of rFlagsReg.
12397 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2)
12398 %{
12399 match(Set cr (CmpUL op1 op2));
12400
12401 format %{ "cmpq $op1, $op2\t# unsigned" %}
12402 ins_encode %{
12403 __ cmpq($op1$$Register, $op2$$Register);
12404 %}
12405 ins_pipe(ialu_cr_reg_reg);
12406 %}
12407
12408 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2)
12409 %{
12410 match(Set cr (CmpUL op1 op2));
12411
12412 format %{ "cmpq $op1, $op2\t# unsigned" %}
12413 ins_encode %{
12414 __ cmpq($op1$$Register, $op2$$constant);
12415 %}
12416 ins_pipe(ialu_cr_reg_imm);
12417 %}
12418
12419 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2)
12420 %{
12421 match(Set cr (CmpUL op1 (LoadL op2)));
12422
12423 format %{ "cmpq $op1, $op2\t# unsigned" %}
12424 ins_encode %{
12425 __ cmpq($op1$$Register, $op2$$Address);
12426 %}
12427 ins_pipe(ialu_cr_reg_mem);
12428 %}
12429
12430 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero)
12431 %{
12432 match(Set cr (CmpUL src zero));
12433
12434 format %{ "testq $src, $src\t# unsigned" %}
12435 ins_encode %{
12436 __ testq($src$$Register, $src$$Register);
12437 %}
12438 ins_pipe(ialu_cr_reg_imm);
12439 %}
12440
12441 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm)
12442 %{
12443 match(Set cr (CmpI (LoadB mem) imm));
12444
12445 ins_cost(125);
12446 format %{ "cmpb $mem, $imm" %}
12447 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %}
12448 ins_pipe(ialu_cr_reg_mem);
12449 %}
12450
12451 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero)
12452 %{
12453 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero));
12454
12455 ins_cost(125);
12456 format %{ "testb $mem, $imm\t# ubyte" %}
12457 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %}
12458 ins_pipe(ialu_cr_reg_mem);
12459 %}
12460
12461 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero)
12462 %{
12463 match(Set cr (CmpI (AndI (LoadB mem) imm) zero));
12464
12465 ins_cost(125);
12466 format %{ "testb $mem, $imm\t# byte" %}
12467 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %}
12468 ins_pipe(ialu_cr_reg_mem);
12469 %}
12470
12471 //----------Max and Min--------------------------------------------------------
12472 // Min Instructions
12473
12474 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr)
12475 %{
12476 effect(USE_DEF dst, USE src, USE cr);
12477
12478 format %{ "cmovlgt $dst, $src\t# min" %}
12479 ins_encode %{
12480 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register);
12481 %}
12482 ins_pipe(pipe_cmov_reg);
12483 %}
12484
12485
12486 instruct minI_rReg(rRegI dst, rRegI src)
12487 %{
12488 match(Set dst (MinI dst src));
12489
12490 ins_cost(200);
12491 expand %{
12492 rFlagsReg cr;
12493 compI_rReg(cr, dst, src);
12494 cmovI_reg_g(dst, src, cr);
12495 %}
12496 %}
12497
12498 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr)
12499 %{
12500 effect(USE_DEF dst, USE src, USE cr);
12501
12502 format %{ "cmovllt $dst, $src\t# max" %}
12503 ins_encode %{
12504 __ cmovl(Assembler::less, $dst$$Register, $src$$Register);
12505 %}
12506 ins_pipe(pipe_cmov_reg);
12507 %}
12508
12509
12510 instruct maxI_rReg(rRegI dst, rRegI src)
12511 %{
12512 match(Set dst (MaxI dst src));
12513
12514 ins_cost(200);
12515 expand %{
12516 rFlagsReg cr;
12517 compI_rReg(cr, dst, src);
12518 cmovI_reg_l(dst, src, cr);
12519 %}
12520 %}
12521
12522 // ============================================================================
12523 // Branch Instructions
12524
12525 // Jump Direct - Label defines a relative address from JMP+1
12526 instruct jmpDir(label labl)
12527 %{
12528 match(Goto);
12529 effect(USE labl);
12530
12531 ins_cost(300);
12532 format %{ "jmp $labl" %}
12533 size(5);
12534 ins_encode %{
12535 Label* L = $labl$$label;
12536 __ jmp(*L, false); // Always long jump
12537 %}
12538 ins_pipe(pipe_jmp);
12539 %}
12540
12541 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12542 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl)
12543 %{
12544 match(If cop cr);
12545 effect(USE labl);
12546
12547 ins_cost(300);
12548 format %{ "j$cop $labl" %}
12549 size(6);
12550 ins_encode %{
12551 Label* L = $labl$$label;
12552 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12553 %}
12554 ins_pipe(pipe_jcc);
12555 %}
12556
12557 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12558 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
12559 %{
12560 predicate(!n->has_vector_mask_set());
12561 match(CountedLoopEnd cop cr);
12562 effect(USE labl);
12563
12564 ins_cost(300);
12565 format %{ "j$cop $labl\t# loop end" %}
12566 size(6);
12567 ins_encode %{
12568 Label* L = $labl$$label;
12569 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12570 %}
12571 ins_pipe(pipe_jcc);
12572 %}
12573
12574 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12575 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12576 predicate(!n->has_vector_mask_set());
12577 match(CountedLoopEnd cop cmp);
12578 effect(USE labl);
12579
12580 ins_cost(300);
12581 format %{ "j$cop,u $labl\t# loop end" %}
12582 size(6);
12583 ins_encode %{
12584 Label* L = $labl$$label;
12585 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12586 %}
12587 ins_pipe(pipe_jcc);
12588 %}
12589
12590 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12591 predicate(!n->has_vector_mask_set());
12592 match(CountedLoopEnd cop cmp);
12593 effect(USE labl);
12594
12595 ins_cost(200);
12596 format %{ "j$cop,u $labl\t# loop end" %}
12597 size(6);
12598 ins_encode %{
12599 Label* L = $labl$$label;
12600 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12601 %}
12602 ins_pipe(pipe_jcc);
12603 %}
12604
12605 // mask version
12606 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12607 // Bounded mask operand used in following patten is needed for
12608 // post-loop multiversioning.
12609 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, kReg_K1 ktmp, rFlagsReg cr, label labl)
12610 %{
12611 predicate(PostLoopMultiversioning && n->has_vector_mask_set());
12612 match(CountedLoopEnd cop cr);
12613 effect(USE labl, TEMP ktmp);
12614
12615 ins_cost(400);
12616 format %{ "j$cop $labl\t# loop end\n\t"
12617 "restorevectmask \t# vector mask restore for loops" %}
12618 size(10);
12619 ins_encode %{
12620 Label* L = $labl$$label;
12621 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12622 __ restorevectmask($ktmp$$KRegister);
12623 %}
12624 ins_pipe(pipe_jcc);
12625 %}
12626
12627 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12628 // Bounded mask operand used in following patten is needed for
12629 // post-loop multiversioning.
12630 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, kReg_K1 ktmp, rFlagsRegU cmp, label labl) %{
12631 predicate(PostLoopMultiversioning && n->has_vector_mask_set());
12632 match(CountedLoopEnd cop cmp);
12633 effect(USE labl, TEMP ktmp);
12634
12635 ins_cost(400);
12636 format %{ "j$cop,u $labl\t# loop end\n\t"
12637 "restorevectmask \t# vector mask restore for loops" %}
12638 size(10);
12639 ins_encode %{
12640 Label* L = $labl$$label;
12641 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12642 __ restorevectmask($ktmp$$KRegister);
12643 %}
12644 ins_pipe(pipe_jcc);
12645 %}
12646
12647 // Bounded mask operand used in following patten is needed for
12648 // post-loop multiversioning.
12649 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, kReg_K1 ktmp, rFlagsRegUCF cmp, label labl) %{
12650 predicate(PostLoopMultiversioning && n->has_vector_mask_set());
12651 match(CountedLoopEnd cop cmp);
12652 effect(USE labl, TEMP ktmp);
12653
12654 ins_cost(300);
12655 format %{ "j$cop,u $labl\t# loop end\n\t"
12656 "restorevectmask \t# vector mask restore for loops" %}
12657 size(10);
12658 ins_encode %{
12659 Label* L = $labl$$label;
12660 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12661 __ restorevectmask($ktmp$$KRegister);
12662 %}
12663 ins_pipe(pipe_jcc);
12664 %}
12665
12666 // Jump Direct Conditional - using unsigned comparison
12667 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12668 match(If cop cmp);
12669 effect(USE labl);
12670
12671 ins_cost(300);
12672 format %{ "j$cop,u $labl" %}
12673 size(6);
12674 ins_encode %{
12675 Label* L = $labl$$label;
12676 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12677 %}
12678 ins_pipe(pipe_jcc);
12679 %}
12680
12681 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12682 match(If cop cmp);
12683 effect(USE labl);
12684
12685 ins_cost(200);
12686 format %{ "j$cop,u $labl" %}
12687 size(6);
12688 ins_encode %{
12689 Label* L = $labl$$label;
12690 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
12691 %}
12692 ins_pipe(pipe_jcc);
12693 %}
12694
12695 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
12696 match(If cop cmp);
12697 effect(USE labl);
12698
12699 ins_cost(200);
12700 format %{ $$template
12701 if ($cop$$cmpcode == Assembler::notEqual) {
12702 $$emit$$"jp,u $labl\n\t"
12703 $$emit$$"j$cop,u $labl"
12704 } else {
12705 $$emit$$"jp,u done\n\t"
12706 $$emit$$"j$cop,u $labl\n\t"
12707 $$emit$$"done:"
12708 }
12709 %}
12710 ins_encode %{
12711 Label* l = $labl$$label;
12712 if ($cop$$cmpcode == Assembler::notEqual) {
12713 __ jcc(Assembler::parity, *l, false);
12714 __ jcc(Assembler::notEqual, *l, false);
12715 } else if ($cop$$cmpcode == Assembler::equal) {
12716 Label done;
12717 __ jccb(Assembler::parity, done);
12718 __ jcc(Assembler::equal, *l, false);
12719 __ bind(done);
12720 } else {
12721 ShouldNotReachHere();
12722 }
12723 %}
12724 ins_pipe(pipe_jcc);
12725 %}
12726
12727 // ============================================================================
12728 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
12729 // superklass array for an instance of the superklass. Set a hidden
12730 // internal cache on a hit (cache is checked with exposed code in
12731 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The
12732 // encoding ALSO sets flags.
12733
12734 instruct partialSubtypeCheck(rdi_RegP result,
12735 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
12736 rFlagsReg cr)
12737 %{
12738 match(Set result (PartialSubtypeCheck sub super));
12739 effect(KILL rcx, KILL cr);
12740
12741 ins_cost(1100); // slightly larger than the next version
12742 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
12743 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t"
12744 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t"
12745 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t"
12746 "jne,s miss\t\t# Missed: rdi not-zero\n\t"
12747 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
12748 "xorq $result, $result\t\t Hit: rdi zero\n\t"
12749 "miss:\t" %}
12750
12751 opcode(0x1); // Force a XOR of RDI
12752 ins_encode(enc_PartialSubtypeCheck());
12753 ins_pipe(pipe_slow);
12754 %}
12755
12756 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr,
12757 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
12758 immP0 zero,
12759 rdi_RegP result)
12760 %{
12761 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
12762 effect(KILL rcx, KILL result);
12763
12764 ins_cost(1000);
12765 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
12766 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t"
12767 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t"
12768 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t"
12769 "jne,s miss\t\t# Missed: flags nz\n\t"
12770 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
12771 "miss:\t" %}
12772
12773 opcode(0x0); // No need to XOR RDI
12774 ins_encode(enc_PartialSubtypeCheck());
12775 ins_pipe(pipe_slow);
12776 %}
12777
12778 // ============================================================================
12779 // Branch Instructions -- short offset versions
12780 //
12781 // These instructions are used to replace jumps of a long offset (the default
12782 // match) with jumps of a shorter offset. These instructions are all tagged
12783 // with the ins_short_branch attribute, which causes the ADLC to suppress the
12784 // match rules in general matching. Instead, the ADLC generates a conversion
12785 // method in the MachNode which can be used to do in-place replacement of the
12786 // long variant with the shorter variant. The compiler will determine if a
12787 // branch can be taken by the is_short_branch_offset() predicate in the machine
12788 // specific code section of the file.
12789
12790 // Jump Direct - Label defines a relative address from JMP+1
12791 instruct jmpDir_short(label labl) %{
12792 match(Goto);
12793 effect(USE labl);
12794
12795 ins_cost(300);
12796 format %{ "jmp,s $labl" %}
12797 size(2);
12798 ins_encode %{
12799 Label* L = $labl$$label;
12800 __ jmpb(*L);
12801 %}
12802 ins_pipe(pipe_jmp);
12803 ins_short_branch(1);
12804 %}
12805
12806 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12807 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
12808 match(If cop cr);
12809 effect(USE labl);
12810
12811 ins_cost(300);
12812 format %{ "j$cop,s $labl" %}
12813 size(2);
12814 ins_encode %{
12815 Label* L = $labl$$label;
12816 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12817 %}
12818 ins_pipe(pipe_jcc);
12819 ins_short_branch(1);
12820 %}
12821
12822 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12823 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
12824 match(CountedLoopEnd cop cr);
12825 effect(USE labl);
12826
12827 ins_cost(300);
12828 format %{ "j$cop,s $labl\t# loop end" %}
12829 size(2);
12830 ins_encode %{
12831 Label* L = $labl$$label;
12832 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12833 %}
12834 ins_pipe(pipe_jcc);
12835 ins_short_branch(1);
12836 %}
12837
12838 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12839 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12840 match(CountedLoopEnd cop cmp);
12841 effect(USE labl);
12842
12843 ins_cost(300);
12844 format %{ "j$cop,us $labl\t# loop end" %}
12845 size(2);
12846 ins_encode %{
12847 Label* L = $labl$$label;
12848 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12849 %}
12850 ins_pipe(pipe_jcc);
12851 ins_short_branch(1);
12852 %}
12853
12854 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12855 match(CountedLoopEnd cop cmp);
12856 effect(USE labl);
12857
12858 ins_cost(300);
12859 format %{ "j$cop,us $labl\t# loop end" %}
12860 size(2);
12861 ins_encode %{
12862 Label* L = $labl$$label;
12863 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12864 %}
12865 ins_pipe(pipe_jcc);
12866 ins_short_branch(1);
12867 %}
12868
12869 // Jump Direct Conditional - using unsigned comparison
12870 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12871 match(If cop cmp);
12872 effect(USE labl);
12873
12874 ins_cost(300);
12875 format %{ "j$cop,us $labl" %}
12876 size(2);
12877 ins_encode %{
12878 Label* L = $labl$$label;
12879 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12880 %}
12881 ins_pipe(pipe_jcc);
12882 ins_short_branch(1);
12883 %}
12884
12885 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12886 match(If cop cmp);
12887 effect(USE labl);
12888
12889 ins_cost(300);
12890 format %{ "j$cop,us $labl" %}
12891 size(2);
12892 ins_encode %{
12893 Label* L = $labl$$label;
12894 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
12895 %}
12896 ins_pipe(pipe_jcc);
12897 ins_short_branch(1);
12898 %}
12899
12900 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
12901 match(If cop cmp);
12902 effect(USE labl);
12903
12904 ins_cost(300);
12905 format %{ $$template
12906 if ($cop$$cmpcode == Assembler::notEqual) {
12907 $$emit$$"jp,u,s $labl\n\t"
12908 $$emit$$"j$cop,u,s $labl"
12909 } else {
12910 $$emit$$"jp,u,s done\n\t"
12911 $$emit$$"j$cop,u,s $labl\n\t"
12912 $$emit$$"done:"
12913 }
12914 %}
12915 size(4);
12916 ins_encode %{
12917 Label* l = $labl$$label;
12918 if ($cop$$cmpcode == Assembler::notEqual) {
12919 __ jccb(Assembler::parity, *l);
12920 __ jccb(Assembler::notEqual, *l);
12921 } else if ($cop$$cmpcode == Assembler::equal) {
12922 Label done;
12923 __ jccb(Assembler::parity, done);
12924 __ jccb(Assembler::equal, *l);
12925 __ bind(done);
12926 } else {
12927 ShouldNotReachHere();
12928 }
12929 %}
12930 ins_pipe(pipe_jcc);
12931 ins_short_branch(1);
12932 %}
12933
12934 // ============================================================================
12935 // inlined locking and unlocking
12936
12937 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{
12938 predicate(Compile::current()->use_rtm());
12939 match(Set cr (FastLock object box));
12940 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box);
12941 ins_cost(300);
12942 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %}
12943 ins_encode %{
12944 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
12945 $scr$$Register, $cx1$$Register, $cx2$$Register, r15_thread,
12946 _counters, _rtm_counters, _stack_rtm_counters,
12947 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(),
12948 true, ra_->C->profile_rtm());
12949 %}
12950 ins_pipe(pipe_slow);
12951 %}
12952
12953 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr, rRegP cx1) %{
12954 predicate(LockingMode != LM_LIGHTWEIGHT && !Compile::current()->use_rtm());
12955 match(Set cr (FastLock object box));
12956 effect(TEMP tmp, TEMP scr, TEMP cx1, USE_KILL box);
12957 ins_cost(300);
12958 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
12959 ins_encode %{
12960 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
12961 $scr$$Register, $cx1$$Register, noreg, r15_thread, _counters, NULL, NULL, NULL, false, false);
12962 %}
12963 ins_pipe(pipe_slow);
12964 %}
12965
12966 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{
12967 predicate(LockingMode != LM_LIGHTWEIGHT);
12968 match(Set cr (FastUnlock object box));
12969 effect(TEMP tmp, USE_KILL box);
12970 ins_cost(300);
12971 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
12972 ins_encode %{
12973 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm());
12974 %}
12975 ins_pipe(pipe_slow);
12976 %}
12977
12978 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{
12979 predicate(LockingMode == LM_LIGHTWEIGHT);
12980 match(Set cr (FastLock object box));
12981 effect(TEMP rax_reg, TEMP tmp, USE_KILL box);
12982 ins_cost(300);
12983 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %}
12984 ins_encode %{
12985 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread);
12986 %}
12987 ins_pipe(pipe_slow);
12988 %}
12989
12990 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{
12991 predicate(LockingMode == LM_LIGHTWEIGHT);
12992 match(Set cr (FastUnlock object rax_reg));
12993 effect(TEMP tmp, USE_KILL rax_reg);
12994 ins_cost(300);
12995 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %}
12996 ins_encode %{
12997 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread);
12998 %}
12999 ins_pipe(pipe_slow);
13000 %}
13001
13002
13003 // ============================================================================
13004 // Safepoint Instructions
13005 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll)
13006 %{
13007 match(SafePoint poll);
13008 effect(KILL cr, USE poll);
13009
13010 format %{ "testl rax, [$poll]\t"
13011 "# Safepoint: poll for GC" %}
13012 ins_cost(125);
13013 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */
13014 ins_encode %{
13015 __ relocate(relocInfo::poll_type);
13016 address pre_pc = __ pc();
13017 __ testl(rax, Address($poll$$Register, 0));
13018 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]");
13019 %}
13020 ins_pipe(ialu_reg_mem);
13021 %}
13022
13023 // ============================================================================
13024 // Procedure Call/Return Instructions
13025 // Call Java Static Instruction
13026 // Note: If this code changes, the corresponding ret_addr_offset() and
13027 // compute_padding() functions will have to be adjusted.
13028 instruct CallStaticJavaDirect(method meth) %{
13029 match(CallStaticJava);
13030 effect(USE meth);
13031
13032 ins_cost(300);
13033 format %{ "call,static " %}
13034 opcode(0xE8); /* E8 cd */
13035 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog);
13036 ins_pipe(pipe_slow);
13037 ins_alignment(4);
13038 %}
13039
13040 // Call Java Dynamic Instruction
13041 // Note: If this code changes, the corresponding ret_addr_offset() and
13042 // compute_padding() functions will have to be adjusted.
13043 instruct CallDynamicJavaDirect(method meth)
13044 %{
13045 match(CallDynamicJava);
13046 effect(USE meth);
13047
13048 ins_cost(300);
13049 format %{ "movq rax, #Universe::non_oop_word()\n\t"
13050 "call,dynamic " %}
13051 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog);
13052 ins_pipe(pipe_slow);
13053 ins_alignment(4);
13054 %}
13055
13056 // Call Runtime Instruction
13057 instruct CallRuntimeDirect(method meth)
13058 %{
13059 match(CallRuntime);
13060 effect(USE meth);
13061
13062 ins_cost(300);
13063 format %{ "call,runtime " %}
13064 ins_encode(clear_avx, Java_To_Runtime(meth));
13065 ins_pipe(pipe_slow);
13066 %}
13067
13068 // Call runtime without safepoint
13069 instruct CallLeafDirect(method meth)
13070 %{
13071 match(CallLeaf);
13072 effect(USE meth);
13073
13074 ins_cost(300);
13075 format %{ "call_leaf,runtime " %}
13076 ins_encode(clear_avx, Java_To_Runtime(meth));
13077 ins_pipe(pipe_slow);
13078 %}
13079
13080 // Call runtime without safepoint and with vector arguments
13081 instruct CallLeafDirectVector(method meth)
13082 %{
13083 match(CallLeafVector);
13084 effect(USE meth);
13085
13086 ins_cost(300);
13087 format %{ "call_leaf,vector " %}
13088 ins_encode(Java_To_Runtime(meth));
13089 ins_pipe(pipe_slow);
13090 %}
13091
13092 //
13093 instruct CallNativeDirect(method meth)
13094 %{
13095 match(CallNative);
13096 effect(USE meth);
13097
13098 ins_cost(300);
13099 format %{ "call_native " %}
13100 ins_encode(clear_avx, Java_To_Runtime(meth));
13101 ins_pipe(pipe_slow);
13102 %}
13103
13104 // Call runtime without safepoint
13105 instruct CallLeafNoFPDirect(method meth)
13106 %{
13107 match(CallLeafNoFP);
13108 effect(USE meth);
13109
13110 ins_cost(300);
13111 format %{ "call_leaf_nofp,runtime " %}
13112 ins_encode(clear_avx, Java_To_Runtime(meth));
13113 ins_pipe(pipe_slow);
13114 %}
13115
13116 // Return Instruction
13117 // Remove the return address & jump to it.
13118 // Notice: We always emit a nop after a ret to make sure there is room
13119 // for safepoint patching
13120 instruct Ret()
13121 %{
13122 match(Return);
13123
13124 format %{ "ret" %}
13125 ins_encode %{
13126 __ ret(0);
13127 %}
13128 ins_pipe(pipe_jmp);
13129 %}
13130
13131 // Tail Call; Jump from runtime stub to Java code.
13132 // Also known as an 'interprocedural jump'.
13133 // Target of jump will eventually return to caller.
13134 // TailJump below removes the return address.
13135 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr)
13136 %{
13137 match(TailCall jump_target method_ptr);
13138
13139 ins_cost(300);
13140 format %{ "jmp $jump_target\t# rbx holds method" %}
13141 ins_encode %{
13142 __ jmp($jump_target$$Register);
13143 %}
13144 ins_pipe(pipe_jmp);
13145 %}
13146
13147 // Tail Jump; remove the return address; jump to target.
13148 // TailCall above leaves the return address around.
13149 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop)
13150 %{
13151 match(TailJump jump_target ex_oop);
13152
13153 ins_cost(300);
13154 format %{ "popq rdx\t# pop return address\n\t"
13155 "jmp $jump_target" %}
13156 ins_encode %{
13157 __ popq(as_Register(RDX_enc));
13158 __ jmp($jump_target$$Register);
13159 %}
13160 ins_pipe(pipe_jmp);
13161 %}
13162
13163 // Create exception oop: created by stack-crawling runtime code.
13164 // Created exception is now available to this handler, and is setup
13165 // just prior to jumping to this handler. No code emitted.
13166 instruct CreateException(rax_RegP ex_oop)
13167 %{
13168 match(Set ex_oop (CreateEx));
13169
13170 size(0);
13171 // use the following format syntax
13172 format %{ "# exception oop is in rax; no code emitted" %}
13173 ins_encode();
13174 ins_pipe(empty);
13175 %}
13176
13177 // Rethrow exception:
13178 // The exception oop will come in the first argument position.
13179 // Then JUMP (not call) to the rethrow stub code.
13180 instruct RethrowException()
13181 %{
13182 match(Rethrow);
13183
13184 // use the following format syntax
13185 format %{ "jmp rethrow_stub" %}
13186 ins_encode(enc_rethrow);
13187 ins_pipe(pipe_jmp);
13188 %}
13189
13190 // ============================================================================
13191 // This name is KNOWN by the ADLC and cannot be changed.
13192 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
13193 // for this guy.
13194 instruct tlsLoadP(r15_RegP dst) %{
13195 match(Set dst (ThreadLocal));
13196 effect(DEF dst);
13197
13198 size(0);
13199 format %{ "# TLS is in R15" %}
13200 ins_encode( /*empty encoding*/ );
13201 ins_pipe(ialu_reg_reg);
13202 %}
13203
13204
13205 //----------PEEPHOLE RULES-----------------------------------------------------
13206 // These must follow all instruction definitions as they use the names
13207 // defined in the instructions definitions.
13208 //
13209 // peepmatch ( root_instr_name [preceding_instruction]* );
13210 //
13211 // peepconstraint %{
13212 // (instruction_number.operand_name relational_op instruction_number.operand_name
13213 // [, ...] );
13214 // // instruction numbers are zero-based using left to right order in peepmatch
13215 //
13216 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
13217 // // provide an instruction_number.operand_name for each operand that appears
13218 // // in the replacement instruction's match rule
13219 //
13220 // ---------VM FLAGS---------------------------------------------------------
13221 //
13222 // All peephole optimizations can be turned off using -XX:-OptoPeephole
13223 //
13224 // Each peephole rule is given an identifying number starting with zero and
13225 // increasing by one in the order seen by the parser. An individual peephole
13226 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
13227 // on the command-line.
13228 //
13229 // ---------CURRENT LIMITATIONS----------------------------------------------
13230 //
13231 // Only match adjacent instructions in same basic block
13232 // Only equality constraints
13233 // Only constraints between operands, not (0.dest_reg == RAX_enc)
13234 // Only one replacement instruction
13235 //
13236 // ---------EXAMPLE----------------------------------------------------------
13237 //
13238 // // pertinent parts of existing instructions in architecture description
13239 // instruct movI(rRegI dst, rRegI src)
13240 // %{
13241 // match(Set dst (CopyI src));
13242 // %}
13243 //
13244 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr)
13245 // %{
13246 // match(Set dst (AddI dst src));
13247 // effect(KILL cr);
13248 // %}
13249 //
13250 // // Change (inc mov) to lea
13251 // peephole %{
13252 // // increment preceeded by register-register move
13253 // peepmatch ( incI_rReg movI );
13254 // // require that the destination register of the increment
13255 // // match the destination register of the move
13256 // peepconstraint ( 0.dst == 1.dst );
13257 // // construct a replacement instruction that sets
13258 // // the destination to ( move's source register + one )
13259 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) );
13260 // %}
13261 //
13262
13263 // Implementation no longer uses movX instructions since
13264 // machine-independent system no longer uses CopyX nodes.
13265 //
13266 // peephole
13267 // %{
13268 // peepmatch (incI_rReg movI);
13269 // peepconstraint (0.dst == 1.dst);
13270 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
13271 // %}
13272
13273 // peephole
13274 // %{
13275 // peepmatch (decI_rReg movI);
13276 // peepconstraint (0.dst == 1.dst);
13277 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
13278 // %}
13279
13280 // peephole
13281 // %{
13282 // peepmatch (addI_rReg_imm movI);
13283 // peepconstraint (0.dst == 1.dst);
13284 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
13285 // %}
13286
13287 // peephole
13288 // %{
13289 // peepmatch (incL_rReg movL);
13290 // peepconstraint (0.dst == 1.dst);
13291 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
13292 // %}
13293
13294 // peephole
13295 // %{
13296 // peepmatch (decL_rReg movL);
13297 // peepconstraint (0.dst == 1.dst);
13298 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
13299 // %}
13300
13301 // peephole
13302 // %{
13303 // peepmatch (addL_rReg_imm movL);
13304 // peepconstraint (0.dst == 1.dst);
13305 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
13306 // %}
13307
13308 // peephole
13309 // %{
13310 // peepmatch (addP_rReg_imm movP);
13311 // peepconstraint (0.dst == 1.dst);
13312 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src));
13313 // %}
13314
13315 // // Change load of spilled value to only a spill
13316 // instruct storeI(memory mem, rRegI src)
13317 // %{
13318 // match(Set mem (StoreI mem src));
13319 // %}
13320 //
13321 // instruct loadI(rRegI dst, memory mem)
13322 // %{
13323 // match(Set dst (LoadI mem));
13324 // %}
13325 //
13326
13327 peephole
13328 %{
13329 peepmatch (loadI storeI);
13330 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
13331 peepreplace (storeI(1.mem 1.mem 1.src));
13332 %}
13333
13334 peephole
13335 %{
13336 peepmatch (loadL storeL);
13337 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
13338 peepreplace (storeL(1.mem 1.mem 1.src));
13339 %}
13340
13341 //----------SMARTSPILL RULES---------------------------------------------------
13342 // These must follow all instruction definitions as they use the names
13343 // defined in the instructions definitions.