Mercurial > hg > truffle
annotate src/cpu/x86/vm/x86_64.ad @ 6639:892ec0920ccd
Merge
author | vladidan |
---|---|
date | Wed, 08 Aug 2012 16:09:11 -0400 |
parents | 8c92982cbbc4 |
children | 006050192a5a |
rev | line source |
---|---|
0 | 1 // |
4950 | 2 // Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 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 // | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1396
diff
changeset
|
19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1396
diff
changeset
|
20 // or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1396
diff
changeset
|
21 // questions. |
0 | 22 // |
23 // | |
24 | |
25 // AMD64 Architecture Description File | |
26 | |
27 //----------REGISTER DEFINITION BLOCK------------------------------------------ | |
28 // This information is used by the matcher and the register allocator to | |
29 // describe individual registers and classes of registers within the target | |
30 // archtecture. | |
31 | |
32 register %{ | |
33 //----------Architecture Description Register Definitions---------------------- | |
34 // General Registers | |
35 // "reg_def" name ( register save type, C convention save type, | |
36 // ideal register type, encoding ); | |
37 // Register Save Types: | |
38 // | |
39 // NS = No-Save: The register allocator assumes that these registers | |
40 // can be used without saving upon entry to the method, & | |
41 // that they do not need to be saved at call sites. | |
42 // | |
43 // SOC = Save-On-Call: The register allocator assumes that these registers | |
44 // can be used without saving upon entry to the method, | |
45 // but that they must be saved at call sites. | |
46 // | |
47 // SOE = Save-On-Entry: The register allocator assumes that these registers | |
48 // must be saved before using them upon entry to the | |
49 // method, but they do not need to be saved at call | |
50 // sites. | |
51 // | |
52 // AS = Always-Save: The register allocator assumes that these registers | |
53 // must be saved before using them upon entry to the | |
54 // method, & that they must be saved at call sites. | |
55 // | |
56 // Ideal Register Type is used to determine how to save & restore a | |
57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get | |
58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. | |
59 // | |
60 // The encoding number is the actual bit-pattern placed into the opcodes. | |
61 | |
62 // General Registers | |
63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when | |
64 // used as byte registers) | |
65 | |
66 // Previously set RBX, RSI, and RDI as save-on-entry for java code | |
67 // Turn off SOE in java-code due to frequent use of uncommon-traps. | |
68 // Now that allocator is better, turn on RSI and RDI as SOE registers. | |
69 | |
70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); | |
71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); | |
72 | |
73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); | |
74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); | |
75 | |
76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); | |
77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); | |
78 | |
79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); | |
80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); | |
81 | |
82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); | |
83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); | |
84 | |
85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code | |
86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); | |
87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); | |
88 | |
89 #ifdef _WIN64 | |
90 | |
91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); | |
92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); | |
93 | |
94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); | |
95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); | |
96 | |
97 #else | |
98 | |
99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); | |
100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); | |
101 | |
102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); | |
103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); | |
104 | |
105 #endif | |
106 | |
107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); | |
108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); | |
109 | |
110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); | |
111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); | |
112 | |
113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); | |
114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); | |
115 | |
116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); | |
117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); | |
118 | |
119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); | |
120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); | |
121 | |
122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); | |
123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); | |
124 | |
125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); | |
126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); | |
127 | |
128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); | |
129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); | |
130 | |
131 | |
132 // Floating Point Registers | |
133 | |
134 // Specify priority of register selection within phases of register | |
135 // allocation. Highest priority is first. A useful heuristic is to | |
136 // give registers a low priority when they are required by machine | |
137 // instructions, like EAX and EDX on I486, and choose no-save registers | |
138 // before save-on-call, & save-on-call before save-on-entry. Registers | |
139 // which participate in fixed calling sequences should come last. | |
140 // Registers which are used as pairs must fall on an even boundary. | |
141 | |
142 alloc_class chunk0(R10, R10_H, | |
143 R11, R11_H, | |
144 R8, R8_H, | |
145 R9, R9_H, | |
146 R12, R12_H, | |
147 RCX, RCX_H, | |
148 RBX, RBX_H, | |
149 RDI, RDI_H, | |
150 RDX, RDX_H, | |
151 RSI, RSI_H, | |
152 RAX, RAX_H, | |
153 RBP, RBP_H, | |
154 R13, R13_H, | |
155 R14, R14_H, | |
156 R15, R15_H, | |
157 RSP, RSP_H); | |
158 | |
159 | |
160 //----------Architecture Description Register Classes-------------------------- | |
161 // Several register classes are automatically defined based upon information in | |
162 // this architecture description. | |
163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) | |
164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) | |
165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) | |
166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) | |
167 // | |
168 | |
169 // Class for all pointer registers (including RSP) | |
170 reg_class any_reg(RAX, RAX_H, | |
171 RDX, RDX_H, | |
172 RBP, RBP_H, | |
173 RDI, RDI_H, | |
174 RSI, RSI_H, | |
175 RCX, RCX_H, | |
176 RBX, RBX_H, | |
177 RSP, RSP_H, | |
178 R8, R8_H, | |
179 R9, R9_H, | |
180 R10, R10_H, | |
181 R11, R11_H, | |
182 R12, R12_H, | |
183 R13, R13_H, | |
184 R14, R14_H, | |
185 R15, R15_H); | |
186 | |
187 // Class for all pointer registers except RSP | |
188 reg_class ptr_reg(RAX, RAX_H, | |
189 RDX, RDX_H, | |
190 RBP, RBP_H, | |
191 RDI, RDI_H, | |
192 RSI, RSI_H, | |
193 RCX, RCX_H, | |
194 RBX, RBX_H, | |
195 R8, R8_H, | |
196 R9, R9_H, | |
197 R10, R10_H, | |
198 R11, R11_H, | |
199 R13, R13_H, | |
200 R14, R14_H); | |
201 | |
202 // Class for all pointer registers except RAX and RSP | |
203 reg_class ptr_no_rax_reg(RDX, RDX_H, | |
204 RBP, RBP_H, | |
205 RDI, RDI_H, | |
206 RSI, RSI_H, | |
207 RCX, RCX_H, | |
208 RBX, RBX_H, | |
209 R8, R8_H, | |
210 R9, R9_H, | |
211 R10, R10_H, | |
212 R11, R11_H, | |
213 R13, R13_H, | |
214 R14, R14_H); | |
215 | |
216 reg_class ptr_no_rbp_reg(RDX, RDX_H, | |
217 RAX, RAX_H, | |
218 RDI, RDI_H, | |
219 RSI, RSI_H, | |
220 RCX, RCX_H, | |
221 RBX, RBX_H, | |
222 R8, R8_H, | |
223 R9, R9_H, | |
224 R10, R10_H, | |
225 R11, R11_H, | |
226 R13, R13_H, | |
227 R14, R14_H); | |
228 | |
229 // Class for all pointer registers except RAX, RBX and RSP | |
230 reg_class ptr_no_rax_rbx_reg(RDX, RDX_H, | |
231 RBP, RBP_H, | |
232 RDI, RDI_H, | |
233 RSI, RSI_H, | |
234 RCX, RCX_H, | |
235 R8, R8_H, | |
236 R9, R9_H, | |
237 R10, R10_H, | |
238 R11, R11_H, | |
239 R13, R13_H, | |
240 R14, R14_H); | |
241 | |
242 // Singleton class for RAX pointer register | |
243 reg_class ptr_rax_reg(RAX, RAX_H); | |
244 | |
245 // Singleton class for RBX pointer register | |
246 reg_class ptr_rbx_reg(RBX, RBX_H); | |
247 | |
248 // Singleton class for RSI pointer register | |
249 reg_class ptr_rsi_reg(RSI, RSI_H); | |
250 | |
251 // Singleton class for RDI pointer register | |
252 reg_class ptr_rdi_reg(RDI, RDI_H); | |
253 | |
254 // Singleton class for RBP pointer register | |
255 reg_class ptr_rbp_reg(RBP, RBP_H); | |
256 | |
257 // Singleton class for stack pointer | |
258 reg_class ptr_rsp_reg(RSP, RSP_H); | |
259 | |
260 // Singleton class for TLS pointer | |
261 reg_class ptr_r15_reg(R15, R15_H); | |
262 | |
263 // Class for all long registers (except RSP) | |
264 reg_class long_reg(RAX, RAX_H, | |
265 RDX, RDX_H, | |
266 RBP, RBP_H, | |
267 RDI, RDI_H, | |
268 RSI, RSI_H, | |
269 RCX, RCX_H, | |
270 RBX, RBX_H, | |
271 R8, R8_H, | |
272 R9, R9_H, | |
273 R10, R10_H, | |
274 R11, R11_H, | |
275 R13, R13_H, | |
276 R14, R14_H); | |
277 | |
278 // Class for all long registers except RAX, RDX (and RSP) | |
279 reg_class long_no_rax_rdx_reg(RBP, RBP_H, | |
280 RDI, RDI_H, | |
281 RSI, RSI_H, | |
282 RCX, RCX_H, | |
283 RBX, RBX_H, | |
284 R8, R8_H, | |
285 R9, R9_H, | |
286 R10, R10_H, | |
287 R11, R11_H, | |
288 R13, R13_H, | |
289 R14, R14_H); | |
290 | |
291 // Class for all long registers except RCX (and RSP) | |
292 reg_class long_no_rcx_reg(RBP, RBP_H, | |
293 RDI, RDI_H, | |
294 RSI, RSI_H, | |
295 RAX, RAX_H, | |
296 RDX, RDX_H, | |
297 RBX, RBX_H, | |
298 R8, R8_H, | |
299 R9, R9_H, | |
300 R10, R10_H, | |
301 R11, R11_H, | |
302 R13, R13_H, | |
303 R14, R14_H); | |
304 | |
305 // Class for all long registers except RAX (and RSP) | |
306 reg_class long_no_rax_reg(RBP, RBP_H, | |
307 RDX, RDX_H, | |
308 RDI, RDI_H, | |
309 RSI, RSI_H, | |
310 RCX, RCX_H, | |
311 RBX, RBX_H, | |
312 R8, R8_H, | |
313 R9, R9_H, | |
314 R10, R10_H, | |
315 R11, R11_H, | |
316 R13, R13_H, | |
317 R14, R14_H); | |
318 | |
319 // Singleton class for RAX long register | |
320 reg_class long_rax_reg(RAX, RAX_H); | |
321 | |
322 // Singleton class for RCX long register | |
323 reg_class long_rcx_reg(RCX, RCX_H); | |
324 | |
325 // Singleton class for RDX long register | |
326 reg_class long_rdx_reg(RDX, RDX_H); | |
327 | |
328 // Class for all int registers (except RSP) | |
329 reg_class int_reg(RAX, | |
330 RDX, | |
331 RBP, | |
332 RDI, | |
333 RSI, | |
334 RCX, | |
335 RBX, | |
336 R8, | |
337 R9, | |
338 R10, | |
339 R11, | |
340 R13, | |
341 R14); | |
342 | |
343 // Class for all int registers except RCX (and RSP) | |
344 reg_class int_no_rcx_reg(RAX, | |
345 RDX, | |
346 RBP, | |
347 RDI, | |
348 RSI, | |
349 RBX, | |
350 R8, | |
351 R9, | |
352 R10, | |
353 R11, | |
354 R13, | |
355 R14); | |
356 | |
357 // Class for all int registers except RAX, RDX (and RSP) | |
358 reg_class int_no_rax_rdx_reg(RBP, | |
304 | 359 RDI, |
0 | 360 RSI, |
361 RCX, | |
362 RBX, | |
363 R8, | |
364 R9, | |
365 R10, | |
366 R11, | |
367 R13, | |
368 R14); | |
369 | |
370 // Singleton class for RAX int register | |
371 reg_class int_rax_reg(RAX); | |
372 | |
373 // Singleton class for RBX int register | |
374 reg_class int_rbx_reg(RBX); | |
375 | |
376 // Singleton class for RCX int register | |
377 reg_class int_rcx_reg(RCX); | |
378 | |
379 // Singleton class for RCX int register | |
380 reg_class int_rdx_reg(RDX); | |
381 | |
382 // Singleton class for RCX int register | |
383 reg_class int_rdi_reg(RDI); | |
384 | |
385 // Singleton class for instruction pointer | |
386 // reg_class ip_reg(RIP); | |
387 | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
388 %} |
0 | 389 |
390 //----------SOURCE BLOCK------------------------------------------------------- | |
391 // This is a block of C++ code which provides values, functions, and | |
392 // definitions necessary in the rest of the architecture description | |
393 source %{ | |
304 | 394 #define RELOC_IMM64 Assembler::imm_operand |
0 | 395 #define RELOC_DISP32 Assembler::disp32_operand |
396 | |
397 #define __ _masm. | |
398 | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
399 static int preserve_SP_size() { |
4759 | 400 return 3; // rex.w, op, rm(reg/reg) |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
401 } |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
402 |
0 | 403 // !!!!! Special hack to get all types of calls to specify the byte offset |
404 // from the start of the call to the point where the return address | |
405 // will point. | |
406 int MachCallStaticJavaNode::ret_addr_offset() | |
407 { | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
408 int offset = 5; // 5 bytes from start of call to where return address points |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
409 if (_method_handle_invoke) |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
410 offset += preserve_SP_size(); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
411 return offset; |
0 | 412 } |
413 | |
414 int MachCallDynamicJavaNode::ret_addr_offset() | |
415 { | |
416 return 15; // 15 bytes from start of call to where return address points | |
417 } | |
418 | |
419 // In os_cpu .ad file | |
420 // int MachCallRuntimeNode::ret_addr_offset() | |
421 | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
422 // Indicate if the safepoint node needs the polling page as an input, |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
423 // it does if the polling page is more than disp32 away. |
0 | 424 bool SafePointNode::needs_polling_address_input() |
425 { | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
426 return Assembler::is_polling_page_far(); |
0 | 427 } |
428 | |
429 // | |
430 // Compute padding required for nodes which need alignment | |
431 // | |
432 | |
433 // The address of the call instruction needs to be 4-byte aligned to | |
434 // ensure that it does not span a cache line so that it can be patched. | |
435 int CallStaticJavaDirectNode::compute_padding(int current_offset) const | |
436 { | |
437 current_offset += 1; // skip call opcode byte | |
438 return round_to(current_offset, alignment_required()) - current_offset; | |
439 } | |
440 | |
441 // The address of the call instruction needs to be 4-byte aligned to | |
442 // ensure that it does not span a cache line so that it can be patched. | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
443 int CallStaticJavaHandleNode::compute_padding(int current_offset) const |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
444 { |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
445 current_offset += preserve_SP_size(); // skip mov rbp, rsp |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
446 current_offset += 1; // skip call opcode byte |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
447 return round_to(current_offset, alignment_required()) - current_offset; |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
448 } |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
449 |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
450 // The address of the call instruction needs to be 4-byte aligned to |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
451 // ensure that it does not span a cache line so that it can be patched. |
0 | 452 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const |
453 { | |
454 current_offset += 11; // skip movq instruction + call opcode byte | |
455 return round_to(current_offset, alignment_required()) - current_offset; | |
456 } | |
457 | |
458 // EMIT_RM() | |
1748 | 459 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { |
0 | 460 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); |
1748 | 461 cbuf.insts()->emit_int8(c); |
0 | 462 } |
463 | |
464 // EMIT_CC() | |
1748 | 465 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { |
0 | 466 unsigned char c = (unsigned char) (f1 | f2); |
1748 | 467 cbuf.insts()->emit_int8(c); |
0 | 468 } |
469 | |
470 // EMIT_OPCODE() | |
1748 | 471 void emit_opcode(CodeBuffer &cbuf, int code) { |
472 cbuf.insts()->emit_int8((unsigned char) code); | |
0 | 473 } |
474 | |
475 // EMIT_OPCODE() w/ relocation information | |
476 void emit_opcode(CodeBuffer &cbuf, | |
477 int code, relocInfo::relocType reloc, int offset, int format) | |
478 { | |
1748 | 479 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); |
0 | 480 emit_opcode(cbuf, code); |
481 } | |
482 | |
483 // EMIT_D8() | |
1748 | 484 void emit_d8(CodeBuffer &cbuf, int d8) { |
485 cbuf.insts()->emit_int8((unsigned char) d8); | |
0 | 486 } |
487 | |
488 // EMIT_D16() | |
1748 | 489 void emit_d16(CodeBuffer &cbuf, int d16) { |
490 cbuf.insts()->emit_int16(d16); | |
0 | 491 } |
492 | |
493 // EMIT_D32() | |
1748 | 494 void emit_d32(CodeBuffer &cbuf, int d32) { |
495 cbuf.insts()->emit_int32(d32); | |
0 | 496 } |
497 | |
498 // EMIT_D64() | |
1748 | 499 void emit_d64(CodeBuffer &cbuf, int64_t d64) { |
500 cbuf.insts()->emit_int64(d64); | |
0 | 501 } |
502 | |
503 // emit 32 bit value and construct relocation entry from relocInfo::relocType | |
504 void emit_d32_reloc(CodeBuffer& cbuf, | |
505 int d32, | |
506 relocInfo::relocType reloc, | |
507 int format) | |
508 { | |
509 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); | |
1748 | 510 cbuf.relocate(cbuf.insts_mark(), reloc, format); |
511 cbuf.insts()->emit_int32(d32); | |
0 | 512 } |
513 | |
514 // emit 32 bit value and construct relocation entry from RelocationHolder | |
1748 | 515 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { |
0 | 516 #ifdef ASSERT |
517 if (rspec.reloc()->type() == relocInfo::oop_type && | |
518 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
986
diff
changeset
|
519 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); |
0 | 520 } |
521 #endif | |
1748 | 522 cbuf.relocate(cbuf.insts_mark(), rspec, format); |
523 cbuf.insts()->emit_int32(d32); | |
0 | 524 } |
525 | |
526 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { | |
1748 | 527 address next_ip = cbuf.insts_end() + 4; |
0 | 528 emit_d32_reloc(cbuf, (int) (addr - next_ip), |
529 external_word_Relocation::spec(addr), | |
530 RELOC_DISP32); | |
531 } | |
532 | |
533 | |
534 // emit 64 bit value and construct relocation entry from relocInfo::relocType | |
1748 | 535 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { |
536 cbuf.relocate(cbuf.insts_mark(), reloc, format); | |
537 cbuf.insts()->emit_int64(d64); | |
0 | 538 } |
539 | |
540 // emit 64 bit value and construct relocation entry from RelocationHolder | |
1748 | 541 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { |
0 | 542 #ifdef ASSERT |
543 if (rspec.reloc()->type() == relocInfo::oop_type && | |
544 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
986
diff
changeset
|
545 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()), |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
986
diff
changeset
|
546 "cannot embed scavengable oops in code"); |
0 | 547 } |
548 #endif | |
1748 | 549 cbuf.relocate(cbuf.insts_mark(), rspec, format); |
550 cbuf.insts()->emit_int64(d64); | |
0 | 551 } |
552 | |
553 // Access stack slot for load or store | |
554 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) | |
555 { | |
556 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) | |
557 if (-0x80 <= disp && disp < 0x80) { | |
558 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte | |
559 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte | |
560 emit_d8(cbuf, disp); // Displacement // R/M byte | |
561 } else { | |
562 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte | |
563 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte | |
564 emit_d32(cbuf, disp); // Displacement // R/M byte | |
565 } | |
566 } | |
567 | |
568 // rRegI ereg, memory mem) %{ // emit_reg_mem | |
569 void encode_RegMem(CodeBuffer &cbuf, | |
570 int reg, | |
571 int base, int index, int scale, int disp, bool disp_is_oop) | |
572 { | |
573 assert(!disp_is_oop, "cannot have disp"); | |
574 int regenc = reg & 7; | |
575 int baseenc = base & 7; | |
576 int indexenc = index & 7; | |
577 | |
578 // There is no index & no scale, use form without SIB byte | |
579 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { | |
580 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] | |
581 if (disp == 0 && base != RBP_enc && base != R13_enc) { | |
582 emit_rm(cbuf, 0x0, regenc, baseenc); // * | |
583 } else if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { | |
584 // If 8-bit displacement, mode 0x1 | |
585 emit_rm(cbuf, 0x1, regenc, baseenc); // * | |
586 emit_d8(cbuf, disp); | |
587 } else { | |
588 // If 32-bit displacement | |
589 if (base == -1) { // Special flag for absolute address | |
590 emit_rm(cbuf, 0x0, regenc, 0x5); // * | |
591 if (disp_is_oop) { | |
592 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); | |
593 } else { | |
594 emit_d32(cbuf, disp); | |
595 } | |
596 } else { | |
597 // Normal base + offset | |
598 emit_rm(cbuf, 0x2, regenc, baseenc); // * | |
599 if (disp_is_oop) { | |
600 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); | |
601 } else { | |
602 emit_d32(cbuf, disp); | |
603 } | |
604 } | |
605 } | |
606 } else { | |
607 // Else, encode with the SIB byte | |
608 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] | |
609 if (disp == 0 && base != RBP_enc && base != R13_enc) { | |
610 // If no displacement | |
611 emit_rm(cbuf, 0x0, regenc, 0x4); // * | |
612 emit_rm(cbuf, scale, indexenc, baseenc); | |
613 } else { | |
614 if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { | |
615 // If 8-bit displacement, mode 0x1 | |
616 emit_rm(cbuf, 0x1, regenc, 0x4); // * | |
617 emit_rm(cbuf, scale, indexenc, baseenc); | |
618 emit_d8(cbuf, disp); | |
619 } else { | |
620 // If 32-bit displacement | |
621 if (base == 0x04 ) { | |
622 emit_rm(cbuf, 0x2, regenc, 0x4); | |
623 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? | |
624 } else { | |
625 emit_rm(cbuf, 0x2, regenc, 0x4); | |
626 emit_rm(cbuf, scale, indexenc, baseenc); // * | |
627 } | |
628 if (disp_is_oop) { | |
629 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); | |
630 } else { | |
631 emit_d32(cbuf, disp); | |
632 } | |
633 } | |
634 } | |
635 } | |
636 } | |
637 | |
3783 | 638 // This could be in MacroAssembler but it's fairly C2 specific |
639 void emit_cmpfp_fixup(MacroAssembler& _masm) { | |
640 Label exit; | |
641 __ jccb(Assembler::noParity, exit); | |
642 __ pushf(); | |
4759 | 643 // |
644 // comiss/ucomiss instructions set ZF,PF,CF flags and | |
645 // zero OF,AF,SF for NaN values. | |
646 // Fixup flags by zeroing ZF,PF so that compare of NaN | |
647 // values returns 'less than' result (CF is set). | |
648 // Leave the rest of flags unchanged. | |
649 // | |
650 // 7 6 5 4 3 2 1 0 | |
651 // |S|Z|r|A|r|P|r|C| (r - reserved bit) | |
652 // 0 0 1 0 1 0 1 1 (0x2B) | |
653 // | |
3783 | 654 __ andq(Address(rsp, 0), 0xffffff2b); |
655 __ popf(); | |
656 __ bind(exit); | |
4759 | 657 } |
658 | |
659 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { | |
660 Label done; | |
661 __ movl(dst, -1); | |
662 __ jcc(Assembler::parity, done); | |
663 __ jcc(Assembler::below, done); | |
664 __ setb(Assembler::notEqual, dst); | |
665 __ movzbl(dst, dst); | |
666 __ bind(done); | |
3783 | 667 } |
668 | |
0 | 669 |
670 //============================================================================= | |
2008 | 671 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; |
672 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4047
diff
changeset
|
673 int Compile::ConstantTable::calculate_table_base_offset() const { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4047
diff
changeset
|
674 return 0; // absolute addressing, no offset |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4047
diff
changeset
|
675 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4047
diff
changeset
|
676 |
2008 | 677 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { |
678 // Empty encoding | |
679 } | |
680 | |
681 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { | |
682 return 0; | |
683 } | |
684 | |
685 #ifndef PRODUCT | |
686 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { | |
687 st->print("# MachConstantBaseNode (empty encoding)"); | |
688 } | |
689 #endif | |
690 | |
691 | |
692 //============================================================================= | |
0 | 693 #ifndef PRODUCT |
4947
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
694 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { |
0 | 695 Compile* C = ra_->C; |
696 | |
697 int framesize = C->frame_slots() << LogBytesPerInt; | |
698 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); | |
4947
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
699 // Remove wordSize for return addr which is already pushed. |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
700 framesize -= wordSize; |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
701 |
0 | 702 if (C->need_stack_bang(framesize)) { |
4947
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
703 framesize -= wordSize; |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
704 st->print("# stack bang"); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
705 st->print("\n\t"); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
706 st->print("pushq rbp\t# Save rbp"); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
707 if (framesize) { |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
708 st->print("\n\t"); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
709 st->print("subq rsp, #%d\t# Create frame",framesize); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
710 } |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
711 } else { |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
712 st->print("subq rsp, #%d\t# Create frame",framesize); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
713 st->print("\n\t"); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
714 framesize -= wordSize; |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
715 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); |
0 | 716 } |
717 | |
718 if (VerifyStackAtCalls) { | |
4947
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
719 st->print("\n\t"); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
720 framesize -= wordSize; |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
721 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
722 #ifdef ASSERT |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
723 st->print("\n\t"); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
724 st->print("# stack alignment check"); |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
725 #endif |
0 | 726 } |
4947
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
727 st->cr(); |
0 | 728 } |
729 #endif | |
730 | |
4947
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
731 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { |
0 | 732 Compile* C = ra_->C; |
4947
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
733 MacroAssembler _masm(&cbuf); |
0 | 734 |
735 int framesize = C->frame_slots() << LogBytesPerInt; | |
4947
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
736 |
fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
kvn
parents:
4777
diff
changeset
|
737 __ verified_entry(framesize, C->need_stack_bang(framesize), false); |
0 | 738 |
1748 | 739 C->set_frame_complete(cbuf.insts_size()); |
0 | 740 |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4047
diff
changeset
|
741 if (C->has_mach_constant_base_node()) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4047
diff
changeset
|
742 // NOTE: We set the table base offset here because users might be |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4047
diff
changeset
|
743 // emitted before MachConstantBaseNode. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4047
diff
changeset
|
744 Compile::ConstantTable& constant_table = C->constant_table(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4047
diff
changeset
|
745 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4047
diff
changeset
|
746 } |
0 | 747 } |
748 | |
749 uint MachPrologNode::size(PhaseRegAlloc* ra_) const | |
750 { | |
751 return MachNode::size(ra_); // too many variables; just compute it | |
752 // the hard way | |
753 } | |
754 | |
755 int MachPrologNode::reloc() const | |
756 { | |
757 return 0; // a large enough number | |
758 } | |
759 | |
760 //============================================================================= | |
761 #ifndef PRODUCT | |
762 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const | |
763 { | |
764 Compile* C = ra_->C; | |
765 int framesize = C->frame_slots() << LogBytesPerInt; | |
766 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); | |
767 // Remove word for return adr already pushed | |
768 // and RBP | |
769 framesize -= 2*wordSize; | |
770 | |
771 if (framesize) { | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
772 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); |
0 | 773 st->print("\t"); |
774 } | |
775 | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
776 st->print_cr("popq rbp"); |
0 | 777 if (do_polling() && C->is_method_compilation()) { |
778 st->print("\t"); | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
779 if (Assembler::is_polling_page_far()) { |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
780 st->print_cr("movq rscratch1, #polling_page_address\n\t" |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
781 "testl rax, [rscratch1]\t" |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
782 "# Safepoint: poll for GC"); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
783 } else { |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
784 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
785 "# Safepoint: poll for GC"); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
786 } |
0 | 787 } |
788 } | |
789 #endif | |
790 | |
791 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const | |
792 { | |
793 Compile* C = ra_->C; | |
794 int framesize = C->frame_slots() << LogBytesPerInt; | |
795 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); | |
796 // Remove word for return adr already pushed | |
797 // and RBP | |
798 framesize -= 2*wordSize; | |
799 | |
800 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here | |
801 | |
802 if (framesize) { | |
803 emit_opcode(cbuf, Assembler::REX_W); | |
804 if (framesize < 0x80) { | |
805 emit_opcode(cbuf, 0x83); // addq rsp, #framesize | |
806 emit_rm(cbuf, 0x3, 0x00, RSP_enc); | |
807 emit_d8(cbuf, framesize); | |
808 } else { | |
809 emit_opcode(cbuf, 0x81); // addq rsp, #framesize | |
810 emit_rm(cbuf, 0x3, 0x00, RSP_enc); | |
811 emit_d32(cbuf, framesize); | |
812 } | |
813 } | |
814 | |
815 // popq rbp | |
816 emit_opcode(cbuf, 0x58 | RBP_enc); | |
817 | |
818 if (do_polling() && C->is_method_compilation()) { | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
819 MacroAssembler _masm(&cbuf); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
820 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
821 if (Assembler::is_polling_page_far()) { |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
822 __ lea(rscratch1, polling_page); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
823 __ relocate(relocInfo::poll_return_type); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
824 __ testl(rax, Address(rscratch1, 0)); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
825 } else { |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
826 __ testl(rax, polling_page); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
827 } |
0 | 828 } |
829 } | |
830 | |
831 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const | |
832 { | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
833 return MachNode::size(ra_); // too many variables; just compute it |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
834 // the hard way |
0 | 835 } |
836 | |
837 int MachEpilogNode::reloc() const | |
838 { | |
839 return 2; // a large enough number | |
840 } | |
841 | |
842 const Pipeline* MachEpilogNode::pipeline() const | |
843 { | |
844 return MachNode::pipeline_class(); | |
845 } | |
846 | |
847 int MachEpilogNode::safepoint_offset() const | |
848 { | |
849 return 0; | |
850 } | |
851 | |
852 //============================================================================= | |
853 | |
854 enum RC { | |
855 rc_bad, | |
856 rc_int, | |
857 rc_float, | |
858 rc_stack | |
859 }; | |
860 | |
861 static enum RC rc_class(OptoReg::Name reg) | |
862 { | |
863 if( !OptoReg::is_valid(reg) ) return rc_bad; | |
864 | |
865 if (OptoReg::is_stack(reg)) return rc_stack; | |
866 | |
867 VMReg r = OptoReg::as_VMReg(reg); | |
868 | |
869 if (r->is_Register()) return rc_int; | |
870 | |
871 assert(r->is_XMMRegister(), "must be"); | |
872 return rc_float; | |
873 } | |
874 | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
875 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
876 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
877 int src_hi, int dst_hi, uint ireg, outputStream* st); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
878 |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
879 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
880 int stack_offset, int reg, uint ireg, outputStream* st); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
881 |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
882 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
883 int dst_offset, uint ireg, outputStream* st) { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
884 if (cbuf) { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
885 MacroAssembler _masm(cbuf); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
886 switch (ireg) { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
887 case Op_VecS: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
888 __ movq(Address(rsp, -8), rax); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
889 __ movl(rax, Address(rsp, src_offset)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
890 __ movl(Address(rsp, dst_offset), rax); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
891 __ movq(rax, Address(rsp, -8)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
892 break; |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
893 case Op_VecD: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
894 __ pushq(Address(rsp, src_offset)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
895 __ popq (Address(rsp, dst_offset)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
896 break; |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
897 case Op_VecX: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
898 __ pushq(Address(rsp, src_offset)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
899 __ popq (Address(rsp, dst_offset)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
900 __ pushq(Address(rsp, src_offset+8)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
901 __ popq (Address(rsp, dst_offset+8)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
902 break; |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
903 case Op_VecY: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
904 __ vmovdqu(Address(rsp, -32), xmm0); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
905 __ vmovdqu(xmm0, Address(rsp, src_offset)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
906 __ vmovdqu(Address(rsp, dst_offset), xmm0); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
907 __ vmovdqu(xmm0, Address(rsp, -32)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
908 break; |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
909 default: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
910 ShouldNotReachHere(); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
911 } |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
912 #ifndef PRODUCT |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
913 } else { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
914 switch (ireg) { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
915 case Op_VecS: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
916 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
917 "movl rax, [rsp + #%d]\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
918 "movl [rsp + #%d], rax\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
919 "movq rax, [rsp - #8]", |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
920 src_offset, dst_offset); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
921 break; |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
922 case Op_VecD: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
923 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
924 "popq [rsp + #%d]", |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
925 src_offset, dst_offset); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
926 break; |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
927 case Op_VecX: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
928 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
929 "popq [rsp + #%d]\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
930 "pushq [rsp + #%d]\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
931 "popq [rsp + #%d]", |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
932 src_offset, dst_offset, src_offset+8, dst_offset+8); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
933 break; |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
934 case Op_VecY: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
935 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
936 "vmovdqu xmm0, [rsp + #%d]\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
937 "vmovdqu [rsp + #%d], xmm0\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
938 "vmovdqu xmm0, [rsp - #32]", |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
939 src_offset, dst_offset); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
940 break; |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
941 default: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
942 ShouldNotReachHere(); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
943 } |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
944 #endif |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
945 } |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
946 } |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
947 |
0 | 948 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, |
949 PhaseRegAlloc* ra_, | |
950 bool do_size, | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
951 outputStream* st) const { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
952 assert(cbuf != NULL || st != NULL, "sanity"); |
0 | 953 // Get registers to move |
954 OptoReg::Name src_second = ra_->get_reg_second(in(1)); | |
955 OptoReg::Name src_first = ra_->get_reg_first(in(1)); | |
956 OptoReg::Name dst_second = ra_->get_reg_second(this); | |
957 OptoReg::Name dst_first = ra_->get_reg_first(this); | |
958 | |
959 enum RC src_second_rc = rc_class(src_second); | |
960 enum RC src_first_rc = rc_class(src_first); | |
961 enum RC dst_second_rc = rc_class(dst_second); | |
962 enum RC dst_first_rc = rc_class(dst_first); | |
963 | |
964 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), | |
965 "must move at least 1 register" ); | |
966 | |
967 if (src_first == dst_first && src_second == dst_second) { | |
968 // Self copy, no move | |
969 return 0; | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
970 } |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
971 if (bottom_type()->isa_vect() != NULL) { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
972 uint ireg = ideal_reg(); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
973 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
974 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity"); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
975 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
976 // mem -> mem |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
977 int src_offset = ra_->reg2offset(src_first); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
978 int dst_offset = ra_->reg2offset(dst_first); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
979 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
980 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
981 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
982 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
983 int stack_offset = ra_->reg2offset(dst_first); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
984 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
985 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
986 int stack_offset = ra_->reg2offset(src_first); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
987 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
988 } else { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
989 ShouldNotReachHere(); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
990 } |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
991 return 0; |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
992 } |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
993 if (src_first_rc == rc_stack) { |
0 | 994 // mem -> |
995 if (dst_first_rc == rc_stack) { | |
996 // mem -> mem | |
997 assert(src_second != dst_first, "overlap"); | |
998 if ((src_first & 1) == 0 && src_first + 1 == src_second && | |
999 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { | |
1000 // 64-bit | |
1001 int src_offset = ra_->reg2offset(src_first); | |
1002 int dst_offset = ra_->reg2offset(dst_first); | |
1003 if (cbuf) { | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1004 MacroAssembler _masm(cbuf); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1005 __ pushq(Address(rsp, src_offset)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1006 __ popq (Address(rsp, dst_offset)); |
0 | 1007 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1008 } else { |
0 | 1009 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1010 "popq [rsp + #%d]", |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1011 src_offset, dst_offset); |
0 | 1012 #endif |
1013 } | |
1014 } else { | |
1015 // 32-bit | |
1016 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); | |
1017 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); | |
1018 // No pushl/popl, so: | |
1019 int src_offset = ra_->reg2offset(src_first); | |
1020 int dst_offset = ra_->reg2offset(dst_first); | |
1021 if (cbuf) { | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1022 MacroAssembler _masm(cbuf); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1023 __ movq(Address(rsp, -8), rax); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1024 __ movl(rax, Address(rsp, src_offset)); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1025 __ movl(Address(rsp, dst_offset), rax); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1026 __ movq(rax, Address(rsp, -8)); |
0 | 1027 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1028 } else { |
0 | 1029 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1030 "movl rax, [rsp + #%d]\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1031 "movl [rsp + #%d], rax\n\t" |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1032 "movq rax, [rsp - #8]", |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1033 src_offset, dst_offset); |
0 | 1034 #endif |
1035 } | |
1036 } | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1037 return 0; |
0 | 1038 } else if (dst_first_rc == rc_int) { |
1039 // mem -> gpr | |
1040 if ((src_first & 1) == 0 && src_first + 1 == src_second && | |
1041 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { | |
1042 // 64-bit | |
1043 int offset = ra_->reg2offset(src_first); | |
1044 if (cbuf) { | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1045 MacroAssembler _masm(cbuf); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1046 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); |
0 | 1047 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1048 } else { |
0 | 1049 st->print("movq %s, [rsp + #%d]\t# spill", |
1050 Matcher::regName[dst_first], | |
1051 offset); | |
1052 #endif | |
1053 } | |
1054 } else { | |
1055 // 32-bit | |
1056 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); | |
1057 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); | |
1058 int offset = ra_->reg2offset(src_first); | |
1059 if (cbuf) { | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1060 MacroAssembler _masm(cbuf); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1061 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); |
0 | 1062 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1063 } else { |
0 | 1064 st->print("movl %s, [rsp + #%d]\t# spill", |
1065 Matcher::regName[dst_first], | |
1066 offset); | |
1067 #endif | |
1068 } | |
1069 } | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1070 return 0; |
0 | 1071 } else if (dst_first_rc == rc_float) { |
1072 // mem-> xmm | |
1073 if ((src_first & 1) == 0 && src_first + 1 == src_second && | |
1074 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { | |
1075 // 64-bit | |
1076 int offset = ra_->reg2offset(src_first); | |
1077 if (cbuf) { | |
4759 | 1078 MacroAssembler _masm(cbuf); |
1079 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); | |
0 | 1080 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1081 } else { |
0 | 1082 st->print("%s %s, [rsp + #%d]\t# spill", |
1083 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", | |
1084 Matcher::regName[dst_first], | |
1085 offset); | |
1086 #endif | |
1087 } | |
1088 } else { | |
1089 // 32-bit | |
1090 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); | |
1091 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); | |
1092 int offset = ra_->reg2offset(src_first); | |
1093 if (cbuf) { | |
4759 | 1094 MacroAssembler _masm(cbuf); |
1095 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); | |
0 | 1096 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1097 } else { |
0 | 1098 st->print("movss %s, [rsp + #%d]\t# spill", |
1099 Matcher::regName[dst_first], | |
1100 offset); | |
1101 #endif | |
1102 } | |
1103 } | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1104 return 0; |
0 | 1105 } |
1106 } else if (src_first_rc == rc_int) { | |
1107 // gpr -> | |
1108 if (dst_first_rc == rc_stack) { | |
1109 // gpr -> mem | |
1110 if ((src_first & 1) == 0 && src_first + 1 == src_second && | |
1111 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { | |
1112 // 64-bit | |
1113 int offset = ra_->reg2offset(dst_first); | |
1114 if (cbuf) { | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1115 MacroAssembler _masm(cbuf); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1116 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); |
0 | 1117 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1118 } else { |
0 | 1119 st->print("movq [rsp + #%d], %s\t# spill", |
1120 offset, | |
1121 Matcher::regName[src_first]); | |
1122 #endif | |
1123 } | |
1124 } else { | |
1125 // 32-bit | |
1126 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); | |
1127 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); | |
1128 int offset = ra_->reg2offset(dst_first); | |
1129 if (cbuf) { | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1130 MacroAssembler _masm(cbuf); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1131 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); |
0 | 1132 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1133 } else { |
0 | 1134 st->print("movl [rsp + #%d], %s\t# spill", |
1135 offset, | |
1136 Matcher::regName[src_first]); | |
1137 #endif | |
1138 } | |
1139 } | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1140 return 0; |
0 | 1141 } else if (dst_first_rc == rc_int) { |
1142 // gpr -> gpr | |
1143 if ((src_first & 1) == 0 && src_first + 1 == src_second && | |
1144 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { | |
1145 // 64-bit | |
1146 if (cbuf) { | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1147 MacroAssembler _masm(cbuf); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1148 __ movq(as_Register(Matcher::_regEncode[dst_first]), |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1149 as_Register(Matcher::_regEncode[src_first])); |
0 | 1150 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1151 } else { |
0 | 1152 st->print("movq %s, %s\t# spill", |
1153 Matcher::regName[dst_first], | |
1154 Matcher::regName[src_first]); | |
1155 #endif | |
1156 } | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1157 return 0; |
0 | 1158 } else { |
1159 // 32-bit | |
1160 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); | |
1161 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); | |
1162 if (cbuf) { | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1163 MacroAssembler _masm(cbuf); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1164 __ movl(as_Register(Matcher::_regEncode[dst_first]), |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1165 as_Register(Matcher::_regEncode[src_first])); |
0 | 1166 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1167 } else { |
0 | 1168 st->print("movl %s, %s\t# spill", |
1169 Matcher::regName[dst_first], | |
1170 Matcher::regName[src_first]); | |
1171 #endif | |
1172 } | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1173 return 0; |
0 | 1174 } |
1175 } else if (dst_first_rc == rc_float) { | |
1176 // gpr -> xmm | |
1177 if ((src_first & 1) == 0 && src_first + 1 == src_second && | |
1178 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { | |
1179 // 64-bit | |
1180 if (cbuf) { | |
4759 | 1181 MacroAssembler _masm(cbuf); |
1182 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); | |
0 | 1183 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1184 } else { |
0 | 1185 st->print("movdq %s, %s\t# spill", |
1186 Matcher::regName[dst_first], | |
1187 Matcher::regName[src_first]); | |
1188 #endif | |
1189 } | |
1190 } else { | |
1191 // 32-bit | |
1192 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); | |
1193 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); | |
1194 if (cbuf) { | |
4759 | 1195 MacroAssembler _masm(cbuf); |
1196 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); | |
0 | 1197 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1198 } else { |
0 | 1199 st->print("movdl %s, %s\t# spill", |
1200 Matcher::regName[dst_first], | |
1201 Matcher::regName[src_first]); | |
1202 #endif | |
1203 } | |
1204 } | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1205 return 0; |
0 | 1206 } |
1207 } else if (src_first_rc == rc_float) { | |
1208 // xmm -> | |
1209 if (dst_first_rc == rc_stack) { | |
1210 // xmm -> mem | |
1211 if ((src_first & 1) == 0 && src_first + 1 == src_second && | |
1212 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { | |
1213 // 64-bit | |
1214 int offset = ra_->reg2offset(dst_first); | |
1215 if (cbuf) { | |
4759 | 1216 MacroAssembler _masm(cbuf); |
1217 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); | |
0 | 1218 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1219 } else { |
0 | 1220 st->print("movsd [rsp + #%d], %s\t# spill", |
1221 offset, | |
1222 Matcher::regName[src_first]); | |
1223 #endif | |
1224 } | |
1225 } else { | |
1226 // 32-bit | |
1227 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); | |
1228 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); | |
1229 int offset = ra_->reg2offset(dst_first); | |
1230 if (cbuf) { | |
4759 | 1231 MacroAssembler _masm(cbuf); |
1232 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); | |
0 | 1233 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1234 } else { |
0 | 1235 st->print("movss [rsp + #%d], %s\t# spill", |
1236 offset, | |
1237 Matcher::regName[src_first]); | |
1238 #endif | |
1239 } | |
1240 } | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1241 return 0; |
0 | 1242 } else if (dst_first_rc == rc_int) { |
1243 // xmm -> gpr | |
1244 if ((src_first & 1) == 0 && src_first + 1 == src_second && | |
1245 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { | |
1246 // 64-bit | |
1247 if (cbuf) { | |
4759 | 1248 MacroAssembler _masm(cbuf); |
1249 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); | |
0 | 1250 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1251 } else { |
0 | 1252 st->print("movdq %s, %s\t# spill", |
1253 Matcher::regName[dst_first], | |
1254 Matcher::regName[src_first]); | |
1255 #endif | |
1256 } | |
1257 } else { | |
1258 // 32-bit | |
1259 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); | |
1260 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); | |
1261 if (cbuf) { | |
4759 | 1262 MacroAssembler _masm(cbuf); |
1263 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); | |
0 | 1264 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1265 } else { |
0 | 1266 st->print("movdl %s, %s\t# spill", |
1267 Matcher::regName[dst_first], | |
1268 Matcher::regName[src_first]); | |
1269 #endif | |
1270 } | |
1271 } | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1272 return 0; |
0 | 1273 } else if (dst_first_rc == rc_float) { |
1274 // xmm -> xmm | |
1275 if ((src_first & 1) == 0 && src_first + 1 == src_second && | |
1276 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { | |
1277 // 64-bit | |
1278 if (cbuf) { | |
4759 | 1279 MacroAssembler _masm(cbuf); |
1280 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); | |
0 | 1281 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1282 } else { |
0 | 1283 st->print("%s %s, %s\t# spill", |
1284 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", | |
1285 Matcher::regName[dst_first], | |
1286 Matcher::regName[src_first]); | |
1287 #endif | |
1288 } | |
1289 } else { | |
1290 // 32-bit | |
1291 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); | |
1292 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); | |
1293 if (cbuf) { | |
4759 | 1294 MacroAssembler _masm(cbuf); |
1295 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); | |
0 | 1296 #ifndef PRODUCT |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1297 } else { |
0 | 1298 st->print("%s %s, %s\t# spill", |
1299 UseXmmRegToRegMoveAll ? "movaps" : "movss ", | |
1300 Matcher::regName[dst_first], | |
1301 Matcher::regName[src_first]); | |
1302 #endif | |
1303 } | |
1304 } | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1305 return 0; |
0 | 1306 } |
1307 } | |
1308 | |
1309 assert(0," foo "); | |
1310 Unimplemented(); | |
1311 return 0; | |
1312 } | |
1313 | |
1314 #ifndef PRODUCT | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1315 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { |
0 | 1316 implementation(NULL, ra_, false, st); |
1317 } | |
1318 #endif | |
1319 | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1320 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { |
0 | 1321 implementation(&cbuf, ra_, false, NULL); |
1322 } | |
1323 | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1324 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1325 return MachNode::size(ra_); |
0 | 1326 } |
1327 | |
1328 //============================================================================= | |
1329 #ifndef PRODUCT | |
1330 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const | |
1331 { | |
1332 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); | |
1333 int reg = ra_->get_reg_first(this); | |
1334 st->print("leaq %s, [rsp + #%d]\t# box lock", | |
1335 Matcher::regName[reg], offset); | |
1336 } | |
1337 #endif | |
1338 | |
1339 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const | |
1340 { | |
1341 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); | |
1342 int reg = ra_->get_encode(this); | |
1343 if (offset >= 0x80) { | |
1344 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); | |
1345 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] | |
1346 emit_rm(cbuf, 0x2, reg & 7, 0x04); | |
1347 emit_rm(cbuf, 0x0, 0x04, RSP_enc); | |
1348 emit_d32(cbuf, offset); | |
1349 } else { | |
1350 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); | |
1351 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] | |
1352 emit_rm(cbuf, 0x1, reg & 7, 0x04); | |
1353 emit_rm(cbuf, 0x0, 0x04, RSP_enc); | |
1354 emit_d8(cbuf, offset); | |
1355 } | |
1356 } | |
1357 | |
1358 uint BoxLockNode::size(PhaseRegAlloc *ra_) const | |
1359 { | |
1360 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); | |
1361 return (offset < 0x80) ? 5 : 8; // REX | |
1362 } | |
1363 | |
1364 //============================================================================= | |
1365 | |
1366 // emit call stub, compiled java to interpreter | |
1367 void emit_java_to_interp(CodeBuffer& cbuf) | |
1368 { | |
1369 // Stub is fixed up when the corresponding call is converted from | |
1370 // calling compiled code to calling interpreted code. | |
1371 // movq rbx, 0 | |
1372 // jmp -5 # to self | |
1373 | |
1748 | 1374 address mark = cbuf.insts_mark(); // get mark within main instrs section |
1375 | |
1376 // Note that the code buffer's insts_mark is always relative to insts. | |
0 | 1377 // That's why we must use the macroassembler to generate a stub. |
1378 MacroAssembler _masm(&cbuf); | |
1379 | |
1380 address base = | |
1381 __ start_a_stub(Compile::MAX_stubs_size); | |
1382 if (base == NULL) return; // CodeBuffer::expand failed | |
1383 // static stub relocation stores the instruction address of the call | |
1384 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); | |
1385 // static stub relocation also tags the methodOop in the code-stream. | |
1386 __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time | |
304 | 1387 // This is recognized as unresolved by relocs/nativeinst/ic code |
0 | 1388 __ jump(RuntimeAddress(__ pc())); |
1389 | |
1748 | 1390 // Update current stubs pointer and restore insts_end. |
0 | 1391 __ end_a_stub(); |
1392 } | |
1393 | |
1394 // size of call stub, compiled java to interpretor | |
1395 uint size_java_to_interp() | |
1396 { | |
1397 return 15; // movq (1+1+8); jmp (1+4) | |
1398 } | |
1399 | |
1400 // relocation entries for call stub, compiled java to interpretor | |
1401 uint reloc_java_to_interp() | |
1402 { | |
1403 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call | |
1404 } | |
1405 | |
1406 //============================================================================= | |
1407 #ifndef PRODUCT | |
1408 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const | |
1409 { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1410 if (UseCompressedOops) { |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1411 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
1412 if (Universe::narrow_oop_shift() != 0) { |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1413 st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1"); |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1414 } |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1415 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1416 } else { |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1417 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1418 "# Inline cache check"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1419 } |
0 | 1420 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1421 st->print_cr("\tnop\t# nops to align entry point"); |
0 | 1422 } |
1423 #endif | |
1424 | |
1425 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const | |
1426 { | |
1427 MacroAssembler masm(&cbuf); | |
1748 | 1428 uint insts_size = cbuf.insts_size(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1429 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1430 masm.load_klass(rscratch1, j_rarg0); |
304 | 1431 masm.cmpptr(rax, rscratch1); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1432 } else { |
304 | 1433 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1434 } |
0 | 1435 |
1436 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); | |
1437 | |
1438 /* WARNING these NOPs are critical so that verified entry point is properly | |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1439 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ |
1748 | 1440 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1441 if (OptoBreakpoint) { |
0 | 1442 // Leave space for int3 |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1443 nops_cnt -= 1; |
0 | 1444 } |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1445 nops_cnt &= 0x3; // Do not add nops if code is aligned. |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1446 if (nops_cnt > 0) |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1447 masm.nop(nops_cnt); |
0 | 1448 } |
1449 | |
1450 uint MachUEPNode::size(PhaseRegAlloc* ra_) const | |
1451 { | |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1452 return MachNode::size(ra_); // too many variables; just compute it |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
1453 // the hard way |
0 | 1454 } |
1455 | |
1456 | |
1457 //============================================================================= | |
1458 uint size_exception_handler() | |
1459 { | |
1460 // NativeCall instruction size is the same as NativeJump. | |
1461 // Note that this value is also credited (in output.cpp) to | |
1462 // the size of the code section. | |
1463 return NativeJump::instruction_size; | |
1464 } | |
1465 | |
1466 // Emit exception handler code. | |
1467 int emit_exception_handler(CodeBuffer& cbuf) | |
1468 { | |
1469 | |
1748 | 1470 // Note that the code buffer's insts_mark is always relative to insts. |
0 | 1471 // That's why we must use the macroassembler to generate a handler. |
1472 MacroAssembler _masm(&cbuf); | |
1473 address base = | |
1474 __ start_a_stub(size_exception_handler()); | |
1475 if (base == NULL) return 0; // CodeBuffer::expand failed | |
1476 int offset = __ offset(); | |
1748 | 1477 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); |
0 | 1478 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); |
1479 __ end_a_stub(); | |
1480 return offset; | |
1481 } | |
1482 | |
1483 uint size_deopt_handler() | |
1484 { | |
1485 // three 5 byte instructions | |
1486 return 15; | |
1487 } | |
1488 | |
1489 // Emit deopt handler code. | |
1490 int emit_deopt_handler(CodeBuffer& cbuf) | |
1491 { | |
1492 | |
1748 | 1493 // Note that the code buffer's insts_mark is always relative to insts. |
0 | 1494 // That's why we must use the macroassembler to generate a handler. |
1495 MacroAssembler _masm(&cbuf); | |
1496 address base = | |
1497 __ start_a_stub(size_deopt_handler()); | |
1498 if (base == NULL) return 0; // CodeBuffer::expand failed | |
1499 int offset = __ offset(); | |
1500 address the_pc = (address) __ pc(); | |
1501 Label next; | |
1502 // push a "the_pc" on the stack without destroying any registers | |
1503 // as they all may be live. | |
1504 | |
1505 // push address of "next" | |
1506 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 | |
1507 __ bind(next); | |
1508 // adjust it so it matches "the_pc" | |
304 | 1509 __ subptr(Address(rsp, 0), __ offset() - offset); |
0 | 1510 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); |
1511 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); | |
1512 __ end_a_stub(); | |
1513 return offset; | |
1514 } | |
1515 | |
1516 | |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
1517 const bool Matcher::match_rule_supported(int opcode) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
1518 if (!has_match_rule(opcode)) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
1519 return false; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
1520 |
5934
61b82be3b1ff
7152957: VM crashes with assert(false) failed: bad AD file
never
parents:
4950
diff
changeset
|
1521 switch (opcode) { |
61b82be3b1ff
7152957: VM crashes with assert(false) failed: bad AD file
never
parents:
4950
diff
changeset
|
1522 case Op_PopCountI: |
61b82be3b1ff
7152957: VM crashes with assert(false) failed: bad AD file
never
parents:
4950
diff
changeset
|
1523 case Op_PopCountL: |
61b82be3b1ff
7152957: VM crashes with assert(false) failed: bad AD file
never
parents:
4950
diff
changeset
|
1524 if (!UsePopCountInstruction) |
61b82be3b1ff
7152957: VM crashes with assert(false) failed: bad AD file
never
parents:
4950
diff
changeset
|
1525 return false; |
61b82be3b1ff
7152957: VM crashes with assert(false) failed: bad AD file
never
parents:
4950
diff
changeset
|
1526 break; |
61b82be3b1ff
7152957: VM crashes with assert(false) failed: bad AD file
never
parents:
4950
diff
changeset
|
1527 } |
61b82be3b1ff
7152957: VM crashes with assert(false) failed: bad AD file
never
parents:
4950
diff
changeset
|
1528 |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
1529 return true; // Per default match rules are supported. |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
1530 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
1531 |
0 | 1532 int Matcher::regnum_to_fpu_offset(int regnum) |
1533 { | |
1534 return regnum - 32; // The FP registers are in the second chunk | |
1535 } | |
1536 | |
1537 // This is UltraSparc specific, true just means we have fast l2f conversion | |
1538 const bool Matcher::convL2FSupported(void) { | |
1539 return true; | |
1540 } | |
1541 | |
1542 // Is this branch offset short enough that a short branch can be used? | |
1543 // | |
1544 // NOTE: If the platform does not provide any short branch variants, then | |
1545 // this method should return false for offset 0. | |
3851 | 1546 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { |
1547 // The passed offset is relative to address of the branch. | |
1548 // On 86 a branch displacement is calculated relative to address | |
1549 // of a next instruction. | |
1550 offset -= br_size; | |
1551 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
1552 // the short version of jmpConUCF2 contains multiple branches, |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
1553 // making the reach slightly less |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
1554 if (rule == jmpConUCF2_rule) |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
1555 return (-126 <= offset && offset <= 125); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
1556 return (-128 <= offset && offset <= 127); |
0 | 1557 } |
1558 | |
1559 const bool Matcher::isSimpleConstant64(jlong value) { | |
1560 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. | |
1561 //return value == (int) value; // Cf. storeImmL and immL32. | |
1562 | |
1563 // Probably always true, even if a temp register is required. | |
1564 return true; | |
1565 } | |
1566 | |
1567 // The ecx parameter to rep stosq for the ClearArray node is in words. | |
1568 const bool Matcher::init_array_count_is_in_bytes = false; | |
1569 | |
1570 // Threshold size for cleararray. | |
1571 const int Matcher::init_array_short_size = 8 * BytesPerLong; | |
1572 | |
4047 | 1573 // No additional cost for CMOVL. |
1574 const int Matcher::long_cmove_cost() { return 0; } | |
1575 | |
1576 // No CMOVF/CMOVD with SSE2 | |
1577 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } | |
1578 | |
0 | 1579 // Should the Matcher clone shifts on addressing modes, expecting them |
1580 // to be subsumed into complex addressing expressions or compute them | |
1581 // into registers? True for Intel but false for most RISCs | |
1582 const bool Matcher::clone_shift_expressions = true; | |
1583 | |
2401
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2320
diff
changeset
|
1584 // Do we need to mask the count passed to shift instructions or does |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2320
diff
changeset
|
1585 // the cpu only look at the lower 5/6 bits anyway? |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2320
diff
changeset
|
1586 const bool Matcher::need_masked_shift_count = false; |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2320
diff
changeset
|
1587 |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1588 bool Matcher::narrow_oop_use_complex_address() { |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1589 assert(UseCompressedOops, "only for compressed oops code"); |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1590 return (LogMinObjAlignmentInBytes <= 3); |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1591 } |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1592 |
0 | 1593 // Is it better to copy float constants, or load them directly from |
1594 // memory? Intel can load a float constant from a direct address, | |
1595 // requiring no extra registers. Most RISCs will have to materialize | |
1596 // an address into a register first, so they would do better to copy | |
1597 // the constant from stack. | |
1598 const bool Matcher::rematerialize_float_constants = true; // XXX | |
1599 | |
1600 // If CPU can load and store mis-aligned doubles directly then no | |
1601 // fixup is needed. Else we split the double into 2 integer pieces | |
1602 // and move it piece-by-piece. Only happens when passing doubles into | |
1603 // C code as the Java calling convention forces doubles to be aligned. | |
1604 const bool Matcher::misaligned_doubles_ok = true; | |
1605 | |
1606 // No-op on amd64 | |
1607 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} | |
1608 | |
1609 // Advertise here if the CPU requires explicit rounding operations to | |
1610 // implement the UseStrictFP mode. | |
1611 const bool Matcher::strict_fp_requires_explicit_rounding = true; | |
1612 | |
1274
2883969d09e7
6910664: C2: java/util/Arrays/Sorting.java fails with DeoptimizeALot flag
kvn
parents:
1137
diff
changeset
|
1613 // Are floats conerted to double when stored to stack during deoptimization? |
2883969d09e7
6910664: C2: java/util/Arrays/Sorting.java fails with DeoptimizeALot flag
kvn
parents:
1137
diff
changeset
|
1614 // On x64 it is stored without convertion so we can use normal access. |
2883969d09e7
6910664: C2: java/util/Arrays/Sorting.java fails with DeoptimizeALot flag
kvn
parents:
1137
diff
changeset
|
1615 bool Matcher::float_in_double() { return false; } |
2883969d09e7
6910664: C2: java/util/Arrays/Sorting.java fails with DeoptimizeALot flag
kvn
parents:
1137
diff
changeset
|
1616 |
0 | 1617 // Do ints take an entire long register or just half? |
1618 const bool Matcher::int_in_long = true; | |
1619 | |
1620 // Return whether or not this register is ever used as an argument. | |
1621 // This function is used on startup to build the trampoline stubs in | |
1622 // generateOptoStub. Registers not mentioned will be killed by the VM | |
1623 // call in the trampoline, and arguments in those registers not be | |
1624 // available to the callee. | |
1625 bool Matcher::can_be_java_arg(int reg) | |
1626 { | |
1627 return | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1628 reg == RDI_num || reg == RDI_H_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1629 reg == RSI_num || reg == RSI_H_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1630 reg == RDX_num || reg == RDX_H_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1631 reg == RCX_num || reg == RCX_H_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1632 reg == R8_num || reg == R8_H_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1633 reg == R9_num || reg == R9_H_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1634 reg == R12_num || reg == R12_H_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1635 reg == XMM0_num || reg == XMM0b_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1636 reg == XMM1_num || reg == XMM1b_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1637 reg == XMM2_num || reg == XMM2b_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1638 reg == XMM3_num || reg == XMM3b_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1639 reg == XMM4_num || reg == XMM4b_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1640 reg == XMM5_num || reg == XMM5b_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1641 reg == XMM6_num || reg == XMM6b_num || |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
1642 reg == XMM7_num || reg == XMM7b_num; |
0 | 1643 } |
1644 | |
1645 bool Matcher::is_spillable_arg(int reg) | |
1646 { | |
1647 return can_be_java_arg(reg); | |
1648 } | |
1649 | |
1914
ae065c367d93
6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents:
1827
diff
changeset
|
1650 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { |
ae065c367d93
6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents:
1827
diff
changeset
|
1651 // In 64 bit mode a code which use multiply when |
ae065c367d93
6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents:
1827
diff
changeset
|
1652 // devisor is constant is faster than hardware |
ae065c367d93
6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents:
1827
diff
changeset
|
1653 // DIV instruction (it uses MulHiL). |
ae065c367d93
6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents:
1827
diff
changeset
|
1654 return false; |
ae065c367d93
6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents:
1827
diff
changeset
|
1655 } |
ae065c367d93
6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents:
1827
diff
changeset
|
1656 |
0 | 1657 // Register for DIVI projection of divmodI |
1658 RegMask Matcher::divI_proj_mask() { | |
4121
db2e64ca2d5a
7090968: Allow adlc register class to depend on runtime conditions
roland
parents:
4114
diff
changeset
|
1659 return INT_RAX_REG_mask(); |
0 | 1660 } |
1661 | |
1662 // Register for MODI projection of divmodI | |
1663 RegMask Matcher::modI_proj_mask() { | |
4121
db2e64ca2d5a
7090968: Allow adlc register class to depend on runtime conditions
roland
parents:
4114
diff
changeset
|
1664 return INT_RDX_REG_mask(); |
0 | 1665 } |
1666 | |
1667 // Register for DIVL projection of divmodL | |
1668 RegMask Matcher::divL_proj_mask() { | |
4121
db2e64ca2d5a
7090968: Allow adlc register class to depend on runtime conditions
roland
parents:
4114
diff
changeset
|
1669 return LONG_RAX_REG_mask(); |
0 | 1670 } |
1671 | |
1672 // Register for MODL projection of divmodL | |
1673 RegMask Matcher::modL_proj_mask() { | |
4121
db2e64ca2d5a
7090968: Allow adlc register class to depend on runtime conditions
roland
parents:
4114
diff
changeset
|
1674 return LONG_RDX_REG_mask(); |
0 | 1675 } |
1676 | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
1677 const RegMask Matcher::method_handle_invoke_SP_save_mask() { |
4121
db2e64ca2d5a
7090968: Allow adlc register class to depend on runtime conditions
roland
parents:
4114
diff
changeset
|
1678 return PTR_RBP_REG_mask(); |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
1679 } |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
1680 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1681 static Address build_address(int b, int i, int s, int d) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1682 Register index = as_Register(i); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1683 Address::ScaleFactor scale = (Address::ScaleFactor)s; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1684 if (index == rsp) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1685 index = noreg; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1686 scale = Address::no_scale; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1687 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1688 Address addr(as_Register(b), index, scale, d); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1689 return addr; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1690 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
1691 |
0 | 1692 %} |
1693 | |
1694 //----------ENCODING BLOCK----------------------------------------------------- | |
1695 // This block specifies the encoding classes used by the compiler to | |
1696 // output byte streams. Encoding classes are parameterized macros | |
1697 // used by Machine Instruction Nodes in order to generate the bit | |
1698 // encoding of the instruction. Operands specify their base encoding | |
1699 // interface with the interface keyword. There are currently | |
1700 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & | |
1701 // COND_INTER. REG_INTER causes an operand to generate a function | |
1702 // which returns its register number when queried. CONST_INTER causes | |
1703 // an operand to generate a function which returns the value of the | |
1704 // constant when queried. MEMORY_INTER causes an operand to generate | |
1705 // four functions which return the Base Register, the Index Register, | |
1706 // the Scale Value, and the Offset Value of the operand when queried. | |
1707 // COND_INTER causes an operand to generate six functions which return | |
1708 // the encoding code (ie - encoding bits for the instruction) | |
1709 // associated with each basic boolean condition for a conditional | |
1710 // instruction. | |
1711 // | |
1712 // Instructions specify two basic values for encoding. Again, a | |
1713 // function is available to check if the constant displacement is an | |
1714 // oop. They use the ins_encode keyword to specify their encoding | |
1715 // classes (which must be a sequence of enc_class names, and their | |
1716 // parameters, specified in the encoding block), and they use the | |
1717 // opcode keyword to specify, in order, their primary, secondary, and | |
1718 // tertiary opcode. Only the opcode sections which a particular | |
1719 // instruction needs for encoding need to be specified. | |
1720 encode %{ | |
1721 // Build emit functions for each basic byte or larger field in the | |
1722 // intel encoding scheme (opcode, rm, sib, immediate), and call them | |
1723 // from C++ code in the enc_class source block. Emit functions will | |
1724 // live in the main source block for now. In future, we can | |
1725 // generalize this by adding a syntax that specifies the sizes of | |
1726 // fields in an order, so that the adlc can build the emit functions | |
1727 // automagically | |
1728 | |
1729 // Emit primary opcode | |
1730 enc_class OpcP | |
1731 %{ | |
1732 emit_opcode(cbuf, $primary); | |
1733 %} | |
1734 | |
1735 // Emit secondary opcode | |
1736 enc_class OpcS | |
1737 %{ | |
1738 emit_opcode(cbuf, $secondary); | |
1739 %} | |
1740 | |
1741 // Emit tertiary opcode | |
1742 enc_class OpcT | |
1743 %{ | |
1744 emit_opcode(cbuf, $tertiary); | |
1745 %} | |
1746 | |
1747 // Emit opcode directly | |
1748 enc_class Opcode(immI d8) | |
1749 %{ | |
1750 emit_opcode(cbuf, $d8$$constant); | |
1751 %} | |
1752 | |
1753 // Emit size prefix | |
1754 enc_class SizePrefix | |
1755 %{ | |
1756 emit_opcode(cbuf, 0x66); | |
1757 %} | |
1758 | |
1759 enc_class reg(rRegI reg) | |
1760 %{ | |
1761 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); | |
1762 %} | |
1763 | |
1764 enc_class reg_reg(rRegI dst, rRegI src) | |
1765 %{ | |
1766 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); | |
1767 %} | |
1768 | |
1769 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) | |
1770 %{ | |
1771 emit_opcode(cbuf, $opcode$$constant); | |
1772 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); | |
1773 %} | |
1774 | |
1775 enc_class cdql_enc(no_rax_rdx_RegI div) | |
1776 %{ | |
1777 // Full implementation of Java idiv and irem; checks for | |
1778 // special case as described in JVM spec., p.243 & p.271. | |
1779 // | |
1780 // normal case special case | |
1781 // | |
1782 // input : rax: dividend min_int | |
1783 // reg: divisor -1 | |
1784 // | |
1785 // output: rax: quotient (= rax idiv reg) min_int | |
1786 // rdx: remainder (= rax irem reg) 0 | |
1787 // | |
1788 // Code sequnce: | |
1789 // | |
1790 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax | |
1791 // 5: 75 07/08 jne e <normal> | |
1792 // 7: 33 d2 xor %edx,%edx | |
1793 // [div >= 8 -> offset + 1] | |
1794 // [REX_B] | |
1795 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div | |
1796 // c: 74 03/04 je 11 <done> | |
1797 // 000000000000000e <normal>: | |
1798 // e: 99 cltd | |
1799 // [div >= 8 -> offset + 1] | |
1800 // [REX_B] | |
1801 // f: f7 f9 idiv $div | |
1802 // 0000000000000011 <done>: | |
1803 | |
1804 // cmp $0x80000000,%eax | |
1805 emit_opcode(cbuf, 0x3d); | |
1806 emit_d8(cbuf, 0x00); | |
1807 emit_d8(cbuf, 0x00); | |
1808 emit_d8(cbuf, 0x00); | |
1809 emit_d8(cbuf, 0x80); | |
1810 | |
1811 // jne e <normal> | |
1812 emit_opcode(cbuf, 0x75); | |
1813 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); | |
1814 | |
1815 // xor %edx,%edx | |
1816 emit_opcode(cbuf, 0x33); | |
1817 emit_d8(cbuf, 0xD2); | |
1818 | |
1819 // cmp $0xffffffffffffffff,%ecx | |
1820 if ($div$$reg >= 8) { | |
1821 emit_opcode(cbuf, Assembler::REX_B); | |
1822 } | |
1823 emit_opcode(cbuf, 0x83); | |
1824 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); | |
1825 emit_d8(cbuf, 0xFF); | |
1826 | |
1827 // je 11 <done> | |
1828 emit_opcode(cbuf, 0x74); | |
1829 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); | |
1830 | |
1831 // <normal> | |
1832 // cltd | |
1833 emit_opcode(cbuf, 0x99); | |
1834 | |
1835 // idivl (note: must be emitted by the user of this rule) | |
1836 // <done> | |
1837 %} | |
1838 | |
1839 enc_class cdqq_enc(no_rax_rdx_RegL div) | |
1840 %{ | |
1841 // Full implementation of Java ldiv and lrem; checks for | |
1842 // special case as described in JVM spec., p.243 & p.271. | |
1843 // | |
1844 // normal case special case | |
1845 // | |
1846 // input : rax: dividend min_long | |
1847 // reg: divisor -1 | |
1848 // | |
1849 // output: rax: quotient (= rax idiv reg) min_long | |
1850 // rdx: remainder (= rax irem reg) 0 | |
1851 // | |
1852 // Code sequnce: | |
1853 // | |
1854 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx | |
1855 // 7: 00 00 80 | |
1856 // a: 48 39 d0 cmp %rdx,%rax | |
1857 // d: 75 08 jne 17 <normal> | |
1858 // f: 33 d2 xor %edx,%edx | |
1859 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div | |
1860 // 15: 74 05 je 1c <done> | |
1861 // 0000000000000017 <normal>: | |
1862 // 17: 48 99 cqto | |
1863 // 19: 48 f7 f9 idiv $div | |
1864 // 000000000000001c <done>: | |
1865 | |
1866 // mov $0x8000000000000000,%rdx | |
1867 emit_opcode(cbuf, Assembler::REX_W); | |
1868 emit_opcode(cbuf, 0xBA); | |
1869 emit_d8(cbuf, 0x00); | |
1870 emit_d8(cbuf, 0x00); | |
1871 emit_d8(cbuf, 0x00); | |
1872 emit_d8(cbuf, 0x00); | |
1873 emit_d8(cbuf, 0x00); | |
1874 emit_d8(cbuf, 0x00); | |
1875 emit_d8(cbuf, 0x00); | |
1876 emit_d8(cbuf, 0x80); | |
1877 | |
1878 // cmp %rdx,%rax | |
1879 emit_opcode(cbuf, Assembler::REX_W); | |
1880 emit_opcode(cbuf, 0x39); | |
1881 emit_d8(cbuf, 0xD0); | |
1882 | |
1883 // jne 17 <normal> | |
1884 emit_opcode(cbuf, 0x75); | |
1885 emit_d8(cbuf, 0x08); | |
1886 | |
1887 // xor %edx,%edx | |
1888 emit_opcode(cbuf, 0x33); | |
1889 emit_d8(cbuf, 0xD2); | |
1890 | |
1891 // cmp $0xffffffffffffffff,$div | |
1892 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); | |
1893 emit_opcode(cbuf, 0x83); | |
1894 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); | |
1895 emit_d8(cbuf, 0xFF); | |
1896 | |
1897 // je 1e <done> | |
1898 emit_opcode(cbuf, 0x74); | |
1899 emit_d8(cbuf, 0x05); | |
1900 | |
1901 // <normal> | |
1902 // cqto | |
1903 emit_opcode(cbuf, Assembler::REX_W); | |
1904 emit_opcode(cbuf, 0x99); | |
1905 | |
1906 // idivq (note: must be emitted by the user of this rule) | |
1907 // <done> | |
1908 %} | |
1909 | |
1910 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension | |
1911 enc_class OpcSE(immI imm) | |
1912 %{ | |
1913 // Emit primary opcode and set sign-extend bit | |
1914 // Check for 8-bit immediate, and set sign extend bit in opcode | |
1915 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { | |
1916 emit_opcode(cbuf, $primary | 0x02); | |
1917 } else { | |
1918 // 32-bit immediate | |
1919 emit_opcode(cbuf, $primary); | |
1920 } | |
1921 %} | |
1922 | |
1923 enc_class OpcSErm(rRegI dst, immI imm) | |
1924 %{ | |
1925 // OpcSEr/m | |
1926 int dstenc = $dst$$reg; | |
1927 if (dstenc >= 8) { | |
1928 emit_opcode(cbuf, Assembler::REX_B); | |
1929 dstenc -= 8; | |
1930 } | |
1931 // Emit primary opcode and set sign-extend bit | |
1932 // Check for 8-bit immediate, and set sign extend bit in opcode | |
1933 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { | |
1934 emit_opcode(cbuf, $primary | 0x02); | |
1935 } else { | |
1936 // 32-bit immediate | |
1937 emit_opcode(cbuf, $primary); | |
1938 } | |
1939 // Emit r/m byte with secondary opcode, after primary opcode. | |
1940 emit_rm(cbuf, 0x3, $secondary, dstenc); | |
1941 %} | |
1942 | |
1943 enc_class OpcSErm_wide(rRegL dst, immI imm) | |
1944 %{ | |
1945 // OpcSEr/m | |
1946 int dstenc = $dst$$reg; | |
1947 if (dstenc < 8) { | |
1948 emit_opcode(cbuf, Assembler::REX_W); | |
1949 } else { | |
1950 emit_opcode(cbuf, Assembler::REX_WB); | |
1951 dstenc -= 8; | |
1952 } | |
1953 // Emit primary opcode and set sign-extend bit | |
1954 // Check for 8-bit immediate, and set sign extend bit in opcode | |
1955 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { | |
1956 emit_opcode(cbuf, $primary | 0x02); | |
1957 } else { | |
1958 // 32-bit immediate | |
1959 emit_opcode(cbuf, $primary); | |
1960 } | |
1961 // Emit r/m byte with secondary opcode, after primary opcode. | |
1962 emit_rm(cbuf, 0x3, $secondary, dstenc); | |
1963 %} | |
1964 | |
1965 enc_class Con8or32(immI imm) | |
1966 %{ | |
1967 // Check for 8-bit immediate, and set sign extend bit in opcode | |
1968 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { | |
1969 $$$emit8$imm$$constant; | |
1970 } else { | |
1971 // 32-bit immediate | |
1972 $$$emit32$imm$$constant; | |
1973 } | |
1974 %} | |
1975 | |
1976 enc_class opc2_reg(rRegI dst) | |
1977 %{ | |
1978 // BSWAP | |
1979 emit_cc(cbuf, $secondary, $dst$$reg); | |
1980 %} | |
1981 | |
1982 enc_class opc3_reg(rRegI dst) | |
1983 %{ | |
1984 // BSWAP | |
1985 emit_cc(cbuf, $tertiary, $dst$$reg); | |
1986 %} | |
1987 | |
1988 enc_class reg_opc(rRegI div) | |
1989 %{ | |
1990 // INC, DEC, IDIV, IMOD, JMP indirect, ... | |
1991 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); | |
1992 %} | |
1993 | |
1994 enc_class enc_cmov(cmpOp cop) | |
1995 %{ | |
1996 // CMOV | |
1997 $$$emit8$primary; | |
1998 emit_cc(cbuf, $secondary, $cop$$cmpcode); | |
1999 %} | |
2000 | |
2001 enc_class enc_PartialSubtypeCheck() | |
2002 %{ | |
2003 Register Rrdi = as_Register(RDI_enc); // result register | |
2004 Register Rrax = as_Register(RAX_enc); // super class | |
2005 Register Rrcx = as_Register(RCX_enc); // killed | |
2006 Register Rrsi = as_Register(RSI_enc); // sub class | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
2007 Label miss; |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
2008 const bool set_cond_codes = true; |
0 | 2009 |
2010 MacroAssembler _masm(&cbuf); | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
2011 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
2012 NULL, &miss, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
2013 /*set_cond_codes:*/ true); |
0 | 2014 if ($primary) { |
304 | 2015 __ xorptr(Rrdi, Rrdi); |
0 | 2016 } |
2017 __ bind(miss); | |
2018 %} | |
2019 | |
2020 enc_class Java_To_Interpreter(method meth) | |
2021 %{ | |
2022 // CALL Java_To_Interpreter | |
2023 // This is the instruction starting address for relocation info. | |
1748 | 2024 cbuf.set_insts_mark(); |
0 | 2025 $$$emit8$primary; |
2026 // CALL directly to the runtime | |
2027 emit_d32_reloc(cbuf, | |
1748 | 2028 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), |
0 | 2029 runtime_call_Relocation::spec(), |
2030 RELOC_DISP32); | |
2031 %} | |
2032 | |
2033 enc_class Java_Static_Call(method meth) | |
2034 %{ | |
2035 // JAVA STATIC CALL | |
2036 // CALL to fixup routine. Fixup routine uses ScopeDesc info to | |
2037 // determine who we intended to call. | |
1748 | 2038 cbuf.set_insts_mark(); |
0 | 2039 $$$emit8$primary; |
2040 | |
2041 if (!_method) { | |
2042 emit_d32_reloc(cbuf, | |
1748 | 2043 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), |
0 | 2044 runtime_call_Relocation::spec(), |
2045 RELOC_DISP32); | |
2046 } else if (_optimized_virtual) { | |
2047 emit_d32_reloc(cbuf, | |
1748 | 2048 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), |
0 | 2049 opt_virtual_call_Relocation::spec(), |
2050 RELOC_DISP32); | |
2051 } else { | |
2052 emit_d32_reloc(cbuf, | |
1748 | 2053 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), |
0 | 2054 static_call_Relocation::spec(), |
2055 RELOC_DISP32); | |
2056 } | |
2057 if (_method) { | |
2058 // Emit stub for static call | |
2059 emit_java_to_interp(cbuf); | |
2060 } | |
2061 %} | |
2062 | |
2063 enc_class Java_Dynamic_Call(method meth) | |
2064 %{ | |
2065 // JAVA DYNAMIC CALL | |
2066 // !!!!! | |
2067 // Generate "movq rax, -1", placeholder instruction to load oop-info | |
2068 // emit_call_dynamic_prologue( cbuf ); | |
1748 | 2069 cbuf.set_insts_mark(); |
0 | 2070 |
2071 // movq rax, -1 | |
2072 emit_opcode(cbuf, Assembler::REX_W); | |
2073 emit_opcode(cbuf, 0xB8 | RAX_enc); | |
2074 emit_d64_reloc(cbuf, | |
2075 (int64_t) Universe::non_oop_word(), | |
2076 oop_Relocation::spec_for_immediate(), RELOC_IMM64); | |
1748 | 2077 address virtual_call_oop_addr = cbuf.insts_mark(); |
0 | 2078 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine |
2079 // who we intended to call. | |
1748 | 2080 cbuf.set_insts_mark(); |
0 | 2081 $$$emit8$primary; |
2082 emit_d32_reloc(cbuf, | |
1748 | 2083 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), |
0 | 2084 virtual_call_Relocation::spec(virtual_call_oop_addr), |
2085 RELOC_DISP32); | |
2086 %} | |
2087 | |
2088 enc_class Java_Compiled_Call(method meth) | |
2089 %{ | |
2090 // JAVA COMPILED CALL | |
2091 int disp = in_bytes(methodOopDesc:: from_compiled_offset()); | |
2092 | |
2093 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! | |
2094 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); | |
2095 | |
2096 // callq *disp(%rax) | |
1748 | 2097 cbuf.set_insts_mark(); |
0 | 2098 $$$emit8$primary; |
2099 if (disp < 0x80) { | |
2100 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte | |
2101 emit_d8(cbuf, disp); // Displacement | |
2102 } else { | |
2103 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte | |
2104 emit_d32(cbuf, disp); // Displacement | |
2105 } | |
2106 %} | |
2107 | |
2108 enc_class reg_opc_imm(rRegI dst, immI8 shift) | |
2109 %{ | |
2110 // SAL, SAR, SHR | |
2111 int dstenc = $dst$$reg; | |
2112 if (dstenc >= 8) { | |
2113 emit_opcode(cbuf, Assembler::REX_B); | |
2114 dstenc -= 8; | |
2115 } | |
2116 $$$emit8$primary; | |
2117 emit_rm(cbuf, 0x3, $secondary, dstenc); | |
2118 $$$emit8$shift$$constant; | |
2119 %} | |
2120 | |
2121 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) | |
2122 %{ | |
2123 // SAL, SAR, SHR | |
2124 int dstenc = $dst$$reg; | |
2125 if (dstenc < 8) { | |
2126 emit_opcode(cbuf, Assembler::REX_W); | |
2127 } else { | |
2128 emit_opcode(cbuf, Assembler::REX_WB); | |
2129 dstenc -= 8; | |
2130 } | |
2131 $$$emit8$primary; | |
2132 emit_rm(cbuf, 0x3, $secondary, dstenc); | |
2133 $$$emit8$shift$$constant; | |
2134 %} | |
2135 | |
2136 enc_class load_immI(rRegI dst, immI src) | |
2137 %{ | |
2138 int dstenc = $dst$$reg; | |
2139 if (dstenc >= 8) { | |
2140 emit_opcode(cbuf, Assembler::REX_B); | |
2141 dstenc -= 8; | |
2142 } | |
2143 emit_opcode(cbuf, 0xB8 | dstenc); | |
2144 $$$emit32$src$$constant; | |
2145 %} | |
2146 | |
2147 enc_class load_immL(rRegL dst, immL src) | |
2148 %{ | |
2149 int dstenc = $dst$$reg; | |
2150 if (dstenc < 8) { | |
2151 emit_opcode(cbuf, Assembler::REX_W); | |
2152 } else { | |
2153 emit_opcode(cbuf, Assembler::REX_WB); | |
2154 dstenc -= 8; | |
2155 } | |
2156 emit_opcode(cbuf, 0xB8 | dstenc); | |
2157 emit_d64(cbuf, $src$$constant); | |
2158 %} | |
2159 | |
2160 enc_class load_immUL32(rRegL dst, immUL32 src) | |
2161 %{ | |
2162 // same as load_immI, but this time we care about zeroes in the high word | |
2163 int dstenc = $dst$$reg; | |
2164 if (dstenc >= 8) { | |
2165 emit_opcode(cbuf, Assembler::REX_B); | |
2166 dstenc -= 8; | |
2167 } | |
2168 emit_opcode(cbuf, 0xB8 | dstenc); | |
2169 $$$emit32$src$$constant; | |
2170 %} | |
2171 | |
2172 enc_class load_immL32(rRegL dst, immL32 src) | |
2173 %{ | |
2174 int dstenc = $dst$$reg; | |
2175 if (dstenc < 8) { | |
2176 emit_opcode(cbuf, Assembler::REX_W); | |
2177 } else { | |
2178 emit_opcode(cbuf, Assembler::REX_WB); | |
2179 dstenc -= 8; | |
2180 } | |
2181 emit_opcode(cbuf, 0xC7); | |
2182 emit_rm(cbuf, 0x03, 0x00, dstenc); | |
2183 $$$emit32$src$$constant; | |
2184 %} | |
2185 | |
2186 enc_class load_immP31(rRegP dst, immP32 src) | |
2187 %{ | |
2188 // same as load_immI, but this time we care about zeroes in the high word | |
2189 int dstenc = $dst$$reg; | |
2190 if (dstenc >= 8) { | |
2191 emit_opcode(cbuf, Assembler::REX_B); | |
2192 dstenc -= 8; | |
2193 } | |
2194 emit_opcode(cbuf, 0xB8 | dstenc); | |
2195 $$$emit32$src$$constant; | |
2196 %} | |
2197 | |
2198 enc_class load_immP(rRegP dst, immP src) | |
2199 %{ | |
2200 int dstenc = $dst$$reg; | |
2201 if (dstenc < 8) { | |
2202 emit_opcode(cbuf, Assembler::REX_W); | |
2203 } else { | |
2204 emit_opcode(cbuf, Assembler::REX_WB); | |
2205 dstenc -= 8; | |
2206 } | |
2207 emit_opcode(cbuf, 0xB8 | dstenc); | |
2208 // This next line should be generated from ADLC | |
2209 if ($src->constant_is_oop()) { | |
2210 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64); | |
2211 } else { | |
2212 emit_d64(cbuf, $src$$constant); | |
2213 } | |
2214 %} | |
2215 | |
2216 enc_class Con32(immI src) | |
2217 %{ | |
2218 // Output immediate | |
2219 $$$emit32$src$$constant; | |
2220 %} | |
2221 | |
2222 enc_class Con64(immL src) | |
2223 %{ | |
2224 // Output immediate | |
2225 emit_d64($src$$constant); | |
2226 %} | |
2227 | |
2228 enc_class Con32F_as_bits(immF src) | |
2229 %{ | |
2230 // Output Float immediate bits | |
2231 jfloat jf = $src$$constant; | |
2232 jint jf_as_bits = jint_cast(jf); | |
2233 emit_d32(cbuf, jf_as_bits); | |
2234 %} | |
2235 | |
2236 enc_class Con16(immI src) | |
2237 %{ | |
2238 // Output immediate | |
2239 $$$emit16$src$$constant; | |
2240 %} | |
2241 | |
2242 // How is this different from Con32??? XXX | |
2243 enc_class Con_d32(immI src) | |
2244 %{ | |
2245 emit_d32(cbuf,$src$$constant); | |
2246 %} | |
2247 | |
2248 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) | |
2249 // Output immediate memory reference | |
2250 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); | |
2251 emit_d32(cbuf, 0x00); | |
2252 %} | |
2253 | |
2254 enc_class lock_prefix() | |
2255 %{ | |
2256 if (os::is_MP()) { | |
2257 emit_opcode(cbuf, 0xF0); // lock | |
2258 } | |
2259 %} | |
2260 | |
2261 enc_class REX_mem(memory mem) | |
2262 %{ | |
2263 if ($mem$$base >= 8) { | |
2264 if ($mem$$index < 8) { | |
2265 emit_opcode(cbuf, Assembler::REX_B); | |
2266 } else { | |
2267 emit_opcode(cbuf, Assembler::REX_XB); | |
2268 } | |
2269 } else { | |
2270 if ($mem$$index >= 8) { | |
2271 emit_opcode(cbuf, Assembler::REX_X); | |
2272 } | |
2273 } | |
2274 %} | |
2275 | |
2276 enc_class REX_mem_wide(memory mem) | |
2277 %{ | |
2278 if ($mem$$base >= 8) { | |
2279 if ($mem$$index < 8) { | |
2280 emit_opcode(cbuf, Assembler::REX_WB); | |
2281 } else { | |
2282 emit_opcode(cbuf, Assembler::REX_WXB); | |
2283 } | |
2284 } else { | |
2285 if ($mem$$index < 8) { | |
2286 emit_opcode(cbuf, Assembler::REX_W); | |
2287 } else { | |
2288 emit_opcode(cbuf, Assembler::REX_WX); | |
2289 } | |
2290 } | |
2291 %} | |
2292 | |
2293 // for byte regs | |
2294 enc_class REX_breg(rRegI reg) | |
2295 %{ | |
2296 if ($reg$$reg >= 4) { | |
2297 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); | |
2298 } | |
2299 %} | |
2300 | |
2301 // for byte regs | |
2302 enc_class REX_reg_breg(rRegI dst, rRegI src) | |
2303 %{ | |
2304 if ($dst$$reg < 8) { | |
2305 if ($src$$reg >= 4) { | |
2306 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); | |
2307 } | |
2308 } else { | |
2309 if ($src$$reg < 8) { | |
2310 emit_opcode(cbuf, Assembler::REX_R); | |
2311 } else { | |
2312 emit_opcode(cbuf, Assembler::REX_RB); | |
2313 } | |
2314 } | |
2315 %} | |
2316 | |
2317 // for byte regs | |
2318 enc_class REX_breg_mem(rRegI reg, memory mem) | |
2319 %{ | |
2320 if ($reg$$reg < 8) { | |
2321 if ($mem$$base < 8) { | |
2322 if ($mem$$index >= 8) { | |
2323 emit_opcode(cbuf, Assembler::REX_X); | |
2324 } else if ($reg$$reg >= 4) { | |
2325 emit_opcode(cbuf, Assembler::REX); | |
2326 } | |
2327 } else { | |
2328 if ($mem$$index < 8) { | |
2329 emit_opcode(cbuf, Assembler::REX_B); | |
2330 } else { | |
2331 emit_opcode(cbuf, Assembler::REX_XB); | |
2332 } | |
2333 } | |
2334 } else { | |
2335 if ($mem$$base < 8) { | |
2336 if ($mem$$index < 8) { | |
2337 emit_opcode(cbuf, Assembler::REX_R); | |
2338 } else { | |
2339 emit_opcode(cbuf, Assembler::REX_RX); | |
2340 } | |
2341 } else { | |
2342 if ($mem$$index < 8) { | |
2343 emit_opcode(cbuf, Assembler::REX_RB); | |
2344 } else { | |
2345 emit_opcode(cbuf, Assembler::REX_RXB); | |
2346 } | |
2347 } | |
2348 } | |
2349 %} | |
2350 | |
2351 enc_class REX_reg(rRegI reg) | |
2352 %{ | |
2353 if ($reg$$reg >= 8) { | |
2354 emit_opcode(cbuf, Assembler::REX_B); | |
2355 } | |
2356 %} | |
2357 | |
2358 enc_class REX_reg_wide(rRegI reg) | |
2359 %{ | |
2360 if ($reg$$reg < 8) { | |
2361 emit_opcode(cbuf, Assembler::REX_W); | |
2362 } else { | |
2363 emit_opcode(cbuf, Assembler::REX_WB); | |
2364 } | |
2365 %} | |
2366 | |
2367 enc_class REX_reg_reg(rRegI dst, rRegI src) | |
2368 %{ | |
2369 if ($dst$$reg < 8) { | |
2370 if ($src$$reg >= 8) { | |
2371 emit_opcode(cbuf, Assembler::REX_B); | |
2372 } | |
2373 } else { | |
2374 if ($src$$reg < 8) { | |
2375 emit_opcode(cbuf, Assembler::REX_R); | |
2376 } else { | |
2377 emit_opcode(cbuf, Assembler::REX_RB); | |
2378 } | |
2379 } | |
2380 %} | |
2381 | |
2382 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) | |
2383 %{ | |
2384 if ($dst$$reg < 8) { | |
2385 if ($src$$reg < 8) { | |
2386 emit_opcode(cbuf, Assembler::REX_W); | |
2387 } else { | |
2388 emit_opcode(cbuf, Assembler::REX_WB); | |
2389 } | |
2390 } else { | |
2391 if ($src$$reg < 8) { | |
2392 emit_opcode(cbuf, Assembler::REX_WR); | |
2393 } else { | |
2394 emit_opcode(cbuf, Assembler::REX_WRB); | |
2395 } | |
2396 } | |
2397 %} | |
2398 | |
2399 enc_class REX_reg_mem(rRegI reg, memory mem) | |
2400 %{ | |
2401 if ($reg$$reg < 8) { | |
2402 if ($mem$$base < 8) { | |
2403 if ($mem$$index >= 8) { | |
2404 emit_opcode(cbuf, Assembler::REX_X); | |
2405 } | |
2406 } else { | |
2407 if ($mem$$index < 8) { | |
2408 emit_opcode(cbuf, Assembler::REX_B); | |
2409 } else { | |
2410 emit_opcode(cbuf, Assembler::REX_XB); | |
2411 } | |
2412 } | |
2413 } else { | |
2414 if ($mem$$base < 8) { | |
2415 if ($mem$$index < 8) { | |
2416 emit_opcode(cbuf, Assembler::REX_R); | |
2417 } else { | |
2418 emit_opcode(cbuf, Assembler::REX_RX); | |
2419 } | |
2420 } else { | |
2421 if ($mem$$index < 8) { | |
2422 emit_opcode(cbuf, Assembler::REX_RB); | |
2423 } else { | |
2424 emit_opcode(cbuf, Assembler::REX_RXB); | |
2425 } | |
2426 } | |
2427 } | |
2428 %} | |
2429 | |
2430 enc_class REX_reg_mem_wide(rRegL reg, memory mem) | |
2431 %{ | |
2432 if ($reg$$reg < 8) { | |
2433 if ($mem$$base < 8) { | |
2434 if ($mem$$index < 8) { | |
2435 emit_opcode(cbuf, Assembler::REX_W); | |
2436 } else { | |
2437 emit_opcode(cbuf, Assembler::REX_WX); | |
2438 } | |
2439 } else { | |
2440 if ($mem$$index < 8) { | |
2441 emit_opcode(cbuf, Assembler::REX_WB); | |
2442 } else { | |
2443 emit_opcode(cbuf, Assembler::REX_WXB); | |
2444 } | |
2445 } | |
2446 } else { | |
2447 if ($mem$$base < 8) { | |
2448 if ($mem$$index < 8) { | |
2449 emit_opcode(cbuf, Assembler::REX_WR); | |
2450 } else { | |
2451 emit_opcode(cbuf, Assembler::REX_WRX); | |
2452 } | |
2453 } else { | |
2454 if ($mem$$index < 8) { | |
2455 emit_opcode(cbuf, Assembler::REX_WRB); | |
2456 } else { | |
2457 emit_opcode(cbuf, Assembler::REX_WRXB); | |
2458 } | |
2459 } | |
2460 } | |
2461 %} | |
2462 | |
2463 enc_class reg_mem(rRegI ereg, memory mem) | |
2464 %{ | |
2465 // High registers handle in encode_RegMem | |
2466 int reg = $ereg$$reg; | |
2467 int base = $mem$$base; | |
2468 int index = $mem$$index; | |
2469 int scale = $mem$$scale; | |
2470 int disp = $mem$$disp; | |
2471 bool disp_is_oop = $mem->disp_is_oop(); | |
2472 | |
2473 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_is_oop); | |
2474 %} | |
2475 | |
2476 enc_class RM_opc_mem(immI rm_opcode, memory mem) | |
2477 %{ | |
2478 int rm_byte_opcode = $rm_opcode$$constant; | |
2479 | |
2480 // High registers handle in encode_RegMem | |
2481 int base = $mem$$base; | |
2482 int index = $mem$$index; | |
2483 int scale = $mem$$scale; | |
2484 int displace = $mem$$disp; | |
2485 | |
2486 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when | |
2487 // working with static | |
2488 // globals | |
2489 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, | |
2490 disp_is_oop); | |
2491 %} | |
2492 | |
2493 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) | |
2494 %{ | |
2495 int reg_encoding = $dst$$reg; | |
2496 int base = $src0$$reg; // 0xFFFFFFFF indicates no base | |
2497 int index = 0x04; // 0x04 indicates no index | |
2498 int scale = 0x00; // 0x00 indicates no scale | |
2499 int displace = $src1$$constant; // 0x00 indicates no displacement | |
2500 bool disp_is_oop = false; | |
2501 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, | |
2502 disp_is_oop); | |
2503 %} | |
2504 | |
2505 enc_class neg_reg(rRegI dst) | |
2506 %{ | |
2507 int dstenc = $dst$$reg; | |
2508 if (dstenc >= 8) { | |
2509 emit_opcode(cbuf, Assembler::REX_B); | |
2510 dstenc -= 8; | |
2511 } | |
2512 // NEG $dst | |
2513 emit_opcode(cbuf, 0xF7); | |
2514 emit_rm(cbuf, 0x3, 0x03, dstenc); | |
2515 %} | |
2516 | |
2517 enc_class neg_reg_wide(rRegI dst) | |
2518 %{ | |
2519 int dstenc = $dst$$reg; | |
2520 if (dstenc < 8) { | |
2521 emit_opcode(cbuf, Assembler::REX_W); | |
2522 } else { | |
2523 emit_opcode(cbuf, Assembler::REX_WB); | |
2524 dstenc -= 8; | |
2525 } | |
2526 // NEG $dst | |
2527 emit_opcode(cbuf, 0xF7); | |
2528 emit_rm(cbuf, 0x3, 0x03, dstenc); | |
2529 %} | |
2530 | |
2531 enc_class setLT_reg(rRegI dst) | |
2532 %{ | |
2533 int dstenc = $dst$$reg; | |
2534 if (dstenc >= 8) { | |
2535 emit_opcode(cbuf, Assembler::REX_B); | |
2536 dstenc -= 8; | |
2537 } else if (dstenc >= 4) { | |
2538 emit_opcode(cbuf, Assembler::REX); | |
2539 } | |
2540 // SETLT $dst | |
2541 emit_opcode(cbuf, 0x0F); | |
2542 emit_opcode(cbuf, 0x9C); | |
2543 emit_rm(cbuf, 0x3, 0x0, dstenc); | |
2544 %} | |
2545 | |
2546 enc_class setNZ_reg(rRegI dst) | |
2547 %{ | |
2548 int dstenc = $dst$$reg; | |
2549 if (dstenc >= 8) { | |
2550 emit_opcode(cbuf, Assembler::REX_B); | |
2551 dstenc -= 8; | |
2552 } else if (dstenc >= 4) { | |
2553 emit_opcode(cbuf, Assembler::REX); | |
2554 } | |
2555 // SETNZ $dst | |
2556 emit_opcode(cbuf, 0x0F); | |
2557 emit_opcode(cbuf, 0x95); | |
2558 emit_rm(cbuf, 0x3, 0x0, dstenc); | |
2559 %} | |
2560 | |
2561 | |
2562 // Compare the lonogs and set -1, 0, or 1 into dst | |
2563 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) | |
2564 %{ | |
2565 int src1enc = $src1$$reg; | |
2566 int src2enc = $src2$$reg; | |
2567 int dstenc = $dst$$reg; | |
2568 | |
2569 // cmpq $src1, $src2 | |
2570 if (src1enc < 8) { | |
2571 if (src2enc < 8) { | |
2572 emit_opcode(cbuf, Assembler::REX_W); | |
2573 } else { | |
2574 emit_opcode(cbuf, Assembler::REX_WB); | |
2575 } | |
2576 } else { | |
2577 if (src2enc < 8) { | |
2578 emit_opcode(cbuf, Assembler::REX_WR); | |
2579 } else { | |
2580 emit_opcode(cbuf, Assembler::REX_WRB); | |
2581 } | |
2582 } | |
2583 emit_opcode(cbuf, 0x3B); | |
2584 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); | |
2585 | |
2586 // movl $dst, -1 | |
2587 if (dstenc >= 8) { | |
2588 emit_opcode(cbuf, Assembler::REX_B); | |
2589 } | |
2590 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); | |
2591 emit_d32(cbuf, -1); | |
2592 | |
2593 // jl,s done | |
2594 emit_opcode(cbuf, 0x7C); | |
2595 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); | |
2596 | |
2597 // setne $dst | |
2598 if (dstenc >= 4) { | |
2599 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); | |
2600 } | |
2601 emit_opcode(cbuf, 0x0F); | |
2602 emit_opcode(cbuf, 0x95); | |
2603 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); | |
2604 | |
2605 // movzbl $dst, $dst | |
2606 if (dstenc >= 4) { | |
2607 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); | |
2608 } | |
2609 emit_opcode(cbuf, 0x0F); | |
2610 emit_opcode(cbuf, 0xB6); | |
2611 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); | |
2612 %} | |
2613 | |
2614 enc_class Push_ResultXD(regD dst) %{ | |
4759 | 2615 MacroAssembler _masm(&cbuf); |
2616 __ fstp_d(Address(rsp, 0)); | |
2617 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); | |
2618 __ addptr(rsp, 8); | |
0 | 2619 %} |
2620 | |
2621 enc_class Push_SrcXD(regD src) %{ | |
2622 MacroAssembler _masm(&cbuf); | |
4759 | 2623 __ subptr(rsp, 8); |
2624 __ movdbl(Address(rsp, 0), $src$$XMMRegister); | |
2625 __ fld_d(Address(rsp, 0)); | |
2626 %} | |
2627 | |
0 | 2628 |
2629 // obj: object to lock | |
2630 // box: box address (header location) -- killed | |
2631 // tmp: rax -- killed | |
2632 // scr: rbx -- killed | |
2633 // | |
2634 // What follows is a direct transliteration of fast_lock() and fast_unlock() | |
2635 // from i486.ad. See that file for comments. | |
2636 // TODO: where possible switch from movq (r, 0) to movl(r,0) and | |
2637 // use the shorter encoding. (Movl clears the high-order 32-bits). | |
2638 | |
2639 | |
2640 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) | |
2641 %{ | |
2642 Register objReg = as_Register((int)$obj$$reg); | |
2643 Register boxReg = as_Register((int)$box$$reg); | |
2644 Register tmpReg = as_Register($tmp$$reg); | |
2645 Register scrReg = as_Register($scr$$reg); | |
2646 MacroAssembler masm(&cbuf); | |
2647 | |
2648 // Verify uniqueness of register assignments -- necessary but not sufficient | |
2649 assert (objReg != boxReg && objReg != tmpReg && | |
2650 objReg != scrReg && tmpReg != scrReg, "invariant") ; | |
2651 | |
2652 if (_counters != NULL) { | |
2653 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); | |
2654 } | |
2655 if (EmitSync & 1) { | |
304 | 2656 // Without cast to int32_t a movptr will destroy r10 which is typically obj |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2657 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2658 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; |
0 | 2659 } else |
2660 if (EmitSync & 2) { | |
2661 Label DONE_LABEL; | |
2662 if (UseBiasedLocking) { | |
2663 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. | |
2664 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); | |
2665 } | |
304 | 2666 // QQQ was movl... |
2667 masm.movptr(tmpReg, 0x1); | |
2668 masm.orptr(tmpReg, Address(objReg, 0)); | |
2669 masm.movptr(Address(boxReg, 0), tmpReg); | |
0 | 2670 if (os::is_MP()) { |
2671 masm.lock(); | |
2672 } | |
304 | 2673 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg |
0 | 2674 masm.jcc(Assembler::equal, DONE_LABEL); |
2675 | |
2676 // Recursive locking | |
304 | 2677 masm.subptr(tmpReg, rsp); |
2678 masm.andptr(tmpReg, 7 - os::vm_page_size()); | |
2679 masm.movptr(Address(boxReg, 0), tmpReg); | |
0 | 2680 |
2681 masm.bind(DONE_LABEL); | |
2682 masm.nop(); // avoid branch to branch | |
2683 } else { | |
2684 Label DONE_LABEL, IsInflated, Egress; | |
2685 | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2686 masm.movptr(tmpReg, Address(objReg, 0)) ; |
304 | 2687 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2688 masm.jcc (Assembler::notZero, IsInflated) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2689 |
0 | 2690 // it's stack-locked, biased or neutral |
2691 // TODO: optimize markword triage order to reduce the number of | |
2692 // conditional branches in the most common cases. | |
2693 // Beware -- there's a subtle invariant that fetch of the markword | |
2694 // at [FETCH], below, will never observe a biased encoding (*101b). | |
2695 // If this invariant is not held we'll suffer exclusion (safety) failure. | |
2696 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
2697 if (UseBiasedLocking && !UseOptoBiasInlining) { |
0 | 2698 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); |
304 | 2699 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] |
0 | 2700 } |
2701 | |
304 | 2702 // was q will it destroy high? |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2703 masm.orl (tmpReg, 1) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2704 masm.movptr(Address(boxReg, 0), tmpReg) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2705 if (os::is_MP()) { masm.lock(); } |
304 | 2706 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg |
0 | 2707 if (_counters != NULL) { |
2708 masm.cond_inc32(Assembler::equal, | |
2709 ExternalAddress((address) _counters->fast_path_entry_count_addr())); | |
2710 } | |
2711 masm.jcc (Assembler::equal, DONE_LABEL); | |
2712 | |
2713 // Recursive locking | |
304 | 2714 masm.subptr(tmpReg, rsp); |
2715 masm.andptr(tmpReg, 7 - os::vm_page_size()); | |
2716 masm.movptr(Address(boxReg, 0), tmpReg); | |
0 | 2717 if (_counters != NULL) { |
2718 masm.cond_inc32(Assembler::equal, | |
2719 ExternalAddress((address) _counters->fast_path_entry_count_addr())); | |
2720 } | |
2721 masm.jmp (DONE_LABEL) ; | |
2722 | |
2723 masm.bind (IsInflated) ; | |
2724 // It's inflated | |
2725 | |
2726 // TODO: someday avoid the ST-before-CAS penalty by | |
2727 // relocating (deferring) the following ST. | |
2728 // We should also think about trying a CAS without having | |
2729 // fetched _owner. If the CAS is successful we may | |
2730 // avoid an RTO->RTS upgrade on the $line. | |
304 | 2731 // Without cast to int32_t a movptr will destroy r10 which is typically obj |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2732 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2733 |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2734 masm.mov (boxReg, tmpReg) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2735 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2736 masm.testptr(tmpReg, tmpReg) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2737 masm.jcc (Assembler::notZero, DONE_LABEL) ; |
0 | 2738 |
2739 // It's inflated and appears unlocked | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2740 if (os::is_MP()) { masm.lock(); } |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2741 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; |
0 | 2742 // Intentional fall-through into DONE_LABEL ... |
2743 | |
2744 masm.bind (DONE_LABEL) ; | |
2745 masm.nop () ; // avoid jmp to jmp | |
2746 } | |
2747 %} | |
2748 | |
2749 // obj: object to unlock | |
2750 // box: box address (displaced header location), killed | |
2751 // RBX: killed tmp; cannot be obj nor box | |
2752 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) | |
2753 %{ | |
2754 | |
2755 Register objReg = as_Register($obj$$reg); | |
2756 Register boxReg = as_Register($box$$reg); | |
2757 Register tmpReg = as_Register($tmp$$reg); | |
2758 MacroAssembler masm(&cbuf); | |
2759 | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2760 if (EmitSync & 4) { |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2761 masm.cmpptr(rsp, 0) ; |
0 | 2762 } else |
2763 if (EmitSync & 8) { | |
2764 Label DONE_LABEL; | |
2765 if (UseBiasedLocking) { | |
2766 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); | |
2767 } | |
2768 | |
2769 // Check whether the displaced header is 0 | |
2770 //(=> recursive unlock) | |
304 | 2771 masm.movptr(tmpReg, Address(boxReg, 0)); |
2772 masm.testptr(tmpReg, tmpReg); | |
0 | 2773 masm.jcc(Assembler::zero, DONE_LABEL); |
2774 | |
2775 // If not recursive lock, reset the header to displaced header | |
2776 if (os::is_MP()) { | |
2777 masm.lock(); | |
2778 } | |
304 | 2779 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box |
0 | 2780 masm.bind(DONE_LABEL); |
2781 masm.nop(); // avoid branch to branch | |
2782 } else { | |
2783 Label DONE_LABEL, Stacked, CheckSucc ; | |
2784 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
2785 if (UseBiasedLocking && !UseOptoBiasInlining) { |
0 | 2786 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); |
2787 } | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2788 |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2789 masm.movptr(tmpReg, Address(objReg, 0)) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2790 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2791 masm.jcc (Assembler::zero, DONE_LABEL) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2792 masm.testl (tmpReg, 0x02) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2793 masm.jcc (Assembler::zero, Stacked) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2794 |
0 | 2795 // It's inflated |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2796 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2797 masm.xorptr(boxReg, r15_thread) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2798 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2799 masm.jcc (Assembler::notZero, DONE_LABEL) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2800 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2801 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2802 masm.jcc (Assembler::notZero, CheckSucc) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2803 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2804 masm.jmp (DONE_LABEL) ; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2805 |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2806 if ((EmitSync & 65536) == 0) { |
0 | 2807 Label LSuccess, LGoSlowPath ; |
2808 masm.bind (CheckSucc) ; | |
304 | 2809 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; |
0 | 2810 masm.jcc (Assembler::zero, LGoSlowPath) ; |
2811 | |
2812 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the | |
2813 // the explicit ST;MEMBAR combination, but masm doesn't currently support | |
2814 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc | |
2815 // are all faster when the write buffer is populated. | |
304 | 2816 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; |
0 | 2817 if (os::is_MP()) { |
304 | 2818 masm.lock () ; masm.addl (Address(rsp, 0), 0) ; |
0 | 2819 } |
304 | 2820 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; |
0 | 2821 masm.jcc (Assembler::notZero, LSuccess) ; |
2822 | |
304 | 2823 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX |
0 | 2824 if (os::is_MP()) { masm.lock(); } |
304 | 2825 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); |
0 | 2826 masm.jcc (Assembler::notEqual, LSuccess) ; |
2827 // Intentional fall-through into slow-path | |
2828 | |
2829 masm.bind (LGoSlowPath) ; | |
2830 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure | |
2831 masm.jmp (DONE_LABEL) ; | |
2832 | |
2833 masm.bind (LSuccess) ; | |
2834 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success | |
2835 masm.jmp (DONE_LABEL) ; | |
2836 } | |
2837 | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2838 masm.bind (Stacked) ; |
304 | 2839 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
2840 if (os::is_MP()) { masm.lock(); } |
304 | 2841 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box |
0 | 2842 |
2843 if (EmitSync & 65536) { | |
2844 masm.bind (CheckSucc) ; | |
2845 } | |
2846 masm.bind(DONE_LABEL); | |
2847 if (EmitSync & 32768) { | |
2848 masm.nop(); // avoid branch to branch | |
2849 } | |
2850 } | |
2851 %} | |
2852 | |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
2853 |
0 | 2854 enc_class enc_rethrow() |
2855 %{ | |
1748 | 2856 cbuf.set_insts_mark(); |
0 | 2857 emit_opcode(cbuf, 0xE9); // jmp entry |
2858 emit_d32_reloc(cbuf, | |
1748 | 2859 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), |
0 | 2860 runtime_call_Relocation::spec(), |
2861 RELOC_DISP32); | |
2862 %} | |
2863 | |
2864 %} | |
2865 | |
2866 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
2867 |
0 | 2868 //----------FRAME-------------------------------------------------------------- |
2869 // Definition of frame structure and management information. | |
2870 // | |
2871 // S T A C K L A Y O U T Allocators stack-slot number | |
2872 // | (to get allocators register number | |
2873 // G Owned by | | v add OptoReg::stack0()) | |
2874 // r CALLER | | | |
2875 // o | +--------+ pad to even-align allocators stack-slot | |
2876 // w V | pad0 | numbers; owned by CALLER | |
2877 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned | |
2878 // h ^ | in | 5 | |
2879 // | | args | 4 Holes in incoming args owned by SELF | |
2880 // | | | | 3 | |
2881 // | | +--------+ | |
2882 // V | | old out| Empty on Intel, window on Sparc | |
2883 // | old |preserve| Must be even aligned. | |
2884 // | SP-+--------+----> Matcher::_old_SP, even aligned | |
2885 // | | in | 3 area for Intel ret address | |
2886 // Owned by |preserve| Empty on Sparc. | |
2887 // SELF +--------+ | |
2888 // | | pad2 | 2 pad to align old SP | |
2889 // | +--------+ 1 | |
2890 // | | locks | 0 | |
2891 // | +--------+----> OptoReg::stack0(), even aligned | |
2892 // | | pad1 | 11 pad to align new SP | |
2893 // | +--------+ | |
2894 // | | | 10 | |
2895 // | | spills | 9 spills | |
2896 // V | | 8 (pad0 slot for callee) | |
2897 // -----------+--------+----> Matcher::_out_arg_limit, unaligned | |
2898 // ^ | out | 7 | |
2899 // | | args | 6 Holes in outgoing args owned by CALLEE | |
2900 // Owned by +--------+ | |
2901 // CALLEE | new out| 6 Empty on Intel, window on Sparc | |
2902 // | new |preserve| Must be even-aligned. | |
2903 // | SP-+--------+----> Matcher::_new_SP, even aligned | |
2904 // | | | | |
2905 // | |
2906 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is | |
2907 // known from SELF's arguments and the Java calling convention. | |
2908 // Region 6-7 is determined per call site. | |
2909 // Note 2: If the calling convention leaves holes in the incoming argument | |
2910 // area, those holes are owned by SELF. Holes in the outgoing area | |
2911 // are owned by the CALLEE. Holes should not be nessecary in the | |
2912 // incoming area, as the Java calling convention is completely under | |
2913 // the control of the AD file. Doubles can be sorted and packed to | |
2914 // avoid holes. Holes in the outgoing arguments may be nessecary for | |
2915 // varargs C calling conventions. | |
2916 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is | |
2917 // even aligned with pad0 as needed. | |
2918 // Region 6 is even aligned. Region 6-7 is NOT even aligned; | |
2919 // region 6-11 is even aligned; it may be padded out more so that | |
2920 // the region from SP to FP meets the minimum stack alignment. | |
2921 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack | |
2922 // alignment. Region 11, pad1, may be dynamically extended so that | |
2923 // SP meets the minimum alignment. | |
2924 | |
2925 frame | |
2926 %{ | |
2927 // What direction does stack grow in (assumed to be same for C & Java) | |
2928 stack_direction(TOWARDS_LOW); | |
2929 | |
2930 // These three registers define part of the calling convention | |
2931 // between compiled code and the interpreter. | |
2932 inline_cache_reg(RAX); // Inline Cache Register | |
2933 interpreter_method_oop_reg(RBX); // Method Oop Register when | |
2934 // calling interpreter | |
2935 | |
2936 // Optional: name the operand used by cisc-spilling to access | |
2937 // [stack_pointer + offset] | |
2938 cisc_spilling_operand_name(indOffset32); | |
2939 | |
2940 // Number of stack slots consumed by locking an object | |
2941 sync_stack_slots(2); | |
2942 | |
2943 // Compiled code's Frame Pointer | |
2944 frame_pointer(RSP); | |
2945 | |
2946 // Interpreter stores its frame pointer in a register which is | |
2947 // stored to the stack by I2CAdaptors. | |
2948 // I2CAdaptors convert from interpreted java to compiled java. | |
2949 interpreter_frame_pointer(RBP); | |
2950 | |
2951 // Stack alignment requirement | |
2952 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) | |
2953 | |
2954 // Number of stack slots between incoming argument block and the start of | |
2955 // a new frame. The PROLOG must add this many slots to the stack. The | |
2956 // EPILOG must remove this many slots. amd64 needs two slots for | |
2957 // return address. | |
2958 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); | |
2959 | |
2960 // Number of outgoing stack slots killed above the out_preserve_stack_slots | |
2961 // for calls to C. Supports the var-args backing area for register parms. | |
2962 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); | |
2963 | |
2964 // The after-PROLOG location of the return address. Location of | |
2965 // return address specifies a type (REG or STACK) and a number | |
2966 // representing the register number (i.e. - use a register name) or | |
2967 // stack slot. | |
2968 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. | |
2969 // Otherwise, it is above the locks and verification slot and alignment word | |
2970 return_addr(STACK - 2 + | |
4950 | 2971 round_to((Compile::current()->in_preserve_stack_slots() + |
2972 Compile::current()->fixed_slots()), | |
2973 stack_alignment_in_slots())); | |
0 | 2974 |
2975 // Body of function which returns an integer array locating | |
2976 // arguments either in registers or in stack slots. Passed an array | |
2977 // of ideal registers called "sig" and a "length" count. Stack-slot | |
2978 // offsets are based on outgoing arguments, i.e. a CALLER setting up | |
2979 // arguments for a CALLEE. Incoming stack arguments are | |
2980 // automatically biased by the preserve_stack_slots field above. | |
2981 | |
2982 calling_convention | |
2983 %{ | |
2984 // No difference between ingoing/outgoing just pass false | |
2985 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); | |
2986 %} | |
2987 | |
2988 c_calling_convention | |
2989 %{ | |
2990 // This is obviously always outgoing | |
2991 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); | |
2992 %} | |
2993 | |
2994 // Location of compiled Java return values. Same as C for now. | |
2995 return_value | |
2996 %{ | |
2997 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, | |
2998 "only return normal values"); | |
2999 | |
3000 static const int lo[Op_RegL + 1] = { | |
3001 0, | |
3002 0, | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3003 RAX_num, // Op_RegN |
0 | 3004 RAX_num, // Op_RegI |
3005 RAX_num, // Op_RegP | |
3006 XMM0_num, // Op_RegF | |
3007 XMM0_num, // Op_RegD | |
3008 RAX_num // Op_RegL | |
3009 }; | |
3010 static const int hi[Op_RegL + 1] = { | |
3011 0, | |
3012 0, | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3013 OptoReg::Bad, // Op_RegN |
0 | 3014 OptoReg::Bad, // Op_RegI |
3015 RAX_H_num, // Op_RegP | |
3016 OptoReg::Bad, // Op_RegF | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
3017 XMM0b_num, // Op_RegD |
0 | 3018 RAX_H_num // Op_RegL |
3019 }; | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
3020 // Excluded flags and vector registers. |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
3021 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type"); |
0 | 3022 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); |
3023 %} | |
3024 %} | |
3025 | |
3026 //----------ATTRIBUTES--------------------------------------------------------- | |
3027 //----------Operand Attributes------------------------------------------------- | |
3028 op_attrib op_cost(0); // Required cost attribute | |
3029 | |
3030 //----------Instruction Attributes--------------------------------------------- | |
3031 ins_attrib ins_cost(100); // Required cost attribute | |
3032 ins_attrib ins_size(8); // Required size attribute (in bits) | |
3033 ins_attrib ins_short_branch(0); // Required flag: is this instruction | |
3034 // a non-matching short branch variant | |
3035 // of some long branch? | |
3036 ins_attrib ins_alignment(1); // Required alignment attribute (must | |
3037 // be a power of 2) specifies the | |
3038 // alignment that some part of the | |
3039 // instruction (not necessarily the | |
3040 // start) requires. If > 1, a | |
3041 // compute_padding() function must be | |
3042 // provided for the instruction | |
3043 | |
3044 //----------OPERANDS----------------------------------------------------------- | |
3045 // Operand definitions must precede instruction definitions for correct parsing | |
3046 // in the ADLC because operands constitute user defined types which are used in | |
3047 // instruction definitions. | |
3048 | |
3049 //----------Simple Operands---------------------------------------------------- | |
3050 // Immediate Operands | |
3051 // Integer Immediate | |
3052 operand immI() | |
3053 %{ | |
3054 match(ConI); | |
3055 | |
3056 op_cost(10); | |
3057 format %{ %} | |
3058 interface(CONST_INTER); | |
3059 %} | |
3060 | |
3061 // Constant for test vs zero | |
3062 operand immI0() | |
3063 %{ | |
3064 predicate(n->get_int() == 0); | |
3065 match(ConI); | |
3066 | |
3067 op_cost(0); | |
3068 format %{ %} | |
3069 interface(CONST_INTER); | |
3070 %} | |
3071 | |
3072 // Constant for increment | |
3073 operand immI1() | |
3074 %{ | |
3075 predicate(n->get_int() == 1); | |
3076 match(ConI); | |
3077 | |
3078 op_cost(0); | |
3079 format %{ %} | |
3080 interface(CONST_INTER); | |
3081 %} | |
3082 | |
3083 // Constant for decrement | |
3084 operand immI_M1() | |
3085 %{ | |
3086 predicate(n->get_int() == -1); | |
3087 match(ConI); | |
3088 | |
3089 op_cost(0); | |
3090 format %{ %} | |
3091 interface(CONST_INTER); | |
3092 %} | |
3093 | |
3094 // Valid scale values for addressing modes | |
3095 operand immI2() | |
3096 %{ | |
3097 predicate(0 <= n->get_int() && (n->get_int() <= 3)); | |
3098 match(ConI); | |
3099 | |
3100 format %{ %} | |
3101 interface(CONST_INTER); | |
3102 %} | |
3103 | |
3104 operand immI8() | |
3105 %{ | |
3106 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); | |
3107 match(ConI); | |
3108 | |
3109 op_cost(5); | |
3110 format %{ %} | |
3111 interface(CONST_INTER); | |
3112 %} | |
3113 | |
3114 operand immI16() | |
3115 %{ | |
3116 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); | |
3117 match(ConI); | |
3118 | |
3119 op_cost(10); | |
3120 format %{ %} | |
3121 interface(CONST_INTER); | |
3122 %} | |
3123 | |
3124 // Constant for long shifts | |
3125 operand immI_32() | |
3126 %{ | |
3127 predicate( n->get_int() == 32 ); | |
3128 match(ConI); | |
3129 | |
3130 op_cost(0); | |
3131 format %{ %} | |
3132 interface(CONST_INTER); | |
3133 %} | |
3134 | |
3135 // Constant for long shifts | |
3136 operand immI_64() | |
3137 %{ | |
3138 predicate( n->get_int() == 64 ); | |
3139 match(ConI); | |
3140 | |
3141 op_cost(0); | |
3142 format %{ %} | |
3143 interface(CONST_INTER); | |
3144 %} | |
3145 | |
3146 // Pointer Immediate | |
3147 operand immP() | |
3148 %{ | |
3149 match(ConP); | |
3150 | |
3151 op_cost(10); | |
3152 format %{ %} | |
3153 interface(CONST_INTER); | |
3154 %} | |
3155 | |
3156 // NULL Pointer Immediate | |
3157 operand immP0() | |
3158 %{ | |
3159 predicate(n->get_ptr() == 0); | |
3160 match(ConP); | |
3161 | |
3162 op_cost(5); | |
3163 format %{ %} | |
3164 interface(CONST_INTER); | |
3165 %} | |
3166 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3167 // Pointer Immediate |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3168 operand immN() %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3169 match(ConN); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3170 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3171 op_cost(10); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3172 format %{ %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3173 interface(CONST_INTER); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3174 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3175 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3176 // NULL Pointer Immediate |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3177 operand immN0() %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3178 predicate(n->get_narrowcon() == 0); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3179 match(ConN); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3180 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3181 op_cost(5); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3182 format %{ %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3183 interface(CONST_INTER); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3184 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3185 |
0 | 3186 operand immP31() |
3187 %{ | |
3188 predicate(!n->as_Type()->type()->isa_oopptr() | |
3189 && (n->get_ptr() >> 31) == 0); | |
3190 match(ConP); | |
3191 | |
3192 op_cost(5); | |
3193 format %{ %} | |
3194 interface(CONST_INTER); | |
3195 %} | |
3196 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3197 |
0 | 3198 // Long Immediate |
3199 operand immL() | |
3200 %{ | |
3201 match(ConL); | |
3202 | |
3203 op_cost(20); | |
3204 format %{ %} | |
3205 interface(CONST_INTER); | |
3206 %} | |
3207 | |
3208 // Long Immediate 8-bit | |
3209 operand immL8() | |
3210 %{ | |
3211 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); | |
3212 match(ConL); | |
3213 | |
3214 op_cost(5); | |
3215 format %{ %} | |
3216 interface(CONST_INTER); | |
3217 %} | |
3218 | |
3219 // Long Immediate 32-bit unsigned | |
3220 operand immUL32() | |
3221 %{ | |
3222 predicate(n->get_long() == (unsigned int) (n->get_long())); | |
3223 match(ConL); | |
3224 | |
3225 op_cost(10); | |
3226 format %{ %} | |
3227 interface(CONST_INTER); | |
3228 %} | |
3229 | |
3230 // Long Immediate 32-bit signed | |
3231 operand immL32() | |
3232 %{ | |
3233 predicate(n->get_long() == (int) (n->get_long())); | |
3234 match(ConL); | |
3235 | |
3236 op_cost(15); | |
3237 format %{ %} | |
3238 interface(CONST_INTER); | |
3239 %} | |
3240 | |
3241 // Long Immediate zero | |
3242 operand immL0() | |
3243 %{ | |
3244 predicate(n->get_long() == 0L); | |
3245 match(ConL); | |
3246 | |
3247 op_cost(10); | |
3248 format %{ %} | |
3249 interface(CONST_INTER); | |
3250 %} | |
3251 | |
3252 // Constant for increment | |
3253 operand immL1() | |
3254 %{ | |
3255 predicate(n->get_long() == 1); | |
3256 match(ConL); | |
3257 | |
3258 format %{ %} | |
3259 interface(CONST_INTER); | |
3260 %} | |
3261 | |
3262 // Constant for decrement | |
3263 operand immL_M1() | |
3264 %{ | |
3265 predicate(n->get_long() == -1); | |
3266 match(ConL); | |
3267 | |
3268 format %{ %} | |
3269 interface(CONST_INTER); | |
3270 %} | |
3271 | |
3272 // Long Immediate: the value 10 | |
3273 operand immL10() | |
3274 %{ | |
3275 predicate(n->get_long() == 10); | |
3276 match(ConL); | |
3277 | |
3278 format %{ %} | |
3279 interface(CONST_INTER); | |
3280 %} | |
3281 | |
3282 // Long immediate from 0 to 127. | |
3283 // Used for a shorter form of long mul by 10. | |
3284 operand immL_127() | |
3285 %{ | |
3286 predicate(0 <= n->get_long() && n->get_long() < 0x80); | |
3287 match(ConL); | |
3288 | |
3289 op_cost(10); | |
3290 format %{ %} | |
3291 interface(CONST_INTER); | |
3292 %} | |
3293 | |
3294 // Long Immediate: low 32-bit mask | |
3295 operand immL_32bits() | |
3296 %{ | |
3297 predicate(n->get_long() == 0xFFFFFFFFL); | |
3298 match(ConL); | |
3299 op_cost(20); | |
3300 | |
3301 format %{ %} | |
3302 interface(CONST_INTER); | |
3303 %} | |
3304 | |
3305 // Float Immediate zero | |
3306 operand immF0() | |
3307 %{ | |
3308 predicate(jint_cast(n->getf()) == 0); | |
3309 match(ConF); | |
3310 | |
3311 op_cost(5); | |
3312 format %{ %} | |
3313 interface(CONST_INTER); | |
3314 %} | |
3315 | |
3316 // Float Immediate | |
3317 operand immF() | |
3318 %{ | |
3319 match(ConF); | |
3320 | |
3321 op_cost(15); | |
3322 format %{ %} | |
3323 interface(CONST_INTER); | |
3324 %} | |
3325 | |
3326 // Double Immediate zero | |
3327 operand immD0() | |
3328 %{ | |
3329 predicate(jlong_cast(n->getd()) == 0); | |
3330 match(ConD); | |
3331 | |
3332 op_cost(5); | |
3333 format %{ %} | |
3334 interface(CONST_INTER); | |
3335 %} | |
3336 | |
3337 // Double Immediate | |
3338 operand immD() | |
3339 %{ | |
3340 match(ConD); | |
3341 | |
3342 op_cost(15); | |
3343 format %{ %} | |
3344 interface(CONST_INTER); | |
3345 %} | |
3346 | |
3347 // Immediates for special shifts (sign extend) | |
3348 | |
3349 // Constants for increment | |
3350 operand immI_16() | |
3351 %{ | |
3352 predicate(n->get_int() == 16); | |
3353 match(ConI); | |
3354 | |
3355 format %{ %} | |
3356 interface(CONST_INTER); | |
3357 %} | |
3358 | |
3359 operand immI_24() | |
3360 %{ | |
3361 predicate(n->get_int() == 24); | |
3362 match(ConI); | |
3363 | |
3364 format %{ %} | |
3365 interface(CONST_INTER); | |
3366 %} | |
3367 | |
3368 // Constant for byte-wide masking | |
3369 operand immI_255() | |
3370 %{ | |
3371 predicate(n->get_int() == 255); | |
3372 match(ConI); | |
3373 | |
3374 format %{ %} | |
3375 interface(CONST_INTER); | |
3376 %} | |
3377 | |
3378 // Constant for short-wide masking | |
3379 operand immI_65535() | |
3380 %{ | |
3381 predicate(n->get_int() == 65535); | |
3382 match(ConI); | |
3383 | |
3384 format %{ %} | |
3385 interface(CONST_INTER); | |
3386 %} | |
3387 | |
3388 // Constant for byte-wide masking | |
3389 operand immL_255() | |
3390 %{ | |
3391 predicate(n->get_long() == 255); | |
3392 match(ConL); | |
3393 | |
3394 format %{ %} | |
3395 interface(CONST_INTER); | |
3396 %} | |
3397 | |
3398 // Constant for short-wide masking | |
3399 operand immL_65535() | |
3400 %{ | |
3401 predicate(n->get_long() == 65535); | |
3402 match(ConL); | |
3403 | |
3404 format %{ %} | |
3405 interface(CONST_INTER); | |
3406 %} | |
3407 | |
3408 // Register Operands | |
3409 // Integer Register | |
3410 operand rRegI() | |
3411 %{ | |
3412 constraint(ALLOC_IN_RC(int_reg)); | |
3413 match(RegI); | |
3414 | |
3415 match(rax_RegI); | |
3416 match(rbx_RegI); | |
3417 match(rcx_RegI); | |
3418 match(rdx_RegI); | |
3419 match(rdi_RegI); | |
3420 | |
3421 format %{ %} | |
3422 interface(REG_INTER); | |
3423 %} | |
3424 | |
3425 // Special Registers | |
3426 operand rax_RegI() | |
3427 %{ | |
3428 constraint(ALLOC_IN_RC(int_rax_reg)); | |
3429 match(RegI); | |
3430 match(rRegI); | |
3431 | |
3432 format %{ "RAX" %} | |
3433 interface(REG_INTER); | |
3434 %} | |
3435 | |
3436 // Special Registers | |
3437 operand rbx_RegI() | |
3438 %{ | |
3439 constraint(ALLOC_IN_RC(int_rbx_reg)); | |
3440 match(RegI); | |
3441 match(rRegI); | |
3442 | |
3443 format %{ "RBX" %} | |
3444 interface(REG_INTER); | |
3445 %} | |
3446 | |
3447 operand rcx_RegI() | |
3448 %{ | |
3449 constraint(ALLOC_IN_RC(int_rcx_reg)); | |
3450 match(RegI); | |
3451 match(rRegI); | |
3452 | |
3453 format %{ "RCX" %} | |
3454 interface(REG_INTER); | |
3455 %} | |
3456 | |
3457 operand rdx_RegI() | |
3458 %{ | |
3459 constraint(ALLOC_IN_RC(int_rdx_reg)); | |
3460 match(RegI); | |
3461 match(rRegI); | |
3462 | |
3463 format %{ "RDX" %} | |
3464 interface(REG_INTER); | |
3465 %} | |
3466 | |
3467 operand rdi_RegI() | |
3468 %{ | |
3469 constraint(ALLOC_IN_RC(int_rdi_reg)); | |
3470 match(RegI); | |
3471 match(rRegI); | |
3472 | |
3473 format %{ "RDI" %} | |
3474 interface(REG_INTER); | |
3475 %} | |
3476 | |
3477 operand no_rcx_RegI() | |
3478 %{ | |
3479 constraint(ALLOC_IN_RC(int_no_rcx_reg)); | |
3480 match(RegI); | |
3481 match(rax_RegI); | |
3482 match(rbx_RegI); | |
3483 match(rdx_RegI); | |
3484 match(rdi_RegI); | |
3485 | |
3486 format %{ %} | |
3487 interface(REG_INTER); | |
3488 %} | |
3489 | |
3490 operand no_rax_rdx_RegI() | |
3491 %{ | |
3492 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); | |
3493 match(RegI); | |
3494 match(rbx_RegI); | |
3495 match(rcx_RegI); | |
3496 match(rdi_RegI); | |
3497 | |
3498 format %{ %} | |
3499 interface(REG_INTER); | |
3500 %} | |
3501 | |
3502 // Pointer Register | |
3503 operand any_RegP() | |
3504 %{ | |
3505 constraint(ALLOC_IN_RC(any_reg)); | |
3506 match(RegP); | |
3507 match(rax_RegP); | |
3508 match(rbx_RegP); | |
3509 match(rdi_RegP); | |
3510 match(rsi_RegP); | |
3511 match(rbp_RegP); | |
3512 match(r15_RegP); | |
3513 match(rRegP); | |
3514 | |
3515 format %{ %} | |
3516 interface(REG_INTER); | |
3517 %} | |
3518 | |
3519 operand rRegP() | |
3520 %{ | |
3521 constraint(ALLOC_IN_RC(ptr_reg)); | |
3522 match(RegP); | |
3523 match(rax_RegP); | |
3524 match(rbx_RegP); | |
3525 match(rdi_RegP); | |
3526 match(rsi_RegP); | |
3527 match(rbp_RegP); | |
3528 match(r15_RegP); // See Q&A below about r15_RegP. | |
3529 | |
3530 format %{ %} | |
3531 interface(REG_INTER); | |
3532 %} | |
3533 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3534 operand rRegN() %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3535 constraint(ALLOC_IN_RC(int_reg)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3536 match(RegN); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3537 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3538 format %{ %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3539 interface(REG_INTER); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3540 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3541 |
0 | 3542 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? |
3543 // Answer: Operand match rules govern the DFA as it processes instruction inputs. | |
3544 // It's fine for an instruction input which expects rRegP to match a r15_RegP. | |
3545 // The output of an instruction is controlled by the allocator, which respects | |
3546 // register class masks, not match rules. Unless an instruction mentions | |
3547 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered | |
3548 // by the allocator as an input. | |
3549 | |
3550 operand no_rax_RegP() | |
3551 %{ | |
3552 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); | |
3553 match(RegP); | |
3554 match(rbx_RegP); | |
3555 match(rsi_RegP); | |
3556 match(rdi_RegP); | |
3557 | |
3558 format %{ %} | |
3559 interface(REG_INTER); | |
3560 %} | |
3561 | |
3562 operand no_rbp_RegP() | |
3563 %{ | |
3564 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); | |
3565 match(RegP); | |
3566 match(rbx_RegP); | |
3567 match(rsi_RegP); | |
3568 match(rdi_RegP); | |
3569 | |
3570 format %{ %} | |
3571 interface(REG_INTER); | |
3572 %} | |
3573 | |
3574 operand no_rax_rbx_RegP() | |
3575 %{ | |
3576 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); | |
3577 match(RegP); | |
3578 match(rsi_RegP); | |
3579 match(rdi_RegP); | |
3580 | |
3581 format %{ %} | |
3582 interface(REG_INTER); | |
3583 %} | |
3584 | |
3585 // Special Registers | |
3586 // Return a pointer value | |
3587 operand rax_RegP() | |
3588 %{ | |
3589 constraint(ALLOC_IN_RC(ptr_rax_reg)); | |
3590 match(RegP); | |
3591 match(rRegP); | |
3592 | |
3593 format %{ %} | |
3594 interface(REG_INTER); | |
3595 %} | |
3596 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3597 // Special Registers |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3598 // Return a compressed pointer value |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3599 operand rax_RegN() |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3600 %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3601 constraint(ALLOC_IN_RC(int_rax_reg)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3602 match(RegN); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3603 match(rRegN); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3604 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3605 format %{ %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3606 interface(REG_INTER); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3607 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
3608 |
0 | 3609 // Used in AtomicAdd |
3610 operand rbx_RegP() | |
3611 %{ | |
3612 constraint(ALLOC_IN_RC(ptr_rbx_reg)); | |
3613 match(RegP); | |
3614 match(rRegP); | |
3615 | |
3616 format %{ %} | |
3617 interface(REG_INTER); | |
3618 %} | |
3619 | |
3620 operand rsi_RegP() | |
3621 %{ | |
3622 constraint(ALLOC_IN_RC(ptr_rsi_reg)); | |
3623 match(RegP); | |
3624 match(rRegP); | |
3625 | |
3626 format %{ %} | |
3627 interface(REG_INTER); | |
3628 %} | |
3629 | |
3630 // Used in rep stosq | |
3631 operand rdi_RegP() | |
3632 %{ | |
3633 constraint(ALLOC_IN_RC(ptr_rdi_reg)); | |
3634 match(RegP); | |
3635 match(rRegP); | |
3636 | |
3637 format %{ %} | |
3638 interface(REG_INTER); | |
3639 %} | |
3640 | |
3641 operand rbp_RegP() | |
3642 %{ | |
3643 constraint(ALLOC_IN_RC(ptr_rbp_reg)); | |
3644 match(RegP); | |
3645 match(rRegP); | |
3646 | |
3647 format %{ %} | |
3648 interface(REG_INTER); | |
3649 %} | |
3650 | |
3651 operand r15_RegP() | |
3652 %{ | |
3653 constraint(ALLOC_IN_RC(ptr_r15_reg)); | |
3654 match(RegP); | |
3655 match(rRegP); | |
3656 | |
3657 format %{ %} | |
3658 interface(REG_INTER); | |
3659 %} | |
3660 | |
3661 operand rRegL() | |
3662 %{ | |
3663 constraint(ALLOC_IN_RC(long_reg)); | |
3664 match(RegL); | |
3665 match(rax_RegL); | |
3666 match(rdx_RegL); | |
3667 | |
3668 format %{ %} | |
3669 interface(REG_INTER); | |
3670 %} | |
3671 | |
3672 // Special Registers | |
3673 operand no_rax_rdx_RegL() | |
3674 %{ | |
3675 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); | |
3676 match(RegL); | |
3677 match(rRegL); | |
3678 | |
3679 format %{ %} | |
3680 interface(REG_INTER); | |
3681 %} | |
3682 | |
3683 operand no_rax_RegL() | |
3684 %{ | |
3685 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); | |
3686 match(RegL); | |
3687 match(rRegL); | |
3688 match(rdx_RegL); | |
3689 | |
3690 format %{ %} | |
3691 interface(REG_INTER); | |
3692 %} | |
3693 | |
3694 operand no_rcx_RegL() | |
3695 %{ | |
3696 constraint(ALLOC_IN_RC(long_no_rcx_reg)); | |
3697 match(RegL); | |
3698 match(rRegL); | |
3699 | |
3700 format %{ %} | |
3701 interface(REG_INTER); | |
3702 %} | |
3703 | |
3704 operand rax_RegL() | |
3705 %{ | |
3706 constraint(ALLOC_IN_RC(long_rax_reg)); | |
3707 match(RegL); | |
3708 match(rRegL); | |
3709 | |
3710 format %{ "RAX" %} | |
3711 interface(REG_INTER); | |
3712 %} | |
3713 | |
3714 operand rcx_RegL() | |
3715 %{ | |
3716 constraint(ALLOC_IN_RC(long_rcx_reg)); | |
3717 match(RegL); | |
3718 match(rRegL); | |
3719 | |
3720 format %{ %} | |
3721 interface(REG_INTER); | |
3722 %} | |
3723 | |
3724 operand rdx_RegL() | |
3725 %{ | |
3726 constraint(ALLOC_IN_RC(long_rdx_reg)); | |
3727 match(RegL); | |
3728 match(rRegL); | |
3729 | |
3730 format %{ %} | |
3731 interface(REG_INTER); | |
3732 %} | |
3733 | |
3734 // Flags register, used as output of compare instructions | |
3735 operand rFlagsReg() | |
3736 %{ | |
3737 constraint(ALLOC_IN_RC(int_flags)); | |
3738 match(RegFlags); | |
3739 | |
3740 format %{ "RFLAGS" %} | |
3741 interface(REG_INTER); | |
3742 %} | |
3743 | |
3744 // Flags register, used as output of FLOATING POINT compare instructions | |
3745 operand rFlagsRegU() | |
3746 %{ | |
3747 constraint(ALLOC_IN_RC(int_flags)); | |
3748 match(RegFlags); | |
3749 | |
3750 format %{ "RFLAGS_U" %} | |
3751 interface(REG_INTER); | |
3752 %} | |
3753 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
3754 operand rFlagsRegUCF() %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
3755 constraint(ALLOC_IN_RC(int_flags)); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
3756 match(RegFlags); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
3757 predicate(false); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
3758 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
3759 format %{ "RFLAGS_U_CF" %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
3760 interface(REG_INTER); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
3761 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
3762 |
0 | 3763 // Float register operands |
3764 operand regF() | |
3765 %{ | |
3766 constraint(ALLOC_IN_RC(float_reg)); | |
3767 match(RegF); | |
3768 | |
3769 format %{ %} | |
3770 interface(REG_INTER); | |
3771 %} | |
3772 | |
3773 // Double register operands | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
3774 operand regD() |
0 | 3775 %{ |
3776 constraint(ALLOC_IN_RC(double_reg)); | |
3777 match(RegD); | |
3778 | |
3779 format %{ %} | |
3780 interface(REG_INTER); | |
3781 %} | |
3782 | |
3783 //----------Memory Operands---------------------------------------------------- | |
3784 // Direct Memory Operand | |
3785 // operand direct(immP addr) | |
3786 // %{ | |
3787 // match(addr); | |
3788 | |
3789 // format %{ "[$addr]" %} | |
3790 // interface(MEMORY_INTER) %{ | |
3791 // base(0xFFFFFFFF); | |
3792 // index(0x4); | |
3793 // scale(0x0); | |
3794 // disp($addr); | |
3795 // %} | |
3796 // %} | |
3797 | |
3798 // Indirect Memory Operand | |
3799 operand indirect(any_RegP reg) | |
3800 %{ | |
3801 constraint(ALLOC_IN_RC(ptr_reg)); | |
3802 match(reg); | |
3803 | |
3804 format %{ "[$reg]" %} | |
3805 interface(MEMORY_INTER) %{ | |
3806 base($reg); | |
3807 index(0x4); | |
3808 scale(0x0); | |
3809 disp(0x0); | |
3810 %} | |
3811 %} | |
3812 | |
3813 // Indirect Memory Plus Short Offset Operand | |
3814 operand indOffset8(any_RegP reg, immL8 off) | |
3815 %{ | |
3816 constraint(ALLOC_IN_RC(ptr_reg)); | |
3817 match(AddP reg off); | |
3818 | |
3819 format %{ "[$reg + $off (8-bit)]" %} | |
3820 interface(MEMORY_INTER) %{ | |
3821 base($reg); | |
3822 index(0x4); | |
3823 scale(0x0); | |
3824 disp($off); | |
3825 %} | |
3826 %} | |
3827 | |
3828 // Indirect Memory Plus Long Offset Operand | |
3829 operand indOffset32(any_RegP reg, immL32 off) | |
3830 %{ | |
3831 constraint(ALLOC_IN_RC(ptr_reg)); | |
3832 match(AddP reg off); | |
3833 | |
3834 format %{ "[$reg + $off (32-bit)]" %} | |
3835 interface(MEMORY_INTER) %{ | |
3836 base($reg); | |
3837 index(0x4); | |
3838 scale(0x0); | |
3839 disp($off); | |
3840 %} | |
3841 %} | |
3842 | |
3843 // Indirect Memory Plus Index Register Plus Offset Operand | |
3844 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) | |
3845 %{ | |
3846 constraint(ALLOC_IN_RC(ptr_reg)); | |
3847 match(AddP (AddP reg lreg) off); | |
3848 | |
3849 op_cost(10); | |
3850 format %{"[$reg + $off + $lreg]" %} | |
3851 interface(MEMORY_INTER) %{ | |
3852 base($reg); | |
3853 index($lreg); | |
3854 scale(0x0); | |
3855 disp($off); | |
3856 %} | |
3857 %} | |
3858 | |
3859 // Indirect Memory Plus Index Register Plus Offset Operand | |
3860 operand indIndex(any_RegP reg, rRegL lreg) | |
3861 %{ | |
3862 constraint(ALLOC_IN_RC(ptr_reg)); | |
3863 match(AddP reg lreg); | |
3864 | |
3865 op_cost(10); | |
3866 format %{"[$reg + $lreg]" %} | |
3867 interface(MEMORY_INTER) %{ | |
3868 base($reg); | |
3869 index($lreg); | |
3870 scale(0x0); | |
3871 disp(0x0); | |
3872 %} | |
3873 %} | |
3874 | |
3875 // Indirect Memory Times Scale Plus Index Register | |
3876 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) | |
3877 %{ | |
3878 constraint(ALLOC_IN_RC(ptr_reg)); | |
3879 match(AddP reg (LShiftL lreg scale)); | |
3880 | |
3881 op_cost(10); | |
3882 format %{"[$reg + $lreg << $scale]" %} | |
3883 interface(MEMORY_INTER) %{ | |
3884 base($reg); | |
3885 index($lreg); | |
3886 scale($scale); | |
3887 disp(0x0); | |
3888 %} | |
3889 %} | |
3890 | |
3891 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand | |
3892 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) | |
3893 %{ | |
3894 constraint(ALLOC_IN_RC(ptr_reg)); | |
3895 match(AddP (AddP reg (LShiftL lreg scale)) off); | |
3896 | |
3897 op_cost(10); | |
3898 format %{"[$reg + $off + $lreg << $scale]" %} | |
3899 interface(MEMORY_INTER) %{ | |
3900 base($reg); | |
3901 index($lreg); | |
3902 scale($scale); | |
3903 disp($off); | |
3904 %} | |
3905 %} | |
3906 | |
3907 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand | |
3908 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) | |
3909 %{ | |
3910 constraint(ALLOC_IN_RC(ptr_reg)); | |
3911 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); | |
3912 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); | |
3913 | |
3914 op_cost(10); | |
3915 format %{"[$reg + $off + $idx << $scale]" %} | |
3916 interface(MEMORY_INTER) %{ | |
3917 base($reg); | |
3918 index($idx); | |
3919 scale($scale); | |
3920 disp($off); | |
3921 %} | |
3922 %} | |
3923 | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3924 // Indirect Narrow Oop Plus Offset Operand |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3925 // Note: x86 architecture doesn't support "scale * index + offset" without a base |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3926 // we can't free r12 even with Universe::narrow_oop_base() == NULL. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3927 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
3928 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3929 constraint(ALLOC_IN_RC(ptr_reg)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3930 match(AddP (DecodeN reg) off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3931 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3932 op_cost(10); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3933 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3934 interface(MEMORY_INTER) %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3935 base(0xc); // R12 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3936 index($reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3937 scale(0x3); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3938 disp($off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3939 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3940 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3941 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3942 // Indirect Memory Operand |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3943 operand indirectNarrow(rRegN reg) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3944 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3945 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3946 constraint(ALLOC_IN_RC(ptr_reg)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3947 match(DecodeN reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3948 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3949 format %{ "[$reg]" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3950 interface(MEMORY_INTER) %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3951 base($reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3952 index(0x4); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3953 scale(0x0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3954 disp(0x0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3955 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3956 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3957 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3958 // Indirect Memory Plus Short Offset Operand |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3959 operand indOffset8Narrow(rRegN reg, immL8 off) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3960 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3961 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3962 constraint(ALLOC_IN_RC(ptr_reg)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3963 match(AddP (DecodeN reg) off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3964 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3965 format %{ "[$reg + $off (8-bit)]" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3966 interface(MEMORY_INTER) %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3967 base($reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3968 index(0x4); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3969 scale(0x0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3970 disp($off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3971 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3972 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3973 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3974 // Indirect Memory Plus Long Offset Operand |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3975 operand indOffset32Narrow(rRegN reg, immL32 off) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3976 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3977 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3978 constraint(ALLOC_IN_RC(ptr_reg)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3979 match(AddP (DecodeN reg) off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3980 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3981 format %{ "[$reg + $off (32-bit)]" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3982 interface(MEMORY_INTER) %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3983 base($reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3984 index(0x4); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3985 scale(0x0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3986 disp($off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3987 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3988 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3989 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3990 // Indirect Memory Plus Index Register Plus Offset Operand |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3991 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3992 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3993 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3994 constraint(ALLOC_IN_RC(ptr_reg)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3995 match(AddP (AddP (DecodeN reg) lreg) off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3996 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3997 op_cost(10); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3998 format %{"[$reg + $off + $lreg]" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
3999 interface(MEMORY_INTER) %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4000 base($reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4001 index($lreg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4002 scale(0x0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4003 disp($off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4004 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4005 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4006 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4007 // Indirect Memory Plus Index Register Plus Offset Operand |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4008 operand indIndexNarrow(rRegN reg, rRegL lreg) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4009 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4010 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4011 constraint(ALLOC_IN_RC(ptr_reg)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4012 match(AddP (DecodeN reg) lreg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4013 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4014 op_cost(10); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4015 format %{"[$reg + $lreg]" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4016 interface(MEMORY_INTER) %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4017 base($reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4018 index($lreg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4019 scale(0x0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4020 disp(0x0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4021 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4022 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4023 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4024 // Indirect Memory Times Scale Plus Index Register |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4025 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4026 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4027 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4028 constraint(ALLOC_IN_RC(ptr_reg)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4029 match(AddP (DecodeN reg) (LShiftL lreg scale)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4030 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4031 op_cost(10); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4032 format %{"[$reg + $lreg << $scale]" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4033 interface(MEMORY_INTER) %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4034 base($reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4035 index($lreg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4036 scale($scale); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4037 disp(0x0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4038 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4039 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4040 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4041 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4042 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4043 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4044 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4045 constraint(ALLOC_IN_RC(ptr_reg)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4046 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4047 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4048 op_cost(10); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4049 format %{"[$reg + $off + $lreg << $scale]" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4050 interface(MEMORY_INTER) %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4051 base($reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4052 index($lreg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4053 scale($scale); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4054 disp($off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4055 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4056 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4057 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4058 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4059 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4060 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4061 constraint(ALLOC_IN_RC(ptr_reg)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4062 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4063 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4064 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4065 op_cost(10); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4066 format %{"[$reg + $off + $idx << $scale]" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4067 interface(MEMORY_INTER) %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4068 base($reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4069 index($idx); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4070 scale($scale); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4071 disp($off); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4072 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4073 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4074 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4075 |
0 | 4076 //----------Special Memory Operands-------------------------------------------- |
4077 // Stack Slot Operand - This operand is used for loading and storing temporary | |
4078 // values on the stack where a match requires a value to | |
4079 // flow through memory. | |
4080 operand stackSlotP(sRegP reg) | |
4081 %{ | |
4082 constraint(ALLOC_IN_RC(stack_slots)); | |
4083 // No match rule because this operand is only generated in matching | |
4084 | |
4085 format %{ "[$reg]" %} | |
4086 interface(MEMORY_INTER) %{ | |
4087 base(0x4); // RSP | |
4088 index(0x4); // No Index | |
4089 scale(0x0); // No Scale | |
4090 disp($reg); // Stack Offset | |
4091 %} | |
4092 %} | |
4093 | |
4094 operand stackSlotI(sRegI reg) | |
4095 %{ | |
4096 constraint(ALLOC_IN_RC(stack_slots)); | |
4097 // No match rule because this operand is only generated in matching | |
4098 | |
4099 format %{ "[$reg]" %} | |
4100 interface(MEMORY_INTER) %{ | |
4101 base(0x4); // RSP | |
4102 index(0x4); // No Index | |
4103 scale(0x0); // No Scale | |
4104 disp($reg); // Stack Offset | |
4105 %} | |
4106 %} | |
4107 | |
4108 operand stackSlotF(sRegF reg) | |
4109 %{ | |
4110 constraint(ALLOC_IN_RC(stack_slots)); | |
4111 // No match rule because this operand is only generated in matching | |
4112 | |
4113 format %{ "[$reg]" %} | |
4114 interface(MEMORY_INTER) %{ | |
4115 base(0x4); // RSP | |
4116 index(0x4); // No Index | |
4117 scale(0x0); // No Scale | |
4118 disp($reg); // Stack Offset | |
4119 %} | |
4120 %} | |
4121 | |
4122 operand stackSlotD(sRegD reg) | |
4123 %{ | |
4124 constraint(ALLOC_IN_RC(stack_slots)); | |
4125 // No match rule because this operand is only generated in matching | |
4126 | |
4127 format %{ "[$reg]" %} | |
4128 interface(MEMORY_INTER) %{ | |
4129 base(0x4); // RSP | |
4130 index(0x4); // No Index | |
4131 scale(0x0); // No Scale | |
4132 disp($reg); // Stack Offset | |
4133 %} | |
4134 %} | |
4135 operand stackSlotL(sRegL reg) | |
4136 %{ | |
4137 constraint(ALLOC_IN_RC(stack_slots)); | |
4138 // No match rule because this operand is only generated in matching | |
4139 | |
4140 format %{ "[$reg]" %} | |
4141 interface(MEMORY_INTER) %{ | |
4142 base(0x4); // RSP | |
4143 index(0x4); // No Index | |
4144 scale(0x0); // No Scale | |
4145 disp($reg); // Stack Offset | |
4146 %} | |
4147 %} | |
4148 | |
4149 //----------Conditional Branch Operands---------------------------------------- | |
4150 // Comparison Op - This is the operation of the comparison, and is limited to | |
4151 // the following set of codes: | |
4152 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) | |
4153 // | |
4154 // Other attributes of the comparison, such as unsignedness, are specified | |
4155 // by the comparison instruction that sets a condition code flags register. | |
4156 // That result is represented by a flags operand whose subtype is appropriate | |
4157 // to the unsignedness (etc.) of the comparison. | |
4158 // | |
4159 // Later, the instruction which matches both the Comparison Op (a Bool) and | |
4160 // the flags (produced by the Cmp) specifies the coding of the comparison op | |
4161 // by matching a specific subtype of Bool operand below, such as cmpOpU. | |
4162 | |
4163 // Comparision Code | |
4164 operand cmpOp() | |
4165 %{ | |
4166 match(Bool); | |
4167 | |
4168 format %{ "" %} | |
4169 interface(COND_INTER) %{ | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4170 equal(0x4, "e"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4171 not_equal(0x5, "ne"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4172 less(0xC, "l"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4173 greater_equal(0xD, "ge"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4174 less_equal(0xE, "le"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4175 greater(0xF, "g"); |
0 | 4176 %} |
4177 %} | |
4178 | |
4179 // Comparison Code, unsigned compare. Used by FP also, with | |
4180 // C2 (unordered) turned into GT or LT already. The other bits | |
4181 // C0 and C3 are turned into Carry & Zero flags. | |
4182 operand cmpOpU() | |
4183 %{ | |
4184 match(Bool); | |
4185 | |
4186 format %{ "" %} | |
4187 interface(COND_INTER) %{ | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4188 equal(0x4, "e"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4189 not_equal(0x5, "ne"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4190 less(0x2, "b"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4191 greater_equal(0x3, "nb"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4192 less_equal(0x6, "be"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4193 greater(0x7, "nbe"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4194 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4195 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4196 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4197 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4198 // Floating comparisons that don't require any fixup for the unordered case |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4199 operand cmpOpUCF() %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4200 match(Bool); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4201 predicate(n->as_Bool()->_test._test == BoolTest::lt || |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4202 n->as_Bool()->_test._test == BoolTest::ge || |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4203 n->as_Bool()->_test._test == BoolTest::le || |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4204 n->as_Bool()->_test._test == BoolTest::gt); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4205 format %{ "" %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4206 interface(COND_INTER) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4207 equal(0x4, "e"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4208 not_equal(0x5, "ne"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4209 less(0x2, "b"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4210 greater_equal(0x3, "nb"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4211 less_equal(0x6, "be"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4212 greater(0x7, "nbe"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4213 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4214 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4215 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4216 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4217 // Floating comparisons that can be fixed up with extra conditional jumps |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4218 operand cmpOpUCF2() %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4219 match(Bool); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4220 predicate(n->as_Bool()->_test._test == BoolTest::ne || |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4221 n->as_Bool()->_test._test == BoolTest::eq); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4222 format %{ "" %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4223 interface(COND_INTER) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4224 equal(0x4, "e"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4225 not_equal(0x5, "ne"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4226 less(0x2, "b"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4227 greater_equal(0x3, "nb"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4228 less_equal(0x6, "be"); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
4229 greater(0x7, "nbe"); |
0 | 4230 %} |
4231 %} | |
4232 | |
4233 | |
4234 //----------OPERAND CLASSES---------------------------------------------------- | |
4235 // Operand Classes are groups of operands that are used as to simplify | |
605 | 4236 // instruction definitions by not requiring the AD writer to specify separate |
0 | 4237 // instructions for every form of operand when the instruction accepts |
4238 // multiple operand types with the same basic encoding and format. The classic | |
4239 // case of this is memory operands. | |
4240 | |
4241 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
4242 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4243 indCompressedOopOffset, |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4244 indirectNarrow, indOffset8Narrow, indOffset32Narrow, |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4245 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
4246 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); |
0 | 4247 |
4248 //----------PIPELINE----------------------------------------------------------- | |
4249 // Rules which define the behavior of the target architectures pipeline. | |
4250 pipeline %{ | |
4251 | |
4252 //----------ATTRIBUTES--------------------------------------------------------- | |
4253 attributes %{ | |
4254 variable_size_instructions; // Fixed size instructions | |
4255 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle | |
4256 instruction_unit_size = 1; // An instruction is 1 bytes long | |
4257 instruction_fetch_unit_size = 16; // The processor fetches one line | |
4258 instruction_fetch_units = 1; // of 16 bytes | |
4259 | |
4260 // List of nop instructions | |
4261 nops( MachNop ); | |
4262 %} | |
4263 | |
4264 //----------RESOURCES---------------------------------------------------------- | |
4265 // Resources are the functional units available to the machine | |
4266 | |
4267 // Generic P2/P3 pipeline | |
4268 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of | |
4269 // 3 instructions decoded per cycle. | |
4270 // 2 load/store ops per cycle, 1 branch, 1 FPU, | |
4271 // 3 ALU op, only ALU0 handles mul instructions. | |
4272 resources( D0, D1, D2, DECODE = D0 | D1 | D2, | |
4273 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, | |
4274 BR, FPU, | |
4275 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); | |
4276 | |
4277 //----------PIPELINE DESCRIPTION----------------------------------------------- | |
4278 // Pipeline Description specifies the stages in the machine's pipeline | |
4279 | |
4280 // Generic P2/P3 pipeline | |
4281 pipe_desc(S0, S1, S2, S3, S4, S5); | |
4282 | |
4283 //----------PIPELINE CLASSES--------------------------------------------------- | |
4284 // Pipeline Classes describe the stages in which input and output are | |
4285 // referenced by the hardware pipeline. | |
4286 | |
4287 // Naming convention: ialu or fpu | |
4288 // Then: _reg | |
4289 // Then: _reg if there is a 2nd register | |
4290 // Then: _long if it's a pair of instructions implementing a long | |
4291 // Then: _fat if it requires the big decoder | |
4292 // Or: _mem if it requires the big decoder and a memory unit. | |
4293 | |
4294 // Integer ALU reg operation | |
4295 pipe_class ialu_reg(rRegI dst) | |
4296 %{ | |
4297 single_instruction; | |
4298 dst : S4(write); | |
4299 dst : S3(read); | |
4300 DECODE : S0; // any decoder | |
4301 ALU : S3; // any alu | |
4302 %} | |
4303 | |
4304 // Long ALU reg operation | |
4305 pipe_class ialu_reg_long(rRegL dst) | |
4306 %{ | |
4307 instruction_count(2); | |
4308 dst : S4(write); | |
4309 dst : S3(read); | |
4310 DECODE : S0(2); // any 2 decoders | |
4311 ALU : S3(2); // both alus | |
4312 %} | |
4313 | |
4314 // Integer ALU reg operation using big decoder | |
4315 pipe_class ialu_reg_fat(rRegI dst) | |
4316 %{ | |
4317 single_instruction; | |
4318 dst : S4(write); | |
4319 dst : S3(read); | |
4320 D0 : S0; // big decoder only | |
4321 ALU : S3; // any alu | |
4322 %} | |
4323 | |
4324 // Long ALU reg operation using big decoder | |
4325 pipe_class ialu_reg_long_fat(rRegL dst) | |
4326 %{ | |
4327 instruction_count(2); | |
4328 dst : S4(write); | |
4329 dst : S3(read); | |
4330 D0 : S0(2); // big decoder only; twice | |
4331 ALU : S3(2); // any 2 alus | |
4332 %} | |
4333 | |
4334 // Integer ALU reg-reg operation | |
4335 pipe_class ialu_reg_reg(rRegI dst, rRegI src) | |
4336 %{ | |
4337 single_instruction; | |
4338 dst : S4(write); | |
4339 src : S3(read); | |
4340 DECODE : S0; // any decoder | |
4341 ALU : S3; // any alu | |
4342 %} | |
4343 | |
4344 // Long ALU reg-reg operation | |
4345 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) | |
4346 %{ | |
4347 instruction_count(2); | |
4348 dst : S4(write); | |
4349 src : S3(read); | |
4350 DECODE : S0(2); // any 2 decoders | |
4351 ALU : S3(2); // both alus | |
4352 %} | |
4353 | |
4354 // Integer ALU reg-reg operation | |
4355 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) | |
4356 %{ | |
4357 single_instruction; | |
4358 dst : S4(write); | |
4359 src : S3(read); | |
4360 D0 : S0; // big decoder only | |
4361 ALU : S3; // any alu | |
4362 %} | |
4363 | |
4364 // Long ALU reg-reg operation | |
4365 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) | |
4366 %{ | |
4367 instruction_count(2); | |
4368 dst : S4(write); | |
4369 src : S3(read); | |
4370 D0 : S0(2); // big decoder only; twice | |
4371 ALU : S3(2); // both alus | |
4372 %} | |
4373 | |
4374 // Integer ALU reg-mem operation | |
4375 pipe_class ialu_reg_mem(rRegI dst, memory mem) | |
4376 %{ | |
4377 single_instruction; | |
4378 dst : S5(write); | |
4379 mem : S3(read); | |
4380 D0 : S0; // big decoder only | |
4381 ALU : S4; // any alu | |
4382 MEM : S3; // any mem | |
4383 %} | |
4384 | |
4385 // Integer mem operation (prefetch) | |
4386 pipe_class ialu_mem(memory mem) | |
4387 %{ | |
4388 single_instruction; | |
4389 mem : S3(read); | |
4390 D0 : S0; // big decoder only | |
4391 MEM : S3; // any mem | |
4392 %} | |
4393 | |
4394 // Integer Store to Memory | |
4395 pipe_class ialu_mem_reg(memory mem, rRegI src) | |
4396 %{ | |
4397 single_instruction; | |
4398 mem : S3(read); | |
4399 src : S5(read); | |
4400 D0 : S0; // big decoder only | |
4401 ALU : S4; // any alu | |
4402 MEM : S3; | |
4403 %} | |
4404 | |
4405 // // Long Store to Memory | |
4406 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) | |
4407 // %{ | |
4408 // instruction_count(2); | |
4409 // mem : S3(read); | |
4410 // src : S5(read); | |
4411 // D0 : S0(2); // big decoder only; twice | |
4412 // ALU : S4(2); // any 2 alus | |
4413 // MEM : S3(2); // Both mems | |
4414 // %} | |
4415 | |
4416 // Integer Store to Memory | |
4417 pipe_class ialu_mem_imm(memory mem) | |
4418 %{ | |
4419 single_instruction; | |
4420 mem : S3(read); | |
4421 D0 : S0; // big decoder only | |
4422 ALU : S4; // any alu | |
4423 MEM : S3; | |
4424 %} | |
4425 | |
4426 // Integer ALU0 reg-reg operation | |
4427 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) | |
4428 %{ | |
4429 single_instruction; | |
4430 dst : S4(write); | |
4431 src : S3(read); | |
4432 D0 : S0; // Big decoder only | |
4433 ALU0 : S3; // only alu0 | |
4434 %} | |
4435 | |
4436 // Integer ALU0 reg-mem operation | |
4437 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) | |
4438 %{ | |
4439 single_instruction; | |
4440 dst : S5(write); | |
4441 mem : S3(read); | |
4442 D0 : S0; // big decoder only | |
4443 ALU0 : S4; // ALU0 only | |
4444 MEM : S3; // any mem | |
4445 %} | |
4446 | |
4447 // Integer ALU reg-reg operation | |
4448 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) | |
4449 %{ | |
4450 single_instruction; | |
4451 cr : S4(write); | |
4452 src1 : S3(read); | |
4453 src2 : S3(read); | |
4454 DECODE : S0; // any decoder | |
4455 ALU : S3; // any alu | |
4456 %} | |
4457 | |
4458 // Integer ALU reg-imm operation | |
4459 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) | |
4460 %{ | |
4461 single_instruction; | |
4462 cr : S4(write); | |
4463 src1 : S3(read); | |
4464 DECODE : S0; // any decoder | |
4465 ALU : S3; // any alu | |
4466 %} | |
4467 | |
4468 // Integer ALU reg-mem operation | |
4469 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) | |
4470 %{ | |
4471 single_instruction; | |
4472 cr : S4(write); | |
4473 src1 : S3(read); | |
4474 src2 : S3(read); | |
4475 D0 : S0; // big decoder only | |
4476 ALU : S4; // any alu | |
4477 MEM : S3; | |
4478 %} | |
4479 | |
4480 // Conditional move reg-reg | |
4481 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) | |
4482 %{ | |
4483 instruction_count(4); | |
4484 y : S4(read); | |
4485 q : S3(read); | |
4486 p : S3(read); | |
4487 DECODE : S0(4); // any decoder | |
4488 %} | |
4489 | |
4490 // Conditional move reg-reg | |
4491 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) | |
4492 %{ | |
4493 single_instruction; | |
4494 dst : S4(write); | |
4495 src : S3(read); | |
4496 cr : S3(read); | |
4497 DECODE : S0; // any decoder | |
4498 %} | |
4499 | |
4500 // Conditional move reg-mem | |
4501 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) | |
4502 %{ | |
4503 single_instruction; | |
4504 dst : S4(write); | |
4505 src : S3(read); | |
4506 cr : S3(read); | |
4507 DECODE : S0; // any decoder | |
4508 MEM : S3; | |
4509 %} | |
4510 | |
4511 // Conditional move reg-reg long | |
4512 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) | |
4513 %{ | |
4514 single_instruction; | |
4515 dst : S4(write); | |
4516 src : S3(read); | |
4517 cr : S3(read); | |
4518 DECODE : S0(2); // any 2 decoders | |
4519 %} | |
4520 | |
4521 // XXX | |
4522 // // Conditional move double reg-reg | |
4523 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) | |
4524 // %{ | |
4525 // single_instruction; | |
4526 // dst : S4(write); | |
4527 // src : S3(read); | |
4528 // cr : S3(read); | |
4529 // DECODE : S0; // any decoder | |
4530 // %} | |
4531 | |
4532 // Float reg-reg operation | |
4533 pipe_class fpu_reg(regD dst) | |
4534 %{ | |
4535 instruction_count(2); | |
4536 dst : S3(read); | |
4537 DECODE : S0(2); // any 2 decoders | |
4538 FPU : S3; | |
4539 %} | |
4540 | |
4541 // Float reg-reg operation | |
4542 pipe_class fpu_reg_reg(regD dst, regD src) | |
4543 %{ | |
4544 instruction_count(2); | |
4545 dst : S4(write); | |
4546 src : S3(read); | |
4547 DECODE : S0(2); // any 2 decoders | |
4548 FPU : S3; | |
4549 %} | |
4550 | |
4551 // Float reg-reg operation | |
4552 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) | |
4553 %{ | |
4554 instruction_count(3); | |
4555 dst : S4(write); | |
4556 src1 : S3(read); | |
4557 src2 : S3(read); | |
4558 DECODE : S0(3); // any 3 decoders | |
4559 FPU : S3(2); | |
4560 %} | |
4561 | |
4562 // Float reg-reg operation | |
4563 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) | |
4564 %{ | |
4565 instruction_count(4); | |
4566 dst : S4(write); | |
4567 src1 : S3(read); | |
4568 src2 : S3(read); | |
4569 src3 : S3(read); | |
4570 DECODE : S0(4); // any 3 decoders | |
4571 FPU : S3(2); | |
4572 %} | |
4573 | |
4574 // Float reg-reg operation | |
4575 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) | |
4576 %{ | |
4577 instruction_count(4); | |
4578 dst : S4(write); | |
4579 src1 : S3(read); | |
4580 src2 : S3(read); | |
4581 src3 : S3(read); | |
4582 DECODE : S1(3); // any 3 decoders | |
4583 D0 : S0; // Big decoder only | |
4584 FPU : S3(2); | |
4585 MEM : S3; | |
4586 %} | |
4587 | |
4588 // Float reg-mem operation | |
4589 pipe_class fpu_reg_mem(regD dst, memory mem) | |
4590 %{ | |
4591 instruction_count(2); | |
4592 dst : S5(write); | |
4593 mem : S3(read); | |
4594 D0 : S0; // big decoder only | |
4595 DECODE : S1; // any decoder for FPU POP | |
4596 FPU : S4; | |
4597 MEM : S3; // any mem | |
4598 %} | |
4599 | |
4600 // Float reg-mem operation | |
4601 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) | |
4602 %{ | |
4603 instruction_count(3); | |
4604 dst : S5(write); | |
4605 src1 : S3(read); | |
4606 mem : S3(read); | |
4607 D0 : S0; // big decoder only | |
4608 DECODE : S1(2); // any decoder for FPU POP | |
4609 FPU : S4; | |
4610 MEM : S3; // any mem | |
4611 %} | |
4612 | |
4613 // Float mem-reg operation | |
4614 pipe_class fpu_mem_reg(memory mem, regD src) | |
4615 %{ | |
4616 instruction_count(2); | |
4617 src : S5(read); | |
4618 mem : S3(read); | |
4619 DECODE : S0; // any decoder for FPU PUSH | |
4620 D0 : S1; // big decoder only | |
4621 FPU : S4; | |
4622 MEM : S3; // any mem | |
4623 %} | |
4624 | |
4625 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) | |
4626 %{ | |
4627 instruction_count(3); | |
4628 src1 : S3(read); | |
4629 src2 : S3(read); | |
4630 mem : S3(read); | |
4631 DECODE : S0(2); // any decoder for FPU PUSH | |
4632 D0 : S1; // big decoder only | |
4633 FPU : S4; | |
4634 MEM : S3; // any mem | |
4635 %} | |
4636 | |
4637 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) | |
4638 %{ | |
4639 instruction_count(3); | |
4640 src1 : S3(read); | |
4641 src2 : S3(read); | |
4642 mem : S4(read); | |
4643 DECODE : S0; // any decoder for FPU PUSH | |
4644 D0 : S0(2); // big decoder only | |
4645 FPU : S4; | |
4646 MEM : S3(2); // any mem | |
4647 %} | |
4648 | |
4649 pipe_class fpu_mem_mem(memory dst, memory src1) | |
4650 %{ | |
4651 instruction_count(2); | |
4652 src1 : S3(read); | |
4653 dst : S4(read); | |
4654 D0 : S0(2); // big decoder only | |
4655 MEM : S3(2); // any mem | |
4656 %} | |
4657 | |
4658 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) | |
4659 %{ | |
4660 instruction_count(3); | |
4661 src1 : S3(read); | |
4662 src2 : S3(read); | |
4663 dst : S4(read); | |
4664 D0 : S0(3); // big decoder only | |
4665 FPU : S4; | |
4666 MEM : S3(3); // any mem | |
4667 %} | |
4668 | |
4669 pipe_class fpu_mem_reg_con(memory mem, regD src1) | |
4670 %{ | |
4671 instruction_count(3); | |
4672 src1 : S4(read); | |
4673 mem : S4(read); | |
4674 DECODE : S0; // any decoder for FPU PUSH | |
4675 D0 : S0(2); // big decoder only | |
4676 FPU : S4; | |
4677 MEM : S3(2); // any mem | |
4678 %} | |
4679 | |
4680 // Float load constant | |
4681 pipe_class fpu_reg_con(regD dst) | |
4682 %{ | |
4683 instruction_count(2); | |
4684 dst : S5(write); | |
4685 D0 : S0; // big decoder only for the load | |
4686 DECODE : S1; // any decoder for FPU POP | |
4687 FPU : S4; | |
4688 MEM : S3; // any mem | |
4689 %} | |
4690 | |
4691 // Float load constant | |
4692 pipe_class fpu_reg_reg_con(regD dst, regD src) | |
4693 %{ | |
4694 instruction_count(3); | |
4695 dst : S5(write); | |
4696 src : S3(read); | |
4697 D0 : S0; // big decoder only for the load | |
4698 DECODE : S1(2); // any decoder for FPU POP | |
4699 FPU : S4; | |
4700 MEM : S3; // any mem | |
4701 %} | |
4702 | |
4703 // UnConditional branch | |
4704 pipe_class pipe_jmp(label labl) | |
4705 %{ | |
4706 single_instruction; | |
4707 BR : S3; | |
4708 %} | |
4709 | |
4710 // Conditional branch | |
4711 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) | |
4712 %{ | |
4713 single_instruction; | |
4714 cr : S1(read); | |
4715 BR : S3; | |
4716 %} | |
4717 | |
4718 // Allocation idiom | |
4719 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) | |
4720 %{ | |
4721 instruction_count(1); force_serialization; | |
4722 fixed_latency(6); | |
4723 heap_ptr : S3(read); | |
4724 DECODE : S0(3); | |
4725 D0 : S2; | |
4726 MEM : S3; | |
4727 ALU : S3(2); | |
4728 dst : S5(write); | |
4729 BR : S5; | |
4730 %} | |
4731 | |
4732 // Generic big/slow expanded idiom | |
4733 pipe_class pipe_slow() | |
4734 %{ | |
4735 instruction_count(10); multiple_bundles; force_serialization; | |
4736 fixed_latency(100); | |
4737 D0 : S0(2); | |
4738 MEM : S3(2); | |
4739 %} | |
4740 | |
4741 // The real do-nothing guy | |
4742 pipe_class empty() | |
4743 %{ | |
4744 instruction_count(0); | |
4745 %} | |
4746 | |
4747 // Define the class for the Nop node | |
4748 define | |
4749 %{ | |
4750 MachNop = empty; | |
4751 %} | |
4752 | |
4753 %} | |
4754 | |
4755 //----------INSTRUCTIONS------------------------------------------------------- | |
4756 // | |
4757 // match -- States which machine-independent subtree may be replaced | |
4758 // by this instruction. | |
4759 // ins_cost -- The estimated cost of this instruction is used by instruction | |
4760 // selection to identify a minimum cost tree of machine | |
4761 // instructions that matches a tree of machine-independent | |
4762 // instructions. | |
4763 // format -- A string providing the disassembly for this instruction. | |
4764 // The value of an instruction's operand may be inserted | |
4765 // by referring to it with a '$' prefix. | |
4766 // opcode -- Three instruction opcodes may be provided. These are referred | |
4767 // to within an encode class as $primary, $secondary, and $tertiary | |
4768 // rrspectively. The primary opcode is commonly used to | |
4769 // indicate the type of machine instruction, while secondary | |
4770 // and tertiary are often used for prefix options or addressing | |
4771 // modes. | |
4772 // ins_encode -- A list of encode classes with parameters. The encode class | |
4773 // name must have been defined in an 'enc_class' specification | |
4774 // in the encode section of the architecture description. | |
4775 | |
4776 | |
4777 //----------Load/Store/Move Instructions--------------------------------------- | |
4778 //----------Load Instructions-------------------------------------------------- | |
4779 | |
4780 // Load Byte (8 bit signed) | |
4781 instruct loadB(rRegI dst, memory mem) | |
4782 %{ | |
4783 match(Set dst (LoadB mem)); | |
4784 | |
4785 ins_cost(125); | |
4786 format %{ "movsbl $dst, $mem\t# byte" %} | |
624 | 4787 |
4788 ins_encode %{ | |
4789 __ movsbl($dst$$Register, $mem$$Address); | |
4790 %} | |
4791 | |
0 | 4792 ins_pipe(ialu_reg_mem); |
4793 %} | |
4794 | |
624 | 4795 // Load Byte (8 bit signed) into Long Register |
4796 instruct loadB2L(rRegL dst, memory mem) | |
4797 %{ | |
4798 match(Set dst (ConvI2L (LoadB mem))); | |
4799 | |
4800 ins_cost(125); | |
4801 format %{ "movsbq $dst, $mem\t# byte -> long" %} | |
4802 | |
4803 ins_encode %{ | |
4804 __ movsbq($dst$$Register, $mem$$Address); | |
4805 %} | |
4806 | |
4807 ins_pipe(ialu_reg_mem); | |
4808 %} | |
4809 | |
4810 // Load Unsigned Byte (8 bit UNsigned) | |
4811 instruct loadUB(rRegI dst, memory mem) | |
4812 %{ | |
4813 match(Set dst (LoadUB mem)); | |
0 | 4814 |
4815 ins_cost(125); | |
4816 format %{ "movzbl $dst, $mem\t# ubyte" %} | |
624 | 4817 |
4818 ins_encode %{ | |
4819 __ movzbl($dst$$Register, $mem$$Address); | |
4820 %} | |
4821 | |
0 | 4822 ins_pipe(ialu_reg_mem); |
4823 %} | |
4824 | |
624 | 4825 // Load Unsigned Byte (8 bit UNsigned) into Long Register |
4826 instruct loadUB2L(rRegL dst, memory mem) | |
4827 %{ | |
4828 match(Set dst (ConvI2L (LoadUB mem))); | |
4829 | |
4830 ins_cost(125); | |
4831 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} | |
4832 | |
4833 ins_encode %{ | |
4834 __ movzbq($dst$$Register, $mem$$Address); | |
4835 %} | |
4836 | |
4837 ins_pipe(ialu_reg_mem); | |
4838 %} | |
0 | 4839 |
824 | 4840 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register |
4841 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ | |
4842 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); | |
4843 effect(KILL cr); | |
4844 | |
4845 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" | |
4846 "andl $dst, $mask" %} | |
4847 ins_encode %{ | |
4848 Register Rdst = $dst$$Register; | |
4849 __ movzbq(Rdst, $mem$$Address); | |
4850 __ andl(Rdst, $mask$$constant); | |
4851 %} | |
4852 ins_pipe(ialu_reg_mem); | |
4853 %} | |
4854 | |
0 | 4855 // Load Short (16 bit signed) |
4856 instruct loadS(rRegI dst, memory mem) | |
4857 %{ | |
4858 match(Set dst (LoadS mem)); | |
4859 | |
624 | 4860 ins_cost(125); |
0 | 4861 format %{ "movswl $dst, $mem\t# short" %} |
624 | 4862 |
4863 ins_encode %{ | |
4864 __ movswl($dst$$Register, $mem$$Address); | |
4865 %} | |
4866 | |
0 | 4867 ins_pipe(ialu_reg_mem); |
4868 %} | |
4869 | |
785 | 4870 // Load Short (16 bit signed) to Byte (8 bit signed) |
4871 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ | |
4872 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); | |
4873 | |
4874 ins_cost(125); | |
4875 format %{ "movsbl $dst, $mem\t# short -> byte" %} | |
4876 ins_encode %{ | |
4877 __ movsbl($dst$$Register, $mem$$Address); | |
4878 %} | |
4879 ins_pipe(ialu_reg_mem); | |
4880 %} | |
4881 | |
624 | 4882 // Load Short (16 bit signed) into Long Register |
4883 instruct loadS2L(rRegL dst, memory mem) | |
4884 %{ | |
4885 match(Set dst (ConvI2L (LoadS mem))); | |
4886 | |
4887 ins_cost(125); | |
4888 format %{ "movswq $dst, $mem\t# short -> long" %} | |
4889 | |
4890 ins_encode %{ | |
4891 __ movswq($dst$$Register, $mem$$Address); | |
4892 %} | |
4893 | |
4894 ins_pipe(ialu_reg_mem); | |
4895 %} | |
0 | 4896 |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
420
diff
changeset
|
4897 // Load Unsigned Short/Char (16 bit UNsigned) |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
420
diff
changeset
|
4898 instruct loadUS(rRegI dst, memory mem) |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
420
diff
changeset
|
4899 %{ |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
420
diff
changeset
|
4900 match(Set dst (LoadUS mem)); |
0 | 4901 |
4902 ins_cost(125); | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
420
diff
changeset
|
4903 format %{ "movzwl $dst, $mem\t# ushort/char" %} |
624 | 4904 |
4905 ins_encode %{ | |
4906 __ movzwl($dst$$Register, $mem$$Address); | |
4907 %} | |
4908 | |
0 | 4909 ins_pipe(ialu_reg_mem); |
4910 %} | |
4911 | |
785 | 4912 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) |
4913 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ | |
4914 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); | |
4915 | |
4916 ins_cost(125); | |
4917 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} | |
4918 ins_encode %{ | |
4919 __ movsbl($dst$$Register, $mem$$Address); | |
4920 %} | |
4921 ins_pipe(ialu_reg_mem); | |
4922 %} | |
4923 | |
624 | 4924 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register |
4925 instruct loadUS2L(rRegL dst, memory mem) | |
4926 %{ | |
4927 match(Set dst (ConvI2L (LoadUS mem))); | |
4928 | |
4929 ins_cost(125); | |
4930 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} | |
4931 | |
4932 ins_encode %{ | |
4933 __ movzwq($dst$$Register, $mem$$Address); | |
4934 %} | |
4935 | |
4936 ins_pipe(ialu_reg_mem); | |
4937 %} | |
0 | 4938 |
824 | 4939 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register |
4940 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ | |
4941 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); | |
4942 | |
4943 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} | |
4944 ins_encode %{ | |
4945 __ movzbq($dst$$Register, $mem$$Address); | |
4946 %} | |
4947 ins_pipe(ialu_reg_mem); | |
4948 %} | |
4949 | |
4950 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register | |
4951 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ | |
4952 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); | |
4953 effect(KILL cr); | |
4954 | |
4955 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" | |
4956 "andl $dst, $mask" %} | |
4957 ins_encode %{ | |
4958 Register Rdst = $dst$$Register; | |
4959 __ movzwq(Rdst, $mem$$Address); | |
4960 __ andl(Rdst, $mask$$constant); | |
4961 %} | |
4962 ins_pipe(ialu_reg_mem); | |
4963 %} | |
4964 | |
0 | 4965 // Load Integer |
4966 instruct loadI(rRegI dst, memory mem) | |
4967 %{ | |
4968 match(Set dst (LoadI mem)); | |
4969 | |
624 | 4970 ins_cost(125); |
0 | 4971 format %{ "movl $dst, $mem\t# int" %} |
624 | 4972 |
4973 ins_encode %{ | |
4974 __ movl($dst$$Register, $mem$$Address); | |
4975 %} | |
4976 | |
4977 ins_pipe(ialu_reg_mem); | |
4978 %} | |
4979 | |
785 | 4980 // Load Integer (32 bit signed) to Byte (8 bit signed) |
4981 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ | |
4982 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); | |
4983 | |
4984 ins_cost(125); | |
4985 format %{ "movsbl $dst, $mem\t# int -> byte" %} | |
4986 ins_encode %{ | |
4987 __ movsbl($dst$$Register, $mem$$Address); | |
4988 %} | |
4989 ins_pipe(ialu_reg_mem); | |
4990 %} | |
4991 | |
4992 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) | |
4993 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ | |
4994 match(Set dst (AndI (LoadI mem) mask)); | |
4995 | |
4996 ins_cost(125); | |
4997 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} | |
4998 ins_encode %{ | |
4999 __ movzbl($dst$$Register, $mem$$Address); | |
5000 %} | |
5001 ins_pipe(ialu_reg_mem); | |
5002 %} | |
5003 | |
5004 // Load Integer (32 bit signed) to Short (16 bit signed) | |
5005 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ | |
5006 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); | |
5007 | |
5008 ins_cost(125); | |
5009 format %{ "movswl $dst, $mem\t# int -> short" %} | |
5010 ins_encode %{ | |
5011 __ movswl($dst$$Register, $mem$$Address); | |
5012 %} | |
5013 ins_pipe(ialu_reg_mem); | |
5014 %} | |
5015 | |
5016 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) | |
5017 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ | |
5018 match(Set dst (AndI (LoadI mem) mask)); | |
5019 | |
5020 ins_cost(125); | |
5021 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} | |
5022 ins_encode %{ | |
5023 __ movzwl($dst$$Register, $mem$$Address); | |
5024 %} | |
5025 ins_pipe(ialu_reg_mem); | |
5026 %} | |
5027 | |
624 | 5028 // Load Integer into Long Register |
5029 instruct loadI2L(rRegL dst, memory mem) | |
5030 %{ | |
5031 match(Set dst (ConvI2L (LoadI mem))); | |
5032 | |
5033 ins_cost(125); | |
5034 format %{ "movslq $dst, $mem\t# int -> long" %} | |
5035 | |
5036 ins_encode %{ | |
5037 __ movslq($dst$$Register, $mem$$Address); | |
5038 %} | |
5039 | |
5040 ins_pipe(ialu_reg_mem); | |
5041 %} | |
5042 | |
824 | 5043 // Load Integer with mask 0xFF into Long Register |
5044 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ | |
5045 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); | |
5046 | |
5047 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} | |
5048 ins_encode %{ | |
5049 __ movzbq($dst$$Register, $mem$$Address); | |
5050 %} | |
5051 ins_pipe(ialu_reg_mem); | |
5052 %} | |
5053 | |
5054 // Load Integer with mask 0xFFFF into Long Register | |
5055 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ | |
5056 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); | |
5057 | |
5058 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} | |
5059 ins_encode %{ | |
5060 __ movzwq($dst$$Register, $mem$$Address); | |
5061 %} | |
5062 ins_pipe(ialu_reg_mem); | |
5063 %} | |
5064 | |
5065 // Load Integer with a 32-bit mask into Long Register | |
5066 instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ | |
5067 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); | |
5068 effect(KILL cr); | |
5069 | |
5070 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t" | |
5071 "andl $dst, $mask" %} | |
5072 ins_encode %{ | |
5073 Register Rdst = $dst$$Register; | |
5074 __ movl(Rdst, $mem$$Address); | |
5075 __ andl(Rdst, $mask$$constant); | |
5076 %} | |
5077 ins_pipe(ialu_reg_mem); | |
5078 %} | |
5079 | |
624 | 5080 // Load Unsigned Integer into Long Register |
5081 instruct loadUI2L(rRegL dst, memory mem) | |
5082 %{ | |
5083 match(Set dst (LoadUI2L mem)); | |
5084 | |
5085 ins_cost(125); | |
5086 format %{ "movl $dst, $mem\t# uint -> long" %} | |
5087 | |
5088 ins_encode %{ | |
5089 __ movl($dst$$Register, $mem$$Address); | |
5090 %} | |
5091 | |
0 | 5092 ins_pipe(ialu_reg_mem); |
5093 %} | |
5094 | |
5095 // Load Long | |
5096 instruct loadL(rRegL dst, memory mem) | |
5097 %{ | |
5098 match(Set dst (LoadL mem)); | |
5099 | |
624 | 5100 ins_cost(125); |
0 | 5101 format %{ "movq $dst, $mem\t# long" %} |
624 | 5102 |
5103 ins_encode %{ | |
5104 __ movq($dst$$Register, $mem$$Address); | |
5105 %} | |
5106 | |
0 | 5107 ins_pipe(ialu_reg_mem); // XXX |
5108 %} | |
5109 | |
5110 // Load Range | |
5111 instruct loadRange(rRegI dst, memory mem) | |
5112 %{ | |
5113 match(Set dst (LoadRange mem)); | |
5114 | |
5115 ins_cost(125); // XXX | |
5116 format %{ "movl $dst, $mem\t# range" %} | |
5117 opcode(0x8B); | |
5118 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); | |
5119 ins_pipe(ialu_reg_mem); | |
5120 %} | |
5121 | |
5122 // Load Pointer | |
5123 instruct loadP(rRegP dst, memory mem) | |
5124 %{ | |
5125 match(Set dst (LoadP mem)); | |
5126 | |
5127 ins_cost(125); // XXX | |
5128 format %{ "movq $dst, $mem\t# ptr" %} | |
5129 opcode(0x8B); | |
5130 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | |
5131 ins_pipe(ialu_reg_mem); // XXX | |
5132 %} | |
5133 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5134 // Load Compressed Pointer |
163 | 5135 instruct loadN(rRegN dst, memory mem) |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5136 %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5137 match(Set dst (LoadN mem)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5138 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5139 ins_cost(125); // XXX |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5140 format %{ "movl $dst, $mem\t# compressed ptr" %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5141 ins_encode %{ |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5142 __ movl($dst$$Register, $mem$$Address); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5143 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5144 ins_pipe(ialu_reg_mem); // XXX |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5145 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5146 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5147 |
0 | 5148 // Load Klass Pointer |
5149 instruct loadKlass(rRegP dst, memory mem) | |
5150 %{ | |
5151 match(Set dst (LoadKlass mem)); | |
5152 | |
5153 ins_cost(125); // XXX | |
5154 format %{ "movq $dst, $mem\t# class" %} | |
5155 opcode(0x8B); | |
5156 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | |
5157 ins_pipe(ialu_reg_mem); // XXX | |
5158 %} | |
5159 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
5160 // Load narrow Klass Pointer |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
5161 instruct loadNKlass(rRegN dst, memory mem) |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
5162 %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
5163 match(Set dst (LoadNKlass mem)); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5164 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5165 ins_cost(125); // XXX |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
169
diff
changeset
|
5166 format %{ "movl $dst, $mem\t# compressed klass ptr" %} |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5167 ins_encode %{ |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5168 __ movl($dst$$Register, $mem$$Address); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5169 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5170 ins_pipe(ialu_reg_mem); // XXX |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5171 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5172 |
0 | 5173 // Load Float |
5174 instruct loadF(regF dst, memory mem) | |
5175 %{ | |
5176 match(Set dst (LoadF mem)); | |
5177 | |
5178 ins_cost(145); // XXX | |
5179 format %{ "movss $dst, $mem\t# float" %} | |
4759 | 5180 ins_encode %{ |
5181 __ movflt($dst$$XMMRegister, $mem$$Address); | |
5182 %} | |
0 | 5183 ins_pipe(pipe_slow); // XXX |
5184 %} | |
5185 | |
5186 // Load Double | |
5187 instruct loadD_partial(regD dst, memory mem) | |
5188 %{ | |
5189 predicate(!UseXmmLoadAndClearUpper); | |
5190 match(Set dst (LoadD mem)); | |
5191 | |
5192 ins_cost(145); // XXX | |
5193 format %{ "movlpd $dst, $mem\t# double" %} | |
4759 | 5194 ins_encode %{ |
5195 __ movdbl($dst$$XMMRegister, $mem$$Address); | |
5196 %} | |
0 | 5197 ins_pipe(pipe_slow); // XXX |
5198 %} | |
5199 | |
5200 instruct loadD(regD dst, memory mem) | |
5201 %{ | |
5202 predicate(UseXmmLoadAndClearUpper); | |
5203 match(Set dst (LoadD mem)); | |
5204 | |
5205 ins_cost(145); // XXX | |
5206 format %{ "movsd $dst, $mem\t# double" %} | |
4759 | 5207 ins_encode %{ |
5208 __ movdbl($dst$$XMMRegister, $mem$$Address); | |
5209 %} | |
0 | 5210 ins_pipe(pipe_slow); // XXX |
5211 %} | |
5212 | |
5213 // Load Effective Address | |
5214 instruct leaP8(rRegP dst, indOffset8 mem) | |
5215 %{ | |
5216 match(Set dst mem); | |
5217 | |
5218 ins_cost(110); // XXX | |
5219 format %{ "leaq $dst, $mem\t# ptr 8" %} | |
5220 opcode(0x8D); | |
5221 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | |
5222 ins_pipe(ialu_reg_reg_fat); | |
5223 %} | |
5224 | |
5225 instruct leaP32(rRegP dst, indOffset32 mem) | |
5226 %{ | |
5227 match(Set dst mem); | |
5228 | |
5229 ins_cost(110); | |
5230 format %{ "leaq $dst, $mem\t# ptr 32" %} | |
5231 opcode(0x8D); | |
5232 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | |
5233 ins_pipe(ialu_reg_reg_fat); | |
5234 %} | |
5235 | |
5236 // instruct leaPIdx(rRegP dst, indIndex mem) | |
5237 // %{ | |
5238 // match(Set dst mem); | |
5239 | |
5240 // ins_cost(110); | |
5241 // format %{ "leaq $dst, $mem\t# ptr idx" %} | |
5242 // opcode(0x8D); | |
5243 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | |
5244 // ins_pipe(ialu_reg_reg_fat); | |
5245 // %} | |
5246 | |
5247 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) | |
5248 %{ | |
5249 match(Set dst mem); | |
5250 | |
5251 ins_cost(110); | |
5252 format %{ "leaq $dst, $mem\t# ptr idxoff" %} | |
5253 opcode(0x8D); | |
5254 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | |
5255 ins_pipe(ialu_reg_reg_fat); | |
5256 %} | |
5257 | |
5258 instruct leaPIdxScale(rRegP dst, indIndexScale mem) | |
5259 %{ | |
5260 match(Set dst mem); | |
5261 | |
5262 ins_cost(110); | |
5263 format %{ "leaq $dst, $mem\t# ptr idxscale" %} | |
5264 opcode(0x8D); | |
5265 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | |
5266 ins_pipe(ialu_reg_reg_fat); | |
5267 %} | |
5268 | |
5269 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) | |
5270 %{ | |
5271 match(Set dst mem); | |
5272 | |
5273 ins_cost(110); | |
5274 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} | |
5275 opcode(0x8D); | |
5276 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | |
5277 ins_pipe(ialu_reg_reg_fat); | |
5278 %} | |
5279 | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5280 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5281 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5282 match(Set dst mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5283 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5284 ins_cost(110); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5285 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5286 opcode(0x8D); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5287 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5288 ins_pipe(ialu_reg_reg_fat); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5289 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5290 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5291 // Load Effective Address which uses Narrow (32-bits) oop |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5292 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5293 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5294 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5295 match(Set dst mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5296 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5297 ins_cost(110); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5298 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5299 opcode(0x8D); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5300 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5301 ins_pipe(ialu_reg_reg_fat); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5302 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5303 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5304 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5305 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5306 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5307 match(Set dst mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5308 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5309 ins_cost(110); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5310 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5311 opcode(0x8D); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5312 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5313 ins_pipe(ialu_reg_reg_fat); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5314 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5315 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5316 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5317 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5318 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5319 match(Set dst mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5320 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5321 ins_cost(110); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5322 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5323 opcode(0x8D); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5324 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5325 ins_pipe(ialu_reg_reg_fat); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5326 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5327 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5328 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5329 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5330 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5331 match(Set dst mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5332 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5333 ins_cost(110); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5334 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5335 opcode(0x8D); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5336 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5337 ins_pipe(ialu_reg_reg_fat); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5338 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5339 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5340 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5341 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5342 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5343 match(Set dst mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5344 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5345 ins_cost(110); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5346 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5347 opcode(0x8D); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5348 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5349 ins_pipe(ialu_reg_reg_fat); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5350 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5351 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5352 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5353 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5354 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5355 match(Set dst mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5356 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5357 ins_cost(110); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5358 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5359 opcode(0x8D); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5360 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5361 ins_pipe(ialu_reg_reg_fat); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5362 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5363 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5364 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5365 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5366 predicate(Universe::narrow_oop_shift() == 0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5367 match(Set dst mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5368 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5369 ins_cost(110); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5370 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5371 opcode(0x8D); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5372 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5373 ins_pipe(ialu_reg_reg_fat); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5374 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5375 |
0 | 5376 instruct loadConI(rRegI dst, immI src) |
5377 %{ | |
5378 match(Set dst src); | |
5379 | |
5380 format %{ "movl $dst, $src\t# int" %} | |
5381 ins_encode(load_immI(dst, src)); | |
5382 ins_pipe(ialu_reg_fat); // XXX | |
5383 %} | |
5384 | |
5385 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) | |
5386 %{ | |
5387 match(Set dst src); | |
5388 effect(KILL cr); | |
5389 | |
5390 ins_cost(50); | |
5391 format %{ "xorl $dst, $dst\t# int" %} | |
5392 opcode(0x33); /* + rd */ | |
5393 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); | |
5394 ins_pipe(ialu_reg); | |
5395 %} | |
5396 | |
5397 instruct loadConL(rRegL dst, immL src) | |
5398 %{ | |
5399 match(Set dst src); | |
5400 | |
5401 ins_cost(150); | |
5402 format %{ "movq $dst, $src\t# long" %} | |
5403 ins_encode(load_immL(dst, src)); | |
5404 ins_pipe(ialu_reg); | |
5405 %} | |
5406 | |
5407 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) | |
5408 %{ | |
5409 match(Set dst src); | |
5410 effect(KILL cr); | |
5411 | |
5412 ins_cost(50); | |
5413 format %{ "xorl $dst, $dst\t# long" %} | |
5414 opcode(0x33); /* + rd */ | |
5415 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); | |
5416 ins_pipe(ialu_reg); // XXX | |
5417 %} | |
5418 | |
5419 instruct loadConUL32(rRegL dst, immUL32 src) | |
5420 %{ | |
5421 match(Set dst src); | |
5422 | |
5423 ins_cost(60); | |
5424 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} | |
5425 ins_encode(load_immUL32(dst, src)); | |
5426 ins_pipe(ialu_reg); | |
5427 %} | |
5428 | |
5429 instruct loadConL32(rRegL dst, immL32 src) | |
5430 %{ | |
5431 match(Set dst src); | |
5432 | |
5433 ins_cost(70); | |
5434 format %{ "movq $dst, $src\t# long (32-bit)" %} | |
5435 ins_encode(load_immL32(dst, src)); | |
5436 ins_pipe(ialu_reg); | |
5437 %} | |
5438 | |
2008 | 5439 instruct loadConP(rRegP dst, immP con) %{ |
5440 match(Set dst con); | |
5441 | |
5442 format %{ "movq $dst, $con\t# ptr" %} | |
5443 ins_encode(load_immP(dst, con)); | |
0 | 5444 ins_pipe(ialu_reg_fat); // XXX |
5445 %} | |
5446 | |
5447 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) | |
5448 %{ | |
5449 match(Set dst src); | |
5450 effect(KILL cr); | |
5451 | |
5452 ins_cost(50); | |
5453 format %{ "xorl $dst, $dst\t# ptr" %} | |
5454 opcode(0x33); /* + rd */ | |
5455 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); | |
5456 ins_pipe(ialu_reg); | |
5457 %} | |
5458 | |
5459 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) | |
5460 %{ | |
5461 match(Set dst src); | |
5462 effect(KILL cr); | |
5463 | |
5464 ins_cost(60); | |
5465 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} | |
5466 ins_encode(load_immP31(dst, src)); | |
5467 ins_pipe(ialu_reg); | |
5468 %} | |
5469 | |
2008 | 5470 instruct loadConF(regF dst, immF con) %{ |
5471 match(Set dst con); | |
0 | 5472 ins_cost(125); |
2008 | 5473 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} |
5474 ins_encode %{ | |
5475 __ movflt($dst$$XMMRegister, $constantaddress($con)); | |
5476 %} | |
0 | 5477 ins_pipe(pipe_slow); |
5478 %} | |
5479 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5480 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5481 match(Set dst src); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5482 effect(KILL cr); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
5483 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5484 ins_encode %{ |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5485 __ xorq($dst$$Register, $dst$$Register); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5486 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5487 ins_pipe(ialu_reg); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5488 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5489 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
5490 instruct loadConN(rRegN dst, immN src) %{ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5491 match(Set dst src); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5492 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5493 ins_cost(125); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
5494 format %{ "movl $dst, $src\t# compressed ptr" %} |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5495 ins_encode %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5496 address con = (address)$src$$constant; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5497 if (con == NULL) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5498 ShouldNotReachHere(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5499 } else { |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5500 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5501 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5502 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5503 ins_pipe(ialu_reg_fat); // XXX |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5504 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5505 |
0 | 5506 instruct loadConF0(regF dst, immF0 src) |
5507 %{ | |
5508 match(Set dst src); | |
5509 ins_cost(100); | |
5510 | |
5511 format %{ "xorps $dst, $dst\t# float 0.0" %} | |
4759 | 5512 ins_encode %{ |
5513 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); | |
5514 %} | |
0 | 5515 ins_pipe(pipe_slow); |
5516 %} | |
5517 | |
5518 // Use the same format since predicate() can not be used here. | |
2008 | 5519 instruct loadConD(regD dst, immD con) %{ |
5520 match(Set dst con); | |
0 | 5521 ins_cost(125); |
2008 | 5522 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} |
5523 ins_encode %{ | |
5524 __ movdbl($dst$$XMMRegister, $constantaddress($con)); | |
5525 %} | |
0 | 5526 ins_pipe(pipe_slow); |
5527 %} | |
5528 | |
5529 instruct loadConD0(regD dst, immD0 src) | |
5530 %{ | |
5531 match(Set dst src); | |
5532 ins_cost(100); | |
5533 | |
5534 format %{ "xorpd $dst, $dst\t# double 0.0" %} | |
4759 | 5535 ins_encode %{ |
5536 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); | |
5537 %} | |
0 | 5538 ins_pipe(pipe_slow); |
5539 %} | |
5540 | |
5541 instruct loadSSI(rRegI dst, stackSlotI src) | |
5542 %{ | |
5543 match(Set dst src); | |
5544 | |
5545 ins_cost(125); | |
5546 format %{ "movl $dst, $src\t# int stk" %} | |
5547 opcode(0x8B); | |
5548 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); | |
5549 ins_pipe(ialu_reg_mem); | |
5550 %} | |
5551 | |
5552 instruct loadSSL(rRegL dst, stackSlotL src) | |
5553 %{ | |
5554 match(Set dst src); | |
5555 | |
5556 ins_cost(125); | |
5557 format %{ "movq $dst, $src\t# long stk" %} | |
5558 opcode(0x8B); | |
5559 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); | |
5560 ins_pipe(ialu_reg_mem); | |
5561 %} | |
5562 | |
5563 instruct loadSSP(rRegP dst, stackSlotP src) | |
5564 %{ | |
5565 match(Set dst src); | |
5566 | |
5567 ins_cost(125); | |
5568 format %{ "movq $dst, $src\t# ptr stk" %} | |
5569 opcode(0x8B); | |
5570 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); | |
5571 ins_pipe(ialu_reg_mem); | |
5572 %} | |
5573 | |
5574 instruct loadSSF(regF dst, stackSlotF src) | |
5575 %{ | |
5576 match(Set dst src); | |
5577 | |
5578 ins_cost(125); | |
5579 format %{ "movss $dst, $src\t# float stk" %} | |
4759 | 5580 ins_encode %{ |
5581 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); | |
5582 %} | |
0 | 5583 ins_pipe(pipe_slow); // XXX |
5584 %} | |
5585 | |
5586 // Use the same format since predicate() can not be used here. | |
5587 instruct loadSSD(regD dst, stackSlotD src) | |
5588 %{ | |
5589 match(Set dst src); | |
5590 | |
5591 ins_cost(125); | |
5592 format %{ "movsd $dst, $src\t# double stk" %} | |
5593 ins_encode %{ | |
5594 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); | |
5595 %} | |
5596 ins_pipe(pipe_slow); // XXX | |
5597 %} | |
5598 | |
5599 // Prefetch instructions. | |
5600 // Must be safe to execute with invalid address (cannot fault). | |
5601 | |
5602 instruct prefetchr( memory mem ) %{ | |
5603 predicate(ReadPrefetchInstr==3); | |
5604 match(PrefetchRead mem); | |
5605 ins_cost(125); | |
5606 | |
5607 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} | |
3854 | 5608 ins_encode %{ |
5609 __ prefetchr($mem$$Address); | |
5610 %} | |
0 | 5611 ins_pipe(ialu_mem); |
5612 %} | |
5613 | |
5614 instruct prefetchrNTA( memory mem ) %{ | |
5615 predicate(ReadPrefetchInstr==0); | |
5616 match(PrefetchRead mem); | |
5617 ins_cost(125); | |
5618 | |
5619 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} | |
3854 | 5620 ins_encode %{ |
5621 __ prefetchnta($mem$$Address); | |
5622 %} | |
0 | 5623 ins_pipe(ialu_mem); |
5624 %} | |
5625 | |
5626 instruct prefetchrT0( memory mem ) %{ | |
5627 predicate(ReadPrefetchInstr==1); | |
5628 match(PrefetchRead mem); | |
5629 ins_cost(125); | |
5630 | |
5631 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} | |
3854 | 5632 ins_encode %{ |
5633 __ prefetcht0($mem$$Address); | |
5634 %} | |
0 | 5635 ins_pipe(ialu_mem); |
5636 %} | |
5637 | |
5638 instruct prefetchrT2( memory mem ) %{ | |
5639 predicate(ReadPrefetchInstr==2); | |
5640 match(PrefetchRead mem); | |
5641 ins_cost(125); | |
5642 | |
5643 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} | |
3854 | 5644 ins_encode %{ |
5645 __ prefetcht2($mem$$Address); | |
5646 %} | |
0 | 5647 ins_pipe(ialu_mem); |
5648 %} | |
5649 | |
5650 instruct prefetchwNTA( memory mem ) %{ | |
5651 match(PrefetchWrite mem); | |
5652 ins_cost(125); | |
5653 | |
5654 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} | |
3854 | 5655 ins_encode %{ |
5656 __ prefetchnta($mem$$Address); | |
5657 %} | |
0 | 5658 ins_pipe(ialu_mem); |
5659 %} | |
5660 | |
3854 | 5661 // Prefetch instructions for allocation. |
5662 | |
5663 instruct prefetchAlloc( memory mem ) %{ | |
5664 predicate(AllocatePrefetchInstr==3); | |
5665 match(PrefetchAllocation mem); | |
5666 ins_cost(125); | |
5667 | |
5668 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} | |
5669 ins_encode %{ | |
5670 __ prefetchw($mem$$Address); | |
5671 %} | |
5672 ins_pipe(ialu_mem); | |
5673 %} | |
5674 | |
5675 instruct prefetchAllocNTA( memory mem ) %{ | |
5676 predicate(AllocatePrefetchInstr==0); | |
5677 match(PrefetchAllocation mem); | |
0 | 5678 ins_cost(125); |
5679 | |
3854 | 5680 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} |
5681 ins_encode %{ | |
5682 __ prefetchnta($mem$$Address); | |
5683 %} | |
0 | 5684 ins_pipe(ialu_mem); |
5685 %} | |
5686 | |
3854 | 5687 instruct prefetchAllocT0( memory mem ) %{ |
5688 predicate(AllocatePrefetchInstr==1); | |
5689 match(PrefetchAllocation mem); | |
0 | 5690 ins_cost(125); |
5691 | |
3854 | 5692 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} |
5693 ins_encode %{ | |
5694 __ prefetcht0($mem$$Address); | |
5695 %} | |
5696 ins_pipe(ialu_mem); | |
5697 %} | |
5698 | |
5699 instruct prefetchAllocT2( memory mem ) %{ | |
5700 predicate(AllocatePrefetchInstr==2); | |
5701 match(PrefetchAllocation mem); | |
5702 ins_cost(125); | |
5703 | |
5704 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} | |
5705 ins_encode %{ | |
5706 __ prefetcht2($mem$$Address); | |
5707 %} | |
0 | 5708 ins_pipe(ialu_mem); |
5709 %} | |
5710 | |
5711 //----------Store Instructions------------------------------------------------- | |
5712 | |
5713 // Store Byte | |
5714 instruct storeB(memory mem, rRegI src) | |
5715 %{ | |
5716 match(Set mem (StoreB mem src)); | |
5717 | |
5718 ins_cost(125); // XXX | |
5719 format %{ "movb $mem, $src\t# byte" %} | |
5720 opcode(0x88); | |
5721 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); | |
5722 ins_pipe(ialu_mem_reg); | |
5723 %} | |
5724 | |
5725 // Store Char/Short | |
5726 instruct storeC(memory mem, rRegI src) | |
5727 %{ | |
5728 match(Set mem (StoreC mem src)); | |
5729 | |
5730 ins_cost(125); // XXX | |
5731 format %{ "movw $mem, $src\t# char/short" %} | |
5732 opcode(0x89); | |
5733 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); | |
5734 ins_pipe(ialu_mem_reg); | |
5735 %} | |
5736 | |
5737 // Store Integer | |
5738 instruct storeI(memory mem, rRegI src) | |
5739 %{ | |
5740 match(Set mem (StoreI mem src)); | |
5741 | |
5742 ins_cost(125); // XXX | |
5743 format %{ "movl $mem, $src\t# int" %} | |
5744 opcode(0x89); | |
5745 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); | |
5746 ins_pipe(ialu_mem_reg); | |
5747 %} | |
5748 | |
5749 // Store Long | |
5750 instruct storeL(memory mem, rRegL src) | |
5751 %{ | |
5752 match(Set mem (StoreL mem src)); | |
5753 | |
5754 ins_cost(125); // XXX | |
5755 format %{ "movq $mem, $src\t# long" %} | |
5756 opcode(0x89); | |
5757 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); | |
5758 ins_pipe(ialu_mem_reg); // XXX | |
5759 %} | |
5760 | |
5761 // Store Pointer | |
5762 instruct storeP(memory mem, any_RegP src) | |
5763 %{ | |
5764 match(Set mem (StoreP mem src)); | |
5765 | |
5766 ins_cost(125); // XXX | |
5767 format %{ "movq $mem, $src\t# ptr" %} | |
5768 opcode(0x89); | |
5769 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); | |
5770 ins_pipe(ialu_mem_reg); | |
5771 %} | |
5772 | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5773 instruct storeImmP0(memory mem, immP0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5774 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5775 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5776 match(Set mem (StoreP mem zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5777 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5778 ins_cost(125); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5779 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5780 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5781 __ movq($mem$$Address, r12); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5782 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5783 ins_pipe(ialu_mem_reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5784 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5785 |
0 | 5786 // Store NULL Pointer, mark word, or other simple pointer constant. |
5787 instruct storeImmP(memory mem, immP31 src) | |
5788 %{ | |
5789 match(Set mem (StoreP mem src)); | |
5790 | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5791 ins_cost(150); // XXX |
0 | 5792 format %{ "movq $mem, $src\t# ptr" %} |
5793 opcode(0xC7); /* C7 /0 */ | |
5794 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); | |
5795 ins_pipe(ialu_mem_imm); | |
5796 %} | |
5797 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5798 // Store Compressed Pointer |
163 | 5799 instruct storeN(memory mem, rRegN src) |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5800 %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5801 match(Set mem (StoreN mem src)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5802 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5803 ins_cost(125); // XXX |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
5804 format %{ "movl $mem, $src\t# compressed ptr" %} |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5805 ins_encode %{ |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5806 __ movl($mem$$Address, $src$$Register); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5807 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5808 ins_pipe(ialu_mem_reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5809 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5810 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5811 instruct storeImmN0(memory mem, immN0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5812 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5813 predicate(Universe::narrow_oop_base() == NULL); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5814 match(Set mem (StoreN mem zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5815 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5816 ins_cost(125); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5817 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5818 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5819 __ movl($mem$$Address, r12); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5820 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5821 ins_pipe(ialu_mem_reg); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5822 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
5823 |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5824 instruct storeImmN(memory mem, immN src) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5825 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5826 match(Set mem (StoreN mem src)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5827 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5828 ins_cost(150); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5829 format %{ "movl $mem, $src\t# compressed ptr" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5830 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5831 address con = (address)$src$$constant; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5832 if (con == NULL) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5833 __ movl($mem$$Address, (int32_t)0); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5834 } else { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5835 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5836 } |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5837 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5838 ins_pipe(ialu_mem_imm); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5839 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5840 |
0 | 5841 // Store Integer Immediate |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5842 instruct storeImmI0(memory mem, immI0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5843 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5844 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5845 match(Set mem (StoreI mem zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5846 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5847 ins_cost(125); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5848 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5849 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5850 __ movl($mem$$Address, r12); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5851 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5852 ins_pipe(ialu_mem_reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5853 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5854 |
0 | 5855 instruct storeImmI(memory mem, immI src) |
5856 %{ | |
5857 match(Set mem (StoreI mem src)); | |
5858 | |
5859 ins_cost(150); | |
5860 format %{ "movl $mem, $src\t# int" %} | |
5861 opcode(0xC7); /* C7 /0 */ | |
5862 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); | |
5863 ins_pipe(ialu_mem_imm); | |
5864 %} | |
5865 | |
5866 // Store Long Immediate | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5867 instruct storeImmL0(memory mem, immL0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5868 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5869 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5870 match(Set mem (StoreL mem zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5871 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5872 ins_cost(125); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5873 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5874 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5875 __ movq($mem$$Address, r12); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5876 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5877 ins_pipe(ialu_mem_reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5878 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5879 |
0 | 5880 instruct storeImmL(memory mem, immL32 src) |
5881 %{ | |
5882 match(Set mem (StoreL mem src)); | |
5883 | |
5884 ins_cost(150); | |
5885 format %{ "movq $mem, $src\t# long" %} | |
5886 opcode(0xC7); /* C7 /0 */ | |
5887 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); | |
5888 ins_pipe(ialu_mem_imm); | |
5889 %} | |
5890 | |
5891 // Store Short/Char Immediate | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5892 instruct storeImmC0(memory mem, immI0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5893 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5894 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5895 match(Set mem (StoreC mem zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5896 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5897 ins_cost(125); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5898 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5899 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5900 __ movw($mem$$Address, r12); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5901 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5902 ins_pipe(ialu_mem_reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5903 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5904 |
0 | 5905 instruct storeImmI16(memory mem, immI16 src) |
5906 %{ | |
5907 predicate(UseStoreImmI16); | |
5908 match(Set mem (StoreC mem src)); | |
5909 | |
5910 ins_cost(150); | |
5911 format %{ "movw $mem, $src\t# short/char" %} | |
5912 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ | |
5913 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); | |
5914 ins_pipe(ialu_mem_imm); | |
5915 %} | |
5916 | |
5917 // Store Byte Immediate | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5918 instruct storeImmB0(memory mem, immI0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5919 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5920 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5921 match(Set mem (StoreB mem zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5922 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5923 ins_cost(125); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5924 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5925 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5926 __ movb($mem$$Address, r12); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5927 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5928 ins_pipe(ialu_mem_reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5929 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5930 |
0 | 5931 instruct storeImmB(memory mem, immI8 src) |
5932 %{ | |
5933 match(Set mem (StoreB mem src)); | |
5934 | |
5935 ins_cost(150); // XXX | |
5936 format %{ "movb $mem, $src\t# byte" %} | |
5937 opcode(0xC6); /* C6 /0 */ | |
5938 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); | |
5939 ins_pipe(ialu_mem_imm); | |
5940 %} | |
5941 | |
5942 // Store CMS card-mark Immediate | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5943 instruct storeImmCM0_reg(memory mem, immI0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5944 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5945 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5946 match(Set mem (StoreCM mem zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5947 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5948 ins_cost(125); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5949 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5950 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5951 __ movb($mem$$Address, r12); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5952 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5953 ins_pipe(ialu_mem_reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5954 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5955 |
0 | 5956 instruct storeImmCM0(memory mem, immI0 src) |
5957 %{ | |
5958 match(Set mem (StoreCM mem src)); | |
5959 | |
5960 ins_cost(150); // XXX | |
5961 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} | |
5962 opcode(0xC6); /* C6 /0 */ | |
5963 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); | |
5964 ins_pipe(ialu_mem_imm); | |
5965 %} | |
5966 | |
5967 // Store Float | |
5968 instruct storeF(memory mem, regF src) | |
5969 %{ | |
5970 match(Set mem (StoreF mem src)); | |
5971 | |
5972 ins_cost(95); // XXX | |
5973 format %{ "movss $mem, $src\t# float" %} | |
4759 | 5974 ins_encode %{ |
5975 __ movflt($mem$$Address, $src$$XMMRegister); | |
5976 %} | |
0 | 5977 ins_pipe(pipe_slow); // XXX |
5978 %} | |
5979 | |
5980 // Store immediate Float value (it is faster than store from XMM register) | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5981 instruct storeF0(memory mem, immF0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5982 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5983 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5984 match(Set mem (StoreF mem zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5985 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5986 ins_cost(25); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5987 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5988 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5989 __ movl($mem$$Address, r12); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5990 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5991 ins_pipe(ialu_mem_reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5992 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
5993 |
0 | 5994 instruct storeF_imm(memory mem, immF src) |
5995 %{ | |
5996 match(Set mem (StoreF mem src)); | |
5997 | |
5998 ins_cost(50); | |
5999 format %{ "movl $mem, $src\t# float" %} | |
6000 opcode(0xC7); /* C7 /0 */ | |
6001 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); | |
6002 ins_pipe(ialu_mem_imm); | |
6003 %} | |
6004 | |
6005 // Store Double | |
6006 instruct storeD(memory mem, regD src) | |
6007 %{ | |
6008 match(Set mem (StoreD mem src)); | |
6009 | |
6010 ins_cost(95); // XXX | |
6011 format %{ "movsd $mem, $src\t# double" %} | |
4759 | 6012 ins_encode %{ |
6013 __ movdbl($mem$$Address, $src$$XMMRegister); | |
6014 %} | |
0 | 6015 ins_pipe(pipe_slow); // XXX |
6016 %} | |
6017 | |
6018 // Store immediate double 0.0 (it is faster than store from XMM register) | |
6019 instruct storeD0_imm(memory mem, immD0 src) | |
6020 %{ | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6021 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); |
0 | 6022 match(Set mem (StoreD mem src)); |
6023 | |
6024 ins_cost(50); | |
6025 format %{ "movq $mem, $src\t# double 0." %} | |
6026 opcode(0xC7); /* C7 /0 */ | |
6027 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); | |
6028 ins_pipe(ialu_mem_imm); | |
6029 %} | |
6030 | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6031 instruct storeD0(memory mem, immD0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6032 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6033 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6034 match(Set mem (StoreD mem zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6035 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6036 ins_cost(25); // XXX |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6037 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6038 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6039 __ movq($mem$$Address, r12); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6040 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6041 ins_pipe(ialu_mem_reg); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6042 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6043 |
0 | 6044 instruct storeSSI(stackSlotI dst, rRegI src) |
6045 %{ | |
6046 match(Set dst src); | |
6047 | |
6048 ins_cost(100); | |
6049 format %{ "movl $dst, $src\t# int stk" %} | |
6050 opcode(0x89); | |
6051 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); | |
6052 ins_pipe( ialu_mem_reg ); | |
6053 %} | |
6054 | |
6055 instruct storeSSL(stackSlotL dst, rRegL src) | |
6056 %{ | |
6057 match(Set dst src); | |
6058 | |
6059 ins_cost(100); | |
6060 format %{ "movq $dst, $src\t# long stk" %} | |
6061 opcode(0x89); | |
6062 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); | |
6063 ins_pipe(ialu_mem_reg); | |
6064 %} | |
6065 | |
6066 instruct storeSSP(stackSlotP dst, rRegP src) | |
6067 %{ | |
6068 match(Set dst src); | |
6069 | |
6070 ins_cost(100); | |
6071 format %{ "movq $dst, $src\t# ptr stk" %} | |
6072 opcode(0x89); | |
6073 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); | |
6074 ins_pipe(ialu_mem_reg); | |
6075 %} | |
6076 | |
6077 instruct storeSSF(stackSlotF dst, regF src) | |
6078 %{ | |
6079 match(Set dst src); | |
6080 | |
6081 ins_cost(95); // XXX | |
6082 format %{ "movss $dst, $src\t# float stk" %} | |
4759 | 6083 ins_encode %{ |
6084 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); | |
6085 %} | |
0 | 6086 ins_pipe(pipe_slow); // XXX |
6087 %} | |
6088 | |
6089 instruct storeSSD(stackSlotD dst, regD src) | |
6090 %{ | |
6091 match(Set dst src); | |
6092 | |
6093 ins_cost(95); // XXX | |
6094 format %{ "movsd $dst, $src\t# double stk" %} | |
4759 | 6095 ins_encode %{ |
6096 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); | |
6097 %} | |
0 | 6098 ins_pipe(pipe_slow); // XXX |
6099 %} | |
6100 | |
6101 //----------BSWAP Instructions------------------------------------------------- | |
6102 instruct bytes_reverse_int(rRegI dst) %{ | |
6103 match(Set dst (ReverseBytesI dst)); | |
6104 | |
6105 format %{ "bswapl $dst" %} | |
6106 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ | |
6107 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); | |
6108 ins_pipe( ialu_reg ); | |
6109 %} | |
6110 | |
6111 instruct bytes_reverse_long(rRegL dst) %{ | |
6112 match(Set dst (ReverseBytesL dst)); | |
6113 | |
6114 format %{ "bswapq $dst" %} | |
6115 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ | |
6116 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); | |
6117 ins_pipe( ialu_reg); | |
6118 %} | |
6119 | |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6120 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6121 match(Set dst (ReverseBytesUS dst)); |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6122 effect(KILL cr); |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6123 |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
6124 format %{ "bswapl $dst\n\t" |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6125 "shrl $dst,16\n\t" %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6126 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6127 __ bswapl($dst$$Register); |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
6128 __ shrl($dst$$Register, 16); |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6129 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6130 ins_pipe( ialu_reg ); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6131 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6132 |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6133 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6134 match(Set dst (ReverseBytesS dst)); |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6135 effect(KILL cr); |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6136 |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
6137 format %{ "bswapl $dst\n\t" |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6138 "sar $dst,16\n\t" %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6139 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6140 __ bswapl($dst$$Register); |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
6141 __ sarl($dst$$Register, 16); |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6142 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6143 ins_pipe( ialu_reg ); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6144 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1274
diff
changeset
|
6145 |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6146 //---------- Zeros Count Instructions ------------------------------------------ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6147 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6148 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6149 predicate(UseCountLeadingZerosInstruction); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6150 match(Set dst (CountLeadingZerosI src)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6151 effect(KILL cr); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6152 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6153 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6154 ins_encode %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6155 __ lzcntl($dst$$Register, $src$$Register); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6156 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6157 ins_pipe(ialu_reg); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6158 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6159 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6160 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6161 predicate(!UseCountLeadingZerosInstruction); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6162 match(Set dst (CountLeadingZerosI src)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6163 effect(KILL cr); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6164 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6165 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6166 "jnz skip\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6167 "movl $dst, -1\n" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6168 "skip:\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6169 "negl $dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6170 "addl $dst, 31" %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6171 ins_encode %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6172 Register Rdst = $dst$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6173 Register Rsrc = $src$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6174 Label skip; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6175 __ bsrl(Rdst, Rsrc); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6176 __ jccb(Assembler::notZero, skip); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6177 __ movl(Rdst, -1); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6178 __ bind(skip); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6179 __ negl(Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6180 __ addl(Rdst, BitsPerInt - 1); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6181 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6182 ins_pipe(ialu_reg); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6183 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6184 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6185 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6186 predicate(UseCountLeadingZerosInstruction); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6187 match(Set dst (CountLeadingZerosL src)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6188 effect(KILL cr); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6189 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6190 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6191 ins_encode %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6192 __ lzcntq($dst$$Register, $src$$Register); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6193 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6194 ins_pipe(ialu_reg); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6195 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6196 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6197 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6198 predicate(!UseCountLeadingZerosInstruction); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6199 match(Set dst (CountLeadingZerosL src)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6200 effect(KILL cr); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6201 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6202 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6203 "jnz skip\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6204 "movl $dst, -1\n" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6205 "skip:\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6206 "negl $dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6207 "addl $dst, 63" %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6208 ins_encode %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6209 Register Rdst = $dst$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6210 Register Rsrc = $src$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6211 Label skip; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6212 __ bsrq(Rdst, Rsrc); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6213 __ jccb(Assembler::notZero, skip); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6214 __ movl(Rdst, -1); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6215 __ bind(skip); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6216 __ negl(Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6217 __ addl(Rdst, BitsPerLong - 1); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6218 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6219 ins_pipe(ialu_reg); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6220 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6221 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6222 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6223 match(Set dst (CountTrailingZerosI src)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6224 effect(KILL cr); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6225 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6226 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6227 "jnz done\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6228 "movl $dst, 32\n" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6229 "done:" %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6230 ins_encode %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6231 Register Rdst = $dst$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6232 Label done; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6233 __ bsfl(Rdst, $src$$Register); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6234 __ jccb(Assembler::notZero, done); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6235 __ movl(Rdst, BitsPerInt); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6236 __ bind(done); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6237 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6238 ins_pipe(ialu_reg); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6239 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6240 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6241 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6242 match(Set dst (CountTrailingZerosL src)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6243 effect(KILL cr); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6244 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6245 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6246 "jnz done\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6247 "movl $dst, 64\n" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6248 "done:" %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6249 ins_encode %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6250 Register Rdst = $dst$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6251 Label done; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6252 __ bsfq(Rdst, $src$$Register); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6253 __ jccb(Assembler::notZero, done); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6254 __ movl(Rdst, BitsPerLong); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6255 __ bind(done); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6256 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6257 ins_pipe(ialu_reg); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6258 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6259 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
681
diff
changeset
|
6260 |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6261 //---------- Population Count Instructions ------------------------------------- |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6262 |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6263 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6264 predicate(UsePopCountInstruction); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6265 match(Set dst (PopCountI src)); |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6266 effect(KILL cr); |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6267 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6268 format %{ "popcnt $dst, $src" %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6269 ins_encode %{ |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6270 __ popcntl($dst$$Register, $src$$Register); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6271 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6272 ins_pipe(ialu_reg); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6273 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6274 |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6275 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6276 predicate(UsePopCountInstruction); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6277 match(Set dst (PopCountI (LoadI mem))); |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6278 effect(KILL cr); |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6279 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6280 format %{ "popcnt $dst, $mem" %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6281 ins_encode %{ |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6282 __ popcntl($dst$$Register, $mem$$Address); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6283 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6284 ins_pipe(ialu_reg); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6285 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6286 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6287 // Note: Long.bitCount(long) returns an int. |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6288 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6289 predicate(UsePopCountInstruction); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6290 match(Set dst (PopCountL src)); |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6291 effect(KILL cr); |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6292 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6293 format %{ "popcnt $dst, $src" %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6294 ins_encode %{ |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6295 __ popcntq($dst$$Register, $src$$Register); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6296 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6297 ins_pipe(ialu_reg); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6298 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6299 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6300 // Note: Long.bitCount(long) returns an int. |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6301 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6302 predicate(UsePopCountInstruction); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6303 match(Set dst (PopCountL (LoadL mem))); |
6138
ccaa67adfe5b
7063674: Wrong results from basic comparisons after calls to Long.bitCount(long)
twisti
parents:
6084
diff
changeset
|
6304 effect(KILL cr); |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6305 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6306 format %{ "popcnt $dst, $mem" %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6307 ins_encode %{ |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6308 __ popcntq($dst$$Register, $mem$$Address); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6309 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6310 ins_pipe(ialu_reg); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6311 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6312 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
6313 |
0 | 6314 //----------MemBar Instructions----------------------------------------------- |
6315 // Memory barrier flavors | |
6316 | |
6317 instruct membar_acquire() | |
6318 %{ | |
6319 match(MemBarAcquire); | |
6320 ins_cost(0); | |
6321 | |
6322 size(0); | |
671
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6323 format %{ "MEMBAR-acquire ! (empty encoding)" %} |
0 | 6324 ins_encode(); |
6325 ins_pipe(empty); | |
6326 %} | |
6327 | |
6328 instruct membar_acquire_lock() | |
6329 %{ | |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3842
diff
changeset
|
6330 match(MemBarAcquireLock); |
0 | 6331 ins_cost(0); |
6332 | |
6333 size(0); | |
6334 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} | |
6335 ins_encode(); | |
6336 ins_pipe(empty); | |
6337 %} | |
6338 | |
6339 instruct membar_release() | |
6340 %{ | |
6341 match(MemBarRelease); | |
6342 ins_cost(0); | |
6343 | |
6344 size(0); | |
671
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6345 format %{ "MEMBAR-release ! (empty encoding)" %} |
0 | 6346 ins_encode(); |
6347 ins_pipe(empty); | |
6348 %} | |
6349 | |
6350 instruct membar_release_lock() | |
6351 %{ | |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3842
diff
changeset
|
6352 match(MemBarReleaseLock); |
0 | 6353 ins_cost(0); |
6354 | |
6355 size(0); | |
6356 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} | |
6357 ins_encode(); | |
6358 ins_pipe(empty); | |
6359 %} | |
6360 | |
671
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6361 instruct membar_volatile(rFlagsReg cr) %{ |
0 | 6362 match(MemBarVolatile); |
671
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6363 effect(KILL cr); |
0 | 6364 ins_cost(400); |
6365 | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
6366 format %{ |
671
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6367 $$template |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6368 if (os::is_MP()) { |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6369 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6370 } else { |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6371 $$emit$$"MEMBAR-volatile ! (empty encoding)" |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6372 } |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6373 %} |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6374 ins_encode %{ |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6375 __ membar(Assembler::StoreLoad); |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
647
diff
changeset
|
6376 %} |
0 | 6377 ins_pipe(pipe_slow); |
6378 %} | |
6379 | |
6380 instruct unnecessary_membar_volatile() | |
6381 %{ | |
6382 match(MemBarVolatile); | |
6383 predicate(Matcher::post_store_load_barrier(n)); | |
6384 ins_cost(0); | |
6385 | |
6386 size(0); | |
6387 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} | |
6388 ins_encode(); | |
6389 ins_pipe(empty); | |
6390 %} | |
6391 | |
4763
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
6392 instruct membar_storestore() %{ |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
6393 match(MemBarStoreStore); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
6394 ins_cost(0); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
6395 |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
6396 size(0); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
6397 format %{ "MEMBAR-storestore (empty encoding)" %} |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
6398 ins_encode( ); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
6399 ins_pipe(empty); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
6400 %} |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
6401 |
0 | 6402 //----------Move Instructions-------------------------------------------------- |
6403 | |
6404 instruct castX2P(rRegP dst, rRegL src) | |
6405 %{ | |
6406 match(Set dst (CastX2P src)); | |
6407 | |
6408 format %{ "movq $dst, $src\t# long->ptr" %} | |
4759 | 6409 ins_encode %{ |
6410 if ($dst$$reg != $src$$reg) { | |
6411 __ movptr($dst$$Register, $src$$Register); | |
6412 } | |
6413 %} | |
0 | 6414 ins_pipe(ialu_reg_reg); // XXX |
6415 %} | |
6416 | |
6417 instruct castP2X(rRegL dst, rRegP src) | |
6418 %{ | |
6419 match(Set dst (CastP2X src)); | |
6420 | |
6421 format %{ "movq $dst, $src\t# ptr -> long" %} | |
4759 | 6422 ins_encode %{ |
6423 if ($dst$$reg != $src$$reg) { | |
6424 __ movptr($dst$$Register, $src$$Register); | |
6425 } | |
6426 %} | |
0 | 6427 ins_pipe(ialu_reg_reg); // XXX |
6428 %} | |
6429 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6430 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6431 // Convert oop pointer into compressed form |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6432 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
182
diff
changeset
|
6433 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6434 match(Set dst (EncodeP src)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6435 effect(KILL cr); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6436 format %{ "encode_heap_oop $dst,$src" %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6437 ins_encode %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6438 Register s = $src$$Register; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6439 Register d = $dst$$Register; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6440 if (s != d) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6441 __ movq(d, s); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6442 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6443 __ encode_heap_oop(d); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6444 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6445 ins_pipe(ialu_reg_long); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6446 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6447 |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6448 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
182
diff
changeset
|
6449 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6450 match(Set dst (EncodeP src)); |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6451 effect(KILL cr); |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6452 format %{ "encode_heap_oop_not_null $dst,$src" %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6453 ins_encode %{ |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6454 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6455 %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6456 ins_pipe(ialu_reg_long); |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6457 %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6458 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6459 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
169
diff
changeset
|
6460 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
169
diff
changeset
|
6461 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6462 match(Set dst (DecodeN src)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6463 effect(KILL cr); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6464 format %{ "decode_heap_oop $dst,$src" %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6465 ins_encode %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6466 Register s = $src$$Register; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6467 Register d = $dst$$Register; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6468 if (s != d) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6469 __ movq(d, s); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6470 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6471 __ decode_heap_oop(d); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6472 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6473 ins_pipe(ialu_reg_long); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6474 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6475 |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
6476 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
169
diff
changeset
|
6477 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
169
diff
changeset
|
6478 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6479 match(Set dst (DecodeN src)); |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
6480 effect(KILL cr); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6481 format %{ "decode_heap_oop_not_null $dst,$src" %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6482 ins_encode %{ |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6483 Register s = $src$$Register; |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6484 Register d = $dst$$Register; |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6485 if (s != d) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6486 __ decode_heap_oop_not_null(d, s); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6487 } else { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6488 __ decode_heap_oop_not_null(d); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
6489 } |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6490 %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6491 ins_pipe(ialu_reg_long); |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6492 %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6493 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
6494 |
0 | 6495 //----------Conditional Move--------------------------------------------------- |
6496 // Jump | |
6497 // dummy instruction for generating temp registers | |
6498 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ | |
6499 match(Jump (LShiftL switch_val shift)); | |
6500 ins_cost(350); | |
6501 predicate(false); | |
6502 effect(TEMP dest); | |
6503 | |
2008 | 6504 format %{ "leaq $dest, [$constantaddress]\n\t" |
0 | 6505 "jmp [$dest + $switch_val << $shift]\n\t" %} |
2008 | 6506 ins_encode %{ |
6507 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 | |
6508 // to do that and the compiler is using that register as one it can allocate. | |
6509 // So we build it all by hand. | |
6510 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); | |
6511 // ArrayAddress dispatch(table, index); | |
6512 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); | |
6513 __ lea($dest$$Register, $constantaddress); | |
6514 __ jmp(dispatch); | |
6515 %} | |
0 | 6516 ins_pipe(pipe_jmp); |
6517 %} | |
6518 | |
6519 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ | |
6520 match(Jump (AddL (LShiftL switch_val shift) offset)); | |
6521 ins_cost(350); | |
6522 effect(TEMP dest); | |
6523 | |
2008 | 6524 format %{ "leaq $dest, [$constantaddress]\n\t" |
0 | 6525 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} |
2008 | 6526 ins_encode %{ |
6527 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 | |
6528 // to do that and the compiler is using that register as one it can allocate. | |
6529 // So we build it all by hand. | |
6530 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); | |
6531 // ArrayAddress dispatch(table, index); | |
6532 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); | |
6533 __ lea($dest$$Register, $constantaddress); | |
6534 __ jmp(dispatch); | |
6535 %} | |
0 | 6536 ins_pipe(pipe_jmp); |
6537 %} | |
6538 | |
6539 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ | |
6540 match(Jump switch_val); | |
6541 ins_cost(350); | |
6542 effect(TEMP dest); | |
6543 | |
2008 | 6544 format %{ "leaq $dest, [$constantaddress]\n\t" |
0 | 6545 "jmp [$dest + $switch_val]\n\t" %} |
2008 | 6546 ins_encode %{ |
6547 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 | |
6548 // to do that and the compiler is using that register as one it can allocate. | |
6549 // So we build it all by hand. | |
6550 // Address index(noreg, switch_reg, Address::times_1); | |
6551 // ArrayAddress dispatch(table, index); | |
6552 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); | |
6553 __ lea($dest$$Register, $constantaddress); | |
6554 __ jmp(dispatch); | |
6555 %} | |
0 | 6556 ins_pipe(pipe_jmp); |
6557 %} | |
6558 | |
6559 // Conditional move | |
6560 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) | |
6561 %{ | |
6562 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); | |
6563 | |
6564 ins_cost(200); // XXX | |
6565 format %{ "cmovl$cop $dst, $src\t# signed, int" %} | |
6566 opcode(0x0F, 0x40); | |
6567 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); | |
6568 ins_pipe(pipe_cmov_reg); | |
6569 %} | |
6570 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6571 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ |
0 | 6572 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); |
6573 | |
6574 ins_cost(200); // XXX | |
6575 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} | |
6576 opcode(0x0F, 0x40); | |
6577 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); | |
6578 ins_pipe(pipe_cmov_reg); | |
6579 %} | |
6580 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6581 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6582 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6583 ins_cost(200); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6584 expand %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6585 cmovI_regU(cop, cr, dst, src); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6586 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6587 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6588 |
0 | 6589 // Conditional move |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6590 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ |
0 | 6591 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); |
6592 | |
6593 ins_cost(250); // XXX | |
6594 format %{ "cmovl$cop $dst, $src\t# signed, int" %} | |
6595 opcode(0x0F, 0x40); | |
6596 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); | |
6597 ins_pipe(pipe_cmov_mem); | |
6598 %} | |
6599 | |
6600 // Conditional move | |
6601 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) | |
6602 %{ | |
6603 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); | |
6604 | |
6605 ins_cost(250); // XXX | |
6606 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} | |
6607 opcode(0x0F, 0x40); | |
6608 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); | |
6609 ins_pipe(pipe_cmov_mem); | |
6610 %} | |
6611 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6612 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6613 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6614 ins_cost(250); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6615 expand %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6616 cmovI_memU(cop, cr, dst, src); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6617 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6618 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6619 |
0 | 6620 // Conditional move |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6621 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6622 %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6623 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6624 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6625 ins_cost(200); // XXX |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6626 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6627 opcode(0x0F, 0x40); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6628 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6629 ins_pipe(pipe_cmov_reg); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6630 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6631 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6632 // Conditional move |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6633 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6634 %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6635 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6636 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6637 ins_cost(200); // XXX |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6638 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6639 opcode(0x0F, 0x40); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6640 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6641 ins_pipe(pipe_cmov_reg); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6642 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6643 |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6644 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6645 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6646 ins_cost(200); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6647 expand %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6648 cmovN_regU(cop, cr, dst, src); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6649 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6650 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6651 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6652 // Conditional move |
0 | 6653 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) |
6654 %{ | |
6655 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); | |
6656 | |
6657 ins_cost(200); // XXX | |
6658 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} | |
6659 opcode(0x0F, 0x40); | |
6660 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); | |
6661 ins_pipe(pipe_cmov_reg); // XXX | |
6662 %} | |
6663 | |
6664 // Conditional move | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6665 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) |
0 | 6666 %{ |
6667 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); | |
6668 | |
6669 ins_cost(200); // XXX | |
6670 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} | |
6671 opcode(0x0F, 0x40); | |
6672 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); | |
6673 ins_pipe(pipe_cmov_reg); // XXX | |
6674 %} | |
6675 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6676 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6677 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6678 ins_cost(200); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6679 expand %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6680 cmovP_regU(cop, cr, dst, src); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6681 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6682 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6683 |
0 | 6684 // DISABLED: Requires the ADLC to emit a bottom_type call that |
6685 // correctly meets the two pointer arguments; one is an incoming | |
6686 // register but the other is a memory operand. ALSO appears to | |
6687 // be buggy with implicit null checks. | |
6688 // | |
6689 //// Conditional move | |
6690 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) | |
6691 //%{ | |
6692 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); | |
6693 // ins_cost(250); | |
6694 // format %{ "CMOV$cop $dst,$src\t# ptr" %} | |
6695 // opcode(0x0F,0x40); | |
6696 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); | |
6697 // ins_pipe( pipe_cmov_mem ); | |
6698 //%} | |
6699 // | |
6700 //// Conditional move | |
6701 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) | |
6702 //%{ | |
6703 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); | |
6704 // ins_cost(250); | |
6705 // format %{ "CMOV$cop $dst,$src\t# ptr" %} | |
6706 // opcode(0x0F,0x40); | |
6707 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); | |
6708 // ins_pipe( pipe_cmov_mem ); | |
6709 //%} | |
6710 | |
6711 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) | |
6712 %{ | |
6713 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); | |
6714 | |
6715 ins_cost(200); // XXX | |
6716 format %{ "cmovq$cop $dst, $src\t# signed, long" %} | |
6717 opcode(0x0F, 0x40); | |
6718 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); | |
6719 ins_pipe(pipe_cmov_reg); // XXX | |
6720 %} | |
6721 | |
6722 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) | |
6723 %{ | |
6724 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); | |
6725 | |
6726 ins_cost(200); // XXX | |
6727 format %{ "cmovq$cop $dst, $src\t# signed, long" %} | |
6728 opcode(0x0F, 0x40); | |
6729 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); | |
6730 ins_pipe(pipe_cmov_mem); // XXX | |
6731 %} | |
6732 | |
6733 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) | |
6734 %{ | |
6735 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); | |
6736 | |
6737 ins_cost(200); // XXX | |
6738 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} | |
6739 opcode(0x0F, 0x40); | |
6740 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); | |
6741 ins_pipe(pipe_cmov_reg); // XXX | |
6742 %} | |
6743 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6744 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6745 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6746 ins_cost(200); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6747 expand %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6748 cmovL_regU(cop, cr, dst, src); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6749 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6750 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6751 |
0 | 6752 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) |
6753 %{ | |
6754 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); | |
6755 | |
6756 ins_cost(200); // XXX | |
6757 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} | |
6758 opcode(0x0F, 0x40); | |
6759 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); | |
6760 ins_pipe(pipe_cmov_mem); // XXX | |
6761 %} | |
6762 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6763 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6764 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6765 ins_cost(200); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6766 expand %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6767 cmovL_memU(cop, cr, dst, src); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6768 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6769 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6770 |
0 | 6771 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) |
6772 %{ | |
6773 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); | |
6774 | |
6775 ins_cost(200); // XXX | |
6776 format %{ "jn$cop skip\t# signed cmove float\n\t" | |
6777 "movss $dst, $src\n" | |
6778 "skip:" %} | |
4759 | 6779 ins_encode %{ |
6780 Label Lskip; | |
6781 // Invert sense of branch from sense of CMOV | |
6782 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); | |
6783 __ movflt($dst$$XMMRegister, $src$$XMMRegister); | |
6784 __ bind(Lskip); | |
6785 %} | |
0 | 6786 ins_pipe(pipe_slow); |
6787 %} | |
6788 | |
6789 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) | |
6790 // %{ | |
6791 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); | |
6792 | |
6793 // ins_cost(200); // XXX | |
6794 // format %{ "jn$cop skip\t# signed cmove float\n\t" | |
6795 // "movss $dst, $src\n" | |
6796 // "skip:" %} | |
6797 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); | |
6798 // ins_pipe(pipe_slow); | |
6799 // %} | |
6800 | |
6801 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) | |
6802 %{ | |
6803 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); | |
6804 | |
6805 ins_cost(200); // XXX | |
6806 format %{ "jn$cop skip\t# unsigned cmove float\n\t" | |
6807 "movss $dst, $src\n" | |
6808 "skip:" %} | |
4759 | 6809 ins_encode %{ |
6810 Label Lskip; | |
6811 // Invert sense of branch from sense of CMOV | |
6812 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); | |
6813 __ movflt($dst$$XMMRegister, $src$$XMMRegister); | |
6814 __ bind(Lskip); | |
6815 %} | |
0 | 6816 ins_pipe(pipe_slow); |
6817 %} | |
6818 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6819 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6820 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6821 ins_cost(200); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6822 expand %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6823 cmovF_regU(cop, cr, dst, src); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6824 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6825 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6826 |
0 | 6827 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) |
6828 %{ | |
6829 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); | |
6830 | |
6831 ins_cost(200); // XXX | |
6832 format %{ "jn$cop skip\t# signed cmove double\n\t" | |
6833 "movsd $dst, $src\n" | |
6834 "skip:" %} | |
4759 | 6835 ins_encode %{ |
6836 Label Lskip; | |
6837 // Invert sense of branch from sense of CMOV | |
6838 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); | |
6839 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); | |
6840 __ bind(Lskip); | |
6841 %} | |
0 | 6842 ins_pipe(pipe_slow); |
6843 %} | |
6844 | |
6845 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) | |
6846 %{ | |
6847 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); | |
6848 | |
6849 ins_cost(200); // XXX | |
6850 format %{ "jn$cop skip\t# unsigned cmove double\n\t" | |
6851 "movsd $dst, $src\n" | |
6852 "skip:" %} | |
4759 | 6853 ins_encode %{ |
6854 Label Lskip; | |
6855 // Invert sense of branch from sense of CMOV | |
6856 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); | |
6857 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); | |
6858 __ bind(Lskip); | |
6859 %} | |
0 | 6860 ins_pipe(pipe_slow); |
6861 %} | |
6862 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6863 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6864 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6865 ins_cost(200); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6866 expand %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6867 cmovD_regU(cop, cr, dst, src); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6868 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6869 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
6870 |
0 | 6871 //----------Arithmetic Instructions-------------------------------------------- |
6872 //----------Addition Instructions---------------------------------------------- | |
6873 | |
6874 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | |
6875 %{ | |
6876 match(Set dst (AddI dst src)); | |
6877 effect(KILL cr); | |
6878 | |
6879 format %{ "addl $dst, $src\t# int" %} | |
6880 opcode(0x03); | |
6881 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); | |
6882 ins_pipe(ialu_reg_reg); | |
6883 %} | |
6884 | |
6885 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) | |
6886 %{ | |
6887 match(Set dst (AddI dst src)); | |
6888 effect(KILL cr); | |
6889 | |
6890 format %{ "addl $dst, $src\t# int" %} | |
6891 opcode(0x81, 0x00); /* /0 id */ | |
6892 ins_encode(OpcSErm(dst, src), Con8or32(src)); | |
6893 ins_pipe( ialu_reg ); | |
6894 %} | |
6895 | |
6896 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) | |
6897 %{ | |
6898 match(Set dst (AddI dst (LoadI src))); | |
6899 effect(KILL cr); | |
6900 | |
6901 ins_cost(125); // XXX | |
6902 format %{ "addl $dst, $src\t# int" %} | |
6903 opcode(0x03); | |
6904 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); | |
6905 ins_pipe(ialu_reg_mem); | |
6906 %} | |
6907 | |
6908 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) | |
6909 %{ | |
6910 match(Set dst (StoreI dst (AddI (LoadI dst) src))); | |
6911 effect(KILL cr); | |
6912 | |
6913 ins_cost(150); // XXX | |
6914 format %{ "addl $dst, $src\t# int" %} | |
6915 opcode(0x01); /* Opcode 01 /r */ | |
6916 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); | |
6917 ins_pipe(ialu_mem_reg); | |
6918 %} | |
6919 | |
6920 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) | |
6921 %{ | |
6922 match(Set dst (StoreI dst (AddI (LoadI dst) src))); | |
6923 effect(KILL cr); | |
6924 | |
6925 ins_cost(125); // XXX | |
6926 format %{ "addl $dst, $src\t# int" %} | |
6927 opcode(0x81); /* Opcode 81 /0 id */ | |
6928 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); | |
6929 ins_pipe(ialu_mem_imm); | |
6930 %} | |
6931 | |
6932 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) | |
6933 %{ | |
6934 predicate(UseIncDec); | |
6935 match(Set dst (AddI dst src)); | |
6936 effect(KILL cr); | |
6937 | |
6938 format %{ "incl $dst\t# int" %} | |
6939 opcode(0xFF, 0x00); // FF /0 | |
6940 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
6941 ins_pipe(ialu_reg); | |
6942 %} | |
6943 | |
6944 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) | |
6945 %{ | |
6946 predicate(UseIncDec); | |
6947 match(Set dst (StoreI dst (AddI (LoadI dst) src))); | |
6948 effect(KILL cr); | |
6949 | |
6950 ins_cost(125); // XXX | |
6951 format %{ "incl $dst\t# int" %} | |
6952 opcode(0xFF); /* Opcode FF /0 */ | |
6953 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); | |
6954 ins_pipe(ialu_mem_imm); | |
6955 %} | |
6956 | |
6957 // XXX why does that use AddI | |
6958 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) | |
6959 %{ | |
6960 predicate(UseIncDec); | |
6961 match(Set dst (AddI dst src)); | |
6962 effect(KILL cr); | |
6963 | |
6964 format %{ "decl $dst\t# int" %} | |
6965 opcode(0xFF, 0x01); // FF /1 | |
6966 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
6967 ins_pipe(ialu_reg); | |
6968 %} | |
6969 | |
6970 // XXX why does that use AddI | |
6971 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) | |
6972 %{ | |
6973 predicate(UseIncDec); | |
6974 match(Set dst (StoreI dst (AddI (LoadI dst) src))); | |
6975 effect(KILL cr); | |
6976 | |
6977 ins_cost(125); // XXX | |
6978 format %{ "decl $dst\t# int" %} | |
6979 opcode(0xFF); /* Opcode FF /1 */ | |
6980 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); | |
6981 ins_pipe(ialu_mem_imm); | |
6982 %} | |
6983 | |
6984 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) | |
6985 %{ | |
6986 match(Set dst (AddI src0 src1)); | |
6987 | |
6988 ins_cost(110); | |
6989 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} | |
6990 opcode(0x8D); /* 0x8D /r */ | |
6991 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX | |
6992 ins_pipe(ialu_reg_reg); | |
6993 %} | |
6994 | |
6995 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) | |
6996 %{ | |
6997 match(Set dst (AddL dst src)); | |
6998 effect(KILL cr); | |
6999 | |
7000 format %{ "addq $dst, $src\t# long" %} | |
7001 opcode(0x03); | |
7002 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); | |
7003 ins_pipe(ialu_reg_reg); | |
7004 %} | |
7005 | |
7006 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) | |
7007 %{ | |
7008 match(Set dst (AddL dst src)); | |
7009 effect(KILL cr); | |
7010 | |
7011 format %{ "addq $dst, $src\t# long" %} | |
7012 opcode(0x81, 0x00); /* /0 id */ | |
7013 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); | |
7014 ins_pipe( ialu_reg ); | |
7015 %} | |
7016 | |
7017 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) | |
7018 %{ | |
7019 match(Set dst (AddL dst (LoadL src))); | |
7020 effect(KILL cr); | |
7021 | |
7022 ins_cost(125); // XXX | |
7023 format %{ "addq $dst, $src\t# long" %} | |
7024 opcode(0x03); | |
7025 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); | |
7026 ins_pipe(ialu_reg_mem); | |
7027 %} | |
7028 | |
7029 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) | |
7030 %{ | |
7031 match(Set dst (StoreL dst (AddL (LoadL dst) src))); | |
7032 effect(KILL cr); | |
7033 | |
7034 ins_cost(150); // XXX | |
7035 format %{ "addq $dst, $src\t# long" %} | |
7036 opcode(0x01); /* Opcode 01 /r */ | |
7037 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); | |
7038 ins_pipe(ialu_mem_reg); | |
7039 %} | |
7040 | |
7041 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) | |
7042 %{ | |
7043 match(Set dst (StoreL dst (AddL (LoadL dst) src))); | |
7044 effect(KILL cr); | |
7045 | |
7046 ins_cost(125); // XXX | |
7047 format %{ "addq $dst, $src\t# long" %} | |
7048 opcode(0x81); /* Opcode 81 /0 id */ | |
7049 ins_encode(REX_mem_wide(dst), | |
7050 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); | |
7051 ins_pipe(ialu_mem_imm); | |
7052 %} | |
7053 | |
7054 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) | |
7055 %{ | |
7056 predicate(UseIncDec); | |
7057 match(Set dst (AddL dst src)); | |
7058 effect(KILL cr); | |
7059 | |
7060 format %{ "incq $dst\t# long" %} | |
7061 opcode(0xFF, 0x00); // FF /0 | |
7062 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
7063 ins_pipe(ialu_reg); | |
7064 %} | |
7065 | |
7066 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) | |
7067 %{ | |
7068 predicate(UseIncDec); | |
7069 match(Set dst (StoreL dst (AddL (LoadL dst) src))); | |
7070 effect(KILL cr); | |
7071 | |
7072 ins_cost(125); // XXX | |
7073 format %{ "incq $dst\t# long" %} | |
7074 opcode(0xFF); /* Opcode FF /0 */ | |
7075 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); | |
7076 ins_pipe(ialu_mem_imm); | |
7077 %} | |
7078 | |
7079 // XXX why does that use AddL | |
7080 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) | |
7081 %{ | |
7082 predicate(UseIncDec); | |
7083 match(Set dst (AddL dst src)); | |
7084 effect(KILL cr); | |
7085 | |
7086 format %{ "decq $dst\t# long" %} | |
7087 opcode(0xFF, 0x01); // FF /1 | |
7088 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
7089 ins_pipe(ialu_reg); | |
7090 %} | |
7091 | |
7092 // XXX why does that use AddL | |
7093 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) | |
7094 %{ | |
7095 predicate(UseIncDec); | |
7096 match(Set dst (StoreL dst (AddL (LoadL dst) src))); | |
7097 effect(KILL cr); | |
7098 | |
7099 ins_cost(125); // XXX | |
7100 format %{ "decq $dst\t# long" %} | |
7101 opcode(0xFF); /* Opcode FF /1 */ | |
7102 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); | |
7103 ins_pipe(ialu_mem_imm); | |
7104 %} | |
7105 | |
7106 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) | |
7107 %{ | |
7108 match(Set dst (AddL src0 src1)); | |
7109 | |
7110 ins_cost(110); | |
7111 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} | |
7112 opcode(0x8D); /* 0x8D /r */ | |
7113 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX | |
7114 ins_pipe(ialu_reg_reg); | |
7115 %} | |
7116 | |
7117 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) | |
7118 %{ | |
7119 match(Set dst (AddP dst src)); | |
7120 effect(KILL cr); | |
7121 | |
7122 format %{ "addq $dst, $src\t# ptr" %} | |
7123 opcode(0x03); | |
7124 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); | |
7125 ins_pipe(ialu_reg_reg); | |
7126 %} | |
7127 | |
7128 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) | |
7129 %{ | |
7130 match(Set dst (AddP dst src)); | |
7131 effect(KILL cr); | |
7132 | |
7133 format %{ "addq $dst, $src\t# ptr" %} | |
7134 opcode(0x81, 0x00); /* /0 id */ | |
7135 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); | |
7136 ins_pipe( ialu_reg ); | |
7137 %} | |
7138 | |
7139 // XXX addP mem ops ???? | |
7140 | |
7141 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) | |
7142 %{ | |
7143 match(Set dst (AddP src0 src1)); | |
7144 | |
7145 ins_cost(110); | |
7146 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} | |
7147 opcode(0x8D); /* 0x8D /r */ | |
7148 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX | |
7149 ins_pipe(ialu_reg_reg); | |
7150 %} | |
7151 | |
7152 instruct checkCastPP(rRegP dst) | |
7153 %{ | |
7154 match(Set dst (CheckCastPP dst)); | |
7155 | |
7156 size(0); | |
7157 format %{ "# checkcastPP of $dst" %} | |
7158 ins_encode(/* empty encoding */); | |
7159 ins_pipe(empty); | |
7160 %} | |
7161 | |
7162 instruct castPP(rRegP dst) | |
7163 %{ | |
7164 match(Set dst (CastPP dst)); | |
7165 | |
7166 size(0); | |
7167 format %{ "# castPP of $dst" %} | |
7168 ins_encode(/* empty encoding */); | |
7169 ins_pipe(empty); | |
7170 %} | |
7171 | |
7172 instruct castII(rRegI dst) | |
7173 %{ | |
7174 match(Set dst (CastII dst)); | |
7175 | |
7176 size(0); | |
7177 format %{ "# castII of $dst" %} | |
7178 ins_encode(/* empty encoding */); | |
7179 ins_cost(0); | |
7180 ins_pipe(empty); | |
7181 %} | |
7182 | |
7183 // LoadP-locked same as a regular LoadP when used with compare-swap | |
7184 instruct loadPLocked(rRegP dst, memory mem) | |
7185 %{ | |
7186 match(Set dst (LoadPLocked mem)); | |
7187 | |
7188 ins_cost(125); // XXX | |
7189 format %{ "movq $dst, $mem\t# ptr locked" %} | |
7190 opcode(0x8B); | |
7191 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | |
7192 ins_pipe(ialu_reg_mem); // XXX | |
7193 %} | |
7194 | |
7195 // Conditional-store of the updated heap-top. | |
7196 // Used during allocation of the shared heap. | |
7197 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. | |
7198 | |
7199 instruct storePConditional(memory heap_top_ptr, | |
7200 rax_RegP oldval, rRegP newval, | |
7201 rFlagsReg cr) | |
7202 %{ | |
7203 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
7204 |
0 | 7205 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " |
7206 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} | |
7207 opcode(0x0F, 0xB1); | |
7208 ins_encode(lock_prefix, | |
7209 REX_reg_mem_wide(newval, heap_top_ptr), | |
7210 OpcP, OpcS, | |
7211 reg_mem(newval, heap_top_ptr)); | |
7212 ins_pipe(pipe_cmpxchg); | |
7213 %} | |
7214 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7215 // Conditional-store of an int value. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7216 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7217 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7218 %{ |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7219 match(Set cr (StoreIConditional mem (Binary oldval newval))); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7220 effect(KILL oldval); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7221 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7222 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} |
0 | 7223 opcode(0x0F, 0xB1); |
7224 ins_encode(lock_prefix, | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7225 REX_reg_mem(newval, mem), |
0 | 7226 OpcP, OpcS, |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7227 reg_mem(newval, mem)); |
0 | 7228 ins_pipe(pipe_cmpxchg); |
7229 %} | |
7230 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7231 // Conditional-store of a long value. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7232 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7233 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7234 %{ |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7235 match(Set cr (StoreLConditional mem (Binary oldval newval))); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7236 effect(KILL oldval); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7237 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7238 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} |
0 | 7239 opcode(0x0F, 0xB1); |
7240 ins_encode(lock_prefix, | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7241 REX_reg_mem_wide(newval, mem), |
0 | 7242 OpcP, OpcS, |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7243 reg_mem(newval, mem)); |
0 | 7244 ins_pipe(pipe_cmpxchg); |
7245 %} | |
7246 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7247 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7248 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them |
0 | 7249 instruct compareAndSwapP(rRegI res, |
7250 memory mem_ptr, | |
7251 rax_RegP oldval, rRegP newval, | |
7252 rFlagsReg cr) | |
7253 %{ | |
7254 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); | |
7255 effect(KILL cr, KILL oldval); | |
7256 | |
7257 format %{ "cmpxchgq $mem_ptr,$newval\t# " | |
7258 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" | |
7259 "sete $res\n\t" | |
7260 "movzbl $res, $res" %} | |
7261 opcode(0x0F, 0xB1); | |
7262 ins_encode(lock_prefix, | |
7263 REX_reg_mem_wide(newval, mem_ptr), | |
7264 OpcP, OpcS, | |
7265 reg_mem(newval, mem_ptr), | |
7266 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete | |
7267 REX_reg_breg(res, res), // movzbl | |
7268 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); | |
7269 ins_pipe( pipe_cmpxchg ); | |
7270 %} | |
7271 | |
7272 instruct compareAndSwapL(rRegI res, | |
7273 memory mem_ptr, | |
7274 rax_RegL oldval, rRegL newval, | |
7275 rFlagsReg cr) | |
7276 %{ | |
7277 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); | |
7278 effect(KILL cr, KILL oldval); | |
7279 | |
7280 format %{ "cmpxchgq $mem_ptr,$newval\t# " | |
7281 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" | |
7282 "sete $res\n\t" | |
7283 "movzbl $res, $res" %} | |
7284 opcode(0x0F, 0xB1); | |
7285 ins_encode(lock_prefix, | |
7286 REX_reg_mem_wide(newval, mem_ptr), | |
7287 OpcP, OpcS, | |
7288 reg_mem(newval, mem_ptr), | |
7289 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete | |
7290 REX_reg_breg(res, res), // movzbl | |
7291 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); | |
7292 ins_pipe( pipe_cmpxchg ); | |
7293 %} | |
7294 | |
7295 instruct compareAndSwapI(rRegI res, | |
7296 memory mem_ptr, | |
7297 rax_RegI oldval, rRegI newval, | |
7298 rFlagsReg cr) | |
7299 %{ | |
7300 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); | |
7301 effect(KILL cr, KILL oldval); | |
7302 | |
7303 format %{ "cmpxchgl $mem_ptr,$newval\t# " | |
7304 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" | |
7305 "sete $res\n\t" | |
7306 "movzbl $res, $res" %} | |
7307 opcode(0x0F, 0xB1); | |
7308 ins_encode(lock_prefix, | |
7309 REX_reg_mem(newval, mem_ptr), | |
7310 OpcP, OpcS, | |
7311 reg_mem(newval, mem_ptr), | |
7312 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete | |
7313 REX_reg_breg(res, res), // movzbl | |
7314 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); | |
7315 ins_pipe( pipe_cmpxchg ); | |
7316 %} | |
7317 | |
7318 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7319 instruct compareAndSwapN(rRegI res, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7320 memory mem_ptr, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7321 rax_RegN oldval, rRegN newval, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7322 rFlagsReg cr) %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7323 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7324 effect(KILL cr, KILL oldval); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7325 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7326 format %{ "cmpxchgl $mem_ptr,$newval\t# " |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7327 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7328 "sete $res\n\t" |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7329 "movzbl $res, $res" %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7330 opcode(0x0F, 0xB1); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7331 ins_encode(lock_prefix, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7332 REX_reg_mem(newval, mem_ptr), |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7333 OpcP, OpcS, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7334 reg_mem(newval, mem_ptr), |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7335 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7336 REX_reg_breg(res, res), // movzbl |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7337 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7338 ins_pipe( pipe_cmpxchg ); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7339 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
7340 |
0 | 7341 //----------Subtraction Instructions------------------------------------------- |
7342 | |
7343 // Integer Subtraction Instructions | |
7344 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | |
7345 %{ | |
7346 match(Set dst (SubI dst src)); | |
7347 effect(KILL cr); | |
7348 | |
7349 format %{ "subl $dst, $src\t# int" %} | |
7350 opcode(0x2B); | |
7351 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); | |
7352 ins_pipe(ialu_reg_reg); | |
7353 %} | |
7354 | |
7355 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) | |
7356 %{ | |
7357 match(Set dst (SubI dst src)); | |
7358 effect(KILL cr); | |
7359 | |
7360 format %{ "subl $dst, $src\t# int" %} | |
7361 opcode(0x81, 0x05); /* Opcode 81 /5 */ | |
7362 ins_encode(OpcSErm(dst, src), Con8or32(src)); | |
7363 ins_pipe(ialu_reg); | |
7364 %} | |
7365 | |
7366 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) | |
7367 %{ | |
7368 match(Set dst (SubI dst (LoadI src))); | |
7369 effect(KILL cr); | |
7370 | |
7371 ins_cost(125); | |
7372 format %{ "subl $dst, $src\t# int" %} | |
7373 opcode(0x2B); | |
7374 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); | |
7375 ins_pipe(ialu_reg_mem); | |
7376 %} | |
7377 | |
7378 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) | |
7379 %{ | |
7380 match(Set dst (StoreI dst (SubI (LoadI dst) src))); | |
7381 effect(KILL cr); | |
7382 | |
7383 ins_cost(150); | |
7384 format %{ "subl $dst, $src\t# int" %} | |
7385 opcode(0x29); /* Opcode 29 /r */ | |
7386 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); | |
7387 ins_pipe(ialu_mem_reg); | |
7388 %} | |
7389 | |
7390 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) | |
7391 %{ | |
7392 match(Set dst (StoreI dst (SubI (LoadI dst) src))); | |
7393 effect(KILL cr); | |
7394 | |
7395 ins_cost(125); // XXX | |
7396 format %{ "subl $dst, $src\t# int" %} | |
7397 opcode(0x81); /* Opcode 81 /5 id */ | |
7398 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); | |
7399 ins_pipe(ialu_mem_imm); | |
7400 %} | |
7401 | |
7402 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) | |
7403 %{ | |
7404 match(Set dst (SubL dst src)); | |
7405 effect(KILL cr); | |
7406 | |
7407 format %{ "subq $dst, $src\t# long" %} | |
7408 opcode(0x2B); | |
7409 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); | |
7410 ins_pipe(ialu_reg_reg); | |
7411 %} | |
7412 | |
7413 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) | |
7414 %{ | |
7415 match(Set dst (SubL dst src)); | |
7416 effect(KILL cr); | |
7417 | |
7418 format %{ "subq $dst, $src\t# long" %} | |
7419 opcode(0x81, 0x05); /* Opcode 81 /5 */ | |
7420 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); | |
7421 ins_pipe(ialu_reg); | |
7422 %} | |
7423 | |
7424 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) | |
7425 %{ | |
7426 match(Set dst (SubL dst (LoadL src))); | |
7427 effect(KILL cr); | |
7428 | |
7429 ins_cost(125); | |
7430 format %{ "subq $dst, $src\t# long" %} | |
7431 opcode(0x2B); | |
7432 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); | |
7433 ins_pipe(ialu_reg_mem); | |
7434 %} | |
7435 | |
7436 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) | |
7437 %{ | |
7438 match(Set dst (StoreL dst (SubL (LoadL dst) src))); | |
7439 effect(KILL cr); | |
7440 | |
7441 ins_cost(150); | |
7442 format %{ "subq $dst, $src\t# long" %} | |
7443 opcode(0x29); /* Opcode 29 /r */ | |
7444 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); | |
7445 ins_pipe(ialu_mem_reg); | |
7446 %} | |
7447 | |
7448 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) | |
7449 %{ | |
7450 match(Set dst (StoreL dst (SubL (LoadL dst) src))); | |
7451 effect(KILL cr); | |
7452 | |
7453 ins_cost(125); // XXX | |
7454 format %{ "subq $dst, $src\t# long" %} | |
7455 opcode(0x81); /* Opcode 81 /5 id */ | |
7456 ins_encode(REX_mem_wide(dst), | |
7457 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); | |
7458 ins_pipe(ialu_mem_imm); | |
7459 %} | |
7460 | |
7461 // Subtract from a pointer | |
7462 // XXX hmpf??? | |
7463 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) | |
7464 %{ | |
7465 match(Set dst (AddP dst (SubI zero src))); | |
7466 effect(KILL cr); | |
7467 | |
7468 format %{ "subq $dst, $src\t# ptr - int" %} | |
7469 opcode(0x2B); | |
7470 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); | |
7471 ins_pipe(ialu_reg_reg); | |
7472 %} | |
7473 | |
7474 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) | |
7475 %{ | |
7476 match(Set dst (SubI zero dst)); | |
7477 effect(KILL cr); | |
7478 | |
7479 format %{ "negl $dst\t# int" %} | |
7480 opcode(0xF7, 0x03); // Opcode F7 /3 | |
7481 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
7482 ins_pipe(ialu_reg); | |
7483 %} | |
7484 | |
7485 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) | |
7486 %{ | |
7487 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); | |
7488 effect(KILL cr); | |
7489 | |
7490 format %{ "negl $dst\t# int" %} | |
7491 opcode(0xF7, 0x03); // Opcode F7 /3 | |
7492 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); | |
7493 ins_pipe(ialu_reg); | |
7494 %} | |
7495 | |
7496 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) | |
7497 %{ | |
7498 match(Set dst (SubL zero dst)); | |
7499 effect(KILL cr); | |
7500 | |
7501 format %{ "negq $dst\t# long" %} | |
7502 opcode(0xF7, 0x03); // Opcode F7 /3 | |
7503 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
7504 ins_pipe(ialu_reg); | |
7505 %} | |
7506 | |
7507 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) | |
7508 %{ | |
7509 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); | |
7510 effect(KILL cr); | |
7511 | |
7512 format %{ "negq $dst\t# long" %} | |
7513 opcode(0xF7, 0x03); // Opcode F7 /3 | |
7514 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); | |
7515 ins_pipe(ialu_reg); | |
7516 %} | |
7517 | |
7518 | |
7519 //----------Multiplication/Division Instructions------------------------------- | |
7520 // Integer Multiplication Instructions | |
7521 // Multiply Register | |
7522 | |
7523 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | |
7524 %{ | |
7525 match(Set dst (MulI dst src)); | |
7526 effect(KILL cr); | |
7527 | |
7528 ins_cost(300); | |
7529 format %{ "imull $dst, $src\t# int" %} | |
7530 opcode(0x0F, 0xAF); | |
7531 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); | |
7532 ins_pipe(ialu_reg_reg_alu0); | |
7533 %} | |
7534 | |
7535 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) | |
7536 %{ | |
7537 match(Set dst (MulI src imm)); | |
7538 effect(KILL cr); | |
7539 | |
7540 ins_cost(300); | |
7541 format %{ "imull $dst, $src, $imm\t# int" %} | |
7542 opcode(0x69); /* 69 /r id */ | |
7543 ins_encode(REX_reg_reg(dst, src), | |
7544 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); | |
7545 ins_pipe(ialu_reg_reg_alu0); | |
7546 %} | |
7547 | |
7548 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) | |
7549 %{ | |
7550 match(Set dst (MulI dst (LoadI src))); | |
7551 effect(KILL cr); | |
7552 | |
7553 ins_cost(350); | |
7554 format %{ "imull $dst, $src\t# int" %} | |
7555 opcode(0x0F, 0xAF); | |
7556 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); | |
7557 ins_pipe(ialu_reg_mem_alu0); | |
7558 %} | |
7559 | |
7560 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) | |
7561 %{ | |
7562 match(Set dst (MulI (LoadI src) imm)); | |
7563 effect(KILL cr); | |
7564 | |
7565 ins_cost(300); | |
7566 format %{ "imull $dst, $src, $imm\t# int" %} | |
7567 opcode(0x69); /* 69 /r id */ | |
7568 ins_encode(REX_reg_mem(dst, src), | |
7569 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); | |
7570 ins_pipe(ialu_reg_mem_alu0); | |
7571 %} | |
7572 | |
7573 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) | |
7574 %{ | |
7575 match(Set dst (MulL dst src)); | |
7576 effect(KILL cr); | |
7577 | |
7578 ins_cost(300); | |
7579 format %{ "imulq $dst, $src\t# long" %} | |
7580 opcode(0x0F, 0xAF); | |
7581 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); | |
7582 ins_pipe(ialu_reg_reg_alu0); | |
7583 %} | |
7584 | |
7585 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) | |
7586 %{ | |
7587 match(Set dst (MulL src imm)); | |
7588 effect(KILL cr); | |
7589 | |
7590 ins_cost(300); | |
7591 format %{ "imulq $dst, $src, $imm\t# long" %} | |
7592 opcode(0x69); /* 69 /r id */ | |
7593 ins_encode(REX_reg_reg_wide(dst, src), | |
7594 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); | |
7595 ins_pipe(ialu_reg_reg_alu0); | |
7596 %} | |
7597 | |
7598 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) | |
7599 %{ | |
7600 match(Set dst (MulL dst (LoadL src))); | |
7601 effect(KILL cr); | |
7602 | |
7603 ins_cost(350); | |
7604 format %{ "imulq $dst, $src\t# long" %} | |
7605 opcode(0x0F, 0xAF); | |
7606 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); | |
7607 ins_pipe(ialu_reg_mem_alu0); | |
7608 %} | |
7609 | |
7610 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) | |
7611 %{ | |
7612 match(Set dst (MulL (LoadL src) imm)); | |
7613 effect(KILL cr); | |
7614 | |
7615 ins_cost(300); | |
7616 format %{ "imulq $dst, $src, $imm\t# long" %} | |
7617 opcode(0x69); /* 69 /r id */ | |
7618 ins_encode(REX_reg_mem_wide(dst, src), | |
7619 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); | |
7620 ins_pipe(ialu_reg_mem_alu0); | |
7621 %} | |
7622 | |
145 | 7623 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) |
7624 %{ | |
7625 match(Set dst (MulHiL src rax)); | |
7626 effect(USE_KILL rax, KILL cr); | |
7627 | |
7628 ins_cost(300); | |
7629 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} | |
7630 opcode(0xF7, 0x5); /* Opcode F7 /5 */ | |
7631 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); | |
7632 ins_pipe(ialu_reg_reg_alu0); | |
7633 %} | |
7634 | |
0 | 7635 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, |
7636 rFlagsReg cr) | |
7637 %{ | |
7638 match(Set rax (DivI rax div)); | |
7639 effect(KILL rdx, KILL cr); | |
7640 | |
7641 ins_cost(30*100+10*100); // XXX | |
7642 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" | |
7643 "jne,s normal\n\t" | |
7644 "xorl rdx, rdx\n\t" | |
7645 "cmpl $div, -1\n\t" | |
7646 "je,s done\n" | |
7647 "normal: cdql\n\t" | |
7648 "idivl $div\n" | |
7649 "done:" %} | |
7650 opcode(0xF7, 0x7); /* Opcode F7 /7 */ | |
7651 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); | |
7652 ins_pipe(ialu_reg_reg_alu0); | |
7653 %} | |
7654 | |
7655 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, | |
7656 rFlagsReg cr) | |
7657 %{ | |
7658 match(Set rax (DivL rax div)); | |
7659 effect(KILL rdx, KILL cr); | |
7660 | |
7661 ins_cost(30*100+10*100); // XXX | |
7662 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" | |
7663 "cmpq rax, rdx\n\t" | |
7664 "jne,s normal\n\t" | |
7665 "xorl rdx, rdx\n\t" | |
7666 "cmpq $div, -1\n\t" | |
7667 "je,s done\n" | |
7668 "normal: cdqq\n\t" | |
7669 "idivq $div\n" | |
7670 "done:" %} | |
7671 opcode(0xF7, 0x7); /* Opcode F7 /7 */ | |
7672 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); | |
7673 ins_pipe(ialu_reg_reg_alu0); | |
7674 %} | |
7675 | |
7676 // Integer DIVMOD with Register, both quotient and mod results | |
7677 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, | |
7678 rFlagsReg cr) | |
7679 %{ | |
7680 match(DivModI rax div); | |
7681 effect(KILL cr); | |
7682 | |
7683 ins_cost(30*100+10*100); // XXX | |
7684 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" | |
7685 "jne,s normal\n\t" | |
7686 "xorl rdx, rdx\n\t" | |
7687 "cmpl $div, -1\n\t" | |
7688 "je,s done\n" | |
7689 "normal: cdql\n\t" | |
7690 "idivl $div\n" | |
7691 "done:" %} | |
7692 opcode(0xF7, 0x7); /* Opcode F7 /7 */ | |
7693 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); | |
7694 ins_pipe(pipe_slow); | |
7695 %} | |
7696 | |
7697 // Long DIVMOD with Register, both quotient and mod results | |
7698 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, | |
7699 rFlagsReg cr) | |
7700 %{ | |
7701 match(DivModL rax div); | |
7702 effect(KILL cr); | |
7703 | |
7704 ins_cost(30*100+10*100); // XXX | |
7705 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" | |
7706 "cmpq rax, rdx\n\t" | |
7707 "jne,s normal\n\t" | |
7708 "xorl rdx, rdx\n\t" | |
7709 "cmpq $div, -1\n\t" | |
7710 "je,s done\n" | |
7711 "normal: cdqq\n\t" | |
7712 "idivq $div\n" | |
7713 "done:" %} | |
7714 opcode(0xF7, 0x7); /* Opcode F7 /7 */ | |
7715 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); | |
7716 ins_pipe(pipe_slow); | |
7717 %} | |
7718 | |
7719 //----------- DivL-By-Constant-Expansions-------------------------------------- | |
7720 // DivI cases are handled by the compiler | |
7721 | |
605 | 7722 // Magic constant, reciprocal of 10 |
0 | 7723 instruct loadConL_0x6666666666666667(rRegL dst) |
7724 %{ | |
7725 effect(DEF dst); | |
7726 | |
7727 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} | |
7728 ins_encode(load_immL(dst, 0x6666666666666667)); | |
7729 ins_pipe(ialu_reg); | |
7730 %} | |
7731 | |
7732 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) | |
7733 %{ | |
7734 effect(DEF dst, USE src, USE_KILL rax, KILL cr); | |
7735 | |
7736 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} | |
7737 opcode(0xF7, 0x5); /* Opcode F7 /5 */ | |
7738 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); | |
7739 ins_pipe(ialu_reg_reg_alu0); | |
7740 %} | |
7741 | |
7742 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) | |
7743 %{ | |
7744 effect(USE_DEF dst, KILL cr); | |
7745 | |
7746 format %{ "sarq $dst, #63\t# Used in div-by-10" %} | |
7747 opcode(0xC1, 0x7); /* C1 /7 ib */ | |
7748 ins_encode(reg_opc_imm_wide(dst, 0x3F)); | |
7749 ins_pipe(ialu_reg); | |
7750 %} | |
7751 | |
7752 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) | |
7753 %{ | |
7754 effect(USE_DEF dst, KILL cr); | |
7755 | |
7756 format %{ "sarq $dst, #2\t# Used in div-by-10" %} | |
7757 opcode(0xC1, 0x7); /* C1 /7 ib */ | |
7758 ins_encode(reg_opc_imm_wide(dst, 0x2)); | |
7759 ins_pipe(ialu_reg); | |
7760 %} | |
7761 | |
7762 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) | |
7763 %{ | |
7764 match(Set dst (DivL src div)); | |
7765 | |
7766 ins_cost((5+8)*100); | |
7767 expand %{ | |
7768 rax_RegL rax; // Killed temp | |
7769 rFlagsReg cr; // Killed | |
7770 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 | |
7771 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src | |
7772 sarL_rReg_63(src, cr); // sarq src, 63 | |
7773 sarL_rReg_2(dst, cr); // sarq rdx, 2 | |
7774 subL_rReg(dst, src, cr); // subl rdx, src | |
7775 %} | |
7776 %} | |
7777 | |
7778 //----------------------------------------------------------------------------- | |
7779 | |
7780 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, | |
7781 rFlagsReg cr) | |
7782 %{ | |
7783 match(Set rdx (ModI rax div)); | |
7784 effect(KILL rax, KILL cr); | |
7785 | |
7786 ins_cost(300); // XXX | |
7787 format %{ "cmpl rax, 0x80000000\t# irem\n\t" | |
7788 "jne,s normal\n\t" | |
7789 "xorl rdx, rdx\n\t" | |
7790 "cmpl $div, -1\n\t" | |
7791 "je,s done\n" | |
7792 "normal: cdql\n\t" | |
7793 "idivl $div\n" | |
7794 "done:" %} | |
7795 opcode(0xF7, 0x7); /* Opcode F7 /7 */ | |
7796 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); | |
7797 ins_pipe(ialu_reg_reg_alu0); | |
7798 %} | |
7799 | |
7800 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, | |
7801 rFlagsReg cr) | |
7802 %{ | |
7803 match(Set rdx (ModL rax div)); | |
7804 effect(KILL rax, KILL cr); | |
7805 | |
7806 ins_cost(300); // XXX | |
7807 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" | |
7808 "cmpq rax, rdx\n\t" | |
7809 "jne,s normal\n\t" | |
7810 "xorl rdx, rdx\n\t" | |
7811 "cmpq $div, -1\n\t" | |
7812 "je,s done\n" | |
7813 "normal: cdqq\n\t" | |
7814 "idivq $div\n" | |
7815 "done:" %} | |
7816 opcode(0xF7, 0x7); /* Opcode F7 /7 */ | |
7817 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); | |
7818 ins_pipe(ialu_reg_reg_alu0); | |
7819 %} | |
7820 | |
7821 // Integer Shift Instructions | |
7822 // Shift Left by one | |
7823 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) | |
7824 %{ | |
7825 match(Set dst (LShiftI dst shift)); | |
7826 effect(KILL cr); | |
7827 | |
7828 format %{ "sall $dst, $shift" %} | |
7829 opcode(0xD1, 0x4); /* D1 /4 */ | |
7830 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
7831 ins_pipe(ialu_reg); | |
7832 %} | |
7833 | |
7834 // Shift Left by one | |
7835 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) | |
7836 %{ | |
7837 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); | |
7838 effect(KILL cr); | |
7839 | |
7840 format %{ "sall $dst, $shift\t" %} | |
7841 opcode(0xD1, 0x4); /* D1 /4 */ | |
7842 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); | |
7843 ins_pipe(ialu_mem_imm); | |
7844 %} | |
7845 | |
7846 // Shift Left by 8-bit immediate | |
7847 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) | |
7848 %{ | |
7849 match(Set dst (LShiftI dst shift)); | |
7850 effect(KILL cr); | |
7851 | |
7852 format %{ "sall $dst, $shift" %} | |
7853 opcode(0xC1, 0x4); /* C1 /4 ib */ | |
7854 ins_encode(reg_opc_imm(dst, shift)); | |
7855 ins_pipe(ialu_reg); | |
7856 %} | |
7857 | |
7858 // Shift Left by 8-bit immediate | |
7859 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) | |
7860 %{ | |
7861 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); | |
7862 effect(KILL cr); | |
7863 | |
7864 format %{ "sall $dst, $shift" %} | |
7865 opcode(0xC1, 0x4); /* C1 /4 ib */ | |
7866 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); | |
7867 ins_pipe(ialu_mem_imm); | |
7868 %} | |
7869 | |
7870 // Shift Left by variable | |
7871 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) | |
7872 %{ | |
7873 match(Set dst (LShiftI dst shift)); | |
7874 effect(KILL cr); | |
7875 | |
7876 format %{ "sall $dst, $shift" %} | |
7877 opcode(0xD3, 0x4); /* D3 /4 */ | |
7878 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
7879 ins_pipe(ialu_reg_reg); | |
7880 %} | |
7881 | |
7882 // Shift Left by variable | |
7883 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) | |
7884 %{ | |
7885 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); | |
7886 effect(KILL cr); | |
7887 | |
7888 format %{ "sall $dst, $shift" %} | |
7889 opcode(0xD3, 0x4); /* D3 /4 */ | |
7890 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); | |
7891 ins_pipe(ialu_mem_reg); | |
7892 %} | |
7893 | |
7894 // Arithmetic shift right by one | |
7895 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) | |
7896 %{ | |
7897 match(Set dst (RShiftI dst shift)); | |
7898 effect(KILL cr); | |
7899 | |
7900 format %{ "sarl $dst, $shift" %} | |
7901 opcode(0xD1, 0x7); /* D1 /7 */ | |
7902 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
7903 ins_pipe(ialu_reg); | |
7904 %} | |
7905 | |
7906 // Arithmetic shift right by one | |
7907 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) | |
7908 %{ | |
7909 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); | |
7910 effect(KILL cr); | |
7911 | |
7912 format %{ "sarl $dst, $shift" %} | |
7913 opcode(0xD1, 0x7); /* D1 /7 */ | |
7914 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); | |
7915 ins_pipe(ialu_mem_imm); | |
7916 %} | |
7917 | |
7918 // Arithmetic Shift Right by 8-bit immediate | |
7919 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) | |
7920 %{ | |
7921 match(Set dst (RShiftI dst shift)); | |
7922 effect(KILL cr); | |
7923 | |
7924 format %{ "sarl $dst, $shift" %} | |
7925 opcode(0xC1, 0x7); /* C1 /7 ib */ | |
7926 ins_encode(reg_opc_imm(dst, shift)); | |
7927 ins_pipe(ialu_mem_imm); | |
7928 %} | |
7929 | |
7930 // Arithmetic Shift Right by 8-bit immediate | |
7931 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) | |
7932 %{ | |
7933 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); | |
7934 effect(KILL cr); | |
7935 | |
7936 format %{ "sarl $dst, $shift" %} | |
7937 opcode(0xC1, 0x7); /* C1 /7 ib */ | |
7938 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); | |
7939 ins_pipe(ialu_mem_imm); | |
7940 %} | |
7941 | |
7942 // Arithmetic Shift Right by variable | |
7943 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) | |
7944 %{ | |
7945 match(Set dst (RShiftI dst shift)); | |
7946 effect(KILL cr); | |
7947 | |
7948 format %{ "sarl $dst, $shift" %} | |
7949 opcode(0xD3, 0x7); /* D3 /7 */ | |
7950 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
7951 ins_pipe(ialu_reg_reg); | |
7952 %} | |
7953 | |
7954 // Arithmetic Shift Right by variable | |
7955 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) | |
7956 %{ | |
7957 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); | |
7958 effect(KILL cr); | |
7959 | |
7960 format %{ "sarl $dst, $shift" %} | |
7961 opcode(0xD3, 0x7); /* D3 /7 */ | |
7962 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); | |
7963 ins_pipe(ialu_mem_reg); | |
7964 %} | |
7965 | |
7966 // Logical shift right by one | |
7967 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) | |
7968 %{ | |
7969 match(Set dst (URShiftI dst shift)); | |
7970 effect(KILL cr); | |
7971 | |
7972 format %{ "shrl $dst, $shift" %} | |
7973 opcode(0xD1, 0x5); /* D1 /5 */ | |
7974 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
7975 ins_pipe(ialu_reg); | |
7976 %} | |
7977 | |
7978 // Logical shift right by one | |
7979 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) | |
7980 %{ | |
7981 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); | |
7982 effect(KILL cr); | |
7983 | |
7984 format %{ "shrl $dst, $shift" %} | |
7985 opcode(0xD1, 0x5); /* D1 /5 */ | |
7986 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); | |
7987 ins_pipe(ialu_mem_imm); | |
7988 %} | |
7989 | |
7990 // Logical Shift Right by 8-bit immediate | |
7991 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) | |
7992 %{ | |
7993 match(Set dst (URShiftI dst shift)); | |
7994 effect(KILL cr); | |
7995 | |
7996 format %{ "shrl $dst, $shift" %} | |
7997 opcode(0xC1, 0x5); /* C1 /5 ib */ | |
7998 ins_encode(reg_opc_imm(dst, shift)); | |
7999 ins_pipe(ialu_reg); | |
8000 %} | |
8001 | |
8002 // Logical Shift Right by 8-bit immediate | |
8003 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) | |
8004 %{ | |
8005 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); | |
8006 effect(KILL cr); | |
8007 | |
8008 format %{ "shrl $dst, $shift" %} | |
8009 opcode(0xC1, 0x5); /* C1 /5 ib */ | |
8010 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); | |
8011 ins_pipe(ialu_mem_imm); | |
8012 %} | |
8013 | |
8014 // Logical Shift Right by variable | |
8015 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) | |
8016 %{ | |
8017 match(Set dst (URShiftI dst shift)); | |
8018 effect(KILL cr); | |
8019 | |
8020 format %{ "shrl $dst, $shift" %} | |
8021 opcode(0xD3, 0x5); /* D3 /5 */ | |
8022 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
8023 ins_pipe(ialu_reg_reg); | |
8024 %} | |
8025 | |
8026 // Logical Shift Right by variable | |
8027 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) | |
8028 %{ | |
8029 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); | |
8030 effect(KILL cr); | |
8031 | |
8032 format %{ "shrl $dst, $shift" %} | |
8033 opcode(0xD3, 0x5); /* D3 /5 */ | |
8034 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); | |
8035 ins_pipe(ialu_mem_reg); | |
8036 %} | |
8037 | |
8038 // Long Shift Instructions | |
8039 // Shift Left by one | |
8040 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) | |
8041 %{ | |
8042 match(Set dst (LShiftL dst shift)); | |
8043 effect(KILL cr); | |
8044 | |
8045 format %{ "salq $dst, $shift" %} | |
8046 opcode(0xD1, 0x4); /* D1 /4 */ | |
8047 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
8048 ins_pipe(ialu_reg); | |
8049 %} | |
8050 | |
8051 // Shift Left by one | |
8052 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) | |
8053 %{ | |
8054 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); | |
8055 effect(KILL cr); | |
8056 | |
8057 format %{ "salq $dst, $shift" %} | |
8058 opcode(0xD1, 0x4); /* D1 /4 */ | |
8059 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); | |
8060 ins_pipe(ialu_mem_imm); | |
8061 %} | |
8062 | |
8063 // Shift Left by 8-bit immediate | |
8064 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) | |
8065 %{ | |
8066 match(Set dst (LShiftL dst shift)); | |
8067 effect(KILL cr); | |
8068 | |
8069 format %{ "salq $dst, $shift" %} | |
8070 opcode(0xC1, 0x4); /* C1 /4 ib */ | |
8071 ins_encode(reg_opc_imm_wide(dst, shift)); | |
8072 ins_pipe(ialu_reg); | |
8073 %} | |
8074 | |
8075 // Shift Left by 8-bit immediate | |
8076 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) | |
8077 %{ | |
8078 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); | |
8079 effect(KILL cr); | |
8080 | |
8081 format %{ "salq $dst, $shift" %} | |
8082 opcode(0xC1, 0x4); /* C1 /4 ib */ | |
8083 ins_encode(REX_mem_wide(dst), OpcP, | |
8084 RM_opc_mem(secondary, dst), Con8or32(shift)); | |
8085 ins_pipe(ialu_mem_imm); | |
8086 %} | |
8087 | |
8088 // Shift Left by variable | |
8089 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) | |
8090 %{ | |
8091 match(Set dst (LShiftL dst shift)); | |
8092 effect(KILL cr); | |
8093 | |
8094 format %{ "salq $dst, $shift" %} | |
8095 opcode(0xD3, 0x4); /* D3 /4 */ | |
8096 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
8097 ins_pipe(ialu_reg_reg); | |
8098 %} | |
8099 | |
8100 // Shift Left by variable | |
8101 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) | |
8102 %{ | |
8103 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); | |
8104 effect(KILL cr); | |
8105 | |
8106 format %{ "salq $dst, $shift" %} | |
8107 opcode(0xD3, 0x4); /* D3 /4 */ | |
8108 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); | |
8109 ins_pipe(ialu_mem_reg); | |
8110 %} | |
8111 | |
8112 // Arithmetic shift right by one | |
8113 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) | |
8114 %{ | |
8115 match(Set dst (RShiftL dst shift)); | |
8116 effect(KILL cr); | |
8117 | |
8118 format %{ "sarq $dst, $shift" %} | |
8119 opcode(0xD1, 0x7); /* D1 /7 */ | |
8120 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
8121 ins_pipe(ialu_reg); | |
8122 %} | |
8123 | |
8124 // Arithmetic shift right by one | |
8125 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) | |
8126 %{ | |
8127 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); | |
8128 effect(KILL cr); | |
8129 | |
8130 format %{ "sarq $dst, $shift" %} | |
8131 opcode(0xD1, 0x7); /* D1 /7 */ | |
8132 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); | |
8133 ins_pipe(ialu_mem_imm); | |
8134 %} | |
8135 | |
8136 // Arithmetic Shift Right by 8-bit immediate | |
8137 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) | |
8138 %{ | |
8139 match(Set dst (RShiftL dst shift)); | |
8140 effect(KILL cr); | |
8141 | |
8142 format %{ "sarq $dst, $shift" %} | |
8143 opcode(0xC1, 0x7); /* C1 /7 ib */ | |
8144 ins_encode(reg_opc_imm_wide(dst, shift)); | |
8145 ins_pipe(ialu_mem_imm); | |
8146 %} | |
8147 | |
8148 // Arithmetic Shift Right by 8-bit immediate | |
8149 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) | |
8150 %{ | |
8151 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); | |
8152 effect(KILL cr); | |
8153 | |
8154 format %{ "sarq $dst, $shift" %} | |
8155 opcode(0xC1, 0x7); /* C1 /7 ib */ | |
8156 ins_encode(REX_mem_wide(dst), OpcP, | |
8157 RM_opc_mem(secondary, dst), Con8or32(shift)); | |
8158 ins_pipe(ialu_mem_imm); | |
8159 %} | |
8160 | |
8161 // Arithmetic Shift Right by variable | |
8162 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) | |
8163 %{ | |
8164 match(Set dst (RShiftL dst shift)); | |
8165 effect(KILL cr); | |
8166 | |
8167 format %{ "sarq $dst, $shift" %} | |
8168 opcode(0xD3, 0x7); /* D3 /7 */ | |
8169 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
8170 ins_pipe(ialu_reg_reg); | |
8171 %} | |
8172 | |
8173 // Arithmetic Shift Right by variable | |
8174 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) | |
8175 %{ | |
8176 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); | |
8177 effect(KILL cr); | |
8178 | |
8179 format %{ "sarq $dst, $shift" %} | |
8180 opcode(0xD3, 0x7); /* D3 /7 */ | |
8181 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); | |
8182 ins_pipe(ialu_mem_reg); | |
8183 %} | |
8184 | |
8185 // Logical shift right by one | |
8186 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) | |
8187 %{ | |
8188 match(Set dst (URShiftL dst shift)); | |
8189 effect(KILL cr); | |
8190 | |
8191 format %{ "shrq $dst, $shift" %} | |
8192 opcode(0xD1, 0x5); /* D1 /5 */ | |
8193 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); | |
8194 ins_pipe(ialu_reg); | |
8195 %} | |
8196 | |
8197 // Logical shift right by one | |
8198 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) | |
8199 %{ | |
8200 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); | |
8201 effect(KILL cr); | |
8202 | |
8203 format %{ "shrq $dst, $shift" %} | |
8204 opcode(0xD1, 0x5); /* D1 /5 */ | |
8205 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); | |
8206 ins_pipe(ialu_mem_imm); | |
8207 %} | |
8208 | |
8209 // Logical Shift Right by 8-bit immediate | |
8210 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) | |
8211 %{ | |
8212 match(Set dst (URShiftL dst shift)); | |
8213 effect(KILL cr); | |
8214 | |
8215 format %{ "shrq $dst, $shift" %} | |
8216 opcode(0xC1, 0x5); /* C1 /5 ib */ | |
8217 ins_encode(reg_opc_imm_wide(dst, shift)); | |
8218 ins_pipe(ialu_reg); | |
8219 %} | |
8220 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8221 |
0 | 8222 // Logical Shift Right by 8-bit immediate |
8223 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) | |
8224 %{ | |
8225 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); | |
8226 effect(KILL cr); | |
8227 | |
8228 format %{ "shrq $dst, $shift" %} | |
8229 opcode(0xC1, 0x5); /* C1 /5 ib */ | |
8230 ins_encode(REX_mem_wide(dst), OpcP, | |
8231 RM_opc_mem(secondary, dst), Con8or32(shift)); | |
8232 ins_pipe(ialu_mem_imm); | |
8233 %} | |
8234 | |
8235 // Logical Shift Right by variable | |
8236 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) | |
8237 %{ | |
8238 match(Set dst (URShiftL dst shift)); | |
8239 effect(KILL cr); | |
8240 | |
8241 format %{ "shrq $dst, $shift" %} | |
8242 opcode(0xD3, 0x5); /* D3 /5 */ | |
8243 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
8244 ins_pipe(ialu_reg_reg); | |
8245 %} | |
8246 | |
8247 // Logical Shift Right by variable | |
8248 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) | |
8249 %{ | |
8250 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); | |
8251 effect(KILL cr); | |
8252 | |
8253 format %{ "shrq $dst, $shift" %} | |
8254 opcode(0xD3, 0x5); /* D3 /5 */ | |
8255 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); | |
8256 ins_pipe(ialu_mem_reg); | |
8257 %} | |
8258 | |
8259 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. | |
8260 // This idiom is used by the compiler for the i2b bytecode. | |
8261 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) | |
8262 %{ | |
8263 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); | |
8264 | |
8265 format %{ "movsbl $dst, $src\t# i2b" %} | |
8266 opcode(0x0F, 0xBE); | |
8267 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); | |
8268 ins_pipe(ialu_reg_reg); | |
8269 %} | |
8270 | |
8271 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. | |
8272 // This idiom is used by the compiler the i2s bytecode. | |
8273 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) | |
8274 %{ | |
8275 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); | |
8276 | |
8277 format %{ "movswl $dst, $src\t# i2s" %} | |
8278 opcode(0x0F, 0xBF); | |
8279 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); | |
8280 ins_pipe(ialu_reg_reg); | |
8281 %} | |
8282 | |
8283 // ROL/ROR instructions | |
8284 | |
8285 // ROL expand | |
8286 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ | |
8287 effect(KILL cr, USE_DEF dst); | |
8288 | |
8289 format %{ "roll $dst" %} | |
8290 opcode(0xD1, 0x0); /* Opcode D1 /0 */ | |
8291 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
8292 ins_pipe(ialu_reg); | |
8293 %} | |
8294 | |
8295 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ | |
8296 effect(USE_DEF dst, USE shift, KILL cr); | |
8297 | |
8298 format %{ "roll $dst, $shift" %} | |
8299 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ | |
8300 ins_encode( reg_opc_imm(dst, shift) ); | |
8301 ins_pipe(ialu_reg); | |
8302 %} | |
8303 | |
8304 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) | |
8305 %{ | |
8306 effect(USE_DEF dst, USE shift, KILL cr); | |
8307 | |
8308 format %{ "roll $dst, $shift" %} | |
8309 opcode(0xD3, 0x0); /* Opcode D3 /0 */ | |
8310 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
8311 ins_pipe(ialu_reg_reg); | |
8312 %} | |
8313 // end of ROL expand | |
8314 | |
8315 // Rotate Left by one | |
8316 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) | |
8317 %{ | |
8318 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); | |
8319 | |
8320 expand %{ | |
8321 rolI_rReg_imm1(dst, cr); | |
8322 %} | |
8323 %} | |
8324 | |
8325 // Rotate Left by 8-bit immediate | |
8326 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) | |
8327 %{ | |
8328 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); | |
8329 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); | |
8330 | |
8331 expand %{ | |
8332 rolI_rReg_imm8(dst, lshift, cr); | |
8333 %} | |
8334 %} | |
8335 | |
8336 // Rotate Left by variable | |
8337 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) | |
8338 %{ | |
8339 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); | |
8340 | |
8341 expand %{ | |
8342 rolI_rReg_CL(dst, shift, cr); | |
8343 %} | |
8344 %} | |
8345 | |
8346 // Rotate Left by variable | |
8347 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) | |
8348 %{ | |
8349 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); | |
8350 | |
8351 expand %{ | |
8352 rolI_rReg_CL(dst, shift, cr); | |
8353 %} | |
8354 %} | |
8355 | |
8356 // ROR expand | |
8357 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) | |
8358 %{ | |
8359 effect(USE_DEF dst, KILL cr); | |
8360 | |
8361 format %{ "rorl $dst" %} | |
8362 opcode(0xD1, 0x1); /* D1 /1 */ | |
8363 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
8364 ins_pipe(ialu_reg); | |
8365 %} | |
8366 | |
8367 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) | |
8368 %{ | |
8369 effect(USE_DEF dst, USE shift, KILL cr); | |
8370 | |
8371 format %{ "rorl $dst, $shift" %} | |
8372 opcode(0xC1, 0x1); /* C1 /1 ib */ | |
8373 ins_encode(reg_opc_imm(dst, shift)); | |
8374 ins_pipe(ialu_reg); | |
8375 %} | |
8376 | |
8377 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) | |
8378 %{ | |
8379 effect(USE_DEF dst, USE shift, KILL cr); | |
8380 | |
8381 format %{ "rorl $dst, $shift" %} | |
8382 opcode(0xD3, 0x1); /* D3 /1 */ | |
8383 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); | |
8384 ins_pipe(ialu_reg_reg); | |
8385 %} | |
8386 // end of ROR expand | |
8387 | |
8388 // Rotate Right by one | |
8389 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) | |
8390 %{ | |
8391 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); | |
8392 | |
8393 expand %{ | |
8394 rorI_rReg_imm1(dst, cr); | |
8395 %} | |
8396 %} | |
8397 | |
8398 // Rotate Right by 8-bit immediate | |
8399 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) | |
8400 %{ | |
8401 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); | |
8402 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); | |
8403 | |
8404 expand %{ | |
8405 rorI_rReg_imm8(dst, rshift, cr); | |
8406 %} | |
8407 %} | |
8408 | |
8409 // Rotate Right by variable | |
8410 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) | |
8411 %{ | |
8412 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); | |
8413 | |
8414 expand %{ | |
8415 rorI_rReg_CL(dst, shift, cr); | |
8416 %} | |
8417 %} | |
8418 | |
8419 // Rotate Right by variable | |
8420 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) | |
8421 %{ | |
8422 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); | |
8423 | |
8424 expand %{ | |
8425 rorI_rReg_CL(dst, shift, cr); | |
8426 %} | |
8427 %} | |
8428 | |
8429 // for long rotate | |
8430 // ROL expand | |
8431 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ | |
8432 effect(USE_DEF dst, KILL cr); | |
8433 | |
8434 format %{ "rolq $dst" %} | |
8435 opcode(0xD1, 0x0); /* Opcode D1 /0 */ | |
8436 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
8437 ins_pipe(ialu_reg); | |
8438 %} | |
8439 | |
8440 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ | |
8441 effect(USE_DEF dst, USE shift, KILL cr); | |
8442 | |
8443 format %{ "rolq $dst, $shift" %} | |
8444 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ | |
8445 ins_encode( reg_opc_imm_wide(dst, shift) ); | |
8446 ins_pipe(ialu_reg); | |
8447 %} | |
8448 | |
8449 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) | |
8450 %{ | |
8451 effect(USE_DEF dst, USE shift, KILL cr); | |
8452 | |
8453 format %{ "rolq $dst, $shift" %} | |
8454 opcode(0xD3, 0x0); /* Opcode D3 /0 */ | |
8455 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
8456 ins_pipe(ialu_reg_reg); | |
8457 %} | |
8458 // end of ROL expand | |
8459 | |
8460 // Rotate Left by one | |
8461 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) | |
8462 %{ | |
8463 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); | |
8464 | |
8465 expand %{ | |
8466 rolL_rReg_imm1(dst, cr); | |
8467 %} | |
8468 %} | |
8469 | |
8470 // Rotate Left by 8-bit immediate | |
8471 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) | |
8472 %{ | |
8473 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); | |
8474 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); | |
8475 | |
8476 expand %{ | |
8477 rolL_rReg_imm8(dst, lshift, cr); | |
8478 %} | |
8479 %} | |
8480 | |
8481 // Rotate Left by variable | |
8482 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) | |
8483 %{ | |
8484 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); | |
8485 | |
8486 expand %{ | |
8487 rolL_rReg_CL(dst, shift, cr); | |
8488 %} | |
8489 %} | |
8490 | |
8491 // Rotate Left by variable | |
8492 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) | |
8493 %{ | |
8494 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); | |
8495 | |
8496 expand %{ | |
8497 rolL_rReg_CL(dst, shift, cr); | |
8498 %} | |
8499 %} | |
8500 | |
8501 // ROR expand | |
8502 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) | |
8503 %{ | |
8504 effect(USE_DEF dst, KILL cr); | |
8505 | |
8506 format %{ "rorq $dst" %} | |
8507 opcode(0xD1, 0x1); /* D1 /1 */ | |
8508 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
8509 ins_pipe(ialu_reg); | |
8510 %} | |
8511 | |
8512 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) | |
8513 %{ | |
8514 effect(USE_DEF dst, USE shift, KILL cr); | |
8515 | |
8516 format %{ "rorq $dst, $shift" %} | |
8517 opcode(0xC1, 0x1); /* C1 /1 ib */ | |
8518 ins_encode(reg_opc_imm_wide(dst, shift)); | |
8519 ins_pipe(ialu_reg); | |
8520 %} | |
8521 | |
8522 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) | |
8523 %{ | |
8524 effect(USE_DEF dst, USE shift, KILL cr); | |
8525 | |
8526 format %{ "rorq $dst, $shift" %} | |
8527 opcode(0xD3, 0x1); /* D3 /1 */ | |
8528 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); | |
8529 ins_pipe(ialu_reg_reg); | |
8530 %} | |
8531 // end of ROR expand | |
8532 | |
8533 // Rotate Right by one | |
8534 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) | |
8535 %{ | |
8536 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); | |
8537 | |
8538 expand %{ | |
8539 rorL_rReg_imm1(dst, cr); | |
8540 %} | |
8541 %} | |
8542 | |
8543 // Rotate Right by 8-bit immediate | |
8544 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) | |
8545 %{ | |
8546 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); | |
8547 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); | |
8548 | |
8549 expand %{ | |
8550 rorL_rReg_imm8(dst, rshift, cr); | |
8551 %} | |
8552 %} | |
8553 | |
8554 // Rotate Right by variable | |
8555 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) | |
8556 %{ | |
8557 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); | |
8558 | |
8559 expand %{ | |
8560 rorL_rReg_CL(dst, shift, cr); | |
8561 %} | |
8562 %} | |
8563 | |
8564 // Rotate Right by variable | |
8565 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) | |
8566 %{ | |
8567 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); | |
8568 | |
8569 expand %{ | |
8570 rorL_rReg_CL(dst, shift, cr); | |
8571 %} | |
8572 %} | |
8573 | |
8574 // Logical Instructions | |
8575 | |
8576 // Integer Logical Instructions | |
8577 | |
8578 // And Instructions | |
8579 // And Register with Register | |
8580 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | |
8581 %{ | |
8582 match(Set dst (AndI dst src)); | |
8583 effect(KILL cr); | |
8584 | |
8585 format %{ "andl $dst, $src\t# int" %} | |
8586 opcode(0x23); | |
8587 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); | |
8588 ins_pipe(ialu_reg_reg); | |
8589 %} | |
8590 | |
8591 // And Register with Immediate 255 | |
8592 instruct andI_rReg_imm255(rRegI dst, immI_255 src) | |
8593 %{ | |
8594 match(Set dst (AndI dst src)); | |
8595 | |
8596 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} | |
8597 opcode(0x0F, 0xB6); | |
8598 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); | |
8599 ins_pipe(ialu_reg); | |
8600 %} | |
8601 | |
8602 // And Register with Immediate 255 and promote to long | |
8603 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) | |
8604 %{ | |
8605 match(Set dst (ConvI2L (AndI src mask))); | |
8606 | |
8607 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} | |
8608 opcode(0x0F, 0xB6); | |
8609 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); | |
8610 ins_pipe(ialu_reg); | |
8611 %} | |
8612 | |
8613 // And Register with Immediate 65535 | |
8614 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) | |
8615 %{ | |
8616 match(Set dst (AndI dst src)); | |
8617 | |
8618 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} | |
8619 opcode(0x0F, 0xB7); | |
8620 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); | |
8621 ins_pipe(ialu_reg); | |
8622 %} | |
8623 | |
8624 // And Register with Immediate 65535 and promote to long | |
8625 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) | |
8626 %{ | |
8627 match(Set dst (ConvI2L (AndI src mask))); | |
8628 | |
8629 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} | |
8630 opcode(0x0F, 0xB7); | |
8631 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); | |
8632 ins_pipe(ialu_reg); | |
8633 %} | |
8634 | |
8635 // And Register with Immediate | |
8636 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) | |
8637 %{ | |
8638 match(Set dst (AndI dst src)); | |
8639 effect(KILL cr); | |
8640 | |
8641 format %{ "andl $dst, $src\t# int" %} | |
8642 opcode(0x81, 0x04); /* Opcode 81 /4 */ | |
8643 ins_encode(OpcSErm(dst, src), Con8or32(src)); | |
8644 ins_pipe(ialu_reg); | |
8645 %} | |
8646 | |
8647 // And Register with Memory | |
8648 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) | |
8649 %{ | |
8650 match(Set dst (AndI dst (LoadI src))); | |
8651 effect(KILL cr); | |
8652 | |
8653 ins_cost(125); | |
8654 format %{ "andl $dst, $src\t# int" %} | |
8655 opcode(0x23); | |
8656 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); | |
8657 ins_pipe(ialu_reg_mem); | |
8658 %} | |
8659 | |
8660 // And Memory with Register | |
8661 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) | |
8662 %{ | |
8663 match(Set dst (StoreI dst (AndI (LoadI dst) src))); | |
8664 effect(KILL cr); | |
8665 | |
8666 ins_cost(150); | |
8667 format %{ "andl $dst, $src\t# int" %} | |
8668 opcode(0x21); /* Opcode 21 /r */ | |
8669 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); | |
8670 ins_pipe(ialu_mem_reg); | |
8671 %} | |
8672 | |
8673 // And Memory with Immediate | |
8674 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) | |
8675 %{ | |
8676 match(Set dst (StoreI dst (AndI (LoadI dst) src))); | |
8677 effect(KILL cr); | |
8678 | |
8679 ins_cost(125); | |
8680 format %{ "andl $dst, $src\t# int" %} | |
8681 opcode(0x81, 0x4); /* Opcode 81 /4 id */ | |
8682 ins_encode(REX_mem(dst), OpcSE(src), | |
8683 RM_opc_mem(secondary, dst), Con8or32(src)); | |
8684 ins_pipe(ialu_mem_imm); | |
8685 %} | |
8686 | |
8687 // Or Instructions | |
8688 // Or Register with Register | |
8689 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | |
8690 %{ | |
8691 match(Set dst (OrI dst src)); | |
8692 effect(KILL cr); | |
8693 | |
8694 format %{ "orl $dst, $src\t# int" %} | |
8695 opcode(0x0B); | |
8696 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); | |
8697 ins_pipe(ialu_reg_reg); | |
8698 %} | |
8699 | |
8700 // Or Register with Immediate | |
8701 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) | |
8702 %{ | |
8703 match(Set dst (OrI dst src)); | |
8704 effect(KILL cr); | |
8705 | |
8706 format %{ "orl $dst, $src\t# int" %} | |
8707 opcode(0x81, 0x01); /* Opcode 81 /1 id */ | |
8708 ins_encode(OpcSErm(dst, src), Con8or32(src)); | |
8709 ins_pipe(ialu_reg); | |
8710 %} | |
8711 | |
8712 // Or Register with Memory | |
8713 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) | |
8714 %{ | |
8715 match(Set dst (OrI dst (LoadI src))); | |
8716 effect(KILL cr); | |
8717 | |
8718 ins_cost(125); | |
8719 format %{ "orl $dst, $src\t# int" %} | |
8720 opcode(0x0B); | |
8721 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); | |
8722 ins_pipe(ialu_reg_mem); | |
8723 %} | |
8724 | |
8725 // Or Memory with Register | |
8726 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) | |
8727 %{ | |
8728 match(Set dst (StoreI dst (OrI (LoadI dst) src))); | |
8729 effect(KILL cr); | |
8730 | |
8731 ins_cost(150); | |
8732 format %{ "orl $dst, $src\t# int" %} | |
8733 opcode(0x09); /* Opcode 09 /r */ | |
8734 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); | |
8735 ins_pipe(ialu_mem_reg); | |
8736 %} | |
8737 | |
8738 // Or Memory with Immediate | |
8739 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) | |
8740 %{ | |
8741 match(Set dst (StoreI dst (OrI (LoadI dst) src))); | |
8742 effect(KILL cr); | |
8743 | |
8744 ins_cost(125); | |
8745 format %{ "orl $dst, $src\t# int" %} | |
8746 opcode(0x81, 0x1); /* Opcode 81 /1 id */ | |
8747 ins_encode(REX_mem(dst), OpcSE(src), | |
8748 RM_opc_mem(secondary, dst), Con8or32(src)); | |
8749 ins_pipe(ialu_mem_imm); | |
8750 %} | |
8751 | |
8752 // Xor Instructions | |
8753 // Xor Register with Register | |
8754 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | |
8755 %{ | |
8756 match(Set dst (XorI dst src)); | |
8757 effect(KILL cr); | |
8758 | |
8759 format %{ "xorl $dst, $src\t# int" %} | |
8760 opcode(0x33); | |
8761 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); | |
8762 ins_pipe(ialu_reg_reg); | |
8763 %} | |
8764 | |
403 | 8765 // Xor Register with Immediate -1 |
8766 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
8767 match(Set dst (XorI dst imm)); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
8768 |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
8769 format %{ "not $dst" %} |
403 | 8770 ins_encode %{ |
8771 __ notl($dst$$Register); | |
8772 %} | |
8773 ins_pipe(ialu_reg); | |
8774 %} | |
8775 | |
0 | 8776 // Xor Register with Immediate |
8777 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) | |
8778 %{ | |
8779 match(Set dst (XorI dst src)); | |
8780 effect(KILL cr); | |
8781 | |
8782 format %{ "xorl $dst, $src\t# int" %} | |
8783 opcode(0x81, 0x06); /* Opcode 81 /6 id */ | |
8784 ins_encode(OpcSErm(dst, src), Con8or32(src)); | |
8785 ins_pipe(ialu_reg); | |
8786 %} | |
8787 | |
8788 // Xor Register with Memory | |
8789 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) | |
8790 %{ | |
8791 match(Set dst (XorI dst (LoadI src))); | |
8792 effect(KILL cr); | |
8793 | |
8794 ins_cost(125); | |
8795 format %{ "xorl $dst, $src\t# int" %} | |
8796 opcode(0x33); | |
8797 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); | |
8798 ins_pipe(ialu_reg_mem); | |
8799 %} | |
8800 | |
8801 // Xor Memory with Register | |
8802 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) | |
8803 %{ | |
8804 match(Set dst (StoreI dst (XorI (LoadI dst) src))); | |
8805 effect(KILL cr); | |
8806 | |
8807 ins_cost(150); | |
8808 format %{ "xorl $dst, $src\t# int" %} | |
8809 opcode(0x31); /* Opcode 31 /r */ | |
8810 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); | |
8811 ins_pipe(ialu_mem_reg); | |
8812 %} | |
8813 | |
8814 // Xor Memory with Immediate | |
8815 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) | |
8816 %{ | |
8817 match(Set dst (StoreI dst (XorI (LoadI dst) src))); | |
8818 effect(KILL cr); | |
8819 | |
8820 ins_cost(125); | |
8821 format %{ "xorl $dst, $src\t# int" %} | |
8822 opcode(0x81, 0x6); /* Opcode 81 /6 id */ | |
8823 ins_encode(REX_mem(dst), OpcSE(src), | |
8824 RM_opc_mem(secondary, dst), Con8or32(src)); | |
8825 ins_pipe(ialu_mem_imm); | |
8826 %} | |
8827 | |
8828 | |
8829 // Long Logical Instructions | |
8830 | |
8831 // And Instructions | |
8832 // And Register with Register | |
8833 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) | |
8834 %{ | |
8835 match(Set dst (AndL dst src)); | |
8836 effect(KILL cr); | |
8837 | |
8838 format %{ "andq $dst, $src\t# long" %} | |
8839 opcode(0x23); | |
8840 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); | |
8841 ins_pipe(ialu_reg_reg); | |
8842 %} | |
8843 | |
8844 // And Register with Immediate 255 | |
8845 instruct andL_rReg_imm255(rRegL dst, immL_255 src) | |
8846 %{ | |
8847 match(Set dst (AndL dst src)); | |
8848 | |
569
2cacccded90f
6805950: Typos in andL_rReg_imm instructions in x86_64.ad
twisti
parents:
558
diff
changeset
|
8849 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} |
0 | 8850 opcode(0x0F, 0xB6); |
8851 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); | |
8852 ins_pipe(ialu_reg); | |
8853 %} | |
8854 | |
8855 // And Register with Immediate 65535 | |
569
2cacccded90f
6805950: Typos in andL_rReg_imm instructions in x86_64.ad
twisti
parents:
558
diff
changeset
|
8856 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) |
0 | 8857 %{ |
8858 match(Set dst (AndL dst src)); | |
8859 | |
8860 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} | |
8861 opcode(0x0F, 0xB7); | |
8862 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); | |
8863 ins_pipe(ialu_reg); | |
8864 %} | |
8865 | |
8866 // And Register with Immediate | |
8867 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) | |
8868 %{ | |
8869 match(Set dst (AndL dst src)); | |
8870 effect(KILL cr); | |
8871 | |
8872 format %{ "andq $dst, $src\t# long" %} | |
8873 opcode(0x81, 0x04); /* Opcode 81 /4 */ | |
8874 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); | |
8875 ins_pipe(ialu_reg); | |
8876 %} | |
8877 | |
8878 // And Register with Memory | |
8879 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) | |
8880 %{ | |
8881 match(Set dst (AndL dst (LoadL src))); | |
8882 effect(KILL cr); | |
8883 | |
8884 ins_cost(125); | |
8885 format %{ "andq $dst, $src\t# long" %} | |
8886 opcode(0x23); | |
8887 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); | |
8888 ins_pipe(ialu_reg_mem); | |
8889 %} | |
8890 | |
8891 // And Memory with Register | |
8892 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) | |
8893 %{ | |
8894 match(Set dst (StoreL dst (AndL (LoadL dst) src))); | |
8895 effect(KILL cr); | |
8896 | |
8897 ins_cost(150); | |
8898 format %{ "andq $dst, $src\t# long" %} | |
8899 opcode(0x21); /* Opcode 21 /r */ | |
8900 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); | |
8901 ins_pipe(ialu_mem_reg); | |
8902 %} | |
8903 | |
8904 // And Memory with Immediate | |
8905 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) | |
8906 %{ | |
8907 match(Set dst (StoreL dst (AndL (LoadL dst) src))); | |
8908 effect(KILL cr); | |
8909 | |
8910 ins_cost(125); | |
8911 format %{ "andq $dst, $src\t# long" %} | |
8912 opcode(0x81, 0x4); /* Opcode 81 /4 id */ | |
8913 ins_encode(REX_mem_wide(dst), OpcSE(src), | |
8914 RM_opc_mem(secondary, dst), Con8or32(src)); | |
8915 ins_pipe(ialu_mem_imm); | |
8916 %} | |
8917 | |
8918 // Or Instructions | |
8919 // Or Register with Register | |
8920 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) | |
8921 %{ | |
8922 match(Set dst (OrL dst src)); | |
8923 effect(KILL cr); | |
8924 | |
8925 format %{ "orq $dst, $src\t# long" %} | |
8926 opcode(0x0B); | |
8927 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); | |
8928 ins_pipe(ialu_reg_reg); | |
8929 %} | |
8930 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8931 // Use any_RegP to match R15 (TLS register) without spilling. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8932 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8933 match(Set dst (OrL dst (CastP2X src))); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8934 effect(KILL cr); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8935 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8936 format %{ "orq $dst, $src\t# long" %} |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8937 opcode(0x0B); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8938 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8939 ins_pipe(ialu_reg_reg); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8940 %} |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8941 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
8942 |
0 | 8943 // Or Register with Immediate |
8944 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) | |
8945 %{ | |
8946 match(Set dst (OrL dst src)); | |
8947 effect(KILL cr); | |
8948 | |
8949 format %{ "orq $dst, $src\t# long" %} | |
8950 opcode(0x81, 0x01); /* Opcode 81 /1 id */ | |
8951 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); | |
8952 ins_pipe(ialu_reg); | |
8953 %} | |
8954 | |
8955 // Or Register with Memory | |
8956 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) | |
8957 %{ | |
8958 match(Set dst (OrL dst (LoadL src))); | |
8959 effect(KILL cr); | |
8960 | |
8961 ins_cost(125); | |
8962 format %{ "orq $dst, $src\t# long" %} | |
8963 opcode(0x0B); | |
8964 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); | |
8965 ins_pipe(ialu_reg_mem); | |
8966 %} | |
8967 | |
8968 // Or Memory with Register | |
8969 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) | |
8970 %{ | |
8971 match(Set dst (StoreL dst (OrL (LoadL dst) src))); | |
8972 effect(KILL cr); | |
8973 | |
8974 ins_cost(150); | |
8975 format %{ "orq $dst, $src\t# long" %} | |
8976 opcode(0x09); /* Opcode 09 /r */ | |
8977 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); | |
8978 ins_pipe(ialu_mem_reg); | |
8979 %} | |
8980 | |
8981 // Or Memory with Immediate | |
8982 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) | |
8983 %{ | |
8984 match(Set dst (StoreL dst (OrL (LoadL dst) src))); | |
8985 effect(KILL cr); | |
8986 | |
8987 ins_cost(125); | |
8988 format %{ "orq $dst, $src\t# long" %} | |
8989 opcode(0x81, 0x1); /* Opcode 81 /1 id */ | |
8990 ins_encode(REX_mem_wide(dst), OpcSE(src), | |
8991 RM_opc_mem(secondary, dst), Con8or32(src)); | |
8992 ins_pipe(ialu_mem_imm); | |
8993 %} | |
8994 | |
8995 // Xor Instructions | |
8996 // Xor Register with Register | |
8997 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) | |
8998 %{ | |
8999 match(Set dst (XorL dst src)); | |
9000 effect(KILL cr); | |
9001 | |
9002 format %{ "xorq $dst, $src\t# long" %} | |
9003 opcode(0x33); | |
9004 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); | |
9005 ins_pipe(ialu_reg_reg); | |
9006 %} | |
9007 | |
403 | 9008 // Xor Register with Immediate -1 |
9009 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
9010 match(Set dst (XorL dst imm)); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
9011 |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
9012 format %{ "notq $dst" %} |
403 | 9013 ins_encode %{ |
9014 __ notq($dst$$Register); | |
9015 %} | |
9016 ins_pipe(ialu_reg); | |
9017 %} | |
9018 | |
0 | 9019 // Xor Register with Immediate |
9020 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) | |
9021 %{ | |
9022 match(Set dst (XorL dst src)); | |
9023 effect(KILL cr); | |
9024 | |
9025 format %{ "xorq $dst, $src\t# long" %} | |
9026 opcode(0x81, 0x06); /* Opcode 81 /6 id */ | |
9027 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); | |
9028 ins_pipe(ialu_reg); | |
9029 %} | |
9030 | |
9031 // Xor Register with Memory | |
9032 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) | |
9033 %{ | |
9034 match(Set dst (XorL dst (LoadL src))); | |
9035 effect(KILL cr); | |
9036 | |
9037 ins_cost(125); | |
9038 format %{ "xorq $dst, $src\t# long" %} | |
9039 opcode(0x33); | |
9040 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); | |
9041 ins_pipe(ialu_reg_mem); | |
9042 %} | |
9043 | |
9044 // Xor Memory with Register | |
9045 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) | |
9046 %{ | |
9047 match(Set dst (StoreL dst (XorL (LoadL dst) src))); | |
9048 effect(KILL cr); | |
9049 | |
9050 ins_cost(150); | |
9051 format %{ "xorq $dst, $src\t# long" %} | |
9052 opcode(0x31); /* Opcode 31 /r */ | |
9053 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); | |
9054 ins_pipe(ialu_mem_reg); | |
9055 %} | |
9056 | |
9057 // Xor Memory with Immediate | |
9058 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) | |
9059 %{ | |
9060 match(Set dst (StoreL dst (XorL (LoadL dst) src))); | |
9061 effect(KILL cr); | |
9062 | |
9063 ins_cost(125); | |
9064 format %{ "xorq $dst, $src\t# long" %} | |
9065 opcode(0x81, 0x6); /* Opcode 81 /6 id */ | |
9066 ins_encode(REX_mem_wide(dst), OpcSE(src), | |
9067 RM_opc_mem(secondary, dst), Con8or32(src)); | |
9068 ins_pipe(ialu_mem_imm); | |
9069 %} | |
9070 | |
9071 // Convert Int to Boolean | |
9072 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) | |
9073 %{ | |
9074 match(Set dst (Conv2B src)); | |
9075 effect(KILL cr); | |
9076 | |
9077 format %{ "testl $src, $src\t# ci2b\n\t" | |
9078 "setnz $dst\n\t" | |
9079 "movzbl $dst, $dst" %} | |
9080 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl | |
9081 setNZ_reg(dst), | |
9082 REX_reg_breg(dst, dst), // movzbl | |
9083 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); | |
9084 ins_pipe(pipe_slow); // XXX | |
9085 %} | |
9086 | |
9087 // Convert Pointer to Boolean | |
9088 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) | |
9089 %{ | |
9090 match(Set dst (Conv2B src)); | |
9091 effect(KILL cr); | |
9092 | |
9093 format %{ "testq $src, $src\t# cp2b\n\t" | |
9094 "setnz $dst\n\t" | |
9095 "movzbl $dst, $dst" %} | |
9096 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq | |
9097 setNZ_reg(dst), | |
9098 REX_reg_breg(dst, dst), // movzbl | |
9099 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); | |
9100 ins_pipe(pipe_slow); // XXX | |
9101 %} | |
9102 | |
9103 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) | |
9104 %{ | |
9105 match(Set dst (CmpLTMask p q)); | |
9106 effect(KILL cr); | |
9107 | |
9108 ins_cost(400); // XXX | |
9109 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" | |
9110 "setlt $dst\n\t" | |
9111 "movzbl $dst, $dst\n\t" | |
9112 "negl $dst" %} | |
9113 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl | |
9114 setLT_reg(dst), | |
9115 REX_reg_breg(dst, dst), // movzbl | |
9116 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), | |
9117 neg_reg(dst)); | |
9118 ins_pipe(pipe_slow); | |
9119 %} | |
9120 | |
9121 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) | |
9122 %{ | |
9123 match(Set dst (CmpLTMask dst zero)); | |
9124 effect(KILL cr); | |
9125 | |
9126 ins_cost(100); // XXX | |
9127 format %{ "sarl $dst, #31\t# cmpLTMask0" %} | |
9128 opcode(0xC1, 0x7); /* C1 /7 ib */ | |
9129 ins_encode(reg_opc_imm(dst, 0x1F)); | |
9130 ins_pipe(ialu_reg); | |
9131 %} | |
9132 | |
9133 | |
3738
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9134 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr) |
0 | 9135 %{ |
9136 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); | |
9137 effect(TEMP tmp, KILL cr); | |
9138 | |
9139 ins_cost(400); // XXX | |
9140 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t" | |
9141 "sbbl $tmp, $tmp\n\t" | |
9142 "andl $tmp, $y\n\t" | |
9143 "addl $p, $tmp" %} | |
3738
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9144 ins_encode %{ |
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9145 Register Rp = $p$$Register; |
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9146 Register Rq = $q$$Register; |
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9147 Register Ry = $y$$Register; |
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9148 Register Rt = $tmp$$Register; |
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9149 __ subl(Rp, Rq); |
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9150 __ sbbl(Rt, Rt); |
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9151 __ andl(Rt, Ry); |
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9152 __ addl(Rp, Rt); |
c7c81f18c834
7048332: Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
kvn
parents:
2404
diff
changeset
|
9153 %} |
0 | 9154 ins_pipe(pipe_cmplt); |
9155 %} | |
9156 | |
9157 //---------- FP Instructions------------------------------------------------ | |
9158 | |
9159 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) | |
9160 %{ | |
9161 match(Set cr (CmpF src1 src2)); | |
9162 | |
9163 ins_cost(145); | |
9164 format %{ "ucomiss $src1, $src2\n\t" | |
9165 "jnp,s exit\n\t" | |
9166 "pushfq\t# saw NaN, set CF\n\t" | |
9167 "andq [rsp], #0xffffff2b\n\t" | |
9168 "popfq\n" | |
4759 | 9169 "exit:" %} |
9170 ins_encode %{ | |
9171 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); | |
9172 emit_cmpfp_fixup(_masm); | |
9173 %} | |
0 | 9174 ins_pipe(pipe_slow); |
9175 %} | |
9176 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9177 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9178 match(Set cr (CmpF src1 src2)); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9179 |
4759 | 9180 ins_cost(100); |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9181 format %{ "ucomiss $src1, $src2" %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9182 ins_encode %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9183 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9184 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9185 ins_pipe(pipe_slow); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9186 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9187 |
0 | 9188 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) |
9189 %{ | |
9190 match(Set cr (CmpF src1 (LoadF src2))); | |
9191 | |
9192 ins_cost(145); | |
9193 format %{ "ucomiss $src1, $src2\n\t" | |
9194 "jnp,s exit\n\t" | |
9195 "pushfq\t# saw NaN, set CF\n\t" | |
9196 "andq [rsp], #0xffffff2b\n\t" | |
9197 "popfq\n" | |
4759 | 9198 "exit:" %} |
9199 ins_encode %{ | |
9200 __ ucomiss($src1$$XMMRegister, $src2$$Address); | |
9201 emit_cmpfp_fixup(_masm); | |
9202 %} | |
0 | 9203 ins_pipe(pipe_slow); |
9204 %} | |
9205 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9206 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9207 match(Set cr (CmpF src1 (LoadF src2))); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9208 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9209 ins_cost(100); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9210 format %{ "ucomiss $src1, $src2" %} |
4759 | 9211 ins_encode %{ |
9212 __ ucomiss($src1$$XMMRegister, $src2$$Address); | |
9213 %} | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9214 ins_pipe(pipe_slow); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9215 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9216 |
2008 | 9217 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ |
9218 match(Set cr (CmpF src con)); | |
0 | 9219 |
9220 ins_cost(145); | |
2008 | 9221 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" |
0 | 9222 "jnp,s exit\n\t" |
9223 "pushfq\t# saw NaN, set CF\n\t" | |
9224 "andq [rsp], #0xffffff2b\n\t" | |
9225 "popfq\n" | |
4759 | 9226 "exit:" %} |
2008 | 9227 ins_encode %{ |
9228 __ ucomiss($src$$XMMRegister, $constantaddress($con)); | |
3783 | 9229 emit_cmpfp_fixup(_masm); |
2008 | 9230 %} |
9231 ins_pipe(pipe_slow); | |
9232 %} | |
9233 | |
9234 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ | |
9235 match(Set cr (CmpF src con)); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9236 ins_cost(100); |
2008 | 9237 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} |
9238 ins_encode %{ | |
9239 __ ucomiss($src$$XMMRegister, $constantaddress($con)); | |
9240 %} | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9241 ins_pipe(pipe_slow); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9242 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9243 |
0 | 9244 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) |
9245 %{ | |
9246 match(Set cr (CmpD src1 src2)); | |
9247 | |
9248 ins_cost(145); | |
9249 format %{ "ucomisd $src1, $src2\n\t" | |
9250 "jnp,s exit\n\t" | |
9251 "pushfq\t# saw NaN, set CF\n\t" | |
9252 "andq [rsp], #0xffffff2b\n\t" | |
9253 "popfq\n" | |
4759 | 9254 "exit:" %} |
9255 ins_encode %{ | |
9256 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); | |
9257 emit_cmpfp_fixup(_masm); | |
9258 %} | |
0 | 9259 ins_pipe(pipe_slow); |
9260 %} | |
9261 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9262 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9263 match(Set cr (CmpD src1 src2)); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9264 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9265 ins_cost(100); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9266 format %{ "ucomisd $src1, $src2 test" %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9267 ins_encode %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9268 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9269 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9270 ins_pipe(pipe_slow); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9271 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9272 |
0 | 9273 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) |
9274 %{ | |
9275 match(Set cr (CmpD src1 (LoadD src2))); | |
9276 | |
9277 ins_cost(145); | |
9278 format %{ "ucomisd $src1, $src2\n\t" | |
9279 "jnp,s exit\n\t" | |
9280 "pushfq\t# saw NaN, set CF\n\t" | |
9281 "andq [rsp], #0xffffff2b\n\t" | |
9282 "popfq\n" | |
4759 | 9283 "exit:" %} |
9284 ins_encode %{ | |
9285 __ ucomisd($src1$$XMMRegister, $src2$$Address); | |
9286 emit_cmpfp_fixup(_masm); | |
9287 %} | |
0 | 9288 ins_pipe(pipe_slow); |
9289 %} | |
9290 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9291 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9292 match(Set cr (CmpD src1 (LoadD src2))); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9293 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9294 ins_cost(100); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9295 format %{ "ucomisd $src1, $src2" %} |
4759 | 9296 ins_encode %{ |
9297 __ ucomisd($src1$$XMMRegister, $src2$$Address); | |
9298 %} | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9299 ins_pipe(pipe_slow); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9300 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9301 |
2008 | 9302 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ |
9303 match(Set cr (CmpD src con)); | |
0 | 9304 |
9305 ins_cost(145); | |
2008 | 9306 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" |
0 | 9307 "jnp,s exit\n\t" |
9308 "pushfq\t# saw NaN, set CF\n\t" | |
9309 "andq [rsp], #0xffffff2b\n\t" | |
9310 "popfq\n" | |
4759 | 9311 "exit:" %} |
2008 | 9312 ins_encode %{ |
9313 __ ucomisd($src$$XMMRegister, $constantaddress($con)); | |
3783 | 9314 emit_cmpfp_fixup(_masm); |
2008 | 9315 %} |
9316 ins_pipe(pipe_slow); | |
9317 %} | |
9318 | |
9319 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ | |
9320 match(Set cr (CmpD src con)); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9321 ins_cost(100); |
2008 | 9322 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} |
9323 ins_encode %{ | |
9324 __ ucomisd($src$$XMMRegister, $constantaddress($con)); | |
9325 %} | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9326 ins_pipe(pipe_slow); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9327 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
9328 |
0 | 9329 // Compare into -1,0,1 |
9330 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) | |
9331 %{ | |
9332 match(Set dst (CmpF3 src1 src2)); | |
9333 effect(KILL cr); | |
9334 | |
9335 ins_cost(275); | |
9336 format %{ "ucomiss $src1, $src2\n\t" | |
9337 "movl $dst, #-1\n\t" | |
9338 "jp,s done\n\t" | |
9339 "jb,s done\n\t" | |
9340 "setne $dst\n\t" | |
9341 "movzbl $dst, $dst\n" | |
9342 "done:" %} | |
4759 | 9343 ins_encode %{ |
9344 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); | |
9345 emit_cmpfp3(_masm, $dst$$Register); | |
9346 %} | |
0 | 9347 ins_pipe(pipe_slow); |
9348 %} | |
9349 | |
9350 // Compare into -1,0,1 | |
9351 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) | |
9352 %{ | |
9353 match(Set dst (CmpF3 src1 (LoadF src2))); | |
9354 effect(KILL cr); | |
9355 | |
9356 ins_cost(275); | |
9357 format %{ "ucomiss $src1, $src2\n\t" | |
9358 "movl $dst, #-1\n\t" | |
9359 "jp,s done\n\t" | |
9360 "jb,s done\n\t" | |
9361 "setne $dst\n\t" | |
9362 "movzbl $dst, $dst\n" | |
9363 "done:" %} | |
4759 | 9364 ins_encode %{ |
9365 __ ucomiss($src1$$XMMRegister, $src2$$Address); | |
9366 emit_cmpfp3(_masm, $dst$$Register); | |
9367 %} | |
0 | 9368 ins_pipe(pipe_slow); |
9369 %} | |
9370 | |
9371 // Compare into -1,0,1 | |
2008 | 9372 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ |
9373 match(Set dst (CmpF3 src con)); | |
0 | 9374 effect(KILL cr); |
9375 | |
9376 ins_cost(275); | |
2008 | 9377 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" |
0 | 9378 "movl $dst, #-1\n\t" |
9379 "jp,s done\n\t" | |
9380 "jb,s done\n\t" | |
9381 "setne $dst\n\t" | |
9382 "movzbl $dst, $dst\n" | |
9383 "done:" %} | |
2008 | 9384 ins_encode %{ |
9385 __ ucomiss($src$$XMMRegister, $constantaddress($con)); | |
4759 | 9386 emit_cmpfp3(_masm, $dst$$Register); |
2008 | 9387 %} |
0 | 9388 ins_pipe(pipe_slow); |
9389 %} | |
9390 | |
9391 // Compare into -1,0,1 | |
9392 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) | |
9393 %{ | |
9394 match(Set dst (CmpD3 src1 src2)); | |
9395 effect(KILL cr); | |
9396 | |
9397 ins_cost(275); | |
9398 format %{ "ucomisd $src1, $src2\n\t" | |
9399 "movl $dst, #-1\n\t" | |
9400 "jp,s done\n\t" | |
9401 "jb,s done\n\t" | |
9402 "setne $dst\n\t" | |
9403 "movzbl $dst, $dst\n" | |
9404 "done:" %} | |
4759 | 9405 ins_encode %{ |
9406 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); | |
9407 emit_cmpfp3(_masm, $dst$$Register); | |
9408 %} | |
0 | 9409 ins_pipe(pipe_slow); |
9410 %} | |
9411 | |
9412 // Compare into -1,0,1 | |
9413 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) | |
9414 %{ | |
9415 match(Set dst (CmpD3 src1 (LoadD src2))); | |
9416 effect(KILL cr); | |
9417 | |
9418 ins_cost(275); | |
9419 format %{ "ucomisd $src1, $src2\n\t" | |
9420 "movl $dst, #-1\n\t" | |
9421 "jp,s done\n\t" | |
9422 "jb,s done\n\t" | |
9423 "setne $dst\n\t" | |
9424 "movzbl $dst, $dst\n" | |
9425 "done:" %} | |
4759 | 9426 ins_encode %{ |
9427 __ ucomisd($src1$$XMMRegister, $src2$$Address); | |
9428 emit_cmpfp3(_masm, $dst$$Register); | |
9429 %} | |
0 | 9430 ins_pipe(pipe_slow); |
9431 %} | |
9432 | |
9433 // Compare into -1,0,1 | |
2008 | 9434 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ |
9435 match(Set dst (CmpD3 src con)); | |
0 | 9436 effect(KILL cr); |
9437 | |
9438 ins_cost(275); | |
2008 | 9439 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" |
0 | 9440 "movl $dst, #-1\n\t" |
9441 "jp,s done\n\t" | |
9442 "jb,s done\n\t" | |
9443 "setne $dst\n\t" | |
9444 "movzbl $dst, $dst\n" | |
9445 "done:" %} | |
2008 | 9446 ins_encode %{ |
9447 __ ucomisd($src$$XMMRegister, $constantaddress($con)); | |
4759 | 9448 emit_cmpfp3(_masm, $dst$$Register); |
2008 | 9449 %} |
0 | 9450 ins_pipe(pipe_slow); |
9451 %} | |
9452 | |
9453 // -----------Trig and Trancendental Instructions------------------------------ | |
9454 instruct cosD_reg(regD dst) %{ | |
9455 match(Set dst (CosD dst)); | |
9456 | |
9457 format %{ "dcos $dst\n\t" %} | |
9458 opcode(0xD9, 0xFF); | |
9459 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); | |
9460 ins_pipe( pipe_slow ); | |
9461 %} | |
9462 | |
9463 instruct sinD_reg(regD dst) %{ | |
9464 match(Set dst (SinD dst)); | |
9465 | |
9466 format %{ "dsin $dst\n\t" %} | |
9467 opcode(0xD9, 0xFE); | |
9468 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); | |
9469 ins_pipe( pipe_slow ); | |
9470 %} | |
9471 | |
9472 instruct tanD_reg(regD dst) %{ | |
9473 match(Set dst (TanD dst)); | |
9474 | |
9475 format %{ "dtan $dst\n\t" %} | |
9476 ins_encode( Push_SrcXD(dst), | |
9477 Opcode(0xD9), Opcode(0xF2), //fptan | |
9478 Opcode(0xDD), Opcode(0xD8), //fstp st | |
9479 Push_ResultXD(dst) ); | |
9480 ins_pipe( pipe_slow ); | |
9481 %} | |
9482 | |
9483 instruct log10D_reg(regD dst) %{ | |
9484 // The source and result Double operands in XMM registers | |
9485 match(Set dst (Log10D dst)); | |
9486 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number | |
9487 // fyl2x ; compute log_10(2) * log_2(x) | |
9488 format %{ "fldlg2\t\t\t#Log10\n\t" | |
9489 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" | |
9490 %} | |
9491 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 | |
9492 Push_SrcXD(dst), | |
9493 Opcode(0xD9), Opcode(0xF1), // fyl2x | |
9494 Push_ResultXD(dst)); | |
9495 | |
9496 ins_pipe( pipe_slow ); | |
9497 %} | |
9498 | |
9499 instruct logD_reg(regD dst) %{ | |
9500 // The source and result Double operands in XMM registers | |
9501 match(Set dst (LogD dst)); | |
9502 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number | |
9503 // fyl2x ; compute log_e(2) * log_2(x) | |
9504 format %{ "fldln2\t\t\t#Log_e\n\t" | |
9505 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" | |
9506 %} | |
9507 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 | |
9508 Push_SrcXD(dst), | |
9509 Opcode(0xD9), Opcode(0xF1), // fyl2x | |
9510 Push_ResultXD(dst)); | |
9511 ins_pipe( pipe_slow ); | |
9512 %} | |
9513 | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9514 instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9515 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9516 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9517 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9518 ins_encode %{ |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9519 __ subptr(rsp, 8); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9520 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9521 __ fld_d(Address(rsp, 0)); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9522 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9523 __ fld_d(Address(rsp, 0)); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9524 __ fast_pow(); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9525 __ fstp_d(Address(rsp, 0)); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9526 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9527 __ addptr(rsp, 8); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9528 %} |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9529 ins_pipe( pipe_slow ); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9530 %} |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9531 |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9532 instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9533 match(Set dst (ExpD src)); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9534 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9535 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %} |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9536 ins_encode %{ |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9537 __ subptr(rsp, 8); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9538 __ movdbl(Address(rsp, 0), $src$$XMMRegister); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9539 __ fld_d(Address(rsp, 0)); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9540 __ fast_exp(); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9541 __ fstp_d(Address(rsp, 0)); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9542 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9543 __ addptr(rsp, 8); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9544 %} |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9545 ins_pipe( pipe_slow ); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5984
diff
changeset
|
9546 %} |
0 | 9547 |
9548 //----------Arithmetic Conversion Instructions--------------------------------- | |
9549 | |
9550 instruct roundFloat_nop(regF dst) | |
9551 %{ | |
9552 match(Set dst (RoundFloat dst)); | |
9553 | |
9554 ins_cost(0); | |
9555 ins_encode(); | |
9556 ins_pipe(empty); | |
9557 %} | |
9558 | |
9559 instruct roundDouble_nop(regD dst) | |
9560 %{ | |
9561 match(Set dst (RoundDouble dst)); | |
9562 | |
9563 ins_cost(0); | |
9564 ins_encode(); | |
9565 ins_pipe(empty); | |
9566 %} | |
9567 | |
9568 instruct convF2D_reg_reg(regD dst, regF src) | |
9569 %{ | |
9570 match(Set dst (ConvF2D src)); | |
9571 | |
9572 format %{ "cvtss2sd $dst, $src" %} | |
4759 | 9573 ins_encode %{ |
9574 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); | |
9575 %} | |
0 | 9576 ins_pipe(pipe_slow); // XXX |
9577 %} | |
9578 | |
9579 instruct convF2D_reg_mem(regD dst, memory src) | |
9580 %{ | |
9581 match(Set dst (ConvF2D (LoadF src))); | |
9582 | |
9583 format %{ "cvtss2sd $dst, $src" %} | |
4759 | 9584 ins_encode %{ |
9585 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); | |
9586 %} | |
0 | 9587 ins_pipe(pipe_slow); // XXX |
9588 %} | |
9589 | |
9590 instruct convD2F_reg_reg(regF dst, regD src) | |
9591 %{ | |
9592 match(Set dst (ConvD2F src)); | |
9593 | |
9594 format %{ "cvtsd2ss $dst, $src" %} | |
4759 | 9595 ins_encode %{ |
9596 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); | |
9597 %} | |
0 | 9598 ins_pipe(pipe_slow); // XXX |
9599 %} | |
9600 | |
9601 instruct convD2F_reg_mem(regF dst, memory src) | |
9602 %{ | |
9603 match(Set dst (ConvD2F (LoadD src))); | |
9604 | |
9605 format %{ "cvtsd2ss $dst, $src" %} | |
4759 | 9606 ins_encode %{ |
9607 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); | |
9608 %} | |
0 | 9609 ins_pipe(pipe_slow); // XXX |
9610 %} | |
9611 | |
9612 // XXX do mem variants | |
9613 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) | |
9614 %{ | |
9615 match(Set dst (ConvF2I src)); | |
9616 effect(KILL cr); | |
9617 | |
9618 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" | |
9619 "cmpl $dst, #0x80000000\n\t" | |
9620 "jne,s done\n\t" | |
9621 "subq rsp, #8\n\t" | |
9622 "movss [rsp], $src\n\t" | |
9623 "call f2i_fixup\n\t" | |
9624 "popq $dst\n" | |
9625 "done: "%} | |
4759 | 9626 ins_encode %{ |
9627 Label done; | |
9628 __ cvttss2sil($dst$$Register, $src$$XMMRegister); | |
9629 __ cmpl($dst$$Register, 0x80000000); | |
9630 __ jccb(Assembler::notEqual, done); | |
9631 __ subptr(rsp, 8); | |
9632 __ movflt(Address(rsp, 0), $src$$XMMRegister); | |
9633 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); | |
9634 __ pop($dst$$Register); | |
9635 __ bind(done); | |
9636 %} | |
0 | 9637 ins_pipe(pipe_slow); |
9638 %} | |
9639 | |
9640 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) | |
9641 %{ | |
9642 match(Set dst (ConvF2L src)); | |
9643 effect(KILL cr); | |
9644 | |
9645 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" | |
9646 "cmpq $dst, [0x8000000000000000]\n\t" | |
9647 "jne,s done\n\t" | |
9648 "subq rsp, #8\n\t" | |
9649 "movss [rsp], $src\n\t" | |
9650 "call f2l_fixup\n\t" | |
9651 "popq $dst\n" | |
9652 "done: "%} | |
4759 | 9653 ins_encode %{ |
9654 Label done; | |
9655 __ cvttss2siq($dst$$Register, $src$$XMMRegister); | |
9656 __ cmp64($dst$$Register, | |
9657 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); | |
9658 __ jccb(Assembler::notEqual, done); | |
9659 __ subptr(rsp, 8); | |
9660 __ movflt(Address(rsp, 0), $src$$XMMRegister); | |
9661 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); | |
9662 __ pop($dst$$Register); | |
9663 __ bind(done); | |
9664 %} | |
0 | 9665 ins_pipe(pipe_slow); |
9666 %} | |
9667 | |
9668 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) | |
9669 %{ | |
9670 match(Set dst (ConvD2I src)); | |
9671 effect(KILL cr); | |
9672 | |
9673 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" | |
9674 "cmpl $dst, #0x80000000\n\t" | |
9675 "jne,s done\n\t" | |
9676 "subq rsp, #8\n\t" | |
9677 "movsd [rsp], $src\n\t" | |
9678 "call d2i_fixup\n\t" | |
9679 "popq $dst\n" | |
9680 "done: "%} | |
4759 | 9681 ins_encode %{ |
9682 Label done; | |
9683 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); | |
9684 __ cmpl($dst$$Register, 0x80000000); | |
9685 __ jccb(Assembler::notEqual, done); | |
9686 __ subptr(rsp, 8); | |
9687 __ movdbl(Address(rsp, 0), $src$$XMMRegister); | |
9688 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); | |
9689 __ pop($dst$$Register); | |
9690 __ bind(done); | |
9691 %} | |
0 | 9692 ins_pipe(pipe_slow); |
9693 %} | |
9694 | |
9695 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) | |
9696 %{ | |
9697 match(Set dst (ConvD2L src)); | |
9698 effect(KILL cr); | |
9699 | |
9700 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" | |
9701 "cmpq $dst, [0x8000000000000000]\n\t" | |
9702 "jne,s done\n\t" | |
9703 "subq rsp, #8\n\t" | |
9704 "movsd [rsp], $src\n\t" | |
9705 "call d2l_fixup\n\t" | |
9706 "popq $dst\n" | |
9707 "done: "%} | |
4759 | 9708 ins_encode %{ |
9709 Label done; | |
9710 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); | |
9711 __ cmp64($dst$$Register, | |
9712 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); | |
9713 __ jccb(Assembler::notEqual, done); | |
9714 __ subptr(rsp, 8); | |
9715 __ movdbl(Address(rsp, 0), $src$$XMMRegister); | |
9716 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); | |
9717 __ pop($dst$$Register); | |
9718 __ bind(done); | |
9719 %} | |
0 | 9720 ins_pipe(pipe_slow); |
9721 %} | |
9722 | |
9723 instruct convI2F_reg_reg(regF dst, rRegI src) | |
9724 %{ | |
71 | 9725 predicate(!UseXmmI2F); |
0 | 9726 match(Set dst (ConvI2F src)); |
9727 | |
9728 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} | |
4759 | 9729 ins_encode %{ |
9730 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); | |
9731 %} | |
0 | 9732 ins_pipe(pipe_slow); // XXX |
9733 %} | |
9734 | |
9735 instruct convI2F_reg_mem(regF dst, memory src) | |
9736 %{ | |
9737 match(Set dst (ConvI2F (LoadI src))); | |
9738 | |
9739 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} | |
4759 | 9740 ins_encode %{ |
9741 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); | |
9742 %} | |
0 | 9743 ins_pipe(pipe_slow); // XXX |
9744 %} | |
9745 | |
9746 instruct convI2D_reg_reg(regD dst, rRegI src) | |
9747 %{ | |
71 | 9748 predicate(!UseXmmI2D); |
0 | 9749 match(Set dst (ConvI2D src)); |
9750 | |
9751 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} | |
4759 | 9752 ins_encode %{ |
9753 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); | |
9754 %} | |
0 | 9755 ins_pipe(pipe_slow); // XXX |
9756 %} | |
9757 | |
9758 instruct convI2D_reg_mem(regD dst, memory src) | |
9759 %{ | |
9760 match(Set dst (ConvI2D (LoadI src))); | |
9761 | |
9762 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} | |
4759 | 9763 ins_encode %{ |
9764 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); | |
9765 %} | |
0 | 9766 ins_pipe(pipe_slow); // XXX |
9767 %} | |
9768 | |
71 | 9769 instruct convXI2F_reg(regF dst, rRegI src) |
9770 %{ | |
9771 predicate(UseXmmI2F); | |
9772 match(Set dst (ConvI2F src)); | |
9773 | |
9774 format %{ "movdl $dst, $src\n\t" | |
9775 "cvtdq2psl $dst, $dst\t# i2f" %} | |
9776 ins_encode %{ | |
9777 __ movdl($dst$$XMMRegister, $src$$Register); | |
9778 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); | |
9779 %} | |
9780 ins_pipe(pipe_slow); // XXX | |
9781 %} | |
9782 | |
9783 instruct convXI2D_reg(regD dst, rRegI src) | |
9784 %{ | |
9785 predicate(UseXmmI2D); | |
9786 match(Set dst (ConvI2D src)); | |
9787 | |
9788 format %{ "movdl $dst, $src\n\t" | |
9789 "cvtdq2pdl $dst, $dst\t# i2d" %} | |
9790 ins_encode %{ | |
9791 __ movdl($dst$$XMMRegister, $src$$Register); | |
9792 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); | |
9793 %} | |
9794 ins_pipe(pipe_slow); // XXX | |
9795 %} | |
9796 | |
0 | 9797 instruct convL2F_reg_reg(regF dst, rRegL src) |
9798 %{ | |
9799 match(Set dst (ConvL2F src)); | |
9800 | |
9801 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} | |
4759 | 9802 ins_encode %{ |
9803 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); | |
9804 %} | |
0 | 9805 ins_pipe(pipe_slow); // XXX |
9806 %} | |
9807 | |
9808 instruct convL2F_reg_mem(regF dst, memory src) | |
9809 %{ | |
9810 match(Set dst (ConvL2F (LoadL src))); | |
9811 | |
9812 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} | |
4759 | 9813 ins_encode %{ |
9814 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); | |
9815 %} | |
0 | 9816 ins_pipe(pipe_slow); // XXX |
9817 %} | |
9818 | |
9819 instruct convL2D_reg_reg(regD dst, rRegL src) | |
9820 %{ | |
9821 match(Set dst (ConvL2D src)); | |
9822 | |
9823 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} | |
4759 | 9824 ins_encode %{ |
9825 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); | |
9826 %} | |
0 | 9827 ins_pipe(pipe_slow); // XXX |
9828 %} | |
9829 | |
9830 instruct convL2D_reg_mem(regD dst, memory src) | |
9831 %{ | |
9832 match(Set dst (ConvL2D (LoadL src))); | |
9833 | |
9834 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} | |
4759 | 9835 ins_encode %{ |
9836 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); | |
9837 %} | |
0 | 9838 ins_pipe(pipe_slow); // XXX |
9839 %} | |
9840 | |
9841 instruct convI2L_reg_reg(rRegL dst, rRegI src) | |
9842 %{ | |
9843 match(Set dst (ConvI2L src)); | |
9844 | |
9845 ins_cost(125); | |
9846 format %{ "movslq $dst, $src\t# i2l" %} | |
824 | 9847 ins_encode %{ |
9848 __ movslq($dst$$Register, $src$$Register); | |
9849 %} | |
0 | 9850 ins_pipe(ialu_reg_reg); |
9851 %} | |
9852 | |
9853 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) | |
9854 // %{ | |
9855 // match(Set dst (ConvI2L src)); | |
9856 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && | |
9857 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); | |
9858 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == | |
9859 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && | |
9860 // ((const TypeNode*) n)->type()->is_long()->_lo == | |
9861 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); | |
9862 | |
9863 // format %{ "movl $dst, $src\t# unsigned i2l" %} | |
9864 // ins_encode(enc_copy(dst, src)); | |
9865 // // opcode(0x63); // needs REX.W | |
9866 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); | |
9867 // ins_pipe(ialu_reg_reg); | |
9868 // %} | |
9869 | |
9870 // Zero-extend convert int to long | |
9871 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) | |
9872 %{ | |
9873 match(Set dst (AndL (ConvI2L src) mask)); | |
9874 | |
9875 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} | |
4759 | 9876 ins_encode %{ |
9877 if ($dst$$reg != $src$$reg) { | |
9878 __ movl($dst$$Register, $src$$Register); | |
9879 } | |
9880 %} | |
0 | 9881 ins_pipe(ialu_reg_reg); |
9882 %} | |
9883 | |
9884 // Zero-extend convert int to long | |
9885 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) | |
9886 %{ | |
9887 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); | |
9888 | |
9889 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} | |
4759 | 9890 ins_encode %{ |
9891 __ movl($dst$$Register, $src$$Address); | |
9892 %} | |
0 | 9893 ins_pipe(ialu_reg_mem); |
9894 %} | |
9895 | |
9896 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) | |
9897 %{ | |
9898 match(Set dst (AndL src mask)); | |
9899 | |
9900 format %{ "movl $dst, $src\t# zero-extend long" %} | |
4759 | 9901 ins_encode %{ |
9902 __ movl($dst$$Register, $src$$Register); | |
9903 %} | |
0 | 9904 ins_pipe(ialu_reg_reg); |
9905 %} | |
9906 | |
9907 instruct convL2I_reg_reg(rRegI dst, rRegL src) | |
9908 %{ | |
9909 match(Set dst (ConvL2I src)); | |
9910 | |
9911 format %{ "movl $dst, $src\t# l2i" %} | |
4759 | 9912 ins_encode %{ |
9913 __ movl($dst$$Register, $src$$Register); | |
9914 %} | |
0 | 9915 ins_pipe(ialu_reg_reg); |
9916 %} | |
9917 | |
9918 | |
9919 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ | |
9920 match(Set dst (MoveF2I src)); | |
9921 effect(DEF dst, USE src); | |
9922 | |
9923 ins_cost(125); | |
9924 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} | |
4759 | 9925 ins_encode %{ |
9926 __ movl($dst$$Register, Address(rsp, $src$$disp)); | |
9927 %} | |
0 | 9928 ins_pipe(ialu_reg_mem); |
9929 %} | |
9930 | |
9931 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ | |
9932 match(Set dst (MoveI2F src)); | |
9933 effect(DEF dst, USE src); | |
9934 | |
9935 ins_cost(125); | |
9936 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} | |
4759 | 9937 ins_encode %{ |
9938 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); | |
9939 %} | |
0 | 9940 ins_pipe(pipe_slow); |
9941 %} | |
9942 | |
9943 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ | |
9944 match(Set dst (MoveD2L src)); | |
9945 effect(DEF dst, USE src); | |
9946 | |
9947 ins_cost(125); | |
9948 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} | |
4759 | 9949 ins_encode %{ |
9950 __ movq($dst$$Register, Address(rsp, $src$$disp)); | |
9951 %} | |
0 | 9952 ins_pipe(ialu_reg_mem); |
9953 %} | |
9954 | |
9955 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ | |
9956 predicate(!UseXmmLoadAndClearUpper); | |
9957 match(Set dst (MoveL2D src)); | |
9958 effect(DEF dst, USE src); | |
9959 | |
9960 ins_cost(125); | |
9961 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} | |
4759 | 9962 ins_encode %{ |
9963 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); | |
9964 %} | |
0 | 9965 ins_pipe(pipe_slow); |
9966 %} | |
9967 | |
9968 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ | |
9969 predicate(UseXmmLoadAndClearUpper); | |
9970 match(Set dst (MoveL2D src)); | |
9971 effect(DEF dst, USE src); | |
9972 | |
9973 ins_cost(125); | |
9974 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} | |
4759 | 9975 ins_encode %{ |
9976 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); | |
9977 %} | |
0 | 9978 ins_pipe(pipe_slow); |
9979 %} | |
9980 | |
9981 | |
9982 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ | |
9983 match(Set dst (MoveF2I src)); | |
9984 effect(DEF dst, USE src); | |
9985 | |
9986 ins_cost(95); // XXX | |
9987 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} | |
4759 | 9988 ins_encode %{ |
9989 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); | |
9990 %} | |
0 | 9991 ins_pipe(pipe_slow); |
9992 %} | |
9993 | |
9994 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ | |
9995 match(Set dst (MoveI2F src)); | |
9996 effect(DEF dst, USE src); | |
9997 | |
9998 ins_cost(100); | |
9999 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} | |
4759 | 10000 ins_encode %{ |
10001 __ movl(Address(rsp, $dst$$disp), $src$$Register); | |
10002 %} | |
0 | 10003 ins_pipe( ialu_mem_reg ); |
10004 %} | |
10005 | |
10006 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ | |
10007 match(Set dst (MoveD2L src)); | |
10008 effect(DEF dst, USE src); | |
10009 | |
10010 ins_cost(95); // XXX | |
10011 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} | |
4759 | 10012 ins_encode %{ |
10013 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); | |
10014 %} | |
0 | 10015 ins_pipe(pipe_slow); |
10016 %} | |
10017 | |
10018 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ | |
10019 match(Set dst (MoveL2D src)); | |
10020 effect(DEF dst, USE src); | |
10021 | |
10022 ins_cost(100); | |
10023 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} | |
4759 | 10024 ins_encode %{ |
10025 __ movq(Address(rsp, $dst$$disp), $src$$Register); | |
10026 %} | |
0 | 10027 ins_pipe(ialu_mem_reg); |
10028 %} | |
10029 | |
10030 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ | |
10031 match(Set dst (MoveF2I src)); | |
10032 effect(DEF dst, USE src); | |
10033 ins_cost(85); | |
10034 format %{ "movd $dst,$src\t# MoveF2I" %} | |
4759 | 10035 ins_encode %{ |
10036 __ movdl($dst$$Register, $src$$XMMRegister); | |
10037 %} | |
0 | 10038 ins_pipe( pipe_slow ); |
10039 %} | |
10040 | |
10041 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ | |
10042 match(Set dst (MoveD2L src)); | |
10043 effect(DEF dst, USE src); | |
10044 ins_cost(85); | |
10045 format %{ "movd $dst,$src\t# MoveD2L" %} | |
4759 | 10046 ins_encode %{ |
10047 __ movdq($dst$$Register, $src$$XMMRegister); | |
10048 %} | |
0 | 10049 ins_pipe( pipe_slow ); |
10050 %} | |
10051 | |
10052 // The next instructions have long latency and use Int unit. Set high cost. | |
10053 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ | |
10054 match(Set dst (MoveI2F src)); | |
10055 effect(DEF dst, USE src); | |
10056 ins_cost(300); | |
10057 format %{ "movd $dst,$src\t# MoveI2F" %} | |
4759 | 10058 ins_encode %{ |
10059 __ movdl($dst$$XMMRegister, $src$$Register); | |
10060 %} | |
0 | 10061 ins_pipe( pipe_slow ); |
10062 %} | |
10063 | |
10064 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ | |
10065 match(Set dst (MoveL2D src)); | |
10066 effect(DEF dst, USE src); | |
10067 ins_cost(300); | |
10068 format %{ "movd $dst,$src\t# MoveL2D" %} | |
4759 | 10069 ins_encode %{ |
10070 __ movdq($dst$$XMMRegister, $src$$Register); | |
10071 %} | |
0 | 10072 ins_pipe( pipe_slow ); |
10073 %} | |
10074 | |
10075 | |
10076 // ======================================================================= | |
10077 // fast clearing of an array | |
10078 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, | |
10079 rFlagsReg cr) | |
10080 %{ | |
10081 match(Set dummy (ClearArray cnt base)); | |
10082 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); | |
10083 | |
10084 format %{ "xorl rax, rax\t# ClearArray:\n\t" | |
10085 "rep stosq\t# Store rax to *rdi++ while rcx--" %} | |
10086 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax | |
10087 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos | |
10088 ins_pipe(pipe_slow); | |
10089 %} | |
10090 | |
2262 | 10091 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, |
10092 rax_RegI result, regD tmp1, rFlagsReg cr) | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10093 %{ |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10094 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); |
2262 | 10095 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); |
10096 | |
10097 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10098 ins_encode %{ |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10099 __ string_compare($str1$$Register, $str2$$Register, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10100 $cnt1$$Register, $cnt2$$Register, $result$$Register, |
2262 | 10101 $tmp1$$XMMRegister); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10102 %} |
681 | 10103 ins_pipe( pipe_slow ); |
10104 %} | |
10105 | |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10106 // fast search of substring with known size. |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10107 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10108 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10109 %{ |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10110 predicate(UseSSE42Intrinsics); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10111 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10112 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10113 |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10114 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10115 ins_encode %{ |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10116 int icnt2 = (int)$int_cnt2$$constant; |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10117 if (icnt2 >= 8) { |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10118 // IndexOf for constant substrings with size >= 8 elements |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10119 // which don't need to be loaded through stack. |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10120 __ string_indexofC8($str1$$Register, $str2$$Register, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10121 $cnt1$$Register, $cnt2$$Register, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10122 icnt2, $result$$Register, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10123 $vec$$XMMRegister, $tmp$$Register); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10124 } else { |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10125 // Small strings are loaded through stack if they cross page boundary. |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10126 __ string_indexof($str1$$Register, $str2$$Register, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10127 $cnt1$$Register, $cnt2$$Register, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10128 icnt2, $result$$Register, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10129 $vec$$XMMRegister, $tmp$$Register); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10130 } |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10131 %} |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10132 ins_pipe( pipe_slow ); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10133 %} |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10134 |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10135 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10136 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) |
681 | 10137 %{ |
10138 predicate(UseSSE42Intrinsics); | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10139 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10140 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10141 |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10142 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10143 ins_encode %{ |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10144 __ string_indexof($str1$$Register, $str2$$Register, |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10145 $cnt1$$Register, $cnt2$$Register, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10146 (-1), $result$$Register, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
10147 $vec$$XMMRegister, $tmp$$Register); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10148 %} |
681 | 10149 ins_pipe( pipe_slow ); |
10150 %} | |
10151 | |
10152 // fast string equals | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10153 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10154 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10155 %{ |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10156 match(Set result (StrEquals (Binary str1 str2) cnt)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10157 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10158 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10159 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10160 ins_encode %{ |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10161 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10162 $cnt$$Register, $result$$Register, $tmp3$$Register, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10163 $tmp1$$XMMRegister, $tmp2$$XMMRegister); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10164 %} |
0 | 10165 ins_pipe( pipe_slow ); |
10166 %} | |
10167 | |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
10168 // fast array equals |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10169 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10170 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) |
681 | 10171 %{ |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
10172 match(Set result (AryEq ary1 ary2)); |
681 | 10173 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
10174 //ins_cost(300); |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
10175 |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10176 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10177 ins_encode %{ |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10178 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10179 $tmp3$$Register, $result$$Register, $tmp4$$Register, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10180 $tmp1$$XMMRegister, $tmp2$$XMMRegister); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
824
diff
changeset
|
10181 %} |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
10182 ins_pipe( pipe_slow ); |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
10183 %} |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
10184 |
0 | 10185 //----------Control Flow Instructions------------------------------------------ |
10186 // Signed compare Instructions | |
10187 | |
10188 // XXX more variants!! | |
10189 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) | |
10190 %{ | |
10191 match(Set cr (CmpI op1 op2)); | |
10192 effect(DEF cr, USE op1, USE op2); | |
10193 | |
10194 format %{ "cmpl $op1, $op2" %} | |
10195 opcode(0x3B); /* Opcode 3B /r */ | |
10196 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); | |
10197 ins_pipe(ialu_cr_reg_reg); | |
10198 %} | |
10199 | |
10200 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) | |
10201 %{ | |
10202 match(Set cr (CmpI op1 op2)); | |
10203 | |
10204 format %{ "cmpl $op1, $op2" %} | |
10205 opcode(0x81, 0x07); /* Opcode 81 /7 */ | |
10206 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); | |
10207 ins_pipe(ialu_cr_reg_imm); | |
10208 %} | |
10209 | |
10210 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) | |
10211 %{ | |
10212 match(Set cr (CmpI op1 (LoadI op2))); | |
10213 | |
10214 ins_cost(500); // XXX | |
10215 format %{ "cmpl $op1, $op2" %} | |
10216 opcode(0x3B); /* Opcode 3B /r */ | |
10217 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); | |
10218 ins_pipe(ialu_cr_reg_mem); | |
10219 %} | |
10220 | |
10221 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) | |
10222 %{ | |
10223 match(Set cr (CmpI src zero)); | |
10224 | |
10225 format %{ "testl $src, $src" %} | |
10226 opcode(0x85); | |
10227 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); | |
10228 ins_pipe(ialu_cr_reg_imm); | |
10229 %} | |
10230 | |
10231 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) | |
10232 %{ | |
10233 match(Set cr (CmpI (AndI src con) zero)); | |
10234 | |
10235 format %{ "testl $src, $con" %} | |
10236 opcode(0xF7, 0x00); | |
10237 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); | |
10238 ins_pipe(ialu_cr_reg_imm); | |
10239 %} | |
10240 | |
10241 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) | |
10242 %{ | |
10243 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); | |
10244 | |
10245 format %{ "testl $src, $mem" %} | |
10246 opcode(0x85); | |
10247 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); | |
10248 ins_pipe(ialu_cr_reg_mem); | |
10249 %} | |
10250 | |
10251 // Unsigned compare Instructions; really, same as signed except they | |
10252 // produce an rFlagsRegU instead of rFlagsReg. | |
10253 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) | |
10254 %{ | |
10255 match(Set cr (CmpU op1 op2)); | |
10256 | |
10257 format %{ "cmpl $op1, $op2\t# unsigned" %} | |
10258 opcode(0x3B); /* Opcode 3B /r */ | |
10259 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); | |
10260 ins_pipe(ialu_cr_reg_reg); | |
10261 %} | |
10262 | |
10263 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) | |
10264 %{ | |
10265 match(Set cr (CmpU op1 op2)); | |
10266 | |
10267 format %{ "cmpl $op1, $op2\t# unsigned" %} | |
10268 opcode(0x81,0x07); /* Opcode 81 /7 */ | |
10269 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); | |
10270 ins_pipe(ialu_cr_reg_imm); | |
10271 %} | |
10272 | |
10273 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) | |
10274 %{ | |
10275 match(Set cr (CmpU op1 (LoadI op2))); | |
10276 | |
10277 ins_cost(500); // XXX | |
10278 format %{ "cmpl $op1, $op2\t# unsigned" %} | |
10279 opcode(0x3B); /* Opcode 3B /r */ | |
10280 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); | |
10281 ins_pipe(ialu_cr_reg_mem); | |
10282 %} | |
10283 | |
10284 // // // Cisc-spilled version of cmpU_rReg | |
10285 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) | |
10286 // //%{ | |
10287 // // match(Set cr (CmpU (LoadI op1) op2)); | |
10288 // // | |
10289 // // format %{ "CMPu $op1,$op2" %} | |
10290 // // ins_cost(500); | |
10291 // // opcode(0x39); /* Opcode 39 /r */ | |
10292 // // ins_encode( OpcP, reg_mem( op1, op2) ); | |
10293 // //%} | |
10294 | |
10295 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) | |
10296 %{ | |
10297 match(Set cr (CmpU src zero)); | |
10298 | |
10299 format %{ "testl $src, $src\t# unsigned" %} | |
10300 opcode(0x85); | |
10301 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); | |
10302 ins_pipe(ialu_cr_reg_imm); | |
10303 %} | |
10304 | |
10305 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) | |
10306 %{ | |
10307 match(Set cr (CmpP op1 op2)); | |
10308 | |
10309 format %{ "cmpq $op1, $op2\t# ptr" %} | |
10310 opcode(0x3B); /* Opcode 3B /r */ | |
10311 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); | |
10312 ins_pipe(ialu_cr_reg_reg); | |
10313 %} | |
10314 | |
10315 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) | |
10316 %{ | |
10317 match(Set cr (CmpP op1 (LoadP op2))); | |
10318 | |
10319 ins_cost(500); // XXX | |
10320 format %{ "cmpq $op1, $op2\t# ptr" %} | |
10321 opcode(0x3B); /* Opcode 3B /r */ | |
10322 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); | |
10323 ins_pipe(ialu_cr_reg_mem); | |
10324 %} | |
10325 | |
10326 // // // Cisc-spilled version of cmpP_rReg | |
10327 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) | |
10328 // //%{ | |
10329 // // match(Set cr (CmpP (LoadP op1) op2)); | |
10330 // // | |
10331 // // format %{ "CMPu $op1,$op2" %} | |
10332 // // ins_cost(500); | |
10333 // // opcode(0x39); /* Opcode 39 /r */ | |
10334 // // ins_encode( OpcP, reg_mem( op1, op2) ); | |
10335 // //%} | |
10336 | |
10337 // XXX this is generalized by compP_rReg_mem??? | |
10338 // Compare raw pointer (used in out-of-heap check). | |
10339 // Only works because non-oop pointers must be raw pointers | |
10340 // and raw pointers have no anti-dependencies. | |
10341 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) | |
10342 %{ | |
10343 predicate(!n->in(2)->in(2)->bottom_type()->isa_oop_ptr()); | |
10344 match(Set cr (CmpP op1 (LoadP op2))); | |
10345 | |
10346 format %{ "cmpq $op1, $op2\t# raw ptr" %} | |
10347 opcode(0x3B); /* Opcode 3B /r */ | |
10348 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); | |
10349 ins_pipe(ialu_cr_reg_mem); | |
10350 %} | |
10351 | |
10352 // This will generate a signed flags result. This should be OK since | |
10353 // any compare to a zero should be eq/neq. | |
10354 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) | |
10355 %{ | |
10356 match(Set cr (CmpP src zero)); | |
10357 | |
10358 format %{ "testq $src, $src\t# ptr" %} | |
10359 opcode(0x85); | |
10360 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); | |
10361 ins_pipe(ialu_cr_reg_imm); | |
10362 %} | |
10363 | |
10364 // This will generate a signed flags result. This should be OK since | |
10365 // any compare to a zero should be eq/neq. | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10366 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10367 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10368 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); |
0 | 10369 match(Set cr (CmpP (LoadP op) zero)); |
10370 | |
10371 ins_cost(500); // XXX | |
10372 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} | |
10373 opcode(0xF7); /* Opcode F7 /0 */ | |
10374 ins_encode(REX_mem_wide(op), | |
10375 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); | |
10376 ins_pipe(ialu_cr_reg_imm); | |
10377 %} | |
10378 | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10379 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10380 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10381 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10382 match(Set cr (CmpP (LoadP mem) zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10383 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10384 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10385 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10386 __ cmpq(r12, $mem$$Address); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10387 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10388 ins_pipe(ialu_cr_reg_mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10389 %} |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10390 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10391 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10392 %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10393 match(Set cr (CmpN op1 op2)); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10394 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10395 format %{ "cmpl $op1, $op2\t# compressed ptr" %} |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10396 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10397 ins_pipe(ialu_cr_reg_reg); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10398 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10399 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10400 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10401 %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10402 match(Set cr (CmpN src (LoadN mem))); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10403 |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10404 format %{ "cmpl $src, $mem\t# compressed ptr" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10405 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10406 __ cmpl($src$$Register, $mem$$Address); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10407 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10408 ins_pipe(ialu_cr_reg_mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10409 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10410 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10411 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10412 match(Set cr (CmpN op1 op2)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10413 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10414 format %{ "cmpl $op1, $op2\t# compressed ptr" %} |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10415 ins_encode %{ |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10416 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10417 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10418 ins_pipe(ialu_cr_reg_imm); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10419 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10420 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10421 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10422 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10423 match(Set cr (CmpN src (LoadN mem))); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10424 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10425 format %{ "cmpl $mem, $src\t# compressed ptr" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10426 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10427 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10428 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10429 ins_pipe(ialu_cr_reg_mem); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10430 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10431 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
10432 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
10433 match(Set cr (CmpN src zero)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
10434 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10435 format %{ "testl $src, $src\t# compressed ptr" %} |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
10436 ins_encode %{ __ testl($src$$Register, $src$$Register); %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
10437 ins_pipe(ialu_cr_reg_imm); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
10438 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
71
diff
changeset
|
10439 |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10440 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10441 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10442 predicate(Universe::narrow_oop_base() != NULL); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10443 match(Set cr (CmpN (LoadN mem) zero)); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10444 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10445 ins_cost(500); // XXX |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10446 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10447 ins_encode %{ |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10448 __ cmpl($mem$$Address, (int)0xFFFFFFFF); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10449 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10450 ins_pipe(ialu_cr_reg_mem); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10451 %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10452 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10453 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10454 %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10455 predicate(Universe::narrow_oop_base() == NULL); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10456 match(Set cr (CmpN (LoadN mem) zero)); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10457 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10458 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10459 ins_encode %{ |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
10460 __ cmpl(r12, $mem$$Address); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10461 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10462 ins_pipe(ialu_cr_reg_mem); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10463 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
10464 |
0 | 10465 // Yanked all unsigned pointer compare operations. |
10466 // Pointer compares are done with CmpP which is already unsigned. | |
10467 | |
10468 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) | |
10469 %{ | |
10470 match(Set cr (CmpL op1 op2)); | |
10471 | |
10472 format %{ "cmpq $op1, $op2" %} | |
10473 opcode(0x3B); /* Opcode 3B /r */ | |
10474 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); | |
10475 ins_pipe(ialu_cr_reg_reg); | |
10476 %} | |
10477 | |
10478 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) | |
10479 %{ | |
10480 match(Set cr (CmpL op1 op2)); | |
10481 | |
10482 format %{ "cmpq $op1, $op2" %} | |
10483 opcode(0x81, 0x07); /* Opcode 81 /7 */ | |
10484 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); | |
10485 ins_pipe(ialu_cr_reg_imm); | |
10486 %} | |
10487 | |
10488 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) | |
10489 %{ | |
10490 match(Set cr (CmpL op1 (LoadL op2))); | |
10491 | |
10492 format %{ "cmpq $op1, $op2" %} | |
10493 opcode(0x3B); /* Opcode 3B /r */ | |
10494 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); | |
10495 ins_pipe(ialu_cr_reg_mem); | |
10496 %} | |
10497 | |
10498 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) | |
10499 %{ | |
10500 match(Set cr (CmpL src zero)); | |
10501 | |
10502 format %{ "testq $src, $src" %} | |
10503 opcode(0x85); | |
10504 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); | |
10505 ins_pipe(ialu_cr_reg_imm); | |
10506 %} | |
10507 | |
10508 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) | |
10509 %{ | |
10510 match(Set cr (CmpL (AndL src con) zero)); | |
10511 | |
10512 format %{ "testq $src, $con\t# long" %} | |
10513 opcode(0xF7, 0x00); | |
10514 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); | |
10515 ins_pipe(ialu_cr_reg_imm); | |
10516 %} | |
10517 | |
10518 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) | |
10519 %{ | |
10520 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); | |
10521 | |
10522 format %{ "testq $src, $mem" %} | |
10523 opcode(0x85); | |
10524 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); | |
10525 ins_pipe(ialu_cr_reg_mem); | |
10526 %} | |
10527 | |
10528 // Manifest a CmpL result in an integer register. Very painful. | |
10529 // This is the test to avoid. | |
10530 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) | |
10531 %{ | |
10532 match(Set dst (CmpL3 src1 src2)); | |
10533 effect(KILL flags); | |
10534 | |
10535 ins_cost(275); // XXX | |
10536 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" | |
10537 "movl $dst, -1\n\t" | |
10538 "jl,s done\n\t" | |
10539 "setne $dst\n\t" | |
10540 "movzbl $dst, $dst\n\t" | |
10541 "done:" %} | |
10542 ins_encode(cmpl3_flag(src1, src2, dst)); | |
10543 ins_pipe(pipe_slow); | |
10544 %} | |
10545 | |
10546 //----------Max and Min-------------------------------------------------------- | |
10547 // Min Instructions | |
10548 | |
10549 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) | |
10550 %{ | |
10551 effect(USE_DEF dst, USE src, USE cr); | |
10552 | |
10553 format %{ "cmovlgt $dst, $src\t# min" %} | |
10554 opcode(0x0F, 0x4F); | |
10555 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); | |
10556 ins_pipe(pipe_cmov_reg); | |
10557 %} | |
10558 | |
10559 | |
10560 instruct minI_rReg(rRegI dst, rRegI src) | |
10561 %{ | |
10562 match(Set dst (MinI dst src)); | |
10563 | |
10564 ins_cost(200); | |
10565 expand %{ | |
10566 rFlagsReg cr; | |
10567 compI_rReg(cr, dst, src); | |
10568 cmovI_reg_g(dst, src, cr); | |
10569 %} | |
10570 %} | |
10571 | |
10572 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) | |
10573 %{ | |
10574 effect(USE_DEF dst, USE src, USE cr); | |
10575 | |
10576 format %{ "cmovllt $dst, $src\t# max" %} | |
10577 opcode(0x0F, 0x4C); | |
10578 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); | |
10579 ins_pipe(pipe_cmov_reg); | |
10580 %} | |
10581 | |
10582 | |
10583 instruct maxI_rReg(rRegI dst, rRegI src) | |
10584 %{ | |
10585 match(Set dst (MaxI dst src)); | |
10586 | |
10587 ins_cost(200); | |
10588 expand %{ | |
10589 rFlagsReg cr; | |
10590 compI_rReg(cr, dst, src); | |
10591 cmovI_reg_l(dst, src, cr); | |
10592 %} | |
10593 %} | |
10594 | |
10595 // ============================================================================ | |
10596 // Branch Instructions | |
10597 | |
10598 // Jump Direct - Label defines a relative address from JMP+1 | |
10599 instruct jmpDir(label labl) | |
10600 %{ | |
10601 match(Goto); | |
10602 effect(USE labl); | |
10603 | |
10604 ins_cost(300); | |
10605 format %{ "jmp $labl" %} | |
10606 size(5); | |
3851 | 10607 ins_encode %{ |
10608 Label* L = $labl$$label; | |
10609 __ jmp(*L, false); // Always long jump | |
10610 %} | |
0 | 10611 ins_pipe(pipe_jmp); |
10612 %} | |
10613 | |
10614 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | |
10615 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) | |
10616 %{ | |
10617 match(If cop cr); | |
10618 effect(USE labl); | |
10619 | |
10620 ins_cost(300); | |
10621 format %{ "j$cop $labl" %} | |
10622 size(6); | |
3851 | 10623 ins_encode %{ |
10624 Label* L = $labl$$label; | |
10625 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
10626 %} | |
0 | 10627 ins_pipe(pipe_jcc); |
10628 %} | |
10629 | |
10630 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | |
10631 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) | |
10632 %{ | |
10633 match(CountedLoopEnd cop cr); | |
10634 effect(USE labl); | |
10635 | |
10636 ins_cost(300); | |
10637 format %{ "j$cop $labl\t# loop end" %} | |
10638 size(6); | |
3851 | 10639 ins_encode %{ |
10640 Label* L = $labl$$label; | |
10641 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
10642 %} | |
0 | 10643 ins_pipe(pipe_jcc); |
10644 %} | |
10645 | |
10646 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10647 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ |
0 | 10648 match(CountedLoopEnd cop cmp); |
10649 effect(USE labl); | |
10650 | |
10651 ins_cost(300); | |
10652 format %{ "j$cop,u $labl\t# loop end" %} | |
10653 size(6); | |
3851 | 10654 ins_encode %{ |
10655 Label* L = $labl$$label; | |
10656 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
10657 %} | |
0 | 10658 ins_pipe(pipe_jcc); |
10659 %} | |
10660 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10661 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10662 match(CountedLoopEnd cop cmp); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10663 effect(USE labl); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10664 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10665 ins_cost(200); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10666 format %{ "j$cop,u $labl\t# loop end" %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10667 size(6); |
3851 | 10668 ins_encode %{ |
10669 Label* L = $labl$$label; | |
10670 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
10671 %} | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10672 ins_pipe(pipe_jcc); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10673 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10674 |
0 | 10675 // Jump Direct Conditional - using unsigned comparison |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10676 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ |
0 | 10677 match(If cop cmp); |
10678 effect(USE labl); | |
10679 | |
10680 ins_cost(300); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10681 format %{ "j$cop,u $labl" %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10682 size(6); |
3851 | 10683 ins_encode %{ |
10684 Label* L = $labl$$label; | |
10685 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
10686 %} | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10687 ins_pipe(pipe_jcc); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10688 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10689 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10690 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10691 match(If cop cmp); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10692 effect(USE labl); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10693 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10694 ins_cost(200); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10695 format %{ "j$cop,u $labl" %} |
0 | 10696 size(6); |
3851 | 10697 ins_encode %{ |
10698 Label* L = $labl$$label; | |
10699 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
10700 %} | |
0 | 10701 ins_pipe(pipe_jcc); |
10702 %} | |
10703 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10704 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10705 match(If cop cmp); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10706 effect(USE labl); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10707 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10708 ins_cost(200); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10709 format %{ $$template |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10710 if ($cop$$cmpcode == Assembler::notEqual) { |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10711 $$emit$$"jp,u $labl\n\t" |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10712 $$emit$$"j$cop,u $labl" |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10713 } else { |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10714 $$emit$$"jp,u done\n\t" |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10715 $$emit$$"j$cop,u $labl\n\t" |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10716 $$emit$$"done:" |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10717 } |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10718 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10719 ins_encode %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10720 Label* l = $labl$$label; |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10721 if ($cop$$cmpcode == Assembler::notEqual) { |
3851 | 10722 __ jcc(Assembler::parity, *l, false); |
10723 __ jcc(Assembler::notEqual, *l, false); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10724 } else if ($cop$$cmpcode == Assembler::equal) { |
3851 | 10725 Label done; |
10726 __ jccb(Assembler::parity, done); | |
10727 __ jcc(Assembler::equal, *l, false); | |
10728 __ bind(done); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10729 } else { |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10730 ShouldNotReachHere(); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10731 } |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10732 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10733 ins_pipe(pipe_jcc); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10734 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10735 |
0 | 10736 // ============================================================================ |
10737 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary | |
10738 // superklass array for an instance of the superklass. Set a hidden | |
10739 // internal cache on a hit (cache is checked with exposed code in | |
10740 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The | |
10741 // encoding ALSO sets flags. | |
10742 | |
10743 instruct partialSubtypeCheck(rdi_RegP result, | |
10744 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, | |
10745 rFlagsReg cr) | |
10746 %{ | |
10747 match(Set result (PartialSubtypeCheck sub super)); | |
10748 effect(KILL rcx, KILL cr); | |
10749 | |
10750 ins_cost(1100); // slightly larger than the next version | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4761
diff
changeset
|
10751 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" |
0 | 10752 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" |
10753 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" | |
10754 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" | |
10755 "jne,s miss\t\t# Missed: rdi not-zero\n\t" | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4761
diff
changeset
|
10756 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" |
0 | 10757 "xorq $result, $result\t\t Hit: rdi zero\n\t" |
10758 "miss:\t" %} | |
10759 | |
10760 opcode(0x1); // Force a XOR of RDI | |
10761 ins_encode(enc_PartialSubtypeCheck()); | |
10762 ins_pipe(pipe_slow); | |
10763 %} | |
10764 | |
10765 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, | |
10766 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, | |
10767 immP0 zero, | |
10768 rdi_RegP result) | |
10769 %{ | |
10770 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); | |
10771 effect(KILL rcx, KILL result); | |
10772 | |
10773 ins_cost(1000); | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4761
diff
changeset
|
10774 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" |
0 | 10775 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" |
10776 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" | |
10777 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" | |
10778 "jne,s miss\t\t# Missed: flags nz\n\t" | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4761
diff
changeset
|
10779 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" |
0 | 10780 "miss:\t" %} |
10781 | |
10782 opcode(0x0); // No need to XOR RDI | |
10783 ins_encode(enc_PartialSubtypeCheck()); | |
10784 ins_pipe(pipe_slow); | |
10785 %} | |
10786 | |
10787 // ============================================================================ | |
10788 // Branch Instructions -- short offset versions | |
10789 // | |
10790 // These instructions are used to replace jumps of a long offset (the default | |
10791 // match) with jumps of a shorter offset. These instructions are all tagged | |
10792 // with the ins_short_branch attribute, which causes the ADLC to suppress the | |
10793 // match rules in general matching. Instead, the ADLC generates a conversion | |
10794 // method in the MachNode which can be used to do in-place replacement of the | |
10795 // long variant with the shorter variant. The compiler will determine if a | |
10796 // branch can be taken by the is_short_branch_offset() predicate in the machine | |
10797 // specific code section of the file. | |
10798 | |
10799 // Jump Direct - Label defines a relative address from JMP+1 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10800 instruct jmpDir_short(label labl) %{ |
0 | 10801 match(Goto); |
10802 effect(USE labl); | |
10803 | |
10804 ins_cost(300); | |
10805 format %{ "jmp,s $labl" %} | |
10806 size(2); | |
3851 | 10807 ins_encode %{ |
10808 Label* L = $labl$$label; | |
10809 __ jmpb(*L); | |
10810 %} | |
0 | 10811 ins_pipe(pipe_jmp); |
10812 ins_short_branch(1); | |
10813 %} | |
10814 | |
10815 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10816 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ |
0 | 10817 match(If cop cr); |
10818 effect(USE labl); | |
10819 | |
10820 ins_cost(300); | |
10821 format %{ "j$cop,s $labl" %} | |
10822 size(2); | |
3851 | 10823 ins_encode %{ |
10824 Label* L = $labl$$label; | |
10825 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
10826 %} | |
0 | 10827 ins_pipe(pipe_jcc); |
10828 ins_short_branch(1); | |
10829 %} | |
10830 | |
10831 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10832 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ |
0 | 10833 match(CountedLoopEnd cop cr); |
10834 effect(USE labl); | |
10835 | |
10836 ins_cost(300); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10837 format %{ "j$cop,s $labl\t# loop end" %} |
0 | 10838 size(2); |
3851 | 10839 ins_encode %{ |
10840 Label* L = $labl$$label; | |
10841 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
10842 %} | |
0 | 10843 ins_pipe(pipe_jcc); |
10844 ins_short_branch(1); | |
10845 %} | |
10846 | |
10847 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10848 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10849 match(CountedLoopEnd cop cmp); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10850 effect(USE labl); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10851 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10852 ins_cost(300); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10853 format %{ "j$cop,us $labl\t# loop end" %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10854 size(2); |
3851 | 10855 ins_encode %{ |
10856 Label* L = $labl$$label; | |
10857 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
10858 %} | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10859 ins_pipe(pipe_jcc); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10860 ins_short_branch(1); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10861 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10862 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10863 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ |
0 | 10864 match(CountedLoopEnd cop cmp); |
10865 effect(USE labl); | |
10866 | |
10867 ins_cost(300); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10868 format %{ "j$cop,us $labl\t# loop end" %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10869 size(2); |
3851 | 10870 ins_encode %{ |
10871 Label* L = $labl$$label; | |
10872 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
10873 %} | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10874 ins_pipe(pipe_jcc); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10875 ins_short_branch(1); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10876 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10877 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10878 // Jump Direct Conditional - using unsigned comparison |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10879 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10880 match(If cop cmp); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10881 effect(USE labl); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10882 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10883 ins_cost(300); |
0 | 10884 format %{ "j$cop,us $labl" %} |
10885 size(2); | |
3851 | 10886 ins_encode %{ |
10887 Label* L = $labl$$label; | |
10888 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
10889 %} | |
0 | 10890 ins_pipe(pipe_jcc); |
10891 ins_short_branch(1); | |
10892 %} | |
10893 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10894 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ |
0 | 10895 match(If cop cmp); |
10896 effect(USE labl); | |
10897 | |
10898 ins_cost(300); | |
10899 format %{ "j$cop,us $labl" %} | |
10900 size(2); | |
3851 | 10901 ins_encode %{ |
10902 Label* L = $labl$$label; | |
10903 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
10904 %} | |
0 | 10905 ins_pipe(pipe_jcc); |
10906 ins_short_branch(1); | |
10907 %} | |
10908 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10909 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10910 match(If cop cmp); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10911 effect(USE labl); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10912 |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10913 ins_cost(300); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10914 format %{ $$template |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10915 if ($cop$$cmpcode == Assembler::notEqual) { |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10916 $$emit$$"jp,u,s $labl\n\t" |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10917 $$emit$$"j$cop,u,s $labl" |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10918 } else { |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10919 $$emit$$"jp,u,s done\n\t" |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10920 $$emit$$"j$cop,u,s $labl\n\t" |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10921 $$emit$$"done:" |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10922 } |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10923 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10924 size(4); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10925 ins_encode %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10926 Label* l = $labl$$label; |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10927 if ($cop$$cmpcode == Assembler::notEqual) { |
3851 | 10928 __ jccb(Assembler::parity, *l); |
10929 __ jccb(Assembler::notEqual, *l); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10930 } else if ($cop$$cmpcode == Assembler::equal) { |
3851 | 10931 Label done; |
10932 __ jccb(Assembler::parity, done); | |
10933 __ jccb(Assembler::equal, *l); | |
10934 __ bind(done); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10935 } else { |
3851 | 10936 ShouldNotReachHere(); |
10937 } | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10938 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10939 ins_pipe(pipe_jcc); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10940 ins_short_branch(1); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10941 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
403
diff
changeset
|
10942 |
0 | 10943 // ============================================================================ |
10944 // inlined locking and unlocking | |
10945 | |
10946 instruct cmpFastLock(rFlagsReg cr, | |
4777 | 10947 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) |
0 | 10948 %{ |
10949 match(Set cr (FastLock object box)); | |
4777 | 10950 effect(TEMP tmp, TEMP scr, USE_KILL box); |
0 | 10951 |
10952 ins_cost(300); | |
4777 | 10953 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} |
0 | 10954 ins_encode(Fast_Lock(object, box, tmp, scr)); |
10955 ins_pipe(pipe_slow); | |
10956 %} | |
10957 | |
10958 instruct cmpFastUnlock(rFlagsReg cr, | |
10959 rRegP object, rax_RegP box, rRegP tmp) | |
10960 %{ | |
10961 match(Set cr (FastUnlock object box)); | |
4777 | 10962 effect(TEMP tmp, USE_KILL box); |
0 | 10963 |
10964 ins_cost(300); | |
4777 | 10965 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} |
0 | 10966 ins_encode(Fast_Unlock(object, box, tmp)); |
10967 ins_pipe(pipe_slow); | |
10968 %} | |
10969 | |
10970 | |
10971 // ============================================================================ | |
10972 // Safepoint Instructions | |
10973 instruct safePoint_poll(rFlagsReg cr) | |
10974 %{ | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10975 predicate(!Assembler::is_polling_page_far()); |
0 | 10976 match(SafePoint); |
10977 effect(KILL cr); | |
10978 | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10979 format %{ "testl rax, [rip + #offset_to_poll_page]\t" |
0 | 10980 "# Safepoint: poll for GC" %} |
10981 ins_cost(125); | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10982 ins_encode %{ |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10983 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10984 __ testl(rax, addr); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10985 %} |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10986 ins_pipe(ialu_reg_mem); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10987 %} |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10988 |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10989 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10990 %{ |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10991 predicate(Assembler::is_polling_page_far()); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10992 match(SafePoint poll); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10993 effect(KILL cr, USE poll); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10994 |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10995 format %{ "testl rax, [$poll]\t" |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10996 "# Safepoint: poll for GC" %} |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10997 ins_cost(125); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10998 ins_encode %{ |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
10999 __ relocate(relocInfo::poll_type); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
11000 __ testl(rax, Address($poll$$Register, 0)); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2401
diff
changeset
|
11001 %} |
0 | 11002 ins_pipe(ialu_reg_mem); |
11003 %} | |
11004 | |
11005 // ============================================================================ | |
11006 // Procedure Call/Return Instructions | |
11007 // Call Java Static Instruction | |
11008 // Note: If this code changes, the corresponding ret_addr_offset() and | |
11009 // compute_padding() functions will have to be adjusted. | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11010 instruct CallStaticJavaDirect(method meth) %{ |
0 | 11011 match(CallStaticJava); |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11012 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); |
0 | 11013 effect(USE meth); |
11014 | |
11015 ins_cost(300); | |
11016 format %{ "call,static " %} | |
11017 opcode(0xE8); /* E8 cd */ | |
11018 ins_encode(Java_Static_Call(meth), call_epilog); | |
11019 ins_pipe(pipe_slow); | |
11020 ins_alignment(4); | |
11021 %} | |
11022 | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11023 // Call Java Static Instruction (method handle version) |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11024 // Note: If this code changes, the corresponding ret_addr_offset() and |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11025 // compute_padding() functions will have to be adjusted. |
1567 | 11026 instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11027 match(CallStaticJava); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11028 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11029 effect(USE meth); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11030 // RBP is saved by all callees (for interpreter stack correction). |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11031 // We use it here for a similar purpose, in {preserve,restore}_SP. |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11032 |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11033 ins_cost(300); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11034 format %{ "call,static/MethodHandle " %} |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11035 opcode(0xE8); /* E8 cd */ |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11036 ins_encode(preserve_SP, |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11037 Java_Static_Call(meth), |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11038 restore_SP, |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11039 call_epilog); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11040 ins_pipe(pipe_slow); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11041 ins_alignment(4); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11042 %} |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
989
diff
changeset
|
11043 |
0 | 11044 // Call Java Dynamic Instruction |
11045 // Note: If this code changes, the corresponding ret_addr_offset() and | |
11046 // compute_padding() functions will have to be adjusted. | |
11047 instruct CallDynamicJavaDirect(method meth) | |
11048 %{ | |
11049 match(CallDynamicJava); | |
11050 effect(USE meth); | |
11051 | |
11052 ins_cost(300); | |
11053 format %{ "movq rax, #Universe::non_oop_word()\n\t" | |
11054 "call,dynamic " %} | |
11055 opcode(0xE8); /* E8 cd */ | |
11056 ins_encode(Java_Dynamic_Call(meth), call_epilog); | |
11057 ins_pipe(pipe_slow); | |
11058 ins_alignment(4); | |
11059 %} | |
11060 | |
11061 // Call Runtime Instruction | |
11062 instruct CallRuntimeDirect(method meth) | |
11063 %{ | |
11064 match(CallRuntime); | |
11065 effect(USE meth); | |
11066 | |
11067 ins_cost(300); | |
11068 format %{ "call,runtime " %} | |
11069 opcode(0xE8); /* E8 cd */ | |
11070 ins_encode(Java_To_Runtime(meth)); | |
11071 ins_pipe(pipe_slow); | |
11072 %} | |
11073 | |
11074 // Call runtime without safepoint | |
11075 instruct CallLeafDirect(method meth) | |
11076 %{ | |
11077 match(CallLeaf); | |
11078 effect(USE meth); | |
11079 | |
11080 ins_cost(300); | |
11081 format %{ "call_leaf,runtime " %} | |
11082 opcode(0xE8); /* E8 cd */ | |
11083 ins_encode(Java_To_Runtime(meth)); | |
11084 ins_pipe(pipe_slow); | |
11085 %} | |
11086 | |
11087 // Call runtime without safepoint | |
11088 instruct CallLeafNoFPDirect(method meth) | |
11089 %{ | |
11090 match(CallLeafNoFP); | |
11091 effect(USE meth); | |
11092 | |
11093 ins_cost(300); | |
11094 format %{ "call_leaf_nofp,runtime " %} | |
11095 opcode(0xE8); /* E8 cd */ | |
11096 ins_encode(Java_To_Runtime(meth)); | |
11097 ins_pipe(pipe_slow); | |
11098 %} | |
11099 | |
11100 // Return Instruction | |
11101 // Remove the return address & jump to it. | |
11102 // Notice: We always emit a nop after a ret to make sure there is room | |
11103 // for safepoint patching | |
11104 instruct Ret() | |
11105 %{ | |
11106 match(Return); | |
11107 | |
11108 format %{ "ret" %} | |
11109 opcode(0xC3); | |
11110 ins_encode(OpcP); | |
11111 ins_pipe(pipe_jmp); | |
11112 %} | |
11113 | |
11114 // Tail Call; Jump from runtime stub to Java code. | |
11115 // Also known as an 'interprocedural jump'. | |
11116 // Target of jump will eventually return to caller. | |
11117 // TailJump below removes the return address. | |
11118 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) | |
11119 %{ | |
11120 match(TailCall jump_target method_oop); | |
11121 | |
11122 ins_cost(300); | |
11123 format %{ "jmp $jump_target\t# rbx holds method oop" %} | |
11124 opcode(0xFF, 0x4); /* Opcode FF /4 */ | |
11125 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); | |
11126 ins_pipe(pipe_jmp); | |
11127 %} | |
11128 | |
11129 // Tail Jump; remove the return address; jump to target. | |
11130 // TailCall above leaves the return address around. | |
11131 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) | |
11132 %{ | |
11133 match(TailJump jump_target ex_oop); | |
11134 | |
11135 ins_cost(300); | |
11136 format %{ "popq rdx\t# pop return address\n\t" | |
11137 "jmp $jump_target" %} | |
11138 opcode(0xFF, 0x4); /* Opcode FF /4 */ | |
11139 ins_encode(Opcode(0x5a), // popq rdx | |
11140 REX_reg(jump_target), OpcP, reg_opc(jump_target)); | |
11141 ins_pipe(pipe_jmp); | |
11142 %} | |
11143 | |
11144 // Create exception oop: created by stack-crawling runtime code. | |
11145 // Created exception is now available to this handler, and is setup | |
11146 // just prior to jumping to this handler. No code emitted. | |
11147 instruct CreateException(rax_RegP ex_oop) | |
11148 %{ | |
11149 match(Set ex_oop (CreateEx)); | |
11150 | |
11151 size(0); | |
11152 // use the following format syntax | |
11153 format %{ "# exception oop is in rax; no code emitted" %} | |
11154 ins_encode(); | |
11155 ins_pipe(empty); | |
11156 %} | |
11157 | |
11158 // Rethrow exception: | |
11159 // The exception oop will come in the first argument position. | |
11160 // Then JUMP (not call) to the rethrow stub code. | |
11161 instruct RethrowException() | |
11162 %{ | |
11163 match(Rethrow); | |
11164 | |
11165 // use the following format syntax | |
11166 format %{ "jmp rethrow_stub" %} | |
11167 ins_encode(enc_rethrow); | |
11168 ins_pipe(pipe_jmp); | |
11169 %} | |
11170 | |
11171 | |
4950 | 11172 // ============================================================================ |
11173 // This name is KNOWN by the ADLC and cannot be changed. | |
11174 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type | |
11175 // for this guy. | |
11176 instruct tlsLoadP(r15_RegP dst) %{ | |
11177 match(Set dst (ThreadLocal)); | |
11178 effect(DEF dst); | |
11179 | |
11180 size(0); | |
11181 format %{ "# TLS is in R15" %} | |
11182 ins_encode( /*empty encoding*/ ); | |
11183 ins_pipe(ialu_reg_reg); | |
11184 %} | |
11185 | |
11186 | |
0 | 11187 //----------PEEPHOLE RULES----------------------------------------------------- |
11188 // These must follow all instruction definitions as they use the names | |
11189 // defined in the instructions definitions. | |
11190 // | |
605 | 11191 // peepmatch ( root_instr_name [preceding_instruction]* ); |
0 | 11192 // |
11193 // peepconstraint %{ | |
11194 // (instruction_number.operand_name relational_op instruction_number.operand_name | |
11195 // [, ...] ); | |
11196 // // instruction numbers are zero-based using left to right order in peepmatch | |
11197 // | |
11198 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); | |
11199 // // provide an instruction_number.operand_name for each operand that appears | |
11200 // // in the replacement instruction's match rule | |
11201 // | |
11202 // ---------VM FLAGS--------------------------------------------------------- | |
11203 // | |
11204 // All peephole optimizations can be turned off using -XX:-OptoPeephole | |
11205 // | |
11206 // Each peephole rule is given an identifying number starting with zero and | |
11207 // increasing by one in the order seen by the parser. An individual peephole | |
11208 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# | |
11209 // on the command-line. | |
11210 // | |
11211 // ---------CURRENT LIMITATIONS---------------------------------------------- | |
11212 // | |
11213 // Only match adjacent instructions in same basic block | |
11214 // Only equality constraints | |
11215 // Only constraints between operands, not (0.dest_reg == RAX_enc) | |
11216 // Only one replacement instruction | |
11217 // | |
11218 // ---------EXAMPLE---------------------------------------------------------- | |
11219 // | |
11220 // // pertinent parts of existing instructions in architecture description | |
11221 // instruct movI(rRegI dst, rRegI src) | |
11222 // %{ | |
11223 // match(Set dst (CopyI src)); | |
11224 // %} | |
11225 // | |
11226 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) | |
11227 // %{ | |
11228 // match(Set dst (AddI dst src)); | |
11229 // effect(KILL cr); | |
11230 // %} | |
11231 // | |
11232 // // Change (inc mov) to lea | |
11233 // peephole %{ | |
11234 // // increment preceeded by register-register move | |
11235 // peepmatch ( incI_rReg movI ); | |
11236 // // require that the destination register of the increment | |
11237 // // match the destination register of the move | |
11238 // peepconstraint ( 0.dst == 1.dst ); | |
11239 // // construct a replacement instruction that sets | |
11240 // // the destination to ( move's source register + one ) | |
11241 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); | |
11242 // %} | |
11243 // | |
11244 | |
11245 // Implementation no longer uses movX instructions since | |
11246 // machine-independent system no longer uses CopyX nodes. | |
11247 // | |
11248 // peephole | |
11249 // %{ | |
11250 // peepmatch (incI_rReg movI); | |
11251 // peepconstraint (0.dst == 1.dst); | |
11252 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); | |
11253 // %} | |
11254 | |
11255 // peephole | |
11256 // %{ | |
11257 // peepmatch (decI_rReg movI); | |
11258 // peepconstraint (0.dst == 1.dst); | |
11259 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); | |
11260 // %} | |
11261 | |
11262 // peephole | |
11263 // %{ | |
11264 // peepmatch (addI_rReg_imm movI); | |
11265 // peepconstraint (0.dst == 1.dst); | |
11266 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); | |
11267 // %} | |
11268 | |
11269 // peephole | |
11270 // %{ | |
11271 // peepmatch (incL_rReg movL); | |
11272 // peepconstraint (0.dst == 1.dst); | |
11273 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); | |
11274 // %} | |
11275 | |
11276 // peephole | |
11277 // %{ | |
11278 // peepmatch (decL_rReg movL); | |
11279 // peepconstraint (0.dst == 1.dst); | |
11280 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); | |
11281 // %} | |
11282 | |
11283 // peephole | |
11284 // %{ | |
11285 // peepmatch (addL_rReg_imm movL); | |
11286 // peepconstraint (0.dst == 1.dst); | |
11287 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); | |
11288 // %} | |
11289 | |
11290 // peephole | |
11291 // %{ | |
11292 // peepmatch (addP_rReg_imm movP); | |
11293 // peepconstraint (0.dst == 1.dst); | |
11294 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); | |
11295 // %} | |
11296 | |
11297 // // Change load of spilled value to only a spill | |
11298 // instruct storeI(memory mem, rRegI src) | |
11299 // %{ | |
11300 // match(Set mem (StoreI mem src)); | |
11301 // %} | |
11302 // | |
11303 // instruct loadI(rRegI dst, memory mem) | |
11304 // %{ | |
11305 // match(Set dst (LoadI mem)); | |
11306 // %} | |
11307 // | |
11308 | |
11309 peephole | |
11310 %{ | |
11311 peepmatch (loadI storeI); | |
11312 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); | |
11313 peepreplace (storeI(1.mem 1.mem 1.src)); | |
11314 %} | |
11315 | |
11316 peephole | |
11317 %{ | |
11318 peepmatch (loadL storeL); | |
11319 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); | |
11320 peepreplace (storeL(1.mem 1.mem 1.src)); | |
11321 %} | |
11322 | |
11323 //----------SMARTSPILL RULES--------------------------------------------------- | |
11324 // These must follow all instruction definitions as they use the names | |
11325 // defined in the instructions definitions. |