Print this page
rev 1025 : imported patch indy.compiler.patch
Split |
Close |
Expand all |
Collapse all |
--- old/src/cpu/x86/vm/x86_64.ad
+++ new/src/cpu/x86/vm/x86_64.ad
1 1 //
2 2 // Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
3 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 //
5 5 // This code is free software; you can redistribute it and/or modify it
6 6 // under the terms of the GNU General Public License version 2 only, as
7 7 // published by the Free Software Foundation.
8 8 //
9 9 // This code is distributed in the hope that it will be useful, but WITHOUT
10 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 12 // version 2 for more details (a copy is included in the LICENSE file that
13 13 // accompanied this code).
14 14 //
15 15 // You should have received a copy of the GNU General Public License version
16 16 // 2 along with this work; if not, write to the Free Software Foundation,
17 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 18 //
19 19 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 20 // CA 95054 USA or visit www.sun.com if you need additional information or
21 21 // have any questions.
22 22 //
23 23 //
24 24
25 25 // AMD64 Architecture Description File
26 26
27 27 //----------REGISTER DEFINITION BLOCK------------------------------------------
28 28 // This information is used by the matcher and the register allocator to
29 29 // describe individual registers and classes of registers within the target
30 30 // archtecture.
31 31
32 32 register %{
33 33 //----------Architecture Description Register Definitions----------------------
34 34 // General Registers
35 35 // "reg_def" name ( register save type, C convention save type,
36 36 // ideal register type, encoding );
37 37 // Register Save Types:
38 38 //
39 39 // NS = No-Save: The register allocator assumes that these registers
40 40 // can be used without saving upon entry to the method, &
41 41 // that they do not need to be saved at call sites.
42 42 //
43 43 // SOC = Save-On-Call: The register allocator assumes that these registers
44 44 // can be used without saving upon entry to the method,
45 45 // but that they must be saved at call sites.
46 46 //
47 47 // SOE = Save-On-Entry: The register allocator assumes that these registers
48 48 // must be saved before using them upon entry to the
49 49 // method, but they do not need to be saved at call
50 50 // sites.
51 51 //
52 52 // AS = Always-Save: The register allocator assumes that these registers
53 53 // must be saved before using them upon entry to the
54 54 // method, & that they must be saved at call sites.
55 55 //
56 56 // Ideal Register Type is used to determine how to save & restore a
57 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
58 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
59 59 //
60 60 // The encoding number is the actual bit-pattern placed into the opcodes.
61 61
62 62 // General Registers
63 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when
64 64 // used as byte registers)
65 65
66 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code
67 67 // Turn off SOE in java-code due to frequent use of uncommon-traps.
68 68 // Now that allocator is better, turn on RSI and RDI as SOE registers.
69 69
70 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg());
71 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next());
72 72
73 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg());
74 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next());
75 75
76 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg());
77 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next());
78 78
79 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg());
80 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next());
81 81
82 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg());
83 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next());
84 84
85 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code
86 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg());
87 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next());
88 88
89 89 #ifdef _WIN64
90 90
91 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg());
92 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next());
93 93
94 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg());
95 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next());
96 96
97 97 #else
98 98
99 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg());
100 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next());
101 101
102 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg());
103 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next());
104 104
105 105 #endif
106 106
107 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg());
108 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next());
109 109
110 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg());
111 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next());
112 112
113 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg());
114 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
115 115
116 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg());
117 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
118 118
119 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg());
120 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next());
121 121
122 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg());
123 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next());
124 124
125 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg());
126 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next());
127 127
128 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg());
129 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next());
130 130
131 131
132 132 // Floating Point Registers
133 133
134 134 // XMM registers. 128-bit registers or 4 words each, labeled (a)-d.
135 135 // Word a in each register holds a Float, words ab hold a Double. We
136 136 // currently do not use the SIMD capabilities, so registers cd are
137 137 // unused at the moment.
138 138 // XMM8-XMM15 must be encoded with REX.
139 139 // Linux ABI: No register preserved across function calls
140 140 // XMM0-XMM7 might hold parameters
141 141 // Windows ABI: XMM6-XMM15 preserved across function calls
142 142 // XMM0-XMM3 might hold parameters
143 143
144 144 reg_def XMM0 (SOC, SOC, Op_RegF, 0, xmm0->as_VMReg());
145 145 reg_def XMM0_H (SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next());
146 146
147 147 reg_def XMM1 (SOC, SOC, Op_RegF, 1, xmm1->as_VMReg());
148 148 reg_def XMM1_H (SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next());
149 149
150 150 reg_def XMM2 (SOC, SOC, Op_RegF, 2, xmm2->as_VMReg());
151 151 reg_def XMM2_H (SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next());
152 152
153 153 reg_def XMM3 (SOC, SOC, Op_RegF, 3, xmm3->as_VMReg());
154 154 reg_def XMM3_H (SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next());
155 155
156 156 reg_def XMM4 (SOC, SOC, Op_RegF, 4, xmm4->as_VMReg());
157 157 reg_def XMM4_H (SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next());
158 158
159 159 reg_def XMM5 (SOC, SOC, Op_RegF, 5, xmm5->as_VMReg());
160 160 reg_def XMM5_H (SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next());
161 161
162 162 #ifdef _WIN64
163 163
164 164 reg_def XMM6 (SOC, SOE, Op_RegF, 6, xmm6->as_VMReg());
165 165 reg_def XMM6_H (SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next());
166 166
167 167 reg_def XMM7 (SOC, SOE, Op_RegF, 7, xmm7->as_VMReg());
168 168 reg_def XMM7_H (SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next());
169 169
170 170 reg_def XMM8 (SOC, SOE, Op_RegF, 8, xmm8->as_VMReg());
171 171 reg_def XMM8_H (SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next());
172 172
173 173 reg_def XMM9 (SOC, SOE, Op_RegF, 9, xmm9->as_VMReg());
174 174 reg_def XMM9_H (SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next());
175 175
176 176 reg_def XMM10 (SOC, SOE, Op_RegF, 10, xmm10->as_VMReg());
177 177 reg_def XMM10_H(SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next());
178 178
179 179 reg_def XMM11 (SOC, SOE, Op_RegF, 11, xmm11->as_VMReg());
180 180 reg_def XMM11_H(SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next());
181 181
182 182 reg_def XMM12 (SOC, SOE, Op_RegF, 12, xmm12->as_VMReg());
183 183 reg_def XMM12_H(SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next());
184 184
185 185 reg_def XMM13 (SOC, SOE, Op_RegF, 13, xmm13->as_VMReg());
186 186 reg_def XMM13_H(SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next());
187 187
188 188 reg_def XMM14 (SOC, SOE, Op_RegF, 14, xmm14->as_VMReg());
189 189 reg_def XMM14_H(SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next());
190 190
191 191 reg_def XMM15 (SOC, SOE, Op_RegF, 15, xmm15->as_VMReg());
192 192 reg_def XMM15_H(SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next());
193 193
194 194 #else
195 195
196 196 reg_def XMM6 (SOC, SOC, Op_RegF, 6, xmm6->as_VMReg());
197 197 reg_def XMM6_H (SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next());
198 198
199 199 reg_def XMM7 (SOC, SOC, Op_RegF, 7, xmm7->as_VMReg());
200 200 reg_def XMM7_H (SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next());
201 201
202 202 reg_def XMM8 (SOC, SOC, Op_RegF, 8, xmm8->as_VMReg());
203 203 reg_def XMM8_H (SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next());
204 204
205 205 reg_def XMM9 (SOC, SOC, Op_RegF, 9, xmm9->as_VMReg());
206 206 reg_def XMM9_H (SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next());
207 207
208 208 reg_def XMM10 (SOC, SOC, Op_RegF, 10, xmm10->as_VMReg());
209 209 reg_def XMM10_H(SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next());
210 210
211 211 reg_def XMM11 (SOC, SOC, Op_RegF, 11, xmm11->as_VMReg());
212 212 reg_def XMM11_H(SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next());
213 213
214 214 reg_def XMM12 (SOC, SOC, Op_RegF, 12, xmm12->as_VMReg());
215 215 reg_def XMM12_H(SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next());
216 216
217 217 reg_def XMM13 (SOC, SOC, Op_RegF, 13, xmm13->as_VMReg());
218 218 reg_def XMM13_H(SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next());
219 219
220 220 reg_def XMM14 (SOC, SOC, Op_RegF, 14, xmm14->as_VMReg());
221 221 reg_def XMM14_H(SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next());
222 222
223 223 reg_def XMM15 (SOC, SOC, Op_RegF, 15, xmm15->as_VMReg());
224 224 reg_def XMM15_H(SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next());
225 225
226 226 #endif // _WIN64
227 227
228 228 reg_def RFLAGS(SOC, SOC, 0, 16, VMRegImpl::Bad());
229 229
230 230 // Specify priority of register selection within phases of register
231 231 // allocation. Highest priority is first. A useful heuristic is to
232 232 // give registers a low priority when they are required by machine
233 233 // instructions, like EAX and EDX on I486, and choose no-save registers
234 234 // before save-on-call, & save-on-call before save-on-entry. Registers
235 235 // which participate in fixed calling sequences should come last.
236 236 // Registers which are used as pairs must fall on an even boundary.
237 237
238 238 alloc_class chunk0(R10, R10_H,
239 239 R11, R11_H,
240 240 R8, R8_H,
241 241 R9, R9_H,
242 242 R12, R12_H,
243 243 RCX, RCX_H,
244 244 RBX, RBX_H,
245 245 RDI, RDI_H,
246 246 RDX, RDX_H,
247 247 RSI, RSI_H,
248 248 RAX, RAX_H,
249 249 RBP, RBP_H,
250 250 R13, R13_H,
251 251 R14, R14_H,
252 252 R15, R15_H,
253 253 RSP, RSP_H);
254 254
255 255 // XXX probably use 8-15 first on Linux
256 256 alloc_class chunk1(XMM0, XMM0_H,
257 257 XMM1, XMM1_H,
258 258 XMM2, XMM2_H,
259 259 XMM3, XMM3_H,
260 260 XMM4, XMM4_H,
261 261 XMM5, XMM5_H,
262 262 XMM6, XMM6_H,
263 263 XMM7, XMM7_H,
264 264 XMM8, XMM8_H,
265 265 XMM9, XMM9_H,
266 266 XMM10, XMM10_H,
267 267 XMM11, XMM11_H,
268 268 XMM12, XMM12_H,
269 269 XMM13, XMM13_H,
270 270 XMM14, XMM14_H,
271 271 XMM15, XMM15_H);
272 272
273 273 alloc_class chunk2(RFLAGS);
274 274
275 275
276 276 //----------Architecture Description Register Classes--------------------------
277 277 // Several register classes are automatically defined based upon information in
278 278 // this architecture description.
279 279 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ )
280 280 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ )
281 281 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
282 282 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
283 283 //
284 284
285 285 // Class for all pointer registers (including RSP)
286 286 reg_class any_reg(RAX, RAX_H,
287 287 RDX, RDX_H,
288 288 RBP, RBP_H,
289 289 RDI, RDI_H,
290 290 RSI, RSI_H,
291 291 RCX, RCX_H,
292 292 RBX, RBX_H,
293 293 RSP, RSP_H,
294 294 R8, R8_H,
295 295 R9, R9_H,
296 296 R10, R10_H,
297 297 R11, R11_H,
298 298 R12, R12_H,
299 299 R13, R13_H,
300 300 R14, R14_H,
301 301 R15, R15_H);
302 302
303 303 // Class for all pointer registers except RSP
304 304 reg_class ptr_reg(RAX, RAX_H,
305 305 RDX, RDX_H,
306 306 RBP, RBP_H,
307 307 RDI, RDI_H,
308 308 RSI, RSI_H,
309 309 RCX, RCX_H,
310 310 RBX, RBX_H,
311 311 R8, R8_H,
312 312 R9, R9_H,
313 313 R10, R10_H,
314 314 R11, R11_H,
315 315 R13, R13_H,
316 316 R14, R14_H);
317 317
318 318 // Class for all pointer registers except RAX and RSP
319 319 reg_class ptr_no_rax_reg(RDX, RDX_H,
320 320 RBP, RBP_H,
321 321 RDI, RDI_H,
322 322 RSI, RSI_H,
323 323 RCX, RCX_H,
324 324 RBX, RBX_H,
325 325 R8, R8_H,
326 326 R9, R9_H,
327 327 R10, R10_H,
328 328 R11, R11_H,
329 329 R13, R13_H,
330 330 R14, R14_H);
331 331
332 332 reg_class ptr_no_rbp_reg(RDX, RDX_H,
333 333 RAX, RAX_H,
334 334 RDI, RDI_H,
335 335 RSI, RSI_H,
336 336 RCX, RCX_H,
337 337 RBX, RBX_H,
338 338 R8, R8_H,
339 339 R9, R9_H,
340 340 R10, R10_H,
341 341 R11, R11_H,
342 342 R13, R13_H,
343 343 R14, R14_H);
344 344
345 345 // Class for all pointer registers except RAX, RBX and RSP
346 346 reg_class ptr_no_rax_rbx_reg(RDX, RDX_H,
347 347 RBP, RBP_H,
348 348 RDI, RDI_H,
349 349 RSI, RSI_H,
350 350 RCX, RCX_H,
351 351 R8, R8_H,
352 352 R9, R9_H,
353 353 R10, R10_H,
354 354 R11, R11_H,
355 355 R13, R13_H,
356 356 R14, R14_H);
357 357
358 358 // Singleton class for RAX pointer register
359 359 reg_class ptr_rax_reg(RAX, RAX_H);
360 360
361 361 // Singleton class for RBX pointer register
362 362 reg_class ptr_rbx_reg(RBX, RBX_H);
363 363
364 364 // Singleton class for RSI pointer register
365 365 reg_class ptr_rsi_reg(RSI, RSI_H);
366 366
367 367 // Singleton class for RDI pointer register
368 368 reg_class ptr_rdi_reg(RDI, RDI_H);
369 369
370 370 // Singleton class for RBP pointer register
371 371 reg_class ptr_rbp_reg(RBP, RBP_H);
372 372
373 373 // Singleton class for stack pointer
374 374 reg_class ptr_rsp_reg(RSP, RSP_H);
375 375
376 376 // Singleton class for TLS pointer
377 377 reg_class ptr_r15_reg(R15, R15_H);
378 378
379 379 // Class for all long registers (except RSP)
380 380 reg_class long_reg(RAX, RAX_H,
381 381 RDX, RDX_H,
382 382 RBP, RBP_H,
383 383 RDI, RDI_H,
384 384 RSI, RSI_H,
385 385 RCX, RCX_H,
386 386 RBX, RBX_H,
387 387 R8, R8_H,
388 388 R9, R9_H,
389 389 R10, R10_H,
390 390 R11, R11_H,
391 391 R13, R13_H,
392 392 R14, R14_H);
393 393
394 394 // Class for all long registers except RAX, RDX (and RSP)
395 395 reg_class long_no_rax_rdx_reg(RBP, RBP_H,
396 396 RDI, RDI_H,
397 397 RSI, RSI_H,
398 398 RCX, RCX_H,
399 399 RBX, RBX_H,
400 400 R8, R8_H,
401 401 R9, R9_H,
402 402 R10, R10_H,
403 403 R11, R11_H,
404 404 R13, R13_H,
405 405 R14, R14_H);
406 406
407 407 // Class for all long registers except RCX (and RSP)
408 408 reg_class long_no_rcx_reg(RBP, RBP_H,
409 409 RDI, RDI_H,
410 410 RSI, RSI_H,
411 411 RAX, RAX_H,
412 412 RDX, RDX_H,
413 413 RBX, RBX_H,
414 414 R8, R8_H,
415 415 R9, R9_H,
416 416 R10, R10_H,
417 417 R11, R11_H,
418 418 R13, R13_H,
419 419 R14, R14_H);
420 420
421 421 // Class for all long registers except RAX (and RSP)
422 422 reg_class long_no_rax_reg(RBP, RBP_H,
423 423 RDX, RDX_H,
424 424 RDI, RDI_H,
425 425 RSI, RSI_H,
426 426 RCX, RCX_H,
427 427 RBX, RBX_H,
428 428 R8, R8_H,
429 429 R9, R9_H,
430 430 R10, R10_H,
431 431 R11, R11_H,
432 432 R13, R13_H,
433 433 R14, R14_H);
434 434
435 435 // Singleton class for RAX long register
436 436 reg_class long_rax_reg(RAX, RAX_H);
437 437
438 438 // Singleton class for RCX long register
439 439 reg_class long_rcx_reg(RCX, RCX_H);
440 440
441 441 // Singleton class for RDX long register
442 442 reg_class long_rdx_reg(RDX, RDX_H);
443 443
444 444 // Class for all int registers (except RSP)
445 445 reg_class int_reg(RAX,
446 446 RDX,
447 447 RBP,
448 448 RDI,
449 449 RSI,
450 450 RCX,
451 451 RBX,
452 452 R8,
453 453 R9,
454 454 R10,
455 455 R11,
456 456 R13,
457 457 R14);
458 458
459 459 // Class for all int registers except RCX (and RSP)
460 460 reg_class int_no_rcx_reg(RAX,
461 461 RDX,
462 462 RBP,
463 463 RDI,
464 464 RSI,
465 465 RBX,
466 466 R8,
467 467 R9,
468 468 R10,
469 469 R11,
470 470 R13,
471 471 R14);
472 472
473 473 // Class for all int registers except RAX, RDX (and RSP)
474 474 reg_class int_no_rax_rdx_reg(RBP,
475 475 RDI,
476 476 RSI,
477 477 RCX,
478 478 RBX,
479 479 R8,
480 480 R9,
481 481 R10,
482 482 R11,
483 483 R13,
484 484 R14);
485 485
486 486 // Singleton class for RAX int register
487 487 reg_class int_rax_reg(RAX);
488 488
489 489 // Singleton class for RBX int register
490 490 reg_class int_rbx_reg(RBX);
491 491
492 492 // Singleton class for RCX int register
493 493 reg_class int_rcx_reg(RCX);
494 494
495 495 // Singleton class for RCX int register
496 496 reg_class int_rdx_reg(RDX);
497 497
498 498 // Singleton class for RCX int register
499 499 reg_class int_rdi_reg(RDI);
500 500
501 501 // Singleton class for instruction pointer
502 502 // reg_class ip_reg(RIP);
503 503
504 504 // Singleton class for condition codes
505 505 reg_class int_flags(RFLAGS);
506 506
507 507 // Class for all float registers
508 508 reg_class float_reg(XMM0,
509 509 XMM1,
510 510 XMM2,
511 511 XMM3,
512 512 XMM4,
513 513 XMM5,
514 514 XMM6,
515 515 XMM7,
516 516 XMM8,
517 517 XMM9,
518 518 XMM10,
519 519 XMM11,
520 520 XMM12,
521 521 XMM13,
522 522 XMM14,
523 523 XMM15);
524 524
525 525 // Class for all double registers
526 526 reg_class double_reg(XMM0, XMM0_H,
527 527 XMM1, XMM1_H,
528 528 XMM2, XMM2_H,
529 529 XMM3, XMM3_H,
530 530 XMM4, XMM4_H,
531 531 XMM5, XMM5_H,
532 532 XMM6, XMM6_H,
533 533 XMM7, XMM7_H,
534 534 XMM8, XMM8_H,
535 535 XMM9, XMM9_H,
536 536 XMM10, XMM10_H,
537 537 XMM11, XMM11_H,
538 538 XMM12, XMM12_H,
539 539 XMM13, XMM13_H,
540 540 XMM14, XMM14_H,
541 541 XMM15, XMM15_H);
542 542 %}
543 543
↓ open down ↓ |
543 lines elided |
↑ open up ↑ |
544 544
545 545 //----------SOURCE BLOCK-------------------------------------------------------
546 546 // This is a block of C++ code which provides values, functions, and
547 547 // definitions necessary in the rest of the architecture description
548 548 source %{
549 549 #define RELOC_IMM64 Assembler::imm_operand
550 550 #define RELOC_DISP32 Assembler::disp32_operand
551 551
552 552 #define __ _masm.
553 553
554 +static int preserve_SP_size() {
555 + return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg)
556 +}
557 +
554 558 // !!!!! Special hack to get all types of calls to specify the byte offset
555 559 // from the start of the call to the point where the return address
556 560 // will point.
557 561 int MachCallStaticJavaNode::ret_addr_offset()
558 562 {
559 - return 5; // 5 bytes from start of call to where return address points
563 + int offset = 5; // 5 bytes from start of call to where return address points
564 + if (_method_handle_invoke)
565 + offset += preserve_SP_size();
566 + return offset;
560 567 }
561 568
562 569 int MachCallDynamicJavaNode::ret_addr_offset()
563 570 {
564 571 return 15; // 15 bytes from start of call to where return address points
565 572 }
566 573
567 574 // In os_cpu .ad file
568 575 // int MachCallRuntimeNode::ret_addr_offset()
569 576
570 577 // Indicate if the safepoint node needs the polling page as an input.
571 578 // Since amd64 does not have absolute addressing but RIP-relative
572 579 // addressing and the polling page is within 2G, it doesn't.
573 580 bool SafePointNode::needs_polling_address_input()
574 581 {
575 582 return false;
576 583 }
577 584
578 585 //
579 586 // Compute padding required for nodes which need alignment
580 587 //
581 588
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
582 589 // The address of the call instruction needs to be 4-byte aligned to
583 590 // ensure that it does not span a cache line so that it can be patched.
584 591 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
585 592 {
586 593 current_offset += 1; // skip call opcode byte
587 594 return round_to(current_offset, alignment_required()) - current_offset;
588 595 }
589 596
590 597 // The address of the call instruction needs to be 4-byte aligned to
591 598 // ensure that it does not span a cache line so that it can be patched.
599 +int CallStaticJavaHandleNode::compute_padding(int current_offset) const
600 +{
601 + current_offset += preserve_SP_size(); // skip mov rbp, rsp
602 + current_offset += 1; // skip call opcode byte
603 + return round_to(current_offset, alignment_required()) - current_offset;
604 +}
605 +
606 +// The address of the call instruction needs to be 4-byte aligned to
607 +// ensure that it does not span a cache line so that it can be patched.
592 608 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
593 609 {
594 610 current_offset += 11; // skip movq instruction + call opcode byte
595 611 return round_to(current_offset, alignment_required()) - current_offset;
596 612 }
597 613
598 614 #ifndef PRODUCT
599 615 void MachBreakpointNode::format(PhaseRegAlloc*, outputStream* st) const
600 616 {
601 617 st->print("INT3");
602 618 }
603 619 #endif
604 620
605 621 // EMIT_RM()
606 622 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3)
607 623 {
608 624 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
609 625 *(cbuf.code_end()) = c;
610 626 cbuf.set_code_end(cbuf.code_end() + 1);
611 627 }
612 628
613 629 // EMIT_CC()
614 630 void emit_cc(CodeBuffer &cbuf, int f1, int f2)
615 631 {
616 632 unsigned char c = (unsigned char) (f1 | f2);
617 633 *(cbuf.code_end()) = c;
618 634 cbuf.set_code_end(cbuf.code_end() + 1);
619 635 }
620 636
621 637 // EMIT_OPCODE()
622 638 void emit_opcode(CodeBuffer &cbuf, int code)
623 639 {
624 640 *(cbuf.code_end()) = (unsigned char) code;
625 641 cbuf.set_code_end(cbuf.code_end() + 1);
626 642 }
627 643
628 644 // EMIT_OPCODE() w/ relocation information
629 645 void emit_opcode(CodeBuffer &cbuf,
630 646 int code, relocInfo::relocType reloc, int offset, int format)
631 647 {
632 648 cbuf.relocate(cbuf.inst_mark() + offset, reloc, format);
633 649 emit_opcode(cbuf, code);
634 650 }
635 651
636 652 // EMIT_D8()
637 653 void emit_d8(CodeBuffer &cbuf, int d8)
638 654 {
639 655 *(cbuf.code_end()) = (unsigned char) d8;
640 656 cbuf.set_code_end(cbuf.code_end() + 1);
641 657 }
642 658
643 659 // EMIT_D16()
644 660 void emit_d16(CodeBuffer &cbuf, int d16)
645 661 {
646 662 *((short *)(cbuf.code_end())) = d16;
647 663 cbuf.set_code_end(cbuf.code_end() + 2);
648 664 }
649 665
650 666 // EMIT_D32()
651 667 void emit_d32(CodeBuffer &cbuf, int d32)
652 668 {
653 669 *((int *)(cbuf.code_end())) = d32;
654 670 cbuf.set_code_end(cbuf.code_end() + 4);
655 671 }
656 672
657 673 // EMIT_D64()
658 674 void emit_d64(CodeBuffer &cbuf, int64_t d64)
659 675 {
660 676 *((int64_t*) (cbuf.code_end())) = d64;
661 677 cbuf.set_code_end(cbuf.code_end() + 8);
662 678 }
663 679
664 680 // emit 32 bit value and construct relocation entry from relocInfo::relocType
665 681 void emit_d32_reloc(CodeBuffer& cbuf,
666 682 int d32,
667 683 relocInfo::relocType reloc,
668 684 int format)
669 685 {
670 686 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
671 687 cbuf.relocate(cbuf.inst_mark(), reloc, format);
672 688
673 689 *((int*) (cbuf.code_end())) = d32;
674 690 cbuf.set_code_end(cbuf.code_end() + 4);
675 691 }
676 692
677 693 // emit 32 bit value and construct relocation entry from RelocationHolder
678 694 void emit_d32_reloc(CodeBuffer& cbuf,
679 695 int d32,
680 696 RelocationHolder const& rspec,
681 697 int format)
682 698 {
683 699 #ifdef ASSERT
684 700 if (rspec.reloc()->type() == relocInfo::oop_type &&
685 701 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
686 702 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
687 703 }
688 704 #endif
689 705 cbuf.relocate(cbuf.inst_mark(), rspec, format);
690 706
691 707 *((int* )(cbuf.code_end())) = d32;
692 708 cbuf.set_code_end(cbuf.code_end() + 4);
693 709 }
694 710
695 711 void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
696 712 address next_ip = cbuf.code_end() + 4;
697 713 emit_d32_reloc(cbuf, (int) (addr - next_ip),
698 714 external_word_Relocation::spec(addr),
699 715 RELOC_DISP32);
700 716 }
701 717
702 718
703 719 // emit 64 bit value and construct relocation entry from relocInfo::relocType
704 720 void emit_d64_reloc(CodeBuffer& cbuf,
705 721 int64_t d64,
706 722 relocInfo::relocType reloc,
707 723 int format)
708 724 {
709 725 cbuf.relocate(cbuf.inst_mark(), reloc, format);
710 726
711 727 *((int64_t*) (cbuf.code_end())) = d64;
712 728 cbuf.set_code_end(cbuf.code_end() + 8);
713 729 }
714 730
715 731 // emit 64 bit value and construct relocation entry from RelocationHolder
716 732 void emit_d64_reloc(CodeBuffer& cbuf,
717 733 int64_t d64,
718 734 RelocationHolder const& rspec,
719 735 int format)
720 736 {
721 737 #ifdef ASSERT
722 738 if (rspec.reloc()->type() == relocInfo::oop_type &&
723 739 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
724 740 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()),
725 741 "cannot embed scavengable oops in code");
726 742 }
727 743 #endif
728 744 cbuf.relocate(cbuf.inst_mark(), rspec, format);
729 745
730 746 *((int64_t*) (cbuf.code_end())) = d64;
731 747 cbuf.set_code_end(cbuf.code_end() + 8);
732 748 }
733 749
734 750 // Access stack slot for load or store
735 751 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp)
736 752 {
737 753 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src])
738 754 if (-0x80 <= disp && disp < 0x80) {
739 755 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte
740 756 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
741 757 emit_d8(cbuf, disp); // Displacement // R/M byte
742 758 } else {
743 759 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte
744 760 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
745 761 emit_d32(cbuf, disp); // Displacement // R/M byte
746 762 }
747 763 }
748 764
749 765 // rRegI ereg, memory mem) %{ // emit_reg_mem
750 766 void encode_RegMem(CodeBuffer &cbuf,
751 767 int reg,
752 768 int base, int index, int scale, int disp, bool disp_is_oop)
753 769 {
754 770 assert(!disp_is_oop, "cannot have disp");
755 771 int regenc = reg & 7;
756 772 int baseenc = base & 7;
757 773 int indexenc = index & 7;
758 774
759 775 // There is no index & no scale, use form without SIB byte
760 776 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) {
761 777 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
762 778 if (disp == 0 && base != RBP_enc && base != R13_enc) {
763 779 emit_rm(cbuf, 0x0, regenc, baseenc); // *
764 780 } else if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) {
765 781 // If 8-bit displacement, mode 0x1
766 782 emit_rm(cbuf, 0x1, regenc, baseenc); // *
767 783 emit_d8(cbuf, disp);
768 784 } else {
769 785 // If 32-bit displacement
770 786 if (base == -1) { // Special flag for absolute address
771 787 emit_rm(cbuf, 0x0, regenc, 0x5); // *
772 788 if (disp_is_oop) {
773 789 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
774 790 } else {
775 791 emit_d32(cbuf, disp);
776 792 }
777 793 } else {
778 794 // Normal base + offset
779 795 emit_rm(cbuf, 0x2, regenc, baseenc); // *
780 796 if (disp_is_oop) {
781 797 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
782 798 } else {
783 799 emit_d32(cbuf, disp);
784 800 }
785 801 }
786 802 }
787 803 } else {
788 804 // Else, encode with the SIB byte
789 805 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
790 806 if (disp == 0 && base != RBP_enc && base != R13_enc) {
791 807 // If no displacement
792 808 emit_rm(cbuf, 0x0, regenc, 0x4); // *
793 809 emit_rm(cbuf, scale, indexenc, baseenc);
794 810 } else {
795 811 if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) {
796 812 // If 8-bit displacement, mode 0x1
797 813 emit_rm(cbuf, 0x1, regenc, 0x4); // *
798 814 emit_rm(cbuf, scale, indexenc, baseenc);
799 815 emit_d8(cbuf, disp);
800 816 } else {
801 817 // If 32-bit displacement
802 818 if (base == 0x04 ) {
803 819 emit_rm(cbuf, 0x2, regenc, 0x4);
804 820 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
805 821 } else {
806 822 emit_rm(cbuf, 0x2, regenc, 0x4);
807 823 emit_rm(cbuf, scale, indexenc, baseenc); // *
808 824 }
809 825 if (disp_is_oop) {
810 826 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
811 827 } else {
812 828 emit_d32(cbuf, disp);
813 829 }
814 830 }
815 831 }
816 832 }
817 833 }
818 834
819 835 void encode_copy(CodeBuffer &cbuf, int dstenc, int srcenc)
820 836 {
821 837 if (dstenc != srcenc) {
822 838 if (dstenc < 8) {
823 839 if (srcenc >= 8) {
824 840 emit_opcode(cbuf, Assembler::REX_B);
825 841 srcenc -= 8;
826 842 }
827 843 } else {
828 844 if (srcenc < 8) {
829 845 emit_opcode(cbuf, Assembler::REX_R);
830 846 } else {
831 847 emit_opcode(cbuf, Assembler::REX_RB);
832 848 srcenc -= 8;
833 849 }
834 850 dstenc -= 8;
835 851 }
836 852
837 853 emit_opcode(cbuf, 0x8B);
838 854 emit_rm(cbuf, 0x3, dstenc, srcenc);
839 855 }
840 856 }
841 857
842 858 void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
843 859 if( dst_encoding == src_encoding ) {
844 860 // reg-reg copy, use an empty encoding
845 861 } else {
846 862 MacroAssembler _masm(&cbuf);
847 863
848 864 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
849 865 }
850 866 }
851 867
852 868
853 869 //=============================================================================
854 870 #ifndef PRODUCT
855 871 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const
856 872 {
857 873 Compile* C = ra_->C;
858 874
859 875 int framesize = C->frame_slots() << LogBytesPerInt;
860 876 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
861 877 // Remove wordSize for return adr already pushed
862 878 // and another for the RBP we are going to save
863 879 framesize -= 2*wordSize;
864 880 bool need_nop = true;
865 881
866 882 // Calls to C2R adapters often do not accept exceptional returns.
867 883 // We require that their callers must bang for them. But be
868 884 // careful, because some VM calls (such as call site linkage) can
869 885 // use several kilobytes of stack. But the stack safety zone should
870 886 // account for that. See bugs 4446381, 4468289, 4497237.
871 887 if (C->need_stack_bang(framesize)) {
872 888 st->print_cr("# stack bang"); st->print("\t");
873 889 need_nop = false;
874 890 }
875 891 st->print_cr("pushq rbp"); st->print("\t");
876 892
877 893 if (VerifyStackAtCalls) {
878 894 // Majik cookie to verify stack depth
879 895 st->print_cr("pushq 0xffffffffbadb100d"
880 896 "\t# Majik cookie for stack depth check");
881 897 st->print("\t");
882 898 framesize -= wordSize; // Remove 2 for cookie
883 899 need_nop = false;
884 900 }
885 901
886 902 if (framesize) {
887 903 st->print("subq rsp, #%d\t# Create frame", framesize);
888 904 if (framesize < 0x80 && need_nop) {
889 905 st->print("\n\tnop\t# nop for patch_verified_entry");
890 906 }
891 907 }
892 908 }
893 909 #endif
894 910
895 911 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const
896 912 {
897 913 Compile* C = ra_->C;
898 914
899 915 // WARNING: Initial instruction MUST be 5 bytes or longer so that
900 916 // NativeJump::patch_verified_entry will be able to patch out the entry
901 917 // code safely. The fldcw is ok at 6 bytes, the push to verify stack
902 918 // depth is ok at 5 bytes, the frame allocation can be either 3 or
903 919 // 6 bytes. So if we don't do the fldcw or the push then we must
904 920 // use the 6 byte frame allocation even if we have no frame. :-(
905 921 // If method sets FPU control word do it now
906 922
907 923 int framesize = C->frame_slots() << LogBytesPerInt;
908 924 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
909 925 // Remove wordSize for return adr already pushed
910 926 // and another for the RBP we are going to save
911 927 framesize -= 2*wordSize;
912 928 bool need_nop = true;
913 929
914 930 // Calls to C2R adapters often do not accept exceptional returns.
915 931 // We require that their callers must bang for them. But be
916 932 // careful, because some VM calls (such as call site linkage) can
917 933 // use several kilobytes of stack. But the stack safety zone should
918 934 // account for that. See bugs 4446381, 4468289, 4497237.
919 935 if (C->need_stack_bang(framesize)) {
920 936 MacroAssembler masm(&cbuf);
921 937 masm.generate_stack_overflow_check(framesize);
922 938 need_nop = false;
923 939 }
924 940
925 941 // We always push rbp so that on return to interpreter rbp will be
926 942 // restored correctly and we can correct the stack.
927 943 emit_opcode(cbuf, 0x50 | RBP_enc);
928 944
929 945 if (VerifyStackAtCalls) {
930 946 // Majik cookie to verify stack depth
931 947 emit_opcode(cbuf, 0x68); // pushq (sign-extended) 0xbadb100d
932 948 emit_d32(cbuf, 0xbadb100d);
933 949 framesize -= wordSize; // Remove 2 for cookie
934 950 need_nop = false;
935 951 }
936 952
937 953 if (framesize) {
938 954 emit_opcode(cbuf, Assembler::REX_W);
939 955 if (framesize < 0x80) {
940 956 emit_opcode(cbuf, 0x83); // sub SP,#framesize
941 957 emit_rm(cbuf, 0x3, 0x05, RSP_enc);
942 958 emit_d8(cbuf, framesize);
943 959 if (need_nop) {
944 960 emit_opcode(cbuf, 0x90); // nop
945 961 }
946 962 } else {
947 963 emit_opcode(cbuf, 0x81); // sub SP,#framesize
948 964 emit_rm(cbuf, 0x3, 0x05, RSP_enc);
949 965 emit_d32(cbuf, framesize);
950 966 }
951 967 }
952 968
953 969 C->set_frame_complete(cbuf.code_end() - cbuf.code_begin());
954 970
955 971 #ifdef ASSERT
956 972 if (VerifyStackAtCalls) {
957 973 Label L;
958 974 MacroAssembler masm(&cbuf);
959 975 masm.push(rax);
960 976 masm.mov(rax, rsp);
961 977 masm.andptr(rax, StackAlignmentInBytes-1);
962 978 masm.cmpptr(rax, StackAlignmentInBytes-wordSize);
963 979 masm.pop(rax);
964 980 masm.jcc(Assembler::equal, L);
965 981 masm.stop("Stack is not properly aligned!");
966 982 masm.bind(L);
967 983 }
968 984 #endif
969 985 }
970 986
971 987 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
972 988 {
973 989 return MachNode::size(ra_); // too many variables; just compute it
974 990 // the hard way
975 991 }
976 992
977 993 int MachPrologNode::reloc() const
978 994 {
979 995 return 0; // a large enough number
980 996 }
981 997
982 998 //=============================================================================
983 999 #ifndef PRODUCT
984 1000 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
985 1001 {
986 1002 Compile* C = ra_->C;
987 1003 int framesize = C->frame_slots() << LogBytesPerInt;
988 1004 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
989 1005 // Remove word for return adr already pushed
990 1006 // and RBP
991 1007 framesize -= 2*wordSize;
992 1008
993 1009 if (framesize) {
994 1010 st->print_cr("addq\trsp, %d\t# Destroy frame", framesize);
995 1011 st->print("\t");
996 1012 }
997 1013
998 1014 st->print_cr("popq\trbp");
999 1015 if (do_polling() && C->is_method_compilation()) {
1000 1016 st->print_cr("\ttestl\trax, [rip + #offset_to_poll_page]\t"
1001 1017 "# Safepoint: poll for GC");
1002 1018 st->print("\t");
1003 1019 }
1004 1020 }
1005 1021 #endif
1006 1022
1007 1023 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1008 1024 {
1009 1025 Compile* C = ra_->C;
1010 1026 int framesize = C->frame_slots() << LogBytesPerInt;
1011 1027 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1012 1028 // Remove word for return adr already pushed
1013 1029 // and RBP
1014 1030 framesize -= 2*wordSize;
1015 1031
1016 1032 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here
1017 1033
1018 1034 if (framesize) {
1019 1035 emit_opcode(cbuf, Assembler::REX_W);
1020 1036 if (framesize < 0x80) {
1021 1037 emit_opcode(cbuf, 0x83); // addq rsp, #framesize
1022 1038 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
1023 1039 emit_d8(cbuf, framesize);
1024 1040 } else {
1025 1041 emit_opcode(cbuf, 0x81); // addq rsp, #framesize
1026 1042 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
1027 1043 emit_d32(cbuf, framesize);
1028 1044 }
1029 1045 }
1030 1046
1031 1047 // popq rbp
1032 1048 emit_opcode(cbuf, 0x58 | RBP_enc);
1033 1049
1034 1050 if (do_polling() && C->is_method_compilation()) {
1035 1051 // testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
1036 1052 // XXX reg_mem doesn't support RIP-relative addressing yet
1037 1053 cbuf.set_inst_mark();
1038 1054 cbuf.relocate(cbuf.inst_mark(), relocInfo::poll_return_type, 0); // XXX
1039 1055 emit_opcode(cbuf, 0x85); // testl
1040 1056 emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
1041 1057 // cbuf.inst_mark() is beginning of instruction
1042 1058 emit_d32_reloc(cbuf, os::get_polling_page());
1043 1059 // relocInfo::poll_return_type,
1044 1060 }
1045 1061 }
1046 1062
1047 1063 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
1048 1064 {
1049 1065 Compile* C = ra_->C;
1050 1066 int framesize = C->frame_slots() << LogBytesPerInt;
1051 1067 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1052 1068 // Remove word for return adr already pushed
1053 1069 // and RBP
1054 1070 framesize -= 2*wordSize;
1055 1071
1056 1072 uint size = 0;
1057 1073
1058 1074 if (do_polling() && C->is_method_compilation()) {
1059 1075 size += 6;
1060 1076 }
1061 1077
1062 1078 // count popq rbp
1063 1079 size++;
1064 1080
1065 1081 if (framesize) {
1066 1082 if (framesize < 0x80) {
1067 1083 size += 4;
1068 1084 } else if (framesize) {
1069 1085 size += 7;
1070 1086 }
1071 1087 }
1072 1088
1073 1089 return size;
1074 1090 }
1075 1091
1076 1092 int MachEpilogNode::reloc() const
1077 1093 {
1078 1094 return 2; // a large enough number
1079 1095 }
1080 1096
1081 1097 const Pipeline* MachEpilogNode::pipeline() const
1082 1098 {
1083 1099 return MachNode::pipeline_class();
1084 1100 }
1085 1101
1086 1102 int MachEpilogNode::safepoint_offset() const
1087 1103 {
1088 1104 return 0;
1089 1105 }
1090 1106
1091 1107 //=============================================================================
1092 1108
1093 1109 enum RC {
1094 1110 rc_bad,
1095 1111 rc_int,
1096 1112 rc_float,
1097 1113 rc_stack
1098 1114 };
1099 1115
1100 1116 static enum RC rc_class(OptoReg::Name reg)
1101 1117 {
1102 1118 if( !OptoReg::is_valid(reg) ) return rc_bad;
1103 1119
1104 1120 if (OptoReg::is_stack(reg)) return rc_stack;
1105 1121
1106 1122 VMReg r = OptoReg::as_VMReg(reg);
1107 1123
1108 1124 if (r->is_Register()) return rc_int;
1109 1125
1110 1126 assert(r->is_XMMRegister(), "must be");
1111 1127 return rc_float;
1112 1128 }
1113 1129
1114 1130 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
1115 1131 PhaseRegAlloc* ra_,
1116 1132 bool do_size,
1117 1133 outputStream* st) const
1118 1134 {
1119 1135
1120 1136 // Get registers to move
1121 1137 OptoReg::Name src_second = ra_->get_reg_second(in(1));
1122 1138 OptoReg::Name src_first = ra_->get_reg_first(in(1));
1123 1139 OptoReg::Name dst_second = ra_->get_reg_second(this);
1124 1140 OptoReg::Name dst_first = ra_->get_reg_first(this);
1125 1141
1126 1142 enum RC src_second_rc = rc_class(src_second);
1127 1143 enum RC src_first_rc = rc_class(src_first);
1128 1144 enum RC dst_second_rc = rc_class(dst_second);
1129 1145 enum RC dst_first_rc = rc_class(dst_first);
1130 1146
1131 1147 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
1132 1148 "must move at least 1 register" );
1133 1149
1134 1150 if (src_first == dst_first && src_second == dst_second) {
1135 1151 // Self copy, no move
1136 1152 return 0;
1137 1153 } else if (src_first_rc == rc_stack) {
1138 1154 // mem ->
1139 1155 if (dst_first_rc == rc_stack) {
1140 1156 // mem -> mem
1141 1157 assert(src_second != dst_first, "overlap");
1142 1158 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1143 1159 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1144 1160 // 64-bit
1145 1161 int src_offset = ra_->reg2offset(src_first);
1146 1162 int dst_offset = ra_->reg2offset(dst_first);
1147 1163 if (cbuf) {
1148 1164 emit_opcode(*cbuf, 0xFF);
1149 1165 encode_RegMem(*cbuf, RSI_enc, RSP_enc, 0x4, 0, src_offset, false);
1150 1166
1151 1167 emit_opcode(*cbuf, 0x8F);
1152 1168 encode_RegMem(*cbuf, RAX_enc, RSP_enc, 0x4, 0, dst_offset, false);
1153 1169
1154 1170 #ifndef PRODUCT
1155 1171 } else if (!do_size) {
1156 1172 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1157 1173 "popq [rsp + #%d]",
1158 1174 src_offset,
1159 1175 dst_offset);
1160 1176 #endif
1161 1177 }
1162 1178 return
1163 1179 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) +
1164 1180 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4));
1165 1181 } else {
1166 1182 // 32-bit
1167 1183 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1168 1184 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1169 1185 // No pushl/popl, so:
1170 1186 int src_offset = ra_->reg2offset(src_first);
1171 1187 int dst_offset = ra_->reg2offset(dst_first);
1172 1188 if (cbuf) {
1173 1189 emit_opcode(*cbuf, Assembler::REX_W);
1174 1190 emit_opcode(*cbuf, 0x89);
1175 1191 emit_opcode(*cbuf, 0x44);
1176 1192 emit_opcode(*cbuf, 0x24);
1177 1193 emit_opcode(*cbuf, 0xF8);
1178 1194
1179 1195 emit_opcode(*cbuf, 0x8B);
1180 1196 encode_RegMem(*cbuf,
1181 1197 RAX_enc,
1182 1198 RSP_enc, 0x4, 0, src_offset,
1183 1199 false);
1184 1200
1185 1201 emit_opcode(*cbuf, 0x89);
1186 1202 encode_RegMem(*cbuf,
1187 1203 RAX_enc,
1188 1204 RSP_enc, 0x4, 0, dst_offset,
1189 1205 false);
1190 1206
1191 1207 emit_opcode(*cbuf, Assembler::REX_W);
1192 1208 emit_opcode(*cbuf, 0x8B);
1193 1209 emit_opcode(*cbuf, 0x44);
1194 1210 emit_opcode(*cbuf, 0x24);
1195 1211 emit_opcode(*cbuf, 0xF8);
1196 1212
1197 1213 #ifndef PRODUCT
1198 1214 } else if (!do_size) {
1199 1215 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1200 1216 "movl rax, [rsp + #%d]\n\t"
1201 1217 "movl [rsp + #%d], rax\n\t"
1202 1218 "movq rax, [rsp - #8]",
1203 1219 src_offset,
1204 1220 dst_offset);
1205 1221 #endif
1206 1222 }
1207 1223 return
1208 1224 5 + // movq
1209 1225 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + // movl
1210 1226 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)) + // movl
1211 1227 5; // movq
1212 1228 }
1213 1229 } else if (dst_first_rc == rc_int) {
1214 1230 // mem -> gpr
1215 1231 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1216 1232 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1217 1233 // 64-bit
1218 1234 int offset = ra_->reg2offset(src_first);
1219 1235 if (cbuf) {
1220 1236 if (Matcher::_regEncode[dst_first] < 8) {
1221 1237 emit_opcode(*cbuf, Assembler::REX_W);
1222 1238 } else {
1223 1239 emit_opcode(*cbuf, Assembler::REX_WR);
1224 1240 }
1225 1241 emit_opcode(*cbuf, 0x8B);
1226 1242 encode_RegMem(*cbuf,
1227 1243 Matcher::_regEncode[dst_first],
1228 1244 RSP_enc, 0x4, 0, offset,
1229 1245 false);
1230 1246 #ifndef PRODUCT
1231 1247 } else if (!do_size) {
1232 1248 st->print("movq %s, [rsp + #%d]\t# spill",
1233 1249 Matcher::regName[dst_first],
1234 1250 offset);
1235 1251 #endif
1236 1252 }
1237 1253 return
1238 1254 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX
1239 1255 } else {
1240 1256 // 32-bit
1241 1257 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1242 1258 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1243 1259 int offset = ra_->reg2offset(src_first);
1244 1260 if (cbuf) {
1245 1261 if (Matcher::_regEncode[dst_first] >= 8) {
1246 1262 emit_opcode(*cbuf, Assembler::REX_R);
1247 1263 }
1248 1264 emit_opcode(*cbuf, 0x8B);
1249 1265 encode_RegMem(*cbuf,
1250 1266 Matcher::_regEncode[dst_first],
1251 1267 RSP_enc, 0x4, 0, offset,
1252 1268 false);
1253 1269 #ifndef PRODUCT
1254 1270 } else if (!do_size) {
1255 1271 st->print("movl %s, [rsp + #%d]\t# spill",
1256 1272 Matcher::regName[dst_first],
1257 1273 offset);
1258 1274 #endif
1259 1275 }
1260 1276 return
1261 1277 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1262 1278 ((Matcher::_regEncode[dst_first] < 8)
1263 1279 ? 3
1264 1280 : 4); // REX
1265 1281 }
1266 1282 } else if (dst_first_rc == rc_float) {
1267 1283 // mem-> xmm
1268 1284 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1269 1285 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1270 1286 // 64-bit
1271 1287 int offset = ra_->reg2offset(src_first);
1272 1288 if (cbuf) {
1273 1289 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
1274 1290 if (Matcher::_regEncode[dst_first] >= 8) {
1275 1291 emit_opcode(*cbuf, Assembler::REX_R);
1276 1292 }
1277 1293 emit_opcode(*cbuf, 0x0F);
1278 1294 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
1279 1295 encode_RegMem(*cbuf,
1280 1296 Matcher::_regEncode[dst_first],
1281 1297 RSP_enc, 0x4, 0, offset,
1282 1298 false);
1283 1299 #ifndef PRODUCT
1284 1300 } else if (!do_size) {
1285 1301 st->print("%s %s, [rsp + #%d]\t# spill",
1286 1302 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1287 1303 Matcher::regName[dst_first],
1288 1304 offset);
1289 1305 #endif
1290 1306 }
1291 1307 return
1292 1308 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1293 1309 ((Matcher::_regEncode[dst_first] < 8)
1294 1310 ? 5
1295 1311 : 6); // REX
1296 1312 } else {
1297 1313 // 32-bit
1298 1314 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1299 1315 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1300 1316 int offset = ra_->reg2offset(src_first);
1301 1317 if (cbuf) {
1302 1318 emit_opcode(*cbuf, 0xF3);
1303 1319 if (Matcher::_regEncode[dst_first] >= 8) {
1304 1320 emit_opcode(*cbuf, Assembler::REX_R);
1305 1321 }
1306 1322 emit_opcode(*cbuf, 0x0F);
1307 1323 emit_opcode(*cbuf, 0x10);
1308 1324 encode_RegMem(*cbuf,
1309 1325 Matcher::_regEncode[dst_first],
1310 1326 RSP_enc, 0x4, 0, offset,
1311 1327 false);
1312 1328 #ifndef PRODUCT
1313 1329 } else if (!do_size) {
1314 1330 st->print("movss %s, [rsp + #%d]\t# spill",
1315 1331 Matcher::regName[dst_first],
1316 1332 offset);
1317 1333 #endif
1318 1334 }
1319 1335 return
1320 1336 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1321 1337 ((Matcher::_regEncode[dst_first] < 8)
1322 1338 ? 5
1323 1339 : 6); // REX
1324 1340 }
1325 1341 }
1326 1342 } else if (src_first_rc == rc_int) {
1327 1343 // gpr ->
1328 1344 if (dst_first_rc == rc_stack) {
1329 1345 // gpr -> mem
1330 1346 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1331 1347 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1332 1348 // 64-bit
1333 1349 int offset = ra_->reg2offset(dst_first);
1334 1350 if (cbuf) {
1335 1351 if (Matcher::_regEncode[src_first] < 8) {
1336 1352 emit_opcode(*cbuf, Assembler::REX_W);
1337 1353 } else {
1338 1354 emit_opcode(*cbuf, Assembler::REX_WR);
1339 1355 }
1340 1356 emit_opcode(*cbuf, 0x89);
1341 1357 encode_RegMem(*cbuf,
1342 1358 Matcher::_regEncode[src_first],
1343 1359 RSP_enc, 0x4, 0, offset,
1344 1360 false);
1345 1361 #ifndef PRODUCT
1346 1362 } else if (!do_size) {
1347 1363 st->print("movq [rsp + #%d], %s\t# spill",
1348 1364 offset,
1349 1365 Matcher::regName[src_first]);
1350 1366 #endif
1351 1367 }
1352 1368 return ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX
1353 1369 } else {
1354 1370 // 32-bit
1355 1371 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1356 1372 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1357 1373 int offset = ra_->reg2offset(dst_first);
1358 1374 if (cbuf) {
1359 1375 if (Matcher::_regEncode[src_first] >= 8) {
1360 1376 emit_opcode(*cbuf, Assembler::REX_R);
1361 1377 }
1362 1378 emit_opcode(*cbuf, 0x89);
1363 1379 encode_RegMem(*cbuf,
1364 1380 Matcher::_regEncode[src_first],
1365 1381 RSP_enc, 0x4, 0, offset,
1366 1382 false);
1367 1383 #ifndef PRODUCT
1368 1384 } else if (!do_size) {
1369 1385 st->print("movl [rsp + #%d], %s\t# spill",
1370 1386 offset,
1371 1387 Matcher::regName[src_first]);
1372 1388 #endif
1373 1389 }
1374 1390 return
1375 1391 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1376 1392 ((Matcher::_regEncode[src_first] < 8)
1377 1393 ? 3
1378 1394 : 4); // REX
1379 1395 }
1380 1396 } else if (dst_first_rc == rc_int) {
1381 1397 // gpr -> gpr
1382 1398 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1383 1399 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1384 1400 // 64-bit
1385 1401 if (cbuf) {
1386 1402 if (Matcher::_regEncode[dst_first] < 8) {
1387 1403 if (Matcher::_regEncode[src_first] < 8) {
1388 1404 emit_opcode(*cbuf, Assembler::REX_W);
1389 1405 } else {
1390 1406 emit_opcode(*cbuf, Assembler::REX_WB);
1391 1407 }
1392 1408 } else {
1393 1409 if (Matcher::_regEncode[src_first] < 8) {
1394 1410 emit_opcode(*cbuf, Assembler::REX_WR);
1395 1411 } else {
1396 1412 emit_opcode(*cbuf, Assembler::REX_WRB);
1397 1413 }
1398 1414 }
1399 1415 emit_opcode(*cbuf, 0x8B);
1400 1416 emit_rm(*cbuf, 0x3,
1401 1417 Matcher::_regEncode[dst_first] & 7,
1402 1418 Matcher::_regEncode[src_first] & 7);
1403 1419 #ifndef PRODUCT
1404 1420 } else if (!do_size) {
1405 1421 st->print("movq %s, %s\t# spill",
1406 1422 Matcher::regName[dst_first],
1407 1423 Matcher::regName[src_first]);
1408 1424 #endif
1409 1425 }
1410 1426 return 3; // REX
1411 1427 } else {
1412 1428 // 32-bit
1413 1429 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1414 1430 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1415 1431 if (cbuf) {
1416 1432 if (Matcher::_regEncode[dst_first] < 8) {
1417 1433 if (Matcher::_regEncode[src_first] >= 8) {
1418 1434 emit_opcode(*cbuf, Assembler::REX_B);
1419 1435 }
1420 1436 } else {
1421 1437 if (Matcher::_regEncode[src_first] < 8) {
1422 1438 emit_opcode(*cbuf, Assembler::REX_R);
1423 1439 } else {
1424 1440 emit_opcode(*cbuf, Assembler::REX_RB);
1425 1441 }
1426 1442 }
1427 1443 emit_opcode(*cbuf, 0x8B);
1428 1444 emit_rm(*cbuf, 0x3,
1429 1445 Matcher::_regEncode[dst_first] & 7,
1430 1446 Matcher::_regEncode[src_first] & 7);
1431 1447 #ifndef PRODUCT
1432 1448 } else if (!do_size) {
1433 1449 st->print("movl %s, %s\t# spill",
1434 1450 Matcher::regName[dst_first],
1435 1451 Matcher::regName[src_first]);
1436 1452 #endif
1437 1453 }
1438 1454 return
1439 1455 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1440 1456 ? 2
1441 1457 : 3; // REX
1442 1458 }
1443 1459 } else if (dst_first_rc == rc_float) {
1444 1460 // gpr -> xmm
1445 1461 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1446 1462 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1447 1463 // 64-bit
1448 1464 if (cbuf) {
1449 1465 emit_opcode(*cbuf, 0x66);
1450 1466 if (Matcher::_regEncode[dst_first] < 8) {
1451 1467 if (Matcher::_regEncode[src_first] < 8) {
1452 1468 emit_opcode(*cbuf, Assembler::REX_W);
1453 1469 } else {
1454 1470 emit_opcode(*cbuf, Assembler::REX_WB);
1455 1471 }
1456 1472 } else {
1457 1473 if (Matcher::_regEncode[src_first] < 8) {
1458 1474 emit_opcode(*cbuf, Assembler::REX_WR);
1459 1475 } else {
1460 1476 emit_opcode(*cbuf, Assembler::REX_WRB);
1461 1477 }
1462 1478 }
1463 1479 emit_opcode(*cbuf, 0x0F);
1464 1480 emit_opcode(*cbuf, 0x6E);
1465 1481 emit_rm(*cbuf, 0x3,
1466 1482 Matcher::_regEncode[dst_first] & 7,
1467 1483 Matcher::_regEncode[src_first] & 7);
1468 1484 #ifndef PRODUCT
1469 1485 } else if (!do_size) {
1470 1486 st->print("movdq %s, %s\t# spill",
1471 1487 Matcher::regName[dst_first],
1472 1488 Matcher::regName[src_first]);
1473 1489 #endif
1474 1490 }
1475 1491 return 5; // REX
1476 1492 } else {
1477 1493 // 32-bit
1478 1494 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1479 1495 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1480 1496 if (cbuf) {
1481 1497 emit_opcode(*cbuf, 0x66);
1482 1498 if (Matcher::_regEncode[dst_first] < 8) {
1483 1499 if (Matcher::_regEncode[src_first] >= 8) {
1484 1500 emit_opcode(*cbuf, Assembler::REX_B);
1485 1501 }
1486 1502 } else {
1487 1503 if (Matcher::_regEncode[src_first] < 8) {
1488 1504 emit_opcode(*cbuf, Assembler::REX_R);
1489 1505 } else {
1490 1506 emit_opcode(*cbuf, Assembler::REX_RB);
1491 1507 }
1492 1508 }
1493 1509 emit_opcode(*cbuf, 0x0F);
1494 1510 emit_opcode(*cbuf, 0x6E);
1495 1511 emit_rm(*cbuf, 0x3,
1496 1512 Matcher::_regEncode[dst_first] & 7,
1497 1513 Matcher::_regEncode[src_first] & 7);
1498 1514 #ifndef PRODUCT
1499 1515 } else if (!do_size) {
1500 1516 st->print("movdl %s, %s\t# spill",
1501 1517 Matcher::regName[dst_first],
1502 1518 Matcher::regName[src_first]);
1503 1519 #endif
1504 1520 }
1505 1521 return
1506 1522 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1507 1523 ? 4
1508 1524 : 5; // REX
1509 1525 }
1510 1526 }
1511 1527 } else if (src_first_rc == rc_float) {
1512 1528 // xmm ->
1513 1529 if (dst_first_rc == rc_stack) {
1514 1530 // xmm -> mem
1515 1531 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1516 1532 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1517 1533 // 64-bit
1518 1534 int offset = ra_->reg2offset(dst_first);
1519 1535 if (cbuf) {
1520 1536 emit_opcode(*cbuf, 0xF2);
1521 1537 if (Matcher::_regEncode[src_first] >= 8) {
1522 1538 emit_opcode(*cbuf, Assembler::REX_R);
1523 1539 }
1524 1540 emit_opcode(*cbuf, 0x0F);
1525 1541 emit_opcode(*cbuf, 0x11);
1526 1542 encode_RegMem(*cbuf,
1527 1543 Matcher::_regEncode[src_first],
1528 1544 RSP_enc, 0x4, 0, offset,
1529 1545 false);
1530 1546 #ifndef PRODUCT
1531 1547 } else if (!do_size) {
1532 1548 st->print("movsd [rsp + #%d], %s\t# spill",
1533 1549 offset,
1534 1550 Matcher::regName[src_first]);
1535 1551 #endif
1536 1552 }
1537 1553 return
1538 1554 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1539 1555 ((Matcher::_regEncode[src_first] < 8)
1540 1556 ? 5
1541 1557 : 6); // REX
1542 1558 } else {
1543 1559 // 32-bit
1544 1560 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1545 1561 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1546 1562 int offset = ra_->reg2offset(dst_first);
1547 1563 if (cbuf) {
1548 1564 emit_opcode(*cbuf, 0xF3);
1549 1565 if (Matcher::_regEncode[src_first] >= 8) {
1550 1566 emit_opcode(*cbuf, Assembler::REX_R);
1551 1567 }
1552 1568 emit_opcode(*cbuf, 0x0F);
1553 1569 emit_opcode(*cbuf, 0x11);
1554 1570 encode_RegMem(*cbuf,
1555 1571 Matcher::_regEncode[src_first],
1556 1572 RSP_enc, 0x4, 0, offset,
1557 1573 false);
1558 1574 #ifndef PRODUCT
1559 1575 } else if (!do_size) {
1560 1576 st->print("movss [rsp + #%d], %s\t# spill",
1561 1577 offset,
1562 1578 Matcher::regName[src_first]);
1563 1579 #endif
1564 1580 }
1565 1581 return
1566 1582 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1567 1583 ((Matcher::_regEncode[src_first] < 8)
1568 1584 ? 5
1569 1585 : 6); // REX
1570 1586 }
1571 1587 } else if (dst_first_rc == rc_int) {
1572 1588 // xmm -> gpr
1573 1589 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1574 1590 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1575 1591 // 64-bit
1576 1592 if (cbuf) {
1577 1593 emit_opcode(*cbuf, 0x66);
1578 1594 if (Matcher::_regEncode[dst_first] < 8) {
1579 1595 if (Matcher::_regEncode[src_first] < 8) {
1580 1596 emit_opcode(*cbuf, Assembler::REX_W);
1581 1597 } else {
1582 1598 emit_opcode(*cbuf, Assembler::REX_WR); // attention!
1583 1599 }
1584 1600 } else {
1585 1601 if (Matcher::_regEncode[src_first] < 8) {
1586 1602 emit_opcode(*cbuf, Assembler::REX_WB); // attention!
1587 1603 } else {
1588 1604 emit_opcode(*cbuf, Assembler::REX_WRB);
1589 1605 }
1590 1606 }
1591 1607 emit_opcode(*cbuf, 0x0F);
1592 1608 emit_opcode(*cbuf, 0x7E);
1593 1609 emit_rm(*cbuf, 0x3,
1594 1610 Matcher::_regEncode[dst_first] & 7,
1595 1611 Matcher::_regEncode[src_first] & 7);
1596 1612 #ifndef PRODUCT
1597 1613 } else if (!do_size) {
1598 1614 st->print("movdq %s, %s\t# spill",
1599 1615 Matcher::regName[dst_first],
1600 1616 Matcher::regName[src_first]);
1601 1617 #endif
1602 1618 }
1603 1619 return 5; // REX
1604 1620 } else {
1605 1621 // 32-bit
1606 1622 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1607 1623 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1608 1624 if (cbuf) {
1609 1625 emit_opcode(*cbuf, 0x66);
1610 1626 if (Matcher::_regEncode[dst_first] < 8) {
1611 1627 if (Matcher::_regEncode[src_first] >= 8) {
1612 1628 emit_opcode(*cbuf, Assembler::REX_R); // attention!
1613 1629 }
1614 1630 } else {
1615 1631 if (Matcher::_regEncode[src_first] < 8) {
1616 1632 emit_opcode(*cbuf, Assembler::REX_B); // attention!
1617 1633 } else {
1618 1634 emit_opcode(*cbuf, Assembler::REX_RB);
1619 1635 }
1620 1636 }
1621 1637 emit_opcode(*cbuf, 0x0F);
1622 1638 emit_opcode(*cbuf, 0x7E);
1623 1639 emit_rm(*cbuf, 0x3,
1624 1640 Matcher::_regEncode[dst_first] & 7,
1625 1641 Matcher::_regEncode[src_first] & 7);
1626 1642 #ifndef PRODUCT
1627 1643 } else if (!do_size) {
1628 1644 st->print("movdl %s, %s\t# spill",
1629 1645 Matcher::regName[dst_first],
1630 1646 Matcher::regName[src_first]);
1631 1647 #endif
1632 1648 }
1633 1649 return
1634 1650 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1635 1651 ? 4
1636 1652 : 5; // REX
1637 1653 }
1638 1654 } else if (dst_first_rc == rc_float) {
1639 1655 // xmm -> xmm
1640 1656 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1641 1657 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1642 1658 // 64-bit
1643 1659 if (cbuf) {
1644 1660 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2);
1645 1661 if (Matcher::_regEncode[dst_first] < 8) {
1646 1662 if (Matcher::_regEncode[src_first] >= 8) {
1647 1663 emit_opcode(*cbuf, Assembler::REX_B);
1648 1664 }
1649 1665 } else {
1650 1666 if (Matcher::_regEncode[src_first] < 8) {
1651 1667 emit_opcode(*cbuf, Assembler::REX_R);
1652 1668 } else {
1653 1669 emit_opcode(*cbuf, Assembler::REX_RB);
1654 1670 }
1655 1671 }
1656 1672 emit_opcode(*cbuf, 0x0F);
1657 1673 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
1658 1674 emit_rm(*cbuf, 0x3,
1659 1675 Matcher::_regEncode[dst_first] & 7,
1660 1676 Matcher::_regEncode[src_first] & 7);
1661 1677 #ifndef PRODUCT
1662 1678 } else if (!do_size) {
1663 1679 st->print("%s %s, %s\t# spill",
1664 1680 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
1665 1681 Matcher::regName[dst_first],
1666 1682 Matcher::regName[src_first]);
1667 1683 #endif
1668 1684 }
1669 1685 return
1670 1686 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1671 1687 ? 4
1672 1688 : 5; // REX
1673 1689 } else {
1674 1690 // 32-bit
1675 1691 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1676 1692 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1677 1693 if (cbuf) {
1678 1694 if (!UseXmmRegToRegMoveAll)
1679 1695 emit_opcode(*cbuf, 0xF3);
1680 1696 if (Matcher::_regEncode[dst_first] < 8) {
1681 1697 if (Matcher::_regEncode[src_first] >= 8) {
1682 1698 emit_opcode(*cbuf, Assembler::REX_B);
1683 1699 }
1684 1700 } else {
1685 1701 if (Matcher::_regEncode[src_first] < 8) {
1686 1702 emit_opcode(*cbuf, Assembler::REX_R);
1687 1703 } else {
1688 1704 emit_opcode(*cbuf, Assembler::REX_RB);
1689 1705 }
1690 1706 }
1691 1707 emit_opcode(*cbuf, 0x0F);
1692 1708 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
1693 1709 emit_rm(*cbuf, 0x3,
1694 1710 Matcher::_regEncode[dst_first] & 7,
1695 1711 Matcher::_regEncode[src_first] & 7);
1696 1712 #ifndef PRODUCT
1697 1713 } else if (!do_size) {
1698 1714 st->print("%s %s, %s\t# spill",
1699 1715 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1700 1716 Matcher::regName[dst_first],
1701 1717 Matcher::regName[src_first]);
1702 1718 #endif
1703 1719 }
1704 1720 return
1705 1721 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1706 1722 ? (UseXmmRegToRegMoveAll ? 3 : 4)
1707 1723 : (UseXmmRegToRegMoveAll ? 4 : 5); // REX
1708 1724 }
1709 1725 }
1710 1726 }
1711 1727
1712 1728 assert(0," foo ");
1713 1729 Unimplemented();
1714 1730
1715 1731 return 0;
1716 1732 }
1717 1733
1718 1734 #ifndef PRODUCT
1719 1735 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const
1720 1736 {
1721 1737 implementation(NULL, ra_, false, st);
1722 1738 }
1723 1739 #endif
1724 1740
1725 1741 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const
1726 1742 {
1727 1743 implementation(&cbuf, ra_, false, NULL);
1728 1744 }
1729 1745
1730 1746 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const
1731 1747 {
1732 1748 return implementation(NULL, ra_, true, NULL);
1733 1749 }
1734 1750
1735 1751 //=============================================================================
1736 1752 #ifndef PRODUCT
1737 1753 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const
1738 1754 {
1739 1755 st->print("nop \t# %d bytes pad for loops and calls", _count);
1740 1756 }
1741 1757 #endif
1742 1758
1743 1759 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const
1744 1760 {
1745 1761 MacroAssembler _masm(&cbuf);
1746 1762 __ nop(_count);
1747 1763 }
1748 1764
1749 1765 uint MachNopNode::size(PhaseRegAlloc*) const
1750 1766 {
1751 1767 return _count;
1752 1768 }
1753 1769
1754 1770
1755 1771 //=============================================================================
1756 1772 #ifndef PRODUCT
1757 1773 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1758 1774 {
1759 1775 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1760 1776 int reg = ra_->get_reg_first(this);
1761 1777 st->print("leaq %s, [rsp + #%d]\t# box lock",
1762 1778 Matcher::regName[reg], offset);
1763 1779 }
1764 1780 #endif
1765 1781
1766 1782 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1767 1783 {
1768 1784 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1769 1785 int reg = ra_->get_encode(this);
1770 1786 if (offset >= 0x80) {
1771 1787 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1772 1788 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1773 1789 emit_rm(cbuf, 0x2, reg & 7, 0x04);
1774 1790 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1775 1791 emit_d32(cbuf, offset);
1776 1792 } else {
1777 1793 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1778 1794 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1779 1795 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1780 1796 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1781 1797 emit_d8(cbuf, offset);
1782 1798 }
1783 1799 }
1784 1800
1785 1801 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1786 1802 {
1787 1803 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1788 1804 return (offset < 0x80) ? 5 : 8; // REX
1789 1805 }
1790 1806
1791 1807 //=============================================================================
1792 1808
1793 1809 // emit call stub, compiled java to interpreter
1794 1810 void emit_java_to_interp(CodeBuffer& cbuf)
1795 1811 {
1796 1812 // Stub is fixed up when the corresponding call is converted from
1797 1813 // calling compiled code to calling interpreted code.
1798 1814 // movq rbx, 0
1799 1815 // jmp -5 # to self
1800 1816
1801 1817 address mark = cbuf.inst_mark(); // get mark within main instrs section
1802 1818
1803 1819 // Note that the code buffer's inst_mark is always relative to insts.
1804 1820 // That's why we must use the macroassembler to generate a stub.
1805 1821 MacroAssembler _masm(&cbuf);
1806 1822
1807 1823 address base =
1808 1824 __ start_a_stub(Compile::MAX_stubs_size);
1809 1825 if (base == NULL) return; // CodeBuffer::expand failed
1810 1826 // static stub relocation stores the instruction address of the call
1811 1827 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64);
1812 1828 // static stub relocation also tags the methodOop in the code-stream.
1813 1829 __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time
1814 1830 // This is recognized as unresolved by relocs/nativeinst/ic code
1815 1831 __ jump(RuntimeAddress(__ pc()));
1816 1832
1817 1833 // Update current stubs pointer and restore code_end.
1818 1834 __ end_a_stub();
1819 1835 }
1820 1836
1821 1837 // size of call stub, compiled java to interpretor
1822 1838 uint size_java_to_interp()
1823 1839 {
1824 1840 return 15; // movq (1+1+8); jmp (1+4)
1825 1841 }
1826 1842
1827 1843 // relocation entries for call stub, compiled java to interpretor
1828 1844 uint reloc_java_to_interp()
1829 1845 {
1830 1846 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call
1831 1847 }
1832 1848
1833 1849 //=============================================================================
1834 1850 #ifndef PRODUCT
1835 1851 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1836 1852 {
1837 1853 if (UseCompressedOops) {
1838 1854 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t", oopDesc::klass_offset_in_bytes());
1839 1855 if (Universe::narrow_oop_shift() != 0) {
1840 1856 st->print_cr("leaq rscratch1, [r12_heapbase, r, Address::times_8, 0]");
1841 1857 }
1842 1858 st->print_cr("cmpq rax, rscratch1\t # Inline cache check");
1843 1859 } else {
1844 1860 st->print_cr("cmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t"
1845 1861 "# Inline cache check", oopDesc::klass_offset_in_bytes());
1846 1862 }
1847 1863 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1848 1864 st->print_cr("\tnop");
1849 1865 if (!OptoBreakpoint) {
1850 1866 st->print_cr("\tnop");
1851 1867 }
1852 1868 }
1853 1869 #endif
1854 1870
1855 1871 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1856 1872 {
1857 1873 MacroAssembler masm(&cbuf);
1858 1874 #ifdef ASSERT
1859 1875 uint code_size = cbuf.code_size();
1860 1876 #endif
1861 1877 if (UseCompressedOops) {
1862 1878 masm.load_klass(rscratch1, j_rarg0);
1863 1879 masm.cmpptr(rax, rscratch1);
1864 1880 } else {
1865 1881 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1866 1882 }
1867 1883
1868 1884 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1869 1885
1870 1886 /* WARNING these NOPs are critical so that verified entry point is properly
1871 1887 aligned for patching by NativeJump::patch_verified_entry() */
1872 1888 int nops_cnt = 1;
1873 1889 if (!OptoBreakpoint) {
1874 1890 // Leave space for int3
1875 1891 nops_cnt += 1;
1876 1892 }
1877 1893 if (UseCompressedOops) {
1878 1894 // ??? divisible by 4 is aligned?
1879 1895 nops_cnt += 1;
1880 1896 }
1881 1897 masm.nop(nops_cnt);
1882 1898
1883 1899 assert(cbuf.code_size() - code_size == size(ra_),
1884 1900 "checking code size of inline cache node");
1885 1901 }
1886 1902
1887 1903 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1888 1904 {
1889 1905 if (UseCompressedOops) {
1890 1906 if (Universe::narrow_oop_shift() == 0) {
1891 1907 return OptoBreakpoint ? 15 : 16;
1892 1908 } else {
1893 1909 return OptoBreakpoint ? 19 : 20;
1894 1910 }
1895 1911 } else {
1896 1912 return OptoBreakpoint ? 11 : 12;
1897 1913 }
1898 1914 }
1899 1915
1900 1916
1901 1917 //=============================================================================
1902 1918 uint size_exception_handler()
1903 1919 {
1904 1920 // NativeCall instruction size is the same as NativeJump.
1905 1921 // Note that this value is also credited (in output.cpp) to
1906 1922 // the size of the code section.
1907 1923 return NativeJump::instruction_size;
1908 1924 }
1909 1925
1910 1926 // Emit exception handler code.
1911 1927 int emit_exception_handler(CodeBuffer& cbuf)
1912 1928 {
1913 1929
1914 1930 // Note that the code buffer's inst_mark is always relative to insts.
1915 1931 // That's why we must use the macroassembler to generate a handler.
1916 1932 MacroAssembler _masm(&cbuf);
1917 1933 address base =
1918 1934 __ start_a_stub(size_exception_handler());
1919 1935 if (base == NULL) return 0; // CodeBuffer::expand failed
1920 1936 int offset = __ offset();
1921 1937 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->instructions_begin()));
1922 1938 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
1923 1939 __ end_a_stub();
1924 1940 return offset;
1925 1941 }
1926 1942
1927 1943 uint size_deopt_handler()
1928 1944 {
1929 1945 // three 5 byte instructions
1930 1946 return 15;
1931 1947 }
1932 1948
1933 1949 // Emit deopt handler code.
1934 1950 int emit_deopt_handler(CodeBuffer& cbuf)
1935 1951 {
1936 1952
1937 1953 // Note that the code buffer's inst_mark is always relative to insts.
1938 1954 // That's why we must use the macroassembler to generate a handler.
1939 1955 MacroAssembler _masm(&cbuf);
1940 1956 address base =
1941 1957 __ start_a_stub(size_deopt_handler());
1942 1958 if (base == NULL) return 0; // CodeBuffer::expand failed
1943 1959 int offset = __ offset();
1944 1960 address the_pc = (address) __ pc();
1945 1961 Label next;
1946 1962 // push a "the_pc" on the stack without destroying any registers
1947 1963 // as they all may be live.
1948 1964
1949 1965 // push address of "next"
1950 1966 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
1951 1967 __ bind(next);
1952 1968 // adjust it so it matches "the_pc"
1953 1969 __ subptr(Address(rsp, 0), __ offset() - offset);
1954 1970 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1955 1971 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1956 1972 __ end_a_stub();
1957 1973 return offset;
1958 1974 }
1959 1975
1960 1976 static void emit_double_constant(CodeBuffer& cbuf, double x) {
1961 1977 int mark = cbuf.insts()->mark_off();
1962 1978 MacroAssembler _masm(&cbuf);
1963 1979 address double_address = __ double_constant(x);
1964 1980 cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
1965 1981 emit_d32_reloc(cbuf,
1966 1982 (int) (double_address - cbuf.code_end() - 4),
1967 1983 internal_word_Relocation::spec(double_address),
1968 1984 RELOC_DISP32);
1969 1985 }
1970 1986
1971 1987 static void emit_float_constant(CodeBuffer& cbuf, float x) {
1972 1988 int mark = cbuf.insts()->mark_off();
1973 1989 MacroAssembler _masm(&cbuf);
1974 1990 address float_address = __ float_constant(x);
1975 1991 cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
1976 1992 emit_d32_reloc(cbuf,
1977 1993 (int) (float_address - cbuf.code_end() - 4),
1978 1994 internal_word_Relocation::spec(float_address),
1979 1995 RELOC_DISP32);
1980 1996 }
1981 1997
1982 1998
1983 1999 const bool Matcher::match_rule_supported(int opcode) {
1984 2000 if (!has_match_rule(opcode))
1985 2001 return false;
1986 2002
1987 2003 return true; // Per default match rules are supported.
1988 2004 }
1989 2005
1990 2006 int Matcher::regnum_to_fpu_offset(int regnum)
1991 2007 {
1992 2008 return regnum - 32; // The FP registers are in the second chunk
1993 2009 }
1994 2010
1995 2011 // This is UltraSparc specific, true just means we have fast l2f conversion
1996 2012 const bool Matcher::convL2FSupported(void) {
1997 2013 return true;
1998 2014 }
1999 2015
2000 2016 // Vector width in bytes
2001 2017 const uint Matcher::vector_width_in_bytes(void) {
2002 2018 return 8;
2003 2019 }
2004 2020
2005 2021 // Vector ideal reg
2006 2022 const uint Matcher::vector_ideal_reg(void) {
2007 2023 return Op_RegD;
2008 2024 }
2009 2025
2010 2026 // Is this branch offset short enough that a short branch can be used?
2011 2027 //
2012 2028 // NOTE: If the platform does not provide any short branch variants, then
2013 2029 // this method should return false for offset 0.
2014 2030 bool Matcher::is_short_branch_offset(int rule, int offset) {
2015 2031 // the short version of jmpConUCF2 contains multiple branches,
2016 2032 // making the reach slightly less
2017 2033 if (rule == jmpConUCF2_rule)
2018 2034 return (-126 <= offset && offset <= 125);
2019 2035 return (-128 <= offset && offset <= 127);
2020 2036 }
2021 2037
2022 2038 const bool Matcher::isSimpleConstant64(jlong value) {
2023 2039 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
2024 2040 //return value == (int) value; // Cf. storeImmL and immL32.
2025 2041
2026 2042 // Probably always true, even if a temp register is required.
2027 2043 return true;
2028 2044 }
2029 2045
2030 2046 // The ecx parameter to rep stosq for the ClearArray node is in words.
2031 2047 const bool Matcher::init_array_count_is_in_bytes = false;
2032 2048
2033 2049 // Threshold size for cleararray.
2034 2050 const int Matcher::init_array_short_size = 8 * BytesPerLong;
2035 2051
2036 2052 // Should the Matcher clone shifts on addressing modes, expecting them
2037 2053 // to be subsumed into complex addressing expressions or compute them
2038 2054 // into registers? True for Intel but false for most RISCs
2039 2055 const bool Matcher::clone_shift_expressions = true;
2040 2056
2041 2057 // Is it better to copy float constants, or load them directly from
2042 2058 // memory? Intel can load a float constant from a direct address,
2043 2059 // requiring no extra registers. Most RISCs will have to materialize
2044 2060 // an address into a register first, so they would do better to copy
2045 2061 // the constant from stack.
2046 2062 const bool Matcher::rematerialize_float_constants = true; // XXX
2047 2063
2048 2064 // If CPU can load and store mis-aligned doubles directly then no
2049 2065 // fixup is needed. Else we split the double into 2 integer pieces
2050 2066 // and move it piece-by-piece. Only happens when passing doubles into
2051 2067 // C code as the Java calling convention forces doubles to be aligned.
2052 2068 const bool Matcher::misaligned_doubles_ok = true;
2053 2069
2054 2070 // No-op on amd64
2055 2071 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {}
2056 2072
2057 2073 // Advertise here if the CPU requires explicit rounding operations to
2058 2074 // implement the UseStrictFP mode.
2059 2075 const bool Matcher::strict_fp_requires_explicit_rounding = true;
2060 2076
2061 2077 // Do floats take an entire double register or just half?
2062 2078 const bool Matcher::float_in_double = true;
2063 2079 // Do ints take an entire long register or just half?
2064 2080 const bool Matcher::int_in_long = true;
2065 2081
2066 2082 // Return whether or not this register is ever used as an argument.
2067 2083 // This function is used on startup to build the trampoline stubs in
2068 2084 // generateOptoStub. Registers not mentioned will be killed by the VM
2069 2085 // call in the trampoline, and arguments in those registers not be
2070 2086 // available to the callee.
2071 2087 bool Matcher::can_be_java_arg(int reg)
2072 2088 {
2073 2089 return
2074 2090 reg == RDI_num || reg == RDI_H_num ||
2075 2091 reg == RSI_num || reg == RSI_H_num ||
2076 2092 reg == RDX_num || reg == RDX_H_num ||
2077 2093 reg == RCX_num || reg == RCX_H_num ||
2078 2094 reg == R8_num || reg == R8_H_num ||
2079 2095 reg == R9_num || reg == R9_H_num ||
2080 2096 reg == R12_num || reg == R12_H_num ||
2081 2097 reg == XMM0_num || reg == XMM0_H_num ||
2082 2098 reg == XMM1_num || reg == XMM1_H_num ||
2083 2099 reg == XMM2_num || reg == XMM2_H_num ||
2084 2100 reg == XMM3_num || reg == XMM3_H_num ||
2085 2101 reg == XMM4_num || reg == XMM4_H_num ||
2086 2102 reg == XMM5_num || reg == XMM5_H_num ||
2087 2103 reg == XMM6_num || reg == XMM6_H_num ||
2088 2104 reg == XMM7_num || reg == XMM7_H_num;
2089 2105 }
2090 2106
2091 2107 bool Matcher::is_spillable_arg(int reg)
2092 2108 {
2093 2109 return can_be_java_arg(reg);
2094 2110 }
2095 2111
2096 2112 // Register for DIVI projection of divmodI
2097 2113 RegMask Matcher::divI_proj_mask() {
2098 2114 return INT_RAX_REG_mask;
2099 2115 }
2100 2116
2101 2117 // Register for MODI projection of divmodI
2102 2118 RegMask Matcher::modI_proj_mask() {
2103 2119 return INT_RDX_REG_mask;
2104 2120 }
2105 2121
↓ open down ↓ |
1504 lines elided |
↑ open up ↑ |
2106 2122 // Register for DIVL projection of divmodL
2107 2123 RegMask Matcher::divL_proj_mask() {
2108 2124 return LONG_RAX_REG_mask;
2109 2125 }
2110 2126
2111 2127 // Register for MODL projection of divmodL
2112 2128 RegMask Matcher::modL_proj_mask() {
2113 2129 return LONG_RDX_REG_mask;
2114 2130 }
2115 2131
2132 +const RegMask Matcher::method_handle_invoke_SP_save_mask() {
2133 + return PTR_RBP_REG_mask;
2134 +}
2135 +
2116 2136 static Address build_address(int b, int i, int s, int d) {
2117 2137 Register index = as_Register(i);
2118 2138 Address::ScaleFactor scale = (Address::ScaleFactor)s;
2119 2139 if (index == rsp) {
2120 2140 index = noreg;
2121 2141 scale = Address::no_scale;
2122 2142 }
2123 2143 Address addr(as_Register(b), index, scale, d);
2124 2144 return addr;
2125 2145 }
2126 2146
2127 2147 %}
2128 2148
2129 2149 //----------ENCODING BLOCK-----------------------------------------------------
2130 2150 // This block specifies the encoding classes used by the compiler to
2131 2151 // output byte streams. Encoding classes are parameterized macros
2132 2152 // used by Machine Instruction Nodes in order to generate the bit
2133 2153 // encoding of the instruction. Operands specify their base encoding
2134 2154 // interface with the interface keyword. There are currently
2135 2155 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
2136 2156 // COND_INTER. REG_INTER causes an operand to generate a function
2137 2157 // which returns its register number when queried. CONST_INTER causes
2138 2158 // an operand to generate a function which returns the value of the
2139 2159 // constant when queried. MEMORY_INTER causes an operand to generate
2140 2160 // four functions which return the Base Register, the Index Register,
2141 2161 // the Scale Value, and the Offset Value of the operand when queried.
2142 2162 // COND_INTER causes an operand to generate six functions which return
2143 2163 // the encoding code (ie - encoding bits for the instruction)
2144 2164 // associated with each basic boolean condition for a conditional
2145 2165 // instruction.
2146 2166 //
2147 2167 // Instructions specify two basic values for encoding. Again, a
2148 2168 // function is available to check if the constant displacement is an
2149 2169 // oop. They use the ins_encode keyword to specify their encoding
2150 2170 // classes (which must be a sequence of enc_class names, and their
2151 2171 // parameters, specified in the encoding block), and they use the
2152 2172 // opcode keyword to specify, in order, their primary, secondary, and
2153 2173 // tertiary opcode. Only the opcode sections which a particular
2154 2174 // instruction needs for encoding need to be specified.
2155 2175 encode %{
2156 2176 // Build emit functions for each basic byte or larger field in the
2157 2177 // intel encoding scheme (opcode, rm, sib, immediate), and call them
2158 2178 // from C++ code in the enc_class source block. Emit functions will
2159 2179 // live in the main source block for now. In future, we can
2160 2180 // generalize this by adding a syntax that specifies the sizes of
2161 2181 // fields in an order, so that the adlc can build the emit functions
2162 2182 // automagically
2163 2183
2164 2184 // Emit primary opcode
2165 2185 enc_class OpcP
2166 2186 %{
2167 2187 emit_opcode(cbuf, $primary);
2168 2188 %}
2169 2189
2170 2190 // Emit secondary opcode
2171 2191 enc_class OpcS
2172 2192 %{
2173 2193 emit_opcode(cbuf, $secondary);
2174 2194 %}
2175 2195
2176 2196 // Emit tertiary opcode
2177 2197 enc_class OpcT
2178 2198 %{
2179 2199 emit_opcode(cbuf, $tertiary);
2180 2200 %}
2181 2201
2182 2202 // Emit opcode directly
2183 2203 enc_class Opcode(immI d8)
2184 2204 %{
2185 2205 emit_opcode(cbuf, $d8$$constant);
2186 2206 %}
2187 2207
2188 2208 // Emit size prefix
2189 2209 enc_class SizePrefix
2190 2210 %{
2191 2211 emit_opcode(cbuf, 0x66);
2192 2212 %}
2193 2213
2194 2214 enc_class reg(rRegI reg)
2195 2215 %{
2196 2216 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
2197 2217 %}
2198 2218
2199 2219 enc_class reg_reg(rRegI dst, rRegI src)
2200 2220 %{
2201 2221 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2202 2222 %}
2203 2223
2204 2224 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
2205 2225 %{
2206 2226 emit_opcode(cbuf, $opcode$$constant);
2207 2227 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2208 2228 %}
2209 2229
2210 2230 enc_class cmpfp_fixup()
2211 2231 %{
2212 2232 // jnp,s exit
2213 2233 emit_opcode(cbuf, 0x7B);
2214 2234 emit_d8(cbuf, 0x0A);
2215 2235
2216 2236 // pushfq
2217 2237 emit_opcode(cbuf, 0x9C);
2218 2238
2219 2239 // andq $0xffffff2b, (%rsp)
2220 2240 emit_opcode(cbuf, Assembler::REX_W);
2221 2241 emit_opcode(cbuf, 0x81);
2222 2242 emit_opcode(cbuf, 0x24);
2223 2243 emit_opcode(cbuf, 0x24);
2224 2244 emit_d32(cbuf, 0xffffff2b);
2225 2245
2226 2246 // popfq
2227 2247 emit_opcode(cbuf, 0x9D);
2228 2248
2229 2249 // nop (target for branch to avoid branch to branch)
2230 2250 emit_opcode(cbuf, 0x90);
2231 2251 %}
2232 2252
2233 2253 enc_class cmpfp3(rRegI dst)
2234 2254 %{
2235 2255 int dstenc = $dst$$reg;
2236 2256
2237 2257 // movl $dst, -1
2238 2258 if (dstenc >= 8) {
2239 2259 emit_opcode(cbuf, Assembler::REX_B);
2240 2260 }
2241 2261 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
2242 2262 emit_d32(cbuf, -1);
2243 2263
2244 2264 // jp,s done
2245 2265 emit_opcode(cbuf, 0x7A);
2246 2266 emit_d8(cbuf, dstenc < 4 ? 0x08 : 0x0A);
2247 2267
2248 2268 // jb,s done
2249 2269 emit_opcode(cbuf, 0x72);
2250 2270 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
2251 2271
2252 2272 // setne $dst
2253 2273 if (dstenc >= 4) {
2254 2274 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
2255 2275 }
2256 2276 emit_opcode(cbuf, 0x0F);
2257 2277 emit_opcode(cbuf, 0x95);
2258 2278 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
2259 2279
2260 2280 // movzbl $dst, $dst
2261 2281 if (dstenc >= 4) {
2262 2282 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
2263 2283 }
2264 2284 emit_opcode(cbuf, 0x0F);
2265 2285 emit_opcode(cbuf, 0xB6);
2266 2286 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
2267 2287 %}
2268 2288
2269 2289 enc_class cdql_enc(no_rax_rdx_RegI div)
2270 2290 %{
2271 2291 // Full implementation of Java idiv and irem; checks for
2272 2292 // special case as described in JVM spec., p.243 & p.271.
2273 2293 //
2274 2294 // normal case special case
2275 2295 //
2276 2296 // input : rax: dividend min_int
2277 2297 // reg: divisor -1
2278 2298 //
2279 2299 // output: rax: quotient (= rax idiv reg) min_int
2280 2300 // rdx: remainder (= rax irem reg) 0
2281 2301 //
2282 2302 // Code sequnce:
2283 2303 //
2284 2304 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax
2285 2305 // 5: 75 07/08 jne e <normal>
2286 2306 // 7: 33 d2 xor %edx,%edx
2287 2307 // [div >= 8 -> offset + 1]
2288 2308 // [REX_B]
2289 2309 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div
2290 2310 // c: 74 03/04 je 11 <done>
2291 2311 // 000000000000000e <normal>:
2292 2312 // e: 99 cltd
2293 2313 // [div >= 8 -> offset + 1]
2294 2314 // [REX_B]
2295 2315 // f: f7 f9 idiv $div
2296 2316 // 0000000000000011 <done>:
2297 2317
2298 2318 // cmp $0x80000000,%eax
2299 2319 emit_opcode(cbuf, 0x3d);
2300 2320 emit_d8(cbuf, 0x00);
2301 2321 emit_d8(cbuf, 0x00);
2302 2322 emit_d8(cbuf, 0x00);
2303 2323 emit_d8(cbuf, 0x80);
2304 2324
2305 2325 // jne e <normal>
2306 2326 emit_opcode(cbuf, 0x75);
2307 2327 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08);
2308 2328
2309 2329 // xor %edx,%edx
2310 2330 emit_opcode(cbuf, 0x33);
2311 2331 emit_d8(cbuf, 0xD2);
2312 2332
2313 2333 // cmp $0xffffffffffffffff,%ecx
2314 2334 if ($div$$reg >= 8) {
2315 2335 emit_opcode(cbuf, Assembler::REX_B);
2316 2336 }
2317 2337 emit_opcode(cbuf, 0x83);
2318 2338 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
2319 2339 emit_d8(cbuf, 0xFF);
2320 2340
2321 2341 // je 11 <done>
2322 2342 emit_opcode(cbuf, 0x74);
2323 2343 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04);
2324 2344
2325 2345 // <normal>
2326 2346 // cltd
2327 2347 emit_opcode(cbuf, 0x99);
2328 2348
2329 2349 // idivl (note: must be emitted by the user of this rule)
2330 2350 // <done>
2331 2351 %}
2332 2352
2333 2353 enc_class cdqq_enc(no_rax_rdx_RegL div)
2334 2354 %{
2335 2355 // Full implementation of Java ldiv and lrem; checks for
2336 2356 // special case as described in JVM spec., p.243 & p.271.
2337 2357 //
2338 2358 // normal case special case
2339 2359 //
2340 2360 // input : rax: dividend min_long
2341 2361 // reg: divisor -1
2342 2362 //
2343 2363 // output: rax: quotient (= rax idiv reg) min_long
2344 2364 // rdx: remainder (= rax irem reg) 0
2345 2365 //
2346 2366 // Code sequnce:
2347 2367 //
2348 2368 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx
2349 2369 // 7: 00 00 80
2350 2370 // a: 48 39 d0 cmp %rdx,%rax
2351 2371 // d: 75 08 jne 17 <normal>
2352 2372 // f: 33 d2 xor %edx,%edx
2353 2373 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div
2354 2374 // 15: 74 05 je 1c <done>
2355 2375 // 0000000000000017 <normal>:
2356 2376 // 17: 48 99 cqto
2357 2377 // 19: 48 f7 f9 idiv $div
2358 2378 // 000000000000001c <done>:
2359 2379
2360 2380 // mov $0x8000000000000000,%rdx
2361 2381 emit_opcode(cbuf, Assembler::REX_W);
2362 2382 emit_opcode(cbuf, 0xBA);
2363 2383 emit_d8(cbuf, 0x00);
2364 2384 emit_d8(cbuf, 0x00);
2365 2385 emit_d8(cbuf, 0x00);
2366 2386 emit_d8(cbuf, 0x00);
2367 2387 emit_d8(cbuf, 0x00);
2368 2388 emit_d8(cbuf, 0x00);
2369 2389 emit_d8(cbuf, 0x00);
2370 2390 emit_d8(cbuf, 0x80);
2371 2391
2372 2392 // cmp %rdx,%rax
2373 2393 emit_opcode(cbuf, Assembler::REX_W);
2374 2394 emit_opcode(cbuf, 0x39);
2375 2395 emit_d8(cbuf, 0xD0);
2376 2396
2377 2397 // jne 17 <normal>
2378 2398 emit_opcode(cbuf, 0x75);
2379 2399 emit_d8(cbuf, 0x08);
2380 2400
2381 2401 // xor %edx,%edx
2382 2402 emit_opcode(cbuf, 0x33);
2383 2403 emit_d8(cbuf, 0xD2);
2384 2404
2385 2405 // cmp $0xffffffffffffffff,$div
2386 2406 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB);
2387 2407 emit_opcode(cbuf, 0x83);
2388 2408 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
2389 2409 emit_d8(cbuf, 0xFF);
2390 2410
2391 2411 // je 1e <done>
2392 2412 emit_opcode(cbuf, 0x74);
2393 2413 emit_d8(cbuf, 0x05);
2394 2414
2395 2415 // <normal>
2396 2416 // cqto
2397 2417 emit_opcode(cbuf, Assembler::REX_W);
2398 2418 emit_opcode(cbuf, 0x99);
2399 2419
2400 2420 // idivq (note: must be emitted by the user of this rule)
2401 2421 // <done>
2402 2422 %}
2403 2423
2404 2424 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
2405 2425 enc_class OpcSE(immI imm)
2406 2426 %{
2407 2427 // Emit primary opcode and set sign-extend bit
2408 2428 // Check for 8-bit immediate, and set sign extend bit in opcode
2409 2429 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2410 2430 emit_opcode(cbuf, $primary | 0x02);
2411 2431 } else {
2412 2432 // 32-bit immediate
2413 2433 emit_opcode(cbuf, $primary);
2414 2434 }
2415 2435 %}
2416 2436
2417 2437 enc_class OpcSErm(rRegI dst, immI imm)
2418 2438 %{
2419 2439 // OpcSEr/m
2420 2440 int dstenc = $dst$$reg;
2421 2441 if (dstenc >= 8) {
2422 2442 emit_opcode(cbuf, Assembler::REX_B);
2423 2443 dstenc -= 8;
2424 2444 }
2425 2445 // Emit primary opcode and set sign-extend bit
2426 2446 // Check for 8-bit immediate, and set sign extend bit in opcode
2427 2447 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2428 2448 emit_opcode(cbuf, $primary | 0x02);
2429 2449 } else {
2430 2450 // 32-bit immediate
2431 2451 emit_opcode(cbuf, $primary);
2432 2452 }
2433 2453 // Emit r/m byte with secondary opcode, after primary opcode.
2434 2454 emit_rm(cbuf, 0x3, $secondary, dstenc);
2435 2455 %}
2436 2456
2437 2457 enc_class OpcSErm_wide(rRegL dst, immI imm)
2438 2458 %{
2439 2459 // OpcSEr/m
2440 2460 int dstenc = $dst$$reg;
2441 2461 if (dstenc < 8) {
2442 2462 emit_opcode(cbuf, Assembler::REX_W);
2443 2463 } else {
2444 2464 emit_opcode(cbuf, Assembler::REX_WB);
2445 2465 dstenc -= 8;
2446 2466 }
2447 2467 // Emit primary opcode and set sign-extend bit
2448 2468 // Check for 8-bit immediate, and set sign extend bit in opcode
2449 2469 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2450 2470 emit_opcode(cbuf, $primary | 0x02);
2451 2471 } else {
2452 2472 // 32-bit immediate
2453 2473 emit_opcode(cbuf, $primary);
2454 2474 }
2455 2475 // Emit r/m byte with secondary opcode, after primary opcode.
2456 2476 emit_rm(cbuf, 0x3, $secondary, dstenc);
2457 2477 %}
2458 2478
2459 2479 enc_class Con8or32(immI imm)
2460 2480 %{
2461 2481 // Check for 8-bit immediate, and set sign extend bit in opcode
2462 2482 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2463 2483 $$$emit8$imm$$constant;
2464 2484 } else {
2465 2485 // 32-bit immediate
2466 2486 $$$emit32$imm$$constant;
2467 2487 }
2468 2488 %}
2469 2489
2470 2490 enc_class Lbl(label labl)
2471 2491 %{
2472 2492 // JMP, CALL
2473 2493 Label* l = $labl$$label;
2474 2494 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0);
2475 2495 %}
2476 2496
2477 2497 enc_class LblShort(label labl)
2478 2498 %{
2479 2499 // JMP, CALL
2480 2500 Label* l = $labl$$label;
2481 2501 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
2482 2502 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
2483 2503 emit_d8(cbuf, disp);
2484 2504 %}
2485 2505
2486 2506 enc_class opc2_reg(rRegI dst)
2487 2507 %{
2488 2508 // BSWAP
2489 2509 emit_cc(cbuf, $secondary, $dst$$reg);
2490 2510 %}
2491 2511
2492 2512 enc_class opc3_reg(rRegI dst)
2493 2513 %{
2494 2514 // BSWAP
2495 2515 emit_cc(cbuf, $tertiary, $dst$$reg);
2496 2516 %}
2497 2517
2498 2518 enc_class reg_opc(rRegI div)
2499 2519 %{
2500 2520 // INC, DEC, IDIV, IMOD, JMP indirect, ...
2501 2521 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
2502 2522 %}
2503 2523
2504 2524 enc_class Jcc(cmpOp cop, label labl)
2505 2525 %{
2506 2526 // JCC
2507 2527 Label* l = $labl$$label;
2508 2528 $$$emit8$primary;
2509 2529 emit_cc(cbuf, $secondary, $cop$$cmpcode);
2510 2530 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0);
2511 2531 %}
2512 2532
2513 2533 enc_class JccShort (cmpOp cop, label labl)
2514 2534 %{
2515 2535 // JCC
2516 2536 Label *l = $labl$$label;
2517 2537 emit_cc(cbuf, $primary, $cop$$cmpcode);
2518 2538 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
2519 2539 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
2520 2540 emit_d8(cbuf, disp);
2521 2541 %}
2522 2542
2523 2543 enc_class enc_cmov(cmpOp cop)
2524 2544 %{
2525 2545 // CMOV
2526 2546 $$$emit8$primary;
2527 2547 emit_cc(cbuf, $secondary, $cop$$cmpcode);
2528 2548 %}
2529 2549
2530 2550 enc_class enc_cmovf_branch(cmpOp cop, regF dst, regF src)
2531 2551 %{
2532 2552 // Invert sense of branch from sense of cmov
2533 2553 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1);
2534 2554 emit_d8(cbuf, ($dst$$reg < 8 && $src$$reg < 8)
2535 2555 ? (UseXmmRegToRegMoveAll ? 3 : 4)
2536 2556 : (UseXmmRegToRegMoveAll ? 4 : 5) ); // REX
2537 2557 // UseXmmRegToRegMoveAll ? movaps(dst, src) : movss(dst, src)
2538 2558 if (!UseXmmRegToRegMoveAll) emit_opcode(cbuf, 0xF3);
2539 2559 if ($dst$$reg < 8) {
2540 2560 if ($src$$reg >= 8) {
2541 2561 emit_opcode(cbuf, Assembler::REX_B);
2542 2562 }
2543 2563 } else {
2544 2564 if ($src$$reg < 8) {
2545 2565 emit_opcode(cbuf, Assembler::REX_R);
2546 2566 } else {
2547 2567 emit_opcode(cbuf, Assembler::REX_RB);
2548 2568 }
2549 2569 }
2550 2570 emit_opcode(cbuf, 0x0F);
2551 2571 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
2552 2572 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2553 2573 %}
2554 2574
2555 2575 enc_class enc_cmovd_branch(cmpOp cop, regD dst, regD src)
2556 2576 %{
2557 2577 // Invert sense of branch from sense of cmov
2558 2578 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1);
2559 2579 emit_d8(cbuf, $dst$$reg < 8 && $src$$reg < 8 ? 4 : 5); // REX
2560 2580
2561 2581 // UseXmmRegToRegMoveAll ? movapd(dst, src) : movsd(dst, src)
2562 2582 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2);
2563 2583 if ($dst$$reg < 8) {
2564 2584 if ($src$$reg >= 8) {
2565 2585 emit_opcode(cbuf, Assembler::REX_B);
2566 2586 }
2567 2587 } else {
2568 2588 if ($src$$reg < 8) {
2569 2589 emit_opcode(cbuf, Assembler::REX_R);
2570 2590 } else {
2571 2591 emit_opcode(cbuf, Assembler::REX_RB);
2572 2592 }
2573 2593 }
2574 2594 emit_opcode(cbuf, 0x0F);
2575 2595 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10);
2576 2596 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
2577 2597 %}
2578 2598
2579 2599 enc_class enc_PartialSubtypeCheck()
2580 2600 %{
2581 2601 Register Rrdi = as_Register(RDI_enc); // result register
2582 2602 Register Rrax = as_Register(RAX_enc); // super class
2583 2603 Register Rrcx = as_Register(RCX_enc); // killed
2584 2604 Register Rrsi = as_Register(RSI_enc); // sub class
2585 2605 Label miss;
2586 2606 const bool set_cond_codes = true;
2587 2607
2588 2608 MacroAssembler _masm(&cbuf);
2589 2609 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
2590 2610 NULL, &miss,
2591 2611 /*set_cond_codes:*/ true);
2592 2612 if ($primary) {
2593 2613 __ xorptr(Rrdi, Rrdi);
2594 2614 }
2595 2615 __ bind(miss);
2596 2616 %}
2597 2617
2598 2618 enc_class Java_To_Interpreter(method meth)
2599 2619 %{
2600 2620 // CALL Java_To_Interpreter
↓ open down ↓ |
475 lines elided |
↑ open up ↑ |
2601 2621 // This is the instruction starting address for relocation info.
2602 2622 cbuf.set_inst_mark();
2603 2623 $$$emit8$primary;
2604 2624 // CALL directly to the runtime
2605 2625 emit_d32_reloc(cbuf,
2606 2626 (int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4),
2607 2627 runtime_call_Relocation::spec(),
2608 2628 RELOC_DISP32);
2609 2629 %}
2610 2630
2631 + enc_class preserve_SP %{
2632 + debug_only(int off0 = cbuf.code_size());
2633 + MacroAssembler _masm(&cbuf);
2634 + // RBP is preserved across all calls, even compiled calls.
2635 + // Use it to preserve RSP in places where the callee might change the SP.
2636 + __ movptr(rbp, rsp);
2637 + debug_only(int off1 = cbuf.code_size());
2638 + assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
2639 + %}
2640 +
2641 + enc_class restore_SP %{
2642 + MacroAssembler _masm(&cbuf);
2643 + __ movptr(rsp, rbp);
2644 + %}
2645 +
2611 2646 enc_class Java_Static_Call(method meth)
2612 2647 %{
2613 2648 // JAVA STATIC CALL
2614 2649 // CALL to fixup routine. Fixup routine uses ScopeDesc info to
2615 2650 // determine who we intended to call.
2616 2651 cbuf.set_inst_mark();
2617 2652 $$$emit8$primary;
2618 2653
2619 2654 if (!_method) {
2620 2655 emit_d32_reloc(cbuf,
2621 2656 (int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4),
2622 2657 runtime_call_Relocation::spec(),
2623 2658 RELOC_DISP32);
2624 2659 } else if (_optimized_virtual) {
2625 2660 emit_d32_reloc(cbuf,
2626 2661 (int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4),
2627 2662 opt_virtual_call_Relocation::spec(),
2628 2663 RELOC_DISP32);
2629 2664 } else {
2630 2665 emit_d32_reloc(cbuf,
2631 2666 (int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4),
2632 2667 static_call_Relocation::spec(),
2633 2668 RELOC_DISP32);
2634 2669 }
2635 2670 if (_method) {
2636 2671 // Emit stub for static call
2637 2672 emit_java_to_interp(cbuf);
2638 2673 }
2639 2674 %}
2640 2675
2641 2676 enc_class Java_Dynamic_Call(method meth)
2642 2677 %{
2643 2678 // JAVA DYNAMIC CALL
2644 2679 // !!!!!
2645 2680 // Generate "movq rax, -1", placeholder instruction to load oop-info
2646 2681 // emit_call_dynamic_prologue( cbuf );
2647 2682 cbuf.set_inst_mark();
2648 2683
2649 2684 // movq rax, -1
2650 2685 emit_opcode(cbuf, Assembler::REX_W);
2651 2686 emit_opcode(cbuf, 0xB8 | RAX_enc);
2652 2687 emit_d64_reloc(cbuf,
2653 2688 (int64_t) Universe::non_oop_word(),
2654 2689 oop_Relocation::spec_for_immediate(), RELOC_IMM64);
2655 2690 address virtual_call_oop_addr = cbuf.inst_mark();
2656 2691 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
2657 2692 // who we intended to call.
2658 2693 cbuf.set_inst_mark();
2659 2694 $$$emit8$primary;
2660 2695 emit_d32_reloc(cbuf,
2661 2696 (int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4),
2662 2697 virtual_call_Relocation::spec(virtual_call_oop_addr),
2663 2698 RELOC_DISP32);
2664 2699 %}
2665 2700
2666 2701 enc_class Java_Compiled_Call(method meth)
2667 2702 %{
2668 2703 // JAVA COMPILED CALL
2669 2704 int disp = in_bytes(methodOopDesc:: from_compiled_offset());
2670 2705
2671 2706 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
2672 2707 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
2673 2708
2674 2709 // callq *disp(%rax)
2675 2710 cbuf.set_inst_mark();
2676 2711 $$$emit8$primary;
2677 2712 if (disp < 0x80) {
2678 2713 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
2679 2714 emit_d8(cbuf, disp); // Displacement
2680 2715 } else {
2681 2716 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte
2682 2717 emit_d32(cbuf, disp); // Displacement
2683 2718 }
2684 2719 %}
2685 2720
2686 2721 enc_class reg_opc_imm(rRegI dst, immI8 shift)
2687 2722 %{
2688 2723 // SAL, SAR, SHR
2689 2724 int dstenc = $dst$$reg;
2690 2725 if (dstenc >= 8) {
2691 2726 emit_opcode(cbuf, Assembler::REX_B);
2692 2727 dstenc -= 8;
2693 2728 }
2694 2729 $$$emit8$primary;
2695 2730 emit_rm(cbuf, 0x3, $secondary, dstenc);
2696 2731 $$$emit8$shift$$constant;
2697 2732 %}
2698 2733
2699 2734 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift)
2700 2735 %{
2701 2736 // SAL, SAR, SHR
2702 2737 int dstenc = $dst$$reg;
2703 2738 if (dstenc < 8) {
2704 2739 emit_opcode(cbuf, Assembler::REX_W);
2705 2740 } else {
2706 2741 emit_opcode(cbuf, Assembler::REX_WB);
2707 2742 dstenc -= 8;
2708 2743 }
2709 2744 $$$emit8$primary;
2710 2745 emit_rm(cbuf, 0x3, $secondary, dstenc);
2711 2746 $$$emit8$shift$$constant;
2712 2747 %}
2713 2748
2714 2749 enc_class load_immI(rRegI dst, immI src)
2715 2750 %{
2716 2751 int dstenc = $dst$$reg;
2717 2752 if (dstenc >= 8) {
2718 2753 emit_opcode(cbuf, Assembler::REX_B);
2719 2754 dstenc -= 8;
2720 2755 }
2721 2756 emit_opcode(cbuf, 0xB8 | dstenc);
2722 2757 $$$emit32$src$$constant;
2723 2758 %}
2724 2759
2725 2760 enc_class load_immL(rRegL dst, immL src)
2726 2761 %{
2727 2762 int dstenc = $dst$$reg;
2728 2763 if (dstenc < 8) {
2729 2764 emit_opcode(cbuf, Assembler::REX_W);
2730 2765 } else {
2731 2766 emit_opcode(cbuf, Assembler::REX_WB);
2732 2767 dstenc -= 8;
2733 2768 }
2734 2769 emit_opcode(cbuf, 0xB8 | dstenc);
2735 2770 emit_d64(cbuf, $src$$constant);
2736 2771 %}
2737 2772
2738 2773 enc_class load_immUL32(rRegL dst, immUL32 src)
2739 2774 %{
2740 2775 // same as load_immI, but this time we care about zeroes in the high word
2741 2776 int dstenc = $dst$$reg;
2742 2777 if (dstenc >= 8) {
2743 2778 emit_opcode(cbuf, Assembler::REX_B);
2744 2779 dstenc -= 8;
2745 2780 }
2746 2781 emit_opcode(cbuf, 0xB8 | dstenc);
2747 2782 $$$emit32$src$$constant;
2748 2783 %}
2749 2784
2750 2785 enc_class load_immL32(rRegL dst, immL32 src)
2751 2786 %{
2752 2787 int dstenc = $dst$$reg;
2753 2788 if (dstenc < 8) {
2754 2789 emit_opcode(cbuf, Assembler::REX_W);
2755 2790 } else {
2756 2791 emit_opcode(cbuf, Assembler::REX_WB);
2757 2792 dstenc -= 8;
2758 2793 }
2759 2794 emit_opcode(cbuf, 0xC7);
2760 2795 emit_rm(cbuf, 0x03, 0x00, dstenc);
2761 2796 $$$emit32$src$$constant;
2762 2797 %}
2763 2798
2764 2799 enc_class load_immP31(rRegP dst, immP32 src)
2765 2800 %{
2766 2801 // same as load_immI, but this time we care about zeroes in the high word
2767 2802 int dstenc = $dst$$reg;
2768 2803 if (dstenc >= 8) {
2769 2804 emit_opcode(cbuf, Assembler::REX_B);
2770 2805 dstenc -= 8;
2771 2806 }
2772 2807 emit_opcode(cbuf, 0xB8 | dstenc);
2773 2808 $$$emit32$src$$constant;
2774 2809 %}
2775 2810
2776 2811 enc_class load_immP(rRegP dst, immP src)
2777 2812 %{
2778 2813 int dstenc = $dst$$reg;
2779 2814 if (dstenc < 8) {
2780 2815 emit_opcode(cbuf, Assembler::REX_W);
2781 2816 } else {
2782 2817 emit_opcode(cbuf, Assembler::REX_WB);
2783 2818 dstenc -= 8;
2784 2819 }
2785 2820 emit_opcode(cbuf, 0xB8 | dstenc);
2786 2821 // This next line should be generated from ADLC
2787 2822 if ($src->constant_is_oop()) {
2788 2823 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64);
2789 2824 } else {
2790 2825 emit_d64(cbuf, $src$$constant);
2791 2826 }
2792 2827 %}
2793 2828
2794 2829 enc_class load_immF(regF dst, immF con)
2795 2830 %{
2796 2831 // XXX reg_mem doesn't support RIP-relative addressing yet
2797 2832 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2798 2833 emit_float_constant(cbuf, $con$$constant);
2799 2834 %}
2800 2835
2801 2836 enc_class load_immD(regD dst, immD con)
2802 2837 %{
2803 2838 // XXX reg_mem doesn't support RIP-relative addressing yet
2804 2839 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2805 2840 emit_double_constant(cbuf, $con$$constant);
2806 2841 %}
2807 2842
2808 2843 enc_class load_conF (regF dst, immF con) %{ // Load float constant
2809 2844 emit_opcode(cbuf, 0xF3);
2810 2845 if ($dst$$reg >= 8) {
2811 2846 emit_opcode(cbuf, Assembler::REX_R);
2812 2847 }
2813 2848 emit_opcode(cbuf, 0x0F);
2814 2849 emit_opcode(cbuf, 0x10);
2815 2850 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2816 2851 emit_float_constant(cbuf, $con$$constant);
2817 2852 %}
2818 2853
2819 2854 enc_class load_conD (regD dst, immD con) %{ // Load double constant
2820 2855 // UseXmmLoadAndClearUpper ? movsd(dst, con) : movlpd(dst, con)
2821 2856 emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
2822 2857 if ($dst$$reg >= 8) {
2823 2858 emit_opcode(cbuf, Assembler::REX_R);
2824 2859 }
2825 2860 emit_opcode(cbuf, 0x0F);
2826 2861 emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
2827 2862 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
2828 2863 emit_double_constant(cbuf, $con$$constant);
2829 2864 %}
2830 2865
2831 2866 // Encode a reg-reg copy. If it is useless, then empty encoding.
2832 2867 enc_class enc_copy(rRegI dst, rRegI src)
2833 2868 %{
2834 2869 encode_copy(cbuf, $dst$$reg, $src$$reg);
2835 2870 %}
2836 2871
2837 2872 // Encode xmm reg-reg copy. If it is useless, then empty encoding.
2838 2873 enc_class enc_CopyXD( RegD dst, RegD src ) %{
2839 2874 encode_CopyXD( cbuf, $dst$$reg, $src$$reg );
2840 2875 %}
2841 2876
2842 2877 enc_class enc_copy_always(rRegI dst, rRegI src)
2843 2878 %{
2844 2879 int srcenc = $src$$reg;
2845 2880 int dstenc = $dst$$reg;
2846 2881
2847 2882 if (dstenc < 8) {
2848 2883 if (srcenc >= 8) {
2849 2884 emit_opcode(cbuf, Assembler::REX_B);
2850 2885 srcenc -= 8;
2851 2886 }
2852 2887 } else {
2853 2888 if (srcenc < 8) {
2854 2889 emit_opcode(cbuf, Assembler::REX_R);
2855 2890 } else {
2856 2891 emit_opcode(cbuf, Assembler::REX_RB);
2857 2892 srcenc -= 8;
2858 2893 }
2859 2894 dstenc -= 8;
2860 2895 }
2861 2896
2862 2897 emit_opcode(cbuf, 0x8B);
2863 2898 emit_rm(cbuf, 0x3, dstenc, srcenc);
2864 2899 %}
2865 2900
2866 2901 enc_class enc_copy_wide(rRegL dst, rRegL src)
2867 2902 %{
2868 2903 int srcenc = $src$$reg;
2869 2904 int dstenc = $dst$$reg;
2870 2905
2871 2906 if (dstenc != srcenc) {
2872 2907 if (dstenc < 8) {
2873 2908 if (srcenc < 8) {
2874 2909 emit_opcode(cbuf, Assembler::REX_W);
2875 2910 } else {
2876 2911 emit_opcode(cbuf, Assembler::REX_WB);
2877 2912 srcenc -= 8;
2878 2913 }
2879 2914 } else {
2880 2915 if (srcenc < 8) {
2881 2916 emit_opcode(cbuf, Assembler::REX_WR);
2882 2917 } else {
2883 2918 emit_opcode(cbuf, Assembler::REX_WRB);
2884 2919 srcenc -= 8;
2885 2920 }
2886 2921 dstenc -= 8;
2887 2922 }
2888 2923 emit_opcode(cbuf, 0x8B);
2889 2924 emit_rm(cbuf, 0x3, dstenc, srcenc);
2890 2925 }
2891 2926 %}
2892 2927
2893 2928 enc_class Con32(immI src)
2894 2929 %{
2895 2930 // Output immediate
2896 2931 $$$emit32$src$$constant;
2897 2932 %}
2898 2933
2899 2934 enc_class Con64(immL src)
2900 2935 %{
2901 2936 // Output immediate
2902 2937 emit_d64($src$$constant);
2903 2938 %}
2904 2939
2905 2940 enc_class Con32F_as_bits(immF src)
2906 2941 %{
2907 2942 // Output Float immediate bits
2908 2943 jfloat jf = $src$$constant;
2909 2944 jint jf_as_bits = jint_cast(jf);
2910 2945 emit_d32(cbuf, jf_as_bits);
2911 2946 %}
2912 2947
2913 2948 enc_class Con16(immI src)
2914 2949 %{
2915 2950 // Output immediate
2916 2951 $$$emit16$src$$constant;
2917 2952 %}
2918 2953
2919 2954 // How is this different from Con32??? XXX
2920 2955 enc_class Con_d32(immI src)
2921 2956 %{
2922 2957 emit_d32(cbuf,$src$$constant);
2923 2958 %}
2924 2959
2925 2960 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
2926 2961 // Output immediate memory reference
2927 2962 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2928 2963 emit_d32(cbuf, 0x00);
2929 2964 %}
2930 2965
2931 2966 enc_class jump_enc(rRegL switch_val, rRegI dest) %{
2932 2967 MacroAssembler masm(&cbuf);
2933 2968
2934 2969 Register switch_reg = as_Register($switch_val$$reg);
2935 2970 Register dest_reg = as_Register($dest$$reg);
2936 2971 address table_base = masm.address_table_constant(_index2label);
2937 2972
2938 2973 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2939 2974 // to do that and the compiler is using that register as one it can allocate.
2940 2975 // So we build it all by hand.
2941 2976 // Address index(noreg, switch_reg, Address::times_1);
2942 2977 // ArrayAddress dispatch(table, index);
2943 2978
2944 2979 Address dispatch(dest_reg, switch_reg, Address::times_1);
2945 2980
2946 2981 masm.lea(dest_reg, InternalAddress(table_base));
2947 2982 masm.jmp(dispatch);
2948 2983 %}
2949 2984
2950 2985 enc_class jump_enc_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
2951 2986 MacroAssembler masm(&cbuf);
2952 2987
2953 2988 Register switch_reg = as_Register($switch_val$$reg);
2954 2989 Register dest_reg = as_Register($dest$$reg);
2955 2990 address table_base = masm.address_table_constant(_index2label);
2956 2991
2957 2992 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2958 2993 // to do that and the compiler is using that register as one it can allocate.
2959 2994 // So we build it all by hand.
2960 2995 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant);
2961 2996 // ArrayAddress dispatch(table, index);
2962 2997
2963 2998 Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant);
2964 2999
2965 3000 masm.lea(dest_reg, InternalAddress(table_base));
2966 3001 masm.jmp(dispatch);
2967 3002 %}
2968 3003
2969 3004 enc_class jump_enc_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
2970 3005 MacroAssembler masm(&cbuf);
2971 3006
2972 3007 Register switch_reg = as_Register($switch_val$$reg);
2973 3008 Register dest_reg = as_Register($dest$$reg);
2974 3009 address table_base = masm.address_table_constant(_index2label);
2975 3010
2976 3011 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
2977 3012 // to do that and the compiler is using that register as one it can allocate.
2978 3013 // So we build it all by hand.
2979 3014 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
2980 3015 // ArrayAddress dispatch(table, index);
2981 3016
2982 3017 Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant);
2983 3018 masm.lea(dest_reg, InternalAddress(table_base));
2984 3019 masm.jmp(dispatch);
2985 3020
2986 3021 %}
2987 3022
2988 3023 enc_class lock_prefix()
2989 3024 %{
2990 3025 if (os::is_MP()) {
2991 3026 emit_opcode(cbuf, 0xF0); // lock
2992 3027 }
2993 3028 %}
2994 3029
2995 3030 enc_class REX_mem(memory mem)
2996 3031 %{
2997 3032 if ($mem$$base >= 8) {
2998 3033 if ($mem$$index < 8) {
2999 3034 emit_opcode(cbuf, Assembler::REX_B);
3000 3035 } else {
3001 3036 emit_opcode(cbuf, Assembler::REX_XB);
3002 3037 }
3003 3038 } else {
3004 3039 if ($mem$$index >= 8) {
3005 3040 emit_opcode(cbuf, Assembler::REX_X);
3006 3041 }
3007 3042 }
3008 3043 %}
3009 3044
3010 3045 enc_class REX_mem_wide(memory mem)
3011 3046 %{
3012 3047 if ($mem$$base >= 8) {
3013 3048 if ($mem$$index < 8) {
3014 3049 emit_opcode(cbuf, Assembler::REX_WB);
3015 3050 } else {
3016 3051 emit_opcode(cbuf, Assembler::REX_WXB);
3017 3052 }
3018 3053 } else {
3019 3054 if ($mem$$index < 8) {
3020 3055 emit_opcode(cbuf, Assembler::REX_W);
3021 3056 } else {
3022 3057 emit_opcode(cbuf, Assembler::REX_WX);
3023 3058 }
3024 3059 }
3025 3060 %}
3026 3061
3027 3062 // for byte regs
3028 3063 enc_class REX_breg(rRegI reg)
3029 3064 %{
3030 3065 if ($reg$$reg >= 4) {
3031 3066 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B);
3032 3067 }
3033 3068 %}
3034 3069
3035 3070 // for byte regs
3036 3071 enc_class REX_reg_breg(rRegI dst, rRegI src)
3037 3072 %{
3038 3073 if ($dst$$reg < 8) {
3039 3074 if ($src$$reg >= 4) {
3040 3075 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B);
3041 3076 }
3042 3077 } else {
3043 3078 if ($src$$reg < 8) {
3044 3079 emit_opcode(cbuf, Assembler::REX_R);
3045 3080 } else {
3046 3081 emit_opcode(cbuf, Assembler::REX_RB);
3047 3082 }
3048 3083 }
3049 3084 %}
3050 3085
3051 3086 // for byte regs
3052 3087 enc_class REX_breg_mem(rRegI reg, memory mem)
3053 3088 %{
3054 3089 if ($reg$$reg < 8) {
3055 3090 if ($mem$$base < 8) {
3056 3091 if ($mem$$index >= 8) {
3057 3092 emit_opcode(cbuf, Assembler::REX_X);
3058 3093 } else if ($reg$$reg >= 4) {
3059 3094 emit_opcode(cbuf, Assembler::REX);
3060 3095 }
3061 3096 } else {
3062 3097 if ($mem$$index < 8) {
3063 3098 emit_opcode(cbuf, Assembler::REX_B);
3064 3099 } else {
3065 3100 emit_opcode(cbuf, Assembler::REX_XB);
3066 3101 }
3067 3102 }
3068 3103 } else {
3069 3104 if ($mem$$base < 8) {
3070 3105 if ($mem$$index < 8) {
3071 3106 emit_opcode(cbuf, Assembler::REX_R);
3072 3107 } else {
3073 3108 emit_opcode(cbuf, Assembler::REX_RX);
3074 3109 }
3075 3110 } else {
3076 3111 if ($mem$$index < 8) {
3077 3112 emit_opcode(cbuf, Assembler::REX_RB);
3078 3113 } else {
3079 3114 emit_opcode(cbuf, Assembler::REX_RXB);
3080 3115 }
3081 3116 }
3082 3117 }
3083 3118 %}
3084 3119
3085 3120 enc_class REX_reg(rRegI reg)
3086 3121 %{
3087 3122 if ($reg$$reg >= 8) {
3088 3123 emit_opcode(cbuf, Assembler::REX_B);
3089 3124 }
3090 3125 %}
3091 3126
3092 3127 enc_class REX_reg_wide(rRegI reg)
3093 3128 %{
3094 3129 if ($reg$$reg < 8) {
3095 3130 emit_opcode(cbuf, Assembler::REX_W);
3096 3131 } else {
3097 3132 emit_opcode(cbuf, Assembler::REX_WB);
3098 3133 }
3099 3134 %}
3100 3135
3101 3136 enc_class REX_reg_reg(rRegI dst, rRegI src)
3102 3137 %{
3103 3138 if ($dst$$reg < 8) {
3104 3139 if ($src$$reg >= 8) {
3105 3140 emit_opcode(cbuf, Assembler::REX_B);
3106 3141 }
3107 3142 } else {
3108 3143 if ($src$$reg < 8) {
3109 3144 emit_opcode(cbuf, Assembler::REX_R);
3110 3145 } else {
3111 3146 emit_opcode(cbuf, Assembler::REX_RB);
3112 3147 }
3113 3148 }
3114 3149 %}
3115 3150
3116 3151 enc_class REX_reg_reg_wide(rRegI dst, rRegI src)
3117 3152 %{
3118 3153 if ($dst$$reg < 8) {
3119 3154 if ($src$$reg < 8) {
3120 3155 emit_opcode(cbuf, Assembler::REX_W);
3121 3156 } else {
3122 3157 emit_opcode(cbuf, Assembler::REX_WB);
3123 3158 }
3124 3159 } else {
3125 3160 if ($src$$reg < 8) {
3126 3161 emit_opcode(cbuf, Assembler::REX_WR);
3127 3162 } else {
3128 3163 emit_opcode(cbuf, Assembler::REX_WRB);
3129 3164 }
3130 3165 }
3131 3166 %}
3132 3167
3133 3168 enc_class REX_reg_mem(rRegI reg, memory mem)
3134 3169 %{
3135 3170 if ($reg$$reg < 8) {
3136 3171 if ($mem$$base < 8) {
3137 3172 if ($mem$$index >= 8) {
3138 3173 emit_opcode(cbuf, Assembler::REX_X);
3139 3174 }
3140 3175 } else {
3141 3176 if ($mem$$index < 8) {
3142 3177 emit_opcode(cbuf, Assembler::REX_B);
3143 3178 } else {
3144 3179 emit_opcode(cbuf, Assembler::REX_XB);
3145 3180 }
3146 3181 }
3147 3182 } else {
3148 3183 if ($mem$$base < 8) {
3149 3184 if ($mem$$index < 8) {
3150 3185 emit_opcode(cbuf, Assembler::REX_R);
3151 3186 } else {
3152 3187 emit_opcode(cbuf, Assembler::REX_RX);
3153 3188 }
3154 3189 } else {
3155 3190 if ($mem$$index < 8) {
3156 3191 emit_opcode(cbuf, Assembler::REX_RB);
3157 3192 } else {
3158 3193 emit_opcode(cbuf, Assembler::REX_RXB);
3159 3194 }
3160 3195 }
3161 3196 }
3162 3197 %}
3163 3198
3164 3199 enc_class REX_reg_mem_wide(rRegL reg, memory mem)
3165 3200 %{
3166 3201 if ($reg$$reg < 8) {
3167 3202 if ($mem$$base < 8) {
3168 3203 if ($mem$$index < 8) {
3169 3204 emit_opcode(cbuf, Assembler::REX_W);
3170 3205 } else {
3171 3206 emit_opcode(cbuf, Assembler::REX_WX);
3172 3207 }
3173 3208 } else {
3174 3209 if ($mem$$index < 8) {
3175 3210 emit_opcode(cbuf, Assembler::REX_WB);
3176 3211 } else {
3177 3212 emit_opcode(cbuf, Assembler::REX_WXB);
3178 3213 }
3179 3214 }
3180 3215 } else {
3181 3216 if ($mem$$base < 8) {
3182 3217 if ($mem$$index < 8) {
3183 3218 emit_opcode(cbuf, Assembler::REX_WR);
3184 3219 } else {
3185 3220 emit_opcode(cbuf, Assembler::REX_WRX);
3186 3221 }
3187 3222 } else {
3188 3223 if ($mem$$index < 8) {
3189 3224 emit_opcode(cbuf, Assembler::REX_WRB);
3190 3225 } else {
3191 3226 emit_opcode(cbuf, Assembler::REX_WRXB);
3192 3227 }
3193 3228 }
3194 3229 }
3195 3230 %}
3196 3231
3197 3232 enc_class reg_mem(rRegI ereg, memory mem)
3198 3233 %{
3199 3234 // High registers handle in encode_RegMem
3200 3235 int reg = $ereg$$reg;
3201 3236 int base = $mem$$base;
3202 3237 int index = $mem$$index;
3203 3238 int scale = $mem$$scale;
3204 3239 int disp = $mem$$disp;
3205 3240 bool disp_is_oop = $mem->disp_is_oop();
3206 3241
3207 3242 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_is_oop);
3208 3243 %}
3209 3244
3210 3245 enc_class RM_opc_mem(immI rm_opcode, memory mem)
3211 3246 %{
3212 3247 int rm_byte_opcode = $rm_opcode$$constant;
3213 3248
3214 3249 // High registers handle in encode_RegMem
3215 3250 int base = $mem$$base;
3216 3251 int index = $mem$$index;
3217 3252 int scale = $mem$$scale;
3218 3253 int displace = $mem$$disp;
3219 3254
3220 3255 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when
3221 3256 // working with static
3222 3257 // globals
3223 3258 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace,
3224 3259 disp_is_oop);
3225 3260 %}
3226 3261
3227 3262 enc_class reg_lea(rRegI dst, rRegI src0, immI src1)
3228 3263 %{
3229 3264 int reg_encoding = $dst$$reg;
3230 3265 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
3231 3266 int index = 0x04; // 0x04 indicates no index
3232 3267 int scale = 0x00; // 0x00 indicates no scale
3233 3268 int displace = $src1$$constant; // 0x00 indicates no displacement
3234 3269 bool disp_is_oop = false;
3235 3270 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace,
3236 3271 disp_is_oop);
3237 3272 %}
3238 3273
3239 3274 enc_class neg_reg(rRegI dst)
3240 3275 %{
3241 3276 int dstenc = $dst$$reg;
3242 3277 if (dstenc >= 8) {
3243 3278 emit_opcode(cbuf, Assembler::REX_B);
3244 3279 dstenc -= 8;
3245 3280 }
3246 3281 // NEG $dst
3247 3282 emit_opcode(cbuf, 0xF7);
3248 3283 emit_rm(cbuf, 0x3, 0x03, dstenc);
3249 3284 %}
3250 3285
3251 3286 enc_class neg_reg_wide(rRegI dst)
3252 3287 %{
3253 3288 int dstenc = $dst$$reg;
3254 3289 if (dstenc < 8) {
3255 3290 emit_opcode(cbuf, Assembler::REX_W);
3256 3291 } else {
3257 3292 emit_opcode(cbuf, Assembler::REX_WB);
3258 3293 dstenc -= 8;
3259 3294 }
3260 3295 // NEG $dst
3261 3296 emit_opcode(cbuf, 0xF7);
3262 3297 emit_rm(cbuf, 0x3, 0x03, dstenc);
3263 3298 %}
3264 3299
3265 3300 enc_class setLT_reg(rRegI dst)
3266 3301 %{
3267 3302 int dstenc = $dst$$reg;
3268 3303 if (dstenc >= 8) {
3269 3304 emit_opcode(cbuf, Assembler::REX_B);
3270 3305 dstenc -= 8;
3271 3306 } else if (dstenc >= 4) {
3272 3307 emit_opcode(cbuf, Assembler::REX);
3273 3308 }
3274 3309 // SETLT $dst
3275 3310 emit_opcode(cbuf, 0x0F);
3276 3311 emit_opcode(cbuf, 0x9C);
3277 3312 emit_rm(cbuf, 0x3, 0x0, dstenc);
3278 3313 %}
3279 3314
3280 3315 enc_class setNZ_reg(rRegI dst)
3281 3316 %{
3282 3317 int dstenc = $dst$$reg;
3283 3318 if (dstenc >= 8) {
3284 3319 emit_opcode(cbuf, Assembler::REX_B);
3285 3320 dstenc -= 8;
3286 3321 } else if (dstenc >= 4) {
3287 3322 emit_opcode(cbuf, Assembler::REX);
3288 3323 }
3289 3324 // SETNZ $dst
3290 3325 emit_opcode(cbuf, 0x0F);
3291 3326 emit_opcode(cbuf, 0x95);
3292 3327 emit_rm(cbuf, 0x3, 0x0, dstenc);
3293 3328 %}
3294 3329
3295 3330 enc_class enc_cmpLTP(no_rcx_RegI p, no_rcx_RegI q, no_rcx_RegI y,
3296 3331 rcx_RegI tmp)
3297 3332 %{
3298 3333 // cadd_cmpLT
3299 3334
3300 3335 int tmpReg = $tmp$$reg;
3301 3336
3302 3337 int penc = $p$$reg;
3303 3338 int qenc = $q$$reg;
3304 3339 int yenc = $y$$reg;
3305 3340
3306 3341 // subl $p,$q
3307 3342 if (penc < 8) {
3308 3343 if (qenc >= 8) {
3309 3344 emit_opcode(cbuf, Assembler::REX_B);
3310 3345 }
3311 3346 } else {
3312 3347 if (qenc < 8) {
3313 3348 emit_opcode(cbuf, Assembler::REX_R);
3314 3349 } else {
3315 3350 emit_opcode(cbuf, Assembler::REX_RB);
3316 3351 }
3317 3352 }
3318 3353 emit_opcode(cbuf, 0x2B);
3319 3354 emit_rm(cbuf, 0x3, penc & 7, qenc & 7);
3320 3355
3321 3356 // sbbl $tmp, $tmp
3322 3357 emit_opcode(cbuf, 0x1B);
3323 3358 emit_rm(cbuf, 0x3, tmpReg, tmpReg);
3324 3359
3325 3360 // andl $tmp, $y
3326 3361 if (yenc >= 8) {
3327 3362 emit_opcode(cbuf, Assembler::REX_B);
3328 3363 }
3329 3364 emit_opcode(cbuf, 0x23);
3330 3365 emit_rm(cbuf, 0x3, tmpReg, yenc & 7);
3331 3366
3332 3367 // addl $p,$tmp
3333 3368 if (penc >= 8) {
3334 3369 emit_opcode(cbuf, Assembler::REX_R);
3335 3370 }
3336 3371 emit_opcode(cbuf, 0x03);
3337 3372 emit_rm(cbuf, 0x3, penc & 7, tmpReg);
3338 3373 %}
3339 3374
3340 3375 // Compare the lonogs and set -1, 0, or 1 into dst
3341 3376 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst)
3342 3377 %{
3343 3378 int src1enc = $src1$$reg;
3344 3379 int src2enc = $src2$$reg;
3345 3380 int dstenc = $dst$$reg;
3346 3381
3347 3382 // cmpq $src1, $src2
3348 3383 if (src1enc < 8) {
3349 3384 if (src2enc < 8) {
3350 3385 emit_opcode(cbuf, Assembler::REX_W);
3351 3386 } else {
3352 3387 emit_opcode(cbuf, Assembler::REX_WB);
3353 3388 }
3354 3389 } else {
3355 3390 if (src2enc < 8) {
3356 3391 emit_opcode(cbuf, Assembler::REX_WR);
3357 3392 } else {
3358 3393 emit_opcode(cbuf, Assembler::REX_WRB);
3359 3394 }
3360 3395 }
3361 3396 emit_opcode(cbuf, 0x3B);
3362 3397 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7);
3363 3398
3364 3399 // movl $dst, -1
3365 3400 if (dstenc >= 8) {
3366 3401 emit_opcode(cbuf, Assembler::REX_B);
3367 3402 }
3368 3403 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
3369 3404 emit_d32(cbuf, -1);
3370 3405
3371 3406 // jl,s done
3372 3407 emit_opcode(cbuf, 0x7C);
3373 3408 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
3374 3409
3375 3410 // setne $dst
3376 3411 if (dstenc >= 4) {
3377 3412 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
3378 3413 }
3379 3414 emit_opcode(cbuf, 0x0F);
3380 3415 emit_opcode(cbuf, 0x95);
3381 3416 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
3382 3417
3383 3418 // movzbl $dst, $dst
3384 3419 if (dstenc >= 4) {
3385 3420 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
3386 3421 }
3387 3422 emit_opcode(cbuf, 0x0F);
3388 3423 emit_opcode(cbuf, 0xB6);
3389 3424 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
3390 3425 %}
3391 3426
3392 3427 enc_class Push_ResultXD(regD dst) %{
3393 3428 int dstenc = $dst$$reg;
3394 3429
3395 3430 store_to_stackslot( cbuf, 0xDD, 0x03, 0 ); //FSTP [RSP]
3396 3431
3397 3432 // UseXmmLoadAndClearUpper ? movsd dst,[rsp] : movlpd dst,[rsp]
3398 3433 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
3399 3434 if (dstenc >= 8) {
3400 3435 emit_opcode(cbuf, Assembler::REX_R);
3401 3436 }
3402 3437 emit_opcode (cbuf, 0x0F );
3403 3438 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12 );
3404 3439 encode_RegMem(cbuf, dstenc, RSP_enc, 0x4, 0, 0, false);
3405 3440
3406 3441 // add rsp,8
3407 3442 emit_opcode(cbuf, Assembler::REX_W);
3408 3443 emit_opcode(cbuf,0x83);
3409 3444 emit_rm(cbuf,0x3, 0x0, RSP_enc);
3410 3445 emit_d8(cbuf,0x08);
3411 3446 %}
3412 3447
3413 3448 enc_class Push_SrcXD(regD src) %{
3414 3449 int srcenc = $src$$reg;
3415 3450
3416 3451 // subq rsp,#8
3417 3452 emit_opcode(cbuf, Assembler::REX_W);
3418 3453 emit_opcode(cbuf, 0x83);
3419 3454 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3420 3455 emit_d8(cbuf, 0x8);
3421 3456
3422 3457 // movsd [rsp],src
3423 3458 emit_opcode(cbuf, 0xF2);
3424 3459 if (srcenc >= 8) {
3425 3460 emit_opcode(cbuf, Assembler::REX_R);
3426 3461 }
3427 3462 emit_opcode(cbuf, 0x0F);
3428 3463 emit_opcode(cbuf, 0x11);
3429 3464 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false);
3430 3465
3431 3466 // fldd [rsp]
3432 3467 emit_opcode(cbuf, 0x66);
3433 3468 emit_opcode(cbuf, 0xDD);
3434 3469 encode_RegMem(cbuf, 0x0, RSP_enc, 0x4, 0, 0, false);
3435 3470 %}
3436 3471
3437 3472
3438 3473 enc_class movq_ld(regD dst, memory mem) %{
3439 3474 MacroAssembler _masm(&cbuf);
3440 3475 __ movq($dst$$XMMRegister, $mem$$Address);
3441 3476 %}
3442 3477
3443 3478 enc_class movq_st(memory mem, regD src) %{
3444 3479 MacroAssembler _masm(&cbuf);
3445 3480 __ movq($mem$$Address, $src$$XMMRegister);
3446 3481 %}
3447 3482
3448 3483 enc_class pshufd_8x8(regF dst, regF src) %{
3449 3484 MacroAssembler _masm(&cbuf);
3450 3485
3451 3486 encode_CopyXD(cbuf, $dst$$reg, $src$$reg);
3452 3487 __ punpcklbw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg));
3453 3488 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg), 0x00);
3454 3489 %}
3455 3490
3456 3491 enc_class pshufd_4x16(regF dst, regF src) %{
3457 3492 MacroAssembler _masm(&cbuf);
3458 3493
3459 3494 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), 0x00);
3460 3495 %}
3461 3496
3462 3497 enc_class pshufd(regD dst, regD src, int mode) %{
3463 3498 MacroAssembler _masm(&cbuf);
3464 3499
3465 3500 __ pshufd(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), $mode);
3466 3501 %}
3467 3502
3468 3503 enc_class pxor(regD dst, regD src) %{
3469 3504 MacroAssembler _masm(&cbuf);
3470 3505
3471 3506 __ pxor(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg));
3472 3507 %}
3473 3508
3474 3509 enc_class mov_i2x(regD dst, rRegI src) %{
3475 3510 MacroAssembler _masm(&cbuf);
3476 3511
3477 3512 __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg));
3478 3513 %}
3479 3514
3480 3515 // obj: object to lock
3481 3516 // box: box address (header location) -- killed
3482 3517 // tmp: rax -- killed
3483 3518 // scr: rbx -- killed
3484 3519 //
3485 3520 // What follows is a direct transliteration of fast_lock() and fast_unlock()
3486 3521 // from i486.ad. See that file for comments.
3487 3522 // TODO: where possible switch from movq (r, 0) to movl(r,0) and
3488 3523 // use the shorter encoding. (Movl clears the high-order 32-bits).
3489 3524
3490 3525
3491 3526 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr)
3492 3527 %{
3493 3528 Register objReg = as_Register((int)$obj$$reg);
3494 3529 Register boxReg = as_Register((int)$box$$reg);
3495 3530 Register tmpReg = as_Register($tmp$$reg);
3496 3531 Register scrReg = as_Register($scr$$reg);
3497 3532 MacroAssembler masm(&cbuf);
3498 3533
3499 3534 // Verify uniqueness of register assignments -- necessary but not sufficient
3500 3535 assert (objReg != boxReg && objReg != tmpReg &&
3501 3536 objReg != scrReg && tmpReg != scrReg, "invariant") ;
3502 3537
3503 3538 if (_counters != NULL) {
3504 3539 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr()));
3505 3540 }
3506 3541 if (EmitSync & 1) {
3507 3542 // Without cast to int32_t a movptr will destroy r10 which is typically obj
3508 3543 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
3509 3544 masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
3510 3545 } else
3511 3546 if (EmitSync & 2) {
3512 3547 Label DONE_LABEL;
3513 3548 if (UseBiasedLocking) {
3514 3549 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument.
3515 3550 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
3516 3551 }
3517 3552 // QQQ was movl...
3518 3553 masm.movptr(tmpReg, 0x1);
3519 3554 masm.orptr(tmpReg, Address(objReg, 0));
3520 3555 masm.movptr(Address(boxReg, 0), tmpReg);
3521 3556 if (os::is_MP()) {
3522 3557 masm.lock();
3523 3558 }
3524 3559 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
3525 3560 masm.jcc(Assembler::equal, DONE_LABEL);
3526 3561
3527 3562 // Recursive locking
3528 3563 masm.subptr(tmpReg, rsp);
3529 3564 masm.andptr(tmpReg, 7 - os::vm_page_size());
3530 3565 masm.movptr(Address(boxReg, 0), tmpReg);
3531 3566
3532 3567 masm.bind(DONE_LABEL);
3533 3568 masm.nop(); // avoid branch to branch
3534 3569 } else {
3535 3570 Label DONE_LABEL, IsInflated, Egress;
3536 3571
3537 3572 masm.movptr(tmpReg, Address(objReg, 0)) ;
3538 3573 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased
3539 3574 masm.jcc (Assembler::notZero, IsInflated) ;
3540 3575
3541 3576 // it's stack-locked, biased or neutral
3542 3577 // TODO: optimize markword triage order to reduce the number of
3543 3578 // conditional branches in the most common cases.
3544 3579 // Beware -- there's a subtle invariant that fetch of the markword
3545 3580 // at [FETCH], below, will never observe a biased encoding (*101b).
3546 3581 // If this invariant is not held we'll suffer exclusion (safety) failure.
3547 3582
3548 3583 if (UseBiasedLocking && !UseOptoBiasInlining) {
3549 3584 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
3550 3585 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH]
3551 3586 }
3552 3587
3553 3588 // was q will it destroy high?
3554 3589 masm.orl (tmpReg, 1) ;
3555 3590 masm.movptr(Address(boxReg, 0), tmpReg) ;
3556 3591 if (os::is_MP()) { masm.lock(); }
3557 3592 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
3558 3593 if (_counters != NULL) {
3559 3594 masm.cond_inc32(Assembler::equal,
3560 3595 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
3561 3596 }
3562 3597 masm.jcc (Assembler::equal, DONE_LABEL);
3563 3598
3564 3599 // Recursive locking
3565 3600 masm.subptr(tmpReg, rsp);
3566 3601 masm.andptr(tmpReg, 7 - os::vm_page_size());
3567 3602 masm.movptr(Address(boxReg, 0), tmpReg);
3568 3603 if (_counters != NULL) {
3569 3604 masm.cond_inc32(Assembler::equal,
3570 3605 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
3571 3606 }
3572 3607 masm.jmp (DONE_LABEL) ;
3573 3608
3574 3609 masm.bind (IsInflated) ;
3575 3610 // It's inflated
3576 3611
3577 3612 // TODO: someday avoid the ST-before-CAS penalty by
3578 3613 // relocating (deferring) the following ST.
3579 3614 // We should also think about trying a CAS without having
3580 3615 // fetched _owner. If the CAS is successful we may
3581 3616 // avoid an RTO->RTS upgrade on the $line.
3582 3617 // Without cast to int32_t a movptr will destroy r10 which is typically obj
3583 3618 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
3584 3619
3585 3620 masm.mov (boxReg, tmpReg) ;
3586 3621 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
3587 3622 masm.testptr(tmpReg, tmpReg) ;
3588 3623 masm.jcc (Assembler::notZero, DONE_LABEL) ;
3589 3624
3590 3625 // It's inflated and appears unlocked
3591 3626 if (os::is_MP()) { masm.lock(); }
3592 3627 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
3593 3628 // Intentional fall-through into DONE_LABEL ...
3594 3629
3595 3630 masm.bind (DONE_LABEL) ;
3596 3631 masm.nop () ; // avoid jmp to jmp
3597 3632 }
3598 3633 %}
3599 3634
3600 3635 // obj: object to unlock
3601 3636 // box: box address (displaced header location), killed
3602 3637 // RBX: killed tmp; cannot be obj nor box
3603 3638 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp)
3604 3639 %{
3605 3640
3606 3641 Register objReg = as_Register($obj$$reg);
3607 3642 Register boxReg = as_Register($box$$reg);
3608 3643 Register tmpReg = as_Register($tmp$$reg);
3609 3644 MacroAssembler masm(&cbuf);
3610 3645
3611 3646 if (EmitSync & 4) {
3612 3647 masm.cmpptr(rsp, 0) ;
3613 3648 } else
3614 3649 if (EmitSync & 8) {
3615 3650 Label DONE_LABEL;
3616 3651 if (UseBiasedLocking) {
3617 3652 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
3618 3653 }
3619 3654
3620 3655 // Check whether the displaced header is 0
3621 3656 //(=> recursive unlock)
3622 3657 masm.movptr(tmpReg, Address(boxReg, 0));
3623 3658 masm.testptr(tmpReg, tmpReg);
3624 3659 masm.jcc(Assembler::zero, DONE_LABEL);
3625 3660
3626 3661 // If not recursive lock, reset the header to displaced header
3627 3662 if (os::is_MP()) {
3628 3663 masm.lock();
3629 3664 }
3630 3665 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
3631 3666 masm.bind(DONE_LABEL);
3632 3667 masm.nop(); // avoid branch to branch
3633 3668 } else {
3634 3669 Label DONE_LABEL, Stacked, CheckSucc ;
3635 3670
3636 3671 if (UseBiasedLocking && !UseOptoBiasInlining) {
3637 3672 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
3638 3673 }
3639 3674
3640 3675 masm.movptr(tmpReg, Address(objReg, 0)) ;
3641 3676 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
3642 3677 masm.jcc (Assembler::zero, DONE_LABEL) ;
3643 3678 masm.testl (tmpReg, 0x02) ;
3644 3679 masm.jcc (Assembler::zero, Stacked) ;
3645 3680
3646 3681 // It's inflated
3647 3682 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
3648 3683 masm.xorptr(boxReg, r15_thread) ;
3649 3684 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
3650 3685 masm.jcc (Assembler::notZero, DONE_LABEL) ;
3651 3686 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
3652 3687 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
3653 3688 masm.jcc (Assembler::notZero, CheckSucc) ;
3654 3689 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3655 3690 masm.jmp (DONE_LABEL) ;
3656 3691
3657 3692 if ((EmitSync & 65536) == 0) {
3658 3693 Label LSuccess, LGoSlowPath ;
3659 3694 masm.bind (CheckSucc) ;
3660 3695 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3661 3696 masm.jcc (Assembler::zero, LGoSlowPath) ;
3662 3697
3663 3698 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the
3664 3699 // the explicit ST;MEMBAR combination, but masm doesn't currently support
3665 3700 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc
3666 3701 // are all faster when the write buffer is populated.
3667 3702 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3668 3703 if (os::is_MP()) {
3669 3704 masm.lock () ; masm.addl (Address(rsp, 0), 0) ;
3670 3705 }
3671 3706 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3672 3707 masm.jcc (Assembler::notZero, LSuccess) ;
3673 3708
3674 3709 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX
3675 3710 if (os::is_MP()) { masm.lock(); }
3676 3711 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2));
3677 3712 masm.jcc (Assembler::notEqual, LSuccess) ;
3678 3713 // Intentional fall-through into slow-path
3679 3714
3680 3715 masm.bind (LGoSlowPath) ;
3681 3716 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure
3682 3717 masm.jmp (DONE_LABEL) ;
3683 3718
3684 3719 masm.bind (LSuccess) ;
3685 3720 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success
3686 3721 masm.jmp (DONE_LABEL) ;
3687 3722 }
3688 3723
3689 3724 masm.bind (Stacked) ;
3690 3725 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch
3691 3726 if (os::is_MP()) { masm.lock(); }
3692 3727 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
3693 3728
3694 3729 if (EmitSync & 65536) {
3695 3730 masm.bind (CheckSucc) ;
3696 3731 }
3697 3732 masm.bind(DONE_LABEL);
3698 3733 if (EmitSync & 32768) {
3699 3734 masm.nop(); // avoid branch to branch
3700 3735 }
3701 3736 }
3702 3737 %}
3703 3738
3704 3739
3705 3740 enc_class enc_rethrow()
3706 3741 %{
3707 3742 cbuf.set_inst_mark();
3708 3743 emit_opcode(cbuf, 0xE9); // jmp entry
3709 3744 emit_d32_reloc(cbuf,
3710 3745 (int) (OptoRuntime::rethrow_stub() - cbuf.code_end() - 4),
3711 3746 runtime_call_Relocation::spec(),
3712 3747 RELOC_DISP32);
3713 3748 %}
3714 3749
3715 3750 enc_class absF_encoding(regF dst)
3716 3751 %{
3717 3752 int dstenc = $dst$$reg;
3718 3753 address signmask_address = (address) StubRoutines::x86::float_sign_mask();
3719 3754
3720 3755 cbuf.set_inst_mark();
3721 3756 if (dstenc >= 8) {
3722 3757 emit_opcode(cbuf, Assembler::REX_R);
3723 3758 dstenc -= 8;
3724 3759 }
3725 3760 // XXX reg_mem doesn't support RIP-relative addressing yet
3726 3761 emit_opcode(cbuf, 0x0F);
3727 3762 emit_opcode(cbuf, 0x54);
3728 3763 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3729 3764 emit_d32_reloc(cbuf, signmask_address);
3730 3765 %}
3731 3766
3732 3767 enc_class absD_encoding(regD dst)
3733 3768 %{
3734 3769 int dstenc = $dst$$reg;
3735 3770 address signmask_address = (address) StubRoutines::x86::double_sign_mask();
3736 3771
3737 3772 cbuf.set_inst_mark();
3738 3773 emit_opcode(cbuf, 0x66);
3739 3774 if (dstenc >= 8) {
3740 3775 emit_opcode(cbuf, Assembler::REX_R);
3741 3776 dstenc -= 8;
3742 3777 }
3743 3778 // XXX reg_mem doesn't support RIP-relative addressing yet
3744 3779 emit_opcode(cbuf, 0x0F);
3745 3780 emit_opcode(cbuf, 0x54);
3746 3781 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3747 3782 emit_d32_reloc(cbuf, signmask_address);
3748 3783 %}
3749 3784
3750 3785 enc_class negF_encoding(regF dst)
3751 3786 %{
3752 3787 int dstenc = $dst$$reg;
3753 3788 address signflip_address = (address) StubRoutines::x86::float_sign_flip();
3754 3789
3755 3790 cbuf.set_inst_mark();
3756 3791 if (dstenc >= 8) {
3757 3792 emit_opcode(cbuf, Assembler::REX_R);
3758 3793 dstenc -= 8;
3759 3794 }
3760 3795 // XXX reg_mem doesn't support RIP-relative addressing yet
3761 3796 emit_opcode(cbuf, 0x0F);
3762 3797 emit_opcode(cbuf, 0x57);
3763 3798 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3764 3799 emit_d32_reloc(cbuf, signflip_address);
3765 3800 %}
3766 3801
3767 3802 enc_class negD_encoding(regD dst)
3768 3803 %{
3769 3804 int dstenc = $dst$$reg;
3770 3805 address signflip_address = (address) StubRoutines::x86::double_sign_flip();
3771 3806
3772 3807 cbuf.set_inst_mark();
3773 3808 emit_opcode(cbuf, 0x66);
3774 3809 if (dstenc >= 8) {
3775 3810 emit_opcode(cbuf, Assembler::REX_R);
3776 3811 dstenc -= 8;
3777 3812 }
3778 3813 // XXX reg_mem doesn't support RIP-relative addressing yet
3779 3814 emit_opcode(cbuf, 0x0F);
3780 3815 emit_opcode(cbuf, 0x57);
3781 3816 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101
3782 3817 emit_d32_reloc(cbuf, signflip_address);
3783 3818 %}
3784 3819
3785 3820 enc_class f2i_fixup(rRegI dst, regF src)
3786 3821 %{
3787 3822 int dstenc = $dst$$reg;
3788 3823 int srcenc = $src$$reg;
3789 3824
3790 3825 // cmpl $dst, #0x80000000
3791 3826 if (dstenc >= 8) {
3792 3827 emit_opcode(cbuf, Assembler::REX_B);
3793 3828 }
3794 3829 emit_opcode(cbuf, 0x81);
3795 3830 emit_rm(cbuf, 0x3, 0x7, dstenc & 7);
3796 3831 emit_d32(cbuf, 0x80000000);
3797 3832
3798 3833 // jne,s done
3799 3834 emit_opcode(cbuf, 0x75);
3800 3835 if (srcenc < 8 && dstenc < 8) {
3801 3836 emit_d8(cbuf, 0xF);
3802 3837 } else if (srcenc >= 8 && dstenc >= 8) {
3803 3838 emit_d8(cbuf, 0x11);
3804 3839 } else {
3805 3840 emit_d8(cbuf, 0x10);
3806 3841 }
3807 3842
3808 3843 // subq rsp, #8
3809 3844 emit_opcode(cbuf, Assembler::REX_W);
3810 3845 emit_opcode(cbuf, 0x83);
3811 3846 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3812 3847 emit_d8(cbuf, 8);
3813 3848
3814 3849 // movss [rsp], $src
3815 3850 emit_opcode(cbuf, 0xF3);
3816 3851 if (srcenc >= 8) {
3817 3852 emit_opcode(cbuf, Assembler::REX_R);
3818 3853 }
3819 3854 emit_opcode(cbuf, 0x0F);
3820 3855 emit_opcode(cbuf, 0x11);
3821 3856 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3822 3857
3823 3858 // call f2i_fixup
3824 3859 cbuf.set_inst_mark();
3825 3860 emit_opcode(cbuf, 0xE8);
3826 3861 emit_d32_reloc(cbuf,
3827 3862 (int)
3828 3863 (StubRoutines::x86::f2i_fixup() - cbuf.code_end() - 4),
3829 3864 runtime_call_Relocation::spec(),
3830 3865 RELOC_DISP32);
3831 3866
3832 3867 // popq $dst
3833 3868 if (dstenc >= 8) {
3834 3869 emit_opcode(cbuf, Assembler::REX_B);
3835 3870 }
3836 3871 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3837 3872
3838 3873 // done:
3839 3874 %}
3840 3875
3841 3876 enc_class f2l_fixup(rRegL dst, regF src)
3842 3877 %{
3843 3878 int dstenc = $dst$$reg;
3844 3879 int srcenc = $src$$reg;
3845 3880 address const_address = (address) StubRoutines::x86::double_sign_flip();
3846 3881
3847 3882 // cmpq $dst, [0x8000000000000000]
3848 3883 cbuf.set_inst_mark();
3849 3884 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR);
3850 3885 emit_opcode(cbuf, 0x39);
3851 3886 // XXX reg_mem doesn't support RIP-relative addressing yet
3852 3887 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101
3853 3888 emit_d32_reloc(cbuf, const_address);
3854 3889
3855 3890
3856 3891 // jne,s done
3857 3892 emit_opcode(cbuf, 0x75);
3858 3893 if (srcenc < 8 && dstenc < 8) {
3859 3894 emit_d8(cbuf, 0xF);
3860 3895 } else if (srcenc >= 8 && dstenc >= 8) {
3861 3896 emit_d8(cbuf, 0x11);
3862 3897 } else {
3863 3898 emit_d8(cbuf, 0x10);
3864 3899 }
3865 3900
3866 3901 // subq rsp, #8
3867 3902 emit_opcode(cbuf, Assembler::REX_W);
3868 3903 emit_opcode(cbuf, 0x83);
3869 3904 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3870 3905 emit_d8(cbuf, 8);
3871 3906
3872 3907 // movss [rsp], $src
3873 3908 emit_opcode(cbuf, 0xF3);
3874 3909 if (srcenc >= 8) {
3875 3910 emit_opcode(cbuf, Assembler::REX_R);
3876 3911 }
3877 3912 emit_opcode(cbuf, 0x0F);
3878 3913 emit_opcode(cbuf, 0x11);
3879 3914 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3880 3915
3881 3916 // call f2l_fixup
3882 3917 cbuf.set_inst_mark();
3883 3918 emit_opcode(cbuf, 0xE8);
3884 3919 emit_d32_reloc(cbuf,
3885 3920 (int)
3886 3921 (StubRoutines::x86::f2l_fixup() - cbuf.code_end() - 4),
3887 3922 runtime_call_Relocation::spec(),
3888 3923 RELOC_DISP32);
3889 3924
3890 3925 // popq $dst
3891 3926 if (dstenc >= 8) {
3892 3927 emit_opcode(cbuf, Assembler::REX_B);
3893 3928 }
3894 3929 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3895 3930
3896 3931 // done:
3897 3932 %}
3898 3933
3899 3934 enc_class d2i_fixup(rRegI dst, regD src)
3900 3935 %{
3901 3936 int dstenc = $dst$$reg;
3902 3937 int srcenc = $src$$reg;
3903 3938
3904 3939 // cmpl $dst, #0x80000000
3905 3940 if (dstenc >= 8) {
3906 3941 emit_opcode(cbuf, Assembler::REX_B);
3907 3942 }
3908 3943 emit_opcode(cbuf, 0x81);
3909 3944 emit_rm(cbuf, 0x3, 0x7, dstenc & 7);
3910 3945 emit_d32(cbuf, 0x80000000);
3911 3946
3912 3947 // jne,s done
3913 3948 emit_opcode(cbuf, 0x75);
3914 3949 if (srcenc < 8 && dstenc < 8) {
3915 3950 emit_d8(cbuf, 0xF);
3916 3951 } else if (srcenc >= 8 && dstenc >= 8) {
3917 3952 emit_d8(cbuf, 0x11);
3918 3953 } else {
3919 3954 emit_d8(cbuf, 0x10);
3920 3955 }
3921 3956
3922 3957 // subq rsp, #8
3923 3958 emit_opcode(cbuf, Assembler::REX_W);
3924 3959 emit_opcode(cbuf, 0x83);
3925 3960 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3926 3961 emit_d8(cbuf, 8);
3927 3962
3928 3963 // movsd [rsp], $src
3929 3964 emit_opcode(cbuf, 0xF2);
3930 3965 if (srcenc >= 8) {
3931 3966 emit_opcode(cbuf, Assembler::REX_R);
3932 3967 }
3933 3968 emit_opcode(cbuf, 0x0F);
3934 3969 emit_opcode(cbuf, 0x11);
3935 3970 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3936 3971
3937 3972 // call d2i_fixup
3938 3973 cbuf.set_inst_mark();
3939 3974 emit_opcode(cbuf, 0xE8);
3940 3975 emit_d32_reloc(cbuf,
3941 3976 (int)
3942 3977 (StubRoutines::x86::d2i_fixup() - cbuf.code_end() - 4),
3943 3978 runtime_call_Relocation::spec(),
3944 3979 RELOC_DISP32);
3945 3980
3946 3981 // popq $dst
3947 3982 if (dstenc >= 8) {
3948 3983 emit_opcode(cbuf, Assembler::REX_B);
3949 3984 }
3950 3985 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3951 3986
3952 3987 // done:
3953 3988 %}
3954 3989
3955 3990 enc_class d2l_fixup(rRegL dst, regD src)
3956 3991 %{
3957 3992 int dstenc = $dst$$reg;
3958 3993 int srcenc = $src$$reg;
3959 3994 address const_address = (address) StubRoutines::x86::double_sign_flip();
3960 3995
3961 3996 // cmpq $dst, [0x8000000000000000]
3962 3997 cbuf.set_inst_mark();
3963 3998 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR);
3964 3999 emit_opcode(cbuf, 0x39);
3965 4000 // XXX reg_mem doesn't support RIP-relative addressing yet
3966 4001 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101
3967 4002 emit_d32_reloc(cbuf, const_address);
3968 4003
3969 4004
3970 4005 // jne,s done
3971 4006 emit_opcode(cbuf, 0x75);
3972 4007 if (srcenc < 8 && dstenc < 8) {
3973 4008 emit_d8(cbuf, 0xF);
3974 4009 } else if (srcenc >= 8 && dstenc >= 8) {
3975 4010 emit_d8(cbuf, 0x11);
3976 4011 } else {
3977 4012 emit_d8(cbuf, 0x10);
3978 4013 }
3979 4014
3980 4015 // subq rsp, #8
3981 4016 emit_opcode(cbuf, Assembler::REX_W);
3982 4017 emit_opcode(cbuf, 0x83);
3983 4018 emit_rm(cbuf, 0x3, 0x5, RSP_enc);
3984 4019 emit_d8(cbuf, 8);
3985 4020
3986 4021 // movsd [rsp], $src
3987 4022 emit_opcode(cbuf, 0xF2);
3988 4023 if (srcenc >= 8) {
3989 4024 emit_opcode(cbuf, Assembler::REX_R);
3990 4025 }
3991 4026 emit_opcode(cbuf, 0x0F);
3992 4027 emit_opcode(cbuf, 0x11);
3993 4028 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
3994 4029
3995 4030 // call d2l_fixup
3996 4031 cbuf.set_inst_mark();
3997 4032 emit_opcode(cbuf, 0xE8);
3998 4033 emit_d32_reloc(cbuf,
3999 4034 (int)
4000 4035 (StubRoutines::x86::d2l_fixup() - cbuf.code_end() - 4),
4001 4036 runtime_call_Relocation::spec(),
4002 4037 RELOC_DISP32);
4003 4038
4004 4039 // popq $dst
4005 4040 if (dstenc >= 8) {
4006 4041 emit_opcode(cbuf, Assembler::REX_B);
4007 4042 }
4008 4043 emit_opcode(cbuf, 0x58 | (dstenc & 7));
4009 4044
4010 4045 // done:
4011 4046 %}
4012 4047
4013 4048 // Safepoint Poll. This polls the safepoint page, and causes an
4014 4049 // exception if it is not readable. Unfortunately, it kills
4015 4050 // RFLAGS in the process.
4016 4051 enc_class enc_safepoint_poll
4017 4052 %{
4018 4053 // testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
4019 4054 // XXX reg_mem doesn't support RIP-relative addressing yet
4020 4055 cbuf.set_inst_mark();
4021 4056 cbuf.relocate(cbuf.inst_mark(), relocInfo::poll_type, 0); // XXX
4022 4057 emit_opcode(cbuf, 0x85); // testl
4023 4058 emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
4024 4059 // cbuf.inst_mark() is beginning of instruction
4025 4060 emit_d32_reloc(cbuf, os::get_polling_page());
4026 4061 // relocInfo::poll_type,
4027 4062 %}
4028 4063 %}
4029 4064
4030 4065
4031 4066
4032 4067 //----------FRAME--------------------------------------------------------------
4033 4068 // Definition of frame structure and management information.
4034 4069 //
4035 4070 // S T A C K L A Y O U T Allocators stack-slot number
4036 4071 // | (to get allocators register number
4037 4072 // G Owned by | | v add OptoReg::stack0())
4038 4073 // r CALLER | |
4039 4074 // o | +--------+ pad to even-align allocators stack-slot
4040 4075 // w V | pad0 | numbers; owned by CALLER
4041 4076 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
4042 4077 // h ^ | in | 5
4043 4078 // | | args | 4 Holes in incoming args owned by SELF
4044 4079 // | | | | 3
4045 4080 // | | +--------+
4046 4081 // V | | old out| Empty on Intel, window on Sparc
4047 4082 // | old |preserve| Must be even aligned.
4048 4083 // | SP-+--------+----> Matcher::_old_SP, even aligned
4049 4084 // | | in | 3 area for Intel ret address
4050 4085 // Owned by |preserve| Empty on Sparc.
4051 4086 // SELF +--------+
4052 4087 // | | pad2 | 2 pad to align old SP
4053 4088 // | +--------+ 1
4054 4089 // | | locks | 0
4055 4090 // | +--------+----> OptoReg::stack0(), even aligned
4056 4091 // | | pad1 | 11 pad to align new SP
4057 4092 // | +--------+
4058 4093 // | | | 10
4059 4094 // | | spills | 9 spills
4060 4095 // V | | 8 (pad0 slot for callee)
4061 4096 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
4062 4097 // ^ | out | 7
4063 4098 // | | args | 6 Holes in outgoing args owned by CALLEE
4064 4099 // Owned by +--------+
4065 4100 // CALLEE | new out| 6 Empty on Intel, window on Sparc
4066 4101 // | new |preserve| Must be even-aligned.
4067 4102 // | SP-+--------+----> Matcher::_new_SP, even aligned
4068 4103 // | | |
4069 4104 //
4070 4105 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
4071 4106 // known from SELF's arguments and the Java calling convention.
4072 4107 // Region 6-7 is determined per call site.
4073 4108 // Note 2: If the calling convention leaves holes in the incoming argument
4074 4109 // area, those holes are owned by SELF. Holes in the outgoing area
4075 4110 // are owned by the CALLEE. Holes should not be nessecary in the
4076 4111 // incoming area, as the Java calling convention is completely under
4077 4112 // the control of the AD file. Doubles can be sorted and packed to
4078 4113 // avoid holes. Holes in the outgoing arguments may be nessecary for
4079 4114 // varargs C calling conventions.
4080 4115 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
4081 4116 // even aligned with pad0 as needed.
4082 4117 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
4083 4118 // region 6-11 is even aligned; it may be padded out more so that
4084 4119 // the region from SP to FP meets the minimum stack alignment.
4085 4120 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
4086 4121 // alignment. Region 11, pad1, may be dynamically extended so that
4087 4122 // SP meets the minimum alignment.
4088 4123
4089 4124 frame
4090 4125 %{
4091 4126 // What direction does stack grow in (assumed to be same for C & Java)
4092 4127 stack_direction(TOWARDS_LOW);
4093 4128
4094 4129 // These three registers define part of the calling convention
4095 4130 // between compiled code and the interpreter.
4096 4131 inline_cache_reg(RAX); // Inline Cache Register
4097 4132 interpreter_method_oop_reg(RBX); // Method Oop Register when
4098 4133 // calling interpreter
4099 4134
4100 4135 // Optional: name the operand used by cisc-spilling to access
4101 4136 // [stack_pointer + offset]
4102 4137 cisc_spilling_operand_name(indOffset32);
4103 4138
4104 4139 // Number of stack slots consumed by locking an object
4105 4140 sync_stack_slots(2);
4106 4141
4107 4142 // Compiled code's Frame Pointer
4108 4143 frame_pointer(RSP);
4109 4144
4110 4145 // Interpreter stores its frame pointer in a register which is
4111 4146 // stored to the stack by I2CAdaptors.
4112 4147 // I2CAdaptors convert from interpreted java to compiled java.
4113 4148 interpreter_frame_pointer(RBP);
4114 4149
4115 4150 // Stack alignment requirement
4116 4151 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
4117 4152
4118 4153 // Number of stack slots between incoming argument block and the start of
4119 4154 // a new frame. The PROLOG must add this many slots to the stack. The
4120 4155 // EPILOG must remove this many slots. amd64 needs two slots for
4121 4156 // return address.
4122 4157 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls);
4123 4158
4124 4159 // Number of outgoing stack slots killed above the out_preserve_stack_slots
4125 4160 // for calls to C. Supports the var-args backing area for register parms.
4126 4161 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
4127 4162
4128 4163 // The after-PROLOG location of the return address. Location of
4129 4164 // return address specifies a type (REG or STACK) and a number
4130 4165 // representing the register number (i.e. - use a register name) or
4131 4166 // stack slot.
4132 4167 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
4133 4168 // Otherwise, it is above the locks and verification slot and alignment word
4134 4169 return_addr(STACK - 2 +
4135 4170 round_to(2 + 2 * VerifyStackAtCalls +
4136 4171 Compile::current()->fixed_slots(),
4137 4172 WordsPerLong * 2));
4138 4173
4139 4174 // Body of function which returns an integer array locating
4140 4175 // arguments either in registers or in stack slots. Passed an array
4141 4176 // of ideal registers called "sig" and a "length" count. Stack-slot
4142 4177 // offsets are based on outgoing arguments, i.e. a CALLER setting up
4143 4178 // arguments for a CALLEE. Incoming stack arguments are
4144 4179 // automatically biased by the preserve_stack_slots field above.
4145 4180
4146 4181 calling_convention
4147 4182 %{
4148 4183 // No difference between ingoing/outgoing just pass false
4149 4184 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
4150 4185 %}
4151 4186
4152 4187 c_calling_convention
4153 4188 %{
4154 4189 // This is obviously always outgoing
4155 4190 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length);
4156 4191 %}
4157 4192
4158 4193 // Location of compiled Java return values. Same as C for now.
4159 4194 return_value
4160 4195 %{
4161 4196 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
4162 4197 "only return normal values");
4163 4198
4164 4199 static const int lo[Op_RegL + 1] = {
4165 4200 0,
4166 4201 0,
4167 4202 RAX_num, // Op_RegN
4168 4203 RAX_num, // Op_RegI
4169 4204 RAX_num, // Op_RegP
4170 4205 XMM0_num, // Op_RegF
4171 4206 XMM0_num, // Op_RegD
4172 4207 RAX_num // Op_RegL
4173 4208 };
4174 4209 static const int hi[Op_RegL + 1] = {
4175 4210 0,
4176 4211 0,
4177 4212 OptoReg::Bad, // Op_RegN
4178 4213 OptoReg::Bad, // Op_RegI
4179 4214 RAX_H_num, // Op_RegP
4180 4215 OptoReg::Bad, // Op_RegF
4181 4216 XMM0_H_num, // Op_RegD
4182 4217 RAX_H_num // Op_RegL
4183 4218 };
4184 4219 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type");
4185 4220 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
4186 4221 %}
4187 4222 %}
4188 4223
4189 4224 //----------ATTRIBUTES---------------------------------------------------------
4190 4225 //----------Operand Attributes-------------------------------------------------
4191 4226 op_attrib op_cost(0); // Required cost attribute
4192 4227
4193 4228 //----------Instruction Attributes---------------------------------------------
4194 4229 ins_attrib ins_cost(100); // Required cost attribute
4195 4230 ins_attrib ins_size(8); // Required size attribute (in bits)
4196 4231 ins_attrib ins_pc_relative(0); // Required PC Relative flag
4197 4232 ins_attrib ins_short_branch(0); // Required flag: is this instruction
4198 4233 // a non-matching short branch variant
4199 4234 // of some long branch?
4200 4235 ins_attrib ins_alignment(1); // Required alignment attribute (must
4201 4236 // be a power of 2) specifies the
4202 4237 // alignment that some part of the
4203 4238 // instruction (not necessarily the
4204 4239 // start) requires. If > 1, a
4205 4240 // compute_padding() function must be
4206 4241 // provided for the instruction
4207 4242
4208 4243 //----------OPERANDS-----------------------------------------------------------
4209 4244 // Operand definitions must precede instruction definitions for correct parsing
4210 4245 // in the ADLC because operands constitute user defined types which are used in
4211 4246 // instruction definitions.
4212 4247
4213 4248 //----------Simple Operands----------------------------------------------------
4214 4249 // Immediate Operands
4215 4250 // Integer Immediate
4216 4251 operand immI()
4217 4252 %{
4218 4253 match(ConI);
4219 4254
4220 4255 op_cost(10);
4221 4256 format %{ %}
4222 4257 interface(CONST_INTER);
4223 4258 %}
4224 4259
4225 4260 // Constant for test vs zero
4226 4261 operand immI0()
4227 4262 %{
4228 4263 predicate(n->get_int() == 0);
4229 4264 match(ConI);
4230 4265
4231 4266 op_cost(0);
4232 4267 format %{ %}
4233 4268 interface(CONST_INTER);
4234 4269 %}
4235 4270
4236 4271 // Constant for increment
4237 4272 operand immI1()
4238 4273 %{
4239 4274 predicate(n->get_int() == 1);
4240 4275 match(ConI);
4241 4276
4242 4277 op_cost(0);
4243 4278 format %{ %}
4244 4279 interface(CONST_INTER);
4245 4280 %}
4246 4281
4247 4282 // Constant for decrement
4248 4283 operand immI_M1()
4249 4284 %{
4250 4285 predicate(n->get_int() == -1);
4251 4286 match(ConI);
4252 4287
4253 4288 op_cost(0);
4254 4289 format %{ %}
4255 4290 interface(CONST_INTER);
4256 4291 %}
4257 4292
4258 4293 // Valid scale values for addressing modes
4259 4294 operand immI2()
4260 4295 %{
4261 4296 predicate(0 <= n->get_int() && (n->get_int() <= 3));
4262 4297 match(ConI);
4263 4298
4264 4299 format %{ %}
4265 4300 interface(CONST_INTER);
4266 4301 %}
4267 4302
4268 4303 operand immI8()
4269 4304 %{
4270 4305 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80));
4271 4306 match(ConI);
4272 4307
4273 4308 op_cost(5);
4274 4309 format %{ %}
4275 4310 interface(CONST_INTER);
4276 4311 %}
4277 4312
4278 4313 operand immI16()
4279 4314 %{
4280 4315 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
4281 4316 match(ConI);
4282 4317
4283 4318 op_cost(10);
4284 4319 format %{ %}
4285 4320 interface(CONST_INTER);
4286 4321 %}
4287 4322
4288 4323 // Constant for long shifts
4289 4324 operand immI_32()
4290 4325 %{
4291 4326 predicate( n->get_int() == 32 );
4292 4327 match(ConI);
4293 4328
4294 4329 op_cost(0);
4295 4330 format %{ %}
4296 4331 interface(CONST_INTER);
4297 4332 %}
4298 4333
4299 4334 // Constant for long shifts
4300 4335 operand immI_64()
4301 4336 %{
4302 4337 predicate( n->get_int() == 64 );
4303 4338 match(ConI);
4304 4339
4305 4340 op_cost(0);
4306 4341 format %{ %}
4307 4342 interface(CONST_INTER);
4308 4343 %}
4309 4344
4310 4345 // Pointer Immediate
4311 4346 operand immP()
4312 4347 %{
4313 4348 match(ConP);
4314 4349
4315 4350 op_cost(10);
4316 4351 format %{ %}
4317 4352 interface(CONST_INTER);
4318 4353 %}
4319 4354
4320 4355 // NULL Pointer Immediate
4321 4356 operand immP0()
4322 4357 %{
4323 4358 predicate(n->get_ptr() == 0);
4324 4359 match(ConP);
4325 4360
4326 4361 op_cost(5);
4327 4362 format %{ %}
4328 4363 interface(CONST_INTER);
4329 4364 %}
4330 4365
4331 4366 // Pointer Immediate
4332 4367 operand immN() %{
4333 4368 match(ConN);
4334 4369
4335 4370 op_cost(10);
4336 4371 format %{ %}
4337 4372 interface(CONST_INTER);
4338 4373 %}
4339 4374
4340 4375 // NULL Pointer Immediate
4341 4376 operand immN0() %{
4342 4377 predicate(n->get_narrowcon() == 0);
4343 4378 match(ConN);
4344 4379
4345 4380 op_cost(5);
4346 4381 format %{ %}
4347 4382 interface(CONST_INTER);
4348 4383 %}
4349 4384
4350 4385 operand immP31()
4351 4386 %{
4352 4387 predicate(!n->as_Type()->type()->isa_oopptr()
4353 4388 && (n->get_ptr() >> 31) == 0);
4354 4389 match(ConP);
4355 4390
4356 4391 op_cost(5);
4357 4392 format %{ %}
4358 4393 interface(CONST_INTER);
4359 4394 %}
4360 4395
4361 4396
4362 4397 // Long Immediate
4363 4398 operand immL()
4364 4399 %{
4365 4400 match(ConL);
4366 4401
4367 4402 op_cost(20);
4368 4403 format %{ %}
4369 4404 interface(CONST_INTER);
4370 4405 %}
4371 4406
4372 4407 // Long Immediate 8-bit
4373 4408 operand immL8()
4374 4409 %{
4375 4410 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
4376 4411 match(ConL);
4377 4412
4378 4413 op_cost(5);
4379 4414 format %{ %}
4380 4415 interface(CONST_INTER);
4381 4416 %}
4382 4417
4383 4418 // Long Immediate 32-bit unsigned
4384 4419 operand immUL32()
4385 4420 %{
4386 4421 predicate(n->get_long() == (unsigned int) (n->get_long()));
4387 4422 match(ConL);
4388 4423
4389 4424 op_cost(10);
4390 4425 format %{ %}
4391 4426 interface(CONST_INTER);
4392 4427 %}
4393 4428
4394 4429 // Long Immediate 32-bit signed
4395 4430 operand immL32()
4396 4431 %{
4397 4432 predicate(n->get_long() == (int) (n->get_long()));
4398 4433 match(ConL);
4399 4434
4400 4435 op_cost(15);
4401 4436 format %{ %}
4402 4437 interface(CONST_INTER);
4403 4438 %}
4404 4439
4405 4440 // Long Immediate zero
4406 4441 operand immL0()
4407 4442 %{
4408 4443 predicate(n->get_long() == 0L);
4409 4444 match(ConL);
4410 4445
4411 4446 op_cost(10);
4412 4447 format %{ %}
4413 4448 interface(CONST_INTER);
4414 4449 %}
4415 4450
4416 4451 // Constant for increment
4417 4452 operand immL1()
4418 4453 %{
4419 4454 predicate(n->get_long() == 1);
4420 4455 match(ConL);
4421 4456
4422 4457 format %{ %}
4423 4458 interface(CONST_INTER);
4424 4459 %}
4425 4460
4426 4461 // Constant for decrement
4427 4462 operand immL_M1()
4428 4463 %{
4429 4464 predicate(n->get_long() == -1);
4430 4465 match(ConL);
4431 4466
4432 4467 format %{ %}
4433 4468 interface(CONST_INTER);
4434 4469 %}
4435 4470
4436 4471 // Long Immediate: the value 10
4437 4472 operand immL10()
4438 4473 %{
4439 4474 predicate(n->get_long() == 10);
4440 4475 match(ConL);
4441 4476
4442 4477 format %{ %}
4443 4478 interface(CONST_INTER);
4444 4479 %}
4445 4480
4446 4481 // Long immediate from 0 to 127.
4447 4482 // Used for a shorter form of long mul by 10.
4448 4483 operand immL_127()
4449 4484 %{
4450 4485 predicate(0 <= n->get_long() && n->get_long() < 0x80);
4451 4486 match(ConL);
4452 4487
4453 4488 op_cost(10);
4454 4489 format %{ %}
4455 4490 interface(CONST_INTER);
4456 4491 %}
4457 4492
4458 4493 // Long Immediate: low 32-bit mask
4459 4494 operand immL_32bits()
4460 4495 %{
4461 4496 predicate(n->get_long() == 0xFFFFFFFFL);
4462 4497 match(ConL);
4463 4498 op_cost(20);
4464 4499
4465 4500 format %{ %}
4466 4501 interface(CONST_INTER);
4467 4502 %}
4468 4503
4469 4504 // Float Immediate zero
4470 4505 operand immF0()
4471 4506 %{
4472 4507 predicate(jint_cast(n->getf()) == 0);
4473 4508 match(ConF);
4474 4509
4475 4510 op_cost(5);
4476 4511 format %{ %}
4477 4512 interface(CONST_INTER);
4478 4513 %}
4479 4514
4480 4515 // Float Immediate
4481 4516 operand immF()
4482 4517 %{
4483 4518 match(ConF);
4484 4519
4485 4520 op_cost(15);
4486 4521 format %{ %}
4487 4522 interface(CONST_INTER);
4488 4523 %}
4489 4524
4490 4525 // Double Immediate zero
4491 4526 operand immD0()
4492 4527 %{
4493 4528 predicate(jlong_cast(n->getd()) == 0);
4494 4529 match(ConD);
4495 4530
4496 4531 op_cost(5);
4497 4532 format %{ %}
4498 4533 interface(CONST_INTER);
4499 4534 %}
4500 4535
4501 4536 // Double Immediate
4502 4537 operand immD()
4503 4538 %{
4504 4539 match(ConD);
4505 4540
4506 4541 op_cost(15);
4507 4542 format %{ %}
4508 4543 interface(CONST_INTER);
4509 4544 %}
4510 4545
4511 4546 // Immediates for special shifts (sign extend)
4512 4547
4513 4548 // Constants for increment
4514 4549 operand immI_16()
4515 4550 %{
4516 4551 predicate(n->get_int() == 16);
4517 4552 match(ConI);
4518 4553
4519 4554 format %{ %}
4520 4555 interface(CONST_INTER);
4521 4556 %}
4522 4557
4523 4558 operand immI_24()
4524 4559 %{
4525 4560 predicate(n->get_int() == 24);
4526 4561 match(ConI);
4527 4562
4528 4563 format %{ %}
4529 4564 interface(CONST_INTER);
4530 4565 %}
4531 4566
4532 4567 // Constant for byte-wide masking
4533 4568 operand immI_255()
4534 4569 %{
4535 4570 predicate(n->get_int() == 255);
4536 4571 match(ConI);
4537 4572
4538 4573 format %{ %}
4539 4574 interface(CONST_INTER);
4540 4575 %}
4541 4576
4542 4577 // Constant for short-wide masking
4543 4578 operand immI_65535()
4544 4579 %{
4545 4580 predicate(n->get_int() == 65535);
4546 4581 match(ConI);
4547 4582
4548 4583 format %{ %}
4549 4584 interface(CONST_INTER);
4550 4585 %}
4551 4586
4552 4587 // Constant for byte-wide masking
4553 4588 operand immL_255()
4554 4589 %{
4555 4590 predicate(n->get_long() == 255);
4556 4591 match(ConL);
4557 4592
4558 4593 format %{ %}
4559 4594 interface(CONST_INTER);
4560 4595 %}
4561 4596
4562 4597 // Constant for short-wide masking
4563 4598 operand immL_65535()
4564 4599 %{
4565 4600 predicate(n->get_long() == 65535);
4566 4601 match(ConL);
4567 4602
4568 4603 format %{ %}
4569 4604 interface(CONST_INTER);
4570 4605 %}
4571 4606
4572 4607 // Register Operands
4573 4608 // Integer Register
4574 4609 operand rRegI()
4575 4610 %{
4576 4611 constraint(ALLOC_IN_RC(int_reg));
4577 4612 match(RegI);
4578 4613
4579 4614 match(rax_RegI);
4580 4615 match(rbx_RegI);
4581 4616 match(rcx_RegI);
4582 4617 match(rdx_RegI);
4583 4618 match(rdi_RegI);
4584 4619
4585 4620 format %{ %}
4586 4621 interface(REG_INTER);
4587 4622 %}
4588 4623
4589 4624 // Special Registers
4590 4625 operand rax_RegI()
4591 4626 %{
4592 4627 constraint(ALLOC_IN_RC(int_rax_reg));
4593 4628 match(RegI);
4594 4629 match(rRegI);
4595 4630
4596 4631 format %{ "RAX" %}
4597 4632 interface(REG_INTER);
4598 4633 %}
4599 4634
4600 4635 // Special Registers
4601 4636 operand rbx_RegI()
4602 4637 %{
4603 4638 constraint(ALLOC_IN_RC(int_rbx_reg));
4604 4639 match(RegI);
4605 4640 match(rRegI);
4606 4641
4607 4642 format %{ "RBX" %}
4608 4643 interface(REG_INTER);
4609 4644 %}
4610 4645
4611 4646 operand rcx_RegI()
4612 4647 %{
4613 4648 constraint(ALLOC_IN_RC(int_rcx_reg));
4614 4649 match(RegI);
4615 4650 match(rRegI);
4616 4651
4617 4652 format %{ "RCX" %}
4618 4653 interface(REG_INTER);
4619 4654 %}
4620 4655
4621 4656 operand rdx_RegI()
4622 4657 %{
4623 4658 constraint(ALLOC_IN_RC(int_rdx_reg));
4624 4659 match(RegI);
4625 4660 match(rRegI);
4626 4661
4627 4662 format %{ "RDX" %}
4628 4663 interface(REG_INTER);
4629 4664 %}
4630 4665
4631 4666 operand rdi_RegI()
4632 4667 %{
4633 4668 constraint(ALLOC_IN_RC(int_rdi_reg));
4634 4669 match(RegI);
4635 4670 match(rRegI);
4636 4671
4637 4672 format %{ "RDI" %}
4638 4673 interface(REG_INTER);
4639 4674 %}
4640 4675
4641 4676 operand no_rcx_RegI()
4642 4677 %{
4643 4678 constraint(ALLOC_IN_RC(int_no_rcx_reg));
4644 4679 match(RegI);
4645 4680 match(rax_RegI);
4646 4681 match(rbx_RegI);
4647 4682 match(rdx_RegI);
4648 4683 match(rdi_RegI);
4649 4684
4650 4685 format %{ %}
4651 4686 interface(REG_INTER);
4652 4687 %}
4653 4688
4654 4689 operand no_rax_rdx_RegI()
4655 4690 %{
4656 4691 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg));
4657 4692 match(RegI);
4658 4693 match(rbx_RegI);
4659 4694 match(rcx_RegI);
4660 4695 match(rdi_RegI);
4661 4696
4662 4697 format %{ %}
4663 4698 interface(REG_INTER);
4664 4699 %}
4665 4700
4666 4701 // Pointer Register
4667 4702 operand any_RegP()
4668 4703 %{
4669 4704 constraint(ALLOC_IN_RC(any_reg));
4670 4705 match(RegP);
4671 4706 match(rax_RegP);
4672 4707 match(rbx_RegP);
4673 4708 match(rdi_RegP);
4674 4709 match(rsi_RegP);
4675 4710 match(rbp_RegP);
4676 4711 match(r15_RegP);
4677 4712 match(rRegP);
4678 4713
4679 4714 format %{ %}
4680 4715 interface(REG_INTER);
4681 4716 %}
4682 4717
4683 4718 operand rRegP()
4684 4719 %{
4685 4720 constraint(ALLOC_IN_RC(ptr_reg));
4686 4721 match(RegP);
4687 4722 match(rax_RegP);
4688 4723 match(rbx_RegP);
4689 4724 match(rdi_RegP);
4690 4725 match(rsi_RegP);
4691 4726 match(rbp_RegP);
4692 4727 match(r15_RegP); // See Q&A below about r15_RegP.
4693 4728
4694 4729 format %{ %}
4695 4730 interface(REG_INTER);
4696 4731 %}
4697 4732
4698 4733 operand rRegN() %{
4699 4734 constraint(ALLOC_IN_RC(int_reg));
4700 4735 match(RegN);
4701 4736
4702 4737 format %{ %}
4703 4738 interface(REG_INTER);
4704 4739 %}
4705 4740
4706 4741 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
4707 4742 // Answer: Operand match rules govern the DFA as it processes instruction inputs.
4708 4743 // It's fine for an instruction input which expects rRegP to match a r15_RegP.
4709 4744 // The output of an instruction is controlled by the allocator, which respects
4710 4745 // register class masks, not match rules. Unless an instruction mentions
4711 4746 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered
4712 4747 // by the allocator as an input.
4713 4748
4714 4749 operand no_rax_RegP()
4715 4750 %{
4716 4751 constraint(ALLOC_IN_RC(ptr_no_rax_reg));
4717 4752 match(RegP);
4718 4753 match(rbx_RegP);
4719 4754 match(rsi_RegP);
4720 4755 match(rdi_RegP);
4721 4756
4722 4757 format %{ %}
4723 4758 interface(REG_INTER);
4724 4759 %}
4725 4760
4726 4761 operand no_rbp_RegP()
4727 4762 %{
4728 4763 constraint(ALLOC_IN_RC(ptr_no_rbp_reg));
4729 4764 match(RegP);
4730 4765 match(rbx_RegP);
4731 4766 match(rsi_RegP);
4732 4767 match(rdi_RegP);
4733 4768
4734 4769 format %{ %}
4735 4770 interface(REG_INTER);
4736 4771 %}
4737 4772
4738 4773 operand no_rax_rbx_RegP()
4739 4774 %{
4740 4775 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg));
4741 4776 match(RegP);
4742 4777 match(rsi_RegP);
4743 4778 match(rdi_RegP);
4744 4779
4745 4780 format %{ %}
4746 4781 interface(REG_INTER);
4747 4782 %}
4748 4783
4749 4784 // Special Registers
4750 4785 // Return a pointer value
4751 4786 operand rax_RegP()
4752 4787 %{
4753 4788 constraint(ALLOC_IN_RC(ptr_rax_reg));
4754 4789 match(RegP);
4755 4790 match(rRegP);
4756 4791
4757 4792 format %{ %}
4758 4793 interface(REG_INTER);
4759 4794 %}
4760 4795
4761 4796 // Special Registers
4762 4797 // Return a compressed pointer value
4763 4798 operand rax_RegN()
4764 4799 %{
4765 4800 constraint(ALLOC_IN_RC(int_rax_reg));
4766 4801 match(RegN);
4767 4802 match(rRegN);
4768 4803
4769 4804 format %{ %}
4770 4805 interface(REG_INTER);
4771 4806 %}
4772 4807
4773 4808 // Used in AtomicAdd
4774 4809 operand rbx_RegP()
4775 4810 %{
4776 4811 constraint(ALLOC_IN_RC(ptr_rbx_reg));
4777 4812 match(RegP);
4778 4813 match(rRegP);
4779 4814
4780 4815 format %{ %}
4781 4816 interface(REG_INTER);
4782 4817 %}
4783 4818
4784 4819 operand rsi_RegP()
4785 4820 %{
4786 4821 constraint(ALLOC_IN_RC(ptr_rsi_reg));
4787 4822 match(RegP);
4788 4823 match(rRegP);
4789 4824
4790 4825 format %{ %}
4791 4826 interface(REG_INTER);
4792 4827 %}
4793 4828
4794 4829 // Used in rep stosq
4795 4830 operand rdi_RegP()
4796 4831 %{
4797 4832 constraint(ALLOC_IN_RC(ptr_rdi_reg));
4798 4833 match(RegP);
4799 4834 match(rRegP);
4800 4835
4801 4836 format %{ %}
4802 4837 interface(REG_INTER);
4803 4838 %}
4804 4839
4805 4840 operand rbp_RegP()
4806 4841 %{
4807 4842 constraint(ALLOC_IN_RC(ptr_rbp_reg));
4808 4843 match(RegP);
4809 4844 match(rRegP);
4810 4845
4811 4846 format %{ %}
4812 4847 interface(REG_INTER);
4813 4848 %}
4814 4849
4815 4850 operand r15_RegP()
4816 4851 %{
4817 4852 constraint(ALLOC_IN_RC(ptr_r15_reg));
4818 4853 match(RegP);
4819 4854 match(rRegP);
4820 4855
4821 4856 format %{ %}
4822 4857 interface(REG_INTER);
4823 4858 %}
4824 4859
4825 4860 operand rRegL()
4826 4861 %{
4827 4862 constraint(ALLOC_IN_RC(long_reg));
4828 4863 match(RegL);
4829 4864 match(rax_RegL);
4830 4865 match(rdx_RegL);
4831 4866
4832 4867 format %{ %}
4833 4868 interface(REG_INTER);
4834 4869 %}
4835 4870
4836 4871 // Special Registers
4837 4872 operand no_rax_rdx_RegL()
4838 4873 %{
4839 4874 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
4840 4875 match(RegL);
4841 4876 match(rRegL);
4842 4877
4843 4878 format %{ %}
4844 4879 interface(REG_INTER);
4845 4880 %}
4846 4881
4847 4882 operand no_rax_RegL()
4848 4883 %{
4849 4884 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
4850 4885 match(RegL);
4851 4886 match(rRegL);
4852 4887 match(rdx_RegL);
4853 4888
4854 4889 format %{ %}
4855 4890 interface(REG_INTER);
4856 4891 %}
4857 4892
4858 4893 operand no_rcx_RegL()
4859 4894 %{
4860 4895 constraint(ALLOC_IN_RC(long_no_rcx_reg));
4861 4896 match(RegL);
4862 4897 match(rRegL);
4863 4898
4864 4899 format %{ %}
4865 4900 interface(REG_INTER);
4866 4901 %}
4867 4902
4868 4903 operand rax_RegL()
4869 4904 %{
4870 4905 constraint(ALLOC_IN_RC(long_rax_reg));
4871 4906 match(RegL);
4872 4907 match(rRegL);
4873 4908
4874 4909 format %{ "RAX" %}
4875 4910 interface(REG_INTER);
4876 4911 %}
4877 4912
4878 4913 operand rcx_RegL()
4879 4914 %{
4880 4915 constraint(ALLOC_IN_RC(long_rcx_reg));
4881 4916 match(RegL);
4882 4917 match(rRegL);
4883 4918
4884 4919 format %{ %}
4885 4920 interface(REG_INTER);
4886 4921 %}
4887 4922
4888 4923 operand rdx_RegL()
4889 4924 %{
4890 4925 constraint(ALLOC_IN_RC(long_rdx_reg));
4891 4926 match(RegL);
4892 4927 match(rRegL);
4893 4928
4894 4929 format %{ %}
4895 4930 interface(REG_INTER);
4896 4931 %}
4897 4932
4898 4933 // Flags register, used as output of compare instructions
4899 4934 operand rFlagsReg()
4900 4935 %{
4901 4936 constraint(ALLOC_IN_RC(int_flags));
4902 4937 match(RegFlags);
4903 4938
4904 4939 format %{ "RFLAGS" %}
4905 4940 interface(REG_INTER);
4906 4941 %}
4907 4942
4908 4943 // Flags register, used as output of FLOATING POINT compare instructions
4909 4944 operand rFlagsRegU()
4910 4945 %{
4911 4946 constraint(ALLOC_IN_RC(int_flags));
4912 4947 match(RegFlags);
4913 4948
4914 4949 format %{ "RFLAGS_U" %}
4915 4950 interface(REG_INTER);
4916 4951 %}
4917 4952
4918 4953 operand rFlagsRegUCF() %{
4919 4954 constraint(ALLOC_IN_RC(int_flags));
4920 4955 match(RegFlags);
4921 4956 predicate(false);
4922 4957
4923 4958 format %{ "RFLAGS_U_CF" %}
4924 4959 interface(REG_INTER);
4925 4960 %}
4926 4961
4927 4962 // Float register operands
4928 4963 operand regF()
4929 4964 %{
4930 4965 constraint(ALLOC_IN_RC(float_reg));
4931 4966 match(RegF);
4932 4967
4933 4968 format %{ %}
4934 4969 interface(REG_INTER);
4935 4970 %}
4936 4971
4937 4972 // Double register operands
4938 4973 operand regD()
4939 4974 %{
4940 4975 constraint(ALLOC_IN_RC(double_reg));
4941 4976 match(RegD);
4942 4977
4943 4978 format %{ %}
4944 4979 interface(REG_INTER);
4945 4980 %}
4946 4981
4947 4982
4948 4983 //----------Memory Operands----------------------------------------------------
4949 4984 // Direct Memory Operand
4950 4985 // operand direct(immP addr)
4951 4986 // %{
4952 4987 // match(addr);
4953 4988
4954 4989 // format %{ "[$addr]" %}
4955 4990 // interface(MEMORY_INTER) %{
4956 4991 // base(0xFFFFFFFF);
4957 4992 // index(0x4);
4958 4993 // scale(0x0);
4959 4994 // disp($addr);
4960 4995 // %}
4961 4996 // %}
4962 4997
4963 4998 // Indirect Memory Operand
4964 4999 operand indirect(any_RegP reg)
4965 5000 %{
4966 5001 constraint(ALLOC_IN_RC(ptr_reg));
4967 5002 match(reg);
4968 5003
4969 5004 format %{ "[$reg]" %}
4970 5005 interface(MEMORY_INTER) %{
4971 5006 base($reg);
4972 5007 index(0x4);
4973 5008 scale(0x0);
4974 5009 disp(0x0);
4975 5010 %}
4976 5011 %}
4977 5012
4978 5013 // Indirect Memory Plus Short Offset Operand
4979 5014 operand indOffset8(any_RegP reg, immL8 off)
4980 5015 %{
4981 5016 constraint(ALLOC_IN_RC(ptr_reg));
4982 5017 match(AddP reg off);
4983 5018
4984 5019 format %{ "[$reg + $off (8-bit)]" %}
4985 5020 interface(MEMORY_INTER) %{
4986 5021 base($reg);
4987 5022 index(0x4);
4988 5023 scale(0x0);
4989 5024 disp($off);
4990 5025 %}
4991 5026 %}
4992 5027
4993 5028 // Indirect Memory Plus Long Offset Operand
4994 5029 operand indOffset32(any_RegP reg, immL32 off)
4995 5030 %{
4996 5031 constraint(ALLOC_IN_RC(ptr_reg));
4997 5032 match(AddP reg off);
4998 5033
4999 5034 format %{ "[$reg + $off (32-bit)]" %}
5000 5035 interface(MEMORY_INTER) %{
5001 5036 base($reg);
5002 5037 index(0x4);
5003 5038 scale(0x0);
5004 5039 disp($off);
5005 5040 %}
5006 5041 %}
5007 5042
5008 5043 // Indirect Memory Plus Index Register Plus Offset Operand
5009 5044 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off)
5010 5045 %{
5011 5046 constraint(ALLOC_IN_RC(ptr_reg));
5012 5047 match(AddP (AddP reg lreg) off);
5013 5048
5014 5049 op_cost(10);
5015 5050 format %{"[$reg + $off + $lreg]" %}
5016 5051 interface(MEMORY_INTER) %{
5017 5052 base($reg);
5018 5053 index($lreg);
5019 5054 scale(0x0);
5020 5055 disp($off);
5021 5056 %}
5022 5057 %}
5023 5058
5024 5059 // Indirect Memory Plus Index Register Plus Offset Operand
5025 5060 operand indIndex(any_RegP reg, rRegL lreg)
5026 5061 %{
5027 5062 constraint(ALLOC_IN_RC(ptr_reg));
5028 5063 match(AddP reg lreg);
5029 5064
5030 5065 op_cost(10);
5031 5066 format %{"[$reg + $lreg]" %}
5032 5067 interface(MEMORY_INTER) %{
5033 5068 base($reg);
5034 5069 index($lreg);
5035 5070 scale(0x0);
5036 5071 disp(0x0);
5037 5072 %}
5038 5073 %}
5039 5074
5040 5075 // Indirect Memory Times Scale Plus Index Register
5041 5076 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale)
5042 5077 %{
5043 5078 constraint(ALLOC_IN_RC(ptr_reg));
5044 5079 match(AddP reg (LShiftL lreg scale));
5045 5080
5046 5081 op_cost(10);
5047 5082 format %{"[$reg + $lreg << $scale]" %}
5048 5083 interface(MEMORY_INTER) %{
5049 5084 base($reg);
5050 5085 index($lreg);
5051 5086 scale($scale);
5052 5087 disp(0x0);
5053 5088 %}
5054 5089 %}
5055 5090
5056 5091 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5057 5092 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
5058 5093 %{
5059 5094 constraint(ALLOC_IN_RC(ptr_reg));
5060 5095 match(AddP (AddP reg (LShiftL lreg scale)) off);
5061 5096
5062 5097 op_cost(10);
5063 5098 format %{"[$reg + $off + $lreg << $scale]" %}
5064 5099 interface(MEMORY_INTER) %{
5065 5100 base($reg);
5066 5101 index($lreg);
5067 5102 scale($scale);
5068 5103 disp($off);
5069 5104 %}
5070 5105 %}
5071 5106
5072 5107 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
5073 5108 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale)
5074 5109 %{
5075 5110 constraint(ALLOC_IN_RC(ptr_reg));
5076 5111 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5077 5112 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off);
5078 5113
5079 5114 op_cost(10);
5080 5115 format %{"[$reg + $off + $idx << $scale]" %}
5081 5116 interface(MEMORY_INTER) %{
5082 5117 base($reg);
5083 5118 index($idx);
5084 5119 scale($scale);
5085 5120 disp($off);
5086 5121 %}
5087 5122 %}
5088 5123
5089 5124 // Indirect Narrow Oop Plus Offset Operand
5090 5125 // Note: x86 architecture doesn't support "scale * index + offset" without a base
5091 5126 // we can't free r12 even with Universe::narrow_oop_base() == NULL.
5092 5127 operand indCompressedOopOffset(rRegN reg, immL32 off) %{
5093 5128 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0));
5094 5129 constraint(ALLOC_IN_RC(ptr_reg));
5095 5130 match(AddP (DecodeN reg) off);
5096 5131
5097 5132 op_cost(10);
5098 5133 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
5099 5134 interface(MEMORY_INTER) %{
5100 5135 base(0xc); // R12
5101 5136 index($reg);
5102 5137 scale(0x3);
5103 5138 disp($off);
5104 5139 %}
5105 5140 %}
5106 5141
5107 5142 // Indirect Memory Operand
5108 5143 operand indirectNarrow(rRegN reg)
5109 5144 %{
5110 5145 predicate(Universe::narrow_oop_shift() == 0);
5111 5146 constraint(ALLOC_IN_RC(ptr_reg));
5112 5147 match(DecodeN reg);
5113 5148
5114 5149 format %{ "[$reg]" %}
5115 5150 interface(MEMORY_INTER) %{
5116 5151 base($reg);
5117 5152 index(0x4);
5118 5153 scale(0x0);
5119 5154 disp(0x0);
5120 5155 %}
5121 5156 %}
5122 5157
5123 5158 // Indirect Memory Plus Short Offset Operand
5124 5159 operand indOffset8Narrow(rRegN reg, immL8 off)
5125 5160 %{
5126 5161 predicate(Universe::narrow_oop_shift() == 0);
5127 5162 constraint(ALLOC_IN_RC(ptr_reg));
5128 5163 match(AddP (DecodeN reg) off);
5129 5164
5130 5165 format %{ "[$reg + $off (8-bit)]" %}
5131 5166 interface(MEMORY_INTER) %{
5132 5167 base($reg);
5133 5168 index(0x4);
5134 5169 scale(0x0);
5135 5170 disp($off);
5136 5171 %}
5137 5172 %}
5138 5173
5139 5174 // Indirect Memory Plus Long Offset Operand
5140 5175 operand indOffset32Narrow(rRegN reg, immL32 off)
5141 5176 %{
5142 5177 predicate(Universe::narrow_oop_shift() == 0);
5143 5178 constraint(ALLOC_IN_RC(ptr_reg));
5144 5179 match(AddP (DecodeN reg) off);
5145 5180
5146 5181 format %{ "[$reg + $off (32-bit)]" %}
5147 5182 interface(MEMORY_INTER) %{
5148 5183 base($reg);
5149 5184 index(0x4);
5150 5185 scale(0x0);
5151 5186 disp($off);
5152 5187 %}
5153 5188 %}
5154 5189
5155 5190 // Indirect Memory Plus Index Register Plus Offset Operand
5156 5191 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off)
5157 5192 %{
5158 5193 predicate(Universe::narrow_oop_shift() == 0);
5159 5194 constraint(ALLOC_IN_RC(ptr_reg));
5160 5195 match(AddP (AddP (DecodeN reg) lreg) off);
5161 5196
5162 5197 op_cost(10);
5163 5198 format %{"[$reg + $off + $lreg]" %}
5164 5199 interface(MEMORY_INTER) %{
5165 5200 base($reg);
5166 5201 index($lreg);
5167 5202 scale(0x0);
5168 5203 disp($off);
5169 5204 %}
5170 5205 %}
5171 5206
5172 5207 // Indirect Memory Plus Index Register Plus Offset Operand
5173 5208 operand indIndexNarrow(rRegN reg, rRegL lreg)
5174 5209 %{
5175 5210 predicate(Universe::narrow_oop_shift() == 0);
5176 5211 constraint(ALLOC_IN_RC(ptr_reg));
5177 5212 match(AddP (DecodeN reg) lreg);
5178 5213
5179 5214 op_cost(10);
5180 5215 format %{"[$reg + $lreg]" %}
5181 5216 interface(MEMORY_INTER) %{
5182 5217 base($reg);
5183 5218 index($lreg);
5184 5219 scale(0x0);
5185 5220 disp(0x0);
5186 5221 %}
5187 5222 %}
5188 5223
5189 5224 // Indirect Memory Times Scale Plus Index Register
5190 5225 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale)
5191 5226 %{
5192 5227 predicate(Universe::narrow_oop_shift() == 0);
5193 5228 constraint(ALLOC_IN_RC(ptr_reg));
5194 5229 match(AddP (DecodeN reg) (LShiftL lreg scale));
5195 5230
5196 5231 op_cost(10);
5197 5232 format %{"[$reg + $lreg << $scale]" %}
5198 5233 interface(MEMORY_INTER) %{
5199 5234 base($reg);
5200 5235 index($lreg);
5201 5236 scale($scale);
5202 5237 disp(0x0);
5203 5238 %}
5204 5239 %}
5205 5240
5206 5241 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5207 5242 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
5208 5243 %{
5209 5244 predicate(Universe::narrow_oop_shift() == 0);
5210 5245 constraint(ALLOC_IN_RC(ptr_reg));
5211 5246 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
5212 5247
5213 5248 op_cost(10);
5214 5249 format %{"[$reg + $off + $lreg << $scale]" %}
5215 5250 interface(MEMORY_INTER) %{
5216 5251 base($reg);
5217 5252 index($lreg);
5218 5253 scale($scale);
5219 5254 disp($off);
5220 5255 %}
5221 5256 %}
5222 5257
5223 5258 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
5224 5259 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
5225 5260 %{
5226 5261 constraint(ALLOC_IN_RC(ptr_reg));
5227 5262 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5228 5263 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
5229 5264
5230 5265 op_cost(10);
5231 5266 format %{"[$reg + $off + $idx << $scale]" %}
5232 5267 interface(MEMORY_INTER) %{
5233 5268 base($reg);
5234 5269 index($idx);
5235 5270 scale($scale);
5236 5271 disp($off);
5237 5272 %}
5238 5273 %}
5239 5274
5240 5275
5241 5276 //----------Special Memory Operands--------------------------------------------
5242 5277 // Stack Slot Operand - This operand is used for loading and storing temporary
5243 5278 // values on the stack where a match requires a value to
5244 5279 // flow through memory.
5245 5280 operand stackSlotP(sRegP reg)
5246 5281 %{
5247 5282 constraint(ALLOC_IN_RC(stack_slots));
5248 5283 // No match rule because this operand is only generated in matching
5249 5284
5250 5285 format %{ "[$reg]" %}
5251 5286 interface(MEMORY_INTER) %{
5252 5287 base(0x4); // RSP
5253 5288 index(0x4); // No Index
5254 5289 scale(0x0); // No Scale
5255 5290 disp($reg); // Stack Offset
5256 5291 %}
5257 5292 %}
5258 5293
5259 5294 operand stackSlotI(sRegI reg)
5260 5295 %{
5261 5296 constraint(ALLOC_IN_RC(stack_slots));
5262 5297 // No match rule because this operand is only generated in matching
5263 5298
5264 5299 format %{ "[$reg]" %}
5265 5300 interface(MEMORY_INTER) %{
5266 5301 base(0x4); // RSP
5267 5302 index(0x4); // No Index
5268 5303 scale(0x0); // No Scale
5269 5304 disp($reg); // Stack Offset
5270 5305 %}
5271 5306 %}
5272 5307
5273 5308 operand stackSlotF(sRegF reg)
5274 5309 %{
5275 5310 constraint(ALLOC_IN_RC(stack_slots));
5276 5311 // No match rule because this operand is only generated in matching
5277 5312
5278 5313 format %{ "[$reg]" %}
5279 5314 interface(MEMORY_INTER) %{
5280 5315 base(0x4); // RSP
5281 5316 index(0x4); // No Index
5282 5317 scale(0x0); // No Scale
5283 5318 disp($reg); // Stack Offset
5284 5319 %}
5285 5320 %}
5286 5321
5287 5322 operand stackSlotD(sRegD reg)
5288 5323 %{
5289 5324 constraint(ALLOC_IN_RC(stack_slots));
5290 5325 // No match rule because this operand is only generated in matching
5291 5326
5292 5327 format %{ "[$reg]" %}
5293 5328 interface(MEMORY_INTER) %{
5294 5329 base(0x4); // RSP
5295 5330 index(0x4); // No Index
5296 5331 scale(0x0); // No Scale
5297 5332 disp($reg); // Stack Offset
5298 5333 %}
5299 5334 %}
5300 5335 operand stackSlotL(sRegL reg)
5301 5336 %{
5302 5337 constraint(ALLOC_IN_RC(stack_slots));
5303 5338 // No match rule because this operand is only generated in matching
5304 5339
5305 5340 format %{ "[$reg]" %}
5306 5341 interface(MEMORY_INTER) %{
5307 5342 base(0x4); // RSP
5308 5343 index(0x4); // No Index
5309 5344 scale(0x0); // No Scale
5310 5345 disp($reg); // Stack Offset
5311 5346 %}
5312 5347 %}
5313 5348
5314 5349 //----------Conditional Branch Operands----------------------------------------
5315 5350 // Comparison Op - This is the operation of the comparison, and is limited to
5316 5351 // the following set of codes:
5317 5352 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5318 5353 //
5319 5354 // Other attributes of the comparison, such as unsignedness, are specified
5320 5355 // by the comparison instruction that sets a condition code flags register.
5321 5356 // That result is represented by a flags operand whose subtype is appropriate
5322 5357 // to the unsignedness (etc.) of the comparison.
5323 5358 //
5324 5359 // Later, the instruction which matches both the Comparison Op (a Bool) and
5325 5360 // the flags (produced by the Cmp) specifies the coding of the comparison op
5326 5361 // by matching a specific subtype of Bool operand below, such as cmpOpU.
5327 5362
5328 5363 // Comparision Code
5329 5364 operand cmpOp()
5330 5365 %{
5331 5366 match(Bool);
5332 5367
5333 5368 format %{ "" %}
5334 5369 interface(COND_INTER) %{
5335 5370 equal(0x4, "e");
5336 5371 not_equal(0x5, "ne");
5337 5372 less(0xC, "l");
5338 5373 greater_equal(0xD, "ge");
5339 5374 less_equal(0xE, "le");
5340 5375 greater(0xF, "g");
5341 5376 %}
5342 5377 %}
5343 5378
5344 5379 // Comparison Code, unsigned compare. Used by FP also, with
5345 5380 // C2 (unordered) turned into GT or LT already. The other bits
5346 5381 // C0 and C3 are turned into Carry & Zero flags.
5347 5382 operand cmpOpU()
5348 5383 %{
5349 5384 match(Bool);
5350 5385
5351 5386 format %{ "" %}
5352 5387 interface(COND_INTER) %{
5353 5388 equal(0x4, "e");
5354 5389 not_equal(0x5, "ne");
5355 5390 less(0x2, "b");
5356 5391 greater_equal(0x3, "nb");
5357 5392 less_equal(0x6, "be");
5358 5393 greater(0x7, "nbe");
5359 5394 %}
5360 5395 %}
5361 5396
5362 5397
5363 5398 // Floating comparisons that don't require any fixup for the unordered case
5364 5399 operand cmpOpUCF() %{
5365 5400 match(Bool);
5366 5401 predicate(n->as_Bool()->_test._test == BoolTest::lt ||
5367 5402 n->as_Bool()->_test._test == BoolTest::ge ||
5368 5403 n->as_Bool()->_test._test == BoolTest::le ||
5369 5404 n->as_Bool()->_test._test == BoolTest::gt);
5370 5405 format %{ "" %}
5371 5406 interface(COND_INTER) %{
5372 5407 equal(0x4, "e");
5373 5408 not_equal(0x5, "ne");
5374 5409 less(0x2, "b");
5375 5410 greater_equal(0x3, "nb");
5376 5411 less_equal(0x6, "be");
5377 5412 greater(0x7, "nbe");
5378 5413 %}
5379 5414 %}
5380 5415
5381 5416
5382 5417 // Floating comparisons that can be fixed up with extra conditional jumps
5383 5418 operand cmpOpUCF2() %{
5384 5419 match(Bool);
5385 5420 predicate(n->as_Bool()->_test._test == BoolTest::ne ||
5386 5421 n->as_Bool()->_test._test == BoolTest::eq);
5387 5422 format %{ "" %}
5388 5423 interface(COND_INTER) %{
5389 5424 equal(0x4, "e");
5390 5425 not_equal(0x5, "ne");
5391 5426 less(0x2, "b");
5392 5427 greater_equal(0x3, "nb");
5393 5428 less_equal(0x6, "be");
5394 5429 greater(0x7, "nbe");
5395 5430 %}
5396 5431 %}
5397 5432
5398 5433
5399 5434 //----------OPERAND CLASSES----------------------------------------------------
5400 5435 // Operand Classes are groups of operands that are used as to simplify
5401 5436 // instruction definitions by not requiring the AD writer to specify separate
5402 5437 // instructions for every form of operand when the instruction accepts
5403 5438 // multiple operand types with the same basic encoding and format. The classic
5404 5439 // case of this is memory operands.
5405 5440
5406 5441 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
5407 5442 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
5408 5443 indCompressedOopOffset,
5409 5444 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
5410 5445 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
5411 5446 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow);
5412 5447
5413 5448 //----------PIPELINE-----------------------------------------------------------
5414 5449 // Rules which define the behavior of the target architectures pipeline.
5415 5450 pipeline %{
5416 5451
5417 5452 //----------ATTRIBUTES---------------------------------------------------------
5418 5453 attributes %{
5419 5454 variable_size_instructions; // Fixed size instructions
5420 5455 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
5421 5456 instruction_unit_size = 1; // An instruction is 1 bytes long
5422 5457 instruction_fetch_unit_size = 16; // The processor fetches one line
5423 5458 instruction_fetch_units = 1; // of 16 bytes
5424 5459
5425 5460 // List of nop instructions
5426 5461 nops( MachNop );
5427 5462 %}
5428 5463
5429 5464 //----------RESOURCES----------------------------------------------------------
5430 5465 // Resources are the functional units available to the machine
5431 5466
5432 5467 // Generic P2/P3 pipeline
5433 5468 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of
5434 5469 // 3 instructions decoded per cycle.
5435 5470 // 2 load/store ops per cycle, 1 branch, 1 FPU,
5436 5471 // 3 ALU op, only ALU0 handles mul instructions.
5437 5472 resources( D0, D1, D2, DECODE = D0 | D1 | D2,
5438 5473 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2,
5439 5474 BR, FPU,
5440 5475 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2);
5441 5476
5442 5477 //----------PIPELINE DESCRIPTION-----------------------------------------------
5443 5478 // Pipeline Description specifies the stages in the machine's pipeline
5444 5479
5445 5480 // Generic P2/P3 pipeline
5446 5481 pipe_desc(S0, S1, S2, S3, S4, S5);
5447 5482
5448 5483 //----------PIPELINE CLASSES---------------------------------------------------
5449 5484 // Pipeline Classes describe the stages in which input and output are
5450 5485 // referenced by the hardware pipeline.
5451 5486
5452 5487 // Naming convention: ialu or fpu
5453 5488 // Then: _reg
5454 5489 // Then: _reg if there is a 2nd register
5455 5490 // Then: _long if it's a pair of instructions implementing a long
5456 5491 // Then: _fat if it requires the big decoder
5457 5492 // Or: _mem if it requires the big decoder and a memory unit.
5458 5493
5459 5494 // Integer ALU reg operation
5460 5495 pipe_class ialu_reg(rRegI dst)
5461 5496 %{
5462 5497 single_instruction;
5463 5498 dst : S4(write);
5464 5499 dst : S3(read);
5465 5500 DECODE : S0; // any decoder
5466 5501 ALU : S3; // any alu
5467 5502 %}
5468 5503
5469 5504 // Long ALU reg operation
5470 5505 pipe_class ialu_reg_long(rRegL dst)
5471 5506 %{
5472 5507 instruction_count(2);
5473 5508 dst : S4(write);
5474 5509 dst : S3(read);
5475 5510 DECODE : S0(2); // any 2 decoders
5476 5511 ALU : S3(2); // both alus
5477 5512 %}
5478 5513
5479 5514 // Integer ALU reg operation using big decoder
5480 5515 pipe_class ialu_reg_fat(rRegI dst)
5481 5516 %{
5482 5517 single_instruction;
5483 5518 dst : S4(write);
5484 5519 dst : S3(read);
5485 5520 D0 : S0; // big decoder only
5486 5521 ALU : S3; // any alu
5487 5522 %}
5488 5523
5489 5524 // Long ALU reg operation using big decoder
5490 5525 pipe_class ialu_reg_long_fat(rRegL dst)
5491 5526 %{
5492 5527 instruction_count(2);
5493 5528 dst : S4(write);
5494 5529 dst : S3(read);
5495 5530 D0 : S0(2); // big decoder only; twice
5496 5531 ALU : S3(2); // any 2 alus
5497 5532 %}
5498 5533
5499 5534 // Integer ALU reg-reg operation
5500 5535 pipe_class ialu_reg_reg(rRegI dst, rRegI src)
5501 5536 %{
5502 5537 single_instruction;
5503 5538 dst : S4(write);
5504 5539 src : S3(read);
5505 5540 DECODE : S0; // any decoder
5506 5541 ALU : S3; // any alu
5507 5542 %}
5508 5543
5509 5544 // Long ALU reg-reg operation
5510 5545 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src)
5511 5546 %{
5512 5547 instruction_count(2);
5513 5548 dst : S4(write);
5514 5549 src : S3(read);
5515 5550 DECODE : S0(2); // any 2 decoders
5516 5551 ALU : S3(2); // both alus
5517 5552 %}
5518 5553
5519 5554 // Integer ALU reg-reg operation
5520 5555 pipe_class ialu_reg_reg_fat(rRegI dst, memory src)
5521 5556 %{
5522 5557 single_instruction;
5523 5558 dst : S4(write);
5524 5559 src : S3(read);
5525 5560 D0 : S0; // big decoder only
5526 5561 ALU : S3; // any alu
5527 5562 %}
5528 5563
5529 5564 // Long ALU reg-reg operation
5530 5565 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src)
5531 5566 %{
5532 5567 instruction_count(2);
5533 5568 dst : S4(write);
5534 5569 src : S3(read);
5535 5570 D0 : S0(2); // big decoder only; twice
5536 5571 ALU : S3(2); // both alus
5537 5572 %}
5538 5573
5539 5574 // Integer ALU reg-mem operation
5540 5575 pipe_class ialu_reg_mem(rRegI dst, memory mem)
5541 5576 %{
5542 5577 single_instruction;
5543 5578 dst : S5(write);
5544 5579 mem : S3(read);
5545 5580 D0 : S0; // big decoder only
5546 5581 ALU : S4; // any alu
5547 5582 MEM : S3; // any mem
5548 5583 %}
5549 5584
5550 5585 // Integer mem operation (prefetch)
5551 5586 pipe_class ialu_mem(memory mem)
5552 5587 %{
5553 5588 single_instruction;
5554 5589 mem : S3(read);
5555 5590 D0 : S0; // big decoder only
5556 5591 MEM : S3; // any mem
5557 5592 %}
5558 5593
5559 5594 // Integer Store to Memory
5560 5595 pipe_class ialu_mem_reg(memory mem, rRegI src)
5561 5596 %{
5562 5597 single_instruction;
5563 5598 mem : S3(read);
5564 5599 src : S5(read);
5565 5600 D0 : S0; // big decoder only
5566 5601 ALU : S4; // any alu
5567 5602 MEM : S3;
5568 5603 %}
5569 5604
5570 5605 // // Long Store to Memory
5571 5606 // pipe_class ialu_mem_long_reg(memory mem, rRegL src)
5572 5607 // %{
5573 5608 // instruction_count(2);
5574 5609 // mem : S3(read);
5575 5610 // src : S5(read);
5576 5611 // D0 : S0(2); // big decoder only; twice
5577 5612 // ALU : S4(2); // any 2 alus
5578 5613 // MEM : S3(2); // Both mems
5579 5614 // %}
5580 5615
5581 5616 // Integer Store to Memory
5582 5617 pipe_class ialu_mem_imm(memory mem)
5583 5618 %{
5584 5619 single_instruction;
5585 5620 mem : S3(read);
5586 5621 D0 : S0; // big decoder only
5587 5622 ALU : S4; // any alu
5588 5623 MEM : S3;
5589 5624 %}
5590 5625
5591 5626 // Integer ALU0 reg-reg operation
5592 5627 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src)
5593 5628 %{
5594 5629 single_instruction;
5595 5630 dst : S4(write);
5596 5631 src : S3(read);
5597 5632 D0 : S0; // Big decoder only
5598 5633 ALU0 : S3; // only alu0
5599 5634 %}
5600 5635
5601 5636 // Integer ALU0 reg-mem operation
5602 5637 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem)
5603 5638 %{
5604 5639 single_instruction;
5605 5640 dst : S5(write);
5606 5641 mem : S3(read);
5607 5642 D0 : S0; // big decoder only
5608 5643 ALU0 : S4; // ALU0 only
5609 5644 MEM : S3; // any mem
5610 5645 %}
5611 5646
5612 5647 // Integer ALU reg-reg operation
5613 5648 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2)
5614 5649 %{
5615 5650 single_instruction;
5616 5651 cr : S4(write);
5617 5652 src1 : S3(read);
5618 5653 src2 : S3(read);
5619 5654 DECODE : S0; // any decoder
5620 5655 ALU : S3; // any alu
5621 5656 %}
5622 5657
5623 5658 // Integer ALU reg-imm operation
5624 5659 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1)
5625 5660 %{
5626 5661 single_instruction;
5627 5662 cr : S4(write);
5628 5663 src1 : S3(read);
5629 5664 DECODE : S0; // any decoder
5630 5665 ALU : S3; // any alu
5631 5666 %}
5632 5667
5633 5668 // Integer ALU reg-mem operation
5634 5669 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2)
5635 5670 %{
5636 5671 single_instruction;
5637 5672 cr : S4(write);
5638 5673 src1 : S3(read);
5639 5674 src2 : S3(read);
5640 5675 D0 : S0; // big decoder only
5641 5676 ALU : S4; // any alu
5642 5677 MEM : S3;
5643 5678 %}
5644 5679
5645 5680 // Conditional move reg-reg
5646 5681 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y)
5647 5682 %{
5648 5683 instruction_count(4);
5649 5684 y : S4(read);
5650 5685 q : S3(read);
5651 5686 p : S3(read);
5652 5687 DECODE : S0(4); // any decoder
5653 5688 %}
5654 5689
5655 5690 // Conditional move reg-reg
5656 5691 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr)
5657 5692 %{
5658 5693 single_instruction;
5659 5694 dst : S4(write);
5660 5695 src : S3(read);
5661 5696 cr : S3(read);
5662 5697 DECODE : S0; // any decoder
5663 5698 %}
5664 5699
5665 5700 // Conditional move reg-mem
5666 5701 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src)
5667 5702 %{
5668 5703 single_instruction;
5669 5704 dst : S4(write);
5670 5705 src : S3(read);
5671 5706 cr : S3(read);
5672 5707 DECODE : S0; // any decoder
5673 5708 MEM : S3;
5674 5709 %}
5675 5710
5676 5711 // Conditional move reg-reg long
5677 5712 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src)
5678 5713 %{
5679 5714 single_instruction;
5680 5715 dst : S4(write);
5681 5716 src : S3(read);
5682 5717 cr : S3(read);
5683 5718 DECODE : S0(2); // any 2 decoders
5684 5719 %}
5685 5720
5686 5721 // XXX
5687 5722 // // Conditional move double reg-reg
5688 5723 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src)
5689 5724 // %{
5690 5725 // single_instruction;
5691 5726 // dst : S4(write);
5692 5727 // src : S3(read);
5693 5728 // cr : S3(read);
5694 5729 // DECODE : S0; // any decoder
5695 5730 // %}
5696 5731
5697 5732 // Float reg-reg operation
5698 5733 pipe_class fpu_reg(regD dst)
5699 5734 %{
5700 5735 instruction_count(2);
5701 5736 dst : S3(read);
5702 5737 DECODE : S0(2); // any 2 decoders
5703 5738 FPU : S3;
5704 5739 %}
5705 5740
5706 5741 // Float reg-reg operation
5707 5742 pipe_class fpu_reg_reg(regD dst, regD src)
5708 5743 %{
5709 5744 instruction_count(2);
5710 5745 dst : S4(write);
5711 5746 src : S3(read);
5712 5747 DECODE : S0(2); // any 2 decoders
5713 5748 FPU : S3;
5714 5749 %}
5715 5750
5716 5751 // Float reg-reg operation
5717 5752 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2)
5718 5753 %{
5719 5754 instruction_count(3);
5720 5755 dst : S4(write);
5721 5756 src1 : S3(read);
5722 5757 src2 : S3(read);
5723 5758 DECODE : S0(3); // any 3 decoders
5724 5759 FPU : S3(2);
5725 5760 %}
5726 5761
5727 5762 // Float reg-reg operation
5728 5763 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3)
5729 5764 %{
5730 5765 instruction_count(4);
5731 5766 dst : S4(write);
5732 5767 src1 : S3(read);
5733 5768 src2 : S3(read);
5734 5769 src3 : S3(read);
5735 5770 DECODE : S0(4); // any 3 decoders
5736 5771 FPU : S3(2);
5737 5772 %}
5738 5773
5739 5774 // Float reg-reg operation
5740 5775 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3)
5741 5776 %{
5742 5777 instruction_count(4);
5743 5778 dst : S4(write);
5744 5779 src1 : S3(read);
5745 5780 src2 : S3(read);
5746 5781 src3 : S3(read);
5747 5782 DECODE : S1(3); // any 3 decoders
5748 5783 D0 : S0; // Big decoder only
5749 5784 FPU : S3(2);
5750 5785 MEM : S3;
5751 5786 %}
5752 5787
5753 5788 // Float reg-mem operation
5754 5789 pipe_class fpu_reg_mem(regD dst, memory mem)
5755 5790 %{
5756 5791 instruction_count(2);
5757 5792 dst : S5(write);
5758 5793 mem : S3(read);
5759 5794 D0 : S0; // big decoder only
5760 5795 DECODE : S1; // any decoder for FPU POP
5761 5796 FPU : S4;
5762 5797 MEM : S3; // any mem
5763 5798 %}
5764 5799
5765 5800 // Float reg-mem operation
5766 5801 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem)
5767 5802 %{
5768 5803 instruction_count(3);
5769 5804 dst : S5(write);
5770 5805 src1 : S3(read);
5771 5806 mem : S3(read);
5772 5807 D0 : S0; // big decoder only
5773 5808 DECODE : S1(2); // any decoder for FPU POP
5774 5809 FPU : S4;
5775 5810 MEM : S3; // any mem
5776 5811 %}
5777 5812
5778 5813 // Float mem-reg operation
5779 5814 pipe_class fpu_mem_reg(memory mem, regD src)
5780 5815 %{
5781 5816 instruction_count(2);
5782 5817 src : S5(read);
5783 5818 mem : S3(read);
5784 5819 DECODE : S0; // any decoder for FPU PUSH
5785 5820 D0 : S1; // big decoder only
5786 5821 FPU : S4;
5787 5822 MEM : S3; // any mem
5788 5823 %}
5789 5824
5790 5825 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2)
5791 5826 %{
5792 5827 instruction_count(3);
5793 5828 src1 : S3(read);
5794 5829 src2 : S3(read);
5795 5830 mem : S3(read);
5796 5831 DECODE : S0(2); // any decoder for FPU PUSH
5797 5832 D0 : S1; // big decoder only
5798 5833 FPU : S4;
5799 5834 MEM : S3; // any mem
5800 5835 %}
5801 5836
5802 5837 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2)
5803 5838 %{
5804 5839 instruction_count(3);
5805 5840 src1 : S3(read);
5806 5841 src2 : S3(read);
5807 5842 mem : S4(read);
5808 5843 DECODE : S0; // any decoder for FPU PUSH
5809 5844 D0 : S0(2); // big decoder only
5810 5845 FPU : S4;
5811 5846 MEM : S3(2); // any mem
5812 5847 %}
5813 5848
5814 5849 pipe_class fpu_mem_mem(memory dst, memory src1)
5815 5850 %{
5816 5851 instruction_count(2);
5817 5852 src1 : S3(read);
5818 5853 dst : S4(read);
5819 5854 D0 : S0(2); // big decoder only
5820 5855 MEM : S3(2); // any mem
5821 5856 %}
5822 5857
5823 5858 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2)
5824 5859 %{
5825 5860 instruction_count(3);
5826 5861 src1 : S3(read);
5827 5862 src2 : S3(read);
5828 5863 dst : S4(read);
5829 5864 D0 : S0(3); // big decoder only
5830 5865 FPU : S4;
5831 5866 MEM : S3(3); // any mem
5832 5867 %}
5833 5868
5834 5869 pipe_class fpu_mem_reg_con(memory mem, regD src1)
5835 5870 %{
5836 5871 instruction_count(3);
5837 5872 src1 : S4(read);
5838 5873 mem : S4(read);
5839 5874 DECODE : S0; // any decoder for FPU PUSH
5840 5875 D0 : S0(2); // big decoder only
5841 5876 FPU : S4;
5842 5877 MEM : S3(2); // any mem
5843 5878 %}
5844 5879
5845 5880 // Float load constant
5846 5881 pipe_class fpu_reg_con(regD dst)
5847 5882 %{
5848 5883 instruction_count(2);
5849 5884 dst : S5(write);
5850 5885 D0 : S0; // big decoder only for the load
5851 5886 DECODE : S1; // any decoder for FPU POP
5852 5887 FPU : S4;
5853 5888 MEM : S3; // any mem
5854 5889 %}
5855 5890
5856 5891 // Float load constant
5857 5892 pipe_class fpu_reg_reg_con(regD dst, regD src)
5858 5893 %{
5859 5894 instruction_count(3);
5860 5895 dst : S5(write);
5861 5896 src : S3(read);
5862 5897 D0 : S0; // big decoder only for the load
5863 5898 DECODE : S1(2); // any decoder for FPU POP
5864 5899 FPU : S4;
5865 5900 MEM : S3; // any mem
5866 5901 %}
5867 5902
5868 5903 // UnConditional branch
5869 5904 pipe_class pipe_jmp(label labl)
5870 5905 %{
5871 5906 single_instruction;
5872 5907 BR : S3;
5873 5908 %}
5874 5909
5875 5910 // Conditional branch
5876 5911 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl)
5877 5912 %{
5878 5913 single_instruction;
5879 5914 cr : S1(read);
5880 5915 BR : S3;
5881 5916 %}
5882 5917
5883 5918 // Allocation idiom
5884 5919 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr)
5885 5920 %{
5886 5921 instruction_count(1); force_serialization;
5887 5922 fixed_latency(6);
5888 5923 heap_ptr : S3(read);
5889 5924 DECODE : S0(3);
5890 5925 D0 : S2;
5891 5926 MEM : S3;
5892 5927 ALU : S3(2);
5893 5928 dst : S5(write);
5894 5929 BR : S5;
5895 5930 %}
5896 5931
5897 5932 // Generic big/slow expanded idiom
5898 5933 pipe_class pipe_slow()
5899 5934 %{
5900 5935 instruction_count(10); multiple_bundles; force_serialization;
5901 5936 fixed_latency(100);
5902 5937 D0 : S0(2);
5903 5938 MEM : S3(2);
5904 5939 %}
5905 5940
5906 5941 // The real do-nothing guy
5907 5942 pipe_class empty()
5908 5943 %{
5909 5944 instruction_count(0);
5910 5945 %}
5911 5946
5912 5947 // Define the class for the Nop node
5913 5948 define
5914 5949 %{
5915 5950 MachNop = empty;
5916 5951 %}
5917 5952
5918 5953 %}
5919 5954
5920 5955 //----------INSTRUCTIONS-------------------------------------------------------
5921 5956 //
5922 5957 // match -- States which machine-independent subtree may be replaced
5923 5958 // by this instruction.
5924 5959 // ins_cost -- The estimated cost of this instruction is used by instruction
5925 5960 // selection to identify a minimum cost tree of machine
5926 5961 // instructions that matches a tree of machine-independent
5927 5962 // instructions.
5928 5963 // format -- A string providing the disassembly for this instruction.
5929 5964 // The value of an instruction's operand may be inserted
5930 5965 // by referring to it with a '$' prefix.
5931 5966 // opcode -- Three instruction opcodes may be provided. These are referred
5932 5967 // to within an encode class as $primary, $secondary, and $tertiary
5933 5968 // rrspectively. The primary opcode is commonly used to
5934 5969 // indicate the type of machine instruction, while secondary
5935 5970 // and tertiary are often used for prefix options or addressing
5936 5971 // modes.
5937 5972 // ins_encode -- A list of encode classes with parameters. The encode class
5938 5973 // name must have been defined in an 'enc_class' specification
5939 5974 // in the encode section of the architecture description.
5940 5975
5941 5976
5942 5977 //----------Load/Store/Move Instructions---------------------------------------
5943 5978 //----------Load Instructions--------------------------------------------------
5944 5979
5945 5980 // Load Byte (8 bit signed)
5946 5981 instruct loadB(rRegI dst, memory mem)
5947 5982 %{
5948 5983 match(Set dst (LoadB mem));
5949 5984
5950 5985 ins_cost(125);
5951 5986 format %{ "movsbl $dst, $mem\t# byte" %}
5952 5987
5953 5988 ins_encode %{
5954 5989 __ movsbl($dst$$Register, $mem$$Address);
5955 5990 %}
5956 5991
5957 5992 ins_pipe(ialu_reg_mem);
5958 5993 %}
5959 5994
5960 5995 // Load Byte (8 bit signed) into Long Register
5961 5996 instruct loadB2L(rRegL dst, memory mem)
5962 5997 %{
5963 5998 match(Set dst (ConvI2L (LoadB mem)));
5964 5999
5965 6000 ins_cost(125);
5966 6001 format %{ "movsbq $dst, $mem\t# byte -> long" %}
5967 6002
5968 6003 ins_encode %{
5969 6004 __ movsbq($dst$$Register, $mem$$Address);
5970 6005 %}
5971 6006
5972 6007 ins_pipe(ialu_reg_mem);
5973 6008 %}
5974 6009
5975 6010 // Load Unsigned Byte (8 bit UNsigned)
5976 6011 instruct loadUB(rRegI dst, memory mem)
5977 6012 %{
5978 6013 match(Set dst (LoadUB mem));
5979 6014
5980 6015 ins_cost(125);
5981 6016 format %{ "movzbl $dst, $mem\t# ubyte" %}
5982 6017
5983 6018 ins_encode %{
5984 6019 __ movzbl($dst$$Register, $mem$$Address);
5985 6020 %}
5986 6021
5987 6022 ins_pipe(ialu_reg_mem);
5988 6023 %}
5989 6024
5990 6025 // Load Unsigned Byte (8 bit UNsigned) into Long Register
5991 6026 instruct loadUB2L(rRegL dst, memory mem)
5992 6027 %{
5993 6028 match(Set dst (ConvI2L (LoadUB mem)));
5994 6029
5995 6030 ins_cost(125);
5996 6031 format %{ "movzbq $dst, $mem\t# ubyte -> long" %}
5997 6032
5998 6033 ins_encode %{
5999 6034 __ movzbq($dst$$Register, $mem$$Address);
6000 6035 %}
6001 6036
6002 6037 ins_pipe(ialu_reg_mem);
6003 6038 %}
6004 6039
6005 6040 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register
6006 6041 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{
6007 6042 match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
6008 6043 effect(KILL cr);
6009 6044
6010 6045 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t"
6011 6046 "andl $dst, $mask" %}
6012 6047 ins_encode %{
6013 6048 Register Rdst = $dst$$Register;
6014 6049 __ movzbq(Rdst, $mem$$Address);
6015 6050 __ andl(Rdst, $mask$$constant);
6016 6051 %}
6017 6052 ins_pipe(ialu_reg_mem);
6018 6053 %}
6019 6054
6020 6055 // Load Short (16 bit signed)
6021 6056 instruct loadS(rRegI dst, memory mem)
6022 6057 %{
6023 6058 match(Set dst (LoadS mem));
6024 6059
6025 6060 ins_cost(125);
6026 6061 format %{ "movswl $dst, $mem\t# short" %}
6027 6062
6028 6063 ins_encode %{
6029 6064 __ movswl($dst$$Register, $mem$$Address);
6030 6065 %}
6031 6066
6032 6067 ins_pipe(ialu_reg_mem);
6033 6068 %}
6034 6069
6035 6070 // Load Short (16 bit signed) to Byte (8 bit signed)
6036 6071 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
6037 6072 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
6038 6073
6039 6074 ins_cost(125);
6040 6075 format %{ "movsbl $dst, $mem\t# short -> byte" %}
6041 6076 ins_encode %{
6042 6077 __ movsbl($dst$$Register, $mem$$Address);
6043 6078 %}
6044 6079 ins_pipe(ialu_reg_mem);
6045 6080 %}
6046 6081
6047 6082 // Load Short (16 bit signed) into Long Register
6048 6083 instruct loadS2L(rRegL dst, memory mem)
6049 6084 %{
6050 6085 match(Set dst (ConvI2L (LoadS mem)));
6051 6086
6052 6087 ins_cost(125);
6053 6088 format %{ "movswq $dst, $mem\t# short -> long" %}
6054 6089
6055 6090 ins_encode %{
6056 6091 __ movswq($dst$$Register, $mem$$Address);
6057 6092 %}
6058 6093
6059 6094 ins_pipe(ialu_reg_mem);
6060 6095 %}
6061 6096
6062 6097 // Load Unsigned Short/Char (16 bit UNsigned)
6063 6098 instruct loadUS(rRegI dst, memory mem)
6064 6099 %{
6065 6100 match(Set dst (LoadUS mem));
6066 6101
6067 6102 ins_cost(125);
6068 6103 format %{ "movzwl $dst, $mem\t# ushort/char" %}
6069 6104
6070 6105 ins_encode %{
6071 6106 __ movzwl($dst$$Register, $mem$$Address);
6072 6107 %}
6073 6108
6074 6109 ins_pipe(ialu_reg_mem);
6075 6110 %}
6076 6111
6077 6112 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
6078 6113 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
6079 6114 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
6080 6115
6081 6116 ins_cost(125);
6082 6117 format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
6083 6118 ins_encode %{
6084 6119 __ movsbl($dst$$Register, $mem$$Address);
6085 6120 %}
6086 6121 ins_pipe(ialu_reg_mem);
6087 6122 %}
6088 6123
6089 6124 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
6090 6125 instruct loadUS2L(rRegL dst, memory mem)
6091 6126 %{
6092 6127 match(Set dst (ConvI2L (LoadUS mem)));
6093 6128
6094 6129 ins_cost(125);
6095 6130 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %}
6096 6131
6097 6132 ins_encode %{
6098 6133 __ movzwq($dst$$Register, $mem$$Address);
6099 6134 %}
6100 6135
6101 6136 ins_pipe(ialu_reg_mem);
6102 6137 %}
6103 6138
6104 6139 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register
6105 6140 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
6106 6141 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
6107 6142
6108 6143 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %}
6109 6144 ins_encode %{
6110 6145 __ movzbq($dst$$Register, $mem$$Address);
6111 6146 %}
6112 6147 ins_pipe(ialu_reg_mem);
6113 6148 %}
6114 6149
6115 6150 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register
6116 6151 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{
6117 6152 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
6118 6153 effect(KILL cr);
6119 6154
6120 6155 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t"
6121 6156 "andl $dst, $mask" %}
6122 6157 ins_encode %{
6123 6158 Register Rdst = $dst$$Register;
6124 6159 __ movzwq(Rdst, $mem$$Address);
6125 6160 __ andl(Rdst, $mask$$constant);
6126 6161 %}
6127 6162 ins_pipe(ialu_reg_mem);
6128 6163 %}
6129 6164
6130 6165 // Load Integer
6131 6166 instruct loadI(rRegI dst, memory mem)
6132 6167 %{
6133 6168 match(Set dst (LoadI mem));
6134 6169
6135 6170 ins_cost(125);
6136 6171 format %{ "movl $dst, $mem\t# int" %}
6137 6172
6138 6173 ins_encode %{
6139 6174 __ movl($dst$$Register, $mem$$Address);
6140 6175 %}
6141 6176
6142 6177 ins_pipe(ialu_reg_mem);
6143 6178 %}
6144 6179
6145 6180 // Load Integer (32 bit signed) to Byte (8 bit signed)
6146 6181 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
6147 6182 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
6148 6183
6149 6184 ins_cost(125);
6150 6185 format %{ "movsbl $dst, $mem\t# int -> byte" %}
6151 6186 ins_encode %{
6152 6187 __ movsbl($dst$$Register, $mem$$Address);
6153 6188 %}
6154 6189 ins_pipe(ialu_reg_mem);
6155 6190 %}
6156 6191
6157 6192 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
6158 6193 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
6159 6194 match(Set dst (AndI (LoadI mem) mask));
6160 6195
6161 6196 ins_cost(125);
6162 6197 format %{ "movzbl $dst, $mem\t# int -> ubyte" %}
6163 6198 ins_encode %{
6164 6199 __ movzbl($dst$$Register, $mem$$Address);
6165 6200 %}
6166 6201 ins_pipe(ialu_reg_mem);
6167 6202 %}
6168 6203
6169 6204 // Load Integer (32 bit signed) to Short (16 bit signed)
6170 6205 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
6171 6206 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
6172 6207
6173 6208 ins_cost(125);
6174 6209 format %{ "movswl $dst, $mem\t# int -> short" %}
6175 6210 ins_encode %{
6176 6211 __ movswl($dst$$Register, $mem$$Address);
6177 6212 %}
6178 6213 ins_pipe(ialu_reg_mem);
6179 6214 %}
6180 6215
6181 6216 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
6182 6217 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
6183 6218 match(Set dst (AndI (LoadI mem) mask));
6184 6219
6185 6220 ins_cost(125);
6186 6221 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %}
6187 6222 ins_encode %{
6188 6223 __ movzwl($dst$$Register, $mem$$Address);
6189 6224 %}
6190 6225 ins_pipe(ialu_reg_mem);
6191 6226 %}
6192 6227
6193 6228 // Load Integer into Long Register
6194 6229 instruct loadI2L(rRegL dst, memory mem)
6195 6230 %{
6196 6231 match(Set dst (ConvI2L (LoadI mem)));
6197 6232
6198 6233 ins_cost(125);
6199 6234 format %{ "movslq $dst, $mem\t# int -> long" %}
6200 6235
6201 6236 ins_encode %{
6202 6237 __ movslq($dst$$Register, $mem$$Address);
6203 6238 %}
6204 6239
6205 6240 ins_pipe(ialu_reg_mem);
6206 6241 %}
6207 6242
6208 6243 // Load Integer with mask 0xFF into Long Register
6209 6244 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
6210 6245 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
6211 6246
6212 6247 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %}
6213 6248 ins_encode %{
6214 6249 __ movzbq($dst$$Register, $mem$$Address);
6215 6250 %}
6216 6251 ins_pipe(ialu_reg_mem);
6217 6252 %}
6218 6253
6219 6254 // Load Integer with mask 0xFFFF into Long Register
6220 6255 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{
6221 6256 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
6222 6257
6223 6258 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %}
6224 6259 ins_encode %{
6225 6260 __ movzwq($dst$$Register, $mem$$Address);
6226 6261 %}
6227 6262 ins_pipe(ialu_reg_mem);
6228 6263 %}
6229 6264
6230 6265 // Load Integer with a 32-bit mask into Long Register
6231 6266 instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
6232 6267 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
6233 6268 effect(KILL cr);
6234 6269
6235 6270 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t"
6236 6271 "andl $dst, $mask" %}
6237 6272 ins_encode %{
6238 6273 Register Rdst = $dst$$Register;
6239 6274 __ movl(Rdst, $mem$$Address);
6240 6275 __ andl(Rdst, $mask$$constant);
6241 6276 %}
6242 6277 ins_pipe(ialu_reg_mem);
6243 6278 %}
6244 6279
6245 6280 // Load Unsigned Integer into Long Register
6246 6281 instruct loadUI2L(rRegL dst, memory mem)
6247 6282 %{
6248 6283 match(Set dst (LoadUI2L mem));
6249 6284
6250 6285 ins_cost(125);
6251 6286 format %{ "movl $dst, $mem\t# uint -> long" %}
6252 6287
6253 6288 ins_encode %{
6254 6289 __ movl($dst$$Register, $mem$$Address);
6255 6290 %}
6256 6291
6257 6292 ins_pipe(ialu_reg_mem);
6258 6293 %}
6259 6294
6260 6295 // Load Long
6261 6296 instruct loadL(rRegL dst, memory mem)
6262 6297 %{
6263 6298 match(Set dst (LoadL mem));
6264 6299
6265 6300 ins_cost(125);
6266 6301 format %{ "movq $dst, $mem\t# long" %}
6267 6302
6268 6303 ins_encode %{
6269 6304 __ movq($dst$$Register, $mem$$Address);
6270 6305 %}
6271 6306
6272 6307 ins_pipe(ialu_reg_mem); // XXX
6273 6308 %}
6274 6309
6275 6310 // Load Range
6276 6311 instruct loadRange(rRegI dst, memory mem)
6277 6312 %{
6278 6313 match(Set dst (LoadRange mem));
6279 6314
6280 6315 ins_cost(125); // XXX
6281 6316 format %{ "movl $dst, $mem\t# range" %}
6282 6317 opcode(0x8B);
6283 6318 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem));
6284 6319 ins_pipe(ialu_reg_mem);
6285 6320 %}
6286 6321
6287 6322 // Load Pointer
6288 6323 instruct loadP(rRegP dst, memory mem)
6289 6324 %{
6290 6325 match(Set dst (LoadP mem));
6291 6326
6292 6327 ins_cost(125); // XXX
6293 6328 format %{ "movq $dst, $mem\t# ptr" %}
6294 6329 opcode(0x8B);
6295 6330 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6296 6331 ins_pipe(ialu_reg_mem); // XXX
6297 6332 %}
6298 6333
6299 6334 // Load Compressed Pointer
6300 6335 instruct loadN(rRegN dst, memory mem)
6301 6336 %{
6302 6337 match(Set dst (LoadN mem));
6303 6338
6304 6339 ins_cost(125); // XXX
6305 6340 format %{ "movl $dst, $mem\t# compressed ptr" %}
6306 6341 ins_encode %{
6307 6342 __ movl($dst$$Register, $mem$$Address);
6308 6343 %}
6309 6344 ins_pipe(ialu_reg_mem); // XXX
6310 6345 %}
6311 6346
6312 6347
6313 6348 // Load Klass Pointer
6314 6349 instruct loadKlass(rRegP dst, memory mem)
6315 6350 %{
6316 6351 match(Set dst (LoadKlass mem));
6317 6352
6318 6353 ins_cost(125); // XXX
6319 6354 format %{ "movq $dst, $mem\t# class" %}
6320 6355 opcode(0x8B);
6321 6356 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6322 6357 ins_pipe(ialu_reg_mem); // XXX
6323 6358 %}
6324 6359
6325 6360 // Load narrow Klass Pointer
6326 6361 instruct loadNKlass(rRegN dst, memory mem)
6327 6362 %{
6328 6363 match(Set dst (LoadNKlass mem));
6329 6364
6330 6365 ins_cost(125); // XXX
6331 6366 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
6332 6367 ins_encode %{
6333 6368 __ movl($dst$$Register, $mem$$Address);
6334 6369 %}
6335 6370 ins_pipe(ialu_reg_mem); // XXX
6336 6371 %}
6337 6372
6338 6373 // Load Float
6339 6374 instruct loadF(regF dst, memory mem)
6340 6375 %{
6341 6376 match(Set dst (LoadF mem));
6342 6377
6343 6378 ins_cost(145); // XXX
6344 6379 format %{ "movss $dst, $mem\t# float" %}
6345 6380 opcode(0xF3, 0x0F, 0x10);
6346 6381 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem));
6347 6382 ins_pipe(pipe_slow); // XXX
6348 6383 %}
6349 6384
6350 6385 // Load Double
6351 6386 instruct loadD_partial(regD dst, memory mem)
6352 6387 %{
6353 6388 predicate(!UseXmmLoadAndClearUpper);
6354 6389 match(Set dst (LoadD mem));
6355 6390
6356 6391 ins_cost(145); // XXX
6357 6392 format %{ "movlpd $dst, $mem\t# double" %}
6358 6393 opcode(0x66, 0x0F, 0x12);
6359 6394 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem));
6360 6395 ins_pipe(pipe_slow); // XXX
6361 6396 %}
6362 6397
6363 6398 instruct loadD(regD dst, memory mem)
6364 6399 %{
6365 6400 predicate(UseXmmLoadAndClearUpper);
6366 6401 match(Set dst (LoadD mem));
6367 6402
6368 6403 ins_cost(145); // XXX
6369 6404 format %{ "movsd $dst, $mem\t# double" %}
6370 6405 opcode(0xF2, 0x0F, 0x10);
6371 6406 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem));
6372 6407 ins_pipe(pipe_slow); // XXX
6373 6408 %}
6374 6409
6375 6410 // Load Aligned Packed Byte to XMM register
6376 6411 instruct loadA8B(regD dst, memory mem) %{
6377 6412 match(Set dst (Load8B mem));
6378 6413 ins_cost(125);
6379 6414 format %{ "MOVQ $dst,$mem\t! packed8B" %}
6380 6415 ins_encode( movq_ld(dst, mem));
6381 6416 ins_pipe( pipe_slow );
6382 6417 %}
6383 6418
6384 6419 // Load Aligned Packed Short to XMM register
6385 6420 instruct loadA4S(regD dst, memory mem) %{
6386 6421 match(Set dst (Load4S mem));
6387 6422 ins_cost(125);
6388 6423 format %{ "MOVQ $dst,$mem\t! packed4S" %}
6389 6424 ins_encode( movq_ld(dst, mem));
6390 6425 ins_pipe( pipe_slow );
6391 6426 %}
6392 6427
6393 6428 // Load Aligned Packed Char to XMM register
6394 6429 instruct loadA4C(regD dst, memory mem) %{
6395 6430 match(Set dst (Load4C mem));
6396 6431 ins_cost(125);
6397 6432 format %{ "MOVQ $dst,$mem\t! packed4C" %}
6398 6433 ins_encode( movq_ld(dst, mem));
6399 6434 ins_pipe( pipe_slow );
6400 6435 %}
6401 6436
6402 6437 // Load Aligned Packed Integer to XMM register
6403 6438 instruct load2IU(regD dst, memory mem) %{
6404 6439 match(Set dst (Load2I mem));
6405 6440 ins_cost(125);
6406 6441 format %{ "MOVQ $dst,$mem\t! packed2I" %}
6407 6442 ins_encode( movq_ld(dst, mem));
6408 6443 ins_pipe( pipe_slow );
6409 6444 %}
6410 6445
6411 6446 // Load Aligned Packed Single to XMM
6412 6447 instruct loadA2F(regD dst, memory mem) %{
6413 6448 match(Set dst (Load2F mem));
6414 6449 ins_cost(145);
6415 6450 format %{ "MOVQ $dst,$mem\t! packed2F" %}
6416 6451 ins_encode( movq_ld(dst, mem));
6417 6452 ins_pipe( pipe_slow );
6418 6453 %}
6419 6454
6420 6455 // Load Effective Address
6421 6456 instruct leaP8(rRegP dst, indOffset8 mem)
6422 6457 %{
6423 6458 match(Set dst mem);
6424 6459
6425 6460 ins_cost(110); // XXX
6426 6461 format %{ "leaq $dst, $mem\t# ptr 8" %}
6427 6462 opcode(0x8D);
6428 6463 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6429 6464 ins_pipe(ialu_reg_reg_fat);
6430 6465 %}
6431 6466
6432 6467 instruct leaP32(rRegP dst, indOffset32 mem)
6433 6468 %{
6434 6469 match(Set dst mem);
6435 6470
6436 6471 ins_cost(110);
6437 6472 format %{ "leaq $dst, $mem\t# ptr 32" %}
6438 6473 opcode(0x8D);
6439 6474 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6440 6475 ins_pipe(ialu_reg_reg_fat);
6441 6476 %}
6442 6477
6443 6478 // instruct leaPIdx(rRegP dst, indIndex mem)
6444 6479 // %{
6445 6480 // match(Set dst mem);
6446 6481
6447 6482 // ins_cost(110);
6448 6483 // format %{ "leaq $dst, $mem\t# ptr idx" %}
6449 6484 // opcode(0x8D);
6450 6485 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6451 6486 // ins_pipe(ialu_reg_reg_fat);
6452 6487 // %}
6453 6488
6454 6489 instruct leaPIdxOff(rRegP dst, indIndexOffset mem)
6455 6490 %{
6456 6491 match(Set dst mem);
6457 6492
6458 6493 ins_cost(110);
6459 6494 format %{ "leaq $dst, $mem\t# ptr idxoff" %}
6460 6495 opcode(0x8D);
6461 6496 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6462 6497 ins_pipe(ialu_reg_reg_fat);
6463 6498 %}
6464 6499
6465 6500 instruct leaPIdxScale(rRegP dst, indIndexScale mem)
6466 6501 %{
6467 6502 match(Set dst mem);
6468 6503
6469 6504 ins_cost(110);
6470 6505 format %{ "leaq $dst, $mem\t# ptr idxscale" %}
6471 6506 opcode(0x8D);
6472 6507 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6473 6508 ins_pipe(ialu_reg_reg_fat);
6474 6509 %}
6475 6510
6476 6511 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem)
6477 6512 %{
6478 6513 match(Set dst mem);
6479 6514
6480 6515 ins_cost(110);
6481 6516 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %}
6482 6517 opcode(0x8D);
6483 6518 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6484 6519 ins_pipe(ialu_reg_reg_fat);
6485 6520 %}
6486 6521
6487 6522 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem)
6488 6523 %{
6489 6524 match(Set dst mem);
6490 6525
6491 6526 ins_cost(110);
6492 6527 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %}
6493 6528 opcode(0x8D);
6494 6529 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6495 6530 ins_pipe(ialu_reg_reg_fat);
6496 6531 %}
6497 6532
6498 6533 // Load Effective Address which uses Narrow (32-bits) oop
6499 6534 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem)
6500 6535 %{
6501 6536 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0));
6502 6537 match(Set dst mem);
6503 6538
6504 6539 ins_cost(110);
6505 6540 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %}
6506 6541 opcode(0x8D);
6507 6542 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6508 6543 ins_pipe(ialu_reg_reg_fat);
6509 6544 %}
6510 6545
6511 6546 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem)
6512 6547 %{
6513 6548 predicate(Universe::narrow_oop_shift() == 0);
6514 6549 match(Set dst mem);
6515 6550
6516 6551 ins_cost(110); // XXX
6517 6552 format %{ "leaq $dst, $mem\t# ptr off8narrow" %}
6518 6553 opcode(0x8D);
6519 6554 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6520 6555 ins_pipe(ialu_reg_reg_fat);
6521 6556 %}
6522 6557
6523 6558 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem)
6524 6559 %{
6525 6560 predicate(Universe::narrow_oop_shift() == 0);
6526 6561 match(Set dst mem);
6527 6562
6528 6563 ins_cost(110);
6529 6564 format %{ "leaq $dst, $mem\t# ptr off32narrow" %}
6530 6565 opcode(0x8D);
6531 6566 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6532 6567 ins_pipe(ialu_reg_reg_fat);
6533 6568 %}
6534 6569
6535 6570 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem)
6536 6571 %{
6537 6572 predicate(Universe::narrow_oop_shift() == 0);
6538 6573 match(Set dst mem);
6539 6574
6540 6575 ins_cost(110);
6541 6576 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %}
6542 6577 opcode(0x8D);
6543 6578 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6544 6579 ins_pipe(ialu_reg_reg_fat);
6545 6580 %}
6546 6581
6547 6582 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem)
6548 6583 %{
6549 6584 predicate(Universe::narrow_oop_shift() == 0);
6550 6585 match(Set dst mem);
6551 6586
6552 6587 ins_cost(110);
6553 6588 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %}
6554 6589 opcode(0x8D);
6555 6590 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6556 6591 ins_pipe(ialu_reg_reg_fat);
6557 6592 %}
6558 6593
6559 6594 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem)
6560 6595 %{
6561 6596 predicate(Universe::narrow_oop_shift() == 0);
6562 6597 match(Set dst mem);
6563 6598
6564 6599 ins_cost(110);
6565 6600 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %}
6566 6601 opcode(0x8D);
6567 6602 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6568 6603 ins_pipe(ialu_reg_reg_fat);
6569 6604 %}
6570 6605
6571 6606 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem)
6572 6607 %{
6573 6608 predicate(Universe::narrow_oop_shift() == 0);
6574 6609 match(Set dst mem);
6575 6610
6576 6611 ins_cost(110);
6577 6612 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %}
6578 6613 opcode(0x8D);
6579 6614 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6580 6615 ins_pipe(ialu_reg_reg_fat);
6581 6616 %}
6582 6617
6583 6618 instruct loadConI(rRegI dst, immI src)
6584 6619 %{
6585 6620 match(Set dst src);
6586 6621
6587 6622 format %{ "movl $dst, $src\t# int" %}
6588 6623 ins_encode(load_immI(dst, src));
6589 6624 ins_pipe(ialu_reg_fat); // XXX
6590 6625 %}
6591 6626
6592 6627 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr)
6593 6628 %{
6594 6629 match(Set dst src);
6595 6630 effect(KILL cr);
6596 6631
6597 6632 ins_cost(50);
6598 6633 format %{ "xorl $dst, $dst\t# int" %}
6599 6634 opcode(0x33); /* + rd */
6600 6635 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
6601 6636 ins_pipe(ialu_reg);
6602 6637 %}
6603 6638
6604 6639 instruct loadConL(rRegL dst, immL src)
6605 6640 %{
6606 6641 match(Set dst src);
6607 6642
6608 6643 ins_cost(150);
6609 6644 format %{ "movq $dst, $src\t# long" %}
6610 6645 ins_encode(load_immL(dst, src));
6611 6646 ins_pipe(ialu_reg);
6612 6647 %}
6613 6648
6614 6649 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr)
6615 6650 %{
6616 6651 match(Set dst src);
6617 6652 effect(KILL cr);
6618 6653
6619 6654 ins_cost(50);
6620 6655 format %{ "xorl $dst, $dst\t# long" %}
6621 6656 opcode(0x33); /* + rd */
6622 6657 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
6623 6658 ins_pipe(ialu_reg); // XXX
6624 6659 %}
6625 6660
6626 6661 instruct loadConUL32(rRegL dst, immUL32 src)
6627 6662 %{
6628 6663 match(Set dst src);
6629 6664
6630 6665 ins_cost(60);
6631 6666 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %}
6632 6667 ins_encode(load_immUL32(dst, src));
6633 6668 ins_pipe(ialu_reg);
6634 6669 %}
6635 6670
6636 6671 instruct loadConL32(rRegL dst, immL32 src)
6637 6672 %{
6638 6673 match(Set dst src);
6639 6674
6640 6675 ins_cost(70);
6641 6676 format %{ "movq $dst, $src\t# long (32-bit)" %}
6642 6677 ins_encode(load_immL32(dst, src));
6643 6678 ins_pipe(ialu_reg);
6644 6679 %}
6645 6680
6646 6681 instruct loadConP(rRegP dst, immP src)
6647 6682 %{
6648 6683 match(Set dst src);
6649 6684
6650 6685 format %{ "movq $dst, $src\t# ptr" %}
6651 6686 ins_encode(load_immP(dst, src));
6652 6687 ins_pipe(ialu_reg_fat); // XXX
6653 6688 %}
6654 6689
6655 6690 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
6656 6691 %{
6657 6692 match(Set dst src);
6658 6693 effect(KILL cr);
6659 6694
6660 6695 ins_cost(50);
6661 6696 format %{ "xorl $dst, $dst\t# ptr" %}
6662 6697 opcode(0x33); /* + rd */
6663 6698 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
6664 6699 ins_pipe(ialu_reg);
6665 6700 %}
6666 6701
6667 6702 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
6668 6703 %{
6669 6704 match(Set dst src);
6670 6705 effect(KILL cr);
6671 6706
6672 6707 ins_cost(60);
6673 6708 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %}
6674 6709 ins_encode(load_immP31(dst, src));
6675 6710 ins_pipe(ialu_reg);
6676 6711 %}
6677 6712
6678 6713 instruct loadConF(regF dst, immF src)
6679 6714 %{
6680 6715 match(Set dst src);
6681 6716 ins_cost(125);
6682 6717
6683 6718 format %{ "movss $dst, [$src]" %}
6684 6719 ins_encode(load_conF(dst, src));
6685 6720 ins_pipe(pipe_slow);
6686 6721 %}
6687 6722
6688 6723 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
6689 6724 match(Set dst src);
6690 6725 effect(KILL cr);
6691 6726 format %{ "xorq $dst, $src\t# compressed NULL ptr" %}
6692 6727 ins_encode %{
6693 6728 __ xorq($dst$$Register, $dst$$Register);
6694 6729 %}
6695 6730 ins_pipe(ialu_reg);
6696 6731 %}
6697 6732
6698 6733 instruct loadConN(rRegN dst, immN src) %{
6699 6734 match(Set dst src);
6700 6735
6701 6736 ins_cost(125);
6702 6737 format %{ "movl $dst, $src\t# compressed ptr" %}
6703 6738 ins_encode %{
6704 6739 address con = (address)$src$$constant;
6705 6740 if (con == NULL) {
6706 6741 ShouldNotReachHere();
6707 6742 } else {
6708 6743 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
6709 6744 }
6710 6745 %}
6711 6746 ins_pipe(ialu_reg_fat); // XXX
6712 6747 %}
6713 6748
6714 6749 instruct loadConF0(regF dst, immF0 src)
6715 6750 %{
6716 6751 match(Set dst src);
6717 6752 ins_cost(100);
6718 6753
6719 6754 format %{ "xorps $dst, $dst\t# float 0.0" %}
6720 6755 opcode(0x0F, 0x57);
6721 6756 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
6722 6757 ins_pipe(pipe_slow);
6723 6758 %}
6724 6759
6725 6760 // Use the same format since predicate() can not be used here.
6726 6761 instruct loadConD(regD dst, immD src)
6727 6762 %{
6728 6763 match(Set dst src);
6729 6764 ins_cost(125);
6730 6765
6731 6766 format %{ "movsd $dst, [$src]" %}
6732 6767 ins_encode(load_conD(dst, src));
6733 6768 ins_pipe(pipe_slow);
6734 6769 %}
6735 6770
6736 6771 instruct loadConD0(regD dst, immD0 src)
6737 6772 %{
6738 6773 match(Set dst src);
6739 6774 ins_cost(100);
6740 6775
6741 6776 format %{ "xorpd $dst, $dst\t# double 0.0" %}
6742 6777 opcode(0x66, 0x0F, 0x57);
6743 6778 ins_encode(OpcP, REX_reg_reg(dst, dst), OpcS, OpcT, reg_reg(dst, dst));
6744 6779 ins_pipe(pipe_slow);
6745 6780 %}
6746 6781
6747 6782 instruct loadSSI(rRegI dst, stackSlotI src)
6748 6783 %{
6749 6784 match(Set dst src);
6750 6785
6751 6786 ins_cost(125);
6752 6787 format %{ "movl $dst, $src\t# int stk" %}
6753 6788 opcode(0x8B);
6754 6789 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
6755 6790 ins_pipe(ialu_reg_mem);
6756 6791 %}
6757 6792
6758 6793 instruct loadSSL(rRegL dst, stackSlotL src)
6759 6794 %{
6760 6795 match(Set dst src);
6761 6796
6762 6797 ins_cost(125);
6763 6798 format %{ "movq $dst, $src\t# long stk" %}
6764 6799 opcode(0x8B);
6765 6800 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
6766 6801 ins_pipe(ialu_reg_mem);
6767 6802 %}
6768 6803
6769 6804 instruct loadSSP(rRegP dst, stackSlotP src)
6770 6805 %{
6771 6806 match(Set dst src);
6772 6807
6773 6808 ins_cost(125);
6774 6809 format %{ "movq $dst, $src\t# ptr stk" %}
6775 6810 opcode(0x8B);
6776 6811 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
6777 6812 ins_pipe(ialu_reg_mem);
6778 6813 %}
6779 6814
6780 6815 instruct loadSSF(regF dst, stackSlotF src)
6781 6816 %{
6782 6817 match(Set dst src);
6783 6818
6784 6819 ins_cost(125);
6785 6820 format %{ "movss $dst, $src\t# float stk" %}
6786 6821 opcode(0xF3, 0x0F, 0x10);
6787 6822 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
6788 6823 ins_pipe(pipe_slow); // XXX
6789 6824 %}
6790 6825
6791 6826 // Use the same format since predicate() can not be used here.
6792 6827 instruct loadSSD(regD dst, stackSlotD src)
6793 6828 %{
6794 6829 match(Set dst src);
6795 6830
6796 6831 ins_cost(125);
6797 6832 format %{ "movsd $dst, $src\t# double stk" %}
6798 6833 ins_encode %{
6799 6834 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
6800 6835 %}
6801 6836 ins_pipe(pipe_slow); // XXX
6802 6837 %}
6803 6838
6804 6839 // Prefetch instructions.
6805 6840 // Must be safe to execute with invalid address (cannot fault).
6806 6841
6807 6842 instruct prefetchr( memory mem ) %{
6808 6843 predicate(ReadPrefetchInstr==3);
6809 6844 match(PrefetchRead mem);
6810 6845 ins_cost(125);
6811 6846
6812 6847 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %}
6813 6848 opcode(0x0F, 0x0D); /* Opcode 0F 0D /0 */
6814 6849 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem));
6815 6850 ins_pipe(ialu_mem);
6816 6851 %}
6817 6852
6818 6853 instruct prefetchrNTA( memory mem ) %{
6819 6854 predicate(ReadPrefetchInstr==0);
6820 6855 match(PrefetchRead mem);
6821 6856 ins_cost(125);
6822 6857
6823 6858 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %}
6824 6859 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */
6825 6860 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem));
6826 6861 ins_pipe(ialu_mem);
6827 6862 %}
6828 6863
6829 6864 instruct prefetchrT0( memory mem ) %{
6830 6865 predicate(ReadPrefetchInstr==1);
6831 6866 match(PrefetchRead mem);
6832 6867 ins_cost(125);
6833 6868
6834 6869 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %}
6835 6870 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */
6836 6871 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem));
6837 6872 ins_pipe(ialu_mem);
6838 6873 %}
6839 6874
6840 6875 instruct prefetchrT2( memory mem ) %{
6841 6876 predicate(ReadPrefetchInstr==2);
6842 6877 match(PrefetchRead mem);
6843 6878 ins_cost(125);
6844 6879
6845 6880 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %}
6846 6881 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */
6847 6882 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x03, mem));
6848 6883 ins_pipe(ialu_mem);
6849 6884 %}
6850 6885
6851 6886 instruct prefetchw( memory mem ) %{
6852 6887 predicate(AllocatePrefetchInstr==3);
6853 6888 match(PrefetchWrite mem);
6854 6889 ins_cost(125);
6855 6890
6856 6891 format %{ "PREFETCHW $mem\t# Prefetch into level 1 cache and mark modified" %}
6857 6892 opcode(0x0F, 0x0D); /* Opcode 0F 0D /1 */
6858 6893 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem));
6859 6894 ins_pipe(ialu_mem);
6860 6895 %}
6861 6896
6862 6897 instruct prefetchwNTA( memory mem ) %{
6863 6898 predicate(AllocatePrefetchInstr==0);
6864 6899 match(PrefetchWrite mem);
6865 6900 ins_cost(125);
6866 6901
6867 6902 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %}
6868 6903 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */
6869 6904 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem));
6870 6905 ins_pipe(ialu_mem);
6871 6906 %}
6872 6907
6873 6908 instruct prefetchwT0( memory mem ) %{
6874 6909 predicate(AllocatePrefetchInstr==1);
6875 6910 match(PrefetchWrite mem);
6876 6911 ins_cost(125);
6877 6912
6878 6913 format %{ "PREFETCHT0 $mem\t# Prefetch to level 1 and 2 caches for write" %}
6879 6914 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */
6880 6915 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem));
6881 6916 ins_pipe(ialu_mem);
6882 6917 %}
6883 6918
6884 6919 instruct prefetchwT2( memory mem ) %{
6885 6920 predicate(AllocatePrefetchInstr==2);
6886 6921 match(PrefetchWrite mem);
6887 6922 ins_cost(125);
6888 6923
6889 6924 format %{ "PREFETCHT2 $mem\t# Prefetch to level 2 cache for write" %}
6890 6925 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */
6891 6926 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x03, mem));
6892 6927 ins_pipe(ialu_mem);
6893 6928 %}
6894 6929
6895 6930 //----------Store Instructions-------------------------------------------------
6896 6931
6897 6932 // Store Byte
6898 6933 instruct storeB(memory mem, rRegI src)
6899 6934 %{
6900 6935 match(Set mem (StoreB mem src));
6901 6936
6902 6937 ins_cost(125); // XXX
6903 6938 format %{ "movb $mem, $src\t# byte" %}
6904 6939 opcode(0x88);
6905 6940 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem));
6906 6941 ins_pipe(ialu_mem_reg);
6907 6942 %}
6908 6943
6909 6944 // Store Char/Short
6910 6945 instruct storeC(memory mem, rRegI src)
6911 6946 %{
6912 6947 match(Set mem (StoreC mem src));
6913 6948
6914 6949 ins_cost(125); // XXX
6915 6950 format %{ "movw $mem, $src\t# char/short" %}
6916 6951 opcode(0x89);
6917 6952 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
6918 6953 ins_pipe(ialu_mem_reg);
6919 6954 %}
6920 6955
6921 6956 // Store Integer
6922 6957 instruct storeI(memory mem, rRegI src)
6923 6958 %{
6924 6959 match(Set mem (StoreI mem src));
6925 6960
6926 6961 ins_cost(125); // XXX
6927 6962 format %{ "movl $mem, $src\t# int" %}
6928 6963 opcode(0x89);
6929 6964 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
6930 6965 ins_pipe(ialu_mem_reg);
6931 6966 %}
6932 6967
6933 6968 // Store Long
6934 6969 instruct storeL(memory mem, rRegL src)
6935 6970 %{
6936 6971 match(Set mem (StoreL mem src));
6937 6972
6938 6973 ins_cost(125); // XXX
6939 6974 format %{ "movq $mem, $src\t# long" %}
6940 6975 opcode(0x89);
6941 6976 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
6942 6977 ins_pipe(ialu_mem_reg); // XXX
6943 6978 %}
6944 6979
6945 6980 // Store Pointer
6946 6981 instruct storeP(memory mem, any_RegP src)
6947 6982 %{
6948 6983 match(Set mem (StoreP mem src));
6949 6984
6950 6985 ins_cost(125); // XXX
6951 6986 format %{ "movq $mem, $src\t# ptr" %}
6952 6987 opcode(0x89);
6953 6988 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
6954 6989 ins_pipe(ialu_mem_reg);
6955 6990 %}
6956 6991
6957 6992 instruct storeImmP0(memory mem, immP0 zero)
6958 6993 %{
6959 6994 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6960 6995 match(Set mem (StoreP mem zero));
6961 6996
6962 6997 ins_cost(125); // XXX
6963 6998 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
6964 6999 ins_encode %{
6965 7000 __ movq($mem$$Address, r12);
6966 7001 %}
6967 7002 ins_pipe(ialu_mem_reg);
6968 7003 %}
6969 7004
6970 7005 // Store NULL Pointer, mark word, or other simple pointer constant.
6971 7006 instruct storeImmP(memory mem, immP31 src)
6972 7007 %{
6973 7008 match(Set mem (StoreP mem src));
6974 7009
6975 7010 ins_cost(150); // XXX
6976 7011 format %{ "movq $mem, $src\t# ptr" %}
6977 7012 opcode(0xC7); /* C7 /0 */
6978 7013 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6979 7014 ins_pipe(ialu_mem_imm);
6980 7015 %}
6981 7016
6982 7017 // Store Compressed Pointer
6983 7018 instruct storeN(memory mem, rRegN src)
6984 7019 %{
6985 7020 match(Set mem (StoreN mem src));
6986 7021
6987 7022 ins_cost(125); // XXX
6988 7023 format %{ "movl $mem, $src\t# compressed ptr" %}
6989 7024 ins_encode %{
6990 7025 __ movl($mem$$Address, $src$$Register);
6991 7026 %}
6992 7027 ins_pipe(ialu_mem_reg);
6993 7028 %}
6994 7029
6995 7030 instruct storeImmN0(memory mem, immN0 zero)
6996 7031 %{
6997 7032 predicate(Universe::narrow_oop_base() == NULL);
6998 7033 match(Set mem (StoreN mem zero));
6999 7034
7000 7035 ins_cost(125); // XXX
7001 7036 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
7002 7037 ins_encode %{
7003 7038 __ movl($mem$$Address, r12);
7004 7039 %}
7005 7040 ins_pipe(ialu_mem_reg);
7006 7041 %}
7007 7042
7008 7043 instruct storeImmN(memory mem, immN src)
7009 7044 %{
7010 7045 match(Set mem (StoreN mem src));
7011 7046
7012 7047 ins_cost(150); // XXX
7013 7048 format %{ "movl $mem, $src\t# compressed ptr" %}
7014 7049 ins_encode %{
7015 7050 address con = (address)$src$$constant;
7016 7051 if (con == NULL) {
7017 7052 __ movl($mem$$Address, (int32_t)0);
7018 7053 } else {
7019 7054 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant);
7020 7055 }
7021 7056 %}
7022 7057 ins_pipe(ialu_mem_imm);
7023 7058 %}
7024 7059
7025 7060 // Store Integer Immediate
7026 7061 instruct storeImmI0(memory mem, immI0 zero)
7027 7062 %{
7028 7063 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7029 7064 match(Set mem (StoreI mem zero));
7030 7065
7031 7066 ins_cost(125); // XXX
7032 7067 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
7033 7068 ins_encode %{
7034 7069 __ movl($mem$$Address, r12);
7035 7070 %}
7036 7071 ins_pipe(ialu_mem_reg);
7037 7072 %}
7038 7073
7039 7074 instruct storeImmI(memory mem, immI src)
7040 7075 %{
7041 7076 match(Set mem (StoreI mem src));
7042 7077
7043 7078 ins_cost(150);
7044 7079 format %{ "movl $mem, $src\t# int" %}
7045 7080 opcode(0xC7); /* C7 /0 */
7046 7081 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
7047 7082 ins_pipe(ialu_mem_imm);
7048 7083 %}
7049 7084
7050 7085 // Store Long Immediate
7051 7086 instruct storeImmL0(memory mem, immL0 zero)
7052 7087 %{
7053 7088 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7054 7089 match(Set mem (StoreL mem zero));
7055 7090
7056 7091 ins_cost(125); // XXX
7057 7092 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
7058 7093 ins_encode %{
7059 7094 __ movq($mem$$Address, r12);
7060 7095 %}
7061 7096 ins_pipe(ialu_mem_reg);
7062 7097 %}
7063 7098
7064 7099 instruct storeImmL(memory mem, immL32 src)
7065 7100 %{
7066 7101 match(Set mem (StoreL mem src));
7067 7102
7068 7103 ins_cost(150);
7069 7104 format %{ "movq $mem, $src\t# long" %}
7070 7105 opcode(0xC7); /* C7 /0 */
7071 7106 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
7072 7107 ins_pipe(ialu_mem_imm);
7073 7108 %}
7074 7109
7075 7110 // Store Short/Char Immediate
7076 7111 instruct storeImmC0(memory mem, immI0 zero)
7077 7112 %{
7078 7113 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7079 7114 match(Set mem (StoreC mem zero));
7080 7115
7081 7116 ins_cost(125); // XXX
7082 7117 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
7083 7118 ins_encode %{
7084 7119 __ movw($mem$$Address, r12);
7085 7120 %}
7086 7121 ins_pipe(ialu_mem_reg);
7087 7122 %}
7088 7123
7089 7124 instruct storeImmI16(memory mem, immI16 src)
7090 7125 %{
7091 7126 predicate(UseStoreImmI16);
7092 7127 match(Set mem (StoreC mem src));
7093 7128
7094 7129 ins_cost(150);
7095 7130 format %{ "movw $mem, $src\t# short/char" %}
7096 7131 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */
7097 7132 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src));
7098 7133 ins_pipe(ialu_mem_imm);
7099 7134 %}
7100 7135
7101 7136 // Store Byte Immediate
7102 7137 instruct storeImmB0(memory mem, immI0 zero)
7103 7138 %{
7104 7139 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7105 7140 match(Set mem (StoreB mem zero));
7106 7141
7107 7142 ins_cost(125); // XXX
7108 7143 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
7109 7144 ins_encode %{
7110 7145 __ movb($mem$$Address, r12);
7111 7146 %}
7112 7147 ins_pipe(ialu_mem_reg);
7113 7148 %}
7114 7149
7115 7150 instruct storeImmB(memory mem, immI8 src)
7116 7151 %{
7117 7152 match(Set mem (StoreB mem src));
7118 7153
7119 7154 ins_cost(150); // XXX
7120 7155 format %{ "movb $mem, $src\t# byte" %}
7121 7156 opcode(0xC6); /* C6 /0 */
7122 7157 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
7123 7158 ins_pipe(ialu_mem_imm);
7124 7159 %}
7125 7160
7126 7161 // Store Aligned Packed Byte XMM register to memory
7127 7162 instruct storeA8B(memory mem, regD src) %{
7128 7163 match(Set mem (Store8B mem src));
7129 7164 ins_cost(145);
7130 7165 format %{ "MOVQ $mem,$src\t! packed8B" %}
7131 7166 ins_encode( movq_st(mem, src));
7132 7167 ins_pipe( pipe_slow );
7133 7168 %}
7134 7169
7135 7170 // Store Aligned Packed Char/Short XMM register to memory
7136 7171 instruct storeA4C(memory mem, regD src) %{
7137 7172 match(Set mem (Store4C mem src));
7138 7173 ins_cost(145);
7139 7174 format %{ "MOVQ $mem,$src\t! packed4C" %}
7140 7175 ins_encode( movq_st(mem, src));
7141 7176 ins_pipe( pipe_slow );
7142 7177 %}
7143 7178
7144 7179 // Store Aligned Packed Integer XMM register to memory
7145 7180 instruct storeA2I(memory mem, regD src) %{
7146 7181 match(Set mem (Store2I mem src));
7147 7182 ins_cost(145);
7148 7183 format %{ "MOVQ $mem,$src\t! packed2I" %}
7149 7184 ins_encode( movq_st(mem, src));
7150 7185 ins_pipe( pipe_slow );
7151 7186 %}
7152 7187
7153 7188 // Store CMS card-mark Immediate
7154 7189 instruct storeImmCM0_reg(memory mem, immI0 zero)
7155 7190 %{
7156 7191 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7157 7192 match(Set mem (StoreCM mem zero));
7158 7193
7159 7194 ins_cost(125); // XXX
7160 7195 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
7161 7196 ins_encode %{
7162 7197 __ movb($mem$$Address, r12);
7163 7198 %}
7164 7199 ins_pipe(ialu_mem_reg);
7165 7200 %}
7166 7201
7167 7202 instruct storeImmCM0(memory mem, immI0 src)
7168 7203 %{
7169 7204 match(Set mem (StoreCM mem src));
7170 7205
7171 7206 ins_cost(150); // XXX
7172 7207 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
7173 7208 opcode(0xC6); /* C6 /0 */
7174 7209 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
7175 7210 ins_pipe(ialu_mem_imm);
7176 7211 %}
7177 7212
7178 7213 // Store Aligned Packed Single Float XMM register to memory
7179 7214 instruct storeA2F(memory mem, regD src) %{
7180 7215 match(Set mem (Store2F mem src));
7181 7216 ins_cost(145);
7182 7217 format %{ "MOVQ $mem,$src\t! packed2F" %}
7183 7218 ins_encode( movq_st(mem, src));
7184 7219 ins_pipe( pipe_slow );
7185 7220 %}
7186 7221
7187 7222 // Store Float
7188 7223 instruct storeF(memory mem, regF src)
7189 7224 %{
7190 7225 match(Set mem (StoreF mem src));
7191 7226
7192 7227 ins_cost(95); // XXX
7193 7228 format %{ "movss $mem, $src\t# float" %}
7194 7229 opcode(0xF3, 0x0F, 0x11);
7195 7230 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem));
7196 7231 ins_pipe(pipe_slow); // XXX
7197 7232 %}
7198 7233
7199 7234 // Store immediate Float value (it is faster than store from XMM register)
7200 7235 instruct storeF0(memory mem, immF0 zero)
7201 7236 %{
7202 7237 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7203 7238 match(Set mem (StoreF mem zero));
7204 7239
7205 7240 ins_cost(25); // XXX
7206 7241 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
7207 7242 ins_encode %{
7208 7243 __ movl($mem$$Address, r12);
7209 7244 %}
7210 7245 ins_pipe(ialu_mem_reg);
7211 7246 %}
7212 7247
7213 7248 instruct storeF_imm(memory mem, immF src)
7214 7249 %{
7215 7250 match(Set mem (StoreF mem src));
7216 7251
7217 7252 ins_cost(50);
7218 7253 format %{ "movl $mem, $src\t# float" %}
7219 7254 opcode(0xC7); /* C7 /0 */
7220 7255 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
7221 7256 ins_pipe(ialu_mem_imm);
7222 7257 %}
7223 7258
7224 7259 // Store Double
7225 7260 instruct storeD(memory mem, regD src)
7226 7261 %{
7227 7262 match(Set mem (StoreD mem src));
7228 7263
7229 7264 ins_cost(95); // XXX
7230 7265 format %{ "movsd $mem, $src\t# double" %}
7231 7266 opcode(0xF2, 0x0F, 0x11);
7232 7267 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem));
7233 7268 ins_pipe(pipe_slow); // XXX
7234 7269 %}
7235 7270
7236 7271 // Store immediate double 0.0 (it is faster than store from XMM register)
7237 7272 instruct storeD0_imm(memory mem, immD0 src)
7238 7273 %{
7239 7274 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
7240 7275 match(Set mem (StoreD mem src));
7241 7276
7242 7277 ins_cost(50);
7243 7278 format %{ "movq $mem, $src\t# double 0." %}
7244 7279 opcode(0xC7); /* C7 /0 */
7245 7280 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
7246 7281 ins_pipe(ialu_mem_imm);
7247 7282 %}
7248 7283
7249 7284 instruct storeD0(memory mem, immD0 zero)
7250 7285 %{
7251 7286 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
7252 7287 match(Set mem (StoreD mem zero));
7253 7288
7254 7289 ins_cost(25); // XXX
7255 7290 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
7256 7291 ins_encode %{
7257 7292 __ movq($mem$$Address, r12);
7258 7293 %}
7259 7294 ins_pipe(ialu_mem_reg);
7260 7295 %}
7261 7296
7262 7297 instruct storeSSI(stackSlotI dst, rRegI src)
7263 7298 %{
7264 7299 match(Set dst src);
7265 7300
7266 7301 ins_cost(100);
7267 7302 format %{ "movl $dst, $src\t# int stk" %}
7268 7303 opcode(0x89);
7269 7304 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
7270 7305 ins_pipe( ialu_mem_reg );
7271 7306 %}
7272 7307
7273 7308 instruct storeSSL(stackSlotL dst, rRegL src)
7274 7309 %{
7275 7310 match(Set dst src);
7276 7311
7277 7312 ins_cost(100);
7278 7313 format %{ "movq $dst, $src\t# long stk" %}
7279 7314 opcode(0x89);
7280 7315 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7281 7316 ins_pipe(ialu_mem_reg);
7282 7317 %}
7283 7318
7284 7319 instruct storeSSP(stackSlotP dst, rRegP src)
7285 7320 %{
7286 7321 match(Set dst src);
7287 7322
7288 7323 ins_cost(100);
7289 7324 format %{ "movq $dst, $src\t# ptr stk" %}
7290 7325 opcode(0x89);
7291 7326 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7292 7327 ins_pipe(ialu_mem_reg);
7293 7328 %}
7294 7329
7295 7330 instruct storeSSF(stackSlotF dst, regF src)
7296 7331 %{
7297 7332 match(Set dst src);
7298 7333
7299 7334 ins_cost(95); // XXX
7300 7335 format %{ "movss $dst, $src\t# float stk" %}
7301 7336 opcode(0xF3, 0x0F, 0x11);
7302 7337 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
7303 7338 ins_pipe(pipe_slow); // XXX
7304 7339 %}
7305 7340
7306 7341 instruct storeSSD(stackSlotD dst, regD src)
7307 7342 %{
7308 7343 match(Set dst src);
7309 7344
7310 7345 ins_cost(95); // XXX
7311 7346 format %{ "movsd $dst, $src\t# double stk" %}
7312 7347 opcode(0xF2, 0x0F, 0x11);
7313 7348 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
7314 7349 ins_pipe(pipe_slow); // XXX
7315 7350 %}
7316 7351
7317 7352 //----------BSWAP Instructions-------------------------------------------------
7318 7353 instruct bytes_reverse_int(rRegI dst) %{
7319 7354 match(Set dst (ReverseBytesI dst));
7320 7355
7321 7356 format %{ "bswapl $dst" %}
7322 7357 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */
7323 7358 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) );
7324 7359 ins_pipe( ialu_reg );
7325 7360 %}
7326 7361
7327 7362 instruct bytes_reverse_long(rRegL dst) %{
7328 7363 match(Set dst (ReverseBytesL dst));
7329 7364
7330 7365 format %{ "bswapq $dst" %}
7331 7366
7332 7367 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */
7333 7368 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) );
7334 7369 ins_pipe( ialu_reg);
7335 7370 %}
7336 7371
7337 7372 instruct loadI_reversed(rRegI dst, memory src) %{
7338 7373 match(Set dst (ReverseBytesI (LoadI src)));
7339 7374
7340 7375 format %{ "bswap_movl $dst, $src" %}
7341 7376 opcode(0x8B, 0x0F, 0xC8); /* Opcode 8B 0F C8 */
7342 7377 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src), REX_reg(dst), OpcS, opc3_reg(dst));
7343 7378 ins_pipe( ialu_reg_mem );
7344 7379 %}
7345 7380
7346 7381 instruct loadL_reversed(rRegL dst, memory src) %{
7347 7382 match(Set dst (ReverseBytesL (LoadL src)));
7348 7383
7349 7384 format %{ "bswap_movq $dst, $src" %}
7350 7385 opcode(0x8B, 0x0F, 0xC8); /* Opcode 8B 0F C8 */
7351 7386 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src), REX_reg_wide(dst), OpcS, opc3_reg(dst));
7352 7387 ins_pipe( ialu_reg_mem );
7353 7388 %}
7354 7389
7355 7390 instruct storeI_reversed(memory dst, rRegI src) %{
7356 7391 match(Set dst (StoreI dst (ReverseBytesI src)));
7357 7392
7358 7393 format %{ "movl_bswap $dst, $src" %}
7359 7394 opcode(0x0F, 0xC8, 0x89); /* Opcode 0F C8 89 */
7360 7395 ins_encode( REX_reg(src), OpcP, opc2_reg(src), REX_reg_mem(src, dst), OpcT, reg_mem(src, dst) );
7361 7396 ins_pipe( ialu_mem_reg );
7362 7397 %}
7363 7398
7364 7399 instruct storeL_reversed(memory dst, rRegL src) %{
7365 7400 match(Set dst (StoreL dst (ReverseBytesL src)));
7366 7401
7367 7402 format %{ "movq_bswap $dst, $src" %}
7368 7403 opcode(0x0F, 0xC8, 0x89); /* Opcode 0F C8 89 */
7369 7404 ins_encode( REX_reg_wide(src), OpcP, opc2_reg(src), REX_reg_mem_wide(src, dst), OpcT, reg_mem(src, dst) );
7370 7405 ins_pipe( ialu_mem_reg );
7371 7406 %}
7372 7407
7373 7408
7374 7409 //---------- Zeros Count Instructions ------------------------------------------
7375 7410
7376 7411 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
7377 7412 predicate(UseCountLeadingZerosInstruction);
7378 7413 match(Set dst (CountLeadingZerosI src));
7379 7414 effect(KILL cr);
7380 7415
7381 7416 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %}
7382 7417 ins_encode %{
7383 7418 __ lzcntl($dst$$Register, $src$$Register);
7384 7419 %}
7385 7420 ins_pipe(ialu_reg);
7386 7421 %}
7387 7422
7388 7423 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{
7389 7424 predicate(!UseCountLeadingZerosInstruction);
7390 7425 match(Set dst (CountLeadingZerosI src));
7391 7426 effect(KILL cr);
7392 7427
7393 7428 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t"
7394 7429 "jnz skip\n\t"
7395 7430 "movl $dst, -1\n"
7396 7431 "skip:\n\t"
7397 7432 "negl $dst\n\t"
7398 7433 "addl $dst, 31" %}
7399 7434 ins_encode %{
7400 7435 Register Rdst = $dst$$Register;
7401 7436 Register Rsrc = $src$$Register;
7402 7437 Label skip;
7403 7438 __ bsrl(Rdst, Rsrc);
7404 7439 __ jccb(Assembler::notZero, skip);
7405 7440 __ movl(Rdst, -1);
7406 7441 __ bind(skip);
7407 7442 __ negl(Rdst);
7408 7443 __ addl(Rdst, BitsPerInt - 1);
7409 7444 %}
7410 7445 ins_pipe(ialu_reg);
7411 7446 %}
7412 7447
7413 7448 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
7414 7449 predicate(UseCountLeadingZerosInstruction);
7415 7450 match(Set dst (CountLeadingZerosL src));
7416 7451 effect(KILL cr);
7417 7452
7418 7453 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %}
7419 7454 ins_encode %{
7420 7455 __ lzcntq($dst$$Register, $src$$Register);
7421 7456 %}
7422 7457 ins_pipe(ialu_reg);
7423 7458 %}
7424 7459
7425 7460 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{
7426 7461 predicate(!UseCountLeadingZerosInstruction);
7427 7462 match(Set dst (CountLeadingZerosL src));
7428 7463 effect(KILL cr);
7429 7464
7430 7465 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t"
7431 7466 "jnz skip\n\t"
7432 7467 "movl $dst, -1\n"
7433 7468 "skip:\n\t"
7434 7469 "negl $dst\n\t"
7435 7470 "addl $dst, 63" %}
7436 7471 ins_encode %{
7437 7472 Register Rdst = $dst$$Register;
7438 7473 Register Rsrc = $src$$Register;
7439 7474 Label skip;
7440 7475 __ bsrq(Rdst, Rsrc);
7441 7476 __ jccb(Assembler::notZero, skip);
7442 7477 __ movl(Rdst, -1);
7443 7478 __ bind(skip);
7444 7479 __ negl(Rdst);
7445 7480 __ addl(Rdst, BitsPerLong - 1);
7446 7481 %}
7447 7482 ins_pipe(ialu_reg);
7448 7483 %}
7449 7484
7450 7485 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
7451 7486 match(Set dst (CountTrailingZerosI src));
7452 7487 effect(KILL cr);
7453 7488
7454 7489 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t"
7455 7490 "jnz done\n\t"
7456 7491 "movl $dst, 32\n"
7457 7492 "done:" %}
7458 7493 ins_encode %{
7459 7494 Register Rdst = $dst$$Register;
7460 7495 Label done;
7461 7496 __ bsfl(Rdst, $src$$Register);
7462 7497 __ jccb(Assembler::notZero, done);
7463 7498 __ movl(Rdst, BitsPerInt);
7464 7499 __ bind(done);
7465 7500 %}
7466 7501 ins_pipe(ialu_reg);
7467 7502 %}
7468 7503
7469 7504 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
7470 7505 match(Set dst (CountTrailingZerosL src));
7471 7506 effect(KILL cr);
7472 7507
7473 7508 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t"
7474 7509 "jnz done\n\t"
7475 7510 "movl $dst, 64\n"
7476 7511 "done:" %}
7477 7512 ins_encode %{
7478 7513 Register Rdst = $dst$$Register;
7479 7514 Label done;
7480 7515 __ bsfq(Rdst, $src$$Register);
7481 7516 __ jccb(Assembler::notZero, done);
7482 7517 __ movl(Rdst, BitsPerLong);
7483 7518 __ bind(done);
7484 7519 %}
7485 7520 ins_pipe(ialu_reg);
7486 7521 %}
7487 7522
7488 7523
7489 7524 //---------- Population Count Instructions -------------------------------------
7490 7525
7491 7526 instruct popCountI(rRegI dst, rRegI src) %{
7492 7527 predicate(UsePopCountInstruction);
7493 7528 match(Set dst (PopCountI src));
7494 7529
7495 7530 format %{ "popcnt $dst, $src" %}
7496 7531 ins_encode %{
7497 7532 __ popcntl($dst$$Register, $src$$Register);
7498 7533 %}
7499 7534 ins_pipe(ialu_reg);
7500 7535 %}
7501 7536
7502 7537 instruct popCountI_mem(rRegI dst, memory mem) %{
7503 7538 predicate(UsePopCountInstruction);
7504 7539 match(Set dst (PopCountI (LoadI mem)));
7505 7540
7506 7541 format %{ "popcnt $dst, $mem" %}
7507 7542 ins_encode %{
7508 7543 __ popcntl($dst$$Register, $mem$$Address);
7509 7544 %}
7510 7545 ins_pipe(ialu_reg);
7511 7546 %}
7512 7547
7513 7548 // Note: Long.bitCount(long) returns an int.
7514 7549 instruct popCountL(rRegI dst, rRegL src) %{
7515 7550 predicate(UsePopCountInstruction);
7516 7551 match(Set dst (PopCountL src));
7517 7552
7518 7553 format %{ "popcnt $dst, $src" %}
7519 7554 ins_encode %{
7520 7555 __ popcntq($dst$$Register, $src$$Register);
7521 7556 %}
7522 7557 ins_pipe(ialu_reg);
7523 7558 %}
7524 7559
7525 7560 // Note: Long.bitCount(long) returns an int.
7526 7561 instruct popCountL_mem(rRegI dst, memory mem) %{
7527 7562 predicate(UsePopCountInstruction);
7528 7563 match(Set dst (PopCountL (LoadL mem)));
7529 7564
7530 7565 format %{ "popcnt $dst, $mem" %}
7531 7566 ins_encode %{
7532 7567 __ popcntq($dst$$Register, $mem$$Address);
7533 7568 %}
7534 7569 ins_pipe(ialu_reg);
7535 7570 %}
7536 7571
7537 7572
7538 7573 //----------MemBar Instructions-----------------------------------------------
7539 7574 // Memory barrier flavors
7540 7575
7541 7576 instruct membar_acquire()
7542 7577 %{
7543 7578 match(MemBarAcquire);
7544 7579 ins_cost(0);
7545 7580
7546 7581 size(0);
7547 7582 format %{ "MEMBAR-acquire ! (empty encoding)" %}
7548 7583 ins_encode();
7549 7584 ins_pipe(empty);
7550 7585 %}
7551 7586
7552 7587 instruct membar_acquire_lock()
7553 7588 %{
7554 7589 match(MemBarAcquire);
7555 7590 predicate(Matcher::prior_fast_lock(n));
7556 7591 ins_cost(0);
7557 7592
7558 7593 size(0);
7559 7594 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %}
7560 7595 ins_encode();
7561 7596 ins_pipe(empty);
7562 7597 %}
7563 7598
7564 7599 instruct membar_release()
7565 7600 %{
7566 7601 match(MemBarRelease);
7567 7602 ins_cost(0);
7568 7603
7569 7604 size(0);
7570 7605 format %{ "MEMBAR-release ! (empty encoding)" %}
7571 7606 ins_encode();
7572 7607 ins_pipe(empty);
7573 7608 %}
7574 7609
7575 7610 instruct membar_release_lock()
7576 7611 %{
7577 7612 match(MemBarRelease);
7578 7613 predicate(Matcher::post_fast_unlock(n));
7579 7614 ins_cost(0);
7580 7615
7581 7616 size(0);
7582 7617 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
7583 7618 ins_encode();
7584 7619 ins_pipe(empty);
7585 7620 %}
7586 7621
7587 7622 instruct membar_volatile(rFlagsReg cr) %{
7588 7623 match(MemBarVolatile);
7589 7624 effect(KILL cr);
7590 7625 ins_cost(400);
7591 7626
7592 7627 format %{
7593 7628 $$template
7594 7629 if (os::is_MP()) {
7595 7630 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
7596 7631 } else {
7597 7632 $$emit$$"MEMBAR-volatile ! (empty encoding)"
7598 7633 }
7599 7634 %}
7600 7635 ins_encode %{
7601 7636 __ membar(Assembler::StoreLoad);
7602 7637 %}
7603 7638 ins_pipe(pipe_slow);
7604 7639 %}
7605 7640
7606 7641 instruct unnecessary_membar_volatile()
7607 7642 %{
7608 7643 match(MemBarVolatile);
7609 7644 predicate(Matcher::post_store_load_barrier(n));
7610 7645 ins_cost(0);
7611 7646
7612 7647 size(0);
7613 7648 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
7614 7649 ins_encode();
7615 7650 ins_pipe(empty);
7616 7651 %}
7617 7652
7618 7653 //----------Move Instructions--------------------------------------------------
7619 7654
7620 7655 instruct castX2P(rRegP dst, rRegL src)
7621 7656 %{
7622 7657 match(Set dst (CastX2P src));
7623 7658
7624 7659 format %{ "movq $dst, $src\t# long->ptr" %}
7625 7660 ins_encode(enc_copy_wide(dst, src));
7626 7661 ins_pipe(ialu_reg_reg); // XXX
7627 7662 %}
7628 7663
7629 7664 instruct castP2X(rRegL dst, rRegP src)
7630 7665 %{
7631 7666 match(Set dst (CastP2X src));
7632 7667
7633 7668 format %{ "movq $dst, $src\t# ptr -> long" %}
7634 7669 ins_encode(enc_copy_wide(dst, src));
7635 7670 ins_pipe(ialu_reg_reg); // XXX
7636 7671 %}
7637 7672
7638 7673
7639 7674 // Convert oop pointer into compressed form
7640 7675 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
7641 7676 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
7642 7677 match(Set dst (EncodeP src));
7643 7678 effect(KILL cr);
7644 7679 format %{ "encode_heap_oop $dst,$src" %}
7645 7680 ins_encode %{
7646 7681 Register s = $src$$Register;
7647 7682 Register d = $dst$$Register;
7648 7683 if (s != d) {
7649 7684 __ movq(d, s);
7650 7685 }
7651 7686 __ encode_heap_oop(d);
7652 7687 %}
7653 7688 ins_pipe(ialu_reg_long);
7654 7689 %}
7655 7690
7656 7691 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
7657 7692 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
7658 7693 match(Set dst (EncodeP src));
7659 7694 effect(KILL cr);
7660 7695 format %{ "encode_heap_oop_not_null $dst,$src" %}
7661 7696 ins_encode %{
7662 7697 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
7663 7698 %}
7664 7699 ins_pipe(ialu_reg_long);
7665 7700 %}
7666 7701
7667 7702 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
7668 7703 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
7669 7704 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
7670 7705 match(Set dst (DecodeN src));
7671 7706 effect(KILL cr);
7672 7707 format %{ "decode_heap_oop $dst,$src" %}
7673 7708 ins_encode %{
7674 7709 Register s = $src$$Register;
7675 7710 Register d = $dst$$Register;
7676 7711 if (s != d) {
7677 7712 __ movq(d, s);
7678 7713 }
7679 7714 __ decode_heap_oop(d);
7680 7715 %}
7681 7716 ins_pipe(ialu_reg_long);
7682 7717 %}
7683 7718
7684 7719 instruct decodeHeapOop_not_null(rRegP dst, rRegN src) %{
7685 7720 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
7686 7721 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
7687 7722 match(Set dst (DecodeN src));
7688 7723 format %{ "decode_heap_oop_not_null $dst,$src" %}
7689 7724 ins_encode %{
7690 7725 Register s = $src$$Register;
7691 7726 Register d = $dst$$Register;
7692 7727 if (s != d) {
7693 7728 __ decode_heap_oop_not_null(d, s);
7694 7729 } else {
7695 7730 __ decode_heap_oop_not_null(d);
7696 7731 }
7697 7732 %}
7698 7733 ins_pipe(ialu_reg_long);
7699 7734 %}
7700 7735
7701 7736
7702 7737 //----------Conditional Move---------------------------------------------------
7703 7738 // Jump
7704 7739 // dummy instruction for generating temp registers
7705 7740 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
7706 7741 match(Jump (LShiftL switch_val shift));
7707 7742 ins_cost(350);
7708 7743 predicate(false);
7709 7744 effect(TEMP dest);
7710 7745
7711 7746 format %{ "leaq $dest, table_base\n\t"
7712 7747 "jmp [$dest + $switch_val << $shift]\n\t" %}
7713 7748 ins_encode(jump_enc_offset(switch_val, shift, dest));
7714 7749 ins_pipe(pipe_jmp);
7715 7750 ins_pc_relative(1);
7716 7751 %}
7717 7752
7718 7753 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
7719 7754 match(Jump (AddL (LShiftL switch_val shift) offset));
7720 7755 ins_cost(350);
7721 7756 effect(TEMP dest);
7722 7757
7723 7758 format %{ "leaq $dest, table_base\n\t"
7724 7759 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %}
7725 7760 ins_encode(jump_enc_addr(switch_val, shift, offset, dest));
7726 7761 ins_pipe(pipe_jmp);
7727 7762 ins_pc_relative(1);
7728 7763 %}
7729 7764
7730 7765 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
7731 7766 match(Jump switch_val);
7732 7767 ins_cost(350);
7733 7768 effect(TEMP dest);
7734 7769
7735 7770 format %{ "leaq $dest, table_base\n\t"
7736 7771 "jmp [$dest + $switch_val]\n\t" %}
7737 7772 ins_encode(jump_enc(switch_val, dest));
7738 7773 ins_pipe(pipe_jmp);
7739 7774 ins_pc_relative(1);
7740 7775 %}
7741 7776
7742 7777 // Conditional move
7743 7778 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
7744 7779 %{
7745 7780 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7746 7781
7747 7782 ins_cost(200); // XXX
7748 7783 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
7749 7784 opcode(0x0F, 0x40);
7750 7785 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7751 7786 ins_pipe(pipe_cmov_reg);
7752 7787 %}
7753 7788
7754 7789 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
7755 7790 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7756 7791
7757 7792 ins_cost(200); // XXX
7758 7793 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
7759 7794 opcode(0x0F, 0x40);
7760 7795 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7761 7796 ins_pipe(pipe_cmov_reg);
7762 7797 %}
7763 7798
7764 7799 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
7765 7800 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7766 7801 ins_cost(200);
7767 7802 expand %{
7768 7803 cmovI_regU(cop, cr, dst, src);
7769 7804 %}
7770 7805 %}
7771 7806
7772 7807 // Conditional move
7773 7808 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
7774 7809 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7775 7810
7776 7811 ins_cost(250); // XXX
7777 7812 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
7778 7813 opcode(0x0F, 0x40);
7779 7814 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
7780 7815 ins_pipe(pipe_cmov_mem);
7781 7816 %}
7782 7817
7783 7818 // Conditional move
7784 7819 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
7785 7820 %{
7786 7821 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7787 7822
7788 7823 ins_cost(250); // XXX
7789 7824 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
7790 7825 opcode(0x0F, 0x40);
7791 7826 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
7792 7827 ins_pipe(pipe_cmov_mem);
7793 7828 %}
7794 7829
7795 7830 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
7796 7831 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7797 7832 ins_cost(250);
7798 7833 expand %{
7799 7834 cmovI_memU(cop, cr, dst, src);
7800 7835 %}
7801 7836 %}
7802 7837
7803 7838 // Conditional move
7804 7839 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
7805 7840 %{
7806 7841 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7807 7842
7808 7843 ins_cost(200); // XXX
7809 7844 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
7810 7845 opcode(0x0F, 0x40);
7811 7846 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7812 7847 ins_pipe(pipe_cmov_reg);
7813 7848 %}
7814 7849
7815 7850 // Conditional move
7816 7851 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
7817 7852 %{
7818 7853 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7819 7854
7820 7855 ins_cost(200); // XXX
7821 7856 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
7822 7857 opcode(0x0F, 0x40);
7823 7858 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7824 7859 ins_pipe(pipe_cmov_reg);
7825 7860 %}
7826 7861
7827 7862 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
7828 7863 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7829 7864 ins_cost(200);
7830 7865 expand %{
7831 7866 cmovN_regU(cop, cr, dst, src);
7832 7867 %}
7833 7868 %}
7834 7869
7835 7870 // Conditional move
7836 7871 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
7837 7872 %{
7838 7873 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7839 7874
7840 7875 ins_cost(200); // XXX
7841 7876 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %}
7842 7877 opcode(0x0F, 0x40);
7843 7878 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7844 7879 ins_pipe(pipe_cmov_reg); // XXX
7845 7880 %}
7846 7881
7847 7882 // Conditional move
7848 7883 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
7849 7884 %{
7850 7885 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7851 7886
7852 7887 ins_cost(200); // XXX
7853 7888 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %}
7854 7889 opcode(0x0F, 0x40);
7855 7890 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7856 7891 ins_pipe(pipe_cmov_reg); // XXX
7857 7892 %}
7858 7893
7859 7894 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
7860 7895 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7861 7896 ins_cost(200);
7862 7897 expand %{
7863 7898 cmovP_regU(cop, cr, dst, src);
7864 7899 %}
7865 7900 %}
7866 7901
7867 7902 // DISABLED: Requires the ADLC to emit a bottom_type call that
7868 7903 // correctly meets the two pointer arguments; one is an incoming
7869 7904 // register but the other is a memory operand. ALSO appears to
7870 7905 // be buggy with implicit null checks.
7871 7906 //
7872 7907 //// Conditional move
7873 7908 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src)
7874 7909 //%{
7875 7910 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
7876 7911 // ins_cost(250);
7877 7912 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
7878 7913 // opcode(0x0F,0x40);
7879 7914 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
7880 7915 // ins_pipe( pipe_cmov_mem );
7881 7916 //%}
7882 7917 //
7883 7918 //// Conditional move
7884 7919 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src)
7885 7920 //%{
7886 7921 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
7887 7922 // ins_cost(250);
7888 7923 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
7889 7924 // opcode(0x0F,0x40);
7890 7925 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
7891 7926 // ins_pipe( pipe_cmov_mem );
7892 7927 //%}
7893 7928
7894 7929 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src)
7895 7930 %{
7896 7931 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7897 7932
7898 7933 ins_cost(200); // XXX
7899 7934 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
7900 7935 opcode(0x0F, 0x40);
7901 7936 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7902 7937 ins_pipe(pipe_cmov_reg); // XXX
7903 7938 %}
7904 7939
7905 7940 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src)
7906 7941 %{
7907 7942 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7908 7943
7909 7944 ins_cost(200); // XXX
7910 7945 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
7911 7946 opcode(0x0F, 0x40);
7912 7947 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7913 7948 ins_pipe(pipe_cmov_mem); // XXX
7914 7949 %}
7915 7950
7916 7951 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src)
7917 7952 %{
7918 7953 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7919 7954
7920 7955 ins_cost(200); // XXX
7921 7956 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7922 7957 opcode(0x0F, 0x40);
7923 7958 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7924 7959 ins_pipe(pipe_cmov_reg); // XXX
7925 7960 %}
7926 7961
7927 7962 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
7928 7963 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7929 7964 ins_cost(200);
7930 7965 expand %{
7931 7966 cmovL_regU(cop, cr, dst, src);
7932 7967 %}
7933 7968 %}
7934 7969
7935 7970 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
7936 7971 %{
7937 7972 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7938 7973
7939 7974 ins_cost(200); // XXX
7940 7975 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7941 7976 opcode(0x0F, 0x40);
7942 7977 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7943 7978 ins_pipe(pipe_cmov_mem); // XXX
7944 7979 %}
7945 7980
7946 7981 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
7947 7982 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7948 7983 ins_cost(200);
7949 7984 expand %{
7950 7985 cmovL_memU(cop, cr, dst, src);
7951 7986 %}
7952 7987 %}
7953 7988
7954 7989 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
7955 7990 %{
7956 7991 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7957 7992
7958 7993 ins_cost(200); // XXX
7959 7994 format %{ "jn$cop skip\t# signed cmove float\n\t"
7960 7995 "movss $dst, $src\n"
7961 7996 "skip:" %}
7962 7997 ins_encode(enc_cmovf_branch(cop, dst, src));
7963 7998 ins_pipe(pipe_slow);
7964 7999 %}
7965 8000
7966 8001 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
7967 8002 // %{
7968 8003 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src))));
7969 8004
7970 8005 // ins_cost(200); // XXX
7971 8006 // format %{ "jn$cop skip\t# signed cmove float\n\t"
7972 8007 // "movss $dst, $src\n"
7973 8008 // "skip:" %}
7974 8009 // ins_encode(enc_cmovf_mem_branch(cop, dst, src));
7975 8010 // ins_pipe(pipe_slow);
7976 8011 // %}
7977 8012
7978 8013 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
7979 8014 %{
7980 8015 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7981 8016
7982 8017 ins_cost(200); // XXX
7983 8018 format %{ "jn$cop skip\t# unsigned cmove float\n\t"
7984 8019 "movss $dst, $src\n"
7985 8020 "skip:" %}
7986 8021 ins_encode(enc_cmovf_branch(cop, dst, src));
7987 8022 ins_pipe(pipe_slow);
7988 8023 %}
7989 8024
7990 8025 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
7991 8026 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7992 8027 ins_cost(200);
7993 8028 expand %{
7994 8029 cmovF_regU(cop, cr, dst, src);
7995 8030 %}
7996 8031 %}
7997 8032
7998 8033 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
7999 8034 %{
8000 8035 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
8001 8036
8002 8037 ins_cost(200); // XXX
8003 8038 format %{ "jn$cop skip\t# signed cmove double\n\t"
8004 8039 "movsd $dst, $src\n"
8005 8040 "skip:" %}
8006 8041 ins_encode(enc_cmovd_branch(cop, dst, src));
8007 8042 ins_pipe(pipe_slow);
8008 8043 %}
8009 8044
8010 8045 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
8011 8046 %{
8012 8047 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
8013 8048
8014 8049 ins_cost(200); // XXX
8015 8050 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
8016 8051 "movsd $dst, $src\n"
8017 8052 "skip:" %}
8018 8053 ins_encode(enc_cmovd_branch(cop, dst, src));
8019 8054 ins_pipe(pipe_slow);
8020 8055 %}
8021 8056
8022 8057 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
8023 8058 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
8024 8059 ins_cost(200);
8025 8060 expand %{
8026 8061 cmovD_regU(cop, cr, dst, src);
8027 8062 %}
8028 8063 %}
8029 8064
8030 8065 //----------Arithmetic Instructions--------------------------------------------
8031 8066 //----------Addition Instructions----------------------------------------------
8032 8067
8033 8068 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8034 8069 %{
8035 8070 match(Set dst (AddI dst src));
8036 8071 effect(KILL cr);
8037 8072
8038 8073 format %{ "addl $dst, $src\t# int" %}
8039 8074 opcode(0x03);
8040 8075 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8041 8076 ins_pipe(ialu_reg_reg);
8042 8077 %}
8043 8078
8044 8079 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8045 8080 %{
8046 8081 match(Set dst (AddI dst src));
8047 8082 effect(KILL cr);
8048 8083
8049 8084 format %{ "addl $dst, $src\t# int" %}
8050 8085 opcode(0x81, 0x00); /* /0 id */
8051 8086 ins_encode(OpcSErm(dst, src), Con8or32(src));
8052 8087 ins_pipe( ialu_reg );
8053 8088 %}
8054 8089
8055 8090 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8056 8091 %{
8057 8092 match(Set dst (AddI dst (LoadI src)));
8058 8093 effect(KILL cr);
8059 8094
8060 8095 ins_cost(125); // XXX
8061 8096 format %{ "addl $dst, $src\t# int" %}
8062 8097 opcode(0x03);
8063 8098 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
8064 8099 ins_pipe(ialu_reg_mem);
8065 8100 %}
8066 8101
8067 8102 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8068 8103 %{
8069 8104 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
8070 8105 effect(KILL cr);
8071 8106
8072 8107 ins_cost(150); // XXX
8073 8108 format %{ "addl $dst, $src\t# int" %}
8074 8109 opcode(0x01); /* Opcode 01 /r */
8075 8110 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
8076 8111 ins_pipe(ialu_mem_reg);
8077 8112 %}
8078 8113
8079 8114 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr)
8080 8115 %{
8081 8116 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
8082 8117 effect(KILL cr);
8083 8118
8084 8119 ins_cost(125); // XXX
8085 8120 format %{ "addl $dst, $src\t# int" %}
8086 8121 opcode(0x81); /* Opcode 81 /0 id */
8087 8122 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
8088 8123 ins_pipe(ialu_mem_imm);
8089 8124 %}
8090 8125
8091 8126 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
8092 8127 %{
8093 8128 predicate(UseIncDec);
8094 8129 match(Set dst (AddI dst src));
8095 8130 effect(KILL cr);
8096 8131
8097 8132 format %{ "incl $dst\t# int" %}
8098 8133 opcode(0xFF, 0x00); // FF /0
8099 8134 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8100 8135 ins_pipe(ialu_reg);
8101 8136 %}
8102 8137
8103 8138 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr)
8104 8139 %{
8105 8140 predicate(UseIncDec);
8106 8141 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
8107 8142 effect(KILL cr);
8108 8143
8109 8144 ins_cost(125); // XXX
8110 8145 format %{ "incl $dst\t# int" %}
8111 8146 opcode(0xFF); /* Opcode FF /0 */
8112 8147 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst));
8113 8148 ins_pipe(ialu_mem_imm);
8114 8149 %}
8115 8150
8116 8151 // XXX why does that use AddI
8117 8152 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr)
8118 8153 %{
8119 8154 predicate(UseIncDec);
8120 8155 match(Set dst (AddI dst src));
8121 8156 effect(KILL cr);
8122 8157
8123 8158 format %{ "decl $dst\t# int" %}
8124 8159 opcode(0xFF, 0x01); // FF /1
8125 8160 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8126 8161 ins_pipe(ialu_reg);
8127 8162 %}
8128 8163
8129 8164 // XXX why does that use AddI
8130 8165 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr)
8131 8166 %{
8132 8167 predicate(UseIncDec);
8133 8168 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
8134 8169 effect(KILL cr);
8135 8170
8136 8171 ins_cost(125); // XXX
8137 8172 format %{ "decl $dst\t# int" %}
8138 8173 opcode(0xFF); /* Opcode FF /1 */
8139 8174 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst));
8140 8175 ins_pipe(ialu_mem_imm);
8141 8176 %}
8142 8177
8143 8178 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1)
8144 8179 %{
8145 8180 match(Set dst (AddI src0 src1));
8146 8181
8147 8182 ins_cost(110);
8148 8183 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %}
8149 8184 opcode(0x8D); /* 0x8D /r */
8150 8185 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
8151 8186 ins_pipe(ialu_reg_reg);
8152 8187 %}
8153 8188
8154 8189 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8155 8190 %{
8156 8191 match(Set dst (AddL dst src));
8157 8192 effect(KILL cr);
8158 8193
8159 8194 format %{ "addq $dst, $src\t# long" %}
8160 8195 opcode(0x03);
8161 8196 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8162 8197 ins_pipe(ialu_reg_reg);
8163 8198 %}
8164 8199
8165 8200 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
8166 8201 %{
8167 8202 match(Set dst (AddL dst src));
8168 8203 effect(KILL cr);
8169 8204
8170 8205 format %{ "addq $dst, $src\t# long" %}
8171 8206 opcode(0x81, 0x00); /* /0 id */
8172 8207 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
8173 8208 ins_pipe( ialu_reg );
8174 8209 %}
8175 8210
8176 8211 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
8177 8212 %{
8178 8213 match(Set dst (AddL dst (LoadL src)));
8179 8214 effect(KILL cr);
8180 8215
8181 8216 ins_cost(125); // XXX
8182 8217 format %{ "addq $dst, $src\t# long" %}
8183 8218 opcode(0x03);
8184 8219 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
8185 8220 ins_pipe(ialu_reg_mem);
8186 8221 %}
8187 8222
8188 8223 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
8189 8224 %{
8190 8225 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
8191 8226 effect(KILL cr);
8192 8227
8193 8228 ins_cost(150); // XXX
8194 8229 format %{ "addq $dst, $src\t# long" %}
8195 8230 opcode(0x01); /* Opcode 01 /r */
8196 8231 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
8197 8232 ins_pipe(ialu_mem_reg);
8198 8233 %}
8199 8234
8200 8235 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
8201 8236 %{
8202 8237 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
8203 8238 effect(KILL cr);
8204 8239
8205 8240 ins_cost(125); // XXX
8206 8241 format %{ "addq $dst, $src\t# long" %}
8207 8242 opcode(0x81); /* Opcode 81 /0 id */
8208 8243 ins_encode(REX_mem_wide(dst),
8209 8244 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
8210 8245 ins_pipe(ialu_mem_imm);
8211 8246 %}
8212 8247
8213 8248 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr)
8214 8249 %{
8215 8250 predicate(UseIncDec);
8216 8251 match(Set dst (AddL dst src));
8217 8252 effect(KILL cr);
8218 8253
8219 8254 format %{ "incq $dst\t# long" %}
8220 8255 opcode(0xFF, 0x00); // FF /0
8221 8256 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8222 8257 ins_pipe(ialu_reg);
8223 8258 %}
8224 8259
8225 8260 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr)
8226 8261 %{
8227 8262 predicate(UseIncDec);
8228 8263 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
8229 8264 effect(KILL cr);
8230 8265
8231 8266 ins_cost(125); // XXX
8232 8267 format %{ "incq $dst\t# long" %}
8233 8268 opcode(0xFF); /* Opcode FF /0 */
8234 8269 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst));
8235 8270 ins_pipe(ialu_mem_imm);
8236 8271 %}
8237 8272
8238 8273 // XXX why does that use AddL
8239 8274 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr)
8240 8275 %{
8241 8276 predicate(UseIncDec);
8242 8277 match(Set dst (AddL dst src));
8243 8278 effect(KILL cr);
8244 8279
8245 8280 format %{ "decq $dst\t# long" %}
8246 8281 opcode(0xFF, 0x01); // FF /1
8247 8282 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8248 8283 ins_pipe(ialu_reg);
8249 8284 %}
8250 8285
8251 8286 // XXX why does that use AddL
8252 8287 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr)
8253 8288 %{
8254 8289 predicate(UseIncDec);
8255 8290 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
8256 8291 effect(KILL cr);
8257 8292
8258 8293 ins_cost(125); // XXX
8259 8294 format %{ "decq $dst\t# long" %}
8260 8295 opcode(0xFF); /* Opcode FF /1 */
8261 8296 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst));
8262 8297 ins_pipe(ialu_mem_imm);
8263 8298 %}
8264 8299
8265 8300 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1)
8266 8301 %{
8267 8302 match(Set dst (AddL src0 src1));
8268 8303
8269 8304 ins_cost(110);
8270 8305 format %{ "leaq $dst, [$src0 + $src1]\t# long" %}
8271 8306 opcode(0x8D); /* 0x8D /r */
8272 8307 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
8273 8308 ins_pipe(ialu_reg_reg);
8274 8309 %}
8275 8310
8276 8311 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr)
8277 8312 %{
8278 8313 match(Set dst (AddP dst src));
8279 8314 effect(KILL cr);
8280 8315
8281 8316 format %{ "addq $dst, $src\t# ptr" %}
8282 8317 opcode(0x03);
8283 8318 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8284 8319 ins_pipe(ialu_reg_reg);
8285 8320 %}
8286 8321
8287 8322 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr)
8288 8323 %{
8289 8324 match(Set dst (AddP dst src));
8290 8325 effect(KILL cr);
8291 8326
8292 8327 format %{ "addq $dst, $src\t# ptr" %}
8293 8328 opcode(0x81, 0x00); /* /0 id */
8294 8329 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
8295 8330 ins_pipe( ialu_reg );
8296 8331 %}
8297 8332
8298 8333 // XXX addP mem ops ????
8299 8334
8300 8335 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1)
8301 8336 %{
8302 8337 match(Set dst (AddP src0 src1));
8303 8338
8304 8339 ins_cost(110);
8305 8340 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %}
8306 8341 opcode(0x8D); /* 0x8D /r */
8307 8342 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX
8308 8343 ins_pipe(ialu_reg_reg);
8309 8344 %}
8310 8345
8311 8346 instruct checkCastPP(rRegP dst)
8312 8347 %{
8313 8348 match(Set dst (CheckCastPP dst));
8314 8349
8315 8350 size(0);
8316 8351 format %{ "# checkcastPP of $dst" %}
8317 8352 ins_encode(/* empty encoding */);
8318 8353 ins_pipe(empty);
8319 8354 %}
8320 8355
8321 8356 instruct castPP(rRegP dst)
8322 8357 %{
8323 8358 match(Set dst (CastPP dst));
8324 8359
8325 8360 size(0);
8326 8361 format %{ "# castPP of $dst" %}
8327 8362 ins_encode(/* empty encoding */);
8328 8363 ins_pipe(empty);
8329 8364 %}
8330 8365
8331 8366 instruct castII(rRegI dst)
8332 8367 %{
8333 8368 match(Set dst (CastII dst));
8334 8369
8335 8370 size(0);
8336 8371 format %{ "# castII of $dst" %}
8337 8372 ins_encode(/* empty encoding */);
8338 8373 ins_cost(0);
8339 8374 ins_pipe(empty);
8340 8375 %}
8341 8376
8342 8377 // LoadP-locked same as a regular LoadP when used with compare-swap
8343 8378 instruct loadPLocked(rRegP dst, memory mem)
8344 8379 %{
8345 8380 match(Set dst (LoadPLocked mem));
8346 8381
8347 8382 ins_cost(125); // XXX
8348 8383 format %{ "movq $dst, $mem\t# ptr locked" %}
8349 8384 opcode(0x8B);
8350 8385 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
8351 8386 ins_pipe(ialu_reg_mem); // XXX
8352 8387 %}
8353 8388
8354 8389 // LoadL-locked - same as a regular LoadL when used with compare-swap
8355 8390 instruct loadLLocked(rRegL dst, memory mem)
8356 8391 %{
8357 8392 match(Set dst (LoadLLocked mem));
8358 8393
8359 8394 ins_cost(125); // XXX
8360 8395 format %{ "movq $dst, $mem\t# long locked" %}
8361 8396 opcode(0x8B);
8362 8397 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
8363 8398 ins_pipe(ialu_reg_mem); // XXX
8364 8399 %}
8365 8400
8366 8401 // Conditional-store of the updated heap-top.
8367 8402 // Used during allocation of the shared heap.
8368 8403 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
8369 8404
8370 8405 instruct storePConditional(memory heap_top_ptr,
8371 8406 rax_RegP oldval, rRegP newval,
8372 8407 rFlagsReg cr)
8373 8408 %{
8374 8409 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
8375 8410
8376 8411 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
8377 8412 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
8378 8413 opcode(0x0F, 0xB1);
8379 8414 ins_encode(lock_prefix,
8380 8415 REX_reg_mem_wide(newval, heap_top_ptr),
8381 8416 OpcP, OpcS,
8382 8417 reg_mem(newval, heap_top_ptr));
8383 8418 ins_pipe(pipe_cmpxchg);
8384 8419 %}
8385 8420
8386 8421 // Conditional-store of an int value.
8387 8422 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
8388 8423 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
8389 8424 %{
8390 8425 match(Set cr (StoreIConditional mem (Binary oldval newval)));
8391 8426 effect(KILL oldval);
8392 8427
8393 8428 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
8394 8429 opcode(0x0F, 0xB1);
8395 8430 ins_encode(lock_prefix,
8396 8431 REX_reg_mem(newval, mem),
8397 8432 OpcP, OpcS,
8398 8433 reg_mem(newval, mem));
8399 8434 ins_pipe(pipe_cmpxchg);
8400 8435 %}
8401 8436
8402 8437 // Conditional-store of a long value.
8403 8438 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
8404 8439 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
8405 8440 %{
8406 8441 match(Set cr (StoreLConditional mem (Binary oldval newval)));
8407 8442 effect(KILL oldval);
8408 8443
8409 8444 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
8410 8445 opcode(0x0F, 0xB1);
8411 8446 ins_encode(lock_prefix,
8412 8447 REX_reg_mem_wide(newval, mem),
8413 8448 OpcP, OpcS,
8414 8449 reg_mem(newval, mem));
8415 8450 ins_pipe(pipe_cmpxchg);
8416 8451 %}
8417 8452
8418 8453
8419 8454 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
8420 8455 instruct compareAndSwapP(rRegI res,
8421 8456 memory mem_ptr,
8422 8457 rax_RegP oldval, rRegP newval,
8423 8458 rFlagsReg cr)
8424 8459 %{
8425 8460 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
8426 8461 effect(KILL cr, KILL oldval);
8427 8462
8428 8463 format %{ "cmpxchgq $mem_ptr,$newval\t# "
8429 8464 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
8430 8465 "sete $res\n\t"
8431 8466 "movzbl $res, $res" %}
8432 8467 opcode(0x0F, 0xB1);
8433 8468 ins_encode(lock_prefix,
8434 8469 REX_reg_mem_wide(newval, mem_ptr),
8435 8470 OpcP, OpcS,
8436 8471 reg_mem(newval, mem_ptr),
8437 8472 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
8438 8473 REX_reg_breg(res, res), // movzbl
8439 8474 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
8440 8475 ins_pipe( pipe_cmpxchg );
8441 8476 %}
8442 8477
8443 8478 instruct compareAndSwapL(rRegI res,
8444 8479 memory mem_ptr,
8445 8480 rax_RegL oldval, rRegL newval,
8446 8481 rFlagsReg cr)
8447 8482 %{
8448 8483 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
8449 8484 effect(KILL cr, KILL oldval);
8450 8485
8451 8486 format %{ "cmpxchgq $mem_ptr,$newval\t# "
8452 8487 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
8453 8488 "sete $res\n\t"
8454 8489 "movzbl $res, $res" %}
8455 8490 opcode(0x0F, 0xB1);
8456 8491 ins_encode(lock_prefix,
8457 8492 REX_reg_mem_wide(newval, mem_ptr),
8458 8493 OpcP, OpcS,
8459 8494 reg_mem(newval, mem_ptr),
8460 8495 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
8461 8496 REX_reg_breg(res, res), // movzbl
8462 8497 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
8463 8498 ins_pipe( pipe_cmpxchg );
8464 8499 %}
8465 8500
8466 8501 instruct compareAndSwapI(rRegI res,
8467 8502 memory mem_ptr,
8468 8503 rax_RegI oldval, rRegI newval,
8469 8504 rFlagsReg cr)
8470 8505 %{
8471 8506 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
8472 8507 effect(KILL cr, KILL oldval);
8473 8508
8474 8509 format %{ "cmpxchgl $mem_ptr,$newval\t# "
8475 8510 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
8476 8511 "sete $res\n\t"
8477 8512 "movzbl $res, $res" %}
8478 8513 opcode(0x0F, 0xB1);
8479 8514 ins_encode(lock_prefix,
8480 8515 REX_reg_mem(newval, mem_ptr),
8481 8516 OpcP, OpcS,
8482 8517 reg_mem(newval, mem_ptr),
8483 8518 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
8484 8519 REX_reg_breg(res, res), // movzbl
8485 8520 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
8486 8521 ins_pipe( pipe_cmpxchg );
8487 8522 %}
8488 8523
8489 8524
8490 8525 instruct compareAndSwapN(rRegI res,
8491 8526 memory mem_ptr,
8492 8527 rax_RegN oldval, rRegN newval,
8493 8528 rFlagsReg cr) %{
8494 8529 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
8495 8530 effect(KILL cr, KILL oldval);
8496 8531
8497 8532 format %{ "cmpxchgl $mem_ptr,$newval\t# "
8498 8533 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
8499 8534 "sete $res\n\t"
8500 8535 "movzbl $res, $res" %}
8501 8536 opcode(0x0F, 0xB1);
8502 8537 ins_encode(lock_prefix,
8503 8538 REX_reg_mem(newval, mem_ptr),
8504 8539 OpcP, OpcS,
8505 8540 reg_mem(newval, mem_ptr),
8506 8541 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
8507 8542 REX_reg_breg(res, res), // movzbl
8508 8543 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
8509 8544 ins_pipe( pipe_cmpxchg );
8510 8545 %}
8511 8546
8512 8547 //----------Subtraction Instructions-------------------------------------------
8513 8548
8514 8549 // Integer Subtraction Instructions
8515 8550 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8516 8551 %{
8517 8552 match(Set dst (SubI dst src));
8518 8553 effect(KILL cr);
8519 8554
8520 8555 format %{ "subl $dst, $src\t# int" %}
8521 8556 opcode(0x2B);
8522 8557 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8523 8558 ins_pipe(ialu_reg_reg);
8524 8559 %}
8525 8560
8526 8561 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8527 8562 %{
8528 8563 match(Set dst (SubI dst src));
8529 8564 effect(KILL cr);
8530 8565
8531 8566 format %{ "subl $dst, $src\t# int" %}
8532 8567 opcode(0x81, 0x05); /* Opcode 81 /5 */
8533 8568 ins_encode(OpcSErm(dst, src), Con8or32(src));
8534 8569 ins_pipe(ialu_reg);
8535 8570 %}
8536 8571
8537 8572 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8538 8573 %{
8539 8574 match(Set dst (SubI dst (LoadI src)));
8540 8575 effect(KILL cr);
8541 8576
8542 8577 ins_cost(125);
8543 8578 format %{ "subl $dst, $src\t# int" %}
8544 8579 opcode(0x2B);
8545 8580 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
8546 8581 ins_pipe(ialu_reg_mem);
8547 8582 %}
8548 8583
8549 8584 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8550 8585 %{
8551 8586 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
8552 8587 effect(KILL cr);
8553 8588
8554 8589 ins_cost(150);
8555 8590 format %{ "subl $dst, $src\t# int" %}
8556 8591 opcode(0x29); /* Opcode 29 /r */
8557 8592 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
8558 8593 ins_pipe(ialu_mem_reg);
8559 8594 %}
8560 8595
8561 8596 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr)
8562 8597 %{
8563 8598 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
8564 8599 effect(KILL cr);
8565 8600
8566 8601 ins_cost(125); // XXX
8567 8602 format %{ "subl $dst, $src\t# int" %}
8568 8603 opcode(0x81); /* Opcode 81 /5 id */
8569 8604 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
8570 8605 ins_pipe(ialu_mem_imm);
8571 8606 %}
8572 8607
8573 8608 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8574 8609 %{
8575 8610 match(Set dst (SubL dst src));
8576 8611 effect(KILL cr);
8577 8612
8578 8613 format %{ "subq $dst, $src\t# long" %}
8579 8614 opcode(0x2B);
8580 8615 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8581 8616 ins_pipe(ialu_reg_reg);
8582 8617 %}
8583 8618
8584 8619 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr)
8585 8620 %{
8586 8621 match(Set dst (SubL dst src));
8587 8622 effect(KILL cr);
8588 8623
8589 8624 format %{ "subq $dst, $src\t# long" %}
8590 8625 opcode(0x81, 0x05); /* Opcode 81 /5 */
8591 8626 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
8592 8627 ins_pipe(ialu_reg);
8593 8628 %}
8594 8629
8595 8630 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
8596 8631 %{
8597 8632 match(Set dst (SubL dst (LoadL src)));
8598 8633 effect(KILL cr);
8599 8634
8600 8635 ins_cost(125);
8601 8636 format %{ "subq $dst, $src\t# long" %}
8602 8637 opcode(0x2B);
8603 8638 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
8604 8639 ins_pipe(ialu_reg_mem);
8605 8640 %}
8606 8641
8607 8642 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
8608 8643 %{
8609 8644 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
8610 8645 effect(KILL cr);
8611 8646
8612 8647 ins_cost(150);
8613 8648 format %{ "subq $dst, $src\t# long" %}
8614 8649 opcode(0x29); /* Opcode 29 /r */
8615 8650 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
8616 8651 ins_pipe(ialu_mem_reg);
8617 8652 %}
8618 8653
8619 8654 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
8620 8655 %{
8621 8656 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
8622 8657 effect(KILL cr);
8623 8658
8624 8659 ins_cost(125); // XXX
8625 8660 format %{ "subq $dst, $src\t# long" %}
8626 8661 opcode(0x81); /* Opcode 81 /5 id */
8627 8662 ins_encode(REX_mem_wide(dst),
8628 8663 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
8629 8664 ins_pipe(ialu_mem_imm);
8630 8665 %}
8631 8666
8632 8667 // Subtract from a pointer
8633 8668 // XXX hmpf???
8634 8669 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr)
8635 8670 %{
8636 8671 match(Set dst (AddP dst (SubI zero src)));
8637 8672 effect(KILL cr);
8638 8673
8639 8674 format %{ "subq $dst, $src\t# ptr - int" %}
8640 8675 opcode(0x2B);
8641 8676 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
8642 8677 ins_pipe(ialu_reg_reg);
8643 8678 %}
8644 8679
8645 8680 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr)
8646 8681 %{
8647 8682 match(Set dst (SubI zero dst));
8648 8683 effect(KILL cr);
8649 8684
8650 8685 format %{ "negl $dst\t# int" %}
8651 8686 opcode(0xF7, 0x03); // Opcode F7 /3
8652 8687 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8653 8688 ins_pipe(ialu_reg);
8654 8689 %}
8655 8690
8656 8691 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr)
8657 8692 %{
8658 8693 match(Set dst (StoreI dst (SubI zero (LoadI dst))));
8659 8694 effect(KILL cr);
8660 8695
8661 8696 format %{ "negl $dst\t# int" %}
8662 8697 opcode(0xF7, 0x03); // Opcode F7 /3
8663 8698 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8664 8699 ins_pipe(ialu_reg);
8665 8700 %}
8666 8701
8667 8702 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr)
8668 8703 %{
8669 8704 match(Set dst (SubL zero dst));
8670 8705 effect(KILL cr);
8671 8706
8672 8707 format %{ "negq $dst\t# long" %}
8673 8708 opcode(0xF7, 0x03); // Opcode F7 /3
8674 8709 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8675 8710 ins_pipe(ialu_reg);
8676 8711 %}
8677 8712
8678 8713 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr)
8679 8714 %{
8680 8715 match(Set dst (StoreL dst (SubL zero (LoadL dst))));
8681 8716 effect(KILL cr);
8682 8717
8683 8718 format %{ "negq $dst\t# long" %}
8684 8719 opcode(0xF7, 0x03); // Opcode F7 /3
8685 8720 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8686 8721 ins_pipe(ialu_reg);
8687 8722 %}
8688 8723
8689 8724
8690 8725 //----------Multiplication/Division Instructions-------------------------------
8691 8726 // Integer Multiplication Instructions
8692 8727 // Multiply Register
8693 8728
8694 8729 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8695 8730 %{
8696 8731 match(Set dst (MulI dst src));
8697 8732 effect(KILL cr);
8698 8733
8699 8734 ins_cost(300);
8700 8735 format %{ "imull $dst, $src\t# int" %}
8701 8736 opcode(0x0F, 0xAF);
8702 8737 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8703 8738 ins_pipe(ialu_reg_reg_alu0);
8704 8739 %}
8705 8740
8706 8741 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr)
8707 8742 %{
8708 8743 match(Set dst (MulI src imm));
8709 8744 effect(KILL cr);
8710 8745
8711 8746 ins_cost(300);
8712 8747 format %{ "imull $dst, $src, $imm\t# int" %}
8713 8748 opcode(0x69); /* 69 /r id */
8714 8749 ins_encode(REX_reg_reg(dst, src),
8715 8750 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
8716 8751 ins_pipe(ialu_reg_reg_alu0);
8717 8752 %}
8718 8753
8719 8754 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr)
8720 8755 %{
8721 8756 match(Set dst (MulI dst (LoadI src)));
8722 8757 effect(KILL cr);
8723 8758
8724 8759 ins_cost(350);
8725 8760 format %{ "imull $dst, $src\t# int" %}
8726 8761 opcode(0x0F, 0xAF);
8727 8762 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src));
8728 8763 ins_pipe(ialu_reg_mem_alu0);
8729 8764 %}
8730 8765
8731 8766 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr)
8732 8767 %{
8733 8768 match(Set dst (MulI (LoadI src) imm));
8734 8769 effect(KILL cr);
8735 8770
8736 8771 ins_cost(300);
8737 8772 format %{ "imull $dst, $src, $imm\t# int" %}
8738 8773 opcode(0x69); /* 69 /r id */
8739 8774 ins_encode(REX_reg_mem(dst, src),
8740 8775 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
8741 8776 ins_pipe(ialu_reg_mem_alu0);
8742 8777 %}
8743 8778
8744 8779 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
8745 8780 %{
8746 8781 match(Set dst (MulL dst src));
8747 8782 effect(KILL cr);
8748 8783
8749 8784 ins_cost(300);
8750 8785 format %{ "imulq $dst, $src\t# long" %}
8751 8786 opcode(0x0F, 0xAF);
8752 8787 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src));
8753 8788 ins_pipe(ialu_reg_reg_alu0);
8754 8789 %}
8755 8790
8756 8791 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr)
8757 8792 %{
8758 8793 match(Set dst (MulL src imm));
8759 8794 effect(KILL cr);
8760 8795
8761 8796 ins_cost(300);
8762 8797 format %{ "imulq $dst, $src, $imm\t# long" %}
8763 8798 opcode(0x69); /* 69 /r id */
8764 8799 ins_encode(REX_reg_reg_wide(dst, src),
8765 8800 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
8766 8801 ins_pipe(ialu_reg_reg_alu0);
8767 8802 %}
8768 8803
8769 8804 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr)
8770 8805 %{
8771 8806 match(Set dst (MulL dst (LoadL src)));
8772 8807 effect(KILL cr);
8773 8808
8774 8809 ins_cost(350);
8775 8810 format %{ "imulq $dst, $src\t# long" %}
8776 8811 opcode(0x0F, 0xAF);
8777 8812 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src));
8778 8813 ins_pipe(ialu_reg_mem_alu0);
8779 8814 %}
8780 8815
8781 8816 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr)
8782 8817 %{
8783 8818 match(Set dst (MulL (LoadL src) imm));
8784 8819 effect(KILL cr);
8785 8820
8786 8821 ins_cost(300);
8787 8822 format %{ "imulq $dst, $src, $imm\t# long" %}
8788 8823 opcode(0x69); /* 69 /r id */
8789 8824 ins_encode(REX_reg_mem_wide(dst, src),
8790 8825 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
8791 8826 ins_pipe(ialu_reg_mem_alu0);
8792 8827 %}
8793 8828
8794 8829 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8795 8830 %{
8796 8831 match(Set dst (MulHiL src rax));
8797 8832 effect(USE_KILL rax, KILL cr);
8798 8833
8799 8834 ins_cost(300);
8800 8835 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %}
8801 8836 opcode(0xF7, 0x5); /* Opcode F7 /5 */
8802 8837 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
8803 8838 ins_pipe(ialu_reg_reg_alu0);
8804 8839 %}
8805 8840
8806 8841 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8807 8842 rFlagsReg cr)
8808 8843 %{
8809 8844 match(Set rax (DivI rax div));
8810 8845 effect(KILL rdx, KILL cr);
8811 8846
8812 8847 ins_cost(30*100+10*100); // XXX
8813 8848 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
8814 8849 "jne,s normal\n\t"
8815 8850 "xorl rdx, rdx\n\t"
8816 8851 "cmpl $div, -1\n\t"
8817 8852 "je,s done\n"
8818 8853 "normal: cdql\n\t"
8819 8854 "idivl $div\n"
8820 8855 "done:" %}
8821 8856 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8822 8857 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8823 8858 ins_pipe(ialu_reg_reg_alu0);
8824 8859 %}
8825 8860
8826 8861 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8827 8862 rFlagsReg cr)
8828 8863 %{
8829 8864 match(Set rax (DivL rax div));
8830 8865 effect(KILL rdx, KILL cr);
8831 8866
8832 8867 ins_cost(30*100+10*100); // XXX
8833 8868 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8834 8869 "cmpq rax, rdx\n\t"
8835 8870 "jne,s normal\n\t"
8836 8871 "xorl rdx, rdx\n\t"
8837 8872 "cmpq $div, -1\n\t"
8838 8873 "je,s done\n"
8839 8874 "normal: cdqq\n\t"
8840 8875 "idivq $div\n"
8841 8876 "done:" %}
8842 8877 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8843 8878 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8844 8879 ins_pipe(ialu_reg_reg_alu0);
8845 8880 %}
8846 8881
8847 8882 // Integer DIVMOD with Register, both quotient and mod results
8848 8883 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8849 8884 rFlagsReg cr)
8850 8885 %{
8851 8886 match(DivModI rax div);
8852 8887 effect(KILL cr);
8853 8888
8854 8889 ins_cost(30*100+10*100); // XXX
8855 8890 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
8856 8891 "jne,s normal\n\t"
8857 8892 "xorl rdx, rdx\n\t"
8858 8893 "cmpl $div, -1\n\t"
8859 8894 "je,s done\n"
8860 8895 "normal: cdql\n\t"
8861 8896 "idivl $div\n"
8862 8897 "done:" %}
8863 8898 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8864 8899 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8865 8900 ins_pipe(pipe_slow);
8866 8901 %}
8867 8902
8868 8903 // Long DIVMOD with Register, both quotient and mod results
8869 8904 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8870 8905 rFlagsReg cr)
8871 8906 %{
8872 8907 match(DivModL rax div);
8873 8908 effect(KILL cr);
8874 8909
8875 8910 ins_cost(30*100+10*100); // XXX
8876 8911 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8877 8912 "cmpq rax, rdx\n\t"
8878 8913 "jne,s normal\n\t"
8879 8914 "xorl rdx, rdx\n\t"
8880 8915 "cmpq $div, -1\n\t"
8881 8916 "je,s done\n"
8882 8917 "normal: cdqq\n\t"
8883 8918 "idivq $div\n"
8884 8919 "done:" %}
8885 8920 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8886 8921 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8887 8922 ins_pipe(pipe_slow);
8888 8923 %}
8889 8924
8890 8925 //----------- DivL-By-Constant-Expansions--------------------------------------
8891 8926 // DivI cases are handled by the compiler
8892 8927
8893 8928 // Magic constant, reciprocal of 10
8894 8929 instruct loadConL_0x6666666666666667(rRegL dst)
8895 8930 %{
8896 8931 effect(DEF dst);
8897 8932
8898 8933 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %}
8899 8934 ins_encode(load_immL(dst, 0x6666666666666667));
8900 8935 ins_pipe(ialu_reg);
8901 8936 %}
8902 8937
8903 8938 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8904 8939 %{
8905 8940 effect(DEF dst, USE src, USE_KILL rax, KILL cr);
8906 8941
8907 8942 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %}
8908 8943 opcode(0xF7, 0x5); /* Opcode F7 /5 */
8909 8944 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
8910 8945 ins_pipe(ialu_reg_reg_alu0);
8911 8946 %}
8912 8947
8913 8948 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr)
8914 8949 %{
8915 8950 effect(USE_DEF dst, KILL cr);
8916 8951
8917 8952 format %{ "sarq $dst, #63\t# Used in div-by-10" %}
8918 8953 opcode(0xC1, 0x7); /* C1 /7 ib */
8919 8954 ins_encode(reg_opc_imm_wide(dst, 0x3F));
8920 8955 ins_pipe(ialu_reg);
8921 8956 %}
8922 8957
8923 8958 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr)
8924 8959 %{
8925 8960 effect(USE_DEF dst, KILL cr);
8926 8961
8927 8962 format %{ "sarq $dst, #2\t# Used in div-by-10" %}
8928 8963 opcode(0xC1, 0x7); /* C1 /7 ib */
8929 8964 ins_encode(reg_opc_imm_wide(dst, 0x2));
8930 8965 ins_pipe(ialu_reg);
8931 8966 %}
8932 8967
8933 8968 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div)
8934 8969 %{
8935 8970 match(Set dst (DivL src div));
8936 8971
8937 8972 ins_cost((5+8)*100);
8938 8973 expand %{
8939 8974 rax_RegL rax; // Killed temp
8940 8975 rFlagsReg cr; // Killed
8941 8976 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667
8942 8977 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src
8943 8978 sarL_rReg_63(src, cr); // sarq src, 63
8944 8979 sarL_rReg_2(dst, cr); // sarq rdx, 2
8945 8980 subL_rReg(dst, src, cr); // subl rdx, src
8946 8981 %}
8947 8982 %}
8948 8983
8949 8984 //-----------------------------------------------------------------------------
8950 8985
8951 8986 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div,
8952 8987 rFlagsReg cr)
8953 8988 %{
8954 8989 match(Set rdx (ModI rax div));
8955 8990 effect(KILL rax, KILL cr);
8956 8991
8957 8992 ins_cost(300); // XXX
8958 8993 format %{ "cmpl rax, 0x80000000\t# irem\n\t"
8959 8994 "jne,s normal\n\t"
8960 8995 "xorl rdx, rdx\n\t"
8961 8996 "cmpl $div, -1\n\t"
8962 8997 "je,s done\n"
8963 8998 "normal: cdql\n\t"
8964 8999 "idivl $div\n"
8965 9000 "done:" %}
8966 9001 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8967 9002 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8968 9003 ins_pipe(ialu_reg_reg_alu0);
8969 9004 %}
8970 9005
8971 9006 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div,
8972 9007 rFlagsReg cr)
8973 9008 %{
8974 9009 match(Set rdx (ModL rax div));
8975 9010 effect(KILL rax, KILL cr);
8976 9011
8977 9012 ins_cost(300); // XXX
8978 9013 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t"
8979 9014 "cmpq rax, rdx\n\t"
8980 9015 "jne,s normal\n\t"
8981 9016 "xorl rdx, rdx\n\t"
8982 9017 "cmpq $div, -1\n\t"
8983 9018 "je,s done\n"
8984 9019 "normal: cdqq\n\t"
8985 9020 "idivq $div\n"
8986 9021 "done:" %}
8987 9022 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8988 9023 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8989 9024 ins_pipe(ialu_reg_reg_alu0);
8990 9025 %}
8991 9026
8992 9027 // Integer Shift Instructions
8993 9028 // Shift Left by one
8994 9029 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8995 9030 %{
8996 9031 match(Set dst (LShiftI dst shift));
8997 9032 effect(KILL cr);
8998 9033
8999 9034 format %{ "sall $dst, $shift" %}
9000 9035 opcode(0xD1, 0x4); /* D1 /4 */
9001 9036 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9002 9037 ins_pipe(ialu_reg);
9003 9038 %}
9004 9039
9005 9040 // Shift Left by one
9006 9041 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9007 9042 %{
9008 9043 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
9009 9044 effect(KILL cr);
9010 9045
9011 9046 format %{ "sall $dst, $shift\t" %}
9012 9047 opcode(0xD1, 0x4); /* D1 /4 */
9013 9048 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9014 9049 ins_pipe(ialu_mem_imm);
9015 9050 %}
9016 9051
9017 9052 // Shift Left by 8-bit immediate
9018 9053 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
9019 9054 %{
9020 9055 match(Set dst (LShiftI dst shift));
9021 9056 effect(KILL cr);
9022 9057
9023 9058 format %{ "sall $dst, $shift" %}
9024 9059 opcode(0xC1, 0x4); /* C1 /4 ib */
9025 9060 ins_encode(reg_opc_imm(dst, shift));
9026 9061 ins_pipe(ialu_reg);
9027 9062 %}
9028 9063
9029 9064 // Shift Left by 8-bit immediate
9030 9065 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9031 9066 %{
9032 9067 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
9033 9068 effect(KILL cr);
9034 9069
9035 9070 format %{ "sall $dst, $shift" %}
9036 9071 opcode(0xC1, 0x4); /* C1 /4 ib */
9037 9072 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
9038 9073 ins_pipe(ialu_mem_imm);
9039 9074 %}
9040 9075
9041 9076 // Shift Left by variable
9042 9077 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
9043 9078 %{
9044 9079 match(Set dst (LShiftI dst shift));
9045 9080 effect(KILL cr);
9046 9081
9047 9082 format %{ "sall $dst, $shift" %}
9048 9083 opcode(0xD3, 0x4); /* D3 /4 */
9049 9084 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9050 9085 ins_pipe(ialu_reg_reg);
9051 9086 %}
9052 9087
9053 9088 // Shift Left by variable
9054 9089 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9055 9090 %{
9056 9091 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
9057 9092 effect(KILL cr);
9058 9093
9059 9094 format %{ "sall $dst, $shift" %}
9060 9095 opcode(0xD3, 0x4); /* D3 /4 */
9061 9096 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9062 9097 ins_pipe(ialu_mem_reg);
9063 9098 %}
9064 9099
9065 9100 // Arithmetic shift right by one
9066 9101 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
9067 9102 %{
9068 9103 match(Set dst (RShiftI dst shift));
9069 9104 effect(KILL cr);
9070 9105
9071 9106 format %{ "sarl $dst, $shift" %}
9072 9107 opcode(0xD1, 0x7); /* D1 /7 */
9073 9108 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9074 9109 ins_pipe(ialu_reg);
9075 9110 %}
9076 9111
9077 9112 // Arithmetic shift right by one
9078 9113 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9079 9114 %{
9080 9115 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
9081 9116 effect(KILL cr);
9082 9117
9083 9118 format %{ "sarl $dst, $shift" %}
9084 9119 opcode(0xD1, 0x7); /* D1 /7 */
9085 9120 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9086 9121 ins_pipe(ialu_mem_imm);
9087 9122 %}
9088 9123
9089 9124 // Arithmetic Shift Right by 8-bit immediate
9090 9125 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
9091 9126 %{
9092 9127 match(Set dst (RShiftI dst shift));
9093 9128 effect(KILL cr);
9094 9129
9095 9130 format %{ "sarl $dst, $shift" %}
9096 9131 opcode(0xC1, 0x7); /* C1 /7 ib */
9097 9132 ins_encode(reg_opc_imm(dst, shift));
9098 9133 ins_pipe(ialu_mem_imm);
9099 9134 %}
9100 9135
9101 9136 // Arithmetic Shift Right by 8-bit immediate
9102 9137 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9103 9138 %{
9104 9139 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
9105 9140 effect(KILL cr);
9106 9141
9107 9142 format %{ "sarl $dst, $shift" %}
9108 9143 opcode(0xC1, 0x7); /* C1 /7 ib */
9109 9144 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
9110 9145 ins_pipe(ialu_mem_imm);
9111 9146 %}
9112 9147
9113 9148 // Arithmetic Shift Right by variable
9114 9149 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
9115 9150 %{
9116 9151 match(Set dst (RShiftI dst shift));
9117 9152 effect(KILL cr);
9118 9153
9119 9154 format %{ "sarl $dst, $shift" %}
9120 9155 opcode(0xD3, 0x7); /* D3 /7 */
9121 9156 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9122 9157 ins_pipe(ialu_reg_reg);
9123 9158 %}
9124 9159
9125 9160 // Arithmetic Shift Right by variable
9126 9161 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9127 9162 %{
9128 9163 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
9129 9164 effect(KILL cr);
9130 9165
9131 9166 format %{ "sarl $dst, $shift" %}
9132 9167 opcode(0xD3, 0x7); /* D3 /7 */
9133 9168 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9134 9169 ins_pipe(ialu_mem_reg);
9135 9170 %}
9136 9171
9137 9172 // Logical shift right by one
9138 9173 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
9139 9174 %{
9140 9175 match(Set dst (URShiftI dst shift));
9141 9176 effect(KILL cr);
9142 9177
9143 9178 format %{ "shrl $dst, $shift" %}
9144 9179 opcode(0xD1, 0x5); /* D1 /5 */
9145 9180 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9146 9181 ins_pipe(ialu_reg);
9147 9182 %}
9148 9183
9149 9184 // Logical shift right by one
9150 9185 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9151 9186 %{
9152 9187 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
9153 9188 effect(KILL cr);
9154 9189
9155 9190 format %{ "shrl $dst, $shift" %}
9156 9191 opcode(0xD1, 0x5); /* D1 /5 */
9157 9192 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9158 9193 ins_pipe(ialu_mem_imm);
9159 9194 %}
9160 9195
9161 9196 // Logical Shift Right by 8-bit immediate
9162 9197 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
9163 9198 %{
9164 9199 match(Set dst (URShiftI dst shift));
9165 9200 effect(KILL cr);
9166 9201
9167 9202 format %{ "shrl $dst, $shift" %}
9168 9203 opcode(0xC1, 0x5); /* C1 /5 ib */
9169 9204 ins_encode(reg_opc_imm(dst, shift));
9170 9205 ins_pipe(ialu_reg);
9171 9206 %}
9172 9207
9173 9208 // Logical Shift Right by 8-bit immediate
9174 9209 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9175 9210 %{
9176 9211 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
9177 9212 effect(KILL cr);
9178 9213
9179 9214 format %{ "shrl $dst, $shift" %}
9180 9215 opcode(0xC1, 0x5); /* C1 /5 ib */
9181 9216 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
9182 9217 ins_pipe(ialu_mem_imm);
9183 9218 %}
9184 9219
9185 9220 // Logical Shift Right by variable
9186 9221 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
9187 9222 %{
9188 9223 match(Set dst (URShiftI dst shift));
9189 9224 effect(KILL cr);
9190 9225
9191 9226 format %{ "shrl $dst, $shift" %}
9192 9227 opcode(0xD3, 0x5); /* D3 /5 */
9193 9228 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9194 9229 ins_pipe(ialu_reg_reg);
9195 9230 %}
9196 9231
9197 9232 // Logical Shift Right by variable
9198 9233 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9199 9234 %{
9200 9235 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
9201 9236 effect(KILL cr);
9202 9237
9203 9238 format %{ "shrl $dst, $shift" %}
9204 9239 opcode(0xD3, 0x5); /* D3 /5 */
9205 9240 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
9206 9241 ins_pipe(ialu_mem_reg);
9207 9242 %}
9208 9243
9209 9244 // Long Shift Instructions
9210 9245 // Shift Left by one
9211 9246 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
9212 9247 %{
9213 9248 match(Set dst (LShiftL dst shift));
9214 9249 effect(KILL cr);
9215 9250
9216 9251 format %{ "salq $dst, $shift" %}
9217 9252 opcode(0xD1, 0x4); /* D1 /4 */
9218 9253 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9219 9254 ins_pipe(ialu_reg);
9220 9255 %}
9221 9256
9222 9257 // Shift Left by one
9223 9258 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9224 9259 %{
9225 9260 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
9226 9261 effect(KILL cr);
9227 9262
9228 9263 format %{ "salq $dst, $shift" %}
9229 9264 opcode(0xD1, 0x4); /* D1 /4 */
9230 9265 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9231 9266 ins_pipe(ialu_mem_imm);
9232 9267 %}
9233 9268
9234 9269 // Shift Left by 8-bit immediate
9235 9270 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
9236 9271 %{
9237 9272 match(Set dst (LShiftL dst shift));
9238 9273 effect(KILL cr);
9239 9274
9240 9275 format %{ "salq $dst, $shift" %}
9241 9276 opcode(0xC1, 0x4); /* C1 /4 ib */
9242 9277 ins_encode(reg_opc_imm_wide(dst, shift));
9243 9278 ins_pipe(ialu_reg);
9244 9279 %}
9245 9280
9246 9281 // Shift Left by 8-bit immediate
9247 9282 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9248 9283 %{
9249 9284 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
9250 9285 effect(KILL cr);
9251 9286
9252 9287 format %{ "salq $dst, $shift" %}
9253 9288 opcode(0xC1, 0x4); /* C1 /4 ib */
9254 9289 ins_encode(REX_mem_wide(dst), OpcP,
9255 9290 RM_opc_mem(secondary, dst), Con8or32(shift));
9256 9291 ins_pipe(ialu_mem_imm);
9257 9292 %}
9258 9293
9259 9294 // Shift Left by variable
9260 9295 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
9261 9296 %{
9262 9297 match(Set dst (LShiftL dst shift));
9263 9298 effect(KILL cr);
9264 9299
9265 9300 format %{ "salq $dst, $shift" %}
9266 9301 opcode(0xD3, 0x4); /* D3 /4 */
9267 9302 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9268 9303 ins_pipe(ialu_reg_reg);
9269 9304 %}
9270 9305
9271 9306 // Shift Left by variable
9272 9307 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9273 9308 %{
9274 9309 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
9275 9310 effect(KILL cr);
9276 9311
9277 9312 format %{ "salq $dst, $shift" %}
9278 9313 opcode(0xD3, 0x4); /* D3 /4 */
9279 9314 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9280 9315 ins_pipe(ialu_mem_reg);
9281 9316 %}
9282 9317
9283 9318 // Arithmetic shift right by one
9284 9319 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
9285 9320 %{
9286 9321 match(Set dst (RShiftL dst shift));
9287 9322 effect(KILL cr);
9288 9323
9289 9324 format %{ "sarq $dst, $shift" %}
9290 9325 opcode(0xD1, 0x7); /* D1 /7 */
9291 9326 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9292 9327 ins_pipe(ialu_reg);
9293 9328 %}
9294 9329
9295 9330 // Arithmetic shift right by one
9296 9331 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9297 9332 %{
9298 9333 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
9299 9334 effect(KILL cr);
9300 9335
9301 9336 format %{ "sarq $dst, $shift" %}
9302 9337 opcode(0xD1, 0x7); /* D1 /7 */
9303 9338 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9304 9339 ins_pipe(ialu_mem_imm);
9305 9340 %}
9306 9341
9307 9342 // Arithmetic Shift Right by 8-bit immediate
9308 9343 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
9309 9344 %{
9310 9345 match(Set dst (RShiftL dst shift));
9311 9346 effect(KILL cr);
9312 9347
9313 9348 format %{ "sarq $dst, $shift" %}
9314 9349 opcode(0xC1, 0x7); /* C1 /7 ib */
9315 9350 ins_encode(reg_opc_imm_wide(dst, shift));
9316 9351 ins_pipe(ialu_mem_imm);
9317 9352 %}
9318 9353
9319 9354 // Arithmetic Shift Right by 8-bit immediate
9320 9355 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9321 9356 %{
9322 9357 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
9323 9358 effect(KILL cr);
9324 9359
9325 9360 format %{ "sarq $dst, $shift" %}
9326 9361 opcode(0xC1, 0x7); /* C1 /7 ib */
9327 9362 ins_encode(REX_mem_wide(dst), OpcP,
9328 9363 RM_opc_mem(secondary, dst), Con8or32(shift));
9329 9364 ins_pipe(ialu_mem_imm);
9330 9365 %}
9331 9366
9332 9367 // Arithmetic Shift Right by variable
9333 9368 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
9334 9369 %{
9335 9370 match(Set dst (RShiftL dst shift));
9336 9371 effect(KILL cr);
9337 9372
9338 9373 format %{ "sarq $dst, $shift" %}
9339 9374 opcode(0xD3, 0x7); /* D3 /7 */
9340 9375 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9341 9376 ins_pipe(ialu_reg_reg);
9342 9377 %}
9343 9378
9344 9379 // Arithmetic Shift Right by variable
9345 9380 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9346 9381 %{
9347 9382 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
9348 9383 effect(KILL cr);
9349 9384
9350 9385 format %{ "sarq $dst, $shift" %}
9351 9386 opcode(0xD3, 0x7); /* D3 /7 */
9352 9387 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9353 9388 ins_pipe(ialu_mem_reg);
9354 9389 %}
9355 9390
9356 9391 // Logical shift right by one
9357 9392 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
9358 9393 %{
9359 9394 match(Set dst (URShiftL dst shift));
9360 9395 effect(KILL cr);
9361 9396
9362 9397 format %{ "shrq $dst, $shift" %}
9363 9398 opcode(0xD1, 0x5); /* D1 /5 */
9364 9399 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst ));
9365 9400 ins_pipe(ialu_reg);
9366 9401 %}
9367 9402
9368 9403 // Logical shift right by one
9369 9404 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
9370 9405 %{
9371 9406 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
9372 9407 effect(KILL cr);
9373 9408
9374 9409 format %{ "shrq $dst, $shift" %}
9375 9410 opcode(0xD1, 0x5); /* D1 /5 */
9376 9411 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9377 9412 ins_pipe(ialu_mem_imm);
9378 9413 %}
9379 9414
9380 9415 // Logical Shift Right by 8-bit immediate
9381 9416 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
9382 9417 %{
9383 9418 match(Set dst (URShiftL dst shift));
9384 9419 effect(KILL cr);
9385 9420
9386 9421 format %{ "shrq $dst, $shift" %}
9387 9422 opcode(0xC1, 0x5); /* C1 /5 ib */
9388 9423 ins_encode(reg_opc_imm_wide(dst, shift));
9389 9424 ins_pipe(ialu_reg);
9390 9425 %}
9391 9426
9392 9427
9393 9428 // Logical Shift Right by 8-bit immediate
9394 9429 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
9395 9430 %{
9396 9431 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
9397 9432 effect(KILL cr);
9398 9433
9399 9434 format %{ "shrq $dst, $shift" %}
9400 9435 opcode(0xC1, 0x5); /* C1 /5 ib */
9401 9436 ins_encode(REX_mem_wide(dst), OpcP,
9402 9437 RM_opc_mem(secondary, dst), Con8or32(shift));
9403 9438 ins_pipe(ialu_mem_imm);
9404 9439 %}
9405 9440
9406 9441 // Logical Shift Right by variable
9407 9442 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
9408 9443 %{
9409 9444 match(Set dst (URShiftL dst shift));
9410 9445 effect(KILL cr);
9411 9446
9412 9447 format %{ "shrq $dst, $shift" %}
9413 9448 opcode(0xD3, 0x5); /* D3 /5 */
9414 9449 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9415 9450 ins_pipe(ialu_reg_reg);
9416 9451 %}
9417 9452
9418 9453 // Logical Shift Right by variable
9419 9454 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
9420 9455 %{
9421 9456 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
9422 9457 effect(KILL cr);
9423 9458
9424 9459 format %{ "shrq $dst, $shift" %}
9425 9460 opcode(0xD3, 0x5); /* D3 /5 */
9426 9461 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
9427 9462 ins_pipe(ialu_mem_reg);
9428 9463 %}
9429 9464
9430 9465 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
9431 9466 // This idiom is used by the compiler for the i2b bytecode.
9432 9467 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour)
9433 9468 %{
9434 9469 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
9435 9470
9436 9471 format %{ "movsbl $dst, $src\t# i2b" %}
9437 9472 opcode(0x0F, 0xBE);
9438 9473 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9439 9474 ins_pipe(ialu_reg_reg);
9440 9475 %}
9441 9476
9442 9477 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
9443 9478 // This idiom is used by the compiler the i2s bytecode.
9444 9479 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen)
9445 9480 %{
9446 9481 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
9447 9482
9448 9483 format %{ "movswl $dst, $src\t# i2s" %}
9449 9484 opcode(0x0F, 0xBF);
9450 9485 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9451 9486 ins_pipe(ialu_reg_reg);
9452 9487 %}
9453 9488
9454 9489 // ROL/ROR instructions
9455 9490
9456 9491 // ROL expand
9457 9492 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{
9458 9493 effect(KILL cr, USE_DEF dst);
9459 9494
9460 9495 format %{ "roll $dst" %}
9461 9496 opcode(0xD1, 0x0); /* Opcode D1 /0 */
9462 9497 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9463 9498 ins_pipe(ialu_reg);
9464 9499 %}
9465 9500
9466 9501 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{
9467 9502 effect(USE_DEF dst, USE shift, KILL cr);
9468 9503
9469 9504 format %{ "roll $dst, $shift" %}
9470 9505 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
9471 9506 ins_encode( reg_opc_imm(dst, shift) );
9472 9507 ins_pipe(ialu_reg);
9473 9508 %}
9474 9509
9475 9510 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
9476 9511 %{
9477 9512 effect(USE_DEF dst, USE shift, KILL cr);
9478 9513
9479 9514 format %{ "roll $dst, $shift" %}
9480 9515 opcode(0xD3, 0x0); /* Opcode D3 /0 */
9481 9516 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9482 9517 ins_pipe(ialu_reg_reg);
9483 9518 %}
9484 9519 // end of ROL expand
9485 9520
9486 9521 // Rotate Left by one
9487 9522 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
9488 9523 %{
9489 9524 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
9490 9525
9491 9526 expand %{
9492 9527 rolI_rReg_imm1(dst, cr);
9493 9528 %}
9494 9529 %}
9495 9530
9496 9531 // Rotate Left by 8-bit immediate
9497 9532 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
9498 9533 %{
9499 9534 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9500 9535 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
9501 9536
9502 9537 expand %{
9503 9538 rolI_rReg_imm8(dst, lshift, cr);
9504 9539 %}
9505 9540 %}
9506 9541
9507 9542 // Rotate Left by variable
9508 9543 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9509 9544 %{
9510 9545 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift))));
9511 9546
9512 9547 expand %{
9513 9548 rolI_rReg_CL(dst, shift, cr);
9514 9549 %}
9515 9550 %}
9516 9551
9517 9552 // Rotate Left by variable
9518 9553 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
9519 9554 %{
9520 9555 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift))));
9521 9556
9522 9557 expand %{
9523 9558 rolI_rReg_CL(dst, shift, cr);
9524 9559 %}
9525 9560 %}
9526 9561
9527 9562 // ROR expand
9528 9563 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr)
9529 9564 %{
9530 9565 effect(USE_DEF dst, KILL cr);
9531 9566
9532 9567 format %{ "rorl $dst" %}
9533 9568 opcode(0xD1, 0x1); /* D1 /1 */
9534 9569 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9535 9570 ins_pipe(ialu_reg);
9536 9571 %}
9537 9572
9538 9573 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr)
9539 9574 %{
9540 9575 effect(USE_DEF dst, USE shift, KILL cr);
9541 9576
9542 9577 format %{ "rorl $dst, $shift" %}
9543 9578 opcode(0xC1, 0x1); /* C1 /1 ib */
9544 9579 ins_encode(reg_opc_imm(dst, shift));
9545 9580 ins_pipe(ialu_reg);
9546 9581 %}
9547 9582
9548 9583 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
9549 9584 %{
9550 9585 effect(USE_DEF dst, USE shift, KILL cr);
9551 9586
9552 9587 format %{ "rorl $dst, $shift" %}
9553 9588 opcode(0xD3, 0x1); /* D3 /1 */
9554 9589 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
9555 9590 ins_pipe(ialu_reg_reg);
9556 9591 %}
9557 9592 // end of ROR expand
9558 9593
9559 9594 // Rotate Right by one
9560 9595 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
9561 9596 %{
9562 9597 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
9563 9598
9564 9599 expand %{
9565 9600 rorI_rReg_imm1(dst, cr);
9566 9601 %}
9567 9602 %}
9568 9603
9569 9604 // Rotate Right by 8-bit immediate
9570 9605 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
9571 9606 %{
9572 9607 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9573 9608 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
9574 9609
9575 9610 expand %{
9576 9611 rorI_rReg_imm8(dst, rshift, cr);
9577 9612 %}
9578 9613 %}
9579 9614
9580 9615 // Rotate Right by variable
9581 9616 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9582 9617 %{
9583 9618 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift))));
9584 9619
9585 9620 expand %{
9586 9621 rorI_rReg_CL(dst, shift, cr);
9587 9622 %}
9588 9623 %}
9589 9624
9590 9625 // Rotate Right by variable
9591 9626 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
9592 9627 %{
9593 9628 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift))));
9594 9629
9595 9630 expand %{
9596 9631 rorI_rReg_CL(dst, shift, cr);
9597 9632 %}
9598 9633 %}
9599 9634
9600 9635 // for long rotate
9601 9636 // ROL expand
9602 9637 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{
9603 9638 effect(USE_DEF dst, KILL cr);
9604 9639
9605 9640 format %{ "rolq $dst" %}
9606 9641 opcode(0xD1, 0x0); /* Opcode D1 /0 */
9607 9642 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9608 9643 ins_pipe(ialu_reg);
9609 9644 %}
9610 9645
9611 9646 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{
9612 9647 effect(USE_DEF dst, USE shift, KILL cr);
9613 9648
9614 9649 format %{ "rolq $dst, $shift" %}
9615 9650 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
9616 9651 ins_encode( reg_opc_imm_wide(dst, shift) );
9617 9652 ins_pipe(ialu_reg);
9618 9653 %}
9619 9654
9620 9655 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
9621 9656 %{
9622 9657 effect(USE_DEF dst, USE shift, KILL cr);
9623 9658
9624 9659 format %{ "rolq $dst, $shift" %}
9625 9660 opcode(0xD3, 0x0); /* Opcode D3 /0 */
9626 9661 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9627 9662 ins_pipe(ialu_reg_reg);
9628 9663 %}
9629 9664 // end of ROL expand
9630 9665
9631 9666 // Rotate Left by one
9632 9667 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
9633 9668 %{
9634 9669 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
9635 9670
9636 9671 expand %{
9637 9672 rolL_rReg_imm1(dst, cr);
9638 9673 %}
9639 9674 %}
9640 9675
9641 9676 // Rotate Left by 8-bit immediate
9642 9677 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
9643 9678 %{
9644 9679 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9645 9680 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
9646 9681
9647 9682 expand %{
9648 9683 rolL_rReg_imm8(dst, lshift, cr);
9649 9684 %}
9650 9685 %}
9651 9686
9652 9687 // Rotate Left by variable
9653 9688 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9654 9689 %{
9655 9690 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift))));
9656 9691
9657 9692 expand %{
9658 9693 rolL_rReg_CL(dst, shift, cr);
9659 9694 %}
9660 9695 %}
9661 9696
9662 9697 // Rotate Left by variable
9663 9698 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
9664 9699 %{
9665 9700 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift))));
9666 9701
9667 9702 expand %{
9668 9703 rolL_rReg_CL(dst, shift, cr);
9669 9704 %}
9670 9705 %}
9671 9706
9672 9707 // ROR expand
9673 9708 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr)
9674 9709 %{
9675 9710 effect(USE_DEF dst, KILL cr);
9676 9711
9677 9712 format %{ "rorq $dst" %}
9678 9713 opcode(0xD1, 0x1); /* D1 /1 */
9679 9714 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9680 9715 ins_pipe(ialu_reg);
9681 9716 %}
9682 9717
9683 9718 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr)
9684 9719 %{
9685 9720 effect(USE_DEF dst, USE shift, KILL cr);
9686 9721
9687 9722 format %{ "rorq $dst, $shift" %}
9688 9723 opcode(0xC1, 0x1); /* C1 /1 ib */
9689 9724 ins_encode(reg_opc_imm_wide(dst, shift));
9690 9725 ins_pipe(ialu_reg);
9691 9726 %}
9692 9727
9693 9728 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
9694 9729 %{
9695 9730 effect(USE_DEF dst, USE shift, KILL cr);
9696 9731
9697 9732 format %{ "rorq $dst, $shift" %}
9698 9733 opcode(0xD3, 0x1); /* D3 /1 */
9699 9734 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
9700 9735 ins_pipe(ialu_reg_reg);
9701 9736 %}
9702 9737 // end of ROR expand
9703 9738
9704 9739 // Rotate Right by one
9705 9740 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
9706 9741 %{
9707 9742 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
9708 9743
9709 9744 expand %{
9710 9745 rorL_rReg_imm1(dst, cr);
9711 9746 %}
9712 9747 %}
9713 9748
9714 9749 // Rotate Right by 8-bit immediate
9715 9750 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
9716 9751 %{
9717 9752 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9718 9753 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
9719 9754
9720 9755 expand %{
9721 9756 rorL_rReg_imm8(dst, rshift, cr);
9722 9757 %}
9723 9758 %}
9724 9759
9725 9760 // Rotate Right by variable
9726 9761 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
9727 9762 %{
9728 9763 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift))));
9729 9764
9730 9765 expand %{
9731 9766 rorL_rReg_CL(dst, shift, cr);
9732 9767 %}
9733 9768 %}
9734 9769
9735 9770 // Rotate Right by variable
9736 9771 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
9737 9772 %{
9738 9773 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift))));
9739 9774
9740 9775 expand %{
9741 9776 rorL_rReg_CL(dst, shift, cr);
9742 9777 %}
9743 9778 %}
9744 9779
9745 9780 // Logical Instructions
9746 9781
9747 9782 // Integer Logical Instructions
9748 9783
9749 9784 // And Instructions
9750 9785 // And Register with Register
9751 9786 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9752 9787 %{
9753 9788 match(Set dst (AndI dst src));
9754 9789 effect(KILL cr);
9755 9790
9756 9791 format %{ "andl $dst, $src\t# int" %}
9757 9792 opcode(0x23);
9758 9793 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9759 9794 ins_pipe(ialu_reg_reg);
9760 9795 %}
9761 9796
9762 9797 // And Register with Immediate 255
9763 9798 instruct andI_rReg_imm255(rRegI dst, immI_255 src)
9764 9799 %{
9765 9800 match(Set dst (AndI dst src));
9766 9801
9767 9802 format %{ "movzbl $dst, $dst\t# int & 0xFF" %}
9768 9803 opcode(0x0F, 0xB6);
9769 9804 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9770 9805 ins_pipe(ialu_reg);
9771 9806 %}
9772 9807
9773 9808 // And Register with Immediate 255 and promote to long
9774 9809 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask)
9775 9810 %{
9776 9811 match(Set dst (ConvI2L (AndI src mask)));
9777 9812
9778 9813 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %}
9779 9814 opcode(0x0F, 0xB6);
9780 9815 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9781 9816 ins_pipe(ialu_reg);
9782 9817 %}
9783 9818
9784 9819 // And Register with Immediate 65535
9785 9820 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src)
9786 9821 %{
9787 9822 match(Set dst (AndI dst src));
9788 9823
9789 9824 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %}
9790 9825 opcode(0x0F, 0xB7);
9791 9826 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9792 9827 ins_pipe(ialu_reg);
9793 9828 %}
9794 9829
9795 9830 // And Register with Immediate 65535 and promote to long
9796 9831 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask)
9797 9832 %{
9798 9833 match(Set dst (ConvI2L (AndI src mask)));
9799 9834
9800 9835 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %}
9801 9836 opcode(0x0F, 0xB7);
9802 9837 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9803 9838 ins_pipe(ialu_reg);
9804 9839 %}
9805 9840
9806 9841 // And Register with Immediate
9807 9842 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9808 9843 %{
9809 9844 match(Set dst (AndI dst src));
9810 9845 effect(KILL cr);
9811 9846
9812 9847 format %{ "andl $dst, $src\t# int" %}
9813 9848 opcode(0x81, 0x04); /* Opcode 81 /4 */
9814 9849 ins_encode(OpcSErm(dst, src), Con8or32(src));
9815 9850 ins_pipe(ialu_reg);
9816 9851 %}
9817 9852
9818 9853 // And Register with Memory
9819 9854 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9820 9855 %{
9821 9856 match(Set dst (AndI dst (LoadI src)));
9822 9857 effect(KILL cr);
9823 9858
9824 9859 ins_cost(125);
9825 9860 format %{ "andl $dst, $src\t# int" %}
9826 9861 opcode(0x23);
9827 9862 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9828 9863 ins_pipe(ialu_reg_mem);
9829 9864 %}
9830 9865
9831 9866 // And Memory with Register
9832 9867 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9833 9868 %{
9834 9869 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9835 9870 effect(KILL cr);
9836 9871
9837 9872 ins_cost(150);
9838 9873 format %{ "andl $dst, $src\t# int" %}
9839 9874 opcode(0x21); /* Opcode 21 /r */
9840 9875 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9841 9876 ins_pipe(ialu_mem_reg);
9842 9877 %}
9843 9878
9844 9879 // And Memory with Immediate
9845 9880 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr)
9846 9881 %{
9847 9882 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9848 9883 effect(KILL cr);
9849 9884
9850 9885 ins_cost(125);
9851 9886 format %{ "andl $dst, $src\t# int" %}
9852 9887 opcode(0x81, 0x4); /* Opcode 81 /4 id */
9853 9888 ins_encode(REX_mem(dst), OpcSE(src),
9854 9889 RM_opc_mem(secondary, dst), Con8or32(src));
9855 9890 ins_pipe(ialu_mem_imm);
9856 9891 %}
9857 9892
9858 9893 // Or Instructions
9859 9894 // Or Register with Register
9860 9895 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9861 9896 %{
9862 9897 match(Set dst (OrI dst src));
9863 9898 effect(KILL cr);
9864 9899
9865 9900 format %{ "orl $dst, $src\t# int" %}
9866 9901 opcode(0x0B);
9867 9902 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9868 9903 ins_pipe(ialu_reg_reg);
9869 9904 %}
9870 9905
9871 9906 // Or Register with Immediate
9872 9907 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9873 9908 %{
9874 9909 match(Set dst (OrI dst src));
9875 9910 effect(KILL cr);
9876 9911
9877 9912 format %{ "orl $dst, $src\t# int" %}
9878 9913 opcode(0x81, 0x01); /* Opcode 81 /1 id */
9879 9914 ins_encode(OpcSErm(dst, src), Con8or32(src));
9880 9915 ins_pipe(ialu_reg);
9881 9916 %}
9882 9917
9883 9918 // Or Register with Memory
9884 9919 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9885 9920 %{
9886 9921 match(Set dst (OrI dst (LoadI src)));
9887 9922 effect(KILL cr);
9888 9923
9889 9924 ins_cost(125);
9890 9925 format %{ "orl $dst, $src\t# int" %}
9891 9926 opcode(0x0B);
9892 9927 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9893 9928 ins_pipe(ialu_reg_mem);
9894 9929 %}
9895 9930
9896 9931 // Or Memory with Register
9897 9932 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9898 9933 %{
9899 9934 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9900 9935 effect(KILL cr);
9901 9936
9902 9937 ins_cost(150);
9903 9938 format %{ "orl $dst, $src\t# int" %}
9904 9939 opcode(0x09); /* Opcode 09 /r */
9905 9940 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9906 9941 ins_pipe(ialu_mem_reg);
9907 9942 %}
9908 9943
9909 9944 // Or Memory with Immediate
9910 9945 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr)
9911 9946 %{
9912 9947 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9913 9948 effect(KILL cr);
9914 9949
9915 9950 ins_cost(125);
9916 9951 format %{ "orl $dst, $src\t# int" %}
9917 9952 opcode(0x81, 0x1); /* Opcode 81 /1 id */
9918 9953 ins_encode(REX_mem(dst), OpcSE(src),
9919 9954 RM_opc_mem(secondary, dst), Con8or32(src));
9920 9955 ins_pipe(ialu_mem_imm);
9921 9956 %}
9922 9957
9923 9958 // Xor Instructions
9924 9959 // Xor Register with Register
9925 9960 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9926 9961 %{
9927 9962 match(Set dst (XorI dst src));
9928 9963 effect(KILL cr);
9929 9964
9930 9965 format %{ "xorl $dst, $src\t# int" %}
9931 9966 opcode(0x33);
9932 9967 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9933 9968 ins_pipe(ialu_reg_reg);
9934 9969 %}
9935 9970
9936 9971 // Xor Register with Immediate -1
9937 9972 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
9938 9973 match(Set dst (XorI dst imm));
9939 9974
9940 9975 format %{ "not $dst" %}
9941 9976 ins_encode %{
9942 9977 __ notl($dst$$Register);
9943 9978 %}
9944 9979 ins_pipe(ialu_reg);
9945 9980 %}
9946 9981
9947 9982 // Xor Register with Immediate
9948 9983 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9949 9984 %{
9950 9985 match(Set dst (XorI dst src));
9951 9986 effect(KILL cr);
9952 9987
9953 9988 format %{ "xorl $dst, $src\t# int" %}
9954 9989 opcode(0x81, 0x06); /* Opcode 81 /6 id */
9955 9990 ins_encode(OpcSErm(dst, src), Con8or32(src));
9956 9991 ins_pipe(ialu_reg);
9957 9992 %}
9958 9993
9959 9994 // Xor Register with Memory
9960 9995 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9961 9996 %{
9962 9997 match(Set dst (XorI dst (LoadI src)));
9963 9998 effect(KILL cr);
9964 9999
9965 10000 ins_cost(125);
9966 10001 format %{ "xorl $dst, $src\t# int" %}
9967 10002 opcode(0x33);
9968 10003 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9969 10004 ins_pipe(ialu_reg_mem);
9970 10005 %}
9971 10006
9972 10007 // Xor Memory with Register
9973 10008 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9974 10009 %{
9975 10010 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9976 10011 effect(KILL cr);
9977 10012
9978 10013 ins_cost(150);
9979 10014 format %{ "xorl $dst, $src\t# int" %}
9980 10015 opcode(0x31); /* Opcode 31 /r */
9981 10016 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9982 10017 ins_pipe(ialu_mem_reg);
9983 10018 %}
9984 10019
9985 10020 // Xor Memory with Immediate
9986 10021 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr)
9987 10022 %{
9988 10023 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9989 10024 effect(KILL cr);
9990 10025
9991 10026 ins_cost(125);
9992 10027 format %{ "xorl $dst, $src\t# int" %}
9993 10028 opcode(0x81, 0x6); /* Opcode 81 /6 id */
9994 10029 ins_encode(REX_mem(dst), OpcSE(src),
9995 10030 RM_opc_mem(secondary, dst), Con8or32(src));
9996 10031 ins_pipe(ialu_mem_imm);
9997 10032 %}
9998 10033
9999 10034
10000 10035 // Long Logical Instructions
10001 10036
10002 10037 // And Instructions
10003 10038 // And Register with Register
10004 10039 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
10005 10040 %{
10006 10041 match(Set dst (AndL dst src));
10007 10042 effect(KILL cr);
10008 10043
10009 10044 format %{ "andq $dst, $src\t# long" %}
10010 10045 opcode(0x23);
10011 10046 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
10012 10047 ins_pipe(ialu_reg_reg);
10013 10048 %}
10014 10049
10015 10050 // And Register with Immediate 255
10016 10051 instruct andL_rReg_imm255(rRegL dst, immL_255 src)
10017 10052 %{
10018 10053 match(Set dst (AndL dst src));
10019 10054
10020 10055 format %{ "movzbq $dst, $dst\t# long & 0xFF" %}
10021 10056 opcode(0x0F, 0xB6);
10022 10057 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
10023 10058 ins_pipe(ialu_reg);
10024 10059 %}
10025 10060
10026 10061 // And Register with Immediate 65535
10027 10062 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
10028 10063 %{
10029 10064 match(Set dst (AndL dst src));
10030 10065
10031 10066 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %}
10032 10067 opcode(0x0F, 0xB7);
10033 10068 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
10034 10069 ins_pipe(ialu_reg);
10035 10070 %}
10036 10071
10037 10072 // And Register with Immediate
10038 10073 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
10039 10074 %{
10040 10075 match(Set dst (AndL dst src));
10041 10076 effect(KILL cr);
10042 10077
10043 10078 format %{ "andq $dst, $src\t# long" %}
10044 10079 opcode(0x81, 0x04); /* Opcode 81 /4 */
10045 10080 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
10046 10081 ins_pipe(ialu_reg);
10047 10082 %}
10048 10083
10049 10084 // And Register with Memory
10050 10085 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
10051 10086 %{
10052 10087 match(Set dst (AndL dst (LoadL src)));
10053 10088 effect(KILL cr);
10054 10089
10055 10090 ins_cost(125);
10056 10091 format %{ "andq $dst, $src\t# long" %}
10057 10092 opcode(0x23);
10058 10093 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
10059 10094 ins_pipe(ialu_reg_mem);
10060 10095 %}
10061 10096
10062 10097 // And Memory with Register
10063 10098 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
10064 10099 %{
10065 10100 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
10066 10101 effect(KILL cr);
10067 10102
10068 10103 ins_cost(150);
10069 10104 format %{ "andq $dst, $src\t# long" %}
10070 10105 opcode(0x21); /* Opcode 21 /r */
10071 10106 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
10072 10107 ins_pipe(ialu_mem_reg);
10073 10108 %}
10074 10109
10075 10110 // And Memory with Immediate
10076 10111 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
10077 10112 %{
10078 10113 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
10079 10114 effect(KILL cr);
10080 10115
10081 10116 ins_cost(125);
10082 10117 format %{ "andq $dst, $src\t# long" %}
10083 10118 opcode(0x81, 0x4); /* Opcode 81 /4 id */
10084 10119 ins_encode(REX_mem_wide(dst), OpcSE(src),
10085 10120 RM_opc_mem(secondary, dst), Con8or32(src));
10086 10121 ins_pipe(ialu_mem_imm);
10087 10122 %}
10088 10123
10089 10124 // Or Instructions
10090 10125 // Or Register with Register
10091 10126 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
10092 10127 %{
10093 10128 match(Set dst (OrL dst src));
10094 10129 effect(KILL cr);
10095 10130
10096 10131 format %{ "orq $dst, $src\t# long" %}
10097 10132 opcode(0x0B);
10098 10133 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
10099 10134 ins_pipe(ialu_reg_reg);
10100 10135 %}
10101 10136
10102 10137 // Use any_RegP to match R15 (TLS register) without spilling.
10103 10138 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
10104 10139 match(Set dst (OrL dst (CastP2X src)));
10105 10140 effect(KILL cr);
10106 10141
10107 10142 format %{ "orq $dst, $src\t# long" %}
10108 10143 opcode(0x0B);
10109 10144 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
10110 10145 ins_pipe(ialu_reg_reg);
10111 10146 %}
10112 10147
10113 10148
10114 10149 // Or Register with Immediate
10115 10150 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
10116 10151 %{
10117 10152 match(Set dst (OrL dst src));
10118 10153 effect(KILL cr);
10119 10154
10120 10155 format %{ "orq $dst, $src\t# long" %}
10121 10156 opcode(0x81, 0x01); /* Opcode 81 /1 id */
10122 10157 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
10123 10158 ins_pipe(ialu_reg);
10124 10159 %}
10125 10160
10126 10161 // Or Register with Memory
10127 10162 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
10128 10163 %{
10129 10164 match(Set dst (OrL dst (LoadL src)));
10130 10165 effect(KILL cr);
10131 10166
10132 10167 ins_cost(125);
10133 10168 format %{ "orq $dst, $src\t# long" %}
10134 10169 opcode(0x0B);
10135 10170 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
10136 10171 ins_pipe(ialu_reg_mem);
10137 10172 %}
10138 10173
10139 10174 // Or Memory with Register
10140 10175 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
10141 10176 %{
10142 10177 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
10143 10178 effect(KILL cr);
10144 10179
10145 10180 ins_cost(150);
10146 10181 format %{ "orq $dst, $src\t# long" %}
10147 10182 opcode(0x09); /* Opcode 09 /r */
10148 10183 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
10149 10184 ins_pipe(ialu_mem_reg);
10150 10185 %}
10151 10186
10152 10187 // Or Memory with Immediate
10153 10188 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
10154 10189 %{
10155 10190 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
10156 10191 effect(KILL cr);
10157 10192
10158 10193 ins_cost(125);
10159 10194 format %{ "orq $dst, $src\t# long" %}
10160 10195 opcode(0x81, 0x1); /* Opcode 81 /1 id */
10161 10196 ins_encode(REX_mem_wide(dst), OpcSE(src),
10162 10197 RM_opc_mem(secondary, dst), Con8or32(src));
10163 10198 ins_pipe(ialu_mem_imm);
10164 10199 %}
10165 10200
10166 10201 // Xor Instructions
10167 10202 // Xor Register with Register
10168 10203 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
10169 10204 %{
10170 10205 match(Set dst (XorL dst src));
10171 10206 effect(KILL cr);
10172 10207
10173 10208 format %{ "xorq $dst, $src\t# long" %}
10174 10209 opcode(0x33);
10175 10210 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
10176 10211 ins_pipe(ialu_reg_reg);
10177 10212 %}
10178 10213
10179 10214 // Xor Register with Immediate -1
10180 10215 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
10181 10216 match(Set dst (XorL dst imm));
10182 10217
10183 10218 format %{ "notq $dst" %}
10184 10219 ins_encode %{
10185 10220 __ notq($dst$$Register);
10186 10221 %}
10187 10222 ins_pipe(ialu_reg);
10188 10223 %}
10189 10224
10190 10225 // Xor Register with Immediate
10191 10226 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
10192 10227 %{
10193 10228 match(Set dst (XorL dst src));
10194 10229 effect(KILL cr);
10195 10230
10196 10231 format %{ "xorq $dst, $src\t# long" %}
10197 10232 opcode(0x81, 0x06); /* Opcode 81 /6 id */
10198 10233 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
10199 10234 ins_pipe(ialu_reg);
10200 10235 %}
10201 10236
10202 10237 // Xor Register with Memory
10203 10238 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
10204 10239 %{
10205 10240 match(Set dst (XorL dst (LoadL src)));
10206 10241 effect(KILL cr);
10207 10242
10208 10243 ins_cost(125);
10209 10244 format %{ "xorq $dst, $src\t# long" %}
10210 10245 opcode(0x33);
10211 10246 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
10212 10247 ins_pipe(ialu_reg_mem);
10213 10248 %}
10214 10249
10215 10250 // Xor Memory with Register
10216 10251 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
10217 10252 %{
10218 10253 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
10219 10254 effect(KILL cr);
10220 10255
10221 10256 ins_cost(150);
10222 10257 format %{ "xorq $dst, $src\t# long" %}
10223 10258 opcode(0x31); /* Opcode 31 /r */
10224 10259 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
10225 10260 ins_pipe(ialu_mem_reg);
10226 10261 %}
10227 10262
10228 10263 // Xor Memory with Immediate
10229 10264 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
10230 10265 %{
10231 10266 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
10232 10267 effect(KILL cr);
10233 10268
10234 10269 ins_cost(125);
10235 10270 format %{ "xorq $dst, $src\t# long" %}
10236 10271 opcode(0x81, 0x6); /* Opcode 81 /6 id */
10237 10272 ins_encode(REX_mem_wide(dst), OpcSE(src),
10238 10273 RM_opc_mem(secondary, dst), Con8or32(src));
10239 10274 ins_pipe(ialu_mem_imm);
10240 10275 %}
10241 10276
10242 10277 // Convert Int to Boolean
10243 10278 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr)
10244 10279 %{
10245 10280 match(Set dst (Conv2B src));
10246 10281 effect(KILL cr);
10247 10282
10248 10283 format %{ "testl $src, $src\t# ci2b\n\t"
10249 10284 "setnz $dst\n\t"
10250 10285 "movzbl $dst, $dst" %}
10251 10286 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl
10252 10287 setNZ_reg(dst),
10253 10288 REX_reg_breg(dst, dst), // movzbl
10254 10289 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
10255 10290 ins_pipe(pipe_slow); // XXX
10256 10291 %}
10257 10292
10258 10293 // Convert Pointer to Boolean
10259 10294 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr)
10260 10295 %{
10261 10296 match(Set dst (Conv2B src));
10262 10297 effect(KILL cr);
10263 10298
10264 10299 format %{ "testq $src, $src\t# cp2b\n\t"
10265 10300 "setnz $dst\n\t"
10266 10301 "movzbl $dst, $dst" %}
10267 10302 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq
10268 10303 setNZ_reg(dst),
10269 10304 REX_reg_breg(dst, dst), // movzbl
10270 10305 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
10271 10306 ins_pipe(pipe_slow); // XXX
10272 10307 %}
10273 10308
10274 10309 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr)
10275 10310 %{
10276 10311 match(Set dst (CmpLTMask p q));
10277 10312 effect(KILL cr);
10278 10313
10279 10314 ins_cost(400); // XXX
10280 10315 format %{ "cmpl $p, $q\t# cmpLTMask\n\t"
10281 10316 "setlt $dst\n\t"
10282 10317 "movzbl $dst, $dst\n\t"
10283 10318 "negl $dst" %}
10284 10319 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl
10285 10320 setLT_reg(dst),
10286 10321 REX_reg_breg(dst, dst), // movzbl
10287 10322 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst),
10288 10323 neg_reg(dst));
10289 10324 ins_pipe(pipe_slow);
10290 10325 %}
10291 10326
10292 10327 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr)
10293 10328 %{
10294 10329 match(Set dst (CmpLTMask dst zero));
10295 10330 effect(KILL cr);
10296 10331
10297 10332 ins_cost(100); // XXX
10298 10333 format %{ "sarl $dst, #31\t# cmpLTMask0" %}
10299 10334 opcode(0xC1, 0x7); /* C1 /7 ib */
10300 10335 ins_encode(reg_opc_imm(dst, 0x1F));
10301 10336 ins_pipe(ialu_reg);
10302 10337 %}
10303 10338
10304 10339
10305 10340 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y,
10306 10341 rRegI tmp,
10307 10342 rFlagsReg cr)
10308 10343 %{
10309 10344 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
10310 10345 effect(TEMP tmp, KILL cr);
10311 10346
10312 10347 ins_cost(400); // XXX
10313 10348 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t"
10314 10349 "sbbl $tmp, $tmp\n\t"
10315 10350 "andl $tmp, $y\n\t"
10316 10351 "addl $p, $tmp" %}
10317 10352 ins_encode(enc_cmpLTP(p, q, y, tmp));
10318 10353 ins_pipe(pipe_cmplt);
10319 10354 %}
10320 10355
10321 10356 /* If I enable this, I encourage spilling in the inner loop of compress.
10322 10357 instruct cadd_cmpLTMask_mem( rRegI p, rRegI q, memory y, rRegI tmp, rFlagsReg cr )
10323 10358 %{
10324 10359 match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q)));
10325 10360 effect( TEMP tmp, KILL cr );
10326 10361 ins_cost(400);
10327 10362
10328 10363 format %{ "SUB $p,$q\n\t"
10329 10364 "SBB RCX,RCX\n\t"
10330 10365 "AND RCX,$y\n\t"
10331 10366 "ADD $p,RCX" %}
10332 10367 ins_encode( enc_cmpLTP_mem(p,q,y,tmp) );
10333 10368 %}
10334 10369 */
10335 10370
10336 10371 //---------- FP Instructions------------------------------------------------
10337 10372
10338 10373 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
10339 10374 %{
10340 10375 match(Set cr (CmpF src1 src2));
10341 10376
10342 10377 ins_cost(145);
10343 10378 format %{ "ucomiss $src1, $src2\n\t"
10344 10379 "jnp,s exit\n\t"
10345 10380 "pushfq\t# saw NaN, set CF\n\t"
10346 10381 "andq [rsp], #0xffffff2b\n\t"
10347 10382 "popfq\n"
10348 10383 "exit: nop\t# avoid branch to branch" %}
10349 10384 opcode(0x0F, 0x2E);
10350 10385 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2),
10351 10386 cmpfp_fixup);
10352 10387 ins_pipe(pipe_slow);
10353 10388 %}
10354 10389
10355 10390 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
10356 10391 match(Set cr (CmpF src1 src2));
10357 10392
10358 10393 ins_cost(145);
10359 10394 format %{ "ucomiss $src1, $src2" %}
10360 10395 ins_encode %{
10361 10396 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
10362 10397 %}
10363 10398 ins_pipe(pipe_slow);
10364 10399 %}
10365 10400
10366 10401 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
10367 10402 %{
10368 10403 match(Set cr (CmpF src1 (LoadF src2)));
10369 10404
10370 10405 ins_cost(145);
10371 10406 format %{ "ucomiss $src1, $src2\n\t"
10372 10407 "jnp,s exit\n\t"
10373 10408 "pushfq\t# saw NaN, set CF\n\t"
10374 10409 "andq [rsp], #0xffffff2b\n\t"
10375 10410 "popfq\n"
10376 10411 "exit: nop\t# avoid branch to branch" %}
10377 10412 opcode(0x0F, 0x2E);
10378 10413 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
10379 10414 cmpfp_fixup);
10380 10415 ins_pipe(pipe_slow);
10381 10416 %}
10382 10417
10383 10418 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
10384 10419 match(Set cr (CmpF src1 (LoadF src2)));
10385 10420
10386 10421 ins_cost(100);
10387 10422 format %{ "ucomiss $src1, $src2" %}
10388 10423 opcode(0x0F, 0x2E);
10389 10424 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
10390 10425 ins_pipe(pipe_slow);
10391 10426 %}
10392 10427
10393 10428 instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
10394 10429 %{
10395 10430 match(Set cr (CmpF src1 src2));
10396 10431
10397 10432 ins_cost(145);
10398 10433 format %{ "ucomiss $src1, $src2\n\t"
10399 10434 "jnp,s exit\n\t"
10400 10435 "pushfq\t# saw NaN, set CF\n\t"
10401 10436 "andq [rsp], #0xffffff2b\n\t"
10402 10437 "popfq\n"
10403 10438 "exit: nop\t# avoid branch to branch" %}
10404 10439 opcode(0x0F, 0x2E);
10405 10440 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2),
10406 10441 cmpfp_fixup);
10407 10442 ins_pipe(pipe_slow);
10408 10443 %}
10409 10444
10410 10445 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
10411 10446 match(Set cr (CmpF src1 src2));
10412 10447
10413 10448 ins_cost(100);
10414 10449 format %{ "ucomiss $src1, $src2" %}
10415 10450 opcode(0x0F, 0x2E);
10416 10451 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
10417 10452 ins_pipe(pipe_slow);
10418 10453 %}
10419 10454
10420 10455 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
10421 10456 %{
10422 10457 match(Set cr (CmpD src1 src2));
10423 10458
10424 10459 ins_cost(145);
10425 10460 format %{ "ucomisd $src1, $src2\n\t"
10426 10461 "jnp,s exit\n\t"
10427 10462 "pushfq\t# saw NaN, set CF\n\t"
10428 10463 "andq [rsp], #0xffffff2b\n\t"
10429 10464 "popfq\n"
10430 10465 "exit: nop\t# avoid branch to branch" %}
10431 10466 opcode(0x66, 0x0F, 0x2E);
10432 10467 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
10433 10468 cmpfp_fixup);
10434 10469 ins_pipe(pipe_slow);
10435 10470 %}
10436 10471
10437 10472 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
10438 10473 match(Set cr (CmpD src1 src2));
10439 10474
10440 10475 ins_cost(100);
10441 10476 format %{ "ucomisd $src1, $src2 test" %}
10442 10477 ins_encode %{
10443 10478 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
10444 10479 %}
10445 10480 ins_pipe(pipe_slow);
10446 10481 %}
10447 10482
10448 10483 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
10449 10484 %{
10450 10485 match(Set cr (CmpD src1 (LoadD src2)));
10451 10486
10452 10487 ins_cost(145);
10453 10488 format %{ "ucomisd $src1, $src2\n\t"
10454 10489 "jnp,s exit\n\t"
10455 10490 "pushfq\t# saw NaN, set CF\n\t"
10456 10491 "andq [rsp], #0xffffff2b\n\t"
10457 10492 "popfq\n"
10458 10493 "exit: nop\t# avoid branch to branch" %}
10459 10494 opcode(0x66, 0x0F, 0x2E);
10460 10495 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
10461 10496 cmpfp_fixup);
10462 10497 ins_pipe(pipe_slow);
10463 10498 %}
10464 10499
10465 10500 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
10466 10501 match(Set cr (CmpD src1 (LoadD src2)));
10467 10502
10468 10503 ins_cost(100);
10469 10504 format %{ "ucomisd $src1, $src2" %}
10470 10505 opcode(0x66, 0x0F, 0x2E);
10471 10506 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
10472 10507 ins_pipe(pipe_slow);
10473 10508 %}
10474 10509
10475 10510 instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
10476 10511 %{
10477 10512 match(Set cr (CmpD src1 src2));
10478 10513
10479 10514 ins_cost(145);
10480 10515 format %{ "ucomisd $src1, [$src2]\n\t"
10481 10516 "jnp,s exit\n\t"
10482 10517 "pushfq\t# saw NaN, set CF\n\t"
10483 10518 "andq [rsp], #0xffffff2b\n\t"
10484 10519 "popfq\n"
10485 10520 "exit: nop\t# avoid branch to branch" %}
10486 10521 opcode(0x66, 0x0F, 0x2E);
10487 10522 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2),
10488 10523 cmpfp_fixup);
10489 10524 ins_pipe(pipe_slow);
10490 10525 %}
10491 10526
10492 10527 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
10493 10528 match(Set cr (CmpD src1 src2));
10494 10529
10495 10530 ins_cost(100);
10496 10531 format %{ "ucomisd $src1, [$src2]" %}
10497 10532 opcode(0x66, 0x0F, 0x2E);
10498 10533 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2));
10499 10534 ins_pipe(pipe_slow);
10500 10535 %}
10501 10536
10502 10537 // Compare into -1,0,1
10503 10538 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
10504 10539 %{
10505 10540 match(Set dst (CmpF3 src1 src2));
10506 10541 effect(KILL cr);
10507 10542
10508 10543 ins_cost(275);
10509 10544 format %{ "ucomiss $src1, $src2\n\t"
10510 10545 "movl $dst, #-1\n\t"
10511 10546 "jp,s done\n\t"
10512 10547 "jb,s done\n\t"
10513 10548 "setne $dst\n\t"
10514 10549 "movzbl $dst, $dst\n"
10515 10550 "done:" %}
10516 10551
10517 10552 opcode(0x0F, 0x2E);
10518 10553 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2),
10519 10554 cmpfp3(dst));
10520 10555 ins_pipe(pipe_slow);
10521 10556 %}
10522 10557
10523 10558 // Compare into -1,0,1
10524 10559 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
10525 10560 %{
10526 10561 match(Set dst (CmpF3 src1 (LoadF src2)));
10527 10562 effect(KILL cr);
10528 10563
10529 10564 ins_cost(275);
10530 10565 format %{ "ucomiss $src1, $src2\n\t"
10531 10566 "movl $dst, #-1\n\t"
10532 10567 "jp,s done\n\t"
10533 10568 "jb,s done\n\t"
10534 10569 "setne $dst\n\t"
10535 10570 "movzbl $dst, $dst\n"
10536 10571 "done:" %}
10537 10572
10538 10573 opcode(0x0F, 0x2E);
10539 10574 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2),
10540 10575 cmpfp3(dst));
10541 10576 ins_pipe(pipe_slow);
10542 10577 %}
10543 10578
10544 10579 // Compare into -1,0,1
10545 10580 instruct cmpF_imm(rRegI dst, regF src1, immF src2, rFlagsReg cr)
10546 10581 %{
10547 10582 match(Set dst (CmpF3 src1 src2));
10548 10583 effect(KILL cr);
10549 10584
10550 10585 ins_cost(275);
10551 10586 format %{ "ucomiss $src1, [$src2]\n\t"
10552 10587 "movl $dst, #-1\n\t"
10553 10588 "jp,s done\n\t"
10554 10589 "jb,s done\n\t"
10555 10590 "setne $dst\n\t"
10556 10591 "movzbl $dst, $dst\n"
10557 10592 "done:" %}
10558 10593
10559 10594 opcode(0x0F, 0x2E);
10560 10595 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2),
10561 10596 cmpfp3(dst));
10562 10597 ins_pipe(pipe_slow);
10563 10598 %}
10564 10599
10565 10600 // Compare into -1,0,1
10566 10601 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
10567 10602 %{
10568 10603 match(Set dst (CmpD3 src1 src2));
10569 10604 effect(KILL cr);
10570 10605
10571 10606 ins_cost(275);
10572 10607 format %{ "ucomisd $src1, $src2\n\t"
10573 10608 "movl $dst, #-1\n\t"
10574 10609 "jp,s done\n\t"
10575 10610 "jb,s done\n\t"
10576 10611 "setne $dst\n\t"
10577 10612 "movzbl $dst, $dst\n"
10578 10613 "done:" %}
10579 10614
10580 10615 opcode(0x66, 0x0F, 0x2E);
10581 10616 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2),
10582 10617 cmpfp3(dst));
10583 10618 ins_pipe(pipe_slow);
10584 10619 %}
10585 10620
10586 10621 // Compare into -1,0,1
10587 10622 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
10588 10623 %{
10589 10624 match(Set dst (CmpD3 src1 (LoadD src2)));
10590 10625 effect(KILL cr);
10591 10626
10592 10627 ins_cost(275);
10593 10628 format %{ "ucomisd $src1, $src2\n\t"
10594 10629 "movl $dst, #-1\n\t"
10595 10630 "jp,s done\n\t"
10596 10631 "jb,s done\n\t"
10597 10632 "setne $dst\n\t"
10598 10633 "movzbl $dst, $dst\n"
10599 10634 "done:" %}
10600 10635
10601 10636 opcode(0x66, 0x0F, 0x2E);
10602 10637 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2),
10603 10638 cmpfp3(dst));
10604 10639 ins_pipe(pipe_slow);
10605 10640 %}
10606 10641
10607 10642 // Compare into -1,0,1
10608 10643 instruct cmpD_imm(rRegI dst, regD src1, immD src2, rFlagsReg cr)
10609 10644 %{
10610 10645 match(Set dst (CmpD3 src1 src2));
10611 10646 effect(KILL cr);
10612 10647
10613 10648 ins_cost(275);
10614 10649 format %{ "ucomisd $src1, [$src2]\n\t"
10615 10650 "movl $dst, #-1\n\t"
10616 10651 "jp,s done\n\t"
10617 10652 "jb,s done\n\t"
10618 10653 "setne $dst\n\t"
10619 10654 "movzbl $dst, $dst\n"
10620 10655 "done:" %}
10621 10656
10622 10657 opcode(0x66, 0x0F, 0x2E);
10623 10658 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2),
10624 10659 cmpfp3(dst));
10625 10660 ins_pipe(pipe_slow);
10626 10661 %}
10627 10662
10628 10663 instruct addF_reg(regF dst, regF src)
10629 10664 %{
10630 10665 match(Set dst (AddF dst src));
10631 10666
10632 10667 format %{ "addss $dst, $src" %}
10633 10668 ins_cost(150); // XXX
10634 10669 opcode(0xF3, 0x0F, 0x58);
10635 10670 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10636 10671 ins_pipe(pipe_slow);
10637 10672 %}
10638 10673
10639 10674 instruct addF_mem(regF dst, memory src)
10640 10675 %{
10641 10676 match(Set dst (AddF dst (LoadF src)));
10642 10677
10643 10678 format %{ "addss $dst, $src" %}
10644 10679 ins_cost(150); // XXX
10645 10680 opcode(0xF3, 0x0F, 0x58);
10646 10681 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10647 10682 ins_pipe(pipe_slow);
10648 10683 %}
10649 10684
10650 10685 instruct addF_imm(regF dst, immF src)
10651 10686 %{
10652 10687 match(Set dst (AddF dst src));
10653 10688
10654 10689 format %{ "addss $dst, [$src]" %}
10655 10690 ins_cost(150); // XXX
10656 10691 opcode(0xF3, 0x0F, 0x58);
10657 10692 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10658 10693 ins_pipe(pipe_slow);
10659 10694 %}
10660 10695
10661 10696 instruct addD_reg(regD dst, regD src)
10662 10697 %{
10663 10698 match(Set dst (AddD dst src));
10664 10699
10665 10700 format %{ "addsd $dst, $src" %}
10666 10701 ins_cost(150); // XXX
10667 10702 opcode(0xF2, 0x0F, 0x58);
10668 10703 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10669 10704 ins_pipe(pipe_slow);
10670 10705 %}
10671 10706
10672 10707 instruct addD_mem(regD dst, memory src)
10673 10708 %{
10674 10709 match(Set dst (AddD dst (LoadD src)));
10675 10710
10676 10711 format %{ "addsd $dst, $src" %}
10677 10712 ins_cost(150); // XXX
10678 10713 opcode(0xF2, 0x0F, 0x58);
10679 10714 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10680 10715 ins_pipe(pipe_slow);
10681 10716 %}
10682 10717
10683 10718 instruct addD_imm(regD dst, immD src)
10684 10719 %{
10685 10720 match(Set dst (AddD dst src));
10686 10721
10687 10722 format %{ "addsd $dst, [$src]" %}
10688 10723 ins_cost(150); // XXX
10689 10724 opcode(0xF2, 0x0F, 0x58);
10690 10725 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10691 10726 ins_pipe(pipe_slow);
10692 10727 %}
10693 10728
10694 10729 instruct subF_reg(regF dst, regF src)
10695 10730 %{
10696 10731 match(Set dst (SubF dst src));
10697 10732
10698 10733 format %{ "subss $dst, $src" %}
10699 10734 ins_cost(150); // XXX
10700 10735 opcode(0xF3, 0x0F, 0x5C);
10701 10736 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10702 10737 ins_pipe(pipe_slow);
10703 10738 %}
10704 10739
10705 10740 instruct subF_mem(regF dst, memory src)
10706 10741 %{
10707 10742 match(Set dst (SubF dst (LoadF src)));
10708 10743
10709 10744 format %{ "subss $dst, $src" %}
10710 10745 ins_cost(150); // XXX
10711 10746 opcode(0xF3, 0x0F, 0x5C);
10712 10747 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10713 10748 ins_pipe(pipe_slow);
10714 10749 %}
10715 10750
10716 10751 instruct subF_imm(regF dst, immF src)
10717 10752 %{
10718 10753 match(Set dst (SubF dst src));
10719 10754
10720 10755 format %{ "subss $dst, [$src]" %}
10721 10756 ins_cost(150); // XXX
10722 10757 opcode(0xF3, 0x0F, 0x5C);
10723 10758 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10724 10759 ins_pipe(pipe_slow);
10725 10760 %}
10726 10761
10727 10762 instruct subD_reg(regD dst, regD src)
10728 10763 %{
10729 10764 match(Set dst (SubD dst src));
10730 10765
10731 10766 format %{ "subsd $dst, $src" %}
10732 10767 ins_cost(150); // XXX
10733 10768 opcode(0xF2, 0x0F, 0x5C);
10734 10769 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10735 10770 ins_pipe(pipe_slow);
10736 10771 %}
10737 10772
10738 10773 instruct subD_mem(regD dst, memory src)
10739 10774 %{
10740 10775 match(Set dst (SubD dst (LoadD src)));
10741 10776
10742 10777 format %{ "subsd $dst, $src" %}
10743 10778 ins_cost(150); // XXX
10744 10779 opcode(0xF2, 0x0F, 0x5C);
10745 10780 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10746 10781 ins_pipe(pipe_slow);
10747 10782 %}
10748 10783
10749 10784 instruct subD_imm(regD dst, immD src)
10750 10785 %{
10751 10786 match(Set dst (SubD dst src));
10752 10787
10753 10788 format %{ "subsd $dst, [$src]" %}
10754 10789 ins_cost(150); // XXX
10755 10790 opcode(0xF2, 0x0F, 0x5C);
10756 10791 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10757 10792 ins_pipe(pipe_slow);
10758 10793 %}
10759 10794
10760 10795 instruct mulF_reg(regF dst, regF src)
10761 10796 %{
10762 10797 match(Set dst (MulF dst src));
10763 10798
10764 10799 format %{ "mulss $dst, $src" %}
10765 10800 ins_cost(150); // XXX
10766 10801 opcode(0xF3, 0x0F, 0x59);
10767 10802 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10768 10803 ins_pipe(pipe_slow);
10769 10804 %}
10770 10805
10771 10806 instruct mulF_mem(regF dst, memory src)
10772 10807 %{
10773 10808 match(Set dst (MulF dst (LoadF src)));
10774 10809
10775 10810 format %{ "mulss $dst, $src" %}
10776 10811 ins_cost(150); // XXX
10777 10812 opcode(0xF3, 0x0F, 0x59);
10778 10813 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10779 10814 ins_pipe(pipe_slow);
10780 10815 %}
10781 10816
10782 10817 instruct mulF_imm(regF dst, immF src)
10783 10818 %{
10784 10819 match(Set dst (MulF dst src));
10785 10820
10786 10821 format %{ "mulss $dst, [$src]" %}
10787 10822 ins_cost(150); // XXX
10788 10823 opcode(0xF3, 0x0F, 0x59);
10789 10824 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10790 10825 ins_pipe(pipe_slow);
10791 10826 %}
10792 10827
10793 10828 instruct mulD_reg(regD dst, regD src)
10794 10829 %{
10795 10830 match(Set dst (MulD dst src));
10796 10831
10797 10832 format %{ "mulsd $dst, $src" %}
10798 10833 ins_cost(150); // XXX
10799 10834 opcode(0xF2, 0x0F, 0x59);
10800 10835 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10801 10836 ins_pipe(pipe_slow);
10802 10837 %}
10803 10838
10804 10839 instruct mulD_mem(regD dst, memory src)
10805 10840 %{
10806 10841 match(Set dst (MulD dst (LoadD src)));
10807 10842
10808 10843 format %{ "mulsd $dst, $src" %}
10809 10844 ins_cost(150); // XXX
10810 10845 opcode(0xF2, 0x0F, 0x59);
10811 10846 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10812 10847 ins_pipe(pipe_slow);
10813 10848 %}
10814 10849
10815 10850 instruct mulD_imm(regD dst, immD src)
10816 10851 %{
10817 10852 match(Set dst (MulD dst src));
10818 10853
10819 10854 format %{ "mulsd $dst, [$src]" %}
10820 10855 ins_cost(150); // XXX
10821 10856 opcode(0xF2, 0x0F, 0x59);
10822 10857 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10823 10858 ins_pipe(pipe_slow);
10824 10859 %}
10825 10860
10826 10861 instruct divF_reg(regF dst, regF src)
10827 10862 %{
10828 10863 match(Set dst (DivF dst src));
10829 10864
10830 10865 format %{ "divss $dst, $src" %}
10831 10866 ins_cost(150); // XXX
10832 10867 opcode(0xF3, 0x0F, 0x5E);
10833 10868 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10834 10869 ins_pipe(pipe_slow);
10835 10870 %}
10836 10871
10837 10872 instruct divF_mem(regF dst, memory src)
10838 10873 %{
10839 10874 match(Set dst (DivF dst (LoadF src)));
10840 10875
10841 10876 format %{ "divss $dst, $src" %}
10842 10877 ins_cost(150); // XXX
10843 10878 opcode(0xF3, 0x0F, 0x5E);
10844 10879 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10845 10880 ins_pipe(pipe_slow);
10846 10881 %}
10847 10882
10848 10883 instruct divF_imm(regF dst, immF src)
10849 10884 %{
10850 10885 match(Set dst (DivF dst src));
10851 10886
10852 10887 format %{ "divss $dst, [$src]" %}
10853 10888 ins_cost(150); // XXX
10854 10889 opcode(0xF3, 0x0F, 0x5E);
10855 10890 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10856 10891 ins_pipe(pipe_slow);
10857 10892 %}
10858 10893
10859 10894 instruct divD_reg(regD dst, regD src)
10860 10895 %{
10861 10896 match(Set dst (DivD dst src));
10862 10897
10863 10898 format %{ "divsd $dst, $src" %}
10864 10899 ins_cost(150); // XXX
10865 10900 opcode(0xF2, 0x0F, 0x5E);
10866 10901 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10867 10902 ins_pipe(pipe_slow);
10868 10903 %}
10869 10904
10870 10905 instruct divD_mem(regD dst, memory src)
10871 10906 %{
10872 10907 match(Set dst (DivD dst (LoadD src)));
10873 10908
10874 10909 format %{ "divsd $dst, $src" %}
10875 10910 ins_cost(150); // XXX
10876 10911 opcode(0xF2, 0x0F, 0x5E);
10877 10912 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10878 10913 ins_pipe(pipe_slow);
10879 10914 %}
10880 10915
10881 10916 instruct divD_imm(regD dst, immD src)
10882 10917 %{
10883 10918 match(Set dst (DivD dst src));
10884 10919
10885 10920 format %{ "divsd $dst, [$src]" %}
10886 10921 ins_cost(150); // XXX
10887 10922 opcode(0xF2, 0x0F, 0x5E);
10888 10923 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10889 10924 ins_pipe(pipe_slow);
10890 10925 %}
10891 10926
10892 10927 instruct sqrtF_reg(regF dst, regF src)
10893 10928 %{
10894 10929 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10895 10930
10896 10931 format %{ "sqrtss $dst, $src" %}
10897 10932 ins_cost(150); // XXX
10898 10933 opcode(0xF3, 0x0F, 0x51);
10899 10934 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10900 10935 ins_pipe(pipe_slow);
10901 10936 %}
10902 10937
10903 10938 instruct sqrtF_mem(regF dst, memory src)
10904 10939 %{
10905 10940 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
10906 10941
10907 10942 format %{ "sqrtss $dst, $src" %}
10908 10943 ins_cost(150); // XXX
10909 10944 opcode(0xF3, 0x0F, 0x51);
10910 10945 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10911 10946 ins_pipe(pipe_slow);
10912 10947 %}
10913 10948
10914 10949 instruct sqrtF_imm(regF dst, immF src)
10915 10950 %{
10916 10951 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10917 10952
10918 10953 format %{ "sqrtss $dst, [$src]" %}
10919 10954 ins_cost(150); // XXX
10920 10955 opcode(0xF3, 0x0F, 0x51);
10921 10956 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
10922 10957 ins_pipe(pipe_slow);
10923 10958 %}
10924 10959
10925 10960 instruct sqrtD_reg(regD dst, regD src)
10926 10961 %{
10927 10962 match(Set dst (SqrtD src));
10928 10963
10929 10964 format %{ "sqrtsd $dst, $src" %}
10930 10965 ins_cost(150); // XXX
10931 10966 opcode(0xF2, 0x0F, 0x51);
10932 10967 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
10933 10968 ins_pipe(pipe_slow);
10934 10969 %}
10935 10970
10936 10971 instruct sqrtD_mem(regD dst, memory src)
10937 10972 %{
10938 10973 match(Set dst (SqrtD (LoadD src)));
10939 10974
10940 10975 format %{ "sqrtsd $dst, $src" %}
10941 10976 ins_cost(150); // XXX
10942 10977 opcode(0xF2, 0x0F, 0x51);
10943 10978 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
10944 10979 ins_pipe(pipe_slow);
10945 10980 %}
10946 10981
10947 10982 instruct sqrtD_imm(regD dst, immD src)
10948 10983 %{
10949 10984 match(Set dst (SqrtD src));
10950 10985
10951 10986 format %{ "sqrtsd $dst, [$src]" %}
10952 10987 ins_cost(150); // XXX
10953 10988 opcode(0xF2, 0x0F, 0x51);
10954 10989 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
10955 10990 ins_pipe(pipe_slow);
10956 10991 %}
10957 10992
10958 10993 instruct absF_reg(regF dst)
10959 10994 %{
10960 10995 match(Set dst (AbsF dst));
10961 10996
10962 10997 format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %}
10963 10998 ins_encode(absF_encoding(dst));
10964 10999 ins_pipe(pipe_slow);
10965 11000 %}
10966 11001
10967 11002 instruct absD_reg(regD dst)
10968 11003 %{
10969 11004 match(Set dst (AbsD dst));
10970 11005
10971 11006 format %{ "andpd $dst, [0x7fffffffffffffff]\t"
10972 11007 "# abs double by sign masking" %}
10973 11008 ins_encode(absD_encoding(dst));
10974 11009 ins_pipe(pipe_slow);
10975 11010 %}
10976 11011
10977 11012 instruct negF_reg(regF dst)
10978 11013 %{
10979 11014 match(Set dst (NegF dst));
10980 11015
10981 11016 format %{ "xorps $dst, [0x80000000]\t# neg float by sign flipping" %}
10982 11017 ins_encode(negF_encoding(dst));
10983 11018 ins_pipe(pipe_slow);
10984 11019 %}
10985 11020
10986 11021 instruct negD_reg(regD dst)
10987 11022 %{
10988 11023 match(Set dst (NegD dst));
10989 11024
10990 11025 format %{ "xorpd $dst, [0x8000000000000000]\t"
10991 11026 "# neg double by sign flipping" %}
10992 11027 ins_encode(negD_encoding(dst));
10993 11028 ins_pipe(pipe_slow);
10994 11029 %}
10995 11030
10996 11031 // -----------Trig and Trancendental Instructions------------------------------
10997 11032 instruct cosD_reg(regD dst) %{
10998 11033 match(Set dst (CosD dst));
10999 11034
11000 11035 format %{ "dcos $dst\n\t" %}
11001 11036 opcode(0xD9, 0xFF);
11002 11037 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
11003 11038 ins_pipe( pipe_slow );
11004 11039 %}
11005 11040
11006 11041 instruct sinD_reg(regD dst) %{
11007 11042 match(Set dst (SinD dst));
11008 11043
11009 11044 format %{ "dsin $dst\n\t" %}
11010 11045 opcode(0xD9, 0xFE);
11011 11046 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
11012 11047 ins_pipe( pipe_slow );
11013 11048 %}
11014 11049
11015 11050 instruct tanD_reg(regD dst) %{
11016 11051 match(Set dst (TanD dst));
11017 11052
11018 11053 format %{ "dtan $dst\n\t" %}
11019 11054 ins_encode( Push_SrcXD(dst),
11020 11055 Opcode(0xD9), Opcode(0xF2), //fptan
11021 11056 Opcode(0xDD), Opcode(0xD8), //fstp st
11022 11057 Push_ResultXD(dst) );
11023 11058 ins_pipe( pipe_slow );
11024 11059 %}
11025 11060
11026 11061 instruct log10D_reg(regD dst) %{
11027 11062 // The source and result Double operands in XMM registers
11028 11063 match(Set dst (Log10D dst));
11029 11064 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number
11030 11065 // fyl2x ; compute log_10(2) * log_2(x)
11031 11066 format %{ "fldlg2\t\t\t#Log10\n\t"
11032 11067 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t"
11033 11068 %}
11034 11069 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2
11035 11070 Push_SrcXD(dst),
11036 11071 Opcode(0xD9), Opcode(0xF1), // fyl2x
11037 11072 Push_ResultXD(dst));
11038 11073
11039 11074 ins_pipe( pipe_slow );
11040 11075 %}
11041 11076
11042 11077 instruct logD_reg(regD dst) %{
11043 11078 // The source and result Double operands in XMM registers
11044 11079 match(Set dst (LogD dst));
11045 11080 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number
11046 11081 // fyl2x ; compute log_e(2) * log_2(x)
11047 11082 format %{ "fldln2\t\t\t#Log_e\n\t"
11048 11083 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t"
11049 11084 %}
11050 11085 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2
11051 11086 Push_SrcXD(dst),
11052 11087 Opcode(0xD9), Opcode(0xF1), // fyl2x
11053 11088 Push_ResultXD(dst));
11054 11089 ins_pipe( pipe_slow );
11055 11090 %}
11056 11091
11057 11092
11058 11093
11059 11094 //----------Arithmetic Conversion Instructions---------------------------------
11060 11095
11061 11096 instruct roundFloat_nop(regF dst)
11062 11097 %{
11063 11098 match(Set dst (RoundFloat dst));
11064 11099
11065 11100 ins_cost(0);
11066 11101 ins_encode();
11067 11102 ins_pipe(empty);
11068 11103 %}
11069 11104
11070 11105 instruct roundDouble_nop(regD dst)
11071 11106 %{
11072 11107 match(Set dst (RoundDouble dst));
11073 11108
11074 11109 ins_cost(0);
11075 11110 ins_encode();
11076 11111 ins_pipe(empty);
11077 11112 %}
11078 11113
11079 11114 instruct convF2D_reg_reg(regD dst, regF src)
11080 11115 %{
11081 11116 match(Set dst (ConvF2D src));
11082 11117
11083 11118 format %{ "cvtss2sd $dst, $src" %}
11084 11119 opcode(0xF3, 0x0F, 0x5A);
11085 11120 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
11086 11121 ins_pipe(pipe_slow); // XXX
11087 11122 %}
11088 11123
11089 11124 instruct convF2D_reg_mem(regD dst, memory src)
11090 11125 %{
11091 11126 match(Set dst (ConvF2D (LoadF src)));
11092 11127
11093 11128 format %{ "cvtss2sd $dst, $src" %}
11094 11129 opcode(0xF3, 0x0F, 0x5A);
11095 11130 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11096 11131 ins_pipe(pipe_slow); // XXX
11097 11132 %}
11098 11133
11099 11134 instruct convD2F_reg_reg(regF dst, regD src)
11100 11135 %{
11101 11136 match(Set dst (ConvD2F src));
11102 11137
11103 11138 format %{ "cvtsd2ss $dst, $src" %}
11104 11139 opcode(0xF2, 0x0F, 0x5A);
11105 11140 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
11106 11141 ins_pipe(pipe_slow); // XXX
11107 11142 %}
11108 11143
11109 11144 instruct convD2F_reg_mem(regF dst, memory src)
11110 11145 %{
11111 11146 match(Set dst (ConvD2F (LoadD src)));
11112 11147
11113 11148 format %{ "cvtsd2ss $dst, $src" %}
11114 11149 opcode(0xF2, 0x0F, 0x5A);
11115 11150 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11116 11151 ins_pipe(pipe_slow); // XXX
11117 11152 %}
11118 11153
11119 11154 // XXX do mem variants
11120 11155 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
11121 11156 %{
11122 11157 match(Set dst (ConvF2I src));
11123 11158 effect(KILL cr);
11124 11159
11125 11160 format %{ "cvttss2sil $dst, $src\t# f2i\n\t"
11126 11161 "cmpl $dst, #0x80000000\n\t"
11127 11162 "jne,s done\n\t"
11128 11163 "subq rsp, #8\n\t"
11129 11164 "movss [rsp], $src\n\t"
11130 11165 "call f2i_fixup\n\t"
11131 11166 "popq $dst\n"
11132 11167 "done: "%}
11133 11168 opcode(0xF3, 0x0F, 0x2C);
11134 11169 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src),
11135 11170 f2i_fixup(dst, src));
11136 11171 ins_pipe(pipe_slow);
11137 11172 %}
11138 11173
11139 11174 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
11140 11175 %{
11141 11176 match(Set dst (ConvF2L src));
11142 11177 effect(KILL cr);
11143 11178
11144 11179 format %{ "cvttss2siq $dst, $src\t# f2l\n\t"
11145 11180 "cmpq $dst, [0x8000000000000000]\n\t"
11146 11181 "jne,s done\n\t"
11147 11182 "subq rsp, #8\n\t"
11148 11183 "movss [rsp], $src\n\t"
11149 11184 "call f2l_fixup\n\t"
11150 11185 "popq $dst\n"
11151 11186 "done: "%}
11152 11187 opcode(0xF3, 0x0F, 0x2C);
11153 11188 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src),
11154 11189 f2l_fixup(dst, src));
11155 11190 ins_pipe(pipe_slow);
11156 11191 %}
11157 11192
11158 11193 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
11159 11194 %{
11160 11195 match(Set dst (ConvD2I src));
11161 11196 effect(KILL cr);
11162 11197
11163 11198 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t"
11164 11199 "cmpl $dst, #0x80000000\n\t"
11165 11200 "jne,s done\n\t"
11166 11201 "subq rsp, #8\n\t"
11167 11202 "movsd [rsp], $src\n\t"
11168 11203 "call d2i_fixup\n\t"
11169 11204 "popq $dst\n"
11170 11205 "done: "%}
11171 11206 opcode(0xF2, 0x0F, 0x2C);
11172 11207 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src),
11173 11208 d2i_fixup(dst, src));
11174 11209 ins_pipe(pipe_slow);
11175 11210 %}
11176 11211
11177 11212 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
11178 11213 %{
11179 11214 match(Set dst (ConvD2L src));
11180 11215 effect(KILL cr);
11181 11216
11182 11217 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t"
11183 11218 "cmpq $dst, [0x8000000000000000]\n\t"
11184 11219 "jne,s done\n\t"
11185 11220 "subq rsp, #8\n\t"
11186 11221 "movsd [rsp], $src\n\t"
11187 11222 "call d2l_fixup\n\t"
11188 11223 "popq $dst\n"
11189 11224 "done: "%}
11190 11225 opcode(0xF2, 0x0F, 0x2C);
11191 11226 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src),
11192 11227 d2l_fixup(dst, src));
11193 11228 ins_pipe(pipe_slow);
11194 11229 %}
11195 11230
11196 11231 instruct convI2F_reg_reg(regF dst, rRegI src)
11197 11232 %{
11198 11233 predicate(!UseXmmI2F);
11199 11234 match(Set dst (ConvI2F src));
11200 11235
11201 11236 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
11202 11237 opcode(0xF3, 0x0F, 0x2A);
11203 11238 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
11204 11239 ins_pipe(pipe_slow); // XXX
11205 11240 %}
11206 11241
11207 11242 instruct convI2F_reg_mem(regF dst, memory src)
11208 11243 %{
11209 11244 match(Set dst (ConvI2F (LoadI src)));
11210 11245
11211 11246 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
11212 11247 opcode(0xF3, 0x0F, 0x2A);
11213 11248 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11214 11249 ins_pipe(pipe_slow); // XXX
11215 11250 %}
11216 11251
11217 11252 instruct convI2D_reg_reg(regD dst, rRegI src)
11218 11253 %{
11219 11254 predicate(!UseXmmI2D);
11220 11255 match(Set dst (ConvI2D src));
11221 11256
11222 11257 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
11223 11258 opcode(0xF2, 0x0F, 0x2A);
11224 11259 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src));
11225 11260 ins_pipe(pipe_slow); // XXX
11226 11261 %}
11227 11262
11228 11263 instruct convI2D_reg_mem(regD dst, memory src)
11229 11264 %{
11230 11265 match(Set dst (ConvI2D (LoadI src)));
11231 11266
11232 11267 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
11233 11268 opcode(0xF2, 0x0F, 0x2A);
11234 11269 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11235 11270 ins_pipe(pipe_slow); // XXX
11236 11271 %}
11237 11272
11238 11273 instruct convXI2F_reg(regF dst, rRegI src)
11239 11274 %{
11240 11275 predicate(UseXmmI2F);
11241 11276 match(Set dst (ConvI2F src));
11242 11277
11243 11278 format %{ "movdl $dst, $src\n\t"
11244 11279 "cvtdq2psl $dst, $dst\t# i2f" %}
11245 11280 ins_encode %{
11246 11281 __ movdl($dst$$XMMRegister, $src$$Register);
11247 11282 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
11248 11283 %}
11249 11284 ins_pipe(pipe_slow); // XXX
11250 11285 %}
11251 11286
11252 11287 instruct convXI2D_reg(regD dst, rRegI src)
11253 11288 %{
11254 11289 predicate(UseXmmI2D);
11255 11290 match(Set dst (ConvI2D src));
11256 11291
11257 11292 format %{ "movdl $dst, $src\n\t"
11258 11293 "cvtdq2pdl $dst, $dst\t# i2d" %}
11259 11294 ins_encode %{
11260 11295 __ movdl($dst$$XMMRegister, $src$$Register);
11261 11296 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
11262 11297 %}
11263 11298 ins_pipe(pipe_slow); // XXX
11264 11299 %}
11265 11300
11266 11301 instruct convL2F_reg_reg(regF dst, rRegL src)
11267 11302 %{
11268 11303 match(Set dst (ConvL2F src));
11269 11304
11270 11305 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
11271 11306 opcode(0xF3, 0x0F, 0x2A);
11272 11307 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src));
11273 11308 ins_pipe(pipe_slow); // XXX
11274 11309 %}
11275 11310
11276 11311 instruct convL2F_reg_mem(regF dst, memory src)
11277 11312 %{
11278 11313 match(Set dst (ConvL2F (LoadL src)));
11279 11314
11280 11315 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
11281 11316 opcode(0xF3, 0x0F, 0x2A);
11282 11317 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src));
11283 11318 ins_pipe(pipe_slow); // XXX
11284 11319 %}
11285 11320
11286 11321 instruct convL2D_reg_reg(regD dst, rRegL src)
11287 11322 %{
11288 11323 match(Set dst (ConvL2D src));
11289 11324
11290 11325 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
11291 11326 opcode(0xF2, 0x0F, 0x2A);
11292 11327 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src));
11293 11328 ins_pipe(pipe_slow); // XXX
11294 11329 %}
11295 11330
11296 11331 instruct convL2D_reg_mem(regD dst, memory src)
11297 11332 %{
11298 11333 match(Set dst (ConvL2D (LoadL src)));
11299 11334
11300 11335 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
11301 11336 opcode(0xF2, 0x0F, 0x2A);
11302 11337 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src));
11303 11338 ins_pipe(pipe_slow); // XXX
11304 11339 %}
11305 11340
11306 11341 instruct convI2L_reg_reg(rRegL dst, rRegI src)
11307 11342 %{
11308 11343 match(Set dst (ConvI2L src));
11309 11344
11310 11345 ins_cost(125);
11311 11346 format %{ "movslq $dst, $src\t# i2l" %}
11312 11347 ins_encode %{
11313 11348 __ movslq($dst$$Register, $src$$Register);
11314 11349 %}
11315 11350 ins_pipe(ialu_reg_reg);
11316 11351 %}
11317 11352
11318 11353 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src)
11319 11354 // %{
11320 11355 // match(Set dst (ConvI2L src));
11321 11356 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 &&
11322 11357 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0);
11323 11358 // predicate(((const TypeNode*) n)->type()->is_long()->_hi ==
11324 11359 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi &&
11325 11360 // ((const TypeNode*) n)->type()->is_long()->_lo ==
11326 11361 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo);
11327 11362
11328 11363 // format %{ "movl $dst, $src\t# unsigned i2l" %}
11329 11364 // ins_encode(enc_copy(dst, src));
11330 11365 // // opcode(0x63); // needs REX.W
11331 11366 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
11332 11367 // ins_pipe(ialu_reg_reg);
11333 11368 // %}
11334 11369
11335 11370 // Zero-extend convert int to long
11336 11371 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
11337 11372 %{
11338 11373 match(Set dst (AndL (ConvI2L src) mask));
11339 11374
11340 11375 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
11341 11376 ins_encode(enc_copy(dst, src));
11342 11377 ins_pipe(ialu_reg_reg);
11343 11378 %}
11344 11379
11345 11380 // Zero-extend convert int to long
11346 11381 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
11347 11382 %{
11348 11383 match(Set dst (AndL (ConvI2L (LoadI src)) mask));
11349 11384
11350 11385 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
11351 11386 opcode(0x8B);
11352 11387 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
11353 11388 ins_pipe(ialu_reg_mem);
11354 11389 %}
11355 11390
11356 11391 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
11357 11392 %{
11358 11393 match(Set dst (AndL src mask));
11359 11394
11360 11395 format %{ "movl $dst, $src\t# zero-extend long" %}
11361 11396 ins_encode(enc_copy_always(dst, src));
11362 11397 ins_pipe(ialu_reg_reg);
11363 11398 %}
11364 11399
11365 11400 instruct convL2I_reg_reg(rRegI dst, rRegL src)
11366 11401 %{
11367 11402 match(Set dst (ConvL2I src));
11368 11403
11369 11404 format %{ "movl $dst, $src\t# l2i" %}
11370 11405 ins_encode(enc_copy_always(dst, src));
11371 11406 ins_pipe(ialu_reg_reg);
11372 11407 %}
11373 11408
11374 11409
11375 11410 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
11376 11411 match(Set dst (MoveF2I src));
11377 11412 effect(DEF dst, USE src);
11378 11413
11379 11414 ins_cost(125);
11380 11415 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %}
11381 11416 opcode(0x8B);
11382 11417 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
11383 11418 ins_pipe(ialu_reg_mem);
11384 11419 %}
11385 11420
11386 11421 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
11387 11422 match(Set dst (MoveI2F src));
11388 11423 effect(DEF dst, USE src);
11389 11424
11390 11425 ins_cost(125);
11391 11426 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %}
11392 11427 opcode(0xF3, 0x0F, 0x10);
11393 11428 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11394 11429 ins_pipe(pipe_slow);
11395 11430 %}
11396 11431
11397 11432 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
11398 11433 match(Set dst (MoveD2L src));
11399 11434 effect(DEF dst, USE src);
11400 11435
11401 11436 ins_cost(125);
11402 11437 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %}
11403 11438 opcode(0x8B);
11404 11439 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
11405 11440 ins_pipe(ialu_reg_mem);
11406 11441 %}
11407 11442
11408 11443 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
11409 11444 predicate(!UseXmmLoadAndClearUpper);
11410 11445 match(Set dst (MoveL2D src));
11411 11446 effect(DEF dst, USE src);
11412 11447
11413 11448 ins_cost(125);
11414 11449 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %}
11415 11450 opcode(0x66, 0x0F, 0x12);
11416 11451 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11417 11452 ins_pipe(pipe_slow);
11418 11453 %}
11419 11454
11420 11455 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
11421 11456 predicate(UseXmmLoadAndClearUpper);
11422 11457 match(Set dst (MoveL2D src));
11423 11458 effect(DEF dst, USE src);
11424 11459
11425 11460 ins_cost(125);
11426 11461 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %}
11427 11462 opcode(0xF2, 0x0F, 0x10);
11428 11463 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src));
11429 11464 ins_pipe(pipe_slow);
11430 11465 %}
11431 11466
11432 11467
11433 11468 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
11434 11469 match(Set dst (MoveF2I src));
11435 11470 effect(DEF dst, USE src);
11436 11471
11437 11472 ins_cost(95); // XXX
11438 11473 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %}
11439 11474 opcode(0xF3, 0x0F, 0x11);
11440 11475 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
11441 11476 ins_pipe(pipe_slow);
11442 11477 %}
11443 11478
11444 11479 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
11445 11480 match(Set dst (MoveI2F src));
11446 11481 effect(DEF dst, USE src);
11447 11482
11448 11483 ins_cost(100);
11449 11484 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %}
11450 11485 opcode(0x89);
11451 11486 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
11452 11487 ins_pipe( ialu_mem_reg );
11453 11488 %}
11454 11489
11455 11490 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
11456 11491 match(Set dst (MoveD2L src));
11457 11492 effect(DEF dst, USE src);
11458 11493
11459 11494 ins_cost(95); // XXX
11460 11495 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %}
11461 11496 opcode(0xF2, 0x0F, 0x11);
11462 11497 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst));
11463 11498 ins_pipe(pipe_slow);
11464 11499 %}
11465 11500
11466 11501 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
11467 11502 match(Set dst (MoveL2D src));
11468 11503 effect(DEF dst, USE src);
11469 11504
11470 11505 ins_cost(100);
11471 11506 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %}
11472 11507 opcode(0x89);
11473 11508 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
11474 11509 ins_pipe(ialu_mem_reg);
11475 11510 %}
11476 11511
11477 11512 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
11478 11513 match(Set dst (MoveF2I src));
11479 11514 effect(DEF dst, USE src);
11480 11515 ins_cost(85);
11481 11516 format %{ "movd $dst,$src\t# MoveF2I" %}
11482 11517 ins_encode %{ __ movdl($dst$$Register, $src$$XMMRegister); %}
11483 11518 ins_pipe( pipe_slow );
11484 11519 %}
11485 11520
11486 11521 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
11487 11522 match(Set dst (MoveD2L src));
11488 11523 effect(DEF dst, USE src);
11489 11524 ins_cost(85);
11490 11525 format %{ "movd $dst,$src\t# MoveD2L" %}
11491 11526 ins_encode %{ __ movdq($dst$$Register, $src$$XMMRegister); %}
11492 11527 ins_pipe( pipe_slow );
11493 11528 %}
11494 11529
11495 11530 // The next instructions have long latency and use Int unit. Set high cost.
11496 11531 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
11497 11532 match(Set dst (MoveI2F src));
11498 11533 effect(DEF dst, USE src);
11499 11534 ins_cost(300);
11500 11535 format %{ "movd $dst,$src\t# MoveI2F" %}
11501 11536 ins_encode %{ __ movdl($dst$$XMMRegister, $src$$Register); %}
11502 11537 ins_pipe( pipe_slow );
11503 11538 %}
11504 11539
11505 11540 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
11506 11541 match(Set dst (MoveL2D src));
11507 11542 effect(DEF dst, USE src);
11508 11543 ins_cost(300);
11509 11544 format %{ "movd $dst,$src\t# MoveL2D" %}
11510 11545 ins_encode %{ __ movdq($dst$$XMMRegister, $src$$Register); %}
11511 11546 ins_pipe( pipe_slow );
11512 11547 %}
11513 11548
11514 11549 // Replicate scalar to packed byte (1 byte) values in xmm
11515 11550 instruct Repl8B_reg(regD dst, regD src) %{
11516 11551 match(Set dst (Replicate8B src));
11517 11552 format %{ "MOVDQA $dst,$src\n\t"
11518 11553 "PUNPCKLBW $dst,$dst\n\t"
11519 11554 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
11520 11555 ins_encode( pshufd_8x8(dst, src));
11521 11556 ins_pipe( pipe_slow );
11522 11557 %}
11523 11558
11524 11559 // Replicate scalar to packed byte (1 byte) values in xmm
11525 11560 instruct Repl8B_rRegI(regD dst, rRegI src) %{
11526 11561 match(Set dst (Replicate8B src));
11527 11562 format %{ "MOVD $dst,$src\n\t"
11528 11563 "PUNPCKLBW $dst,$dst\n\t"
11529 11564 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
11530 11565 ins_encode( mov_i2x(dst, src), pshufd_8x8(dst, dst));
11531 11566 ins_pipe( pipe_slow );
11532 11567 %}
11533 11568
11534 11569 // Replicate scalar zero to packed byte (1 byte) values in xmm
11535 11570 instruct Repl8B_immI0(regD dst, immI0 zero) %{
11536 11571 match(Set dst (Replicate8B zero));
11537 11572 format %{ "PXOR $dst,$dst\t! replicate8B" %}
11538 11573 ins_encode( pxor(dst, dst));
11539 11574 ins_pipe( fpu_reg_reg );
11540 11575 %}
11541 11576
11542 11577 // Replicate scalar to packed shore (2 byte) values in xmm
11543 11578 instruct Repl4S_reg(regD dst, regD src) %{
11544 11579 match(Set dst (Replicate4S src));
11545 11580 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
11546 11581 ins_encode( pshufd_4x16(dst, src));
11547 11582 ins_pipe( fpu_reg_reg );
11548 11583 %}
11549 11584
11550 11585 // Replicate scalar to packed shore (2 byte) values in xmm
11551 11586 instruct Repl4S_rRegI(regD dst, rRegI src) %{
11552 11587 match(Set dst (Replicate4S src));
11553 11588 format %{ "MOVD $dst,$src\n\t"
11554 11589 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
11555 11590 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst));
11556 11591 ins_pipe( fpu_reg_reg );
11557 11592 %}
11558 11593
11559 11594 // Replicate scalar zero to packed short (2 byte) values in xmm
11560 11595 instruct Repl4S_immI0(regD dst, immI0 zero) %{
11561 11596 match(Set dst (Replicate4S zero));
11562 11597 format %{ "PXOR $dst,$dst\t! replicate4S" %}
11563 11598 ins_encode( pxor(dst, dst));
11564 11599 ins_pipe( fpu_reg_reg );
11565 11600 %}
11566 11601
11567 11602 // Replicate scalar to packed char (2 byte) values in xmm
11568 11603 instruct Repl4C_reg(regD dst, regD src) %{
11569 11604 match(Set dst (Replicate4C src));
11570 11605 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
11571 11606 ins_encode( pshufd_4x16(dst, src));
11572 11607 ins_pipe( fpu_reg_reg );
11573 11608 %}
11574 11609
11575 11610 // Replicate scalar to packed char (2 byte) values in xmm
11576 11611 instruct Repl4C_rRegI(regD dst, rRegI src) %{
11577 11612 match(Set dst (Replicate4C src));
11578 11613 format %{ "MOVD $dst,$src\n\t"
11579 11614 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
11580 11615 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst));
11581 11616 ins_pipe( fpu_reg_reg );
11582 11617 %}
11583 11618
11584 11619 // Replicate scalar zero to packed char (2 byte) values in xmm
11585 11620 instruct Repl4C_immI0(regD dst, immI0 zero) %{
11586 11621 match(Set dst (Replicate4C zero));
11587 11622 format %{ "PXOR $dst,$dst\t! replicate4C" %}
11588 11623 ins_encode( pxor(dst, dst));
11589 11624 ins_pipe( fpu_reg_reg );
11590 11625 %}
11591 11626
11592 11627 // Replicate scalar to packed integer (4 byte) values in xmm
11593 11628 instruct Repl2I_reg(regD dst, regD src) %{
11594 11629 match(Set dst (Replicate2I src));
11595 11630 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
11596 11631 ins_encode( pshufd(dst, src, 0x00));
11597 11632 ins_pipe( fpu_reg_reg );
11598 11633 %}
11599 11634
11600 11635 // Replicate scalar to packed integer (4 byte) values in xmm
11601 11636 instruct Repl2I_rRegI(regD dst, rRegI src) %{
11602 11637 match(Set dst (Replicate2I src));
11603 11638 format %{ "MOVD $dst,$src\n\t"
11604 11639 "PSHUFD $dst,$dst,0x00\t! replicate2I" %}
11605 11640 ins_encode( mov_i2x(dst, src), pshufd(dst, dst, 0x00));
11606 11641 ins_pipe( fpu_reg_reg );
11607 11642 %}
11608 11643
11609 11644 // Replicate scalar zero to packed integer (2 byte) values in xmm
11610 11645 instruct Repl2I_immI0(regD dst, immI0 zero) %{
11611 11646 match(Set dst (Replicate2I zero));
11612 11647 format %{ "PXOR $dst,$dst\t! replicate2I" %}
11613 11648 ins_encode( pxor(dst, dst));
11614 11649 ins_pipe( fpu_reg_reg );
11615 11650 %}
11616 11651
11617 11652 // Replicate scalar to packed single precision floating point values in xmm
11618 11653 instruct Repl2F_reg(regD dst, regD src) %{
11619 11654 match(Set dst (Replicate2F src));
11620 11655 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11621 11656 ins_encode( pshufd(dst, src, 0xe0));
11622 11657 ins_pipe( fpu_reg_reg );
11623 11658 %}
11624 11659
11625 11660 // Replicate scalar to packed single precision floating point values in xmm
11626 11661 instruct Repl2F_regF(regD dst, regF src) %{
11627 11662 match(Set dst (Replicate2F src));
11628 11663 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11629 11664 ins_encode( pshufd(dst, src, 0xe0));
11630 11665 ins_pipe( fpu_reg_reg );
11631 11666 %}
11632 11667
11633 11668 // Replicate scalar to packed single precision floating point values in xmm
11634 11669 instruct Repl2F_immF0(regD dst, immF0 zero) %{
11635 11670 match(Set dst (Replicate2F zero));
11636 11671 format %{ "PXOR $dst,$dst\t! replicate2F" %}
11637 11672 ins_encode( pxor(dst, dst));
11638 11673 ins_pipe( fpu_reg_reg );
11639 11674 %}
11640 11675
11641 11676
11642 11677 // =======================================================================
11643 11678 // fast clearing of an array
11644 11679 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
11645 11680 rFlagsReg cr)
11646 11681 %{
11647 11682 match(Set dummy (ClearArray cnt base));
11648 11683 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
11649 11684
11650 11685 format %{ "xorl rax, rax\t# ClearArray:\n\t"
11651 11686 "rep stosq\t# Store rax to *rdi++ while rcx--" %}
11652 11687 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax
11653 11688 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos
11654 11689 ins_pipe(pipe_slow);
11655 11690 %}
11656 11691
11657 11692 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rbx_RegI cnt2,
11658 11693 rax_RegI result, regD tmp1, regD tmp2, rFlagsReg cr)
11659 11694 %{
11660 11695 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11661 11696 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11662 11697
11663 11698 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %}
11664 11699 ins_encode %{
11665 11700 __ string_compare($str1$$Register, $str2$$Register,
11666 11701 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11667 11702 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11668 11703 %}
11669 11704 ins_pipe( pipe_slow );
11670 11705 %}
11671 11706
11672 11707 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
11673 11708 rbx_RegI result, regD tmp1, rcx_RegI tmp2, rFlagsReg cr)
11674 11709 %{
11675 11710 predicate(UseSSE42Intrinsics);
11676 11711 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11677 11712 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
11678 11713
11679 11714 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %}
11680 11715 ins_encode %{
11681 11716 __ string_indexof($str1$$Register, $str2$$Register,
11682 11717 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11683 11718 $tmp1$$XMMRegister, $tmp2$$Register);
11684 11719 %}
11685 11720 ins_pipe( pipe_slow );
11686 11721 %}
11687 11722
11688 11723 // fast string equals
11689 11724 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
11690 11725 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
11691 11726 %{
11692 11727 match(Set result (StrEquals (Binary str1 str2) cnt));
11693 11728 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
11694 11729
11695 11730 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
11696 11731 ins_encode %{
11697 11732 __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
11698 11733 $cnt$$Register, $result$$Register, $tmp3$$Register,
11699 11734 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11700 11735 %}
11701 11736 ins_pipe( pipe_slow );
11702 11737 %}
11703 11738
11704 11739 // fast array equals
11705 11740 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
11706 11741 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
11707 11742 %{
11708 11743 match(Set result (AryEq ary1 ary2));
11709 11744 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
11710 11745 //ins_cost(300);
11711 11746
11712 11747 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
11713 11748 ins_encode %{
11714 11749 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
11715 11750 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11716 11751 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11717 11752 %}
11718 11753 ins_pipe( pipe_slow );
11719 11754 %}
11720 11755
11721 11756 //----------Control Flow Instructions------------------------------------------
11722 11757 // Signed compare Instructions
11723 11758
11724 11759 // XXX more variants!!
11725 11760 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
11726 11761 %{
11727 11762 match(Set cr (CmpI op1 op2));
11728 11763 effect(DEF cr, USE op1, USE op2);
11729 11764
11730 11765 format %{ "cmpl $op1, $op2" %}
11731 11766 opcode(0x3B); /* Opcode 3B /r */
11732 11767 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
11733 11768 ins_pipe(ialu_cr_reg_reg);
11734 11769 %}
11735 11770
11736 11771 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
11737 11772 %{
11738 11773 match(Set cr (CmpI op1 op2));
11739 11774
11740 11775 format %{ "cmpl $op1, $op2" %}
11741 11776 opcode(0x81, 0x07); /* Opcode 81 /7 */
11742 11777 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
11743 11778 ins_pipe(ialu_cr_reg_imm);
11744 11779 %}
11745 11780
11746 11781 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2)
11747 11782 %{
11748 11783 match(Set cr (CmpI op1 (LoadI op2)));
11749 11784
11750 11785 ins_cost(500); // XXX
11751 11786 format %{ "cmpl $op1, $op2" %}
11752 11787 opcode(0x3B); /* Opcode 3B /r */
11753 11788 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
11754 11789 ins_pipe(ialu_cr_reg_mem);
11755 11790 %}
11756 11791
11757 11792 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero)
11758 11793 %{
11759 11794 match(Set cr (CmpI src zero));
11760 11795
11761 11796 format %{ "testl $src, $src" %}
11762 11797 opcode(0x85);
11763 11798 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
11764 11799 ins_pipe(ialu_cr_reg_imm);
11765 11800 %}
11766 11801
11767 11802 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero)
11768 11803 %{
11769 11804 match(Set cr (CmpI (AndI src con) zero));
11770 11805
11771 11806 format %{ "testl $src, $con" %}
11772 11807 opcode(0xF7, 0x00);
11773 11808 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con));
11774 11809 ins_pipe(ialu_cr_reg_imm);
11775 11810 %}
11776 11811
11777 11812 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero)
11778 11813 %{
11779 11814 match(Set cr (CmpI (AndI src (LoadI mem)) zero));
11780 11815
11781 11816 format %{ "testl $src, $mem" %}
11782 11817 opcode(0x85);
11783 11818 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
11784 11819 ins_pipe(ialu_cr_reg_mem);
11785 11820 %}
11786 11821
11787 11822 // Unsigned compare Instructions; really, same as signed except they
11788 11823 // produce an rFlagsRegU instead of rFlagsReg.
11789 11824 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2)
11790 11825 %{
11791 11826 match(Set cr (CmpU op1 op2));
11792 11827
11793 11828 format %{ "cmpl $op1, $op2\t# unsigned" %}
11794 11829 opcode(0x3B); /* Opcode 3B /r */
11795 11830 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
11796 11831 ins_pipe(ialu_cr_reg_reg);
11797 11832 %}
11798 11833
11799 11834 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2)
11800 11835 %{
11801 11836 match(Set cr (CmpU op1 op2));
11802 11837
11803 11838 format %{ "cmpl $op1, $op2\t# unsigned" %}
11804 11839 opcode(0x81,0x07); /* Opcode 81 /7 */
11805 11840 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
11806 11841 ins_pipe(ialu_cr_reg_imm);
11807 11842 %}
11808 11843
11809 11844 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2)
11810 11845 %{
11811 11846 match(Set cr (CmpU op1 (LoadI op2)));
11812 11847
11813 11848 ins_cost(500); // XXX
11814 11849 format %{ "cmpl $op1, $op2\t# unsigned" %}
11815 11850 opcode(0x3B); /* Opcode 3B /r */
11816 11851 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
11817 11852 ins_pipe(ialu_cr_reg_mem);
11818 11853 %}
11819 11854
11820 11855 // // // Cisc-spilled version of cmpU_rReg
11821 11856 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2)
11822 11857 // //%{
11823 11858 // // match(Set cr (CmpU (LoadI op1) op2));
11824 11859 // //
11825 11860 // // format %{ "CMPu $op1,$op2" %}
11826 11861 // // ins_cost(500);
11827 11862 // // opcode(0x39); /* Opcode 39 /r */
11828 11863 // // ins_encode( OpcP, reg_mem( op1, op2) );
11829 11864 // //%}
11830 11865
11831 11866 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero)
11832 11867 %{
11833 11868 match(Set cr (CmpU src zero));
11834 11869
11835 11870 format %{ "testl $src, $src\t# unsigned" %}
11836 11871 opcode(0x85);
11837 11872 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
11838 11873 ins_pipe(ialu_cr_reg_imm);
11839 11874 %}
11840 11875
11841 11876 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2)
11842 11877 %{
11843 11878 match(Set cr (CmpP op1 op2));
11844 11879
11845 11880 format %{ "cmpq $op1, $op2\t# ptr" %}
11846 11881 opcode(0x3B); /* Opcode 3B /r */
11847 11882 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
11848 11883 ins_pipe(ialu_cr_reg_reg);
11849 11884 %}
11850 11885
11851 11886 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
11852 11887 %{
11853 11888 match(Set cr (CmpP op1 (LoadP op2)));
11854 11889
11855 11890 ins_cost(500); // XXX
11856 11891 format %{ "cmpq $op1, $op2\t# ptr" %}
11857 11892 opcode(0x3B); /* Opcode 3B /r */
11858 11893 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
11859 11894 ins_pipe(ialu_cr_reg_mem);
11860 11895 %}
11861 11896
11862 11897 // // // Cisc-spilled version of cmpP_rReg
11863 11898 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2)
11864 11899 // //%{
11865 11900 // // match(Set cr (CmpP (LoadP op1) op2));
11866 11901 // //
11867 11902 // // format %{ "CMPu $op1,$op2" %}
11868 11903 // // ins_cost(500);
11869 11904 // // opcode(0x39); /* Opcode 39 /r */
11870 11905 // // ins_encode( OpcP, reg_mem( op1, op2) );
11871 11906 // //%}
11872 11907
11873 11908 // XXX this is generalized by compP_rReg_mem???
11874 11909 // Compare raw pointer (used in out-of-heap check).
11875 11910 // Only works because non-oop pointers must be raw pointers
11876 11911 // and raw pointers have no anti-dependencies.
11877 11912 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
11878 11913 %{
11879 11914 predicate(!n->in(2)->in(2)->bottom_type()->isa_oop_ptr());
11880 11915 match(Set cr (CmpP op1 (LoadP op2)));
11881 11916
11882 11917 format %{ "cmpq $op1, $op2\t# raw ptr" %}
11883 11918 opcode(0x3B); /* Opcode 3B /r */
11884 11919 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
11885 11920 ins_pipe(ialu_cr_reg_mem);
11886 11921 %}
11887 11922
11888 11923 // This will generate a signed flags result. This should be OK since
11889 11924 // any compare to a zero should be eq/neq.
11890 11925 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero)
11891 11926 %{
11892 11927 match(Set cr (CmpP src zero));
11893 11928
11894 11929 format %{ "testq $src, $src\t# ptr" %}
11895 11930 opcode(0x85);
11896 11931 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
11897 11932 ins_pipe(ialu_cr_reg_imm);
11898 11933 %}
11899 11934
11900 11935 // This will generate a signed flags result. This should be OK since
11901 11936 // any compare to a zero should be eq/neq.
11902 11937 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
11903 11938 %{
11904 11939 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
11905 11940 match(Set cr (CmpP (LoadP op) zero));
11906 11941
11907 11942 ins_cost(500); // XXX
11908 11943 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %}
11909 11944 opcode(0xF7); /* Opcode F7 /0 */
11910 11945 ins_encode(REX_mem_wide(op),
11911 11946 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
11912 11947 ins_pipe(ialu_cr_reg_imm);
11913 11948 %}
11914 11949
11915 11950 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
11916 11951 %{
11917 11952 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
11918 11953 match(Set cr (CmpP (LoadP mem) zero));
11919 11954
11920 11955 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
11921 11956 ins_encode %{
11922 11957 __ cmpq(r12, $mem$$Address);
11923 11958 %}
11924 11959 ins_pipe(ialu_cr_reg_mem);
11925 11960 %}
11926 11961
11927 11962 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
11928 11963 %{
11929 11964 match(Set cr (CmpN op1 op2));
11930 11965
11931 11966 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
11932 11967 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %}
11933 11968 ins_pipe(ialu_cr_reg_reg);
11934 11969 %}
11935 11970
11936 11971 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
11937 11972 %{
11938 11973 match(Set cr (CmpN src (LoadN mem)));
11939 11974
11940 11975 format %{ "cmpl $src, $mem\t# compressed ptr" %}
11941 11976 ins_encode %{
11942 11977 __ cmpl($src$$Register, $mem$$Address);
11943 11978 %}
11944 11979 ins_pipe(ialu_cr_reg_mem);
11945 11980 %}
11946 11981
11947 11982 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{
11948 11983 match(Set cr (CmpN op1 op2));
11949 11984
11950 11985 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
11951 11986 ins_encode %{
11952 11987 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant);
11953 11988 %}
11954 11989 ins_pipe(ialu_cr_reg_imm);
11955 11990 %}
11956 11991
11957 11992 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src)
11958 11993 %{
11959 11994 match(Set cr (CmpN src (LoadN mem)));
11960 11995
11961 11996 format %{ "cmpl $mem, $src\t# compressed ptr" %}
11962 11997 ins_encode %{
11963 11998 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
11964 11999 %}
11965 12000 ins_pipe(ialu_cr_reg_mem);
11966 12001 %}
11967 12002
11968 12003 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
11969 12004 match(Set cr (CmpN src zero));
11970 12005
11971 12006 format %{ "testl $src, $src\t# compressed ptr" %}
11972 12007 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
11973 12008 ins_pipe(ialu_cr_reg_imm);
11974 12009 %}
11975 12010
11976 12011 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
11977 12012 %{
11978 12013 predicate(Universe::narrow_oop_base() != NULL);
11979 12014 match(Set cr (CmpN (LoadN mem) zero));
11980 12015
11981 12016 ins_cost(500); // XXX
11982 12017 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
11983 12018 ins_encode %{
11984 12019 __ cmpl($mem$$Address, (int)0xFFFFFFFF);
11985 12020 %}
11986 12021 ins_pipe(ialu_cr_reg_mem);
11987 12022 %}
11988 12023
11989 12024 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
11990 12025 %{
11991 12026 predicate(Universe::narrow_oop_base() == NULL);
11992 12027 match(Set cr (CmpN (LoadN mem) zero));
11993 12028
11994 12029 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
11995 12030 ins_encode %{
11996 12031 __ cmpl(r12, $mem$$Address);
11997 12032 %}
11998 12033 ins_pipe(ialu_cr_reg_mem);
11999 12034 %}
12000 12035
12001 12036 // Yanked all unsigned pointer compare operations.
12002 12037 // Pointer compares are done with CmpP which is already unsigned.
12003 12038
12004 12039 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
12005 12040 %{
12006 12041 match(Set cr (CmpL op1 op2));
12007 12042
12008 12043 format %{ "cmpq $op1, $op2" %}
12009 12044 opcode(0x3B); /* Opcode 3B /r */
12010 12045 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
12011 12046 ins_pipe(ialu_cr_reg_reg);
12012 12047 %}
12013 12048
12014 12049 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
12015 12050 %{
12016 12051 match(Set cr (CmpL op1 op2));
12017 12052
12018 12053 format %{ "cmpq $op1, $op2" %}
12019 12054 opcode(0x81, 0x07); /* Opcode 81 /7 */
12020 12055 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2));
12021 12056 ins_pipe(ialu_cr_reg_imm);
12022 12057 %}
12023 12058
12024 12059 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2)
12025 12060 %{
12026 12061 match(Set cr (CmpL op1 (LoadL op2)));
12027 12062
12028 12063 format %{ "cmpq $op1, $op2" %}
12029 12064 opcode(0x3B); /* Opcode 3B /r */
12030 12065 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
12031 12066 ins_pipe(ialu_cr_reg_mem);
12032 12067 %}
12033 12068
12034 12069 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero)
12035 12070 %{
12036 12071 match(Set cr (CmpL src zero));
12037 12072
12038 12073 format %{ "testq $src, $src" %}
12039 12074 opcode(0x85);
12040 12075 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
12041 12076 ins_pipe(ialu_cr_reg_imm);
12042 12077 %}
12043 12078
12044 12079 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero)
12045 12080 %{
12046 12081 match(Set cr (CmpL (AndL src con) zero));
12047 12082
12048 12083 format %{ "testq $src, $con\t# long" %}
12049 12084 opcode(0xF7, 0x00);
12050 12085 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con));
12051 12086 ins_pipe(ialu_cr_reg_imm);
12052 12087 %}
12053 12088
12054 12089 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero)
12055 12090 %{
12056 12091 match(Set cr (CmpL (AndL src (LoadL mem)) zero));
12057 12092
12058 12093 format %{ "testq $src, $mem" %}
12059 12094 opcode(0x85);
12060 12095 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
12061 12096 ins_pipe(ialu_cr_reg_mem);
12062 12097 %}
12063 12098
12064 12099 // Manifest a CmpL result in an integer register. Very painful.
12065 12100 // This is the test to avoid.
12066 12101 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
12067 12102 %{
12068 12103 match(Set dst (CmpL3 src1 src2));
12069 12104 effect(KILL flags);
12070 12105
12071 12106 ins_cost(275); // XXX
12072 12107 format %{ "cmpq $src1, $src2\t# CmpL3\n\t"
12073 12108 "movl $dst, -1\n\t"
12074 12109 "jl,s done\n\t"
12075 12110 "setne $dst\n\t"
12076 12111 "movzbl $dst, $dst\n\t"
12077 12112 "done:" %}
12078 12113 ins_encode(cmpl3_flag(src1, src2, dst));
12079 12114 ins_pipe(pipe_slow);
12080 12115 %}
12081 12116
12082 12117 //----------Max and Min--------------------------------------------------------
12083 12118 // Min Instructions
12084 12119
12085 12120 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr)
12086 12121 %{
12087 12122 effect(USE_DEF dst, USE src, USE cr);
12088 12123
12089 12124 format %{ "cmovlgt $dst, $src\t# min" %}
12090 12125 opcode(0x0F, 0x4F);
12091 12126 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
12092 12127 ins_pipe(pipe_cmov_reg);
12093 12128 %}
12094 12129
12095 12130
12096 12131 instruct minI_rReg(rRegI dst, rRegI src)
12097 12132 %{
12098 12133 match(Set dst (MinI dst src));
12099 12134
12100 12135 ins_cost(200);
12101 12136 expand %{
12102 12137 rFlagsReg cr;
12103 12138 compI_rReg(cr, dst, src);
12104 12139 cmovI_reg_g(dst, src, cr);
12105 12140 %}
12106 12141 %}
12107 12142
12108 12143 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr)
12109 12144 %{
12110 12145 effect(USE_DEF dst, USE src, USE cr);
12111 12146
12112 12147 format %{ "cmovllt $dst, $src\t# max" %}
12113 12148 opcode(0x0F, 0x4C);
12114 12149 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
12115 12150 ins_pipe(pipe_cmov_reg);
12116 12151 %}
12117 12152
12118 12153
12119 12154 instruct maxI_rReg(rRegI dst, rRegI src)
12120 12155 %{
12121 12156 match(Set dst (MaxI dst src));
12122 12157
12123 12158 ins_cost(200);
12124 12159 expand %{
12125 12160 rFlagsReg cr;
12126 12161 compI_rReg(cr, dst, src);
12127 12162 cmovI_reg_l(dst, src, cr);
12128 12163 %}
12129 12164 %}
12130 12165
12131 12166 // ============================================================================
12132 12167 // Branch Instructions
12133 12168
12134 12169 // Jump Direct - Label defines a relative address from JMP+1
12135 12170 instruct jmpDir(label labl)
12136 12171 %{
12137 12172 match(Goto);
12138 12173 effect(USE labl);
12139 12174
12140 12175 ins_cost(300);
12141 12176 format %{ "jmp $labl" %}
12142 12177 size(5);
12143 12178 opcode(0xE9);
12144 12179 ins_encode(OpcP, Lbl(labl));
12145 12180 ins_pipe(pipe_jmp);
12146 12181 ins_pc_relative(1);
12147 12182 %}
12148 12183
12149 12184 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12150 12185 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl)
12151 12186 %{
12152 12187 match(If cop cr);
12153 12188 effect(USE labl);
12154 12189
12155 12190 ins_cost(300);
12156 12191 format %{ "j$cop $labl" %}
12157 12192 size(6);
12158 12193 opcode(0x0F, 0x80);
12159 12194 ins_encode(Jcc(cop, labl));
12160 12195 ins_pipe(pipe_jcc);
12161 12196 ins_pc_relative(1);
12162 12197 %}
12163 12198
12164 12199 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12165 12200 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
12166 12201 %{
12167 12202 match(CountedLoopEnd cop cr);
12168 12203 effect(USE labl);
12169 12204
12170 12205 ins_cost(300);
12171 12206 format %{ "j$cop $labl\t# loop end" %}
12172 12207 size(6);
12173 12208 opcode(0x0F, 0x80);
12174 12209 ins_encode(Jcc(cop, labl));
12175 12210 ins_pipe(pipe_jcc);
12176 12211 ins_pc_relative(1);
12177 12212 %}
12178 12213
12179 12214 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12180 12215 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12181 12216 match(CountedLoopEnd cop cmp);
12182 12217 effect(USE labl);
12183 12218
12184 12219 ins_cost(300);
12185 12220 format %{ "j$cop,u $labl\t# loop end" %}
12186 12221 size(6);
12187 12222 opcode(0x0F, 0x80);
12188 12223 ins_encode(Jcc(cop, labl));
12189 12224 ins_pipe(pipe_jcc);
12190 12225 ins_pc_relative(1);
12191 12226 %}
12192 12227
12193 12228 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12194 12229 match(CountedLoopEnd cop cmp);
12195 12230 effect(USE labl);
12196 12231
12197 12232 ins_cost(200);
12198 12233 format %{ "j$cop,u $labl\t# loop end" %}
12199 12234 size(6);
12200 12235 opcode(0x0F, 0x80);
12201 12236 ins_encode(Jcc(cop, labl));
12202 12237 ins_pipe(pipe_jcc);
12203 12238 ins_pc_relative(1);
12204 12239 %}
12205 12240
12206 12241 // Jump Direct Conditional - using unsigned comparison
12207 12242 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12208 12243 match(If cop cmp);
12209 12244 effect(USE labl);
12210 12245
12211 12246 ins_cost(300);
12212 12247 format %{ "j$cop,u $labl" %}
12213 12248 size(6);
12214 12249 opcode(0x0F, 0x80);
12215 12250 ins_encode(Jcc(cop, labl));
12216 12251 ins_pipe(pipe_jcc);
12217 12252 ins_pc_relative(1);
12218 12253 %}
12219 12254
12220 12255 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12221 12256 match(If cop cmp);
12222 12257 effect(USE labl);
12223 12258
12224 12259 ins_cost(200);
12225 12260 format %{ "j$cop,u $labl" %}
12226 12261 size(6);
12227 12262 opcode(0x0F, 0x80);
12228 12263 ins_encode(Jcc(cop, labl));
12229 12264 ins_pipe(pipe_jcc);
12230 12265 ins_pc_relative(1);
12231 12266 %}
12232 12267
12233 12268 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
12234 12269 match(If cop cmp);
12235 12270 effect(USE labl);
12236 12271
12237 12272 ins_cost(200);
12238 12273 format %{ $$template
12239 12274 if ($cop$$cmpcode == Assembler::notEqual) {
12240 12275 $$emit$$"jp,u $labl\n\t"
12241 12276 $$emit$$"j$cop,u $labl"
12242 12277 } else {
12243 12278 $$emit$$"jp,u done\n\t"
12244 12279 $$emit$$"j$cop,u $labl\n\t"
12245 12280 $$emit$$"done:"
12246 12281 }
12247 12282 %}
12248 12283 size(12);
12249 12284 opcode(0x0F, 0x80);
12250 12285 ins_encode %{
12251 12286 Label* l = $labl$$label;
12252 12287 $$$emit8$primary;
12253 12288 emit_cc(cbuf, $secondary, Assembler::parity);
12254 12289 int parity_disp = -1;
12255 12290 if ($cop$$cmpcode == Assembler::notEqual) {
12256 12291 // the two jumps 6 bytes apart so the jump distances are too
12257 12292 parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
12258 12293 } else if ($cop$$cmpcode == Assembler::equal) {
12259 12294 parity_disp = 6;
12260 12295 } else {
12261 12296 ShouldNotReachHere();
12262 12297 }
12263 12298 emit_d32(cbuf, parity_disp);
12264 12299 $$$emit8$primary;
12265 12300 emit_cc(cbuf, $secondary, $cop$$cmpcode);
12266 12301 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
12267 12302 emit_d32(cbuf, disp);
12268 12303 %}
12269 12304 ins_pipe(pipe_jcc);
12270 12305 ins_pc_relative(1);
12271 12306 %}
12272 12307
12273 12308 // ============================================================================
12274 12309 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
12275 12310 // superklass array for an instance of the superklass. Set a hidden
12276 12311 // internal cache on a hit (cache is checked with exposed code in
12277 12312 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The
12278 12313 // encoding ALSO sets flags.
12279 12314
12280 12315 instruct partialSubtypeCheck(rdi_RegP result,
12281 12316 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
12282 12317 rFlagsReg cr)
12283 12318 %{
12284 12319 match(Set result (PartialSubtypeCheck sub super));
12285 12320 effect(KILL rcx, KILL cr);
12286 12321
12287 12322 ins_cost(1100); // slightly larger than the next version
12288 12323 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t"
12289 12324 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t"
12290 12325 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t"
12291 12326 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t"
12292 12327 "jne,s miss\t\t# Missed: rdi not-zero\n\t"
12293 12328 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t"
12294 12329 "xorq $result, $result\t\t Hit: rdi zero\n\t"
12295 12330 "miss:\t" %}
12296 12331
12297 12332 opcode(0x1); // Force a XOR of RDI
12298 12333 ins_encode(enc_PartialSubtypeCheck());
12299 12334 ins_pipe(pipe_slow);
12300 12335 %}
12301 12336
12302 12337 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr,
12303 12338 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
12304 12339 immP0 zero,
12305 12340 rdi_RegP result)
12306 12341 %{
12307 12342 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
12308 12343 effect(KILL rcx, KILL result);
12309 12344
12310 12345 ins_cost(1000);
12311 12346 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t"
12312 12347 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t"
12313 12348 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t"
12314 12349 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t"
12315 12350 "jne,s miss\t\t# Missed: flags nz\n\t"
12316 12351 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t"
12317 12352 "miss:\t" %}
12318 12353
12319 12354 opcode(0x0); // No need to XOR RDI
12320 12355 ins_encode(enc_PartialSubtypeCheck());
12321 12356 ins_pipe(pipe_slow);
12322 12357 %}
12323 12358
12324 12359 // ============================================================================
12325 12360 // Branch Instructions -- short offset versions
12326 12361 //
12327 12362 // These instructions are used to replace jumps of a long offset (the default
12328 12363 // match) with jumps of a shorter offset. These instructions are all tagged
12329 12364 // with the ins_short_branch attribute, which causes the ADLC to suppress the
12330 12365 // match rules in general matching. Instead, the ADLC generates a conversion
12331 12366 // method in the MachNode which can be used to do in-place replacement of the
12332 12367 // long variant with the shorter variant. The compiler will determine if a
12333 12368 // branch can be taken by the is_short_branch_offset() predicate in the machine
12334 12369 // specific code section of the file.
12335 12370
12336 12371 // Jump Direct - Label defines a relative address from JMP+1
12337 12372 instruct jmpDir_short(label labl) %{
12338 12373 match(Goto);
12339 12374 effect(USE labl);
12340 12375
12341 12376 ins_cost(300);
12342 12377 format %{ "jmp,s $labl" %}
12343 12378 size(2);
12344 12379 opcode(0xEB);
12345 12380 ins_encode(OpcP, LblShort(labl));
12346 12381 ins_pipe(pipe_jmp);
12347 12382 ins_pc_relative(1);
12348 12383 ins_short_branch(1);
12349 12384 %}
12350 12385
12351 12386 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12352 12387 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
12353 12388 match(If cop cr);
12354 12389 effect(USE labl);
12355 12390
12356 12391 ins_cost(300);
12357 12392 format %{ "j$cop,s $labl" %}
12358 12393 size(2);
12359 12394 opcode(0x70);
12360 12395 ins_encode(JccShort(cop, labl));
12361 12396 ins_pipe(pipe_jcc);
12362 12397 ins_pc_relative(1);
12363 12398 ins_short_branch(1);
12364 12399 %}
12365 12400
12366 12401 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12367 12402 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
12368 12403 match(CountedLoopEnd cop cr);
12369 12404 effect(USE labl);
12370 12405
12371 12406 ins_cost(300);
12372 12407 format %{ "j$cop,s $labl\t# loop end" %}
12373 12408 size(2);
12374 12409 opcode(0x70);
12375 12410 ins_encode(JccShort(cop, labl));
12376 12411 ins_pipe(pipe_jcc);
12377 12412 ins_pc_relative(1);
12378 12413 ins_short_branch(1);
12379 12414 %}
12380 12415
12381 12416 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12382 12417 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12383 12418 match(CountedLoopEnd cop cmp);
12384 12419 effect(USE labl);
12385 12420
12386 12421 ins_cost(300);
12387 12422 format %{ "j$cop,us $labl\t# loop end" %}
12388 12423 size(2);
12389 12424 opcode(0x70);
12390 12425 ins_encode(JccShort(cop, labl));
12391 12426 ins_pipe(pipe_jcc);
12392 12427 ins_pc_relative(1);
12393 12428 ins_short_branch(1);
12394 12429 %}
12395 12430
12396 12431 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12397 12432 match(CountedLoopEnd cop cmp);
12398 12433 effect(USE labl);
12399 12434
12400 12435 ins_cost(300);
12401 12436 format %{ "j$cop,us $labl\t# loop end" %}
12402 12437 size(2);
12403 12438 opcode(0x70);
12404 12439 ins_encode(JccShort(cop, labl));
12405 12440 ins_pipe(pipe_jcc);
12406 12441 ins_pc_relative(1);
12407 12442 ins_short_branch(1);
12408 12443 %}
12409 12444
12410 12445 // Jump Direct Conditional - using unsigned comparison
12411 12446 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
12412 12447 match(If cop cmp);
12413 12448 effect(USE labl);
12414 12449
12415 12450 ins_cost(300);
12416 12451 format %{ "j$cop,us $labl" %}
12417 12452 size(2);
12418 12453 opcode(0x70);
12419 12454 ins_encode(JccShort(cop, labl));
12420 12455 ins_pipe(pipe_jcc);
12421 12456 ins_pc_relative(1);
12422 12457 ins_short_branch(1);
12423 12458 %}
12424 12459
12425 12460 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
12426 12461 match(If cop cmp);
12427 12462 effect(USE labl);
12428 12463
12429 12464 ins_cost(300);
12430 12465 format %{ "j$cop,us $labl" %}
12431 12466 size(2);
12432 12467 opcode(0x70);
12433 12468 ins_encode(JccShort(cop, labl));
12434 12469 ins_pipe(pipe_jcc);
12435 12470 ins_pc_relative(1);
12436 12471 ins_short_branch(1);
12437 12472 %}
12438 12473
12439 12474 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
12440 12475 match(If cop cmp);
12441 12476 effect(USE labl);
12442 12477
12443 12478 ins_cost(300);
12444 12479 format %{ $$template
12445 12480 if ($cop$$cmpcode == Assembler::notEqual) {
12446 12481 $$emit$$"jp,u,s $labl\n\t"
12447 12482 $$emit$$"j$cop,u,s $labl"
12448 12483 } else {
12449 12484 $$emit$$"jp,u,s done\n\t"
12450 12485 $$emit$$"j$cop,u,s $labl\n\t"
12451 12486 $$emit$$"done:"
12452 12487 }
12453 12488 %}
12454 12489 size(4);
12455 12490 opcode(0x70);
12456 12491 ins_encode %{
12457 12492 Label* l = $labl$$label;
12458 12493 emit_cc(cbuf, $primary, Assembler::parity);
12459 12494 int parity_disp = -1;
12460 12495 if ($cop$$cmpcode == Assembler::notEqual) {
12461 12496 parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
12462 12497 } else if ($cop$$cmpcode == Assembler::equal) {
12463 12498 parity_disp = 2;
12464 12499 } else {
12465 12500 ShouldNotReachHere();
12466 12501 }
12467 12502 emit_d8(cbuf, parity_disp);
12468 12503 emit_cc(cbuf, $primary, $cop$$cmpcode);
12469 12504 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
12470 12505 emit_d8(cbuf, disp);
12471 12506 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
12472 12507 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
12473 12508 %}
12474 12509 ins_pipe(pipe_jcc);
12475 12510 ins_pc_relative(1);
12476 12511 ins_short_branch(1);
12477 12512 %}
12478 12513
12479 12514 // ============================================================================
12480 12515 // inlined locking and unlocking
12481 12516
12482 12517 instruct cmpFastLock(rFlagsReg cr,
12483 12518 rRegP object, rRegP box, rax_RegI tmp, rRegP scr)
12484 12519 %{
12485 12520 match(Set cr (FastLock object box));
12486 12521 effect(TEMP tmp, TEMP scr);
12487 12522
12488 12523 ins_cost(300);
12489 12524 format %{ "fastlock $object,$box,$tmp,$scr" %}
12490 12525 ins_encode(Fast_Lock(object, box, tmp, scr));
12491 12526 ins_pipe(pipe_slow);
12492 12527 ins_pc_relative(1);
12493 12528 %}
12494 12529
12495 12530 instruct cmpFastUnlock(rFlagsReg cr,
12496 12531 rRegP object, rax_RegP box, rRegP tmp)
12497 12532 %{
12498 12533 match(Set cr (FastUnlock object box));
12499 12534 effect(TEMP tmp);
12500 12535
12501 12536 ins_cost(300);
12502 12537 format %{ "fastunlock $object, $box, $tmp" %}
12503 12538 ins_encode(Fast_Unlock(object, box, tmp));
12504 12539 ins_pipe(pipe_slow);
12505 12540 ins_pc_relative(1);
12506 12541 %}
12507 12542
12508 12543
12509 12544 // ============================================================================
12510 12545 // Safepoint Instructions
12511 12546 instruct safePoint_poll(rFlagsReg cr)
12512 12547 %{
12513 12548 match(SafePoint);
12514 12549 effect(KILL cr);
12515 12550
12516 12551 format %{ "testl rax, [rip + #offset_to_poll_page]\t"
12517 12552 "# Safepoint: poll for GC" %}
12518 12553 size(6); // Opcode + ModRM + Disp32 == 6 bytes
↓ open down ↓ |
9898 lines elided |
↑ open up ↑ |
12519 12554 ins_cost(125);
12520 12555 ins_encode(enc_safepoint_poll);
12521 12556 ins_pipe(ialu_reg_mem);
12522 12557 %}
12523 12558
12524 12559 // ============================================================================
12525 12560 // Procedure Call/Return Instructions
12526 12561 // Call Java Static Instruction
12527 12562 // Note: If this code changes, the corresponding ret_addr_offset() and
12528 12563 // compute_padding() functions will have to be adjusted.
12529 -instruct CallStaticJavaDirect(method meth)
12530 -%{
12564 +instruct CallStaticJavaDirect(method meth) %{
12531 12565 match(CallStaticJava);
12566 + predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke());
12532 12567 effect(USE meth);
12533 12568
12534 12569 ins_cost(300);
12535 12570 format %{ "call,static " %}
12536 12571 opcode(0xE8); /* E8 cd */
12537 12572 ins_encode(Java_Static_Call(meth), call_epilog);
12538 12573 ins_pipe(pipe_slow);
12539 12574 ins_pc_relative(1);
12540 12575 ins_alignment(4);
12541 12576 %}
12542 12577
12578 +// Call Java Static Instruction (method handle version)
12579 +// Note: If this code changes, the corresponding ret_addr_offset() and
12580 +// compute_padding() functions will have to be adjusted.
12581 +instruct CallStaticJavaHandle(method meth, rbp_RegP rbp) %{
12582 + match(CallStaticJava);
12583 + predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke());
12584 + effect(USE meth);
12585 + // RBP is saved by all callees (for interpreter stack correction).
12586 + // We use it here for a similar purpose, in {preserve,restore}_SP.
12587 +
12588 + ins_cost(300);
12589 + format %{ "call,static/MethodHandle " %}
12590 + opcode(0xE8); /* E8 cd */
12591 + ins_encode(preserve_SP,
12592 + Java_Static_Call(meth),
12593 + restore_SP,
12594 + call_epilog);
12595 + ins_pipe(pipe_slow);
12596 + ins_pc_relative(1);
12597 + ins_alignment(4);
12598 +%}
12599 +
12543 12600 // Call Java Dynamic Instruction
12544 12601 // Note: If this code changes, the corresponding ret_addr_offset() and
12545 12602 // compute_padding() functions will have to be adjusted.
12546 12603 instruct CallDynamicJavaDirect(method meth)
12547 12604 %{
12548 12605 match(CallDynamicJava);
12549 12606 effect(USE meth);
12550 12607
12551 12608 ins_cost(300);
12552 12609 format %{ "movq rax, #Universe::non_oop_word()\n\t"
12553 12610 "call,dynamic " %}
12554 12611 opcode(0xE8); /* E8 cd */
12555 12612 ins_encode(Java_Dynamic_Call(meth), call_epilog);
12556 12613 ins_pipe(pipe_slow);
12557 12614 ins_pc_relative(1);
12558 12615 ins_alignment(4);
12559 12616 %}
12560 12617
12561 12618 // Call Runtime Instruction
12562 12619 instruct CallRuntimeDirect(method meth)
12563 12620 %{
12564 12621 match(CallRuntime);
12565 12622 effect(USE meth);
12566 12623
12567 12624 ins_cost(300);
12568 12625 format %{ "call,runtime " %}
12569 12626 opcode(0xE8); /* E8 cd */
12570 12627 ins_encode(Java_To_Runtime(meth));
12571 12628 ins_pipe(pipe_slow);
12572 12629 ins_pc_relative(1);
12573 12630 %}
12574 12631
12575 12632 // Call runtime without safepoint
12576 12633 instruct CallLeafDirect(method meth)
12577 12634 %{
12578 12635 match(CallLeaf);
12579 12636 effect(USE meth);
12580 12637
12581 12638 ins_cost(300);
12582 12639 format %{ "call_leaf,runtime " %}
12583 12640 opcode(0xE8); /* E8 cd */
12584 12641 ins_encode(Java_To_Runtime(meth));
12585 12642 ins_pipe(pipe_slow);
12586 12643 ins_pc_relative(1);
12587 12644 %}
12588 12645
12589 12646 // Call runtime without safepoint
12590 12647 instruct CallLeafNoFPDirect(method meth)
12591 12648 %{
12592 12649 match(CallLeafNoFP);
12593 12650 effect(USE meth);
12594 12651
12595 12652 ins_cost(300);
12596 12653 format %{ "call_leaf_nofp,runtime " %}
12597 12654 opcode(0xE8); /* E8 cd */
12598 12655 ins_encode(Java_To_Runtime(meth));
12599 12656 ins_pipe(pipe_slow);
12600 12657 ins_pc_relative(1);
12601 12658 %}
12602 12659
12603 12660 // Return Instruction
12604 12661 // Remove the return address & jump to it.
12605 12662 // Notice: We always emit a nop after a ret to make sure there is room
12606 12663 // for safepoint patching
12607 12664 instruct Ret()
12608 12665 %{
12609 12666 match(Return);
12610 12667
12611 12668 format %{ "ret" %}
12612 12669 opcode(0xC3);
12613 12670 ins_encode(OpcP);
12614 12671 ins_pipe(pipe_jmp);
12615 12672 %}
12616 12673
12617 12674 // Tail Call; Jump from runtime stub to Java code.
12618 12675 // Also known as an 'interprocedural jump'.
12619 12676 // Target of jump will eventually return to caller.
12620 12677 // TailJump below removes the return address.
12621 12678 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop)
12622 12679 %{
12623 12680 match(TailCall jump_target method_oop);
12624 12681
12625 12682 ins_cost(300);
12626 12683 format %{ "jmp $jump_target\t# rbx holds method oop" %}
12627 12684 opcode(0xFF, 0x4); /* Opcode FF /4 */
12628 12685 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target));
12629 12686 ins_pipe(pipe_jmp);
12630 12687 %}
12631 12688
12632 12689 // Tail Jump; remove the return address; jump to target.
12633 12690 // TailCall above leaves the return address around.
12634 12691 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop)
12635 12692 %{
12636 12693 match(TailJump jump_target ex_oop);
12637 12694
12638 12695 ins_cost(300);
12639 12696 format %{ "popq rdx\t# pop return address\n\t"
12640 12697 "jmp $jump_target" %}
12641 12698 opcode(0xFF, 0x4); /* Opcode FF /4 */
12642 12699 ins_encode(Opcode(0x5a), // popq rdx
12643 12700 REX_reg(jump_target), OpcP, reg_opc(jump_target));
12644 12701 ins_pipe(pipe_jmp);
12645 12702 %}
12646 12703
12647 12704 // Create exception oop: created by stack-crawling runtime code.
12648 12705 // Created exception is now available to this handler, and is setup
12649 12706 // just prior to jumping to this handler. No code emitted.
12650 12707 instruct CreateException(rax_RegP ex_oop)
12651 12708 %{
12652 12709 match(Set ex_oop (CreateEx));
12653 12710
12654 12711 size(0);
12655 12712 // use the following format syntax
12656 12713 format %{ "# exception oop is in rax; no code emitted" %}
12657 12714 ins_encode();
12658 12715 ins_pipe(empty);
12659 12716 %}
12660 12717
12661 12718 // Rethrow exception:
12662 12719 // The exception oop will come in the first argument position.
12663 12720 // Then JUMP (not call) to the rethrow stub code.
12664 12721 instruct RethrowException()
12665 12722 %{
12666 12723 match(Rethrow);
12667 12724
12668 12725 // use the following format syntax
12669 12726 format %{ "jmp rethrow_stub" %}
12670 12727 ins_encode(enc_rethrow);
12671 12728 ins_pipe(pipe_jmp);
12672 12729 %}
12673 12730
12674 12731
12675 12732 //----------PEEPHOLE RULES-----------------------------------------------------
12676 12733 // These must follow all instruction definitions as they use the names
12677 12734 // defined in the instructions definitions.
12678 12735 //
12679 12736 // peepmatch ( root_instr_name [preceding_instruction]* );
12680 12737 //
12681 12738 // peepconstraint %{
12682 12739 // (instruction_number.operand_name relational_op instruction_number.operand_name
12683 12740 // [, ...] );
12684 12741 // // instruction numbers are zero-based using left to right order in peepmatch
12685 12742 //
12686 12743 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
12687 12744 // // provide an instruction_number.operand_name for each operand that appears
12688 12745 // // in the replacement instruction's match rule
12689 12746 //
12690 12747 // ---------VM FLAGS---------------------------------------------------------
12691 12748 //
12692 12749 // All peephole optimizations can be turned off using -XX:-OptoPeephole
12693 12750 //
12694 12751 // Each peephole rule is given an identifying number starting with zero and
12695 12752 // increasing by one in the order seen by the parser. An individual peephole
12696 12753 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
12697 12754 // on the command-line.
12698 12755 //
12699 12756 // ---------CURRENT LIMITATIONS----------------------------------------------
12700 12757 //
12701 12758 // Only match adjacent instructions in same basic block
12702 12759 // Only equality constraints
12703 12760 // Only constraints between operands, not (0.dest_reg == RAX_enc)
12704 12761 // Only one replacement instruction
12705 12762 //
12706 12763 // ---------EXAMPLE----------------------------------------------------------
12707 12764 //
12708 12765 // // pertinent parts of existing instructions in architecture description
12709 12766 // instruct movI(rRegI dst, rRegI src)
12710 12767 // %{
12711 12768 // match(Set dst (CopyI src));
12712 12769 // %}
12713 12770 //
12714 12771 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
12715 12772 // %{
12716 12773 // match(Set dst (AddI dst src));
12717 12774 // effect(KILL cr);
12718 12775 // %}
12719 12776 //
12720 12777 // // Change (inc mov) to lea
12721 12778 // peephole %{
12722 12779 // // increment preceeded by register-register move
12723 12780 // peepmatch ( incI_rReg movI );
12724 12781 // // require that the destination register of the increment
12725 12782 // // match the destination register of the move
12726 12783 // peepconstraint ( 0.dst == 1.dst );
12727 12784 // // construct a replacement instruction that sets
12728 12785 // // the destination to ( move's source register + one )
12729 12786 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) );
12730 12787 // %}
12731 12788 //
12732 12789
12733 12790 // Implementation no longer uses movX instructions since
12734 12791 // machine-independent system no longer uses CopyX nodes.
12735 12792 //
12736 12793 // peephole
12737 12794 // %{
12738 12795 // peepmatch (incI_rReg movI);
12739 12796 // peepconstraint (0.dst == 1.dst);
12740 12797 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
12741 12798 // %}
12742 12799
12743 12800 // peephole
12744 12801 // %{
12745 12802 // peepmatch (decI_rReg movI);
12746 12803 // peepconstraint (0.dst == 1.dst);
12747 12804 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
12748 12805 // %}
12749 12806
12750 12807 // peephole
12751 12808 // %{
12752 12809 // peepmatch (addI_rReg_imm movI);
12753 12810 // peepconstraint (0.dst == 1.dst);
12754 12811 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
12755 12812 // %}
12756 12813
12757 12814 // peephole
12758 12815 // %{
12759 12816 // peepmatch (incL_rReg movL);
12760 12817 // peepconstraint (0.dst == 1.dst);
12761 12818 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
12762 12819 // %}
12763 12820
12764 12821 // peephole
12765 12822 // %{
12766 12823 // peepmatch (decL_rReg movL);
12767 12824 // peepconstraint (0.dst == 1.dst);
12768 12825 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
12769 12826 // %}
12770 12827
12771 12828 // peephole
12772 12829 // %{
12773 12830 // peepmatch (addL_rReg_imm movL);
12774 12831 // peepconstraint (0.dst == 1.dst);
12775 12832 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
12776 12833 // %}
12777 12834
12778 12835 // peephole
12779 12836 // %{
12780 12837 // peepmatch (addP_rReg_imm movP);
12781 12838 // peepconstraint (0.dst == 1.dst);
12782 12839 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src));
12783 12840 // %}
12784 12841
12785 12842 // // Change load of spilled value to only a spill
12786 12843 // instruct storeI(memory mem, rRegI src)
12787 12844 // %{
12788 12845 // match(Set mem (StoreI mem src));
12789 12846 // %}
12790 12847 //
12791 12848 // instruct loadI(rRegI dst, memory mem)
12792 12849 // %{
12793 12850 // match(Set dst (LoadI mem));
12794 12851 // %}
12795 12852 //
12796 12853
12797 12854 peephole
12798 12855 %{
12799 12856 peepmatch (loadI storeI);
12800 12857 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
12801 12858 peepreplace (storeI(1.mem 1.mem 1.src));
12802 12859 %}
12803 12860
12804 12861 peephole
12805 12862 %{
12806 12863 peepmatch (loadL storeL);
12807 12864 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
12808 12865 peepreplace (storeL(1.mem 1.mem 1.src));
12809 12866 %}
12810 12867
12811 12868 //----------SMARTSPILL RULES---------------------------------------------------
12812 12869 // These must follow all instruction definitions as they use the names
12813 12870 // defined in the instructions definitions.
↓ open down ↓ |
261 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX